From 289c5cf9f7510a9e9bc3239155db27bdbd982e70 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 11 Mar 2019 19:09:39 +0000 Subject: [PATCH] get InputGroup running --- src/add/nmigen_add_experiment.py | 21 ++++++-- src/add/test_inputgroup.py | 83 +++++++++++++++++++++++--------- 2 files changed, 79 insertions(+), 25 deletions(-) diff --git a/src/add/nmigen_add_experiment.py b/src/add/nmigen_add_experiment.py index 660b0794..f53037d1 100644 --- a/src/add/nmigen_add_experiment.py +++ b/src/add/nmigen_add_experiment.py @@ -98,6 +98,7 @@ class InputGroup: pe = PriorityEncoder(self.num_rows) m.submodules.selector = pe m.submodules.out_op = self.out_op + m.submodules.out_op_v = self.out_op.v m.submodules += self.rs # connect priority encoder @@ -105,12 +106,26 @@ class InputGroup: for i in range(self.num_rows): in_ready.append(self.rs[i].ready) m.d.comb += pe.i.eq(Cat(*in_ready)) - m.d.comb += self.out_op.stb.eq(~pe.n) # strobe-out when encoder active - with m.If(self.out_op.trigger): + active = Signal(reset_less=True) + out_en = Signal(reset_less=True) + m.d.comb += active.eq(~pe.n) # encoder active + m.d.comb += out_en.eq(active & self.out_op.trigger) + + # encoder active: ack relevant input, record MID, pass output + with m.If(out_en): + rs = self.rs[pe.o] m.d.sync += self.mid.eq(pe.o) + m.d.sync += rs.ack.eq(0) + m.d.sync += self.out_op.stb.eq(0) for j in range(self.num_ops): - m.d.sync += self.out_op.v[j].eq(self.rs[pe.o].out_op[j]) + m.d.sync += self.out_op.v[j].eq(rs.out_op[j]) + with m.Else(): + m.d.sync += self.out_op.stb.eq(1) + # acks all default to zero + for i in range(self.num_rows): + m.d.sync += self.rs[i].ack.eq(1) + return m def ports(self): diff --git a/src/add/test_inputgroup.py b/src/add/test_inputgroup.py index c4be8004..ca8523dd 100644 --- a/src/add/test_inputgroup.py +++ b/src/add/test_inputgroup.py @@ -1,7 +1,7 @@ from random import randint from nmigen import Module, Signal from nmigen.compat.sim import run_simulation -from nmigen.cli import verilog +from nmigen.cli import verilog, rtlil from nmigen_add_experiment import InputGroup @@ -15,54 +15,93 @@ def testbench(dut): # set row 1 input 0 yield dut.rs[1].in_op[0].eq(5) yield dut.rs[1].stb.eq(0b01) # strobe indicate 1st op ready - yield dut.rs[1].ack.eq(1) - yield + #yield dut.rs[1].ack.eq(1) yield # check row 1 output (should be inactive) decode = yield dut.rs[1].out_decode assert decode == 0 - op0 = yield dut.rs[1].out_op[0] - op1 = yield dut.rs[1].out_op[1] - assert op0 == 0 and op1 == 0 + if False: + op0 = yield dut.rs[1].out_op[0] + op1 = yield dut.rs[1].out_op[1] + assert op0 == 0 and op1 == 0 # output should be inactive out_stb = yield dut.out_op.stb - assert out_stb == 0 + assert out_stb == 1 # set row 0 input 1 yield dut.rs[1].in_op[1].eq(6) yield dut.rs[1].stb.eq(0b11) # strobe indicate both ops ready - yield - yield - # row 0 output should be active - decode = yield dut.rs[1].out_decode - assert decode == 1 - op0 = yield dut.rs[1].out_op[0] - op1 = yield dut.rs[1].out_op[1] - assert op0 == 5 and op1 == 6 + # set acknowledgement of output... takes 1 cycle to respond + yield dut.out_op.ack.eq(1) + yield + yield dut.out_op.ack.eq(0) # clear ack on output + yield dut.rs[1].stb.eq(0) # clear row 1 strobe - # output should be active, MID should be 0 until "ack" is set + # output strobe should be active, MID should be 0 until "ack" is set... out_stb = yield dut.out_op.stb assert out_stb == 1 out_mid = yield dut.mid assert out_mid == 0 - yield dut.out_op.ack.eq(1) - yield - yield - yield + # ... and output should not yet be passed through either + op0 = yield dut.out_op.v[0] + op1 = yield dut.out_op.v[1] + assert op0 == 0 and op1 == 0 + + # wait for out_op.ack to activate... + yield dut.rs[1].stb.eq(0b00) # set row 1 strobes to zero yield + # *now* output should be passed through op0 = yield dut.out_op.v[0] op1 = yield dut.out_op.v[1] assert op0 == 5 and op1 == 6 + # set row 2 input + yield dut.rs[2].in_op[0].eq(3) + yield dut.rs[2].in_op[1].eq(4) + yield dut.rs[2].stb.eq(0b11) # strobe indicate 1st op ready + yield dut.out_op.ack.eq(1) # set output ack + yield + yield dut.rs[2].stb.eq(0) # clear row 2 strobe + yield dut.out_op.ack.eq(0) # set output ack + yield + op0 = yield dut.out_op.v[0] + op1 = yield dut.out_op.v[1] + assert op0 == 3 and op1 == 4, "op0 %d op1 %d" % (op0, op1) + out_mid = yield dut.mid + assert out_mid == 2 + + # set row 0 and 3 input + yield dut.rs[0].in_op[0].eq(9) + yield dut.rs[0].in_op[1].eq(8) + yield dut.rs[0].stb.eq(0b11) # strobe indicate 1st op ready + yield dut.rs[3].in_op[0].eq(1) + yield dut.rs[3].in_op[1].eq(2) + yield dut.rs[3].stb.eq(0b11) # strobe indicate 1st op ready + + # set acknowledgement of output... takes 1 cycle to respond + yield dut.out_op.ack.eq(1) + yield + yield dut.rs[0].stb.eq(0) # clear row 1 strobe + yield + out_mid = yield dut.mid + assert out_mid == 0, "out mid %d" % out_mid + + yield + yield dut.rs[3].stb.eq(0) # clear row 1 strobe + yield dut.out_op.ack.eq(0) # clear ack on output + yield + out_mid = yield dut.mid + assert out_mid == 3, "out mid %d" % out_mid + if __name__ == '__main__': dut = InputGroup(width=32) - vl = verilog.convert(dut, ports=dut.ports()) - with open("test_inputgroup.v", "w") as f: + vl = rtlil.convert(dut, ports=dut.ports()) + with open("test_inputgroup.il", "w") as f: f.write(vl) run_simulation(dut, testbench(dut), vcd_name="test_inputgroup.vcd") -- 2.30.2