wrpll/thls: support processor start/stop

This commit is contained in:
Sebastien Bourdeauducq 2019-07-24 18:51:33 +08:00
parent 623446f82c
commit 7a5dcbe60e
1 changed files with 49 additions and 15 deletions

View File

@ -5,6 +5,7 @@ import operator
from functools import reduce from functools import reduce
from migen import * from migen import *
from migen.genlib.fsm import *
class Isn: class Isn:
@ -53,6 +54,9 @@ class InputIsn(Isn):
class OutputIsn(Isn): class OutputIsn(Isn):
opcode = 6 opcode = 6
class EndIsn(Isn):
opcode = 7
class ASTCompiler: class ASTCompiler:
def __init__(self): def __init__(self):
@ -298,11 +302,14 @@ def compile(processor, function):
scheduler = Scheduler(processor, len(astcompiler.data), astcompiler.program) scheduler = Scheduler(processor, len(astcompiler.data), astcompiler.program)
scheduler.schedule() scheduler.schedule()
max_reg = max(max(max(isn.inputs + [0]) for isn in scheduler.output), max(v[1] for k, v in scheduler.exits.items())) program = copy(scheduler.output)
program.append(EndIsn())
max_reg = max(max(max(isn.inputs + [0]) for isn in program), max(v[1] for k, v in scheduler.exits.items()))
return CompiledProgram( return CompiledProgram(
processor=processor, processor=processor,
program=scheduler.output, program=program,
exits={k: v[1] for k, v in scheduler.exits.items()}, exits={k: v[1] for k, v in scheduler.exits.items()},
data=astcompiler.data + [0]*(max_reg - len(astcompiler.data) + 1), data=astcompiler.data + [0]*(max_reg - len(astcompiler.data) + 1),
glbs=astcompiler.globals) glbs=astcompiler.globals)
@ -355,11 +362,11 @@ class CopyUnit(BaseUnit):
class InputUnit(BaseUnit): class InputUnit(BaseUnit):
def __init__(self, data_width, input_stb, input): def __init__(self, data_width, input_stb, input):
BaseUnit.__init__(self, data_width) BaseUnit.__init__(self, data_width)
self.buffer = Signal(data_width)
# TODO
self.comb += [ self.comb += [
self.stb_o.eq(self.stb_i), self.stb_o.eq(self.stb_i),
self.o.eq(42) self.o.eq(self.buffer)
] ]
@ -381,6 +388,8 @@ class ProcessorImpl(Module):
self.output_stb = Signal() self.output_stb = Signal()
self.output = Signal(pd.data_width) self.output = Signal(pd.data_width)
self.busy = Signal()
# # # # # #
program_mem = Memory(pd.instruction_bits(), pd.program_rom_size, init=program) program_mem = Memory(pd.instruction_bits(), pd.program_rom_size, init=program)
@ -403,9 +412,6 @@ class ProcessorImpl(Module):
self.specials += program_mem_port self.specials += program_mem_port
self.comb += program_mem_port.adr.eq(pc_next) self.comb += program_mem_port.adr.eq(pc_next)
# TODO
self.comb += pc_en.eq(1)
s = 0 s = 0
opcode = Signal(pd.opcode_bits) opcode = Signal(pd.opcode_bits)
self.comb += opcode.eq(program_mem_port.dat_r[s:s+pd.opcode_bits]) self.comb += opcode.eq(program_mem_port.dat_r[s:s+pd.opcode_bits])
@ -448,7 +454,7 @@ class ProcessorImpl(Module):
self.submodules += units self.submodules += units
for n, unit in enumerate(units): for n, unit in enumerate(units):
self.sync += unit.stb_i.eq(opcode == n) self.sync += unit.stb_i.eq(pc_en & (opcode == n))
self.comb += [ self.comb += [
unit.i0.eq(data_read_port0.dat_r), unit.i0.eq(data_read_port0.dat_r),
unit.i1.eq(data_read_port1.dat_r), unit.i1.eq(data_read_port1.dat_r),
@ -458,6 +464,22 @@ class ProcessorImpl(Module):
) )
] ]
fsm = FSM()
self.submodules += fsm
fsm.act("IDLE",
pc_en.eq(0),
NextValue(inu.buffer, self.input),
If(self.input_stb, NextState("PROCESSING"))
)
fsm.act("PROCESSING",
self.busy.eq(1),
pc_en.eq(1),
If(opcode == EndIsn.opcode,
pc_en.eq(0),
NextState("IDLE")
)
)
a = 0 a = 0
b = 0 b = 0
@ -472,8 +494,7 @@ def foo(x):
def simple_test(x): def simple_test(x):
a = 5 + 3 return x*2+2
return a*4
if __name__ == "__main__": if __name__ == "__main__":
@ -484,9 +505,22 @@ if __name__ == "__main__":
print(cp.encode()) print(cp.encode())
proc_impl = proc.implement(cp.encode(), cp.data) proc_impl = proc.implement(cp.encode(), cp.data)
def wait_result(): def send_values(values):
for value in values:
yield proc_impl.input.eq(value)
yield proc_impl.input_stb.eq(1)
yield
yield proc_impl.input.eq(0)
yield proc_impl.input_stb.eq(0)
yield
while (yield proc_impl.busy):
yield
@passive
def receive_values(callback):
while True:
while not (yield proc_impl.output_stb): while not (yield proc_impl.output_stb):
yield yield
result = yield proc_impl.output callback((yield proc_impl.output))
print(result) yield
run_simulation(proc_impl, [wait_result()], vcd_name="test.vcd")
run_simulation(proc_impl, [send_values([42, 40]), receive_values(print)])