p_valid_i = Signal(reset_less=True)
pv = Signal(reset_less=True)
m.d.comb += p_valid_i.eq(self.p.valid_i_test)
- m.d.comb += pv.eq(self.p.valid_i & self.p.ready_o)
+ m.d.comb += pv.eq(self.p.valid_i) #& self.n[muxid].ready_i)
# all outputs to next stages first initialised to zero (invalid)
# the only output "active" is then selected by the muxid
for i in range(len(self.n)):
m.d.comb += self.n[i].valid_o.eq(0)
- data_valid = self.n[muxid].valid_o
- m.d.comb += self.p.ready_o.eq(~data_valid | self.n[muxid].ready_i)
- m.d.comb += data_valid.eq(p_valid_i | \
- (~self.n[muxid].ready_i & data_valid))
+ #with m.If(pv):
+ m.d.comb += self.n[muxid].valid_o.eq(pv)
+ m.d.comb += self.p.ready_o.eq(self.n[muxid].ready_i)
# send data on
- with m.If(pv):
- m.d.comb += eq(r_data, self.p.data_i)
+ #with m.If(pv):
+ m.d.comb += eq(r_data, self.p.data_i)
m.d.comb += eq(self.n[muxid].data_o, self.process(r_data))
if self.maskwid:
if self.routemask: # straight "routing" mode - treat like data
m.d.comb += self.n[muxid].stop_o.eq(self.p.stop_i)
- with m.If(pv):
- m.d.comb += self.n[muxid].mask_o.eq(self.p.mask_i)
+ #with m.If(pv):
+ m.d.comb += self.n[muxid].mask_o.eq(self.p.mask_i)
else:
ml = [] # accumulate output masks
ms = [] # accumulate output stops
p_valid_i.append(Signal(name="p_valid_i", reset_less=True))
n_ready_in.append(Signal(name="n_ready_in", reset_less=True))
if hasattr(self.stage, "setup"):
+ print ("setup", self, self.stage, r)
self.stage.setup(m, r)
if len(r_data) > 1:
r_data = Array(r_data)
nirn = Signal(reset_less=True)
m.d.comb += nirn.eq(~self.n.ready_i)
mid = self.p_mux.m_id
+ print ("CombMuxIn mid", self, self.stage, self.routemask, mid, p_len)
for i in range(p_len):
m.d.comb += data_valid[i].eq(0)
m.d.comb += n_ready_in[i].eq(1)
(n_ready_in[mid] & data_valid[mid]))
if self.routemask:
- m.d.comb += eq(self.n.stop_o, self.p[mid].stop_i)
for i in range(p_len):
- m.d.comb += eq(self.n.stop_o, self.p[i].stop_i)
+ p = self.p[i]
vr = Signal(reset_less=True)
- m.d.comb += vr.eq(self.p[i].valid_i & self.p[i].ready_o)
+ maskedout = Signal(reset_less=True)
+ m.d.comb += maskedout.eq(p.mask_i & ~p.stop_i)
+ m.d.comb += vr.eq(maskedout.bool() & p.valid_i & p.ready_o)
with m.If(vr):
- m.d.comb += eq(self.n.mask_o, self.p[mid].mask_i)
+ m.d.comb += eq(self.n.mask_o, self.p[i].mask_i)
+ m.d.comb += eq(r_data[i], self.p[i].data_i)
+ m.d.comb += eq(self.n.stop_o, self.p[i].stop_i)
else:
ml = [] # accumulate output masks
ms = [] # accumulate output stops
for i in range(p_len):
vr = Signal(reset_less=True)
- m.d.comb += vr.eq(self.p[i].valid_i & self.p[i].ready_o)
+ p = self.p[i]
+ vr = Signal(reset_less=True)
+ maskedout = Signal(reset_less=True)
+ m.d.comb += maskedout.eq(p.mask_i & ~p.stop_i)
+ m.d.comb += vr.eq(maskedout.bool() & p.valid_i & p.ready_o)
with m.If(vr):
m.d.comb += eq(r_data[i], self.p[i].data_i)
if self.maskwid:
in_ready = []
for i in range(self.num_rows):
p_valid_i = Signal(reset_less=True)
- m.d.comb += p_valid_i.eq(self.pipe.p[i].valid_i_test)
+ if self.pipe.maskwid and not self.pipe.routemask:
+ p = self.pipe.p[i]
+ maskedout = Signal(reset_less=True)
+ m.d.comb += maskedout.eq(p.mask_i & ~p.stop_i)
+ m.d.comb += p_valid_i.eq(maskedout.bool() & p.valid_i_test)
+ else:
+ m.d.comb += p_valid_i.eq(self.pipe.p[i].valid_i_test)
in_ready.append(p_valid_i)
m.d.comb += pe.i.eq(Cat(*in_ready)) # array of input "valids"
m.d.comb += self.active.eq(~pe.n) # encoder active (one input valid)
from random import randint
from math import log
-from nmigen import Module, Signal, Cat, Value, Elaboratable
+from nmigen import Module, Signal, Cat, Value, Elaboratable, Const
from nmigen.compat.sim import run_simulation
from nmigen.cli import verilog, rtlil
return PassData()
def ospec(self):
return self.ispec() # same as ospec
- def setup(self, m, i):
+ def _setup(self, m, i):
comb = m.d.comb
#comb += self.o.eq(i)
def process(self, i):
def ispec(self):
return PassData()
def ospec(self):
- return self.ispec() # same as ospec
+ return PassData()
def setup(self, m, i):
comb = m.d.comb
comb += self.o.eq(i)
- with m.If(i.operator == 0):
- #comb += self.o.routeid.eq(1) # selects 2nd output in CombMuxOutPipe
+ with m.If(i.operator == Const(1, 2)):
+ comb += self.o.routeid.eq(1) # selects 2nd output in CombMuxOutPipe
comb += self.o.data.eq(i.data + 1) # add 1 to say "we did it"
- comb += self.o.operator.eq(1) # don't get into infinite loop
+ comb += self.o.operator.eq(2) # don't get into infinite loop
with m.Else():
comb += self.o.routeid.eq(0) # selects 2nd output in CombMuxOutPipe
return self.o
+class DecisionPipe(MaskCancellable):
+ def __init__(self, maskwid):
+ stage = SplitRouteStage()
+ MaskCancellable.__init__(self, stage, maskwid)
+
class RouteBackPipe(CombMuxOutPipe):
""" routes data back to start of pipeline
"""
def __init__(self):
- self.num_rows = 2
- stage = SplitRouteStage()
+ stage = PassThroughStage()
CombMuxOutPipe.__init__(self, stage, n_len=2,
maskwid=4, muxidname="routeid",
routemask=True)
""" merges data coming from end of pipe (with operator now == 1)
"""
def __init__(self):
- self.num_rows = 2
stage = PassThroughStage()
PriorityCombMuxInPipe.__init__(self, stage, p_len=2, maskwid=4,
routemask=True)
yield rs.data_i.data.eq(op2)
yield rs.data_i.idx.eq(i)
yield rs.data_i.muxid.eq(muxid)
+ yield rs.data_i.operator.eq(1)
yield rs.mask_i.eq(1)
yield
o_p_ready = yield rs.ready_o
if len(self.do[muxid]) == 0:
break
- stall_range = randint(0, 3)
- for j in range(randint(1,10)):
- stall = randint(0, stall_range) != 0
- yield self.dut.n[0].ready_i.eq(stall)
- yield
+ #stall_range = randint(0, 3)
+ #for j in range(randint(1,10)):
+ # stall = randint(0, stall_range) != 0
+ # yield self.dut.n[0].ready_i.eq(stall)
+ # yield
n = self.dut.n[muxid]
yield n.ready_i.eq(1)
out_i = yield n.data_o.idx
out_v = yield n.data_o.data
- print ("recv", out_muxid, out_i, hex(out_v), out_v)
+ print ("recv", out_muxid, out_i, hex(out_v), hex(out_v))
# see if this output has occurred already, delete it if it has
assert muxid == out_muxid, \
continue
assert out_i in self.do[muxid], "out_i %d not in array %s" % \
(out_i, repr(self.do[muxid]))
- assert self.do[muxid][out_i] == out_v + 1 # check data
+ assert self.do[muxid][out_i] + 1 == out_v # check data
del self.do[muxid][out_i]
todel = self.sent[muxid].index(out_i)
del self.sent[muxid][todel]
self.inpipe = TestPriorityMuxPipe(nr) # fan-in (combinatorial)
self.mergein = MergeRoutePipe() # merge in feedback
self.pipe1 = PassThroughPipe(nr) # stage 1 (clock-sync)
- self.pipe2 = PassThroughPipe(nr) # stage 2 (clock-sync)
+ self.pipe2 = DecisionPipe(nr) # stage 2 (clock-sync)
#self.pipe3 = PassThroughPipe(nr) # stage 3 (clock-sync)
#self.pipe4 = PassThroughPipe(nr) # stage 4 (clock-sync)
self.splitback = RouteBackPipe() # split back to mergein
self.outpipe = TestMuxOutPipe(nr) # fan-out (combinatorial)
+ self.fifoback = PassThroughPipe(nr) # temp route-back store
self.p = self.inpipe.p # kinda annoying,
self.n = self.outpipe.n # use pipe in/out as this class in/out
#m.submodules.pipe4 = self.pipe4
m.submodules.splitback = self.splitback
m.submodules.outpipe = self.outpipe
+ m.submodules.fifoback = self.fifoback
- m.d.comb += self.inpipe.n.connect_to_next(self.mergein.p[0])
+ m.d.comb += self.inpipe.n.connect_to_next(self.mergein.p[1])
m.d.comb += self.mergein.n.connect_to_next(self.pipe1.p)
m.d.comb += self.pipe1.connect_to_next(self.pipe2)
#m.d.comb += self.pipe2.connect_to_next(self.pipe3)
#m.d.comb += self.pipe3.connect_to_next(self.pipe4)
m.d.comb += self.pipe2.connect_to_next(self.splitback)
- m.d.comb += self.splitback.n[1].connect_to_next(self.mergein.p[1])
+ m.d.comb += self.splitback.n[1].connect_to_next(self.fifoback.p)
+ m.d.comb += self.fifoback.n.connect_to_next(self.mergein.p[0])
m.d.comb += self.splitback.n[0].connect_to_next(self.outpipe.p)
return m
with open("test_inoutmux_feedback_pipe.il", "w") as f:
f.write(vl)
- tlen = 20
+ tlen = 3
test = InputTest(dut, tlen)
- run_simulation(dut, [test.rcv(1), test.rcv(0),
- test.rcv(3), test.rcv(2),
+ run_simulation(dut, [test.rcv(0), test.rcv(1),
+ #test.rcv(3), test.rcv(2),
test.send(0), test.send(1),
- test.send(3), test.send(2),
+ #test.send(3), test.send(2),
],
vcd_name="test_inoutmux_feedback_pipe.vcd")