@@ -350,3 +350,268 @@ def sim_test():
350
350
with Simulator (m , vcd_file = open ("test.vcd" , "w" )) as sim :
351
351
sim .add_process (sim_test ())
352
352
sim .run ()
353
+
354
+
355
+ class ArbiterTestCase (unittest .TestCase ):
356
+ def setUp (self ):
357
+ self .dut = Arbiter (addr_width = 31 , data_width = 32 , granularity = 16 ,
358
+ features = {"err" })
359
+
360
+ def test_add_wrong (self ):
361
+ with self .assertRaisesRegex (TypeError ,
362
+ r"Initiator bus must be an instance of wishbone\.Interface, not 'foo'" ):
363
+ self .dut .add ("foo" )
364
+
365
+ def test_add_wrong_addr_width (self ):
366
+ with self .assertRaisesRegex (ValueError ,
367
+ r"Initiator bus has address width 15, which is not the same as arbiter "
368
+ r"address width 31" ):
369
+ self .dut .add (Interface (addr_width = 15 , data_width = 32 , granularity = 16 ))
370
+
371
+ def test_add_wrong_granularity (self ):
372
+ with self .assertRaisesRegex (ValueError ,
373
+ r"Initiator bus has granularity 8, which is lesser than "
374
+ r"the arbiter granularity 16" ):
375
+ self .dut .add (Interface (addr_width = 31 , data_width = 32 , granularity = 8 ))
376
+
377
+ def test_add_wrong_data_width (self ):
378
+ with self .assertRaisesRegex (ValueError ,
379
+ r"Initiator bus has data width 16, which is not the same as arbiter "
380
+ r"data width 32" ):
381
+ self .dut .add (Interface (addr_width = 31 , data_width = 16 , granularity = 16 ))
382
+
383
+ def test_add_wrong_optional_output (self ):
384
+ with self .assertRaisesRegex (ValueError ,
385
+ r"Arbiter has optional output 'err', but the initiator bus does "
386
+ r"not have a corresponding input" ):
387
+ self .dut .add (Interface (addr_width = 31 , data_width = 32 , granularity = 16 ))
388
+
389
+
390
+ class ArbiterSimulationTestCase (unittest .TestCase ):
391
+ def test_simple (self ):
392
+ dut = Arbiter (addr_width = 30 , data_width = 32 , granularity = 8 ,
393
+ features = {"err" , "rty" , "stall" , "lock" , "cti" , "bte" })
394
+ intr_1 = Interface (addr_width = 30 , data_width = 32 , granularity = 8 ,
395
+ features = {"err" , "rty" })
396
+ dut .add (intr_1 )
397
+ intr_2 = Interface (addr_width = 30 , data_width = 32 , granularity = 16 ,
398
+ features = {"err" , "rty" , "stall" , "lock" , "cti" , "bte" })
399
+ dut .add (intr_2 )
400
+
401
+ def sim_test ():
402
+ yield intr_1 .adr .eq (0x7ffffffc >> 2 )
403
+ yield intr_1 .cyc .eq (1 )
404
+ yield intr_1 .stb .eq (1 )
405
+ yield intr_1 .sel .eq (0b1111 )
406
+ yield intr_1 .we .eq (1 )
407
+ yield intr_1 .dat_w .eq (0x12345678 )
408
+ yield dut .bus .dat_r .eq (0xabcdef01 )
409
+ yield dut .bus .ack .eq (1 )
410
+ yield dut .bus .err .eq (1 )
411
+ yield dut .bus .rty .eq (1 )
412
+ yield Delay (1e-7 )
413
+ self .assertEqual ((yield dut .bus .adr ), 0x7ffffffc >> 2 )
414
+ self .assertEqual ((yield dut .bus .cyc ), 1 )
415
+ self .assertEqual ((yield dut .bus .stb ), 1 )
416
+ self .assertEqual ((yield dut .bus .sel ), 0b1111 )
417
+ self .assertEqual ((yield dut .bus .we ), 1 )
418
+ self .assertEqual ((yield dut .bus .dat_w ), 0x12345678 )
419
+ self .assertEqual ((yield dut .bus .lock ), 1 )
420
+ self .assertEqual ((yield dut .bus .cti ), CycleType .CLASSIC .value )
421
+ self .assertEqual ((yield dut .bus .bte ), BurstTypeExt .LINEAR .value )
422
+ self .assertEqual ((yield intr_1 .dat_r ), 0xabcdef01 )
423
+ self .assertEqual ((yield intr_1 .ack ), 1 )
424
+ self .assertEqual ((yield intr_1 .err ), 1 )
425
+ self .assertEqual ((yield intr_1 .rty ), 1 )
426
+
427
+ yield intr_1 .cyc .eq (0 )
428
+ yield intr_2 .adr .eq (0xe0000000 >> 2 )
429
+ yield intr_2 .cyc .eq (1 )
430
+ yield intr_2 .stb .eq (1 )
431
+ yield intr_2 .sel .eq (0b10 )
432
+ yield intr_2 .we .eq (1 )
433
+ yield intr_2 .dat_w .eq (0x43218765 )
434
+ yield intr_2 .lock .eq (0 )
435
+ yield intr_2 .cti .eq (CycleType .INCR_BURST )
436
+ yield intr_2 .bte .eq (BurstTypeExt .WRAP_4 )
437
+ yield Tick ()
438
+
439
+ yield dut .bus .stall .eq (0 )
440
+ yield Delay (1e-7 )
441
+ self .assertEqual ((yield dut .bus .adr ), 0xe0000000 >> 2 )
442
+ self .assertEqual ((yield dut .bus .cyc ), 1 )
443
+ self .assertEqual ((yield dut .bus .stb ), 1 )
444
+ self .assertEqual ((yield dut .bus .sel ), 0b1100 )
445
+ self .assertEqual ((yield dut .bus .we ), 1 )
446
+ self .assertEqual ((yield dut .bus .dat_w ), 0x43218765 )
447
+ self .assertEqual ((yield dut .bus .lock ), 0 )
448
+ self .assertEqual ((yield dut .bus .cti ), CycleType .INCR_BURST .value )
449
+ self .assertEqual ((yield dut .bus .bte ), BurstTypeExt .WRAP_4 .value )
450
+ self .assertEqual ((yield intr_2 .dat_r ), 0xabcdef01 )
451
+ self .assertEqual ((yield intr_2 .ack ), 1 )
452
+ self .assertEqual ((yield intr_2 .err ), 1 )
453
+ self .assertEqual ((yield intr_2 .rty ), 1 )
454
+ self .assertEqual ((yield intr_2 .stall ), 0 )
455
+
456
+ with Simulator (dut , vcd_file = open ("test.vcd" , "w" )) as sim :
457
+ sim .add_clock (1e-6 )
458
+ sim .add_sync_process (sim_test ())
459
+ sim .run ()
460
+
461
+ def test_lock (self ):
462
+ dut = Arbiter (addr_width = 30 , data_width = 32 , features = {"lock" })
463
+ intr_1 = Interface (addr_width = 30 , data_width = 32 , features = {"lock" })
464
+ dut .add (intr_1 )
465
+ intr_2 = Interface (addr_width = 30 , data_width = 32 , features = {"lock" })
466
+ dut .add (intr_2 )
467
+
468
+ def sim_test ():
469
+ yield intr_1 .cyc .eq (1 )
470
+ yield intr_1 .lock .eq (1 )
471
+ yield intr_2 .cyc .eq (1 )
472
+ yield dut .bus .ack .eq (1 )
473
+ yield Delay (1e-7 )
474
+ self .assertEqual ((yield intr_1 .ack ), 1 )
475
+ self .assertEqual ((yield intr_2 .ack ), 0 )
476
+
477
+ yield Tick ()
478
+ yield Delay (1e-7 )
479
+ self .assertEqual ((yield intr_1 .ack ), 1 )
480
+ self .assertEqual ((yield intr_2 .ack ), 0 )
481
+
482
+ yield intr_1 .lock .eq (0 )
483
+ yield Tick ()
484
+ yield Delay (1e-7 )
485
+ self .assertEqual ((yield intr_1 .ack ), 0 )
486
+ self .assertEqual ((yield intr_2 .ack ), 1 )
487
+
488
+ yield intr_2 .cyc .eq (0 )
489
+ yield Tick ()
490
+ yield Delay (1e-7 )
491
+ self .assertEqual ((yield intr_1 .ack ), 1 )
492
+ self .assertEqual ((yield intr_2 .ack ), 0 )
493
+
494
+ yield intr_1 .stb .eq (1 )
495
+ yield Tick ()
496
+ yield Delay (1e-7 )
497
+ self .assertEqual ((yield intr_1 .ack ), 1 )
498
+ self .assertEqual ((yield intr_2 .ack ), 0 )
499
+
500
+ yield intr_1 .stb .eq (0 )
501
+ yield intr_2 .cyc .eq (1 )
502
+ yield Tick ()
503
+ yield Delay (1e-7 )
504
+ self .assertEqual ((yield intr_1 .ack ), 0 )
505
+ self .assertEqual ((yield intr_2 .ack ), 1 )
506
+
507
+ with Simulator (dut , vcd_file = open ("test.vcd" , "w" )) as sim :
508
+ sim .add_clock (1e-6 )
509
+ sim .add_sync_process (sim_test ())
510
+ sim .run ()
511
+
512
+ def test_stall (self ):
513
+ dut = Arbiter (addr_width = 30 , data_width = 32 , features = {"stall" })
514
+ intr_1 = Interface (addr_width = 30 , data_width = 32 , features = {"stall" })
515
+ dut .add (intr_1 )
516
+ intr_2 = Interface (addr_width = 30 , data_width = 32 , features = {"stall" })
517
+ dut .add (intr_2 )
518
+
519
+ def sim_test ():
520
+ yield intr_1 .cyc .eq (1 )
521
+ yield intr_2 .cyc .eq (1 )
522
+ yield dut .bus .stall .eq (0 )
523
+ yield Delay (1e-6 )
524
+ self .assertEqual ((yield intr_1 .stall ), 0 )
525
+ self .assertEqual ((yield intr_2 .stall ), 1 )
526
+
527
+ yield dut .bus .stall .eq (1 )
528
+ yield Delay (1e-6 )
529
+ self .assertEqual ((yield intr_1 .stall ), 1 )
530
+ self .assertEqual ((yield intr_2 .stall ), 1 )
531
+
532
+ with Simulator (dut , vcd_file = open ("test.vcd" , "w" )) as sim :
533
+ sim .add_process (sim_test ())
534
+ sim .run ()
535
+
536
+ def test_stall_compat (self ):
537
+ dut = Arbiter (addr_width = 30 , data_width = 32 )
538
+ intr_1 = Interface (addr_width = 30 , data_width = 32 , features = {"stall" })
539
+ dut .add (intr_1 )
540
+ intr_2 = Interface (addr_width = 30 , data_width = 32 , features = {"stall" })
541
+ dut .add (intr_2 )
542
+
543
+ def sim_test ():
544
+ yield intr_1 .cyc .eq (1 )
545
+ yield intr_2 .cyc .eq (1 )
546
+ yield Delay (1e-6 )
547
+ self .assertEqual ((yield intr_1 .stall ), 1 )
548
+ self .assertEqual ((yield intr_2 .stall ), 1 )
549
+
550
+ yield dut .bus .ack .eq (1 )
551
+ yield Delay (1e-6 )
552
+ self .assertEqual ((yield intr_1 .stall ), 0 )
553
+ self .assertEqual ((yield intr_2 .stall ), 1 )
554
+
555
+ with Simulator (dut , vcd_file = open ("test.vcd" , "w" )) as sim :
556
+ sim .add_process (sim_test ())
557
+ sim .run ()
558
+
559
+ def test_roundrobin (self ):
560
+ dut = Arbiter (addr_width = 30 , data_width = 32 )
561
+ intr_1 = Interface (addr_width = 30 , data_width = 32 )
562
+ dut .add (intr_1 )
563
+ intr_2 = Interface (addr_width = 30 , data_width = 32 )
564
+ dut .add (intr_2 )
565
+ intr_3 = Interface (addr_width = 30 , data_width = 32 )
566
+ dut .add (intr_3 )
567
+
568
+ def sim_test ():
569
+ yield intr_1 .cyc .eq (1 )
570
+ yield intr_2 .cyc .eq (0 )
571
+ yield intr_3 .cyc .eq (1 )
572
+ yield dut .bus .ack .eq (1 )
573
+ yield Delay (1e-7 )
574
+ self .assertEqual ((yield intr_1 .ack ), 1 )
575
+ self .assertEqual ((yield intr_2 .ack ), 0 )
576
+ self .assertEqual ((yield intr_3 .ack ), 0 )
577
+
578
+ yield intr_1 .cyc .eq (0 )
579
+ yield intr_2 .cyc .eq (0 )
580
+ yield intr_3 .cyc .eq (1 )
581
+ yield Tick ()
582
+ yield Delay (1e-7 )
583
+ self .assertEqual ((yield intr_1 .ack ), 0 )
584
+ self .assertEqual ((yield intr_2 .ack ), 0 )
585
+ self .assertEqual ((yield intr_3 .ack ), 1 )
586
+
587
+ yield intr_1 .cyc .eq (1 )
588
+ yield intr_2 .cyc .eq (1 )
589
+ yield intr_3 .cyc .eq (0 )
590
+ yield Tick ()
591
+ yield Delay (1e-7 )
592
+ self .assertEqual ((yield intr_1 .ack ), 1 )
593
+ self .assertEqual ((yield intr_2 .ack ), 0 )
594
+ self .assertEqual ((yield intr_3 .ack ), 0 )
595
+
596
+ yield intr_1 .cyc .eq (0 )
597
+ yield intr_2 .cyc .eq (1 )
598
+ yield intr_3 .cyc .eq (1 )
599
+ yield Tick ()
600
+ yield Delay (1e-7 )
601
+ self .assertEqual ((yield intr_1 .ack ), 0 )
602
+ self .assertEqual ((yield intr_2 .ack ), 1 )
603
+ self .assertEqual ((yield intr_3 .ack ), 0 )
604
+
605
+ yield intr_1 .cyc .eq (1 )
606
+ yield intr_2 .cyc .eq (0 )
607
+ yield intr_3 .cyc .eq (1 )
608
+ yield Tick ()
609
+ yield Delay (1e-7 )
610
+ self .assertEqual ((yield intr_1 .ack ), 0 )
611
+ self .assertEqual ((yield intr_2 .ack ), 0 )
612
+ self .assertEqual ((yield intr_3 .ack ), 1 )
613
+
614
+ with Simulator (dut , vcd_file = open ("test.vcd" , "w" )) as sim :
615
+ sim .add_clock (1e-6 )
616
+ sim .add_sync_process (sim_test ())
617
+ sim .run ()
0 commit comments