forked from M-Labs/artiq
wrpll/thls: implement global writeback
This commit is contained in:
parent
24082b687e
commit
1fd2322662
|
@ -3,6 +3,7 @@ import ast
|
||||||
from copy import copy
|
from copy import copy
|
||||||
import operator
|
import operator
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
|
from collections import OrderedDict
|
||||||
|
|
||||||
from migen import *
|
from migen import *
|
||||||
from migen.genlib.fsm import *
|
from migen.genlib.fsm import *
|
||||||
|
@ -73,7 +74,7 @@ class ASTCompiler:
|
||||||
self.next_ssa_reg = -1
|
self.next_ssa_reg = -1
|
||||||
self.constants = dict()
|
self.constants = dict()
|
||||||
self.names = dict()
|
self.names = dict()
|
||||||
self.globals = dict()
|
self.globals = OrderedDict()
|
||||||
|
|
||||||
def get_ssa_reg(self):
|
def get_ssa_reg(self):
|
||||||
r = self.next_ssa_reg
|
r = self.next_ssa_reg
|
||||||
|
@ -81,11 +82,11 @@ class ASTCompiler:
|
||||||
return r
|
return r
|
||||||
|
|
||||||
def add_global(self, name):
|
def add_global(self, name):
|
||||||
|
if name not in self.globals:
|
||||||
r = len(self.data)
|
r = len(self.data)
|
||||||
self.data.append(0)
|
self.data.append(0)
|
||||||
self.names[name] = r
|
self.names[name] = r
|
||||||
self.globals[name] = r
|
self.globals[name] = r
|
||||||
return r
|
|
||||||
|
|
||||||
def input(self, name):
|
def input(self, name):
|
||||||
target = self.get_ssa_reg()
|
target = self.get_ssa_reg()
|
||||||
|
@ -266,11 +267,20 @@ class Scheduler:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if isn.outputs:
|
if isn.outputs:
|
||||||
|
# check that exit slot is free
|
||||||
latency = self.processor.get_instruction_latency(isn)
|
latency = self.processor.get_instruction_latency(isn)
|
||||||
exit = cycle + latency
|
exit = cycle + latency
|
||||||
if exit in self.exits:
|
if exit in self.exits:
|
||||||
return False
|
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
|
# Instruction can be scheduled
|
||||||
|
|
||||||
self.remaining.remove(isn)
|
self.remaining.remove(isn)
|
||||||
|
@ -282,7 +292,10 @@ class Scheduler:
|
||||||
|
|
||||||
if isn.outputs:
|
if isn.outputs:
|
||||||
assert len(isn.outputs) == 1
|
assert len(isn.outputs) == 1
|
||||||
|
if isn.outputs[0] < 0:
|
||||||
output = self.allocate_register()
|
output = self.allocate_register()
|
||||||
|
else:
|
||||||
|
output = isn.outputs[0]
|
||||||
self.exits[exit] = (isn.outputs[0], output)
|
self.exits[exit] = (isn.outputs[0], output)
|
||||||
self.output.append(isn.__class__(immediate=isn.immediate, inputs=mapped_inputs))
|
self.output.append(isn.__class__(immediate=isn.immediate, inputs=mapped_inputs))
|
||||||
|
|
||||||
|
@ -352,6 +365,10 @@ def compile(processor, function):
|
||||||
astcompiler.emit(node)
|
astcompiler.emit(node)
|
||||||
if isinstance(node, ast.Return):
|
if isinstance(node, ast.Return):
|
||||||
break
|
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 = Scheduler(processor, len(astcompiler.data), astcompiler.program)
|
||||||
scheduler.schedule()
|
scheduler.schedule()
|
||||||
|
@ -585,7 +602,9 @@ def foo(x):
|
||||||
|
|
||||||
|
|
||||||
def simple_test(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__":
|
if __name__ == "__main__":
|
||||||
|
@ -614,4 +633,4 @@ if __name__ == "__main__":
|
||||||
callback((yield proc_impl.output))
|
callback((yield proc_impl.output))
|
||||||
yield
|
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)])
|
||||||
|
|
Loading…
Reference in New Issue