class PrevControl(Elaboratable):
""" contains signals that come *from* the previous stage (both in and out)
- * valid_i: previous stage indicating all incoming data is valid.
+ * i_valid: previous stage indicating all incoming data is valid.
may be a multi-bit signal, where all bits are required
to be asserted to indicate "valid".
- * ready_o: output to next stage indicating readiness to accept data
+ * o_ready: output to next stage indicating readiness to accept data
* data_i : an input - MUST be added by the USER of this class
"""
if maskwid:
self.mask_i = Signal(maskwid) # prev >>in self
self.stop_i = Signal(maskwid) # prev >>in self
- self.valid_i = Signal(i_width, name="p_valid_i") # prev >>in self
- self._ready_o = Signal(name="p_ready_o") # prev <<out self
+ self.i_valid = Signal(i_width, name="p_i_valid") # prev >>in self
+ self._o_ready = Signal(name="p_o_ready") # prev <<out self
self.data_i = None # XXX MUST BE ADDED BY USER
if stage_ctl:
- self.s_ready_o = Signal(name="p_s_o_rdy") # prev <<out self
+ self.s_o_ready = Signal(name="p_s_o_rdy") # prev <<out self
self.trigger = Signal(reset_less=True)
@property
- def ready_o(self):
+ def o_ready(self):
""" public-facing API: indicates (externally) that stage is ready
"""
if self.stage_ctl:
- return self.s_ready_o # set dynamically by stage
- return self._ready_o # return this when not under dynamic control
+ return self.s_o_ready # set dynamically by stage
+ return self._o_ready # return this when not under dynamic control
def _connect_in(self, prev, direct=False, fn=None,
do_data=True, do_stop=True):
""" internal helper function to connect stage to an input source.
do not use to connect stage-to-stage!
"""
- valid_i = prev.valid_i if direct else prev.valid_i_test
- res = [self.valid_i.eq(valid_i),
- prev.ready_o.eq(self.ready_o)]
+ i_valid = prev.i_valid if direct else prev.i_valid_test
+ res = [self.i_valid.eq(i_valid),
+ prev.o_ready.eq(self.o_ready)]
if self.maskwid:
res.append(self.mask_i.eq(prev.mask_i))
if do_stop:
return res + [nmoperator.eq(self.data_i, data_i)]
@property
- def valid_i_test(self):
- vlen = len(self.valid_i)
+ def i_valid_test(self):
+ vlen = len(self.i_valid)
if vlen > 1:
- # multi-bit case: valid only when valid_i is all 1s
- all1s = Const(-1, (len(self.valid_i), False))
- valid_i = (self.valid_i == all1s)
+ # multi-bit case: valid only when i_valid is all 1s
+ all1s = Const(-1, (len(self.i_valid), False))
+ i_valid = (self.i_valid == all1s)
else:
- # single-bit valid_i case
- valid_i = self.valid_i
+ # single-bit i_valid case
+ i_valid = self.i_valid
# when stage indicates not ready, incoming data
# must "appear" to be not ready too
if self.stage_ctl:
- valid_i = valid_i & self.s_ready_o
+ i_valid = i_valid & self.s_o_ready
- return valid_i
+ return i_valid
def elaborate(self, platform):
m = Module()
- m.d.comb += self.trigger.eq(self.valid_i_test & self.ready_o)
+ m.d.comb += self.trigger.eq(self.i_valid_test & self.o_ready)
return m
def eq(self, i):
res = [nmoperator.eq(self.data_i, i.data_i),
- self.ready_o.eq(i.ready_o),
- self.valid_i.eq(i.valid_i)]
+ self.o_ready.eq(i.o_ready),
+ self.i_valid.eq(i.i_valid)]
if self.maskwid:
res.append(self.mask_i.eq(i.mask_i))
return res
def __iter__(self):
- yield self.valid_i
- yield self.ready_o
+ yield self.i_valid
+ yield self.o_ready
if self.maskwid:
yield self.mask_i
yield self.stop_i
class NextControl(Elaboratable):
""" contains the signals that go *to* the next stage (both in and out)
- * valid_o: output indicating to next stage that data is valid
- * ready_i: input from next stage indicating that it can accept data
+ * o_valid: output indicating to next stage that data is valid
+ * i_ready: input from next stage indicating that it can accept data
* data_o : an output - MUST be added by the USER of this class
"""
def __init__(self, stage_ctl=False, maskwid=0):
if maskwid:
self.mask_o = Signal(maskwid) # self out>> next
self.stop_o = Signal(maskwid) # self out>> next
- self.valid_o = Signal(name="n_valid_o") # self out>> next
- self.ready_i = Signal(name="n_ready_i") # self <<in next
+ self.o_valid = Signal(name="n_o_valid") # self out>> next
+ self.i_ready = Signal(name="n_i_ready") # self <<in next
self.data_o = None # XXX MUST BE ADDED BY USER
#if self.stage_ctl:
self.d_valid = Signal(reset=1) # INTERNAL (data valid)
self.trigger = Signal(reset_less=True)
@property
- def ready_i_test(self):
+ def i_ready_test(self):
if self.stage_ctl:
- return self.ready_i & self.d_valid
- return self.ready_i
+ return self.i_ready & self.d_valid
+ return self.i_ready
def connect_to_next(self, nxt, do_data=True, do_stop=True):
""" helper function to connect to the next stage data/valid/ready.
note: a "connect_from_prev" is completely unnecessary: it's
just nxt.connect_to_next(self)
"""
- res = [nxt.valid_i.eq(self.valid_o),
- self.ready_i.eq(nxt.ready_o)]
+ res = [nxt.i_valid.eq(self.o_valid),
+ self.i_ready.eq(nxt.o_ready)]
if self.maskwid:
res.append(nxt.mask_i.eq(self.mask_o))
if do_stop:
""" internal helper function to connect stage to an output source.
do not use to connect stage-to-stage!
"""
- ready_i = nxt.ready_i if direct else nxt.ready_i_test
- res = [nxt.valid_o.eq(self.valid_o),
- self.ready_i.eq(ready_i)]
+ i_ready = nxt.i_ready if direct else nxt.i_ready_test
+ res = [nxt.o_valid.eq(self.o_valid),
+ self.i_ready.eq(i_ready)]
if self.maskwid:
res.append(nxt.mask_o.eq(self.mask_o))
if do_stop:
def elaborate(self, platform):
m = Module()
- m.d.comb += self.trigger.eq(self.ready_i_test & self.valid_o)
+ m.d.comb += self.trigger.eq(self.i_ready_test & self.o_valid)
return m
def __iter__(self):
- yield self.ready_i
- yield self.valid_o
+ yield self.i_ready
+ yield self.o_valid
if self.maskwid:
yield self.mask_o
yield self.stop_o
Multi-output is simple (pretty much identical to UnbufferedPipeline),
and the selection is just a mux. The only proviso (difference) being:
- the outputs not being selected have to have their ready_o signals
+ the outputs not being selected have to have their o_ready signals
DEASSERTED.
https://bugs.libre-soc.org/show_bug.cgi?id=538
self.n_mux.m_id.name = "m_id"
# temporaries
- p_valid_i = Signal(reset_less=True)
+ p_i_valid = 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.n[muxid].ready_i)
- m.d.comb += pv.eq(self.p.valid_i & self.p.ready_o)
+ m.d.comb += p_i_valid.eq(self.p.i_valid_test)
+ #m.d.comb += pv.eq(self.p.i_valid) #& self.n[muxid].i_ready)
+ m.d.comb += pv.eq(self.p.i_valid & self.p.o_ready)
# 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)
+ m.d.comb += self.n[i].o_valid.eq(0)
if self.routemask:
#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)
+ m.d.comb += self.n[muxid].o_valid.eq(pv)
+ m.d.comb += self.p.o_ready.eq(self.n[muxid].i_ready)
else:
- 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))
+ data_valid = self.n[muxid].o_valid
+ m.d.comb += self.p.o_ready.eq(~data_valid | self.n[muxid].i_ready)
+ m.d.comb += data_valid.eq(p_i_valid | \
+ (~self.n[muxid].i_ready & data_valid))
# send data on
# need an array of buffer registers conforming to *input* spec
r_data = []
data_valid = []
- p_valid_i = []
- n_ready_in = []
+ p_i_valid = []
+ n_i_readyn = []
p_len = len(self.p)
for i in range(p_len):
name = 'r_%d' % i
r = _spec(self.stage.ispec, name) # input type
r_data.append(r)
data_valid.append(Signal(name="data_valid", reset_less=True))
- p_valid_i.append(Signal(name="p_valid_i", reset_less=True))
- n_ready_in.append(Signal(name="n_ready_in", reset_less=True))
+ p_i_valid.append(Signal(name="p_i_valid", reset_less=True))
+ n_i_readyn.append(Signal(name="n_i_readyn", 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)
- p_valid_i = Array(p_valid_i)
- n_ready_in = Array(n_ready_in)
+ p_i_valid = Array(p_i_valid)
+ n_i_readyn = Array(n_i_readyn)
data_valid = Array(data_valid)
nirn = Signal(reset_less=True)
- m.d.comb += nirn.eq(~self.n.ready_i)
+ m.d.comb += nirn.eq(~self.n.i_ready)
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)
- m.d.comb += p_valid_i[i].eq(0)
- #m.d.comb += self.p[i].ready_o.eq(~data_valid[i] | self.n.ready_i)
- m.d.comb += self.p[i].ready_o.eq(0)
+ m.d.comb += n_i_readyn[i].eq(1)
+ m.d.comb += p_i_valid[i].eq(0)
+ #m.d.comb += self.p[i].o_ready.eq(~data_valid[i] | self.n.i_ready)
+ m.d.comb += self.p[i].o_ready.eq(0)
p = self.p[mid]
maskedout = Signal(reset_less=True)
if hasattr(p, "mask_i"):
m.d.comb += maskedout.eq(p.mask_i & ~p.stop_i)
else:
m.d.comb += maskedout.eq(1)
- m.d.comb += p_valid_i[mid].eq(maskedout & self.p_mux.active)
- m.d.comb += self.p[mid].ready_o.eq(~data_valid[mid] | self.n.ready_i)
- m.d.comb += n_ready_in[mid].eq(nirn & data_valid[mid])
+ m.d.comb += p_i_valid[mid].eq(maskedout & self.p_mux.active)
+ m.d.comb += self.p[mid].o_ready.eq(~data_valid[mid] | self.n.i_ready)
+ m.d.comb += n_i_readyn[mid].eq(nirn & data_valid[mid])
anyvalid = Signal(i, reset_less=True)
av = []
for i in range(p_len):
av.append(data_valid[i])
anyvalid = Cat(*av)
- m.d.comb += self.n.valid_o.eq(anyvalid.bool())
- m.d.comb += data_valid[mid].eq(p_valid_i[mid] | \
- (n_ready_in[mid] ))
+ m.d.comb += self.n.o_valid.eq(anyvalid.bool())
+ m.d.comb += data_valid[mid].eq(p_i_valid[mid] | \
+ (n_i_readyn[mid] ))
if self.routemask:
# XXX hack - fixes loop
m.d.comb += maskedout.eq(p.mask_i & ~p.stop_i)
else:
m.d.comb += maskedout.eq(1)
- m.d.comb += vr.eq(maskedout.bool() & p.valid_i & p.ready_o)
- #m.d.comb += vr.eq(p.valid_i & p.ready_o)
+ m.d.comb += vr.eq(maskedout.bool() & p.i_valid & p.o_ready)
+ #m.d.comb += vr.eq(p.i_valid & p.o_ready)
with m.If(vr):
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 += maskedout.eq(p.mask_i & ~p.stop_i)
else:
m.d.comb += maskedout.eq(1)
- m.d.comb += vr.eq(maskedout.bool() & p.valid_i & p.ready_o)
+ m.d.comb += vr.eq(maskedout.bool() & p.i_valid & p.o_ready)
with m.If(vr):
m.d.comb += eq(r_data[i], self.p[i].data_i)
if self.maskwid:
# need an array of buffer registers conforming to *input* spec
r_data = []
r_busy = []
- p_valid_i = []
+ p_i_valid = []
p_len = len(self.p)
for i in range(p_len):
name = 'r_%d' % i
r = _spec(self.stage.ispec, name) # input type
r_data.append(r)
r_busy.append(Signal(name="r_busy%d" % i, reset_less=True))
- p_valid_i.append(Signal(name="p_valid_i%d" % i, reset_less=True))
+ p_i_valid.append(Signal(name="p_i_valid%d" % i, 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)
- p_valid_i = Array(p_valid_i)
+ p_i_valid = Array(p_i_valid)
r_busy = Array(r_busy)
nirn = Signal(reset_less=True)
- m.d.comb += nirn.eq(~self.n.ready_i)
+ m.d.comb += nirn.eq(~self.n.i_ready)
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 += r_busy[i].eq(0)
- m.d.comb += n_ready_in[i].eq(1)
- m.d.comb += p_valid_i[i].eq(0)
- m.d.comb += self.p[i].ready_o.eq(n_ready_in[i])
+ m.d.comb += n_i_readyn[i].eq(1)
+ m.d.comb += p_i_valid[i].eq(0)
+ m.d.comb += self.p[i].o_ready.eq(n_i_readyn[i])
p = self.p[mid]
maskedout = Signal(reset_less=True)
if hasattr(p, "mask_i"):
m.d.comb += maskedout.eq(p.mask_i & ~p.stop_i)
else:
m.d.comb += maskedout.eq(1)
- m.d.comb += p_valid_i[mid].eq(maskedout & self.p_mux.active)
- m.d.comb += self.p[mid].ready_o.eq(~data_valid[mid] | self.n.ready_i)
- m.d.comb += n_ready_in[mid].eq(nirn & data_valid[mid])
+ m.d.comb += p_i_valid[mid].eq(maskedout & self.p_mux.active)
+ m.d.comb += self.p[mid].o_ready.eq(~data_valid[mid] | self.n.i_ready)
+ m.d.comb += n_i_readyn[mid].eq(nirn & data_valid[mid])
anyvalid = Signal(i, reset_less=True)
av = []
for i in range(p_len):
av.append(data_valid[i])
anyvalid = Cat(*av)
- m.d.comb += self.n.valid_o.eq(anyvalid.bool())
- m.d.comb += data_valid[mid].eq(p_valid_i[mid] | \
- (n_ready_in[mid] ))
+ m.d.comb += self.n.o_valid.eq(anyvalid.bool())
+ m.d.comb += data_valid[mid].eq(p_i_valid[mid] | \
+ (n_i_readyn[mid] ))
if self.routemask:
# XXX hack - fixes loop
m.d.comb += maskedout.eq(p.mask_i & ~p.stop_i)
else:
m.d.comb += maskedout.eq(1)
- m.d.comb += vr.eq(maskedout.bool() & p.valid_i & p.ready_o)
- #m.d.comb += vr.eq(p.valid_i & p.ready_o)
+ m.d.comb += vr.eq(maskedout.bool() & p.i_valid & p.o_ready)
+ #m.d.comb += vr.eq(p.i_valid & p.o_ready)
with m.If(vr):
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 += maskedout.eq(p.mask_i & ~p.stop_i)
else:
m.d.comb += maskedout.eq(1)
- m.d.comb += vr.eq(maskedout.bool() & p.valid_i & p.ready_o)
+ m.d.comb += vr.eq(maskedout.bool() & p.i_valid & p.o_ready)
with m.If(vr):
m.d.comb += eq(r_data[i], self.p[i].data_i)
if self.maskwid:
# connect priority encoder
in_ready = []
for i in range(self.num_rows):
- p_valid_i = Signal(reset_less=True)
+ p_i_valid = Signal(reset_less=True)
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)
+ m.d.comb += p_i_valid.eq(maskedout.bool() & p.i_valid_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 += p_i_valid.eq(self.pipe.p[i].i_valid_test)
+ in_ready.append(p_i_valid)
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)
m.d.comb += self.m_id.eq(pe.o) # output one active input
# for people familiar with the chisel Decoupled library:
# enq is "enqueue" (data in, aka "prev stage"),
# deq is "dequeue" (data out, aka "next stage")
- p_ready_o = self.w_rdy
- p_valid_i = self.w_en
+ p_o_ready = self.w_rdy
+ p_i_valid = self.w_en
enq_data = self.w_data # aka p_data_i
- n_valid_o = self.r_rdy
- n_ready_i = self.r_en
+ n_o_valid = self.r_rdy
+ n_i_ready = self.r_en
deq_data = self.r_data # aka n_data_o
# intermediaries
deq_max.eq(deq_ptr == self.depth - 1),
empty.eq(ptr_match & ~maybe_full),
full.eq(ptr_match & maybe_full),
- do_enq.eq(p_ready_o & p_valid_i), # write conditions ok
- do_deq.eq(n_ready_i & n_valid_o), # read conditions ok
+ do_enq.eq(p_o_ready & p_i_valid), # write conditions ok
+ do_deq.eq(n_i_ready & n_o_valid), # read conditions ok
# set r_rdy and w_rdy (NOTE: see pipe mode below)
- n_valid_o.eq(~empty), # cannot read if empty!
- p_ready_o.eq(~full), # cannot write if full!
+ n_o_valid.eq(~empty), # cannot read if empty!
+ p_o_ready.eq(~full), # cannot write if full!
# set up memory and connect to input and output
ram_write.addr.eq(enq_ptr),
# this done combinatorially to give the exact same characteristics
# as Memory "write-through"... without relying on a changing API
if self.fwft:
- with m.If(p_valid_i):
- m.d.comb += n_valid_o.eq(1)
+ with m.If(p_i_valid):
+ m.d.comb += n_o_valid.eq(1)
with m.If(empty):
m.d.comb += deq_data.eq(enq_data)
m.d.comb += do_deq.eq(0)
- with m.If(n_ready_i):
+ with m.If(n_i_ready):
m.d.comb += do_enq.eq(0)
# pipe mode: if next stage says it's ready (r_rdy), w_en
# *must* declare the input ready (w_rdy).
if self.pipe:
- with m.If(n_ready_i):
- m.d.comb += p_ready_o.eq(1)
+ with m.If(n_i_ready):
+ m.d.comb += p_o_ready.eq(1)
# set the count (available free space), optimise on power-of-two
if self.depth == 1 << ptr_width: # is depth a power of 2
where data will flow on *every* clock when the conditions are right.
input acceptance conditions are when:
- * incoming previous-stage strobe (p.valid_i) is HIGH
- * outgoing previous-stage ready (p.ready_o) is LOW
+ * incoming previous-stage strobe (p.i_valid) is HIGH
+ * outgoing previous-stage ready (p.o_ready) is LOW
output transmission conditions are when:
- * outgoing next-stage strobe (n.valid_o) is HIGH
- * outgoing next-stage ready (n.ready_i) is LOW
+ * outgoing next-stage strobe (n.o_valid) is HIGH
+ * outgoing next-stage ready (n.i_ready) is LOW
the tricky bit is when the input has valid data and the output is not
ready to accept it. if it wasn't for the clock synchronisation, it
return m
# intercept the previous (outgoing) "ready", combine with stage ready
- m.d.comb += self.p.s_ready_o.eq(self.p._ready_o & self.stage.d_ready)
+ m.d.comb += self.p.s_o_ready.eq(self.p._o_ready & self.stage.d_ready)
# intercept the next (incoming) "ready" and combine it with data valid
- sdv = self.stage.d_valid(self.n.ready_i)
- m.d.comb += self.n.d_valid.eq(self.n.ready_i & sdv)
+ sdv = self.stage.d_valid(self.n.i_ready)
+ m.d.comb += self.n.d_valid.eq(self.n.i_ready & sdv)
return m
Argument: stage. see Stage API above
- stage-1 p.valid_i >>in stage n.valid_o out>> stage+1
- stage-1 p.ready_o <<out stage n.ready_i <<in stage+1
+ stage-1 p.i_valid >>in stage n.o_valid out>> stage+1
+ stage-1 p.o_ready <<out stage n.i_ready <<in stage+1
stage-1 p.data_i >>in stage n.data_o out>> stage+1
| |
process --->----^
# establish some combinatorial temporaries
o_n_validn = Signal(reset_less=True)
- n_ready_i = Signal(reset_less=True, name="n_i_rdy_data")
+ n_i_ready = Signal(reset_less=True, name="n_i_rdy_data")
nir_por = Signal(reset_less=True)
nir_por_n = Signal(reset_less=True)
- p_valid_i = Signal(reset_less=True)
+ p_i_valid = Signal(reset_less=True)
nir_novn = Signal(reset_less=True)
nirn_novn = Signal(reset_less=True)
por_pivn = Signal(reset_less=True)
npnn = Signal(reset_less=True)
- self.m.d.comb += [p_valid_i.eq(self.p.valid_i_test),
- o_n_validn.eq(~self.n.valid_o),
- n_ready_i.eq(self.n.ready_i_test),
- nir_por.eq(n_ready_i & self.p._ready_o),
- nir_por_n.eq(n_ready_i & ~self.p._ready_o),
- nir_novn.eq(n_ready_i | o_n_validn),
- nirn_novn.eq(~n_ready_i & o_n_validn),
+ self.m.d.comb += [p_i_valid.eq(self.p.i_valid_test),
+ o_n_validn.eq(~self.n.o_valid),
+ n_i_ready.eq(self.n.i_ready_test),
+ nir_por.eq(n_i_ready & self.p._o_ready),
+ nir_por_n.eq(n_i_ready & ~self.p._o_ready),
+ nir_novn.eq(n_i_ready | o_n_validn),
+ nirn_novn.eq(~n_i_ready & o_n_validn),
npnn.eq(nir_por | nirn_novn),
- por_pivn.eq(self.p._ready_o & ~p_valid_i)
+ por_pivn.eq(self.p._o_ready & ~p_i_valid)
]
# store result of processing in combinatorial temporary
self.m.d.comb += nmoperator.eq(result, self.data_r)
# if not in stall condition, update the temporary register
- with self.m.If(self.p.ready_o): # not stalled
+ with self.m.If(self.p.o_ready): # not stalled
self.m.d.sync += nmoperator.eq(r_data, result) # update buffer
# data pass-through conditions
with self.m.If(npnn):
data_o = self._postprocess(result) # XXX TBD, does nothing right now
- self.m.d.sync += [self.n.valid_o.eq(p_valid_i), # valid if p_valid
+ self.m.d.sync += [self.n.o_valid.eq(p_i_valid), # valid if p_valid
nmoperator.eq(self.n.data_o, data_o), # update out
]
# buffer flush conditions (NOTE: can override data passthru conditions)
with self.m.If(nir_por_n): # not stalled
# Flush the [already processed] buffer to the output port.
data_o = self._postprocess(r_data) # XXX TBD, does nothing right now
- self.m.d.sync += [self.n.valid_o.eq(1), # reg empty
+ self.m.d.sync += [self.n.o_valid.eq(1), # reg empty
nmoperator.eq(self.n.data_o, data_o), # flush
]
# output ready conditions
- self.m.d.sync += self.p._ready_o.eq(nir_novn | por_pivn)
+ self.m.d.sync += self.p._o_ready.eq(nir_novn | por_pivn)
return self.m
Argument: stage. see Stage API above
- stage-1 p.valid_i >>in stage n.valid_o out>> stage+1
- stage-1 p.ready_o <<out stage n.ready_i <<in stage+1
+ stage-1 p.i_valid >>in stage n.o_valid out>> stage+1
+ stage-1 p.o_ready <<out stage n.i_ready <<in stage+1
stage-1 p.data_i >>in stage n.data_o out>> stage+1
| |
+--process->--^
# a global signal.
# XXX EXCEPTIONAL CIRCUMSTANCES: inspection of the data payload
# is NOT "normal" for the Stage API.
- p_valid_i = Signal(reset_less=True)
+ p_i_valid = Signal(reset_less=True)
#print ("self.p.data_i", self.p.data_i)
maskedout = Signal(len(self.p.mask_i), reset_less=True)
m.d.comb += maskedout.eq(self.p.mask_i & ~self.p.stop_i)
- m.d.comb += p_valid_i.eq(maskedout.bool())
+ m.d.comb += p_i_valid.eq(maskedout.bool())
# if idmask nonzero, mask gets passed on (and register set).
# register is left as-is if idmask is zero, but out-mask is set to zero
# note however: only the *uncancelled* mask bits get passed on
- m.d.sync += self.n.valid_o.eq(p_valid_i)
- m.d.sync += self.n.mask_o.eq(Mux(p_valid_i, maskedout, 0))
- with m.If(p_valid_i):
+ m.d.sync += self.n.o_valid.eq(p_i_valid)
+ m.d.sync += self.n.mask_o.eq(Mux(p_i_valid, maskedout, 0))
+ with m.If(p_i_valid):
data_o = self._postprocess(result) # XXX TBD, does nothing right now
m.d.sync += nmoperator.eq(self.n.data_o, data_o) # update output
# output valid if
# input always "ready"
- #m.d.comb += self.p._ready_o.eq(self.n.ready_i_test)
- m.d.comb += self.p._ready_o.eq(Const(1))
+ #m.d.comb += self.p._o_ready.eq(self.n.i_ready_test)
+ m.d.comb += self.p._o_ready.eq(Const(1))
# always pass on stop (as combinatorial: single signal)
m.d.comb += self.n.stop_o.eq(self.p.stop_i)
USE WITH CARE. will need the entire pipe to be quiescent
before switching, otherwise data WILL be destroyed.
- stage-1 p.valid_i >>in stage n.valid_o out>> stage+1
- stage-1 p.ready_o <<out stage n.ready_i <<in stage+1
+ stage-1 p.i_valid >>in stage n.o_valid out>> stage+1
+ stage-1 p.o_ready <<out stage n.i_ready <<in stage+1
stage-1 p.data_i >>in stage n.data_o out>> stage+1
| |
+--process->--^
# establish if the data should be passed on. cancellation is
# a global signal.
- p_valid_i = Signal(reset_less=True)
+ p_i_valid = Signal(reset_less=True)
#print ("self.p.data_i", self.p.data_i)
maskedout = Signal(len(self.p.mask_i), reset_less=True)
m.d.comb += maskedout.eq(self.p.mask_i & ~self.p.stop_i)
# establish some combinatorial temporaries
- n_ready_i = Signal(reset_less=True, name="n_i_rdy_data")
- p_valid_i_p_ready_o = Signal(reset_less=True)
- m.d.comb += [p_valid_i.eq(self.p.valid_i_test & maskedout.bool()),
- n_ready_i.eq(self.n.ready_i_test),
- p_valid_i_p_ready_o.eq(p_valid_i & self.p.ready_o),
+ n_i_ready = Signal(reset_less=True, name="n_i_rdy_data")
+ p_i_valid_p_o_ready = Signal(reset_less=True)
+ m.d.comb += [p_i_valid.eq(self.p.i_valid_test & maskedout.bool()),
+ n_i_ready.eq(self.n.i_ready_test),
+ p_i_valid_p_o_ready.eq(p_i_valid & self.p.o_ready),
]
# if idmask nonzero, mask gets passed on (and register set).
# register is left as-is if idmask is zero, but out-mask is set to
# zero
# note however: only the *uncancelled* mask bits get passed on
- m.d.sync += mask_r.eq(Mux(p_valid_i, maskedout, 0))
+ m.d.sync += mask_r.eq(Mux(p_i_valid, maskedout, 0))
m.d.comb += self.n.mask_o.eq(mask_r)
# always pass on stop (as combinatorial: single signal)
m.d.comb += self.n.stop_o.eq(self.p.stop_i)
stor = Signal(reset_less=True)
- m.d.comb += stor.eq(p_valid_i_p_ready_o | n_ready_i)
+ m.d.comb += stor.eq(p_i_valid_p_o_ready | n_i_ready)
with m.If(stor):
# store result of processing in combinatorial temporary
m.d.sync += nmoperator.eq(r_latch, data_r)
# previous valid and ready
- with m.If(p_valid_i_p_ready_o):
+ with m.If(p_i_valid_p_o_ready):
m.d.sync += r_busy.eq(1) # output valid
# previous invalid or not ready, however next is accepting
- with m.Elif(n_ready_i):
+ with m.Elif(n_i_ready):
m.d.sync += r_busy.eq(0) # ...so set output invalid
# output set combinatorially from latch
m.d.comb += nmoperator.eq(self.n.data_o, r_latch)
- m.d.comb += self.n.valid_o.eq(r_busy)
+ m.d.comb += self.n.o_valid.eq(r_busy)
# if next is ready, so is previous
- m.d.comb += self.p._ready_o.eq(n_ready_i)
+ m.d.comb += self.p._o_ready.eq(n_i_ready)
with m.Else():
# pass everything straight through. p connected to n: data,
# StageChain: MaskCancellable is doing "nothing" except
# combinatorially passing everything through
# (except now it's *dynamically selectable* whether to do that)
- m.d.comb += self.n.valid_o.eq(self.p.valid_i_test)
- m.d.comb += self.p._ready_o.eq(self.n.ready_i_test)
+ m.d.comb += self.n.o_valid.eq(self.p.i_valid_test)
+ m.d.comb += self.p._o_ready.eq(self.n.i_ready_test)
m.d.comb += self.n.stop_o.eq(self.p.stop_i)
m.d.comb += self.n.mask_o.eq(self.p.mask_i)
m.d.comb += nmoperator.eq(self.n.data_o, data_r)
Argument: stage. see Stage API above
- stage-1 p.valid_i >>in stage n.valid_o out>> stage+1
- stage-1 p.ready_o <<out stage n.ready_i <<in stage+1
+ stage-1 p.i_valid >>in stage n.o_valid out>> stage+1
+ stage-1 p.o_ready <<out stage n.i_ready <<in stage+1
stage-1 p.data_i >>in stage n.data_o out>> stage+1
| |
+--process->--^
result = _spec(self.stage.ospec, "r_tmp")
# establish some combinatorial temporaries
- n_ready_i = Signal(reset_less=True, name="n_i_rdy_data")
- p_valid_i_p_ready_o = Signal(reset_less=True)
- p_valid_i = Signal(reset_less=True)
- m.d.comb += [p_valid_i.eq(self.p.valid_i_test),
- n_ready_i.eq(self.n.ready_i_test),
- p_valid_i_p_ready_o.eq(p_valid_i & self.p.ready_o),
+ n_i_ready = Signal(reset_less=True, name="n_i_rdy_data")
+ p_i_valid_p_o_ready = Signal(reset_less=True)
+ p_i_valid = Signal(reset_less=True)
+ m.d.comb += [p_i_valid.eq(self.p.i_valid_test),
+ n_i_ready.eq(self.n.i_ready_test),
+ p_i_valid_p_o_ready.eq(p_i_valid & self.p.o_ready),
]
# store result of processing in combinatorial temporary
m.d.comb += nmoperator.eq(result, self.data_r)
# previous valid and ready
- with m.If(p_valid_i_p_ready_o):
+ with m.If(p_i_valid_p_o_ready):
data_o = self._postprocess(result) # XXX TBD, does nothing right now
m.d.sync += [r_busy.eq(1), # output valid
nmoperator.eq(self.n.data_o, data_o), # update output
]
# previous invalid or not ready, however next is accepting
- with m.Elif(n_ready_i):
+ with m.Elif(n_i_ready):
data_o = self._postprocess(result) # XXX TBD, does nothing right now
m.d.sync += [nmoperator.eq(self.n.data_o, data_o)]
# TODO: could still send data here (if there was any)
- #m.d.sync += self.n.valid_o.eq(0) # ...so set output invalid
+ #m.d.sync += self.n.o_valid.eq(0) # ...so set output invalid
m.d.sync += r_busy.eq(0) # ...so set output invalid
- m.d.comb += self.n.valid_o.eq(r_busy)
+ m.d.comb += self.n.o_valid.eq(r_busy)
# if next is ready, so is previous
- m.d.comb += self.p._ready_o.eq(n_ready_i)
+ m.d.comb += self.p._o_ready.eq(n_i_ready)
return self.m
Argument: stage. see Stage API, above
- stage-1 p.valid_i >>in stage n.valid_o out>> stage+1
- stage-1 p.ready_o <<out stage n.ready_i <<in stage+1
+ stage-1 p.i_valid >>in stage n.o_valid out>> stage+1
+ stage-1 p.o_ready <<out stage n.i_ready <<in stage+1
stage-1 p.data_i >>in stage n.data_o out>> stage+1
| |
r_data result
r_data = _spec(self.stage.ospec, "r_tmp") # output type
# some temporaries
- p_valid_i = Signal(reset_less=True)
+ p_i_valid = Signal(reset_less=True)
pv = Signal(reset_less=True)
buf_full = 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 += buf_full.eq(~self.n.ready_i_test & data_valid)
+ m.d.comb += p_i_valid.eq(self.p.i_valid_test)
+ m.d.comb += pv.eq(self.p.i_valid & self.p.o_ready)
+ m.d.comb += buf_full.eq(~self.n.i_ready_test & data_valid)
- m.d.comb += self.n.valid_o.eq(data_valid)
- m.d.comb += self.p._ready_o.eq(~data_valid | self.n.ready_i_test)
- m.d.sync += data_valid.eq(p_valid_i | buf_full)
+ m.d.comb += self.n.o_valid.eq(data_valid)
+ m.d.comb += self.p._o_ready.eq(~data_valid | self.n.i_ready_test)
+ m.d.sync += data_valid.eq(p_i_valid | buf_full)
with m.If(pv):
m.d.sync += nmoperator.eq(r_data, self.data_r)
Argument: stage. see Stage API, above
- stage-1 p.valid_i >>in stage n.valid_o out>> stage+1
- stage-1 p.ready_o <<out stage n.ready_i <<in stage+1
+ stage-1 p.i_valid >>in stage n.o_valid out>> stage+1
+ stage-1 p.o_ready <<out stage n.i_ready <<in stage+1
stage-1 p.data_i >>in stage n.data_o out>> stage+1
| | |
+- process-> buf <-+
buf = _spec(self.stage.ospec, "r_tmp") # output type
# some temporaries
- p_valid_i = Signal(reset_less=True)
- m.d.comb += p_valid_i.eq(self.p.valid_i_test)
+ p_i_valid = Signal(reset_less=True)
+ m.d.comb += p_i_valid.eq(self.p.i_valid_test)
- m.d.comb += self.n.valid_o.eq(buf_full | p_valid_i)
- m.d.comb += self.p._ready_o.eq(~buf_full)
- m.d.sync += buf_full.eq(~self.n.ready_i_test & self.n.valid_o)
+ m.d.comb += self.n.o_valid.eq(buf_full | p_i_valid)
+ m.d.comb += self.p._o_ready.eq(~buf_full)
+ m.d.sync += buf_full.eq(~self.n.i_ready_test & self.n.o_valid)
data_o = Mux(buf_full, buf, self.data_r)
data_o = self._postprocess(data_o) # XXX TBD, does nothing right now
r_data = _spec(self.stage.ospec, "r_tmp") # output type
# temporaries
- p_valid_i = Signal(reset_less=True)
+ p_i_valid = Signal(reset_less=True)
pvr = Signal(reset_less=True)
- m.d.comb += p_valid_i.eq(self.p.valid_i_test)
- m.d.comb += pvr.eq(p_valid_i & self.p.ready_o)
+ m.d.comb += p_i_valid.eq(self.p.i_valid_test)
+ m.d.comb += pvr.eq(p_i_valid & self.p.o_ready)
- m.d.comb += self.p.ready_o.eq(~self.n.valid_o | self.n.ready_i_test)
- m.d.sync += self.n.valid_o.eq(p_valid_i | ~self.p.ready_o)
+ m.d.comb += self.p.o_ready.eq(~self.n.o_valid | self.n.i_ready_test)
+ m.d.sync += self.n.o_valid.eq(p_i_valid | ~self.p.o_ready)
odata = Mux(pvr, self.data_r, r_data)
m.d.sync += nmoperator.eq(r_data, odata)
class RegisterPipeline(UnbufferedPipeline):
""" A pipeline stage that delays by one clock cycle, creating a
- sync'd latch out of data_o and valid_o as an indirect byproduct
+ sync'd latch out of data_o and o_valid as an indirect byproduct
of using PassThroughStage
"""
def __init__(self, iospecfn):
## prev: make the FIFO (Queue object) "look" like a PrevControl...
m.submodules.fp = fp = PrevControl()
- fp.valid_i, fp._ready_o, fp.data_i = fifo.w_en, fifo.w_rdy, fifo.w_data
+ fp.i_valid, fp._o_ready, fp.data_i = fifo.w_en, fifo.w_rdy, fifo.w_data
m.d.comb += fp._connect_in(self.p, fn=processfn)
# next: make the FIFO (Queue object) "look" like a NextControl...
m.submodules.fn = fn = NextControl()
- fn.valid_o, fn.ready_i, fn.data_o = fifo.r_rdy, fifo.r_en, fifo.r_data
+ fn.o_valid, fn.i_ready, fn.data_o = fifo.r_rdy, fifo.r_en, fifo.r_data
connections = fn._connect_out(self.n, fn=nmoperator.cat)
valid_eq, ready_eq, data_o = connections
* ``op__sdir``: shift direction (0 = left, 1 = right)
- * ``p_valid_i`` and ``p_ready_o``: handshake
+ * ``p_i_valid`` and ``p_o_ready``: handshake
* "Next" port:
* ``n_data_o``: shifted value
- * ``n_valid_o`` and ``n_ready_i``: handshake
+ * ``n_o_valid`` and ``n_i_ready``: handshake
"""
def __init__(self, width):
self.width = width
self.p_data_i = Signal(width)
self.p_shift_i = Signal(width)
self.op__sdir = Signal()
- self.p_valid_i = Signal()
- self.p_ready_o = Signal()
+ self.p_i_valid = Signal()
+ self.p_o_ready = Signal()
self.n_data_o = Signal(width)
- self.n_valid_o = Signal()
- self.n_ready_i = Signal()
+ self.n_o_valid = Signal()
+ self.n_i_ready = Signal()
def elaborate(self, _):
m = Module()
with m.FSM():
with m.State("IDLE"):
m.d.comb += [
- # keep p.ready_o active on IDLE
- self.p_ready_o.eq(1),
+ # keep p.o_ready active on IDLE
+ self.p_o_ready.eq(1),
# keep loading the shift register and shift count
load.eq(1),
next_count.eq(self.p_shift_i),
]
# capture the direction bit as well
m.d.sync += direction.eq(self.op__sdir)
- with m.If(self.p_valid_i):
+ with m.If(self.p_i_valid):
# Leave IDLE when data arrives
with m.If(next_count == 0):
# short-circuit for zero shift
# exit when shift counter goes to zero
m.next = "DONE"
with m.State("DONE"):
- # keep n_valid_o active while the data is not accepted
- m.d.comb += self.n_valid_o.eq(1)
- with m.If(self.n_ready_i):
+ # keep n_o_valid active while the data is not accepted
+ m.d.comb += self.n_o_valid.eq(1)
+ with m.If(self.n_i_ready):
# go back to IDLE when the data is accepted
m.next = "IDLE"
yield self.op__sdir
yield self.p_data_i
yield self.p_shift_i
- yield self.p_valid_i
- yield self.p_ready_o
- yield self.n_ready_i
- yield self.n_valid_o
+ yield self.p_i_valid
+ yield self.p_o_ready
+ yield self.n_i_ready
+ yield self.n_o_valid
yield self.n_data_o
def ports(self):
datafmt='dec')
gtkw.trace(dut + "p_shift_i[7:0]", color=style_input,
datafmt='dec')
- gtkw.trace(dut + "p_valid_i", color=style_input)
- gtkw.trace(dut + "p_ready_o", color=style_output)
+ gtkw.trace(dut + "p_i_valid", color=style_input)
+ gtkw.trace(dut + "p_o_ready", color=style_output)
with gtkw.group("debug"):
gtkw.blank("Some debug statements")
# change the displayed name in the panel
with gtkw.group("next port"):
gtkw.trace(dut + "n_data_o[7:0]", color=style_output,
datafmt='dec')
- gtkw.trace(dut + "n_valid_o", color=style_output)
- gtkw.trace(dut + "n_ready_i", color=style_input)
+ gtkw.trace(dut + "n_o_valid", color=style_output)
+ gtkw.trace(dut + "n_i_ready", color=style_input)
def test_shifter():
('op__sdir', 'in'),
('p_data_i[7:0]', 'in'),
('p_shift_i[7:0]', 'in'),
- ('p_valid_i', 'in'),
- ('p_ready_o', 'out'),
+ ('p_i_valid', 'in'),
+ ('p_o_ready', 'out'),
]),
# Signals in a signal group inherit the group attributes.
# In this case, a different module path and color.
]),
('next port', [
('n_data_o[7:0]', 'out'),
- ('n_valid_o', 'out'),
- ('n_ready_i', 'in'),
+ ('n_o_valid', 'out'),
+ ('n_i_ready', 'in'),
]),
]
msg.str = ''
def send(data, shift, direction):
- # present input data and assert valid_i
+ # present input data and assert i_valid
yield dut.p_data_i.eq(data)
yield dut.p_shift_i.eq(shift)
yield dut.op__sdir.eq(direction)
- yield dut.p_valid_i.eq(1)
+ yield dut.p_i_valid.eq(1)
yield
- # wait for p.ready_o to be asserted
- while not (yield dut.p_ready_o):
+ # wait for p.o_ready to be asserted
+ while not (yield dut.p_o_ready):
yield
# show current operation operation
if direction:
# underlying signal
yield msg.eq(0)
yield msg.eq(1)
- # clear input data and negate p.valid_i
- yield dut.p_valid_i.eq(0)
+ # clear input data and negate p.i_valid
+ yield dut.p_i_valid.eq(0)
yield dut.p_data_i.eq(0)
yield dut.p_shift_i.eq(0)
yield dut.op__sdir.eq(0)
def receive(expected):
# signal readiness to receive data
- yield dut.n_ready_i.eq(1)
+ yield dut.n_i_ready.eq(1)
yield
- # wait for n.valid_o to be asserted
- while not (yield dut.n_valid_o):
+ # wait for n.o_valid to be asserted
+ while not (yield dut.n_o_valid):
yield
# read result
result = yield dut.n_data_o
- # negate n.ready_i
- yield dut.n_ready_i.eq(0)
+ # negate n.i_ready
+ yield dut.n_i_ready.eq(0)
# check result
assert result == expected
# finish displaying the current operation
def check_o_n_valid(dut, val):
- o_n_valid = yield dut.n.valid_o
+ o_n_valid = yield dut.n.o_valid
assert o_n_valid == val
def check_o_n_valid2(dut, val):
- o_n_valid = yield dut.n.valid_o
+ o_n_valid = yield dut.n.o_valid
assert o_n_valid == val
def tbench(dut):
# yield dut.i_p_rst.eq(1)
- yield dut.n.ready_i.eq(0)
- # yield dut.p.ready_o.eq(0)
+ yield dut.n.i_ready.eq(0)
+ # yield dut.p.o_ready.eq(0)
yield
yield
# yield dut.i_p_rst.eq(0)
- yield dut.n.ready_i.eq(1)
+ yield dut.n.i_ready.eq(1)
yield dut.p.data_i.eq(5)
- yield dut.p.valid_i.eq(1)
+ yield dut.p.i_valid.eq(1)
yield
yield dut.p.data_i.eq(7)
yield dut.p.data_i.eq(2)
yield
# begin going into "stall" (next stage says ready)
- yield dut.n.ready_i.eq(0)
+ yield dut.n.i_ready.eq(0)
yield dut.p.data_i.eq(9)
yield
- yield dut.p.valid_i.eq(0)
+ yield dut.p.i_valid.eq(0)
yield dut.p.data_i.eq(12)
yield
yield dut.p.data_i.eq(32)
- yield dut.n.ready_i.eq(1)
+ yield dut.n.i_ready.eq(1)
yield
yield from check_o_n_valid(dut, 1) # buffer still needs to output
yield
def tbench2(dut):
# yield dut.p.i_rst.eq(1)
- yield dut.n.ready_i.eq(0)
- # yield dut.p.ready_o.eq(0)
+ yield dut.n.i_ready.eq(0)
+ # yield dut.p.o_ready.eq(0)
yield
yield
# yield dut.p.i_rst.eq(0)
- yield dut.n.ready_i.eq(1)
+ yield dut.n.i_ready.eq(1)
yield dut.p.data_i.eq(5)
- yield dut.p.valid_i.eq(1)
+ yield dut.p.i_valid.eq(1)
yield
yield dut.p.data_i.eq(7)
yield
yield from check_o_n_valid2(dut, 1) # ok *now* i_p_valid effect is felt
# begin going into "stall" (next stage says ready)
- yield dut.n.ready_i.eq(0)
+ yield dut.n.i_ready.eq(0)
yield dut.p.data_i.eq(9)
yield
- yield dut.p.valid_i.eq(0)
+ yield dut.p.i_valid.eq(0)
yield dut.p.data_i.eq(12)
yield
yield dut.p.data_i.eq(32)
- yield dut.n.ready_i.eq(1)
+ yield dut.n.i_ready.eq(1)
yield
yield from check_o_n_valid2(dut, 1) # buffer still needs to output
yield
send = True
else:
send = randint(0, send_range) != 0
- o_p_ready = yield self.dut.p.ready_o
+ o_p_ready = yield self.dut.p.o_ready
if not o_p_ready:
yield
continue
if send and self.i != len(self.data):
- yield self.dut.p.valid_i.eq(1)
+ yield self.dut.p.i_valid.eq(1)
yield self.dut.p.data_i.eq(self.data[self.i])
self.i += 1
else:
- yield self.dut.p.valid_i.eq(0)
+ yield self.dut.p.i_valid.eq(0)
yield
def rcv(self):
stall_range = randint(0, 3)
for j in range(randint(1, 10)):
stall = randint(0, stall_range) != 0
- yield self.dut.n.ready_i.eq(stall)
+ yield self.dut.n.i_ready.eq(stall)
yield
- o_n_valid = yield self.dut.n.valid_o
- i_n_ready = yield self.dut.n.ready_i_test
+ o_n_valid = yield self.dut.n.o_valid
+ i_n_ready = yield self.dut.n.i_ready_test
if not o_n_valid or not i_n_ready:
continue
data_o = yield self.dut.n.data_o
else:
send = randint(0, send_range) != 0
#send = True
- o_p_ready = yield self.dut.p.ready_o
+ o_p_ready = yield self.dut.p.o_ready
if not o_p_ready:
yield
continue
if send and self.i != len(self.data):
- yield self.dut.p.valid_i.eq(1)
+ yield self.dut.p.i_valid.eq(1)
for v in self.dut.set_input(self.data[self.i]):
yield v
self.i += 1
else:
- yield self.dut.p.valid_i.eq(0)
+ yield self.dut.p.i_valid.eq(0)
yield
def rcv(self):
for j in range(randint(1, 10)):
ready = randint(0, stall_range) != 0
#ready = True
- yield self.dut.n.ready_i.eq(ready)
+ yield self.dut.n.i_ready.eq(ready)
yield
- o_n_valid = yield self.dut.n.valid_o
- i_n_ready = yield self.dut.n.ready_i_test
+ o_n_valid = yield self.dut.n.o_valid
+ i_n_ready = yield self.dut.n.i_ready_test
if not o_n_valid or not i_n_ready:
continue
if isinstance(self.dut.n.data_o, Record):
else:
send = randint(0, send_range) != 0
#send = True
- o_p_ready = yield self.dut.p.ready_o
+ o_p_ready = yield self.dut.p.o_ready
if not o_p_ready:
yield
continue
if self.latching:
latchtest = randint(0, 3) == 0
if latchtest:
- yield self.dut.p.valid_i.eq(0)
+ yield self.dut.p.i_valid.eq(0)
yield self.dut.p.mask_i.eq(0)
# wait for pipeline to flush, then invert state
for i in range(10):
if send and self.i != len(self.data):
print("send", self.i, self.data[self.i])
- yield self.dut.p.valid_i.eq(1)
+ yield self.dut.p.i_valid.eq(1)
yield self.dut.p.mask_i.eq(1 << self.i) # XXX TODO
for v in self.dut.set_input(self.data[self.i]):
yield v
self.i += 1
else:
- yield self.dut.p.valid_i.eq(0)
+ yield self.dut.p.i_valid.eq(0)
yield self.dut.p.mask_i.eq(0) # XXX TODO
yield
for j in range(randint(1, 10)):
ready = randint(0, stall_range) != 0
ready = True
- yield self.dut.n.ready_i.eq(ready)
+ yield self.dut.n.i_ready.eq(ready)
yield
- o_n_valid = yield self.dut.n.valid_o
- i_n_ready = yield self.dut.n.ready_i_test
+ o_n_valid = yield self.dut.n.o_valid
+ i_n_ready = yield self.dut.n.i_ready_test
if not o_n_valid or not i_n_ready:
continue
if isinstance(self.dut.n.data_o, Record):
while True:
stall = randint(0, 3) != 0
send = randint(0, 5) != 0
- yield dut.n.ready_i.eq(stall)
- o_p_ready = yield dut.p.ready_o
+ yield dut.n.i_ready.eq(stall)
+ o_p_ready = yield dut.p.o_ready
if o_p_ready:
if send and i != len(data):
- yield dut.p.valid_i.eq(1)
+ yield dut.p.i_valid.eq(1)
yield dut.p.data_i.eq(data[i])
i += 1
else:
- yield dut.p.valid_i.eq(0)
+ yield dut.p.i_valid.eq(0)
yield
- o_n_valid = yield dut.n.valid_o
- i_n_ready = yield dut.n.ready_i_test
+ o_n_valid = yield dut.n.o_valid
+ i_n_ready = yield dut.n.i_ready_test
if o_n_valid and i_n_ready:
data_o = yield dut.n.data_o
assert data_o == data[o] + 2, "%d-%d data %x not match %x\n" \
return (self.count == 1) # | (self.count == 3)
return Const(1)
- def d_valid(self, ready_i):
+ def d_valid(self, i_ready):
""" data is valid at output when this is true
"""
return self.count == self.valid_trigger
maskwid = num_tests
print("test 0")
dut = MaskCancellablePipe(maskwid)
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
dut.p.data_i.ports() + dut.n.data_o.ports()
vl = rtlil.convert(dut, ports=ports)
with open("test_maskchain0.il", "w") as f:
maskwid = 32
print("test 0.1")
dut = MaskCancellableDynamic(maskwid=maskwid)
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] # + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] # + \
#dut.p.data_i.ports() + dut.n.data_o.ports()
vl = rtlil.convert(dut, ports=ports)
with open("test_maskchain0_dynamic.il", "w") as f:
print("test 2")
dut = ExampleBufPipe2()
run_simulation(dut, tbench2(dut), vcd_name="test_bufpipe2.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_bufpipe2.il", "w") as f:
test = Test5(dut, resultfn_6)
run_simulation(dut, [test.send(), test.rcv()], vcd_name="test_ltcomb6.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
list(dut.p.data_i) + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_ltcomb_pipe.il", "w") as f:
dut = ExampleAddRecordPipe()
data = data_dict()
test = Test5(dut, resultfn_7, data=data)
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o,
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready,
dut.p.data_i.src1, dut.p.data_i.src2,
dut.n.data_o.src1, dut.n.data_o.src2]
vl = rtlil.convert(dut, ports=ports)
def test9():
print("test 9")
dut = ExampleBufPipeChain2()
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_bufpipechain2.il", "w") as f:
test = Test5(dut, resultfn_12, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_bufpipe12.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_bufpipe12.il", "w") as f:
test = Test5(dut, resultfn_12, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_unbufpipe13.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_unbufpipe13.il", "w") as f:
test = Test5(dut, resultfn_12, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_bufunbuf15.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_bufunbuf15.il", "w") as f:
test = Test5(dut, resultfn_9, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_bufunbuf16.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_bufunbuf16.il", "w") as f:
test = Test5(dut, resultfn_12, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_unbufpipe17.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_unbufpipe17.il", "w") as f:
test = Test5(dut, resultfn_identical, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_passthru18.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_passthru18.il", "w") as f:
test = Test5(dut, resultfn_9, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_bufpass19.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_bufpass19.il", "w") as f:
data = data_chain1()
test = Test5(dut, resultfn_identical, data=data)
run_simulation(dut, [test.send(), test.rcv()], vcd_name="test_fifo20.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_fifo20.il", "w") as f:
test = Test5(dut, resultfn_12, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_fifopass21.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_fifopass21.il", "w") as f:
test = Test5(dut, resultfn_8, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_addrecord22.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i.op1, dut.p.data_i.op2] + \
[dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
test = Test5(dut, resultfn_8, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_addrecord23.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i.op1, dut.p.data_i.op2] + \
[dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
dut = FIFOTestRecordAddStageControl()
data = data_2op()
test = Test5(dut, resultfn_8, data=data)
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i.op1, dut.p.data_i.op2] + \
[dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
test = Test5(dut, resultfn_9, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_add2pipe25.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_add2pipe25.il", "w") as f:
test = Test5(dut, resultfn_9, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_bufpass997.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_bufpass997.il", "w") as f:
test = Test5(dut, resultfn_9, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_bufpipe14.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_bufpipe14.il", "w") as f:
test = Test5(dut, resultfn_9, data=data)
run_simulation(dut, [test.send(), test.rcv()],
vcd_name="test_bufunbuf999.vcd")
- ports = [dut.p.valid_i, dut.n.ready_i,
- dut.n.valid_o, dut.p.ready_o] + \
+ ports = [dut.p.i_valid, dut.n.i_ready,
+ dut.n.o_valid, dut.p.o_ready] + \
[dut.p.data_i] + [dut.n.data_o]
vl = rtlil.convert(dut, ports=ports)
with open("test_bufunbuf999.il", "w") as f:
for i in range(self.tlen):
op2 = self.di[muxid][i]
rs = self.dut.p[muxid]
- yield rs.valid_i.eq(1)
+ yield rs.i_valid.eq(1)
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
+ o_p_ready = yield rs.o_ready
step_limiter = StepLimiter(10000)
while not o_p_ready:
step_limiter.step()
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
print("send", muxid, i, hex(op2), op2)
self.sent[muxid].append(i)
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
yield rs.mask_i.eq(0)
# wait until it's received
step_limiter = StepLimiter(10000)
for i in range(randint(0, 3)):
yield
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
yield
print("send ended", muxid)
#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 self.dut.n[0].i_ready.eq(stall)
# yield
n = self.dut.n[muxid]
- yield n.ready_i.eq(1)
+ yield n.i_ready.eq(1)
yield
yield rs.stop_i.eq(0) # resets cancel mask
- o_n_valid = yield n.valid_o
- i_n_ready = yield n.ready_i
+ o_n_valid = yield n.o_valid
+ i_n_ready = yield n.i_ready
if not o_n_valid or not i_n_ready:
continue
for i in range(self.tlen):
op2 = self.di[muxid][i]
rs = self.dut.p[muxid]
- yield rs.valid_i.eq(1)
+ yield rs.i_valid.eq(1)
yield rs.data_i.data.eq(op2)
yield rs.data_i.idx.eq(i)
yield rs.data_i.muxid.eq(muxid)
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
while not o_p_ready:
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
print ("send", muxid, i, hex(op2))
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
# wait random period of time before queueing another value
for i in range(randint(0, 3)):
yield
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
yield
print ("send ended", muxid)
#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 self.dut.n[0].i_ready.eq(stall)
# yield
n = self.dut.n[muxid]
- yield n.ready_i.eq(1)
+ yield n.i_ready.eq(1)
yield
- o_n_valid = yield n.valid_o
- i_n_ready = yield n.ready_i
+ o_n_valid = yield n.o_valid
+ i_n_ready = yield n.i_ready
if not o_n_valid or not i_n_ready:
continue
op2 = self.di[i][0]
muxid = self.di[i][1]
rs = dut.p
- yield rs.valid_i.eq(1)
+ yield rs.i_valid.eq(1)
yield rs.data_i.data.eq(op2)
yield rs.data_i.muxid.eq(muxid)
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
while not o_p_ready:
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
print ("send", muxid, i, hex(op2))
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
# wait random period of time before queueing another value
for i in range(randint(0, 3)):
yield
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
class TestMuxOutPipe(CombMuxOutPipe):
for i in range(self.tlen):
op2 = self.di[muxid][i]
rs = self.dut.p[muxid]
- yield rs.valid_i.eq(1)
+ yield rs.i_valid.eq(1)
yield rs.data_i.data.eq(op2)
yield rs.data_i.idx.eq(i)
yield rs.data_i.muxid.eq(muxid)
yield rs.mask_i.eq(1)
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
while not o_p_ready:
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
print ("send", muxid, i, hex(op2), op2)
self.sent[muxid].append(i)
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
yield rs.mask_i.eq(0)
# wait until it's received
while i in self.do[muxid]:
for i in range(randint(0, 3)):
yield
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
yield
print ("send ended", muxid)
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 self.dut.n[0].i_ready.eq(stall)
yield
n = self.dut.n[muxid]
- yield n.ready_i.eq(1)
+ yield n.i_ready.eq(1)
yield
yield rs.stop_i.eq(0) # resets cancel mask
- o_n_valid = yield n.valid_o
- i_n_ready = yield n.ready_i
+ o_n_valid = yield n.o_valid
+ i_n_ready = yield n.i_ready
if not o_n_valid or not i_n_ready:
continue
op2 = self.di[i][0]
muxid = self.di[i][1]
rs = self.dut.p
- yield rs.valid_i.eq(1)
+ yield rs.i_valid.eq(1)
yield rs.data_i.data.eq(op2)
yield rs.data_i.muxid.eq(muxid)
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
while not o_p_ready:
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
print ("send", muxid, i, hex(op2))
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
# wait random period of time before queueing another value
for i in range(randint(0, 3)):
yield
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
def rcv(self, muxid):
out_i = 0
count += 1
assert count != 2000, "timeout: too long"
n = self.dut.n[muxid]
- yield n.ready_i.eq(1)
+ yield n.i_ready.eq(1)
yield
- o_n_valid = yield n.valid_o
- i_n_ready = yield n.ready_i
+ o_n_valid = yield n.o_valid
+ i_n_ready = yield n.i_ready
if not o_n_valid or not i_n_ready:
continue
stall_range = randint(0, 3)
stall = randint(0, stall_range) != 0
if stall:
- yield n.ready_i.eq(0)
+ yield n.i_ready.eq(0)
for i in range(stall_range):
yield
return m
def ports(self):
- res = [self.p.valid_i, self.p.ready_o] + \
+ res = [self.p.i_valid, self.p.o_ready] + \
self.p.data_i.ports()
for i in range(len(self.n)):
- res += [self.n[i].ready_i, self.n[i].valid_o] + \
+ res += [self.n[i].i_ready, self.n[i].o_valid] + \
[self.n[i].data_o]
#self.n[i].data_o.ports()
return res
for i in range(self.tlen):
op2 = self.di[muxid][i]
rs = self.dut.p[muxid]
- yield rs.valid_i.eq(1)
+ yield rs.i_valid.eq(1)
yield rs.data_i.data.eq(op2)
yield rs.data_i.idx.eq(i)
yield rs.data_i.muxid.eq(muxid)
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
step_limiter = StepLimiter(10000)
while not o_p_ready:
step_limiter.step()
yield
- o_p_ready = yield rs.ready_o
+ o_p_ready = yield rs.o_ready
print("send", muxid, i, hex(op2))
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
# wait random period of time before queueing another value
for i in range(randint(0, 3)):
yield
- yield rs.valid_i.eq(0)
+ yield rs.i_valid.eq(0)
# wait random period of time before queueing another value
# for i in range(randint(0, 3)):
# 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 self.dut.n[0].i_ready.eq(stall)
# yield
n = self.dut.n
- yield n.ready_i.eq(1)
+ yield n.i_ready.eq(1)
yield
- o_n_valid = yield n.valid_o
- i_n_ready = yield n.ready_i
+ o_n_valid = yield n.o_valid
+ i_n_ready = yield n.i_ready
if not o_n_valid or not i_n_ready:
continue