Subversion Repositories zxusbnet

Rev

Rev 82 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
15 lvd 1
// ZXiznet project
2
// (c) NedoPC 2012
3
//
4
// testbench
5
 
6
 
76 lvd 7
`timescale 1ns/100ps
15 lvd 8
 
72 lvd 9
//// CPU at 14MHz
81 lvd 10
`define HALF_CPU_PERIOD (35.7)
15 lvd 11
 
72 lvd 12
// CPU at 7MHz
75 lvd 13
//`define HALF_CPU_PERIOD (70)
15 lvd 14
 
72 lvd 15
// filter clock
81 lvd 16
`define HALF_FCLK_PERIOD (10.4)
72 lvd 17
 
15 lvd 18
module tb;
19
 
20
        reg rst_n;
21
        reg clk;
22
 
72 lvd 23
        reg fclk;
15 lvd 24
 
72 lvd 25
 
15 lvd 26
        tri1 iorq_n,
27
             mreq_n,
28
             rd_n,
29
             wr_n;
30
 
30 lvd 31
        tri1 int_n;
16 lvd 32
 
33
        wire csrom_n;
34
 
35
        wire iorqge,
36
             blkrom;
37
 
38
 
15 lvd 39
        wire [15:0] a;
40
        wire [ 7:0] d;
41
 
82 lvd 42
        tri  [ 7:0] #1 bd;
15 lvd 43
 
28 lvd 44
        wire brd_n, bwr_n;
45
 
46
 
15 lvd 47
        reg [7:0] tmp;
48
 
49
 
50
 
51
 
16 lvd 52
        wire [9:0] w5300_addr;
53
        wire       w5300_rst_n;
54
        wire       w5300_cs_n;
55
        wire       w5300_int_n;
56
 
57
        wire       sl811_rst_n;
58
        wire       sl811_a0;
59
        wire       sl811_cs_n;
29 lvd 60
        wire       sl811_ms_n;
16 lvd 61
        wire       sl811_intrq;
62
 
29 lvd 63
 
64
 
23 lvd 65
        reg usb_power;
16 lvd 66
 
23 lvd 67
 
16 lvd 68
        reg [1:0] where_rom;
69
 
70
 
71
 
72
 
72 lvd 73
        // filter clock
74
        initial
75
        begin
76
                fclk = 1'b1;
16 lvd 77
 
72 lvd 78
                forever #`HALF_FCLK_PERIOD fclk = ~fclk;
79
        end
80
 
81
 
15 lvd 82
        initial
83
        begin
84
                clk = 1'b1;
85
 
86
                forever #`HALF_CPU_PERIOD clk = ~clk;
87
        end
88
 
89
 
90
        initial
91
        begin
92
                rst_n = 1'b0;
93
 
94
                repeat(3) @(posedge clk);
95
 
96
                rst_n <= 1'b1;
97
        end
98
 
99
 
100
 
16 lvd 101
        initial
102
        begin
103
                where_rom = 2'b00;
33 lvd 104
 
105
                usb_power = 1'b0;
16 lvd 106
        end
15 lvd 107
 
16 lvd 108
 
109
 
110
 
15 lvd 111
 
112
 
113
 
114
 
115
        top DUT
116
        (
72 lvd 117
                .fclk(fclk),
81 lvd 118
 
15 lvd 119
                .za(a),
120
                .zd(d),
121
 
122
                .ziorq_n(iorq_n),
123
                .zmreq_n(mreq_n),
124
                .zrd_n(rd_n),
125
                .zwr_n(wr_n),
126
 
16 lvd 127
                .zcsrom_n(csrom_n),
128
 
129
                .ziorqge(iorqge),
130
                .zblkrom(blkrom),
15 lvd 131
 
16 lvd 132
                .zrst_n(rst_n),
133
                .zint_n(int_n),
15 lvd 134
 
28 lvd 135
                .bd(bd),
16 lvd 136
 
28 lvd 137
                .bwr_n(bwr_n),
138
                .brd_n(brd_n),
139
 
140
 
16 lvd 141
                .w5300_rst_n(w5300_rst_n),
142
                .w5300_addr (w5300_addr ),
143
                .w5300_cs_n (w5300_cs_n ),
144
                .w5300_int_n(w5300_int_n),
145
 
146
                .sl811_rst_n(sl811_rst_n),
147
                .sl811_intrq(sl811_intrq),
28 lvd 148
                .sl811_ms_n (sl811_ms_n ),
16 lvd 149
                .sl811_cs_n (sl811_cs_n ),
23 lvd 150
                .sl811_a0   (sl811_a0   ),
16 lvd 151
 
23 lvd 152
                .usb_power(usb_power)
153
 
15 lvd 154
        );
155
 
156
 
157
 
158
 
159
 
160
 
161
 
162
 
163
 
164
 
165
 
166
 
29 lvd 167
        ssz80 z
15 lvd 168
        (
169
                .clk  (clk  ),
170
                .rst_n(rst_n),
171
 
172
                .iorq_n(iorq_n),
173
                .mreq_n(mreq_n),
174
                .rd_n  (rd_n  ),
175
                .wr_n  (wr_n  ),
176
 
177
                .a(a),
178
                .d(d)
179
        );
180
 
181
 
182
 
183
 
184
 
29 lvd 185
        w5300 w
16 lvd 186
        (
187
                .rst_n(w5300_rst_n),
188
                .addr (w5300_addr ),
189
                .cs_n (w5300_cs_n ),
28 lvd 190
                .rd_n (brd_n      ),
191
                .wr_n (bwr_n      ),
23 lvd 192
                .int_n(w5300_int_n),
28 lvd 193
                .d(bd)
16 lvd 194
        );
195
 
196
 
29 lvd 197
        sl811 s
16 lvd 198
        (
199
                .rst_n(sl811_rst_n),
200
                .a0   (sl811_a0   ),
201
                .cs_n (sl811_cs_n ),
28 lvd 202
                .wr_n (bwr_n      ),
203
                .rd_n (brd_n      ),
204
                .ms   (~sl811_ms_n),
205
                .intrq(sl811_intrq),
206
                .d(bd)
16 lvd 207
        );
208
 
209
 
29 lvd 210
        // csrom gen
30 lvd 211
        assign csrom_n = !(a[15:14]==where_rom[1:0]);
16 lvd 212
 
29 lvd 213
 
214
 
215
 
216
 
217
 
218
////////////////////////////////////////////////////////////////////////////////        
219
////////////////////////////////////////////////////////////////////////////////        
220
////////////////////////////////////////////////////////////////////////////////        
221
/// here start tests
16 lvd 222
 
30 lvd 223
        reg [15:0] rstint_port = 16'h83_AB;
224
        reg [15:0] w5300_port  = 16'h82_AB;
225
        reg [15:0] sl811_port  = 16'h81_AB;
226
        reg [15:0] sl_addr     = 16'h80_AB;
227
        reg [15:0] sl_data     = 16'h7F_AB;
228
 
29 lvd 229
        initial
230
        begin : tests
231
 
232
 
233
                reg [7:0] tmp;
234
                reg [7:0] tmp2;
16 lvd 235
 
29 lvd 236
 
237
                wait(rst_n===1'b1);
16 lvd 238
 
29 lvd 239
                repeat(10) @(posedge clk);
240
 
241
 
16 lvd 242
 
31 lvd 243
                test_pwon_resets();
244
                test_pwon_ints();
30 lvd 245
 
246
 
247
 
31 lvd 248
                forever // repeat(10000)
30 lvd 249
                begin
32 lvd 250
                        case( $random%6 )
31 lvd 251
                        0: check_sl811_access();
32 lvd 252
                        1: check_w5300_mem_access();
253
                        2: check_w5300_port_access();
254
                        3: test_resets();
255
                        4: check_sl811_port();
256
                        5: test_ints();
31 lvd 257
                        endcase
30 lvd 258
                end
259
 
260
 
261
 
262
 
263
 
264
 
265
 
266
 
267
 
268
 
269
 
270
 
271
 
272
 
273
 
274
 
275
 
276
                $display("all tests passed!");
277
                $stop;
278
        end
279
 
280
 
281
 
282
 
283
 
284
 
83 lvd 285
        task wait_end_access();
286
 
287
                reg a;
288
 
289
                a = 1'b0;
290
                wait( brd_n==1'b1 && bwr_n==1'b1 );
291
 
292
                a <= 1'b1;
293
                wait(a==1'b1);
294
 
295
        endtask
30 lvd 296
 
297
 
298
 
299
 
300
 
301
 
302
 
303
 
304
        // translates memory address to w5300 address in accordance with specs
305
        function [9:0] mk_w5300_addr( input [13:0] mem_addr );
306
 
307
                if( mem_addr<14'h2000 )
308
                begin
309
                        mk_w5300_addr = mem_addr[9:0];
310
                end
311
                else if( mem_addr<14'h3000 )
312
                begin
313
                        mk_w5300_addr[9] = 1'b1;
314
                        mk_w5300_addr[8:6] = mem_addr[11:9];
315
                        mk_w5300_addr[5:1] = 5'b10111;
316
                        mk_w5300_addr[0] = mem_addr[0];
317
                end
318
                else // if( mem_addr<14'h4000 )
319
                begin
320
                        mk_w5300_addr[9] = 1'b1;
321
                        mk_w5300_addr[8:6] = mem_addr[11:9];
322
                        mk_w5300_addr[5:1] = 5'b11000;
323
                        mk_w5300_addr[0] = mem_addr[0];
324
                end
325
 
326
        endfunction
327
 
328
 
329
 
330
 
331
 
332
 
32 lvd 333
        task check_w5300_port_access();
30 lvd 334
 
335
                reg [7:0] tmp,rddata,wrdata;
32 lvd 336
                reg [9:0] waddr;
337
                reg       a0_inv;
338
 
339
                reg [15:0] port;
340
 
341
 
342
                a0_inv = $random>>31;
343
 
344
                waddr = $random>>22;
345
 
346
 
347
 
348
                z.iowr(w5300_port,{waddr[9:7],1'b1,a0_inv,3'd0});
349
 
350
                z.iord(w5300_port,tmp);
351
                if( tmp!=={waddr[9:7],1'b1,a0_inv,3'd0} )
352
                begin
353
                        $display("can't set w5300 port!");
354
                        $stop;
355
                end
356
 
357
                // make access port address
358
                port = sl_data;
359
                port[14:8] = waddr[6:0];
360
 
361
 
362
                w.init_access(); // clear access_* to X
363
 
364
 
365
                if( $random>>31 )
366
                begin
367
                        wrdata = $random>>24;
368
                        z.iowr(port,wrdata);
83 lvd 369
                        wait_end_access();
32 lvd 370
                        if( w.get_addr()!==(waddr^a0_inv) ||
371
                            w.get_rnw()!==1'b0            ||
372
                            w.get_wr_data()!==wrdata      )
373
                        begin
374
                                $display("w5300 port write failed!");
375
                                $stop;
376
                        end
377
                end
378
                else
379
                begin
380
                        rddata = $random>>24;
381
                        w.set_rd_data(rddata);
382
                        z.iord(port,tmp);
72 lvd 383
                        @(negedge clk);
32 lvd 384
                        if( w.get_addr()!==(waddr^a0_inv) ||
385
                            w.get_rnw()!==1'b1            ||
386
                            tmp!==rddata                  )
387
                        begin
388
                                $display("w5300 port read failed!");
389
                                $stop;
390
                        end
391
                end
392
 
393
        endtask
394
 
395
 
396
 
397
 
398
        task check_w5300_mem_access;
399
 
400
                reg [7:0] tmp,rddata,wrdata;
30 lvd 401
                reg [15:0] memaddr;
402
                reg [ 9:0] waddr;
403
 
404
                reg [1:0] rom;
405
                reg       a0_inv;
406
                reg       sub_ena;
407
 
408
 
409
                rom    = $random>>30;
410
                a0_inv = $random>>31;
411
                sub_ena= $random>>31;
412
 
413
                z.iowr(w5300_port,{4'd0,a0_inv,sub_ena,rom});
414
 
415
                z.iord(w5300_port,tmp);
32 lvd 416
                if( tmp!=={4'd0,a0_inv,sub_ena,rom} )
30 lvd 417
                begin
418
                        $display("can't set w5300 port!");
419
                        $stop;
420
                end
421
 
422
 
423
                if( $random>>31 )
424
                        where_rom = rom;
425
                else
426
                begin
427
                        where_rom = $random>>30;
428
                        while( where_rom==rom )
429
                                where_rom = $random>>30;
430
                end
431
 
432
 
433
 
434
                w.init_access(); // clear access_* to X
435
 
436
 
437
                memaddr = $random>>18;
438
                memaddr[15:14] = where_rom;
439
 
440
 
441
 
442
                if( $random>>31 )
443
                begin
83 lvd 444
                        repeat(10)
30 lvd 445
                        begin
83 lvd 446
                                wrdata = $random>>24;
447
                                z.memwr(memaddr,wrdata);
448
                                wait_end_access();
449
                                if( where_rom==rom && sub_ena )
30 lvd 450
                                begin
83 lvd 451
                                        if( w.get_addr()!==(mk_w5300_addr(memaddr[13:0])^a0_inv) ||
452
                                            w.get_rnw()!==1'b0                                   ||
453
                                            w.get_wr_data()!==wrdata                             )
454
                                        begin
455
                                                $display("w5300 write failed!");
456
                                                $stop;
457
                                        end
30 lvd 458
                                end
83 lvd 459
                                else
30 lvd 460
                                begin
83 lvd 461
                                        if( w.get_addr()!=={10{1'bX}} || w.get_rnw()!==1'bX || w.get_wr_data()!=={8{1'bX}} )
462
                                        begin
463
                                                $display("write succeeded with wrong ROM mapping!");
464
                                                $stop;
465
                                        end
30 lvd 466
                                end
467
                        end
468
                end
469
                else
470
                begin
471
                        rddata = $random>>24;
472
                        w.set_rd_data(rddata);
473
                        z.memrd(memaddr,tmp);
72 lvd 474
                        @(negedge clk);
30 lvd 475
                        if( where_rom==rom && sub_ena )
476
                        begin
477
                                if( w.get_addr()!==(mk_w5300_addr(memaddr[13:0])^a0_inv) ||
478
                                    w.get_rnw()!==1'b1                                   ||
479
                                    tmp!==rddata                                         )
480
                                begin
481
                                        $display("w5300 read failed!");
482
                                        $stop;
483
                                end
484
                        end
485
                        else
486
                        begin
487
                                if( w.get_addr()!=={10{1'bX}} || w.get_rnw()!==1'bX )
488
                                begin
489
                                        $display("read succeeded with wrong ROM mapping!");
490
                                        $stop;
491
                                end
492
                        end
493
                end
494
 
495
 
496
 
497
 
498
 
499
 
500
 
501
 
502
 
503
 
504
 
505
 
506
 
507
        endtask
508
 
509
 
510
 
511
 
512
 
513
 
514
 
515
        task check_sl811_access;
516
 
517
                reg [7:0] tmp, rddata, wrdata;
518
 
519
                reg [15:0] rdport;
520
 
521
 
32 lvd 522
                // turn off w5300 port access
523
                z.iord(w5300_port,tmp);
524
                if( tmp[4]!==1'b0 )
525
                begin
526
                        tmp[4]=1'b0;
527
                        z.iowr(w5300_port,tmp);
528
                end
529
 
530
 
30 lvd 531
                // check address reg
532
                wrdata=$random>>24;
533
                z.iowr(sl_addr,wrdata);
83 lvd 534
                wait_end_access();
30 lvd 535
                if( s.get_rnw()!==1'b0 || s.get_addr()!==1'b0 || s.get_wr_data()!==wrdata )
536
                begin
537
                        $display("sl811 address write failed!");
538
                        $stop;
539
                end
540
                //
541
                rddata=$random>>24;
542
                s.set_rd_data(rddata);
543
                z.iord(sl_addr,tmp);
72 lvd 544
                @(negedge clk);
30 lvd 545
                if( s.get_rnw()!==1'b1 || s.get_addr()!==1'b0 || tmp!==rddata )
546
                begin
547
                        $display("sl811 address read failed!");
548
                        $stop;
549
                end
550
 
32 lvd 551
 
552
 
30 lvd 553
                // check data reg
554
                rdport=sl_data;
555
                rdport[14:8]=$random>>25;
556
                wrdata=$random>>24;
557
                z.iowr(rdport,wrdata);
83 lvd 558
                wait_end_access();
30 lvd 559
                if( s.get_rnw()!==1'b0 || s.get_addr()!==1'b1 || s.get_wr_data()!==wrdata )
560
                begin
561
                        $display("sl811 data write failed!");
562
                        $stop;
563
                end
564
                //
565
                rddata=$random>>24;
566
                s.set_rd_data(rddata);
567
                z.iord(rdport,tmp);
72 lvd 568
                @(negedge clk);
30 lvd 569
                if( s.get_rnw()!==1'b1 || s.get_addr()!==1'b1 || tmp!==rddata )
570
                begin
571
                        $display("sl811 data read failed!");
572
                        $stop;
573
                end
574
 
575
        endtask
576
 
577
 
578
 
579
 
580
        task check_sl811_port;
581
 
582
                reg [7:0] tmp;
583
 
31 lvd 584
                reg ms;
585
 
586
                ms=$random>>31;
587
 
588
                z.iowr(sl811_port,ms);
83 lvd 589
                wait_end_access();
31 lvd 590
 
30 lvd 591
                @(posedge clk);
71 lvd 592
                if( (rst_n===1'b1 && s.get_ms()!==ms   ) ||
593
                    (rst_n===1'b0 && s.get_ms()!==1'b1 ) )
30 lvd 594
                begin
31 lvd 595
                        $display("sl811_ms_n behaves wrong!");
30 lvd 596
                        $stop;
597
                end
598
 
31 lvd 599
 
600
                usb_power <= $random>>31;
30 lvd 601
                @(posedge clk);
602
                z.iord(sl811_port,tmp);
31 lvd 603
                if( tmp[1]!==usb_power )
30 lvd 604
                begin
31 lvd 605
                        $display("can't sense usb_power!");
30 lvd 606
                        $stop;
607
                end
608
 
609
        endtask
610
 
611
 
612
 
613
 
614
 
31 lvd 615
        task test_pwon_ints;
30 lvd 616
 
617
                reg [7:0] tmp;
618
 
619
                // check ints
620
                z.iord(rstint_port,tmp);
621
                if( tmp[1:0]!==2'b00 )
622
                begin
623
                        $display("int requests after reset!");
624
                        $stop;
625
                end
626
                if( tmp[3:2]!==2'b00 )
627
                begin
628
                        $display("ints enabled after reset!");
629
                        $stop;
630
                end
631
                if( tmp[7]!==1'b0 )
632
                begin
633
                        $display("internal int is on after reset!");
634
                        $stop;
635
                end
636
                if( tmp[6]!==1'b0 )
637
                begin
638
                        $display("ext.int assertion enabled after reset!");
639
                        $stop;
640
                end
31 lvd 641
                if( int_n!==1'b1 )
30 lvd 642
                begin
31 lvd 643
                        $display("ext.int asserted after reset!");
30 lvd 644
                        $stop;
645
                end
31 lvd 646
        endtask
647
 
648
 
649
 
650
 
651
 
652
        task test_ints;
653
 
654
                reg [7:0] tmp;
655
 
656
                reg [1:0] ints,intena;
657
 
658
                reg eintena;
659
 
660
 
661
                ints = $random>>30;
662
 
663
                intena = $random>>30;
664
 
665
                eintena = $random>>31;
666
 
667
 
668
                s.set_intrq(ints[1]);
669
                w.set_int_n(~ints[0]);
670
 
671
                @(posedge clk);
672
 
673
 
30 lvd 674
                z.iord(rstint_port,tmp);
31 lvd 675
                tmp[3:2]=intena;
676
                tmp[6]=eintena;
677
                z.iowr(rstint_port,tmp);
678
 
679
 
30 lvd 680
                z.iord(rstint_port,tmp);
31 lvd 681
 
682
                if( tmp[1]!==ints[1] || tmp[0]!==ints[0] )
30 lvd 683
                begin
31 lvd 684
                        $display("wrong int signals states!");
30 lvd 685
                        $stop;
686
                end
31 lvd 687
 
688
                if( (  (ints&intena) && tmp[7]!==1'b1) ||
689
                    ( !(ints&intena) && tmp[7]!==1'b0) )
30 lvd 690
                begin
31 lvd 691
                        $display("wrong internal int state!");
30 lvd 692
                        $stop;
693
                end
31 lvd 694
 
695
                if( tmp[6]!==eintena )
30 lvd 696
                begin
31 lvd 697
                        $display("wrong eintena state!");
30 lvd 698
                        $stop;
699
                end
31 lvd 700
 
701
                if( (eintena && (ints&intena)) ? (int_n!==1'b0) : (int_n!==1'b1) )
30 lvd 702
                begin
31 lvd 703
                        $display("wrong int_n forming!");
30 lvd 704
                        $stop;
705
                end
31 lvd 706
 
707
 
708
 
709
 
710
        endtask
711
 
712
 
713
 
714
 
715
 
716
 
717
        task test_resets;
718
 
719
                reg [7:0] tmp;
720
 
721
                reg [1:0] resets;
722
 
723
 
724
 
725
                resets = $random>>30;
726
 
727
 
728
                // read-modify-write reset register
729
                z.iord(rstint_port,tmp);
730
 
731
                tmp[5:4] = resets[1:0];
732
 
733
                z.iowr(rstint_port,tmp);
734
 
735
                if( s.get_rst_n() !== resets[1] )
30 lvd 736
                begin
31 lvd 737
                        $display("no control of sl811 reset!");
30 lvd 738
                        $stop;
739
                end
31 lvd 740
 
741
                if( w.get_rst_n() !== resets[0] )
30 lvd 742
                begin
31 lvd 743
                        $display("no control of w5300 reset!");
30 lvd 744
                        $stop;
745
                end
31 lvd 746
 
30 lvd 747
        endtask
748
 
749
 
750
 
31 lvd 751
 
752
        task test_pwon_resets;
753
 
754
                reg [7:0] tmp;
755
 
29 lvd 756
                // test resets state after reset
757
                if( w.get_rst_n() !== 1'b0 )
758
                begin
759
                        $display("w5300 hasn't rst_n=0 after reset!");
760
                        $stop;
761
                end
762
                //
763
                if( s.get_rst_n() !== 1'b0 )
764
                begin
765
                        $display("sl811 hasn't rst_n=0 after reset!");
766
                        $stop;
767
                end
16 lvd 768
 
29 lvd 769
                // read reset register and check it
770
                z.iord(rstint_port,tmp);
771
                if( tmp[5:4]!==2'b00 )
772
                begin
773
                        $display("reset bits in #83AB not 0 after reset!");
774
                        $stop;
775
                end
16 lvd 776
 
30 lvd 777
        endtask
29 lvd 778
 
779
 
780
 
781
 
31 lvd 782
 
783
 
784
 
785
 
786
 
787
 
788
 
789
        // time marks
790
        always
791
        begin : timemarks
792
 
793
                int ms;
794
 
795
                ms = ($time/1000000);
796
 
797
                #1000000.0;
798
 
799
                $display("time mark: %d ms",ms);
800
        end
801
 
802
 
803
 
804
 
805
 
15 lvd 806
endmodule
807