ae035054a8a3c3478558a004aca1b1665ce09d0e
1 """ Unit tests for Buffered and Unbuffered pipelines
3 contains useful worked examples of how to use the Pipeline API,
6 * Combinatorial Stage "Chaining"
7 * class-based data stages
8 * nmigen module-based data stages
9 * special nmigen module-based data stage, where the stage *is* the module
10 * Record-based data stages
11 * static-class data stages
12 * multi-stage pipelines (and how to connect them)
13 * how to *use* the pipelines (see Test5) - how to get data in and out
17 from nmigen
import Module
, Signal
, Mux
, Const
18 from nmigen
.hdl
.rec
import Record
19 from nmigen
.compat
.sim
import run_simulation
20 from nmigen
.cli
import verilog
, rtlil
22 from example_buf_pipe
import ExampleBufPipe
, ExampleBufPipeAdd
23 from example_buf_pipe
import ExamplePipeline
, UnbufferedPipeline
24 from example_buf_pipe
import ExampleStageCls
25 from example_buf_pipe
import PrevControl
, NextControl
, BufferedPipeline
26 from example_buf_pipe
import StageChain
, ControlBase
, StageCls
27 from singlepipe
import UnbufferedPipeline2
29 from random
import randint
, seed
34 def check_o_n_valid(dut
, val
):
35 o_n_valid
= yield dut
.n
.o_valid
36 assert o_n_valid
== val
38 def check_o_n_valid2(dut
, val
):
39 o_n_valid
= yield dut
.n
.o_valid
40 assert o_n_valid
== val
44 #yield dut.i_p_rst.eq(1)
45 yield dut
.n
.i_ready
.eq(0)
46 yield dut
.p
.o_ready
.eq(0)
49 #yield dut.i_p_rst.eq(0)
50 yield dut
.n
.i_ready
.eq(1)
51 yield dut
.p
.i_data
.eq(5)
52 yield dut
.p
.i_valid
.eq(1)
55 yield dut
.p
.i_data
.eq(7)
56 yield from check_o_n_valid(dut
, 0) # effects of i_p_valid delayed
58 yield from check_o_n_valid(dut
, 1) # ok *now* i_p_valid effect is felt
60 yield dut
.p
.i_data
.eq(2)
62 yield dut
.n
.i_ready
.eq(0) # begin going into "stall" (next stage says ready)
63 yield dut
.p
.i_data
.eq(9)
65 yield dut
.p
.i_valid
.eq(0)
66 yield dut
.p
.i_data
.eq(12)
68 yield dut
.p
.i_data
.eq(32)
69 yield dut
.n
.i_ready
.eq(1)
71 yield from check_o_n_valid(dut
, 1) # buffer still needs to output
73 yield from check_o_n_valid(dut
, 1) # buffer still needs to output
75 yield from check_o_n_valid(dut
, 0) # buffer outputted, *now* we're done.
80 #yield dut.p.i_rst.eq(1)
81 yield dut
.n
.i_ready
.eq(0)
82 #yield dut.p.o_ready.eq(0)
85 #yield dut.p.i_rst.eq(0)
86 yield dut
.n
.i_ready
.eq(1)
87 yield dut
.p
.i_data
.eq(5)
88 yield dut
.p
.i_valid
.eq(1)
91 yield dut
.p
.i_data
.eq(7)
92 yield from check_o_n_valid2(dut
, 0) # effects of i_p_valid delayed 2 clocks
94 yield from check_o_n_valid2(dut
, 0) # effects of i_p_valid delayed 2 clocks
96 yield dut
.p
.i_data
.eq(2)
98 yield from check_o_n_valid2(dut
, 1) # ok *now* i_p_valid effect is felt
99 yield dut
.n
.i_ready
.eq(0) # begin going into "stall" (next stage says ready)
100 yield dut
.p
.i_data
.eq(9)
102 yield dut
.p
.i_valid
.eq(0)
103 yield dut
.p
.i_data
.eq(12)
105 yield dut
.p
.i_data
.eq(32)
106 yield dut
.n
.i_ready
.eq(1)
108 yield from check_o_n_valid2(dut
, 1) # buffer still needs to output
110 yield from check_o_n_valid2(dut
, 1) # buffer still needs to output
112 yield from check_o_n_valid2(dut
, 1) # buffer still needs to output
114 yield from check_o_n_valid2(dut
, 0) # buffer outputted, *now* we're done.
121 def __init__(self
, dut
, resultfn
):
123 self
.resultfn
= resultfn
125 for i
in range(num_tests
):
126 #data.append(randint(0, 1<<16-1))
127 self
.data
.append(i
+1)
132 while self
.o
!= len(self
.data
):
133 send_range
= randint(0, 3)
134 for j
in range(randint(1,10)):
138 send
= randint(0, send_range
) != 0
140 o_p_ready
= yield self
.dut
.p
.o_ready
144 if send
and self
.i
!= len(self
.data
):
145 yield self
.dut
.p
.i_valid
.eq(1)
146 yield self
.dut
.p
.i_data
.eq(self
.data
[self
.i
])
149 yield self
.dut
.p
.i_valid
.eq(0)
153 while self
.o
!= len(self
.data
):
154 stall_range
= randint(0, 3)
155 for j
in range(randint(1,10)):
156 stall
= randint(0, stall_range
) != 0
157 yield self
.dut
.n
.i_ready
.eq(stall
)
159 o_n_valid
= yield self
.dut
.n
.o_valid
160 i_n_ready
= yield self
.dut
.n
.i_ready_test
161 if not o_n_valid
or not i_n_ready
:
163 o_data
= yield self
.dut
.n
.o_data
164 self
.resultfn(o_data
, self
.data
[self
.o
], self
.i
, self
.o
)
166 if self
.o
== len(self
.data
):
169 def test3_resultfn(o_data
, expected
, i
, o
):
170 assert o_data
== expected
+ 1, \
171 "%d-%d data %x not match %x\n" \
172 % (i
, o
, o_data
, expected
)
174 def data_placeholder():
176 for i
in range(num_tests
):
178 d
.src1
= randint(0, 1<<16-1)
179 d
.src2
= randint(0, 1<<16-1)
185 for i
in range(num_tests
):
186 data
.append({'src1': randint(0, 1<<16-1),
187 'src2': randint(0, 1<<16-1)})
192 def __init__(self
, dut
, resultfn
, data
=None, stage_ctl
=False):
194 self
.resultfn
= resultfn
195 self
.stage_ctl
= stage_ctl
200 for i
in range(num_tests
):
201 self
.data
.append((randint(0, 1<<16-1), randint(0, 1<<16-1)))
206 while self
.o
!= len(self
.data
):
207 send_range
= randint(0, 3)
208 for j
in range(randint(1,10)):
212 send
= randint(0, send_range
) != 0
213 o_p_ready
= yield self
.dut
.p
.o_ready
217 if send
and self
.i
!= len(self
.data
):
218 yield self
.dut
.p
.i_valid
.eq(1)
219 for v
in self
.dut
.set_input(self
.data
[self
.i
]):
223 yield self
.dut
.p
.i_valid
.eq(0)
227 while self
.o
!= len(self
.data
):
228 stall_range
= randint(0, 3)
229 for j
in range(randint(1,10)):
230 ready
= randint(0, stall_range
) != 0
232 yield self
.dut
.n
.i_ready
.eq(ready
)
234 o_n_valid
= yield self
.dut
.n
.o_valid
235 i_n_ready
= yield self
.dut
.n
.i_ready_test
236 if not o_n_valid
or not i_n_ready
:
238 if isinstance(self
.dut
.n
.o_data
, Record
):
240 dod
= self
.dut
.n
.o_data
241 for k
, v
in dod
.fields
.items():
244 o_data
= yield self
.dut
.n
.o_data
245 self
.resultfn(o_data
, self
.data
[self
.o
], self
.i
, self
.o
)
247 if self
.o
== len(self
.data
):
250 def test5_resultfn(o_data
, expected
, i
, o
):
251 res
= expected
[0] + expected
[1]
252 assert o_data
== res
, \
253 "%d-%d data %x not match %s\n" \
254 % (i
, o
, o_data
, repr(expected
))
258 for i
in range(num_tests
):
259 #data.append(randint(0, 1<<16-1))
264 stall
= randint(0, 3) != 0
265 send
= randint(0, 5) != 0
266 yield dut
.n
.i_ready
.eq(stall
)
267 o_p_ready
= yield dut
.p
.o_ready
269 if send
and i
!= len(data
):
270 yield dut
.p
.i_valid
.eq(1)
271 yield dut
.p
.i_data
.eq(data
[i
])
274 yield dut
.p
.i_valid
.eq(0)
276 o_n_valid
= yield dut
.n
.o_valid
277 i_n_ready
= yield dut
.n
.i_ready_test
278 if o_n_valid
and i_n_ready
:
279 o_data
= yield dut
.n
.o_data
280 assert o_data
== data
[o
] + 2, "%d-%d data %x not match %x\n" \
281 % (i
, o
, o_data
, data
[o
])
286 ######################################################################
288 ######################################################################
290 class ExampleBufPipe2(ControlBase
):
291 """ Example of how to do chained pipeline stages.
294 def elaborate(self
, platform
):
297 pipe1
= ExampleBufPipe()
298 pipe2
= ExampleBufPipe()
300 m
.submodules
.pipe1
= pipe1
301 m
.submodules
.pipe2
= pipe2
303 m
.d
.comb
+= self
.connect([pipe1
, pipe2
])
308 ######################################################################
310 ######################################################################
312 class ExampleBufPipeChain2(BufferedPipeline
):
313 """ connects two stages together as a *single* combinatorial stage.
316 stage1
= ExampleStageCls()
317 stage2
= ExampleStageCls()
318 combined
= StageChain([stage1
, stage2
])
319 BufferedPipeline
.__init
__(self
, combined
)
324 for i
in range(num_tests
):
325 data
.append(randint(0, 1<<16-2))
329 def test9_resultfn(o_data
, expected
, i
, o
):
331 assert o_data
== res
, \
332 "%d-%d received data %x not match expected %x\n" \
333 % (i
, o
, o_data
, res
)
336 ######################################################################
338 ######################################################################
341 def __init__(self
, width
, signed
):
343 self
.src1
= Signal((width
, signed
), name
="src1")
344 self
.src2
= Signal((width
, signed
), name
="src2")
345 self
.output
= Signal(width
, name
="out")
347 def elaborate(self
, platform
):
348 self
.m
.d
.comb
+= self
.output
.eq(Mux(self
.src1
< self
.src2
, 1, 0))
352 class LTStage(StageCls
):
353 """ module-based stage example
356 self
.slt
= SetLessThan(16, True)
359 return (Signal(16, name
="sig1"), Signal(16, "sig2"))
362 return Signal(16, "out")
364 def setup(self
, m
, i
):
366 m
.submodules
.slt
= self
.slt
367 m
.d
.comb
+= self
.slt
.src1
.eq(i
[0])
368 m
.d
.comb
+= self
.slt
.src2
.eq(i
[1])
369 m
.d
.comb
+= self
.o
.eq(self
.slt
.output
)
371 def process(self
, i
):
375 class LTStageDerived(SetLessThan
, StageCls
):
376 """ special version of a nmigen module where the module is also a stage
378 shows that you don't actually need to combinatorially connect
379 to the outputs, or add the module as a submodule: just return
380 the module output parameter(s) from the Stage.process() function
384 SetLessThan
.__init
__(self
, 16, True)
387 return (Signal(16), Signal(16))
392 def setup(self
, m
, i
):
393 m
.submodules
.slt
= self
394 m
.d
.comb
+= self
.src1
.eq(i
[0])
395 m
.d
.comb
+= self
.src2
.eq(i
[1])
397 def process(self
, i
):
401 class ExampleLTPipeline(UnbufferedPipeline
):
402 """ an example of how to use the unbuffered pipeline.
407 UnbufferedPipeline
.__init
__(self
, stage
)
410 class ExampleLTBufferedPipeDerived(BufferedPipeline
):
411 """ an example of how to use the buffered pipeline.
415 stage
= LTStageDerived()
416 BufferedPipeline
.__init
__(self
, stage
)
419 def test6_resultfn(o_data
, expected
, i
, o
):
420 res
= 1 if expected
[0] < expected
[1] else 0
421 assert o_data
== res
, \
422 "%d-%d data %x not match %s\n" \
423 % (i
, o
, o_data
, repr(expected
))
426 ######################################################################
428 ######################################################################
430 class ExampleAddRecordStage(StageCls
):
431 """ example use of a Record
434 record_spec
= [('src1', 16), ('src2', 16)]
436 """ returns a Record using the specification
438 return Record(self
.record_spec
)
441 return Record(self
.record_spec
)
443 def process(self
, i
):
444 """ process the input data, returning a dictionary with key names
445 that exactly match the Record's attributes.
447 return {'src1': i
.src1
+ 1,
450 ######################################################################
452 ######################################################################
454 class ExampleAddRecordPlaceHolderStage(StageCls
):
455 """ example use of a Record, with a placeholder as the processing result
458 record_spec
= [('src1', 16), ('src2', 16)]
460 """ returns a Record using the specification
462 return Record(self
.record_spec
)
465 return Record(self
.record_spec
)
467 def process(self
, i
):
468 """ process the input data, returning a PlaceHolder class instance
469 with attributes that exactly match those of the Record.
477 class PlaceHolder
: pass
480 class ExampleAddRecordPipe(UnbufferedPipeline
):
481 """ an example of how to use the combinatorial pipeline.
485 stage
= ExampleAddRecordStage()
486 UnbufferedPipeline
.__init
__(self
, stage
)
489 def test7_resultfn(o_data
, expected
, i
, o
):
490 res
= (expected
['src1'] + 1, expected
['src2'] + 1)
491 assert o_data
['src1'] == res
[0] and o_data
['src2'] == res
[1], \
492 "%d-%d data %s not match %s\n" \
493 % (i
, o
, repr(o_data
), repr(expected
))
496 class ExampleAddRecordPlaceHolderPipe(UnbufferedPipeline
):
497 """ an example of how to use the combinatorial pipeline.
501 stage
= ExampleAddRecordPlaceHolderStage()
502 UnbufferedPipeline
.__init
__(self
, stage
)
505 def test11_resultfn(o_data
, expected
, i
, o
):
506 res1
= expected
.src1
+ 1
507 res2
= expected
.src2
+ 1
508 assert o_data
['src1'] == res1
and o_data
['src2'] == res2
, \
509 "%d-%d data %s not match %s\n" \
510 % (i
, o
, repr(o_data
), repr(expected
))
513 ######################################################################
515 ######################################################################
518 class Example2OpClass
:
519 """ an example of a class used to store 2 operands.
520 requires an eq function, to conform with the pipeline stage API
524 self
.op1
= Signal(16)
525 self
.op2
= Signal(16)
528 return [self
.op1
.eq(i
.op1
), self
.op2
.eq(i
.op2
)]
531 class ExampleAddClassStage(StageCls
):
532 """ an example of how to use the buffered pipeline, as a class instance
536 """ returns an instance of an Example2OpClass.
538 return Example2OpClass()
541 """ returns an output signal which will happen to contain the sum
546 def process(self
, i
):
547 """ process the input data (sums the values in the tuple) and returns it
552 class ExampleBufPipeAddClass(BufferedPipeline
):
553 """ an example of how to use the buffered pipeline, using a class instance
557 addstage
= ExampleAddClassStage()
558 BufferedPipeline
.__init
__(self
, addstage
)
562 """ the eq function, called by set_input, needs an incoming object
563 that conforms to the Example2OpClass.eq function requirements
564 easiest way to do that is to create a class that has the exact
565 same member layout (self.op1, self.op2) as Example2OpClass
567 def __init__(self
, op1
, op2
):
572 def test8_resultfn(o_data
, expected
, i
, o
):
573 res
= expected
.op1
+ expected
.op2
# these are a TestInputAdd instance
574 assert o_data
== res
, \
575 "%d-%d data %x not match %s\n" \
576 % (i
, o
, o_data
, repr(expected
))
580 for i
in range(num_tests
):
581 data
.append(TestInputAdd(randint(0, 1<<16-1), randint(0, 1<<16-1)))
585 ######################################################################
587 ######################################################################
589 class ExampleStageDelayCls(StageCls
):
590 """ an example of how to use the buffered pipeline, in a static class
594 def __init__(self
, valid_trigger
=2):
595 self
.count
= Signal(2)
596 self
.valid_trigger
= valid_trigger
599 return Signal(16, name
="example_input_signal")
602 return Signal(16, name
="example_output_signal")
606 return (self
.count
== 1)# | (self.count == 3)
611 return self
.count
== self
.valid_trigger
614 def process(self
, i
):
615 """ process the input data and returns it (adds 1)
619 def elaborate(self
, platform
):
621 m
.d
.sync
+= self
.count
.eq(self
.count
+ 1)
625 class ExampleBufDelayedPipe(BufferedPipeline
):
628 stage
= ExampleStageDelayCls(valid_trigger
=3)
629 BufferedPipeline
.__init
__(self
, stage
, stage_ctl
=True,
632 def elaborate(self
, platform
):
633 m
= BufferedPipeline
.elaborate(self
, platform
)
634 m
.submodules
.stage
= self
.stage
640 for i
in range(num_tests
):
641 data
.append(1<<((i
*3)%15))
642 #data.append(randint(0, 1<<16-2))
643 print (hex(data
[-1]))
647 def test12_resultfn(o_data
, expected
, i
, o
):
649 assert o_data
== res
, \
650 "%d-%d data %x not match %x\n" \
651 % (i
, o
, o_data
, res
)
654 ######################################################################
656 ######################################################################
658 class ExampleUnBufDelayedPipe(BufferedPipeline
):
661 stage
= ExampleStageDelayCls()
662 BufferedPipeline
.__init
__(self
, stage
, stage_ctl
=True)
664 def elaborate(self
, platform
):
665 m
= BufferedPipeline
.elaborate(self
, platform
)
666 m
.submodules
.stage
= self
.stage
669 ######################################################################
671 ######################################################################
673 class ExampleBufPipe3(ControlBase
):
674 """ Example of how to do delayed pipeline, where the stage signals
678 def elaborate(self
, platform
):
679 m
= ControlBase
._elaborate
(self
, platform
)
681 pipe1
= ExampleBufDelayedPipe()
682 pipe2
= ExampleBufPipe()
684 m
.submodules
.pipe1
= pipe1
685 m
.submodules
.pipe2
= pipe2
687 m
.d
.comb
+= self
.connect([pipe1
, pipe2
])
691 ######################################################################
693 ######################################################################
695 class ExampleBufModeAdd1Pipe(BufferedPipeline
):
698 stage
= ExampleStageCls()
699 BufferedPipeline
.__init
__(self
, stage
, buffermode
=False)
702 class ExampleBufModeUnBufPipe(ControlBase
):
704 def elaborate(self
, platform
):
705 m
= ControlBase
._elaborate
(self
, platform
)
707 pipe1
= ExampleBufModeAdd1Pipe()
708 pipe2
= ExampleBufAdd1Pipe()
710 m
.submodules
.pipe1
= pipe1
711 m
.submodules
.pipe2
= pipe2
713 m
.d
.comb
+= self
.connect([pipe1
, pipe2
])
718 ######################################################################
719 # Test 999 - XXX FAILS
720 # http://bugs.libre-riscv.org/show_bug.cgi?id=57
721 ######################################################################
723 class ExampleBufAdd1Pipe(BufferedPipeline
):
726 stage
= ExampleStageCls()
727 BufferedPipeline
.__init
__(self
, stage
)
730 class ExampleUnBufAdd1Pipe(UnbufferedPipeline
):
733 stage
= ExampleStageCls()
734 UnbufferedPipeline
.__init
__(self
, stage
)
737 class ExampleBufUnBufPipe(ControlBase
):
739 def elaborate(self
, platform
):
740 m
= ControlBase
._elaborate
(self
, platform
)
742 # XXX currently fails: any other permutation works fine.
743 # p1=u,p2=b ok p1=u,p2=u ok p1=b,p2=b ok
744 # also fails using UnbufferedPipeline as well
745 #pipe1 = ExampleUnBufAdd1Pipe()
746 #pipe2 = ExampleBufAdd1Pipe()
747 pipe1
= ExampleBufAdd1Pipe()
748 pipe2
= ExampleUnBufAdd1Pipe()
750 m
.submodules
.pipe1
= pipe1
751 m
.submodules
.pipe2
= pipe2
753 m
.d
.comb
+= self
.connect([pipe1
, pipe2
])
758 ######################################################################
760 ######################################################################
764 if __name__
== '__main__':
766 dut
= ExampleBufPipe()
767 run_simulation(dut
, testbench(dut
), vcd_name
="test_bufpipe.vcd")
770 dut
= ExampleBufPipe2()
771 run_simulation(dut
, testbench2(dut
), vcd_name
="test_bufpipe2.vcd")
772 ports
= [dut
.p
.i_valid
, dut
.n
.i_ready
,
773 dut
.n
.o_valid
, dut
.p
.o_ready
] + \
774 [dut
.p
.i_data
] + [dut
.n
.o_data
]
775 vl
= rtlil
.convert(dut
, ports
=ports
)
776 with
open("test_bufpipe2.il", "w") as f
:
781 dut
= ExampleBufPipe()
782 test
= Test3(dut
, test3_resultfn
)
783 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_bufpipe3.vcd")
786 dut
= ExamplePipeline()
787 test
= Test3(dut
, test3_resultfn
)
788 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_combpipe3.vcd")
791 dut
= ExampleBufPipe2()
792 run_simulation(dut
, testbench4(dut
), vcd_name
="test_bufpipe4.vcd")
795 dut
= ExampleBufPipeAdd()
796 test
= Test5(dut
, test5_resultfn
, stage_ctl
=True)
797 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_bufpipe5.vcd")
800 dut
= ExampleLTPipeline()
801 test
= Test5(dut
, test6_resultfn
)
802 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_ltcomb6.vcd")
804 ports
= [dut
.p
.i_valid
, dut
.n
.i_ready
,
805 dut
.n
.o_valid
, dut
.p
.o_ready
] + \
806 list(dut
.p
.i_data
) + [dut
.n
.o_data
]
807 vl
= rtlil
.convert(dut
, ports
=ports
)
808 with
open("test_ltcomb_pipe.il", "w") as f
:
812 dut
= ExampleAddRecordPipe()
814 test
= Test5(dut
, test7_resultfn
, data
=data
)
815 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_addrecord.vcd")
817 ports
= [dut
.p
.i_valid
, dut
.n
.i_ready
,
818 dut
.n
.o_valid
, dut
.p
.o_ready
,
819 dut
.p
.i_data
.src1
, dut
.p
.i_data
.src2
,
820 dut
.n
.o_data
.src1
, dut
.n
.o_data
.src2
]
821 vl
= rtlil
.convert(dut
, ports
=ports
)
822 with
open("test_recordcomb_pipe.il", "w") as f
:
826 dut
= ExampleBufPipeAddClass()
828 test
= Test5(dut
, test8_resultfn
, data
=data
)
829 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_bufpipe8.vcd")
832 dut
= ExampleBufPipeChain2()
833 ports
= [dut
.p
.i_valid
, dut
.n
.i_ready
,
834 dut
.n
.o_valid
, dut
.p
.o_ready
] + \
835 [dut
.p
.i_data
] + [dut
.n
.o_data
]
836 vl
= rtlil
.convert(dut
, ports
=ports
)
837 with
open("test_bufpipechain2.il", "w") as f
:
841 test
= Test5(dut
, test9_resultfn
, data
=data
)
842 run_simulation(dut
, [test
.send
, test
.rcv
],
843 vcd_name
="test_bufpipechain2.vcd")
846 dut
= ExampleLTBufferedPipeDerived()
847 test
= Test5(dut
, test6_resultfn
)
848 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_ltbufpipe10.vcd")
849 vl
= rtlil
.convert(dut
, ports
=ports
)
850 with
open("test_ltbufpipe10.il", "w") as f
:
854 dut
= ExampleAddRecordPlaceHolderPipe()
855 data
=data_placeholder()
856 test
= Test5(dut
, test11_resultfn
, data
=data
)
857 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_addrecord.vcd")
861 dut
= ExampleBufDelayedPipe()
863 test
= Test5(dut
, test12_resultfn
, data
=data
)
864 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_bufpipe12.vcd")
865 ports
= [dut
.p
.i_valid
, dut
.n
.i_ready
,
866 dut
.n
.o_valid
, dut
.p
.o_ready
] + \
867 [dut
.p
.i_data
] + [dut
.n
.o_data
]
868 vl
= rtlil
.convert(dut
, ports
=ports
)
869 with
open("test_bufpipe12.il", "w") as f
:
873 dut
= ExampleUnBufDelayedPipe()
875 test
= Test5(dut
, test12_resultfn
, data
=data
)
876 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_unbufpipe13.vcd")
877 ports
= [dut
.p
.i_valid
, dut
.n
.i_ready
,
878 dut
.n
.o_valid
, dut
.p
.o_ready
] + \
879 [dut
.p
.i_data
] + [dut
.n
.o_data
]
880 vl
= rtlil
.convert(dut
, ports
=ports
)
881 with
open("test_unbufpipe13.il", "w") as f
:
885 dut
= ExampleBufPipe3()
887 test
= Test5(dut
, test9_resultfn
, data
=data
)
888 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_bufpipe14.vcd")
889 ports
= [dut
.p
.i_valid
, dut
.n
.i_ready
,
890 dut
.n
.o_valid
, dut
.p
.o_ready
] + \
891 [dut
.p
.i_data
] + [dut
.n
.o_data
]
892 vl
= rtlil
.convert(dut
, ports
=ports
)
893 with
open("test_bufpipe14.il", "w") as f
:
897 dut
= ExampleBufModeUnBufPipe()
899 test
= Test5(dut
, test9_resultfn
, data
=data
)
900 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_bufunbuf15.vcd")
901 ports
= [dut
.p
.i_valid
, dut
.n
.i_ready
,
902 dut
.n
.o_valid
, dut
.p
.o_ready
] + \
903 [dut
.p
.i_data
] + [dut
.n
.o_data
]
904 vl
= rtlil
.convert(dut
, ports
=ports
)
905 with
open("test_bufunbuf15.il", "w") as f
:
908 print ("test 999 (expected to fail, which is a bug)")
909 dut
= ExampleBufUnBufPipe()
911 test
= Test5(dut
, test9_resultfn
, data
=data
)
912 run_simulation(dut
, [test
.send
, test
.rcv
], vcd_name
="test_bufunbuf999.vcd")
913 ports
= [dut
.p
.i_valid
, dut
.n
.i_ready
,
914 dut
.n
.o_valid
, dut
.p
.o_ready
] + \
915 [dut
.p
.i_data
] + [dut
.n
.o_data
]
916 vl
= rtlil
.convert(dut
, ports
=ports
)
917 with
open("test_bufunbuf999.il", "w") as f
: