make data regular for test in bug #59
[ieee754fpu.git] / src / add / test_buf_pipe.py
1 """ Unit tests for Buffered and Unbuffered pipelines
2
3 contains useful worked examples of how to use the Pipeline API,
4 including:
5
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
14
15 """
16
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
21
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
28
29 from random import randint, seed
30
31 seed(4)
32
33
34 def check_o_n_valid(dut, val):
35 o_n_valid = yield dut.n.o_valid
36 assert o_n_valid == val
37
38 def check_o_n_valid2(dut, val):
39 o_n_valid = yield dut.n.o_valid
40 assert o_n_valid == val
41
42
43 def testbench(dut):
44 #yield dut.i_p_rst.eq(1)
45 yield dut.n.i_ready.eq(0)
46 yield dut.p.o_ready.eq(0)
47 yield
48 yield
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)
53 yield
54
55 yield dut.p.i_data.eq(7)
56 yield from check_o_n_valid(dut, 0) # effects of i_p_valid delayed
57 yield
58 yield from check_o_n_valid(dut, 1) # ok *now* i_p_valid effect is felt
59
60 yield dut.p.i_data.eq(2)
61 yield
62 yield dut.n.i_ready.eq(0) # begin going into "stall" (next stage says ready)
63 yield dut.p.i_data.eq(9)
64 yield
65 yield dut.p.i_valid.eq(0)
66 yield dut.p.i_data.eq(12)
67 yield
68 yield dut.p.i_data.eq(32)
69 yield dut.n.i_ready.eq(1)
70 yield
71 yield from check_o_n_valid(dut, 1) # buffer still needs to output
72 yield
73 yield from check_o_n_valid(dut, 1) # buffer still needs to output
74 yield
75 yield from check_o_n_valid(dut, 0) # buffer outputted, *now* we're done.
76 yield
77
78
79 def testbench2(dut):
80 #yield dut.p.i_rst.eq(1)
81 yield dut.n.i_ready.eq(0)
82 #yield dut.p.o_ready.eq(0)
83 yield
84 yield
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)
89 yield
90
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
93 yield
94 yield from check_o_n_valid2(dut, 0) # effects of i_p_valid delayed 2 clocks
95
96 yield dut.p.i_data.eq(2)
97 yield
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)
101 yield
102 yield dut.p.i_valid.eq(0)
103 yield dut.p.i_data.eq(12)
104 yield
105 yield dut.p.i_data.eq(32)
106 yield dut.n.i_ready.eq(1)
107 yield
108 yield from check_o_n_valid2(dut, 1) # buffer still needs to output
109 yield
110 yield from check_o_n_valid2(dut, 1) # buffer still needs to output
111 yield
112 yield from check_o_n_valid2(dut, 1) # buffer still needs to output
113 yield
114 yield from check_o_n_valid2(dut, 0) # buffer outputted, *now* we're done.
115 yield
116 yield
117 yield
118
119
120 class Test3:
121 def __init__(self, dut, resultfn):
122 self.dut = dut
123 self.resultfn = resultfn
124 self.data = []
125 for i in range(num_tests):
126 #data.append(randint(0, 1<<16-1))
127 self.data.append(i+1)
128 self.i = 0
129 self.o = 0
130
131 def send(self):
132 while self.o != len(self.data):
133 send_range = randint(0, 3)
134 for j in range(randint(1,10)):
135 if send_range == 0:
136 send = True
137 else:
138 send = randint(0, send_range) != 0
139 send = True
140 o_p_ready = yield self.dut.p.o_ready
141 if not o_p_ready:
142 yield
143 continue
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])
147 self.i += 1
148 else:
149 yield self.dut.p.i_valid.eq(0)
150 yield
151
152 def rcv(self):
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)
158 yield
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:
162 continue
163 o_data = yield self.dut.n.o_data
164 self.resultfn(o_data, self.data[self.o], self.i, self.o)
165 self.o += 1
166 if self.o == len(self.data):
167 break
168
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)
173
174 def data_placeholder():
175 data = []
176 for i in range(num_tests):
177 d = PlaceHolder()
178 d.src1 = randint(0, 1<<16-1)
179 d.src2 = randint(0, 1<<16-1)
180 data.append(d)
181 return data
182
183 def data_dict():
184 data = []
185 for i in range(num_tests):
186 data.append({'src1': randint(0, 1<<16-1),
187 'src2': randint(0, 1<<16-1)})
188 return data
189
190
191 class Test5:
192 def __init__(self, dut, resultfn, data=None, stage_ctl=False):
193 self.dut = dut
194 self.resultfn = resultfn
195 self.stage_ctl = stage_ctl
196 if data:
197 self.data = data
198 else:
199 self.data = []
200 for i in range(num_tests):
201 self.data.append((randint(0, 1<<16-1), randint(0, 1<<16-1)))
202 self.i = 0
203 self.o = 0
204
205 def send(self):
206 while self.o != len(self.data):
207 send_range = randint(0, 3)
208 for j in range(randint(1,10)):
209 if send_range == 0:
210 send = True
211 else:
212 send = randint(0, send_range) != 0
213 o_p_ready = yield self.dut.p.o_ready
214 if not o_p_ready:
215 yield
216 continue
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]):
220 yield v
221 self.i += 1
222 else:
223 yield self.dut.p.i_valid.eq(0)
224 yield
225
226 def rcv(self):
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
231 ready = True
232 yield self.dut.n.i_ready.eq(ready)
233 yield
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:
237 continue
238 if isinstance(self.dut.n.o_data, Record):
239 o_data = {}
240 dod = self.dut.n.o_data
241 for k, v in dod.fields.items():
242 o_data[k] = yield v
243 else:
244 o_data = yield self.dut.n.o_data
245 self.resultfn(o_data, self.data[self.o], self.i, self.o)
246 self.o += 1
247 if self.o == len(self.data):
248 break
249
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))
255
256 def testbench4(dut):
257 data = []
258 for i in range(num_tests):
259 #data.append(randint(0, 1<<16-1))
260 data.append(i+1)
261 i = 0
262 o = 0
263 while True:
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
268 if o_p_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])
272 i += 1
273 else:
274 yield dut.p.i_valid.eq(0)
275 yield
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])
282 o += 1
283 if o == len(data):
284 break
285
286 ######################################################################
287 # Test 2 and 4
288 ######################################################################
289
290 class ExampleBufPipe2(ControlBase):
291 """ Example of how to do chained pipeline stages.
292 """
293
294 def elaborate(self, platform):
295 m = Module()
296
297 pipe1 = ExampleBufPipe()
298 pipe2 = ExampleBufPipe()
299
300 m.submodules.pipe1 = pipe1
301 m.submodules.pipe2 = pipe2
302
303 m.d.comb += self.connect([pipe1, pipe2])
304
305 return m
306
307
308 ######################################################################
309 # Test 9
310 ######################################################################
311
312 class ExampleBufPipeChain2(BufferedPipeline):
313 """ connects two stages together as a *single* combinatorial stage.
314 """
315 def __init__(self):
316 stage1 = ExampleStageCls()
317 stage2 = ExampleStageCls()
318 combined = StageChain([stage1, stage2])
319 BufferedPipeline.__init__(self, combined)
320
321
322 def data_chain2():
323 data = []
324 for i in range(num_tests):
325 data.append(randint(0, 1<<16-2))
326 return data
327
328
329 def test9_resultfn(o_data, expected, i, o):
330 res = expected + 2
331 assert o_data == res, \
332 "%d-%d received data %x not match expected %x\n" \
333 % (i, o, o_data, res)
334
335
336 ######################################################################
337 # Test 6 and 10
338 ######################################################################
339
340 class SetLessThan:
341 def __init__(self, width, signed):
342 self.m = Module()
343 self.src1 = Signal((width, signed), name="src1")
344 self.src2 = Signal((width, signed), name="src2")
345 self.output = Signal(width, name="out")
346
347 def elaborate(self, platform):
348 self.m.d.comb += self.output.eq(Mux(self.src1 < self.src2, 1, 0))
349 return self.m
350
351
352 class LTStage(StageCls):
353 """ module-based stage example
354 """
355 def __init__(self):
356 self.slt = SetLessThan(16, True)
357
358 def ispec(self):
359 return (Signal(16, name="sig1"), Signal(16, "sig2"))
360
361 def ospec(self):
362 return Signal(16, "out")
363
364 def setup(self, m, i):
365 self.o = Signal(16)
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)
370
371 def process(self, i):
372 return self.o
373
374
375 class LTStageDerived(SetLessThan, StageCls):
376 """ special version of a nmigen module where the module is also a stage
377
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
381 """
382
383 def __init__(self):
384 SetLessThan.__init__(self, 16, True)
385
386 def ispec(self):
387 return (Signal(16), Signal(16))
388
389 def ospec(self):
390 return Signal(16)
391
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])
396
397 def process(self, i):
398 return self.output
399
400
401 class ExampleLTPipeline(UnbufferedPipeline):
402 """ an example of how to use the unbuffered pipeline.
403 """
404
405 def __init__(self):
406 stage = LTStage()
407 UnbufferedPipeline.__init__(self, stage)
408
409
410 class ExampleLTBufferedPipeDerived(BufferedPipeline):
411 """ an example of how to use the buffered pipeline.
412 """
413
414 def __init__(self):
415 stage = LTStageDerived()
416 BufferedPipeline.__init__(self, stage)
417
418
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))
424
425
426 ######################################################################
427 # Test 7
428 ######################################################################
429
430 class ExampleAddRecordStage(StageCls):
431 """ example use of a Record
432 """
433
434 record_spec = [('src1', 16), ('src2', 16)]
435 def ispec(self):
436 """ returns a Record using the specification
437 """
438 return Record(self.record_spec)
439
440 def ospec(self):
441 return Record(self.record_spec)
442
443 def process(self, i):
444 """ process the input data, returning a dictionary with key names
445 that exactly match the Record's attributes.
446 """
447 return {'src1': i.src1 + 1,
448 'src2': i.src2 + 1}
449
450 ######################################################################
451 # Test 11
452 ######################################################################
453
454 class ExampleAddRecordPlaceHolderStage(StageCls):
455 """ example use of a Record, with a placeholder as the processing result
456 """
457
458 record_spec = [('src1', 16), ('src2', 16)]
459 def ispec(self):
460 """ returns a Record using the specification
461 """
462 return Record(self.record_spec)
463
464 def ospec(self):
465 return Record(self.record_spec)
466
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.
470 """
471 o = PlaceHolder()
472 o.src1 = i.src1 + 1
473 o.src2 = i.src2 + 1
474 return o
475
476
477 class PlaceHolder: pass
478
479
480 class ExampleAddRecordPipe(UnbufferedPipeline):
481 """ an example of how to use the combinatorial pipeline.
482 """
483
484 def __init__(self):
485 stage = ExampleAddRecordStage()
486 UnbufferedPipeline.__init__(self, stage)
487
488
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))
494
495
496 class ExampleAddRecordPlaceHolderPipe(UnbufferedPipeline):
497 """ an example of how to use the combinatorial pipeline.
498 """
499
500 def __init__(self):
501 stage = ExampleAddRecordPlaceHolderStage()
502 UnbufferedPipeline.__init__(self, stage)
503
504
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))
511
512
513 ######################################################################
514 # Test 8
515 ######################################################################
516
517
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
521 """
522
523 def __init__(self):
524 self.op1 = Signal(16)
525 self.op2 = Signal(16)
526
527 def eq(self, i):
528 return [self.op1.eq(i.op1), self.op2.eq(i.op2)]
529
530
531 class ExampleAddClassStage(StageCls):
532 """ an example of how to use the buffered pipeline, as a class instance
533 """
534
535 def ispec(self):
536 """ returns an instance of an Example2OpClass.
537 """
538 return Example2OpClass()
539
540 def ospec(self):
541 """ returns an output signal which will happen to contain the sum
542 of the two inputs
543 """
544 return Signal(16)
545
546 def process(self, i):
547 """ process the input data (sums the values in the tuple) and returns it
548 """
549 return i.op1 + i.op2
550
551
552 class ExampleBufPipeAddClass(BufferedPipeline):
553 """ an example of how to use the buffered pipeline, using a class instance
554 """
555
556 def __init__(self):
557 addstage = ExampleAddClassStage()
558 BufferedPipeline.__init__(self, addstage)
559
560
561 class TestInputAdd:
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
566 """
567 def __init__(self, op1, op2):
568 self.op1 = op1
569 self.op2 = op2
570
571
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))
577
578 def data_2op():
579 data = []
580 for i in range(num_tests):
581 data.append(TestInputAdd(randint(0, 1<<16-1), randint(0, 1<<16-1)))
582 return data
583
584
585 ######################################################################
586 # Test 12
587 ######################################################################
588
589 class ExampleStageDelayCls(StageCls):
590 """ an example of how to use the buffered pipeline, in a static class
591 fashion
592 """
593
594 def __init__(self, valid_trigger=2):
595 self.count = Signal(2)
596 self.valid_trigger = valid_trigger
597
598 def ispec(self):
599 return Signal(16, name="example_input_signal")
600
601 def ospec(self):
602 return Signal(16, name="example_output_signal")
603
604 @property
605 def d_ready(self):
606 return (self.count == 1)# | (self.count == 3)
607 return Const(1)
608
609 @property
610 def d_valid(self):
611 return self.count == self.valid_trigger
612 return Const(1)
613
614 def process(self, i):
615 """ process the input data and returns it (adds 1)
616 """
617 return i + 1
618
619 def elaborate(self, platform):
620 m = Module()
621 m.d.sync += self.count.eq(self.count + 1)
622 return m
623
624
625 class ExampleBufDelayedPipe(BufferedPipeline):
626
627 def __init__(self):
628 stage = ExampleStageDelayCls(valid_trigger=3)
629 BufferedPipeline.__init__(self, stage, stage_ctl=True,
630 buffermode=False)
631
632 def elaborate(self, platform):
633 m = BufferedPipeline.elaborate(self, platform)
634 m.submodules.stage = self.stage
635 return m
636
637
638 def data_chain1():
639 data = []
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]))
644 return data
645
646
647 def test12_resultfn(o_data, expected, i, o):
648 res = expected + 1
649 assert o_data == res, \
650 "%d-%d data %x not match %x\n" \
651 % (i, o, o_data, res)
652
653
654 ######################################################################
655 # Test 13
656 ######################################################################
657
658 class ExampleUnBufDelayedPipe(BufferedPipeline):
659
660 def __init__(self):
661 stage = ExampleStageDelayCls()
662 BufferedPipeline.__init__(self, stage, stage_ctl=True)
663
664 def elaborate(self, platform):
665 m = BufferedPipeline.elaborate(self, platform)
666 m.submodules.stage = self.stage
667 return m
668
669 ######################################################################
670 # Test 14
671 ######################################################################
672
673 class ExampleBufPipe3(ControlBase):
674 """ Example of how to do delayed pipeline, where the stage signals
675 whether it is ready.
676 """
677
678 def elaborate(self, platform):
679 m = ControlBase._elaborate(self, platform)
680
681 pipe1 = ExampleBufDelayedPipe()
682 pipe2 = ExampleBufPipe()
683
684 m.submodules.pipe1 = pipe1
685 m.submodules.pipe2 = pipe2
686
687 m.d.comb += self.connect([pipe1, pipe2])
688
689 return m
690
691 ######################################################################
692 # Test 15
693 ######################################################################
694
695 class ExampleBufModeAdd1Pipe(BufferedPipeline):
696
697 def __init__(self):
698 stage = ExampleStageCls()
699 BufferedPipeline.__init__(self, stage, buffermode=False)
700
701
702 class ExampleBufModeUnBufPipe(ControlBase):
703
704 def elaborate(self, platform):
705 m = ControlBase._elaborate(self, platform)
706
707 pipe1 = ExampleBufModeAdd1Pipe()
708 pipe2 = ExampleBufAdd1Pipe()
709
710 m.submodules.pipe1 = pipe1
711 m.submodules.pipe2 = pipe2
712
713 m.d.comb += self.connect([pipe1, pipe2])
714
715 return m
716
717
718 ######################################################################
719 # Test 999 - XXX FAILS
720 # http://bugs.libre-riscv.org/show_bug.cgi?id=57
721 ######################################################################
722
723 class ExampleBufAdd1Pipe(BufferedPipeline):
724
725 def __init__(self):
726 stage = ExampleStageCls()
727 BufferedPipeline.__init__(self, stage)
728
729
730 class ExampleUnBufAdd1Pipe(UnbufferedPipeline):
731
732 def __init__(self):
733 stage = ExampleStageCls()
734 UnbufferedPipeline.__init__(self, stage)
735
736
737 class ExampleBufUnBufPipe(ControlBase):
738
739 def elaborate(self, platform):
740 m = ControlBase._elaborate(self, platform)
741
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()
749
750 m.submodules.pipe1 = pipe1
751 m.submodules.pipe2 = pipe2
752
753 m.d.comb += self.connect([pipe1, pipe2])
754
755 return m
756
757
758 ######################################################################
759 # Unit Tests
760 ######################################################################
761
762 num_tests = 10
763
764 if __name__ == '__main__':
765 print ("test 1")
766 dut = ExampleBufPipe()
767 run_simulation(dut, testbench(dut), vcd_name="test_bufpipe.vcd")
768
769 print ("test 2")
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:
777 f.write(vl)
778
779
780 print ("test 3")
781 dut = ExampleBufPipe()
782 test = Test3(dut, test3_resultfn)
783 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe3.vcd")
784
785 print ("test 3.5")
786 dut = ExamplePipeline()
787 test = Test3(dut, test3_resultfn)
788 run_simulation(dut, [test.send, test.rcv], vcd_name="test_combpipe3.vcd")
789
790 print ("test 4")
791 dut = ExampleBufPipe2()
792 run_simulation(dut, testbench4(dut), vcd_name="test_bufpipe4.vcd")
793
794 print ("test 5")
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")
798
799 print ("test 6")
800 dut = ExampleLTPipeline()
801 test = Test5(dut, test6_resultfn)
802 run_simulation(dut, [test.send, test.rcv], vcd_name="test_ltcomb6.vcd")
803
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:
809 f.write(vl)
810
811 print ("test 7")
812 dut = ExampleAddRecordPipe()
813 data=data_dict()
814 test = Test5(dut, test7_resultfn, data=data)
815 run_simulation(dut, [test.send, test.rcv], vcd_name="test_addrecord.vcd")
816
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:
823 f.write(vl)
824
825 print ("test 8")
826 dut = ExampleBufPipeAddClass()
827 data=data_2op()
828 test = Test5(dut, test8_resultfn, data=data)
829 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe8.vcd")
830
831 print ("test 9")
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:
838 f.write(vl)
839
840 data = data_chain2()
841 test = Test5(dut, test9_resultfn, data=data)
842 run_simulation(dut, [test.send, test.rcv],
843 vcd_name="test_bufpipechain2.vcd")
844
845 print ("test 10")
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:
851 f.write(vl)
852
853 print ("test 11")
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")
858
859
860 print ("test 12")
861 dut = ExampleBufDelayedPipe()
862 data = data_chain1()
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:
870 f.write(vl)
871
872 print ("test 13")
873 dut = ExampleUnBufDelayedPipe()
874 data = data_chain1()
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:
882 f.write(vl)
883
884 print ("test 14")
885 dut = ExampleBufPipe3()
886 data = data_chain1()
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:
894 f.write(vl)
895
896 print ("test 15)")
897 dut = ExampleBufModeUnBufPipe()
898 data = data_chain1()
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:
906 f.write(vl)
907
908 print ("test 999 (expected to fail, which is a bug)")
909 dut = ExampleBufUnBufPipe()
910 data = data_chain1()
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:
918 f.write(vl)
919