860f25cb114e2f5920edd69a9c468d3b506c00cc
1 from nmigen
import Module
, Signal
2 from nmigen
.compat
.sim
import run_simulation
3 from example_buf_pipe
import BufPipe
4 from random
import randint
7 def check_o_n_stb(dut
, val
):
8 o_n_stb
= yield dut
.o_n_stb
13 #yield dut.i_p_rst.eq(1)
14 yield dut
.i_n_busy
.eq(1)
15 yield dut
.o_p_busy
.eq(1)
18 #yield dut.i_p_rst.eq(0)
19 yield dut
.i_n_busy
.eq(0)
20 yield dut
.stage
.i_data
.eq(5)
21 yield dut
.i_p_stb
.eq(1)
24 yield dut
.stage
.i_data
.eq(7)
25 yield from check_o_n_stb(dut
, 0) # effects of i_p_stb delayed
27 yield from check_o_n_stb(dut
, 1) # ok *now* i_p_stb effect is felt
29 yield dut
.stage
.i_data
.eq(2)
31 yield dut
.i_n_busy
.eq(1) # begin going into "stall" (next stage says busy)
32 yield dut
.stage
.i_data
.eq(9)
34 yield dut
.i_p_stb
.eq(0)
35 yield dut
.stage
.i_data
.eq(12)
37 yield dut
.stage
.i_data
.eq(32)
38 yield dut
.i_n_busy
.eq(0)
40 yield from check_o_n_stb(dut
, 1) # buffer still needs to output
42 yield from check_o_n_stb(dut
, 1) # buffer still needs to output
44 yield from check_o_n_stb(dut
, 0) # buffer outputted, *now* we're done.
49 #yield dut.i_p_rst.eq(1)
50 yield dut
.i_n_busy
.eq(1)
51 #yield dut.o_p_busy.eq(1)
54 #yield dut.i_p_rst.eq(0)
55 yield dut
.i_n_busy
.eq(0)
56 yield dut
.i_data
.eq(5)
57 yield dut
.i_p_stb
.eq(1)
60 yield dut
.i_data
.eq(7)
61 yield from check_o_n_stb(dut
, 0) # effects of i_p_stb delayed 2 clocks
63 yield from check_o_n_stb(dut
, 0) # effects of i_p_stb delayed 2 clocks
65 yield dut
.i_data
.eq(2)
67 yield from check_o_n_stb(dut
, 1) # ok *now* i_p_stb effect is felt
68 yield dut
.i_n_busy
.eq(1) # begin going into "stall" (next stage says busy)
69 yield dut
.i_data
.eq(9)
71 yield dut
.i_p_stb
.eq(0)
72 yield dut
.i_data
.eq(12)
74 yield dut
.i_data
.eq(32)
75 yield dut
.i_n_busy
.eq(0)
77 yield from check_o_n_stb(dut
, 1) # buffer still needs to output
79 yield from check_o_n_stb(dut
, 1) # buffer still needs to output
81 yield from check_o_n_stb(dut
, 1) # buffer still needs to output
83 yield from check_o_n_stb(dut
, 0) # buffer outputted, *now* we're done.
92 #data.append(randint(0, 1<<16-1))
97 stall
= randint(0, 3) == 0
98 send
= randint(0, 5) != 0
99 yield dut
.i_n_busy
.eq(stall
)
100 o_p_busy
= yield dut
.o_p_busy
102 if send
and i
!= len(data
):
103 yield dut
.i_p_stb
.eq(1)
104 yield dut
.stage
.i_data
.eq(data
[i
])
107 yield dut
.i_p_stb
.eq(0)
109 o_n_stb
= yield dut
.o_n_stb
110 i_n_busy
= yield dut
.i_n_busy
111 if o_n_stb
and not i_n_busy
:
112 o_data
= yield dut
.stage
.o_data
113 assert o_data
== data
[o
] + 1, "%d-%d data %x not match %x\n" \
114 % (i
, o
, o_data
, data
[o
])
122 for i
in range(1000):
123 #data.append(randint(0, 1<<16-1))
128 stall
= randint(0, 3) == 0
129 send
= randint(0, 5) != 0
130 yield dut
.i_n_busy
.eq(stall
)
131 o_p_busy
= yield dut
.o_p_busy
133 if send
and i
!= len(data
):
134 yield dut
.i_p_stb
.eq(1)
135 yield dut
.i_data
.eq(data
[i
])
138 yield dut
.i_p_stb
.eq(0)
140 o_n_stb
= yield dut
.o_n_stb
141 i_n_busy
= yield dut
.i_n_busy
142 if o_n_stb
and not i_n_busy
:
143 o_data
= yield dut
.o_data
144 assert o_data
== data
[o
] + 2, "%d-%d data %x not match %x\n" \
145 % (i
, o
, o_data
, data
[o
])
153 connect these: ------|---------------|
155 i_p_stb >>in pipe1 o_n_stb out>> i_p_stb >>in pipe2
156 o_p_busy <<out pipe1 i_n_busy <<in o_p_busy <<out pipe2
157 stage.i_data >>in pipe1 o_data out>> stage.i_data >>in pipe2
160 self
.pipe1
= BufPipe()
161 self
.pipe2
= BufPipe()
164 self
.i_p_stb
= Signal() # >>in - comes in from PREVIOUS stage
165 self
.i_n_busy
= Signal() # in<< - comes in from the NEXT stage
166 self
.i_data
= Signal(32) # >>in - comes in from the PREVIOUS stage
169 self
.o_n_stb
= Signal() # out>> - goes out to the NEXT stage
170 self
.o_p_busy
= Signal() # <<out - goes out to the PREVIOUS stage
171 self
.o_data
= Signal(32) # out>> - goes out to the NEXT stage
173 def elaborate(self
, platform
):
175 m
.submodules
.pipe1
= self
.pipe1
176 m
.submodules
.pipe2
= self
.pipe2
178 # connect inter-pipe input/output stb/busy/data
179 m
.d
.comb
+= self
.pipe2
.i_p_stb
.eq(self
.pipe1
.o_n_stb
)
180 m
.d
.comb
+= self
.pipe1
.i_n_busy
.eq(self
.pipe2
.o_p_busy
)
181 m
.d
.comb
+= self
.pipe2
.stage
.i_data
.eq(self
.pipe1
.stage
.o_data
)
183 # inputs/outputs to the module: pipe1 connections here (LHS)
184 m
.d
.comb
+= self
.pipe1
.i_p_stb
.eq(self
.i_p_stb
)
185 m
.d
.comb
+= self
.o_p_busy
.eq(self
.pipe1
.o_p_busy
)
186 m
.d
.comb
+= self
.pipe1
.stage
.i_data
.eq(self
.i_data
)
188 # now pipe2 connections (RHS)
189 m
.d
.comb
+= self
.o_n_stb
.eq(self
.pipe2
.o_n_stb
)
190 m
.d
.comb
+= self
.pipe2
.i_n_busy
.eq(self
.i_n_busy
)
191 m
.d
.comb
+= self
.o_data
.eq(self
.pipe2
.stage
.o_data
)
195 if __name__
== '__main__':
197 run_simulation(dut
, testbench(dut
), vcd_name
="test_bufpipe.vcd")
200 run_simulation(dut
, testbench2(dut
), vcd_name
="test_bufpipe2.vcd")
203 run_simulation(dut
, testbench3(dut
), vcd_name
="test_bufpipe3.vcd")
206 run_simulation(dut
, testbench4(dut
), vcd_name
="test_bufpipe4.vcd")