switch to exact version of cython
[ieee754fpu.git] / src / nmutil / test / 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, Elaboratable
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 nmutil.test.example_buf_pipe import ExampleBufPipe, ExampleBufPipeAdd
23 from nmutil.test.example_buf_pipe import ExamplePipeline, UnbufferedPipeline
24 from nmutil.test.example_buf_pipe import ExampleStageCls
25 from nmutil.iocontrol import PrevControl, NextControl
26 from nmutil.stageapi import StageChain, StageCls
27 from nmutil.singlepipe import ControlBase
28 from nmutil.singlepipe import UnbufferedPipeline2
29 from nmutil.singlepipe import SimpleHandshake
30 from nmutil.singlepipe import BufferedHandshake
31 from nmutil.singlepipe import PassThroughHandshake
32 from nmutil.singlepipe import PassThroughStage
33 from nmutil.singlepipe import FIFOControl
34 from nmutil.singlepipe import RecordObject
35 from nmutil.singlepipe import MaskCancellable
36
37 from random import randint, seed
38
39 #seed(4)
40
41
42 def check_o_n_valid(dut, val):
43 o_n_valid = yield dut.n.valid_o
44 assert o_n_valid == val
45
46 def check_o_n_valid2(dut, val):
47 o_n_valid = yield dut.n.valid_o
48 assert o_n_valid == val
49
50
51 def tbench(dut):
52 #yield dut.i_p_rst.eq(1)
53 yield dut.n.ready_i.eq(0)
54 #yield dut.p.ready_o.eq(0)
55 yield
56 yield
57 #yield dut.i_p_rst.eq(0)
58 yield dut.n.ready_i.eq(1)
59 yield dut.p.data_i.eq(5)
60 yield dut.p.valid_i.eq(1)
61 yield
62
63 yield dut.p.data_i.eq(7)
64 yield from check_o_n_valid(dut, 0) # effects of i_p_valid delayed
65 yield
66 yield from check_o_n_valid(dut, 1) # ok *now* i_p_valid effect is felt
67
68 yield dut.p.data_i.eq(2)
69 yield
70 yield dut.n.ready_i.eq(0) # begin going into "stall" (next stage says ready)
71 yield dut.p.data_i.eq(9)
72 yield
73 yield dut.p.valid_i.eq(0)
74 yield dut.p.data_i.eq(12)
75 yield
76 yield dut.p.data_i.eq(32)
77 yield dut.n.ready_i.eq(1)
78 yield
79 yield from check_o_n_valid(dut, 1) # buffer still needs to output
80 yield
81 yield from check_o_n_valid(dut, 1) # buffer still needs to output
82 yield
83 yield from check_o_n_valid(dut, 0) # buffer outputted, *now* we're done.
84 yield
85
86
87 def tbench2(dut):
88 #yield dut.p.i_rst.eq(1)
89 yield dut.n.ready_i.eq(0)
90 #yield dut.p.ready_o.eq(0)
91 yield
92 yield
93 #yield dut.p.i_rst.eq(0)
94 yield dut.n.ready_i.eq(1)
95 yield dut.p.data_i.eq(5)
96 yield dut.p.valid_i.eq(1)
97 yield
98
99 yield dut.p.data_i.eq(7)
100 yield from check_o_n_valid2(dut, 0) # effects of i_p_valid delayed 2 clocks
101 yield
102 yield from check_o_n_valid2(dut, 0) # effects of i_p_valid delayed 2 clocks
103
104 yield dut.p.data_i.eq(2)
105 yield
106 yield from check_o_n_valid2(dut, 1) # ok *now* i_p_valid effect is felt
107 yield dut.n.ready_i.eq(0) # begin going into "stall" (next stage says ready)
108 yield dut.p.data_i.eq(9)
109 yield
110 yield dut.p.valid_i.eq(0)
111 yield dut.p.data_i.eq(12)
112 yield
113 yield dut.p.data_i.eq(32)
114 yield dut.n.ready_i.eq(1)
115 yield
116 yield from check_o_n_valid2(dut, 1) # buffer still needs to output
117 yield
118 yield from check_o_n_valid2(dut, 1) # buffer still needs to output
119 yield
120 yield from check_o_n_valid2(dut, 1) # buffer still needs to output
121 yield
122 yield from check_o_n_valid2(dut, 0) # buffer outputted, *now* we're done.
123 yield
124 yield
125 yield
126
127
128 class Test3:
129 def __init__(self, dut, resultfn):
130 self.dut = dut
131 self.resultfn = resultfn
132 self.data = []
133 for i in range(num_tests):
134 #data.append(randint(0, 1<<16-1))
135 self.data.append(i+1)
136 self.i = 0
137 self.o = 0
138
139 def send(self):
140 while self.o != len(self.data):
141 send_range = randint(0, 3)
142 for j in range(randint(1,10)):
143 if send_range == 0:
144 send = True
145 else:
146 send = randint(0, send_range) != 0
147 o_p_ready = yield self.dut.p.ready_o
148 if not o_p_ready:
149 yield
150 continue
151 if send and self.i != len(self.data):
152 yield self.dut.p.valid_i.eq(1)
153 yield self.dut.p.data_i.eq(self.data[self.i])
154 self.i += 1
155 else:
156 yield self.dut.p.valid_i.eq(0)
157 yield
158
159 def rcv(self):
160 while self.o != len(self.data):
161 stall_range = randint(0, 3)
162 for j in range(randint(1,10)):
163 stall = randint(0, stall_range) != 0
164 yield self.dut.n.ready_i.eq(stall)
165 yield
166 o_n_valid = yield self.dut.n.valid_o
167 i_n_ready = yield self.dut.n.ready_i_test
168 if not o_n_valid or not i_n_ready:
169 continue
170 data_o = yield self.dut.n.data_o
171 self.resultfn(data_o, self.data[self.o], self.i, self.o)
172 self.o += 1
173 if self.o == len(self.data):
174 break
175
176 def resultfn_3(data_o, expected, i, o):
177 assert data_o == expected + 1, \
178 "%d-%d data %x not match %x\n" \
179 % (i, o, data_o, expected)
180
181 def data_placeholder():
182 data = []
183 for i in range(num_tests):
184 d = PlaceHolder()
185 d.src1 = randint(0, 1<<16-1)
186 d.src2 = randint(0, 1<<16-1)
187 data.append(d)
188 return data
189
190 def data_dict():
191 data = []
192 for i in range(num_tests):
193 data.append({'src1': randint(0, 1<<16-1),
194 'src2': randint(0, 1<<16-1)})
195 return data
196
197
198 class Test5:
199 def __init__(self, dut, resultfn, data=None, stage_ctl=False):
200 self.dut = dut
201 self.resultfn = resultfn
202 self.stage_ctl = stage_ctl
203 if data:
204 self.data = data
205 else:
206 self.data = []
207 for i in range(num_tests):
208 self.data.append((randint(0, 1<<16-1), randint(0, 1<<16-1)))
209 self.i = 0
210 self.o = 0
211
212 def send(self):
213 while self.o != len(self.data):
214 send_range = randint(0, 3)
215 for j in range(randint(1,10)):
216 if send_range == 0:
217 send = True
218 else:
219 send = randint(0, send_range) != 0
220 #send = True
221 o_p_ready = yield self.dut.p.ready_o
222 if not o_p_ready:
223 yield
224 continue
225 if send and self.i != len(self.data):
226 yield self.dut.p.valid_i.eq(1)
227 for v in self.dut.set_input(self.data[self.i]):
228 yield v
229 self.i += 1
230 else:
231 yield self.dut.p.valid_i.eq(0)
232 yield
233
234 def rcv(self):
235 while self.o != len(self.data):
236 stall_range = randint(0, 3)
237 for j in range(randint(1,10)):
238 ready = randint(0, stall_range) != 0
239 #ready = True
240 yield self.dut.n.ready_i.eq(ready)
241 yield
242 o_n_valid = yield self.dut.n.valid_o
243 i_n_ready = yield self.dut.n.ready_i_test
244 if not o_n_valid or not i_n_ready:
245 continue
246 if isinstance(self.dut.n.data_o, Record):
247 data_o = {}
248 dod = self.dut.n.data_o
249 for k, v in dod.fields.items():
250 data_o[k] = yield v
251 else:
252 data_o = yield self.dut.n.data_o
253 self.resultfn(data_o, self.data[self.o], self.i, self.o)
254 self.o += 1
255 if self.o == len(self.data):
256 break
257
258 class TestMask:
259 def __init__(self, dut, resultfn, maskwid, data=None, stage_ctl=False):
260 self.dut = dut
261 self.resultfn = resultfn
262 self.stage_ctl = stage_ctl
263 self.maskwid = maskwid
264 if data:
265 self.data = data
266 else:
267 self.data = []
268 for i in range(num_tests):
269 self.data.append((randint(0, 1<<16-1), randint(0, 1<<16-1)))
270 self.i = 0
271 self.o = 0
272
273 def send(self):
274 while self.o != len(self.data):
275 send_range = randint(0, 3)
276 for j in range(randint(1,10)):
277 if send_range == 0:
278 send = True
279 else:
280 send = randint(0, send_range) != 0
281 #send = True
282 o_p_ready = yield self.dut.p.ready_o
283 if not o_p_ready:
284 yield
285 continue
286 if send and self.i != len(self.data):
287 print ("send", self.i, self.data[self.i])
288 yield self.dut.p.valid_i.eq(1)
289 yield self.dut.p.mask_i.eq(1<<self.i) # XXX TODO
290 for v in self.dut.set_input(self.data[self.i]):
291 yield v
292 self.i += 1
293 else:
294 yield self.dut.p.valid_i.eq(0)
295 yield self.dut.p.mask_i.eq(0) # XXX TODO
296 yield
297
298 def rcv(self):
299 while self.o != len(self.data):
300 stall_range = randint(0, 3)
301 for j in range(randint(1,10)):
302 ready = randint(0, stall_range) != 0
303 ready = True
304 yield self.dut.n.ready_i.eq(ready)
305 yield
306 o_n_valid = yield self.dut.n.valid_o
307 i_n_ready = yield self.dut.n.ready_i_test
308 if not o_n_valid or not i_n_ready:
309 continue
310 if isinstance(self.dut.n.data_o, Record):
311 data_o = {}
312 dod = self.dut.n.data_o
313 for k, v in dod.fields.items():
314 data_o[k] = yield v
315 else:
316 data_o = yield self.dut.n.data_o
317 print ("recv", self.o, data_o)
318 self.resultfn(data_o, self.data[self.o], self.i, self.o)
319 self.o += 1
320 if self.o == len(self.data):
321 break
322
323 def resultfn_5(data_o, expected, i, o):
324 res = expected[0] + expected[1]
325 assert data_o == res, \
326 "%d-%d data %x not match %s\n" \
327 % (i, o, data_o, repr(expected))
328
329 def tbench4(dut):
330 data = []
331 for i in range(num_tests):
332 #data.append(randint(0, 1<<16-1))
333 data.append(i+1)
334 i = 0
335 o = 0
336 while True:
337 stall = randint(0, 3) != 0
338 send = randint(0, 5) != 0
339 yield dut.n.ready_i.eq(stall)
340 o_p_ready = yield dut.p.ready_o
341 if o_p_ready:
342 if send and i != len(data):
343 yield dut.p.valid_i.eq(1)
344 yield dut.p.data_i.eq(data[i])
345 i += 1
346 else:
347 yield dut.p.valid_i.eq(0)
348 yield
349 o_n_valid = yield dut.n.valid_o
350 i_n_ready = yield dut.n.ready_i_test
351 if o_n_valid and i_n_ready:
352 data_o = yield dut.n.data_o
353 assert data_o == data[o] + 2, "%d-%d data %x not match %x\n" \
354 % (i, o, data_o, data[o])
355 o += 1
356 if o == len(data):
357 break
358
359 ######################################################################
360 # Test 2 and 4
361 ######################################################################
362
363 class ExampleBufPipe2(ControlBase):
364 """ Example of how to do chained pipeline stages.
365 """
366
367 def elaborate(self, platform):
368 m = ControlBase.elaborate(self, platform)
369
370 pipe1 = ExampleBufPipe()
371 pipe2 = ExampleBufPipe()
372
373 m.submodules.pipe1 = pipe1
374 m.submodules.pipe2 = pipe2
375
376 m.d.comb += self.connect([pipe1, pipe2])
377
378 return m
379
380
381 ######################################################################
382 # Test 9
383 ######################################################################
384
385 class ExampleBufPipeChain2(BufferedHandshake):
386 """ connects two stages together as a *single* combinatorial stage.
387 """
388 def __init__(self):
389 stage1 = ExampleStageCls()
390 stage2 = ExampleStageCls()
391 combined = StageChain([stage1, stage2])
392 BufferedHandshake.__init__(self, combined)
393
394
395 def data_chain2():
396 data = []
397 for i in range(num_tests):
398 data.append(randint(0, 1<<16-2))
399 return data
400
401
402 def resultfn_9(data_o, expected, i, o):
403 res = expected + 2
404 assert data_o == res, \
405 "%d-%d received data %x not match expected %x\n" \
406 % (i, o, data_o, res)
407
408
409 ######################################################################
410 # Test 6 and 10
411 ######################################################################
412
413 class SetLessThan(Elaboratable):
414 def __init__(self, width, signed):
415 self.m = Module()
416 self.src1 = Signal((width, signed), name="src1")
417 self.src2 = Signal((width, signed), name="src2")
418 self.output = Signal(width, name="out")
419
420 def elaborate(self, platform):
421 self.m.d.comb += self.output.eq(Mux(self.src1 < self.src2, 1, 0))
422 return self.m
423
424
425 class LTStage(StageCls):
426 """ module-based stage example
427 """
428 def __init__(self):
429 self.slt = SetLessThan(16, True)
430
431 def ispec(self, name):
432 return (Signal(16, name="%s_sig1" % name),
433 Signal(16, name="%s_sig2" % name))
434
435 def ospec(self, name):
436 return Signal(16, "%s_out" % name)
437
438 def setup(self, m, i):
439 self.o = Signal(16)
440 m.submodules.slt = self.slt
441 m.d.comb += self.slt.src1.eq(i[0])
442 m.d.comb += self.slt.src2.eq(i[1])
443 m.d.comb += self.o.eq(self.slt.output)
444
445 def process(self, i):
446 return self.o
447
448
449 class LTStageDerived(SetLessThan, StageCls):
450 """ special version of a nmigen module where the module is also a stage
451
452 shows that you don't actually need to combinatorially connect
453 to the outputs, or add the module as a submodule: just return
454 the module output parameter(s) from the Stage.process() function
455 """
456
457 def __init__(self):
458 SetLessThan.__init__(self, 16, True)
459
460 def ispec(self):
461 return (Signal(16), Signal(16))
462
463 def ospec(self):
464 return Signal(16)
465
466 def setup(self, m, i):
467 m.submodules.slt = self
468 m.d.comb += self.src1.eq(i[0])
469 m.d.comb += self.src2.eq(i[1])
470
471 def process(self, i):
472 return self.output
473
474
475 class ExampleLTPipeline(UnbufferedPipeline):
476 """ an example of how to use the unbuffered pipeline.
477 """
478
479 def __init__(self):
480 stage = LTStage()
481 UnbufferedPipeline.__init__(self, stage)
482
483
484 class ExampleLTBufferedPipeDerived(BufferedHandshake):
485 """ an example of how to use the buffered pipeline.
486 """
487
488 def __init__(self):
489 stage = LTStageDerived()
490 BufferedHandshake.__init__(self, stage)
491
492
493 def resultfn_6(data_o, expected, i, o):
494 res = 1 if expected[0] < expected[1] else 0
495 assert data_o == res, \
496 "%d-%d data %x not match %s\n" \
497 % (i, o, data_o, repr(expected))
498
499
500 ######################################################################
501 # Test 7
502 ######################################################################
503
504 class ExampleAddRecordStage(StageCls):
505 """ example use of a Record
506 """
507
508 record_spec = [('src1', 16), ('src2', 16)]
509 def ispec(self):
510 """ returns a Record using the specification
511 """
512 return Record(self.record_spec)
513
514 def ospec(self):
515 return Record(self.record_spec)
516
517 def process(self, i):
518 """ process the input data, returning a dictionary with key names
519 that exactly match the Record's attributes.
520 """
521 return {'src1': i.src1 + 1,
522 'src2': i.src2 + 1}
523
524 ######################################################################
525 # Test 11
526 ######################################################################
527
528 class ExampleAddRecordPlaceHolderStage(StageCls):
529 """ example use of a Record, with a placeholder as the processing result
530 """
531
532 record_spec = [('src1', 16), ('src2', 16)]
533 def ispec(self):
534 """ returns a Record using the specification
535 """
536 return Record(self.record_spec)
537
538 def ospec(self):
539 return Record(self.record_spec)
540
541 def process(self, i):
542 """ process the input data, returning a PlaceHolder class instance
543 with attributes that exactly match those of the Record.
544 """
545 o = PlaceHolder()
546 o.src1 = i.src1 + 1
547 o.src2 = i.src2 + 1
548 return o
549
550
551 # a dummy class that may have stuff assigned to instances once created
552 class PlaceHolder: pass
553
554
555 class ExampleAddRecordPipe(UnbufferedPipeline):
556 """ an example of how to use the combinatorial pipeline.
557 """
558
559 def __init__(self):
560 stage = ExampleAddRecordStage()
561 UnbufferedPipeline.__init__(self, stage)
562
563
564 def resultfn_7(data_o, expected, i, o):
565 res = (expected['src1'] + 1, expected['src2'] + 1)
566 assert data_o['src1'] == res[0] and data_o['src2'] == res[1], \
567 "%d-%d data %s not match %s\n" \
568 % (i, o, repr(data_o), repr(expected))
569
570
571 class ExampleAddRecordPlaceHolderPipe(UnbufferedPipeline):
572 """ an example of how to use the combinatorial pipeline.
573 """
574
575 def __init__(self):
576 stage = ExampleAddRecordPlaceHolderStage()
577 UnbufferedPipeline.__init__(self, stage)
578
579
580 def resultfn_11(data_o, expected, i, o):
581 res1 = expected.src1 + 1
582 res2 = expected.src2 + 1
583 assert data_o['src1'] == res1 and data_o['src2'] == res2, \
584 "%d-%d data %s not match %s\n" \
585 % (i, o, repr(data_o), repr(expected))
586
587
588 ######################################################################
589 # Test 8
590 ######################################################################
591
592
593 class Example2OpClass:
594 """ an example of a class used to store 2 operands.
595 requires an eq function, to conform with the pipeline stage API
596 """
597
598 def __init__(self):
599 self.op1 = Signal(16)
600 self.op2 = Signal(16)
601
602 def eq(self, i):
603 return [self.op1.eq(i.op1), self.op2.eq(i.op2)]
604
605
606 class ExampleAddClassStage(StageCls):
607 """ an example of how to use the buffered pipeline, as a class instance
608 """
609
610 def ispec(self):
611 """ returns an instance of an Example2OpClass.
612 """
613 return Example2OpClass()
614
615 def ospec(self):
616 """ returns an output signal which will happen to contain the sum
617 of the two inputs
618 """
619 return Signal(16, name="add2_out")
620
621 def process(self, i):
622 """ process the input data (sums the values in the tuple) and returns it
623 """
624 return i.op1 + i.op2
625
626
627 class ExampleBufPipeAddClass(BufferedHandshake):
628 """ an example of how to use the buffered pipeline, using a class instance
629 """
630
631 def __init__(self):
632 addstage = ExampleAddClassStage()
633 BufferedHandshake.__init__(self, addstage)
634
635
636 class TestInputAdd:
637 """ the eq function, called by set_input, needs an incoming object
638 that conforms to the Example2OpClass.eq function requirements
639 easiest way to do that is to create a class that has the exact
640 same member layout (self.op1, self.op2) as Example2OpClass
641 """
642 def __init__(self, op1, op2):
643 self.op1 = op1
644 self.op2 = op2
645
646
647 def resultfn_8(data_o, expected, i, o):
648 res = expected.op1 + expected.op2 # these are a TestInputAdd instance
649 assert data_o == res, \
650 "%d-%d data %s res %x not match %s\n" \
651 % (i, o, repr(data_o), res, repr(expected))
652
653 def data_2op():
654 data = []
655 for i in range(num_tests):
656 data.append(TestInputAdd(randint(0, 1<<16-1), randint(0, 1<<16-1)))
657 return data
658
659
660 ######################################################################
661 # Test 12
662 ######################################################################
663
664 class ExampleStageDelayCls(StageCls, Elaboratable):
665 """ an example of how to use the buffered pipeline, in a static class
666 fashion
667 """
668
669 def __init__(self, valid_trigger=2):
670 self.count = Signal(2)
671 self.valid_trigger = valid_trigger
672
673 def ispec(self):
674 return Signal(16, name="example_input_signal")
675
676 def ospec(self):
677 return Signal(16, name="example_output_signal")
678
679 @property
680 def d_ready(self):
681 """ data is ready to be accepted when this is true
682 """
683 return (self.count == 1)# | (self.count == 3)
684 return Const(1)
685
686 def d_valid(self, ready_i):
687 """ data is valid at output when this is true
688 """
689 return self.count == self.valid_trigger
690 return Const(1)
691
692 def process(self, i):
693 """ process the input data and returns it (adds 1)
694 """
695 return i + 1
696
697 def elaborate(self, platform):
698 m = Module()
699 m.d.sync += self.count.eq(self.count + 1)
700 return m
701
702
703 class ExampleBufDelayedPipe(BufferedHandshake):
704
705 def __init__(self):
706 stage = ExampleStageDelayCls(valid_trigger=2)
707 BufferedHandshake.__init__(self, stage, stage_ctl=True)
708
709 def elaborate(self, platform):
710 m = BufferedHandshake.elaborate(self, platform)
711 m.submodules.stage = self.stage
712 return m
713
714
715 def data_chain1():
716 data = []
717 for i in range(num_tests):
718 data.append(1<<((i*3)%15))
719 #data.append(randint(0, 1<<16-2))
720 #print (hex(data[-1]))
721 return data
722
723
724 def resultfn_12(data_o, expected, i, o):
725 res = expected + 1
726 assert data_o == res, \
727 "%d-%d data %x not match %x\n" \
728 % (i, o, data_o, res)
729
730
731 ######################################################################
732 # Test 13
733 ######################################################################
734
735 class ExampleUnBufDelayedPipe(BufferedHandshake):
736
737 def __init__(self):
738 stage = ExampleStageDelayCls(valid_trigger=3)
739 BufferedHandshake.__init__(self, stage, stage_ctl=True)
740
741 def elaborate(self, platform):
742 m = BufferedHandshake.elaborate(self, platform)
743 m.submodules.stage = self.stage
744 return m
745
746 ######################################################################
747 # Test 15
748 ######################################################################
749
750 class ExampleBufModeAdd1Pipe(SimpleHandshake):
751
752 def __init__(self):
753 stage = ExampleStageCls()
754 SimpleHandshake.__init__(self, stage)
755
756
757 ######################################################################
758 # Test 16
759 ######################################################################
760
761 class ExampleBufModeUnBufPipe(ControlBase):
762
763 def elaborate(self, platform):
764 m = ControlBase.elaborate(self, platform)
765
766 pipe1 = ExampleBufModeAdd1Pipe()
767 pipe2 = ExampleBufAdd1Pipe()
768
769 m.submodules.pipe1 = pipe1
770 m.submodules.pipe2 = pipe2
771
772 m.d.comb += self.connect([pipe1, pipe2])
773
774 return m
775
776 ######################################################################
777 # Test 17
778 ######################################################################
779
780 class ExampleUnBufAdd1Pipe2(UnbufferedPipeline2):
781
782 def __init__(self):
783 stage = ExampleStageCls()
784 UnbufferedPipeline2.__init__(self, stage)
785
786
787 ######################################################################
788 # Test 18
789 ######################################################################
790
791 class PassThroughTest(PassThroughHandshake):
792
793 def iospecfn(self):
794 return Signal(16, "out")
795
796 def __init__(self):
797 stage = PassThroughStage(self.iospecfn)
798 PassThroughHandshake.__init__(self, stage)
799
800 def resultfn_identical(data_o, expected, i, o):
801 res = expected
802 assert data_o == res, \
803 "%d-%d data %x not match %x\n" \
804 % (i, o, data_o, res)
805
806
807 ######################################################################
808 # Test 19
809 ######################################################################
810
811 class ExamplePassAdd1Pipe(PassThroughHandshake):
812
813 def __init__(self):
814 stage = ExampleStageCls()
815 PassThroughHandshake.__init__(self, stage)
816
817
818 class ExampleBufPassThruPipe(ControlBase):
819
820 def elaborate(self, platform):
821 m = ControlBase.elaborate(self, platform)
822
823 # XXX currently fails: any other permutation works fine.
824 # p1=u,p2=b ok p1=u,p2=u ok p1=b,p2=b ok
825 # also fails using UnbufferedPipeline as well
826 pipe1 = ExampleBufModeAdd1Pipe()
827 pipe2 = ExamplePassAdd1Pipe()
828
829 m.submodules.pipe1 = pipe1
830 m.submodules.pipe2 = pipe2
831
832 m.d.comb += self.connect([pipe1, pipe2])
833
834 return m
835
836
837 ######################################################################
838 # Test 20
839 ######################################################################
840
841 def iospecfn():
842 return Signal(16, name="d_in")
843
844 class FIFOTest16(FIFOControl):
845
846 def __init__(self):
847 stage = PassThroughStage(iospecfn)
848 FIFOControl.__init__(self, 2, stage)
849
850
851 ######################################################################
852 # Test 21
853 ######################################################################
854
855 class ExampleFIFOPassThruPipe1(ControlBase):
856
857 def elaborate(self, platform):
858 m = ControlBase.elaborate(self, platform)
859
860 pipe1 = FIFOTest16()
861 pipe2 = FIFOTest16()
862 pipe3 = ExamplePassAdd1Pipe()
863
864 m.submodules.pipe1 = pipe1
865 m.submodules.pipe2 = pipe2
866 m.submodules.pipe3 = pipe3
867
868 m.d.comb += self.connect([pipe1, pipe2, pipe3])
869
870 return m
871
872
873 ######################################################################
874 # Test 22
875 ######################################################################
876
877 class Example2OpRecord(RecordObject):
878 def __init__(self):
879 RecordObject.__init__(self)
880 self.op1 = Signal(16)
881 self.op2 = Signal(16)
882
883
884 class ExampleAddRecordObjectStage(StageCls):
885
886 def ispec(self):
887 """ returns an instance of an Example2OpRecord.
888 """
889 return Example2OpRecord()
890
891 def ospec(self):
892 """ returns an output signal which will happen to contain the sum
893 of the two inputs
894 """
895 return Signal(16)
896
897 def process(self, i):
898 """ process the input data (sums the values in the tuple) and returns it
899 """
900 return i.op1 + i.op2
901
902
903 class ExampleRecordHandshakeAddClass(SimpleHandshake):
904
905 def __init__(self):
906 addstage = ExampleAddRecordObjectStage()
907 SimpleHandshake.__init__(self, stage=addstage)
908
909
910 ######################################################################
911 # Test 23
912 ######################################################################
913
914 def iospecfnrecord():
915 return Example2OpRecord()
916
917 class FIFOTestRecordControl(FIFOControl):
918
919 def __init__(self):
920 stage = PassThroughStage(iospecfnrecord)
921 FIFOControl.__init__(self, 2, stage)
922
923
924 class ExampleFIFORecordObjectPipe(ControlBase):
925
926 def elaborate(self, platform):
927 m = ControlBase.elaborate(self, platform)
928
929 pipe1 = FIFOTestRecordControl()
930 pipe2 = ExampleRecordHandshakeAddClass()
931
932 m.submodules.pipe1 = pipe1
933 m.submodules.pipe2 = pipe2
934
935 m.d.comb += self.connect([pipe1, pipe2])
936
937 return m
938
939
940 ######################################################################
941 # Test 24
942 ######################################################################
943
944 class FIFOTestRecordAddStageControl(FIFOControl):
945
946 def __init__(self):
947 stage = ExampleAddRecordObjectStage()
948 FIFOControl.__init__(self, 2, stage)
949
950
951
952 ######################################################################
953 # Test 25
954 ######################################################################
955
956 class FIFOTestAdd16(FIFOControl):
957
958 def __init__(self):
959 stage = ExampleStageCls()
960 FIFOControl.__init__(self, 2, stage)
961
962
963 class ExampleFIFOAdd2Pipe(ControlBase):
964
965 def elaborate(self, platform):
966 m = ControlBase.elaborate(self, platform)
967
968 pipe1 = FIFOTestAdd16()
969 pipe2 = FIFOTestAdd16()
970
971 m.submodules.pipe1 = pipe1
972 m.submodules.pipe2 = pipe2
973
974 m.d.comb += self.connect([pipe1, pipe2])
975
976 return m
977
978
979 ######################################################################
980 # Test 26
981 ######################################################################
982
983 def iospecfn24():
984 return (Signal(16, name="src1"), Signal(16, name="src2"))
985
986 class FIFOTest2x16(FIFOControl):
987
988 def __init__(self):
989 stage = PassThroughStage(iospecfn2)
990 FIFOControl.__init__(self, 2, stage)
991
992
993 ######################################################################
994 # Test 997
995 ######################################################################
996
997 class ExampleBufPassThruPipe2(ControlBase):
998
999 def elaborate(self, platform):
1000 m = ControlBase.elaborate(self, platform)
1001
1002 # XXX currently fails: any other permutation works fine.
1003 # p1=u,p2=b ok p1=u,p2=u ok p1=b,p2=b ok
1004 # also fails using UnbufferedPipeline as well
1005 #pipe1 = ExampleUnBufAdd1Pipe()
1006 #pipe2 = ExampleBufAdd1Pipe()
1007 pipe1 = ExampleBufAdd1Pipe()
1008 pipe2 = ExamplePassAdd1Pipe()
1009
1010 m.submodules.pipe1 = pipe1
1011 m.submodules.pipe2 = pipe2
1012
1013 m.d.comb += self.connect([pipe1, pipe2])
1014
1015 return m
1016
1017
1018 ######################################################################
1019 # Test 998
1020 ######################################################################
1021
1022 class ExampleBufPipe3(ControlBase):
1023 """ Example of how to do delayed pipeline, where the stage signals
1024 whether it is ready.
1025 """
1026
1027 def elaborate(self, platform):
1028 m = ControlBase.elaborate(self, platform)
1029
1030 pipe1 = ExampleBufDelayedPipe()
1031 pipe2 = ExampleBufPipe()
1032
1033 m.submodules.pipe1 = pipe1
1034 m.submodules.pipe2 = pipe2
1035
1036 m.d.comb += self.connect([pipe1, pipe2])
1037
1038 return m
1039
1040 ######################################################################
1041 # Test 999 - XXX FAILS
1042 # http://bugs.libre-riscv.org/show_bug.cgi?id=57
1043 ######################################################################
1044
1045 class ExampleBufAdd1Pipe(BufferedHandshake):
1046
1047 def __init__(self):
1048 stage = ExampleStageCls()
1049 BufferedHandshake.__init__(self, stage)
1050
1051
1052 class ExampleUnBufAdd1Pipe(UnbufferedPipeline):
1053
1054 def __init__(self):
1055 stage = ExampleStageCls()
1056 UnbufferedPipeline.__init__(self, stage)
1057
1058
1059 class ExampleBufUnBufPipe(ControlBase):
1060
1061 def elaborate(self, platform):
1062 m = ControlBase.elaborate(self, platform)
1063
1064 # XXX currently fails: any other permutation works fine.
1065 # p1=u,p2=b ok p1=u,p2=u ok p1=b,p2=b ok
1066 # also fails using UnbufferedPipeline as well
1067 #pipe1 = ExampleUnBufAdd1Pipe()
1068 #pipe2 = ExampleBufAdd1Pipe()
1069 pipe1 = ExampleBufAdd1Pipe()
1070 pipe2 = ExampleUnBufAdd1Pipe()
1071
1072 m.submodules.pipe1 = pipe1
1073 m.submodules.pipe2 = pipe2
1074
1075 m.d.comb += self.connect([pipe1, pipe2])
1076
1077 return m
1078
1079
1080 ######################################################################
1081 # Test 0
1082 ######################################################################
1083
1084 class ExampleMaskRecord(RecordObject):
1085 """ an example of a class used to store 2 operands.
1086 requires an eq function, to conform with the pipeline stage API
1087 """
1088
1089 def __init__(self):
1090 RecordObject.__init__(self)
1091 self.src1 = Signal(16)
1092 self.src2 = Signal(16)
1093
1094 def __eq(self, i):
1095 return [self.src1.eq(i.src1), self.src2.eq(i.src2)]
1096
1097
1098 class TestInputMask:
1099 """ the eq function, called by set_input, needs an incoming object
1100 that conforms to the Example2OpClass.eq function requirements
1101 easiest way to do that is to create a class that has the exact
1102 same member layout (self.op1, self.op2) as Example2OpClass
1103 """
1104 def __init__(self, src1, src2):
1105 self.src1 = src1
1106 self.src2 = src2
1107
1108 def __repr__(self):
1109 return "<TestInputMask %x %x" % (self.src1, self.src2)
1110
1111 class ExampleMaskCancellable(StageCls):
1112
1113 def ispec(self):
1114 """ returns an instance of an ExampleMaskRecord.
1115 """
1116 return ExampleMaskRecord()
1117
1118 def ospec(self):
1119 """ returns the same
1120 """
1121 return ExampleMaskRecord()
1122
1123 def process(self, i):
1124 """ process the input data: increase op1 and op2
1125 """
1126 return TestInputMask(i.src1 + 1, i.src2 + 1)
1127
1128
1129 class MaskCancellablePipe(MaskCancellable):
1130
1131 """ connects two stages together as a *single* combinatorial stage.
1132 """
1133 def __init__(self):
1134 self.cancelmask = Signal(16)
1135 stage1 = ExampleMaskCancellable()
1136 stage2 = ExampleMaskCancellable()
1137 combined = StageChain([stage1, stage2])
1138 MaskCancellable.__init__(self, combined, 16)
1139
1140
1141 def data_chain0():
1142 data = []
1143 for i in range(num_tests):
1144 data.append(TestInputMask(randint(0, 1<<16-1),
1145 randint(0, 1<<16-1)))
1146 return data
1147
1148
1149 def resultfn_0(data_o, expected, i, o):
1150 assert data_o['src1'] == expected.src1 + 2, \
1151 "src1 %x-%x received data no match\n" \
1152 % (data_o['src1'], expected.src1 + 2)
1153 assert data_o['src2'] == expected.src2 + 2, \
1154 "src2 %x-%x received data no match\n" \
1155 % (data_o['src2'] , expected.src2 + 2)
1156
1157
1158 ######################################################################
1159 # Unit Tests
1160 ######################################################################
1161
1162 num_tests = 10
1163
1164 def test0():
1165 print ("test 0")
1166 dut = MaskCancellablePipe()
1167 ports = [dut.p.valid_i, dut.n.ready_i,
1168 dut.n.valid_o, dut.p.ready_o] + \
1169 dut.p.data_i.ports() + dut.n.data_o.ports()
1170 vl = rtlil.convert(dut, ports=ports)
1171 with open("test_maskchain0.il", "w") as f:
1172 f.write(vl)
1173 data = data_chain0()
1174 test = TestMask(dut, resultfn_0, 16, data=data)
1175 run_simulation(dut, [test.send, test.rcv],
1176 vcd_name="test_maskchain0.vcd")
1177
1178 def notworking1():
1179 print ("test 1")
1180 dut = ExampleBufPipe()
1181 run_simulation(dut, tbench(dut), vcd_name="test_bufpipe.vcd")
1182
1183 def notworking2():
1184 print ("test 2")
1185 dut = ExampleBufPipe2()
1186 run_simulation(dut, tbench2(dut), vcd_name="test_bufpipe2.vcd")
1187 ports = [dut.p.valid_i, dut.n.ready_i,
1188 dut.n.valid_o, dut.p.ready_o] + \
1189 [dut.p.data_i] + [dut.n.data_o]
1190 vl = rtlil.convert(dut, ports=ports)
1191 with open("test_bufpipe2.il", "w") as f:
1192 f.write(vl)
1193
1194 def test3():
1195 print ("test 3")
1196 dut = ExampleBufPipe()
1197 test = Test3(dut, resultfn_3)
1198 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe3.vcd")
1199
1200 def test3_5():
1201 print ("test 3.5")
1202 dut = ExamplePipeline()
1203 test = Test3(dut, resultfn_3)
1204 run_simulation(dut, [test.send, test.rcv], vcd_name="test_combpipe3.vcd")
1205
1206 def test4():
1207 print ("test 4")
1208 dut = ExampleBufPipe2()
1209 run_simulation(dut, tbench4(dut), vcd_name="test_bufpipe4.vcd")
1210
1211 def test5():
1212 print ("test 5")
1213 dut = ExampleBufPipeAdd()
1214 test = Test5(dut, resultfn_5, stage_ctl=True)
1215 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe5.vcd")
1216
1217 def test6():
1218 print ("test 6")
1219 dut = ExampleLTPipeline()
1220 test = Test5(dut, resultfn_6)
1221 run_simulation(dut, [test.send, test.rcv], vcd_name="test_ltcomb6.vcd")
1222
1223 ports = [dut.p.valid_i, dut.n.ready_i,
1224 dut.n.valid_o, dut.p.ready_o] + \
1225 list(dut.p.data_i) + [dut.n.data_o]
1226 vl = rtlil.convert(dut, ports=ports)
1227 with open("test_ltcomb_pipe.il", "w") as f:
1228 f.write(vl)
1229
1230 def test7():
1231 print ("test 7")
1232 dut = ExampleAddRecordPipe()
1233 data=data_dict()
1234 test = Test5(dut, resultfn_7, data=data)
1235 ports = [dut.p.valid_i, dut.n.ready_i,
1236 dut.n.valid_o, dut.p.ready_o,
1237 dut.p.data_i.src1, dut.p.data_i.src2,
1238 dut.n.data_o.src1, dut.n.data_o.src2]
1239 vl = rtlil.convert(dut, ports=ports)
1240 with open("test_recordcomb_pipe.il", "w") as f:
1241 f.write(vl)
1242 run_simulation(dut, [test.send, test.rcv], vcd_name="test_addrecord.vcd")
1243
1244 def test8():
1245 print ("test 8")
1246 dut = ExampleBufPipeAddClass()
1247 data=data_2op()
1248 test = Test5(dut, resultfn_8, data=data)
1249 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe8.vcd")
1250
1251 def test9():
1252 print ("test 9")
1253 dut = ExampleBufPipeChain2()
1254 ports = [dut.p.valid_i, dut.n.ready_i,
1255 dut.n.valid_o, dut.p.ready_o] + \
1256 [dut.p.data_i] + [dut.n.data_o]
1257 vl = rtlil.convert(dut, ports=ports)
1258 with open("test_bufpipechain2.il", "w") as f:
1259 f.write(vl)
1260
1261 data = data_chain2()
1262 test = Test5(dut, resultfn_9, data=data)
1263 run_simulation(dut, [test.send, test.rcv],
1264 vcd_name="test_bufpipechain2.vcd")
1265
1266 def test10():
1267 print ("test 10")
1268 dut = ExampleLTBufferedPipeDerived()
1269 test = Test5(dut, resultfn_6)
1270 run_simulation(dut, [test.send, test.rcv], vcd_name="test_ltbufpipe10.vcd")
1271 ports = dut.ports()
1272 vl = rtlil.convert(dut, ports=ports)
1273 with open("test_ltbufpipe10.il", "w") as f:
1274 f.write(vl)
1275
1276 def test11():
1277 print ("test 11")
1278 dut = ExampleAddRecordPlaceHolderPipe()
1279 data=data_placeholder()
1280 test = Test5(dut, resultfn_11, data=data)
1281 run_simulation(dut, [test.send, test.rcv], vcd_name="test_addrecord.vcd")
1282
1283
1284 def test12():
1285 print ("test 12")
1286 dut = ExampleBufDelayedPipe()
1287 data = data_chain1()
1288 test = Test5(dut, resultfn_12, data=data)
1289 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe12.vcd")
1290 ports = [dut.p.valid_i, dut.n.ready_i,
1291 dut.n.valid_o, dut.p.ready_o] + \
1292 [dut.p.data_i] + [dut.n.data_o]
1293 vl = rtlil.convert(dut, ports=ports)
1294 with open("test_bufpipe12.il", "w") as f:
1295 f.write(vl)
1296
1297 def test13():
1298 print ("test 13")
1299 dut = ExampleUnBufDelayedPipe()
1300 data = data_chain1()
1301 test = Test5(dut, resultfn_12, data=data)
1302 run_simulation(dut, [test.send, test.rcv], vcd_name="test_unbufpipe13.vcd")
1303 ports = [dut.p.valid_i, dut.n.ready_i,
1304 dut.n.valid_o, dut.p.ready_o] + \
1305 [dut.p.data_i] + [dut.n.data_o]
1306 vl = rtlil.convert(dut, ports=ports)
1307 with open("test_unbufpipe13.il", "w") as f:
1308 f.write(vl)
1309
1310 def test15():
1311 print ("test 15")
1312 dut = ExampleBufModeAdd1Pipe()
1313 data = data_chain1()
1314 test = Test5(dut, resultfn_12, data=data)
1315 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufunbuf15.vcd")
1316 ports = [dut.p.valid_i, dut.n.ready_i,
1317 dut.n.valid_o, dut.p.ready_o] + \
1318 [dut.p.data_i] + [dut.n.data_o]
1319 vl = rtlil.convert(dut, ports=ports)
1320 with open("test_bufunbuf15.il", "w") as f:
1321 f.write(vl)
1322
1323 def test16():
1324 print ("test 16")
1325 dut = ExampleBufModeUnBufPipe()
1326 data = data_chain1()
1327 test = Test5(dut, resultfn_9, data=data)
1328 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufunbuf16.vcd")
1329 ports = [dut.p.valid_i, dut.n.ready_i,
1330 dut.n.valid_o, dut.p.ready_o] + \
1331 [dut.p.data_i] + [dut.n.data_o]
1332 vl = rtlil.convert(dut, ports=ports)
1333 with open("test_bufunbuf16.il", "w") as f:
1334 f.write(vl)
1335
1336 def test17():
1337 print ("test 17")
1338 dut = ExampleUnBufAdd1Pipe2()
1339 data = data_chain1()
1340 test = Test5(dut, resultfn_12, data=data)
1341 run_simulation(dut, [test.send, test.rcv], vcd_name="test_unbufpipe17.vcd")
1342 ports = [dut.p.valid_i, dut.n.ready_i,
1343 dut.n.valid_o, dut.p.ready_o] + \
1344 [dut.p.data_i] + [dut.n.data_o]
1345 vl = rtlil.convert(dut, ports=ports)
1346 with open("test_unbufpipe17.il", "w") as f:
1347 f.write(vl)
1348
1349 def test18():
1350 print ("test 18")
1351 dut = PassThroughTest()
1352 data = data_chain1()
1353 test = Test5(dut, resultfn_identical, data=data)
1354 run_simulation(dut, [test.send, test.rcv], vcd_name="test_passthru18.vcd")
1355 ports = [dut.p.valid_i, dut.n.ready_i,
1356 dut.n.valid_o, dut.p.ready_o] + \
1357 [dut.p.data_i] + [dut.n.data_o]
1358 vl = rtlil.convert(dut, ports=ports)
1359 with open("test_passthru18.il", "w") as f:
1360 f.write(vl)
1361
1362 def test19():
1363 print ("test 19")
1364 dut = ExampleBufPassThruPipe()
1365 data = data_chain1()
1366 test = Test5(dut, resultfn_9, data=data)
1367 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpass19.vcd")
1368 ports = [dut.p.valid_i, dut.n.ready_i,
1369 dut.n.valid_o, dut.p.ready_o] + \
1370 [dut.p.data_i] + [dut.n.data_o]
1371 vl = rtlil.convert(dut, ports=ports)
1372 with open("test_bufpass19.il", "w") as f:
1373 f.write(vl)
1374
1375 def test20():
1376 print ("test 20")
1377 dut = FIFOTest16()
1378 data = data_chain1()
1379 test = Test5(dut, resultfn_identical, data=data)
1380 run_simulation(dut, [test.send, test.rcv], vcd_name="test_fifo20.vcd")
1381 ports = [dut.p.valid_i, dut.n.ready_i,
1382 dut.n.valid_o, dut.p.ready_o] + \
1383 [dut.p.data_i] + [dut.n.data_o]
1384 vl = rtlil.convert(dut, ports=ports)
1385 with open("test_fifo20.il", "w") as f:
1386 f.write(vl)
1387
1388 def test21():
1389 print ("test 21")
1390 dut = ExampleFIFOPassThruPipe1()
1391 data = data_chain1()
1392 test = Test5(dut, resultfn_12, data=data)
1393 run_simulation(dut, [test.send, test.rcv], vcd_name="test_fifopass21.vcd")
1394 ports = [dut.p.valid_i, dut.n.ready_i,
1395 dut.n.valid_o, dut.p.ready_o] + \
1396 [dut.p.data_i] + [dut.n.data_o]
1397 vl = rtlil.convert(dut, ports=ports)
1398 with open("test_fifopass21.il", "w") as f:
1399 f.write(vl)
1400
1401 def test22():
1402 print ("test 22")
1403 dut = ExampleRecordHandshakeAddClass()
1404 data=data_2op()
1405 test = Test5(dut, resultfn_8, data=data)
1406 run_simulation(dut, [test.send, test.rcv], vcd_name="test_addrecord22.vcd")
1407 ports = [dut.p.valid_i, dut.n.ready_i,
1408 dut.n.valid_o, dut.p.ready_o] + \
1409 [dut.p.data_i.op1, dut.p.data_i.op2] + \
1410 [dut.n.data_o]
1411 vl = rtlil.convert(dut, ports=ports)
1412 with open("test_addrecord22.il", "w") as f:
1413 f.write(vl)
1414
1415 def test23():
1416 print ("test 23")
1417 dut = ExampleFIFORecordObjectPipe()
1418 data=data_2op()
1419 test = Test5(dut, resultfn_8, data=data)
1420 run_simulation(dut, [test.send, test.rcv], vcd_name="test_addrecord23.vcd")
1421 ports = [dut.p.valid_i, dut.n.ready_i,
1422 dut.n.valid_o, dut.p.ready_o] + \
1423 [dut.p.data_i.op1, dut.p.data_i.op2] + \
1424 [dut.n.data_o]
1425 vl = rtlil.convert(dut, ports=ports)
1426 with open("test_addrecord23.il", "w") as f:
1427 f.write(vl)
1428
1429 def test24():
1430 print ("test 24")
1431 dut = FIFOTestRecordAddStageControl()
1432 data=data_2op()
1433 test = Test5(dut, resultfn_8, data=data)
1434 ports = [dut.p.valid_i, dut.n.ready_i,
1435 dut.n.valid_o, dut.p.ready_o] + \
1436 [dut.p.data_i.op1, dut.p.data_i.op2] + \
1437 [dut.n.data_o]
1438 vl = rtlil.convert(dut, ports=ports)
1439 with open("test_addrecord24.il", "w") as f:
1440 f.write(vl)
1441 run_simulation(dut, [test.send, test.rcv], vcd_name="test_addrecord24.vcd")
1442
1443 def test25():
1444 print ("test 25")
1445 dut = ExampleFIFOAdd2Pipe()
1446 data = data_chain1()
1447 test = Test5(dut, resultfn_9, data=data)
1448 run_simulation(dut, [test.send, test.rcv], vcd_name="test_add2pipe25.vcd")
1449 ports = [dut.p.valid_i, dut.n.ready_i,
1450 dut.n.valid_o, dut.p.ready_o] + \
1451 [dut.p.data_i] + [dut.n.data_o]
1452 vl = rtlil.convert(dut, ports=ports)
1453 with open("test_add2pipe25.il", "w") as f:
1454 f.write(vl)
1455
1456 def test997():
1457 print ("test 997")
1458 dut = ExampleBufPassThruPipe2()
1459 data = data_chain1()
1460 test = Test5(dut, resultfn_9, data=data)
1461 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpass997.vcd")
1462 ports = [dut.p.valid_i, dut.n.ready_i,
1463 dut.n.valid_o, dut.p.ready_o] + \
1464 [dut.p.data_i] + [dut.n.data_o]
1465 vl = rtlil.convert(dut, ports=ports)
1466 with open("test_bufpass997.il", "w") as f:
1467 f.write(vl)
1468
1469 def test998():
1470 print ("test 998 (fails, bug)")
1471 dut = ExampleBufPipe3()
1472 data = data_chain1()
1473 test = Test5(dut, resultfn_9, data=data)
1474 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufpipe14.vcd")
1475 ports = [dut.p.valid_i, dut.n.ready_i,
1476 dut.n.valid_o, dut.p.ready_o] + \
1477 [dut.p.data_i] + [dut.n.data_o]
1478 vl = rtlil.convert(dut, ports=ports)
1479 with open("test_bufpipe14.il", "w") as f:
1480 f.write(vl)
1481
1482 def test999():
1483 print ("test 999 (expected to fail, which is a bug)")
1484 dut = ExampleBufUnBufPipe()
1485 data = data_chain1()
1486 test = Test5(dut, resultfn_9, data=data)
1487 run_simulation(dut, [test.send, test.rcv], vcd_name="test_bufunbuf999.vcd")
1488 ports = [dut.p.valid_i, dut.n.ready_i,
1489 dut.n.valid_o, dut.p.ready_o] + \
1490 [dut.p.data_i] + [dut.n.data_o]
1491 vl = rtlil.convert(dut, ports=ports)
1492 with open("test_bufunbuf999.il", "w") as f:
1493 f.write(vl)
1494
1495 if __name__ == '__main__':
1496 test0()