Subversion Repositories pentevo

Rev

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

Rev Author Line No. Line
29 lvd 1
// simulate fpga top-level with external dram, rom, z80
722 lvd 2
// (c) 2010-2016 NedoPC
29 lvd 3
 
4
`include "../include/tune.v"
5
 
31 lvd 6
 
467 lvd 7
 
8
//`define ZLOG 1
9
 
10
 
11
 
29 lvd 12
`define HALF_CLK_PERIOD (17.8)
13
 
37 lvd 14
`define ZCLK_DELAY      (9.5)
34 lvd 15
 
16
// toshibo
37 lvd 17
//`define Z80_DELAY_DOWN  (17.0)
18
//`define Z80_DELAY_UP    (22.0)
33 lvd 19
 
34 lvd 20
// z0840008
37 lvd 21
`define Z80_DELAY_DOWN   34
22
`define Z80_DELAY_UP     30
33 lvd 23
 
29 lvd 24
module tb;
25
 
26
        reg fclk;
27
 
28
        wire clkz_out,clkz_in;
29
 
30
        reg iorq_n,mreq_n,rd_n,wr_n; // has some delays relative to z*_n (below)
31
        reg m1_n,rfsh_n;             //
32
 
425 lvd 33
        wire res;                    //
29 lvd 34
        tri1 ziorq_n,zmreq_n,zrd_n,zwr_n,zm1_n,zrfsh_n; // connected to Z80
35
 
425 lvd 36
        tri1 int_n,wait_n,nmi_n;
37
        wire zint_n,zwait_n,znmi_n;
200 lvd 38
 
467 lvd 39
        wire [15:0] #((`Z80_DELAY_DOWN+`Z80_DELAY_UP)/2) za;
40
        wire [ 7:0] #((`Z80_DELAY_DOWN+`Z80_DELAY_UP)/2) zd;
41
//      wire [15:0] za;
42
//      wire [ 7:0] zd;
29 lvd 43
 
684 lvd 44
        tri1 [ 7:0] zd_dut_to_z80;
467 lvd 45
//      wire [ 7:0] zd_z80_to_dut;
29 lvd 46
 
467 lvd 47
 
684 lvd 48
        reg [15:0] reset_pc = 16'h0000;
49
        reg [15:0] reset_sp = 16'hFFFF;
50
 
51
 
52
 
29 lvd 53
        wire csrom, romoe_n, romwe_n;
200 lvd 54
        wire rompg0_n, dos_n;
425 lvd 55
        wire rompg2,rompg3,rompg4;
29 lvd 56
 
57
        wire [15:0] rd;
58
        wire [9:0] ra;
59
        wire rwe_n,rucas_n,rlcas_n,rras0_n,rras1_n;
60
 
61
 
684 lvd 62
        tri0 [15:0] ide_d;
29 lvd 63
 
64
 
425 lvd 65
        wire hsync,vsync;
66
        wire [1:0] red,grn,blu;
29 lvd 67
 
425 lvd 68
 
69
 
543 lvd 70
        // sdcard
71
        wire sdcs_n, sddo, sddi, sdclk;
425 lvd 72
 
543 lvd 73
        // avr
74
        wire spick, spidi, spido, spics_n;
75
 
76
 
77
 
78
 
280 lvd 79
        assign zwait_n = (wait_n==1'b0) ? 1'b0 : 1'b1;
80
        assign znmi_n = (nmi_n==1'b0) ? 1'b0 : 1'b1;
425 lvd 81
        assign zint_n = (int_n==1'b0) ? 1'b0 : 1'b1;
280 lvd 82
 
83
 
84
 
425 lvd 85
 
86
 
87
 
29 lvd 88
        initial
89
        begin
90
 
91
                fclk = 1'b0;
92
 
93
                forever #`HALF_CLK_PERIOD fclk = ~fclk;
94
        end
95
 
96
 
200 lvd 97
        assign #`ZCLK_DELAY clkz_in = ~clkz_out;
29 lvd 98
 
99
 
100
 
101
 
102
 
103
 
104
 
105
        top DUT( .fclk(fclk),
106
                 .clkz_out(clkz_out),
107
                 .clkz_in(clkz_in),
108
 
109
               // z80
110
                 .iorq_n(iorq_n),
111
                 .mreq_n(mreq_n),
112
                 .rd_n(rd_n),
113
                 .wr_n(wr_n),
114
                 .m1_n(m1_n),
115
                 .rfsh_n(rfsh_n),
116
                 .int_n(int_n),
117
                 .nmi_n(nmi_n),
118
                 .wait_n(wait_n),
119
                 .res(res),
120
                 //
121
                 .d(zd),
122
                 .a(za),
123
 
124
                 // ROM
125
                 .csrom(csrom),
126
                 .romoe_n(romoe_n),
127
                 .romwe_n(romwe_n),
200 lvd 128
                 .rompg0_n(rompg0_n),
129
                 .dos_n(dos_n),
425 lvd 130
                 .rompg2(rompg2),
131
                 .rompg3(rompg3),
132
                 .rompg4(rompg4),
29 lvd 133
 
134
                 // DRAM
135
                 .rd(rd),
136
                 .ra(ra),
137
                 .rwe_n(rwe_n),
138
                 .rucas_n(rucas_n),
139
                 .rlcas_n(rlcas_n),
140
                 .rras0_n(rras0_n),
141
                 .rras1_n(rras1_n),
142
 
143
                 // ZX-bus
144
                 .iorqge1(1'b0),
145
                 .iorqge2(1'b0),
146
 
147
                 // IDE
148
                 .ide_d(ide_d),
149
                 .ide_rdy(1'b1),
150
 
151
                 // VG93
152
                 .step(1'b0),
153
                 .vg_sl(1'b0),
154
                 .vg_sr(1'b0),
155
                 .vg_tr43(1'b0),
156
                 .rdat_b_n(1'b1),
157
                 .vg_wf_de(1'b0),
158
                 .vg_drq(1'b1),
159
                 .vg_irq(1'b1),
160
                 .vg_wd(1'b0),
161
 
162
                 // SDcard SPI
543 lvd 163
                 .sddi(sddi),
164
                 .sddo(sddo),
165
                 .sdcs_n(sdcs_n),
166
                 .sdclk(sdclk),
29 lvd 167
 
168
                 // ATmega SPI
543 lvd 169
                 .spics_n(spics_n),
170
                 .spick(spick),
171
                 .spido(spido),
172
                 .spidi(spidi),
29 lvd 173
 
425 lvd 174
                 .vhsync(hsync),
175
                 .vvsync(vsync),
176
                 .vred(red),
177
                 .vgrn(grn),
178
                 .vblu(blu)
179
 
29 lvd 180
               );
181
 
182
 
467 lvd 183
 
184
 
722 lvd 185
//      assign zd_dut_to_z80 = tb.DUT.ena_ram ? tb.DUT.dout_ram : ( tb.DUT.ena_ports ? tb.DUT.dout_ports : ( tb.DUT.drive_ff ? 8'hFF : 8'bZZZZZZZZ ) );
186
        assign zd_dut_to_z80 = tb.DUT.d_ena ? tb.DUT.d_pre_out : 8'bZZZZ_ZZZZ;
467 lvd 187
 
188
 
189
 
190
 
29 lvd 191
        wire zrst_n = ~res;
192
 
193
        T80a z80( .RESET_n(zrst_n),
194
                  .CLK_n(clkz_in),
280 lvd 195
                  .WAIT_n(zwait_n),
425 lvd 196
                  .INT_n(zint_n),
280 lvd 197
                  .NMI_n(znmi_n),
29 lvd 198
                  .M1_n(zm1_n),
199
                  .RFSH_n(zrfsh_n),
200
                  .MREQ_n(zmreq_n),
201
                  .IORQ_n(ziorq_n),
202
                  .RD_n(zrd_n),
203
                  .WR_n(zwr_n),
204
                  .BUSRQ_n(1'b1),
205
                  .A(za),
467 lvd 206
//                .D(zd),
207
                  .D_I(zd_dut_to_z80),
684 lvd 208
                  .D_O(zd),
209
                  .ResetPC(reset_pc),
210
                  .ResetSP(reset_sp)
29 lvd 211
                );
212
 
213
        // now make delayed versions of signals
214
        //
280 lvd 215
        reg  mreq_wr_n;
216
        wire iorq_wr_n, full_wr_n;
217
        //
218
        // first, assure there is no X's at the start
219
        //
220
        initial
221
        begin
222
                m1_n      = 1'b1;
223
                rfsh_n    = 1'b1;
224
                mreq_n    = 1'b1;
225
                iorq_n    = 1'b1;
226
                rd_n      = 1'b1;
227
                wr_n      = 1'b1;
228
                mreq_wr_n = 1'b1;
229
        end
230
        //
29 lvd 231
        always @(zm1_n)
232
                if( zm1_n )
233
                        m1_n <= #`Z80_DELAY_UP zm1_n;
234
                else
235
                        m1_n <= #`Z80_DELAY_DOWN zm1_n;
236
        //
237
        always @(zrfsh_n)
238
                if( zrfsh_n )
239
                        rfsh_n <= #`Z80_DELAY_UP zrfsh_n;
240
                else
241
                        rfsh_n <= #`Z80_DELAY_DOWN zrfsh_n;
242
        //
243
        always @(zmreq_n)
244
                if( zmreq_n )
245
                        mreq_n <= #`Z80_DELAY_UP zmreq_n;
246
                else
247
                        mreq_n <= #`Z80_DELAY_DOWN zmreq_n;
248
        //
249
        always @(ziorq_n)
250
                if( ziorq_n )
251
                        iorq_n <= #`Z80_DELAY_UP ziorq_n;
252
                else
253
                        iorq_n <= #`Z80_DELAY_DOWN ziorq_n;
254
        //
255
        always @(zrd_n)
256
                if( zrd_n )
257
                        rd_n <= #`Z80_DELAY_UP zrd_n;
258
                else
259
                        rd_n <= #`Z80_DELAY_DOWN zrd_n;
260
        //
280 lvd 261
        //
262
        // special handling for broken T80 WR_n
511 lvd 263
        //
29 lvd 264
        always @(negedge clkz_in)
280 lvd 265
                mreq_wr_n <= zwr_n;
266
        //
267
        assign iorq_wr_n = ziorq_n | (~zrd_n) | (~zm1_n);
268
        //
269
        assign full_wr_n = mreq_wr_n & iorq_wr_n;
270
        //
271
        // this way glitches won't affect state of wr_n
272
        always @(full_wr_n)
273
                if( !full_wr_n )
274
                        #`Z80_DELAY_DOWN wr_n <= full_wr_n;
29 lvd 275
                else
280 lvd 276
                        #`Z80_DELAY_UP wr_n <= full_wr_n;
29 lvd 277
 
278
 
280 lvd 279
 
280
 
281
 
29 lvd 282
        // ROM model
283
        rom romko(
425 lvd 284
                   .addr( {rompg4,rompg3,rompg2,dos_n, (~rompg0_n), za[13:0]} ),
467 lvd 285
                   .data(zd_dut_to_z80),
29 lvd 286
                   .ce_n( romoe_n | (~csrom) )
287
                 );
288
 
289
        // DRAM model
290
        drammem dramko1(
291
                         .ma(ra),
292
                         .d(rd),
293
                         .ras_n(rras0_n),
294
                         .ucas_n(rucas_n),
295
                         .lcas_n(rlcas_n),
296
                         .we_n(rwe_n)
297
                       );
298
        //
299
        drammem dramko2(
300
                         .ma(ra),
301
                         .d(rd),
302
                         .ras_n(rras1_n),
303
                         .ucas_n(rucas_n),
304
                         .lcas_n(rlcas_n),
305
                         .we_n(rwe_n)
306
                       );
307
        defparam dramko1._verbose_ = 0;
308
        defparam dramko2._verbose_ = 0;
309
 
510 lvd 310
        defparam dramko1._init_ = 0;
311
        defparam dramko2._init_ = 0;
29 lvd 312
 
313
 
510 lvd 314
 
280 lvd 315
`ifndef GATE
200 lvd 316
 
317
        // trace rom page
318
        wire rma14,rma15;
319
 
320
        assign rma14 = DUT.page[0][0];
321
        assign rma15 = DUT.page[0][1];
322
 
323
 
324
        always @(rma14 or rma15)
325
        begin
467 lvd 326
//              $display("at time %t us",$time/1000000);
200 lvd 327
 
467 lvd 328
//              case( {rma15, rma14} )
200 lvd 329
 
467 lvd 330
//              2'b00: $display("BASIC 48");
331
//              2'b01: $display("TR-DOS");
332
//              2'b10: $display("BASIC 128");
333
//              2'b11: $display("GLUKROM");
334
//              default: $display("unknown");
200 lvd 335
 
467 lvd 336
//              endcase
200 lvd 337
 
467 lvd 338
//              $display("");
200 lvd 339
        end
340
 
341
 
342
        // trace ram page
343
        wire [5:0] rpag;
344
 
345
        assign rpag=DUT.page[3][5:0];
346
 
347
        always @(rpag)
348
        begin
467 lvd 349
//              $display("at time %t us",$time/1000000);
200 lvd 350
 
467 lvd 351
//              $display("RAM page is %d",rpag);
200 lvd 352
 
467 lvd 353
//              $display("");
200 lvd 354
        end
355
 
356
 
357
 
425 lvd 358
        // key presses/nmi/whatsoever
200 lvd 359
        initial
360
        begin
425 lvd 361
                #1;
200 lvd 362
                tb.DUT.zkbdmus.kbd = 40'd0;
425 lvd 363
                tb.DUT.zkbdmus.kbd[36] = 1'b1;
364
                @(negedge int_n);
469 lvd 365
                @(negedge int_n);
425 lvd 366
                tb.DUT.zkbdmus.kbd[36] = 1'b0;
367
        end
467 lvd 368
/*
425 lvd 369
        initial
370
        begin : gen_nmi
371
 
372
                reg [21:0] a;
373
 
374
                #1000000000;
375
 
511 lvd 376
                a = 22'h3FC066;
425 lvd 377
 
378
                put_byte(a,8'hF5); a=a+1;
379
                put_byte(a,8'hC5); a=a+1;
380
                put_byte(a,8'hD5); a=a+1;
381
                put_byte(a,8'hE5); a=a+1;
382
 
383
                put_byte(a,8'h10); a=a+1;
384
                put_byte(a,8'hFE); a=a+1;
385
 
386
                put_byte(a,8'h14); a=a+1;
387
 
388
                put_byte(a,8'h01); a=a+1;
389
                put_byte(a,8'hFE); a=a+1;
390
                put_byte(a,8'h7F); a=a+1;
391
 
392
                put_byte(a,8'hED); a=a+1;
393
                put_byte(a,8'h51); a=a+1;
394
 
395
                put_byte(a,8'hED); a=a+1;
396
                put_byte(a,8'h78); a=a+1;
397
 
398
                put_byte(a,8'h1F); a=a+1;
511 lvd 399
 
425 lvd 400
                put_byte(a,8'hDA); a=a+1;
401
                put_byte(a,8'h6A); a=a+1;
402
                put_byte(a,8'h00); a=a+1;
200 lvd 403
 
425 lvd 404
                put_byte(a,8'hE1); a=a+1;
405
                put_byte(a,8'hD1); a=a+1;
406
                put_byte(a,8'hC1); a=a+1;
407
                put_byte(a,8'hF1); a=a+1;
200 lvd 408
 
425 lvd 409
                put_byte(a,8'hD3); a=a+1;
410
                put_byte(a,8'hBE); a=a+1;
200 lvd 411
 
425 lvd 412
                put_byte(a,8'hED); a=a+1;
413
                put_byte(a,8'h45); a=a+1;
414
 
415
 
416
                @(posedge fclk);
417
                tb.DUT.slavespi.cfg0_reg_out[1] = 1'b1;
418
                @(posedge fclk);
419
                tb.DUT.slavespi.cfg0_reg_out[1] = 1'b0;
420
 
421
                #64000000;
422
 
423
                tb.DUT.zkbdmus.kbd[39] = 1'b1;
200 lvd 424
                @(negedge int_n);
425 lvd 425
                tb.DUT.zkbdmus.kbd[39] = 1'b0;
467 lvd 426
        end
427
*/
200 lvd 428
 
467 lvd 429
`endif
430
 
431
 
432
 
433
 
434
 
435
 
436
 
437
 
438
`ifdef ZLOG
439
        reg [ 7:0] old_opcode;
440
        reg [15:0] old_opcode_addr;
441
 
442
        wire [7:0] zdd = zd_dut_to_z80;
443
 
444
        reg was_m1;
445
 
446
        always @(zm1_n)
447
        if( zm1_n )
448
                was_m1 <= 1'b0;
511 lvd 449
        else
467 lvd 450
                was_m1 = 1'b1;
451
 
452
        always @(posedge (zmreq_n | zrd_n | zm1_n | (~zrfsh_n)) )
453
        if( was_m1 )
454
        begin
455
                if( (zdd!==old_opcode) || (za!==old_opcode_addr) )
511 lvd 456
                begin
467 lvd 457
                        if( tb.DUT.z80mem.romnram )
458
//                              $display("Z80OPROM: addr %x, opcode %x, time %t",za,zdd,$time);
459
                                $display("Z80OPROM: addr %x, opcode %x",za,zdd);
460
                        else
461
//                              $display("Z80OPRAM: addr %x, opcode %x, time %t",za,zdd,$time);
462
                                $display("Z80OPRAM: addr %x, opcode %x",za,zdd);
463
                end
464
 
465
                old_opcode      = zdd;
466
                old_opcode_addr = za;
200 lvd 467
        end
467 lvd 468
 
469
        always @(posedge (zmreq_n | zrd_n | (~zm1_n) | (~zrfsh_n)) )
470
        if( !was_m1 )
471
        begin
472
                if( tb.DUT.z80mem.romnram )
473
//                      $display("Z80RDROM: addr %x, rddata %x, time %t",za,zdd,$time);
474
                        $display("Z80RDROM: addr %x, rddata %x",za,zdd);
475
                else
476
//                      $display("Z80RDRAM: addr %x, rddata %x, time %t",za,zdd,$time);
477
                        $display("Z80RDRAM: addr %x, rddata %x",za,zdd);
478
        end
479
 
480
        always @(posedge (zmreq_n | zwr_n | (~zm1_n) | (~zrfsh_n)) )
481
        begin
482
                if( tb.DUT.z80mem.romnram )
483
//                      $display("Z80WRROM: addr %x, wrdata %x, time %t",za,zd,$time);
484
                        $display("Z80WRROM: addr %x, wrdata %x",za,zd);
485
                else
486
//                      $display("Z80WRRAM: addr %x, wrdata %x, time %t",za,zd,$time);
487
                        $display("Z80WRRAM: addr %x, wrdata %x",za,zd);
488
        end
425 lvd 489
`endif
200 lvd 490
 
491
 
492
 
493
 
467 lvd 494
        // turbo
495
`ifdef C7MHZ
496
        initial
497
                force tb.DUT.zclock.turbo = 2'b01;
498
`else
499
        `ifdef C35MHZ
200 lvd 500
 
467 lvd 501
                initial
502
                        force tb.DUT.zclock.turbo = 2'b00;
425 lvd 503
 
467 lvd 504
        `endif
505
`endif
425 lvd 506
 
507
 
684 lvd 508
        // raster type
509
`ifdef CCONTEND
510
        initial
511
                force tb.DUT.modes_raster = 2'b10;
512
`endif
425 lvd 513
 
467 lvd 514
 
515
 
684 lvd 516
 
721 lvd 517
`ifdef NMITEST2
518
 `define M48K
519
 
520
        initial
521
        begin
522
                int i,fd;
523
                logic [7:0] ldbyte;
524
 
727 lvd 525
                reset_pc=16'h8000;
721 lvd 526
                reset_sp=16'h8000;
527
 
528
                fd = $fopen("dimkanmi.bin","rb");
529
                if( !fd )
530
                begin
531
                        $display("Can't open 'dimkanmi.bin'!");
532
                        $stop;
533
                end
534
 
727 lvd 535
                i='h8000;
721 lvd 536
 
537
                begin : load_loop
538
                        while(1)
539
                        begin
540
                                if( 1!=$fread(ldbyte,fd) ) disable load_loop;
541
                                put_byte_48k(i,ldbyte);
542
                                i=i+1;
543
                        end
544
                end
545
                $fclose(fd);
722 lvd 546
 
737 lvd 547
 
548
                wait(res===1'b0);
549
                #(0.2);
738 lvd 550
                tb.DUT.zports.atm_turbo = 1'b1;
737 lvd 551
                tb.DUT.zports.peff7_int[4] = 1'b0;
552
 
553
 
722 lvd 554
                #(100000); // 100 us
555
 
556
                //force nmi_n = 1'b0;
557
                @(posedge fclk);
558
                force tb.DUT.imm_nmi = 1'b1;
559
                @(posedge fclk);
560
                release tb.DUT.imm_nmi;
721 lvd 561
        end
738 lvd 562
`endif
721 lvd 563
 
738 lvd 564
 
565
 
566
`ifdef NMITEST3
567
 `define M48K
568
 
569
        initial
570
        begin
571
                int i,fd;
572
                logic [7:0] ldbyte;
573
 
574
                reset_pc=16'h0068;
575
                reset_sp=16'h8000;
576
 
577
 
578
                #(0.1); // let M48K rom load execute
579
 
580
                fd = $fopen("dimkarom.bin","rb");
581
                if( !fd )
582
                begin
583
                        $display("Can't open 'dimkarom.bin'!");
584
                        $stop;
585
                end
586
 
587
                i='h0066;
588
                begin : load_loop
589
                        while(1)
590
                        begin
591
                                if( 1!=$fread(ldbyte,fd) ) disable load_loop;
592
                                tb.romko.zxevo_rom.mem[i]=ldbyte;
593
                                i=i+1;
594
                        end
595
                end
596
                $fclose(fd);
597
 
598
 
599
                wait(res===1'b0);
600
                #(0.2);
601
                tb.DUT.zports.atm_turbo = 1'b1;
602
                tb.DUT.zports.peff7_int[4] = 1'b0;
603
 
604
 
605
                #(1000000); // 1 ms
606
 
607
                //force nmi_n = 1'b0;
608
                @(posedge fclk);
609
                force tb.DUT.imm_nmi = 1'b1;
610
                @(posedge fclk);
611
                release tb.DUT.imm_nmi;
612
        end
613
`endif
614
 
615
 
727 lvd 616
        // port #FE monitor
617
        wire fe_write;
618
        assign fe_write = (za[7:0]==8'hFE) && !wr_n && !iorq_n;
619
        always @(negedge fe_write)
737 lvd 620
                $display("port #FE monitor: border is %d at %t",zd[2:0],$time());
621
        always @(negedge nmi_n)
622
                $display("nmi monitor: negative edge at %t",$time());  
721 lvd 623
 
624
 
737 lvd 625
 
721 lvd 626
 
684 lvd 627
        // start in 48k mode
628
`ifdef M48K
629
        initial
630
        begin : force_48k_mode
631
 
632
                int i;
633
                int fd;
715 lvd 634
 
738 lvd 635
                fd = $fopen("48.rom","rb");
636
                if( 16384!=$fread(tb.romko.zxevo_rom.mem,fd) )
637
                begin
638
                        $display("Couldn't load 48k ROM!\n");
639
                        $stop;
640
                end
641
                $fclose(fd);
642
 
643
 
715 lvd 644
                wait(res===1'b0);
645
                #(0.1);
684 lvd 646
 
715 lvd 647
                tb.DUT.zports.atm_turbo = 1'b0;
648
                tb.DUT.zports.atm_pen = 1'b0;
649
                tb.DUT.zports.atm_cpm_n = 1'b1;
650
                tb.DUT.zports.atm_pen2 = 1'b0;
651
//              tb.DUT.zports.pent1m_ram0_0 = 1'b0;
652
//              tb.DUT.zports.pent1m_1m_on = 1'b0;
653
//              tb.DUT.zports.pent1m_page = 'd0;
654
//              tb.DUT.zports.pent1m_ROM = 1'b1;
655
 
656
                tb.DUT.zdos.dos = 1'b0;
657
 
658
/*              tb.DUT.page[0] = 'd0;
659
                tb.DUT.page[1] = 'd5;
660
                tb.DUT.page[2] = 'd2;
661
                tb.DUT.page[3] = 'd0;
662
                tb.DUT.romnram[0] = 1'b1;
663
                tb.DUT.romnram[1] = 1'b0;
664
                tb.DUT.romnram[2] = 1'b0;
665
                tb.DUT.romnram[3] = 1'b0;*/
666
 
720 lvd 667
                tb.DUT.instantiate_atm_pagers[0].atm_pager.pages[0] = 'd0;
668
                tb.DUT.instantiate_atm_pagers[1].atm_pager.pages[0] = 'd5;
669
                tb.DUT.instantiate_atm_pagers[2].atm_pager.pages[0] = 'd2;
670
                tb.DUT.instantiate_atm_pagers[3].atm_pager.pages[0] = 'd0;
671
                tb.DUT.instantiate_atm_pagers[0].atm_pager.pages[1] = 'd0;
672
                tb.DUT.instantiate_atm_pagers[1].atm_pager.pages[1] = 'd5;
673
                tb.DUT.instantiate_atm_pagers[2].atm_pager.pages[1] = 'd2;
674
                tb.DUT.instantiate_atm_pagers[3].atm_pager.pages[1] = 'd0;
675
 
676
                tb.DUT.instantiate_atm_pagers[0].atm_pager.ramnrom[0] = 'd0;
677
                tb.DUT.instantiate_atm_pagers[1].atm_pager.ramnrom[0] = 'd1;
678
                tb.DUT.instantiate_atm_pagers[2].atm_pager.ramnrom[0] = 'd1;
679
                tb.DUT.instantiate_atm_pagers[3].atm_pager.ramnrom[0] = 'd1;
680
                tb.DUT.instantiate_atm_pagers[0].atm_pager.ramnrom[1] = 'd0;
681
                tb.DUT.instantiate_atm_pagers[1].atm_pager.ramnrom[1] = 'd1;
682
                tb.DUT.instantiate_atm_pagers[2].atm_pager.ramnrom[1] = 'd1;
683
                tb.DUT.instantiate_atm_pagers[3].atm_pager.ramnrom[1] = 'd1;
684
 
715 lvd 685
                tb.DUT.zports.atm_scr_mode = 3'b011;
684 lvd 686
 
715 lvd 687
/*              tb.DUT.peff7[5] = 1'b0;
688
                tb.DUT.peff7[0] = 1'b0;
689
                tb.DUT.p7ffd[3] = 1'b0;*/
720 lvd 690
//              tb.DUT.zports.peff7[7] = 1'b0;
691
//              tb.DUT.zports.peff7[0] = 1'b0;
692
//              tb.DUT.zports.p7ffd[3] = 1'b0;
684 lvd 693
 
720 lvd 694
                tb.DUT.zports.peff7_int = 8'h14;
695
                tb.DUT.zports.p7ffd_int = 8'h30;
715 lvd 696
 
720 lvd 697
 
698
 
684 lvd 699
                for(i=0;i<512;i=i+1)
700
                begin : set_palette //                                            R                               G                              B
701
                        tb.DUT.video_top.video_palframe.palette[i] = { (i[1]?{1'b1,i[3]}:2'b00), 1'b0, (i[2]?{1'b1,i[3]}:2'b00), 1'b0, (i[0]?{1'b1,i[3]}:2'b00) };
702
                end
703
 
704
        end
705
`endif
706
 
707
 
708
        // load and start some code after we've reached "1982 Sinclair research ltd"
709
`ifdef START_LOAD
710
        initial
711
        begin
712
                int i,fd;
713
                logic [7:0] ldbyte;
714
 
715
                wait( za==16'h15e0 && zmreq_n==1'b0 && zrd_n == 1'b0 );
716
 
717
                $display("loading and starting...");
718
 
719
                fd = $fopen(`START_NAME,"rb");
720
                for(i=`START_ADDR;i<`START_ADDR+`START_LEN;i=i+1)
721
                begin
722
                        if( 1!=$fread(ldbyte,fd) )
723
                        begin
724
                                $display("can't read byte from input file!");
725
                                $stop;
726
                        end
727
 
728
                        put_byte_48k(i,ldbyte);
729
                end
730
                $fclose(fd);
731
 
732
                $display("load ok!");
733
 
734
                reset_pc = 16'h9718;
735
                reset_sp = 16'h6000;
736
                @(posedge clkz_in);
737
                force tb.zrst_n = 1'b0;
738
                repeat(3) @(posedge clkz_in);
739
                release tb.zrst_n;
740
                @(posedge clkz_in);
741
                reset_pc = 16'h0000;
742
                reset_sp = 16'hFFFF;
743
        end
744
`endif
745
 
746
 
747
 
748
 
749
 
750
 
751
 
752
 
753
 
754
 
467 lvd 755
        // force fetch mode
756
//      initial
757
//      begin
758
//              force tb.DUT.dramarb.bw = 2'b11;
759
//
760
//              #(64'd2400000000);
761
//
762
//              release tb.DUT.dramarb.bw;
763
//      end
764
 
765
 
766
 
511 lvd 767
`ifndef NO_PIXER
425 lvd 768
        // picture out
769
        pixer pixer
770
        (
771
                .clk(fclk),
772
 
773
                .vsync(vsync),
774
                .hsync(hsync),
775
                .red(red),
776
                .grn(grn),
777
                .blu(blu)
778
        );
511 lvd 779
`endif
425 lvd 780
 
781
 
510 lvd 782
/*
280 lvd 783
        // time ticks
784
        always
785
        begin : timemark
200 lvd 786
 
280 lvd 787
                integer ms;
788
 
789
                ms = ($time/1000000);
790
 
467 lvd 791
//              $display("timemark %d ms",ms);
280 lvd 792
 
793
                #10000000.0; // 1 ms
794
        end
510 lvd 795
*/
280 lvd 796
 
797
 
510 lvd 798
        // init dram
721 lvd 799
`ifndef NMITEST2
510 lvd 800
        initial
511 lvd 801
        begin : init_dram
510 lvd 802
                integer i;
280 lvd 803
 
510 lvd 804
                for(i=0;i<4*1024*1024;i=i+1)
805
                begin
806
                        put_byte(i,(i%257));
807
                end
808
        end
721 lvd 809
`endif
280 lvd 810
 
811
 
812
 
813
 
425 lvd 814
 
684 lvd 815
        // cmos simulation
816
        wire [7:0] cmos_addr;
817
        wire [7:0] cmos_read;
818
        wire [7:0] cmos_write;
819
        wire       cmos_rnw;
820
        wire       cmos_req;
821
 
822
        cmosemu cmosemu
823
        (
824
                .zclk(clkz_in),
825
 
826
                .cmos_req  (cmos_req  ),
827
                .cmos_addr (cmos_addr ),
828
                .cmos_rnw  (cmos_rnw  ),
829
                .cmos_read (cmos_read ),
830
                .cmos_write(cmos_write)
831
        );
832
 
833
        assign cmos_req   = tb.DUT.wait_start_gluclock;
834
        assign cmos_rnw   = tb.DUT.wait_rnw;
835
        assign cmos_addr  = tb.DUT.gluclock_addr;
836
        assign cmos_write = tb.DUT.wait_write;
837
 
838
        always @*
839
                force tb.DUT.wait_read = cmos_read;
840
 
841
 
842
 
843
 
543 lvd 844
`ifdef SPITEST
845
        // spitest printing module
846
        // does not hurt at any time (yet), so attached forever
510 lvd 847
 
543 lvd 848
        spitest_print spitest_print(
849
                .sdclk (sdclk ),
850
                .sddi  (sddi  ),
851
                .sddo  (sddo  ),
852
                .sdcs_n(sdcs_n)
853
        );
510 lvd 854
 
543 lvd 855
        // spitest AVR imitator
510 lvd 856
 
543 lvd 857
        spitest_avr spitest_avr(
858
                .spick  (spick  ),
859
                .spics_n(spics_n),
860
                .spido  (spido  ),
861
                .spidi  (spidi  )
862
        );
863
`else
864
        assign sddi = 1'b1;
510 lvd 865
 
543 lvd 866
        assign spics_n = 1'b1;
867
        assign spick   = 1'b0;
868
        assign spido   = 1'b1;
869
`endif
870
 
871
 
872
 
873
 
874
 
684 lvd 875
//      // set up breakpoint
876
//      initial
877
//      begin
878
//              #(650_000_000); // wait 650ms = 650*1000*1000 ns
879
//
880
//              @(posedge fclk);
881
//
882
//              tb.DUT.zports.brk_ena  = 1'b1;
883
//              tb.DUT.zports.brk_addr = 16'h0041;
884
//      end
576 lvd 885
 
886
 
887
 
888
 
889
 
890
 
891
 
892
 
893
 
894
 
895
 
425 lvd 896
        task put_byte;
897
 
898
                input [21:0] addr;
899
                input [ 7:0] data;
900
 
901
 
511 lvd 902
 
425 lvd 903
                reg [19:0] arraddr;
904
 
905
                begin
906
 
907
                        arraddr = { addr[21:12], addr[11:2] };
908
 
909
                        case( addr[1:0] ) // chipsel, bytesel
910
 
911
                        2'b00: tb.dramko1.array[arraddr][15:8] = data;
912
                        2'b01: tb.dramko1.array[arraddr][ 7:0] = data;
913
                        2'b10: tb.dramko2.array[arraddr][15:8] = data;
914
                        2'b11: tb.dramko2.array[arraddr][ 7:0] = data;
915
 
916
                        endcase
917
                end
918
 
919
        endtask
920
 
684 lvd 921
        task put_byte_48k
922
        (
923
                input [15:0] addr,
924
                input [ 7:0] data
925
        );
425 lvd 926
 
684 lvd 927
                case( addr[15:14] )
928
                        2'b01: put_byte(addr-16'h4000 + 22'h14000,data);
929
                        2'b10: put_byte(addr-16'h8000 + 22'h08000,data);
930
                        2'b11: put_byte(addr-16'hc000 + 22'h00000,data);
931
                endcase
932
        endtask
425 lvd 933
 
934
 
935
 
684 lvd 936
 
29 lvd 937
endmodule
938
 
939