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
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):
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
# 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")