From 1fd2322662b8148e4551d21fb050e72471fbe020 Mon Sep 17 00:00:00 2001 From: Sebastien Bourdeauducq Date: Thu, 15 Aug 2019 23:16:17 +0800 Subject: [PATCH] wrpll/thls: implement global writeback --- artiq/gateware/wrpll/thls.py | 37 +++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/artiq/gateware/wrpll/thls.py b/artiq/gateware/wrpll/thls.py index 3cb545aa4..3f5aa6425 100644 --- a/artiq/gateware/wrpll/thls.py +++ b/artiq/gateware/wrpll/thls.py @@ -3,6 +3,7 @@ import ast from copy import copy import operator from functools import reduce +from collections import OrderedDict from migen import * from migen.genlib.fsm import * @@ -73,7 +74,7 @@ class ASTCompiler: self.next_ssa_reg = -1 self.constants = dict() self.names = dict() - self.globals = dict() + self.globals = OrderedDict() def get_ssa_reg(self): r = self.next_ssa_reg @@ -81,11 +82,11 @@ class ASTCompiler: return r def add_global(self, name): - r = len(self.data) - self.data.append(0) - self.names[name] = r - self.globals[name] = r - return r + if name not in self.globals: + r = len(self.data) + self.data.append(0) + self.names[name] = r + self.globals[name] = r def input(self, name): target = self.get_ssa_reg() @@ -266,11 +267,20 @@ class Scheduler: return False if isn.outputs: + # check that exit slot is free latency = self.processor.get_instruction_latency(isn) exit = cycle + latency if exit in self.exits: return False + # avoid RAW hazard with global writeback + for output in isn.outputs: + if output >= 0: + for risn in self.remaining: + for inp in risn.inputs: + if inp == output: + return False + # Instruction can be scheduled self.remaining.remove(isn) @@ -282,7 +292,10 @@ class Scheduler: if isn.outputs: assert len(isn.outputs) == 1 - output = self.allocate_register() + if isn.outputs[0] < 0: + output = self.allocate_register() + else: + output = isn.outputs[0] self.exits[exit] = (isn.outputs[0], output) self.output.append(isn.__class__(immediate=isn.immediate, inputs=mapped_inputs)) @@ -352,6 +365,10 @@ def compile(processor, function): astcompiler.emit(node) if isinstance(node, ast.Return): break + for glbl, location in astcompiler.globals.items(): + new_location = astcompiler.names[glbl] + if new_location != location: + astcompiler.program.append(CopyIsn(inputs=[new_location], outputs=[location])) scheduler = Scheduler(processor, len(astcompiler.data), astcompiler.program) scheduler.schedule() @@ -585,7 +602,9 @@ def foo(x): def simple_test(x): - return min((x*-2 >> 1) + 2 - 1000, 10) + global a + a = a + (x*4 >> 1) + return a if __name__ == "__main__": @@ -614,4 +633,4 @@ if __name__ == "__main__": callback((yield proc_impl.output)) yield - run_simulation(proc_impl, [send_values([42, 40]), receive_values(print)]) + run_simulation(proc_impl, [send_values([42, 40, 10, 10]), receive_values(print)])