"""
return [self.i_valid.eq(prev.i_valid),
prev.o_ready.eq(self.o_ready),
- eq(self.data, prev.data),
+ eq(self.i_data, prev.i_data),
]
"""
return [nxt.i_valid.eq(self.o_valid),
self.i_ready.eq(nxt.o_ready),
- eq(nxt.data, self.data),
+ eq(nxt.i_data, self.o_data),
]
def connect_out(self, nxt):
"""
return [nxt.o_valid.eq(self.o_valid),
self.i_ready.eq(nxt.i_ready),
- eq(nxt.data, self.data),
+ eq(nxt.o_data, self.o_data),
]
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 >>in stage n.data out>> stage+1
+ stage-1 p.i_data >>in stage n.o_data out>> stage+1
| |
process --->----^
| |
+-- r_data ->-+
- input data p.data is read (only), is processed and goes into an
+ input data p.i_data is read (only), is processed and goes into an
intermediate result store [process()]. this is updated combinatorially.
in a non-stall condition, the intermediate result will go into the
* ispec: returns output signals to the output specification
* process: takes an input instance and returns processed data
- p.data -> process() -> result --> n.data
- | ^
- | |
- +-> r_data -+
+ p.i_data -> process() -> result --> n.o_data
+ | ^
+ | |
+ +-> r_data -+
"""
self.stage = stage
self.n = NextControl()
# set up the input and output data
- self.p.data = stage.ispec() # input type
- self.r_data = stage.ospec() # all these are output type
- self.result = stage.ospec()
- self.n.data = stage.ospec()
+ self.p.i_data = stage.ispec() # input type
+ self.r_data = stage.ospec() # all these are output type
+ self.result = stage.ospec()
+ self.n.o_data = stage.ospec()
def connect_to_next(self, nxt):
""" helper function to connect to the next stage data/valid/ready.
def set_input(self, i):
""" helper function to set the input data
"""
- return eq(self.p.data, i)
+ return eq(self.p.i_data, i)
def update_buffer(self):
""" copies the result into the intermediate register r_data,
def update_output(self):
""" copies the (combinatorial) result into the output
"""
- return eq(self.n.data, self.result)
+ return eq(self.n.o_data, self.result)
def flush_buffer(self):
""" copies the *intermediate* register r_data into the output
"""
- return eq(self.n.data, self.r_data)
+ return eq(self.n.o_data, self.r_data)
def ports(self):
- return [self.p.data, self.n.data]
+ return [self.p.i_data, self.n.o_data]
def elaborate(self, platform):
m = Module()
if hasattr(self.stage, "setup"):
- self.stage.setup(m, self.p.data)
+ self.stage.setup(m, self.p.i_data)
# establish some combinatorial temporaries
o_n_validn = Signal(reset_less=True)
# store result of processing in combinatorial temporary
with m.If(self.p.i_valid): # input is valid: process it
- m.d.comb += eq(self.result, self.stage.process(self.p.data))
+ m.d.comb += eq(self.result, self.stage.process(self.p.i_data))
# if not in stall condition, update the temporary register
with m.If(self.p.o_ready): # not stalled
m.d.sync += self.update_buffer()
self.n = NextControl()
# set up the input and output data
- self.p.data = stage.ispec() # input type
+ self.p.i_data = stage.ispec() # input type
self.r_data = stage.ispec() # input type
self.result = stage.ospec() # output data
- self.n.data = stage.ospec() # output type
- self.n.data.name = "outdata"
+ self.n.o_data = stage.ospec() # output type
+ self.n.o_data.name = "outdata"
def set_input(self, i):
""" helper function to set the input data
"""
- return eq(self.p.data, i)
+ return eq(self.p.i_data, i)
def elaborate(self, platform):
m = Module()
m.d.sync += self._data_valid.eq(self.p.i_valid | \
(~self.n.i_ready & self._data_valid))
with m.If(self.p.i_valid & self.p.o_ready):
- m.d.sync += eq(self.r_data, self.p.data)
- m.d.comb += eq(self.n.data, self.result)
+ m.d.sync += eq(self.r_data, self.p.i_data)
+ m.d.comb += eq(self.n.o_data, self.result)
return m
def ports(self):
- return [self.p.data, self.n.data]
+ return [self.p.i_data, self.n.o_data]
class ExampleCombPipe(CombPipe):
yield
#yield dut.i_p_rst.eq(0)
yield dut.n.i_ready.eq(1)
- yield dut.p.data.eq(5)
+ yield dut.p.i_data.eq(5)
yield dut.p.i_valid.eq(1)
yield
- yield dut.p.data.eq(7)
+ yield dut.p.i_data.eq(7)
yield from check_o_n_valid(dut, 0) # effects of i_p_valid delayed
yield
yield from check_o_n_valid(dut, 1) # ok *now* i_p_valid effect is felt
- yield dut.p.data.eq(2)
+ yield dut.p.i_data.eq(2)
yield
yield dut.n.i_ready.eq(0) # begin going into "stall" (next stage says ready)
- yield dut.p.data.eq(9)
+ yield dut.p.i_data.eq(9)
yield
yield dut.p.i_valid.eq(0)
- yield dut.p.data.eq(12)
+ yield dut.p.i_data.eq(12)
yield
- yield dut.p.data.eq(32)
+ yield dut.p.i_data.eq(32)
yield dut.n.i_ready.eq(1)
yield
yield from check_o_n_valid(dut, 1) # buffer still needs to output
yield
#yield dut.p.i_rst.eq(0)
yield dut.n.i_ready.eq(1)
- yield dut.p.data.eq(5)
+ yield dut.p.i_data.eq(5)
yield dut.p.i_valid.eq(1)
yield
- yield dut.p.data.eq(7)
+ yield dut.p.i_data.eq(7)
yield from check_o_n_valid(dut, 0) # effects of i_p_valid delayed 2 clocks
yield
yield from check_o_n_valid(dut, 0) # effects of i_p_valid delayed 2 clocks
- yield dut.p.data.eq(2)
+ yield dut.p.i_data.eq(2)
yield
yield from check_o_n_valid(dut, 1) # ok *now* i_p_valid effect is felt
yield dut.n.i_ready.eq(0) # begin going into "stall" (next stage says ready)
- yield dut.p.data.eq(9)
+ yield dut.p.i_data.eq(9)
yield
yield dut.p.i_valid.eq(0)
- yield dut.p.data.eq(12)
+ yield dut.p.i_data.eq(12)
yield
- yield dut.p.data.eq(32)
+ yield dut.p.i_data.eq(32)
yield dut.n.i_ready.eq(1)
yield
yield from check_o_n_valid(dut, 1) # buffer still needs to output
continue
if send and self.i != len(self.data):
yield self.dut.p.i_valid.eq(1)
- yield self.dut.p.data.eq(self.data[self.i])
+ yield self.dut.p.i_data.eq(self.data[self.i])
self.i += 1
else:
yield self.dut.p.i_valid.eq(0)
i_n_ready = yield self.dut.n.i_ready
if not o_n_valid or not i_n_ready:
continue
- o_data = yield self.dut.n.data
+ o_data = yield self.dut.n.o_data
self.resultfn(o_data, self.data[self.o], self.i, self.o)
self.o += 1
if self.o == len(self.data):
i_n_ready = yield self.dut.n.i_ready
if not o_n_valid or not i_n_ready:
continue
- o_data = yield self.dut.n.data
+ o_data = yield self.dut.n.o_data
self.resultfn(o_data, self.data[self.o], self.i, self.o)
self.o += 1
if self.o == len(self.data):
if o_p_ready:
if send and i != len(data):
yield dut.p.i_valid.eq(1)
- yield dut.p.data.eq(data[i])
+ yield dut.p.i_data.eq(data[i])
i += 1
else:
yield dut.p.i_valid.eq(0)
o_n_valid = yield dut.n.o_valid
i_n_ready = yield dut.n.i_ready
if o_n_valid and i_n_ready:
- o_data = yield dut.n.data
+ o_data = yield dut.n.o_data
assert o_data == data[o] + 2, "%d-%d data %x not match %x\n" \
% (i, o, o_data, data[o])
o += 1
v v
i_p_valid >>in pipe1 o_n_valid out>> i_p_valid >>in pipe2
o_p_ready <<out pipe1 i_n_ready <<in o_p_ready <<out pipe2
- p_data >>in pipe1 o_data out>> p_data >>in pipe2
+ p_i_data >>in pipe1 p_i_data out>> n_o_data >>in pipe2
"""
def __init__(self):
self.pipe1 = ExampleBufPipe()
# input
self.p = PrevControl()
- self.p.data = Signal(32) # >>in - comes in from the PREVIOUS stage
+ self.p.i_data = Signal(32) # >>in - comes in from the PREVIOUS stage
# output
self.n = NextControl()
- self.n.data = Signal(32) # out>> - goes out to the NEXT stage
+ self.n.o_data = Signal(32) # out>> - goes out to the NEXT stage
def elaborate(self, platform):
m = Module()