- // simulate fpga top-level with external dram, rom, z80 
- // (c) 2010-2016 NedoPC 
-   
- `include "../include/tune.v" 
-   
-   
-   
- //`define ZLOG 1 
-   
-   
-   
- `define HALF_CLK_PERIOD (17.8) 
-   
- `define ZCLK_DELAY      (9.5) 
-   
- // toshibo 
- //`define Z80_DELAY_DOWN  (17.0) 
- //`define Z80_DELAY_UP    (22.0) 
-   
- // z0840008 
- `define Z80_DELAY_DOWN   34 
- `define Z80_DELAY_UP     30 
-   
- module tb; 
-   
-         reg fclk; 
-   
-         wire clkz_out,clkz_in; 
-   
-         reg iorq_n,mreq_n,rd_n,wr_n; // has some delays relative to z*_n (below) 
-         reg m1_n,rfsh_n;             // 
-   
-         wire res;                    // 
-         tri1 ziorq_n,zmreq_n,zrd_n,zwr_n,zm1_n,zrfsh_n; // connected to Z80 
-   
-         tri1 int_n,wait_n,nmi_n; 
-         wire zint_n,zwait_n,znmi_n; 
-   
-         wire [15:0] #((`Z80_DELAY_DOWN+`Z80_DELAY_UP)/2) za; 
-         wire [ 7:0] #((`Z80_DELAY_DOWN+`Z80_DELAY_UP)/2) zd; 
-   
-         tri1 [ 7:0] zd_dut_to_z80; 
-   
-   
-         reg [15:0] reset_pc = 16'h0000; 
-         reg [15:0] reset_sp = 16'hFFFF; 
-   
-   
-   
-         wire csrom, romoe_n, romwe_n; 
-         wire rompg0_n, dos_n; 
-         wire rompg2,rompg3,rompg4; 
-   
-         wire [15:0] rd; 
-         wire [9:0] ra; 
-         wire rwe_n,rucas_n,rlcas_n,rras0_n,rras1_n; 
-   
-   
-         tri1 [15:0] ide_d; 
-   
-   
-         wire hsync,vsync; 
-         wire [1:0] red,grn,blu; 
-   
-   
-   
-         // sdcard 
-         wire sdcs_n, sddo, sddi, sdclk; 
-   
-         // avr 
-         wire spick, spidi, spido, spics_n; 
-   
-   
-   
-   
-         assign zwait_n = (wait_n==1'b0) ? 1'b0 : 1'b1; 
-         assign znmi_n = (nmi_n==1'b0) ? 1'b0 : 1'b1; 
-         assign zint_n = (int_n==1'b0) ? 1'b0 : 1'b1; 
-   
-   
-   
-   
-   
-   
-         initial 
-         begin 
-   
-                 fclk = 1'b0; 
-   
-                 forever #`HALF_CLK_PERIOD fclk = ~fclk; 
-         end 
-   
-   
-         assign #`ZCLK_DELAY clkz_in = ~clkz_out; 
-   
-   
-   
-   
-   
-   
-   
-         top DUT( .fclk(fclk), 
-                  .clkz_out(clkz_out), 
-                  .clkz_in(clkz_in), 
-   
-                // z80 
-                  .iorq_n(iorq_n), 
-                  .mreq_n(mreq_n), 
-                  .rd_n(rd_n), 
-                  .wr_n(wr_n), 
-                  .m1_n(m1_n), 
-                  .rfsh_n(rfsh_n), 
-                  .int_n(int_n), 
-                  .nmi_n(nmi_n), 
-                  .wait_n(wait_n), 
-                  .res(res), 
-                  // 
-                  .d(zd), 
-                  .a(za), 
-   
-                  // ROM 
-                  .csrom(csrom), 
-                  .romoe_n(romoe_n), 
-                  .romwe_n(romwe_n), 
-                  .rompg0_n(rompg0_n), 
-                  .dos_n(dos_n), 
-                  .rompg2(rompg2), 
-                  .rompg3(rompg3), 
-                  .rompg4(rompg4), 
-   
-                  // DRAM 
-                  .rd(rd), 
-                  .ra(ra), 
-                  .rwe_n(rwe_n), 
-                  .rucas_n(rucas_n), 
-                  .rlcas_n(rlcas_n), 
-                  .rras0_n(rras0_n), 
-                  .rras1_n(rras1_n), 
-   
-                  // ZX-bus 
-                  .iorqge1(1'b0), 
-                  .iorqge2(1'b0), 
-   
-                  // IDE 
-                  .ide_d(ide_d), 
-                  .ide_rdy(1'b1), 
-   
-                  // VG93 
-                  .step(1'b0), 
-                  .vg_sl(1'b0), 
-                  .vg_sr(1'b0), 
-                  .vg_tr43(1'b0), 
-                  .rdat_b_n(1'b1), 
-                  .vg_wf_de(1'b0), 
-                  .vg_drq(1'b1), 
-                  .vg_irq(1'b1), 
-                  .vg_wd(1'b0), 
-   
-                  // SDcard SPI 
-                  .sddi(sddi), 
-                  .sddo(sddo), 
-                  .sdcs_n(sdcs_n), 
-                  .sdclk(sdclk), 
-   
-                  // ATmega SPI 
-                  .spics_n(spics_n), 
-                  .spick(spick), 
-                  .spido(spido), 
-                  .spidi(spidi), 
-   
-                  .vhsync(hsync), 
-                  .vvsync(vsync), 
-                  .vred(red), 
-                  .vgrn(grn), 
-                  .vblu(blu) 
-   
-                ); 
-   
-   
-   
-   
- //      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 ) ); 
-         assign zd_dut_to_z80 = tb.DUT.d_ena ? tb.DUT.d_pre_out : 8'bZZZZ_ZZZZ; 
-   
-   
-   
-   
-         wire zrst_n = ~res; 
-   
-         T80a z80( .RESET_n(zrst_n), 
-                   .CLK_n(clkz_in), 
-                   .WAIT_n(zwait_n), 
-                   .INT_n(zint_n), 
-                   .NMI_n(znmi_n), 
-                   .M1_n(zm1_n), 
-                   .RFSH_n(zrfsh_n), 
-                   .MREQ_n(zmreq_n), 
-                   .IORQ_n(ziorq_n), 
-                   .RD_n(zrd_n), 
-                   .WR_n(zwr_n), 
-                   .BUSRQ_n(1'b1), 
-                   .A(za), 
-                   .D_I(zd_dut_to_z80), 
-                   .D_O(zd), 
-                   .ResetPC(reset_pc), 
-                   .ResetSP(reset_sp) 
-                 ); 
-   
-         // now make delayed versions of signals 
-         // 
-         reg  mreq_wr_n; 
-         wire iorq_wr_n, full_wr_n; 
-         // 
-         // first, assure there is no X's at the start 
-         // 
-         initial 
-         begin 
-                 m1_n      = 1'b1; 
-                 rfsh_n    = 1'b1; 
-                 mreq_n    = 1'b1; 
-                 iorq_n    = 1'b1; 
-                 rd_n      = 1'b1; 
-                 wr_n      = 1'b1; 
-                 mreq_wr_n = 1'b1; 
-         end 
-         // 
-         always @(zm1_n) 
-                 if( zm1_n ) 
-                         m1_n <= #`Z80_DELAY_UP zm1_n; 
-                 else 
-                         m1_n <= #`Z80_DELAY_DOWN zm1_n; 
-         // 
-         always @(zrfsh_n) 
-                 if( zrfsh_n ) 
-                         rfsh_n <= #`Z80_DELAY_UP zrfsh_n; 
-                 else 
-                         rfsh_n <= #`Z80_DELAY_DOWN zrfsh_n; 
-         // 
-         always @(zmreq_n) 
-                 if( zmreq_n ) 
-                         mreq_n <= #`Z80_DELAY_UP zmreq_n; 
-                 else 
-                         mreq_n <= #`Z80_DELAY_DOWN zmreq_n; 
-         // 
-         always @(ziorq_n) 
-                 if( ziorq_n ) 
-                         iorq_n <= #`Z80_DELAY_UP ziorq_n; 
-                 else 
-                         iorq_n <= #`Z80_DELAY_DOWN ziorq_n; 
-         // 
-         always @(zrd_n) 
-                 if( zrd_n ) 
-                         rd_n <= #`Z80_DELAY_UP zrd_n; 
-                 else 
-                         rd_n <= #`Z80_DELAY_DOWN zrd_n; 
-         // 
-         // 
-         // special handling for broken T80 WR_n 
-         // 
-         always @(negedge clkz_in) 
-                 mreq_wr_n <= zwr_n; 
-         // 
-         assign iorq_wr_n = ziorq_n | (~zrd_n) | (~zm1_n); 
-         // 
-         assign full_wr_n = mreq_wr_n & iorq_wr_n; 
-         // 
-         // this way glitches won't affect state of wr_n 
-         always @(full_wr_n) 
-                 if( !full_wr_n ) 
-                         #`Z80_DELAY_DOWN wr_n <= full_wr_n; 
-                 else 
-                         #`Z80_DELAY_UP wr_n <= full_wr_n; 
-   
-   
-   
-   
-   
-         // ROM model 
-         rom romko( 
-                    .addr( {rompg4,rompg3,rompg2,dos_n, (~rompg0_n), za[13:0]} ), 
-                    .data(zd_dut_to_z80), 
-                    .ce_n( romoe_n | (~csrom) ) 
-                  ); 
-   
-         // DRAM model 
-         drammem dramko1( 
-                          .ma(ra), 
-                          .d(rd), 
-                          .ras_n(rras0_n), 
-                          .ucas_n(rucas_n), 
-                          .lcas_n(rlcas_n), 
-                          .we_n(rwe_n) 
-                        ); 
-         // 
-         drammem dramko2( 
-                          .ma(ra), 
-                          .d(rd), 
-                          .ras_n(rras1_n), 
-                          .ucas_n(rucas_n), 
-                          .lcas_n(rlcas_n), 
-                          .we_n(rwe_n) 
-                        ); 
-         defparam dramko1._verbose_ = 0; 
-         defparam dramko2._verbose_ = 0; 
-   
-         defparam dramko1._init_ = 0; 
-         defparam dramko2._init_ = 0; 
-   
-   
-   
- `ifndef GATE 
-   
-         // trace rom page 
-         wire rma14,rma15; 
-   
-         assign rma14 = DUT.page[0][0]; 
-         assign rma15 = DUT.page[0][1]; 
-   
-   
-         always @(rma14 or rma15) 
-         begin 
- //              $display("at time %t us",$time/1000000); 
-   
- //              case( {rma15, rma14} ) 
-   
- //              2'b00: $display("BASIC 48"); 
- //              2'b01: $display("TR-DOS"); 
- //              2'b10: $display("BASIC 128"); 
- //              2'b11: $display("GLUKROM"); 
- //              default: $display("unknown"); 
-   
- //              endcase 
-   
- //              $display(""); 
-         end 
-   
-   
-         // trace ram page 
-         wire [5:0] rpag; 
-   
-         assign rpag=DUT.page[3][5:0]; 
-   
-         always @(rpag) 
-         begin 
- //              $display("at time %t us",$time/1000000); 
-   
- //              $display("RAM page is %d",rpag); 
-   
- //              $display(""); 
-         end 
-   
-   
-   
-         // key presses/nmi/whatsoever 
-         initial 
-         begin 
-                 #1; 
-                 tb.DUT.zkbdmus.kbd = 40'd0; 
-                 tb.DUT.zkbdmus.kbd[36] = 1'b1; 
-                 @(negedge int_n); 
-                 @(negedge int_n); 
-                 tb.DUT.zkbdmus.kbd[36] = 1'b0; 
-         end 
-   
- `endif 
-   
-   
-   
-   
-   
-   
-   
-   
- `ifdef ZLOG 
-         reg [ 7:0] old_opcode; 
-         reg [15:0] old_opcode_addr; 
-   
-         wire [7:0] zdd = zd_dut_to_z80; 
-   
-         reg was_m1; 
-   
-         always @(zm1_n) 
-         if( zm1_n ) 
-                 was_m1 <= 1'b0; 
-         else 
-                 was_m1 = 1'b1; 
-   
-         always @(posedge (zmreq_n | zrd_n | zm1_n | (~zrfsh_n)) ) 
-         if( was_m1 ) 
-         begin 
-                 if( (zdd!==old_opcode) || (za!==old_opcode_addr) ) 
-                 begin 
-                         if( tb.DUT.z80mem.romnram ) 
- //                              $display("Z80OPROM: addr %x, opcode %x, time %t",za,zdd,$time); 
-                                 $display("Z80OPROM: addr %x, opcode %x",za,zdd); 
-                         else 
- //                              $display("Z80OPRAM: addr %x, opcode %x, time %t",za,zdd,$time); 
-                                 $display("Z80OPRAM: addr %x, opcode %x",za,zdd); 
-                 end 
-   
-                 old_opcode      = zdd; 
-                 old_opcode_addr = za; 
-         end 
-   
-         always @(posedge (zmreq_n | zrd_n | (~zm1_n) | (~zrfsh_n)) ) 
-         if( !was_m1 ) 
-         begin 
-                 if( tb.DUT.z80mem.romnram ) 
- //                      $display("Z80RDROM: addr %x, rddata %x, time %t",za,zdd,$time); 
-                         $display("Z80RDROM: addr %x, rddata %x",za,zdd); 
-                 else 
- //                      $display("Z80RDRAM: addr %x, rddata %x, time %t",za,zdd,$time); 
-                         $display("Z80RDRAM: addr %x, rddata %x",za,zdd); 
-         end 
-   
-         always @(posedge (zmreq_n | zwr_n | (~zm1_n) | (~zrfsh_n)) ) 
-         begin 
-                 if( tb.DUT.z80mem.romnram ) 
- //                      $display("Z80WRROM: addr %x, wrdata %x, time %t",za,zd,$time); 
-                         $display("Z80WRROM: addr %x, wrdata %x",za,zd); 
-                 else 
- //                      $display("Z80WRRAM: addr %x, wrdata %x, time %t",za,zd,$time); 
-                         $display("Z80WRRAM: addr %x, wrdata %x",za,zd); 
-         end 
- `endif 
-   
-   
-   
-   
-         // turbo 
- `ifdef C7MHZ 
-         initial 
-                 force tb.DUT.zclock.turbo = 2'b01; 
- `else 
-         `ifdef C35MHZ 
-   
-                 initial 
-                         force tb.DUT.zclock.turbo = 2'b00; 
-   
-         `endif 
- `endif 
-   
-   
-         // raster type 
- `ifdef CCONTEND 
-         initial 
-                 force tb.DUT.modes_raster = 2'b10; 
- `endif 
-   
-   
-   
-   
- `ifdef NMITEST2 
-  `define M48K 
-   
-         initial 
-         begin 
-                 int i,fd; 
-                 logic [7:0] ldbyte; 
-   
-                 reset_pc=16'h8000; 
-                 reset_sp=16'h8000; 
-   
-                 fd = $fopen("dimkanmi.bin","rb"); 
-                 if( !fd ) 
-                 begin 
-                         $display("Can't open 'dimkanmi.bin'!"); 
-                         $stop; 
-                 end 
-   
-                 i='h8000; 
-   
-                 begin : load_loop 
-                         while(1) 
-                         begin 
-                                 if( 1!=$fread(ldbyte,fd) ) disable load_loop; 
-                                 put_byte_48k(i,ldbyte); 
-                                 i=i+1; 
-                         end 
-                 end 
-                 $fclose(fd); 
-   
-   
-                 wait(res===1'b0); 
-                 #(0.2); 
-                 tb.DUT.zports.atm_turbo = 1'b1; 
-                 tb.DUT.zports.peff7_int[4] = 1'b0; 
-                  
-                  
-                 #(100000); // 100 us 
-   
-                 //force nmi_n = 1'b0; 
-                 @(posedge fclk); 
-                 force tb.DUT.imm_nmi = 1'b1; 
-                 @(posedge fclk); 
-                 release tb.DUT.imm_nmi; 
-         end 
- `endif 
-   
-   
-   
- `ifdef NMITEST3 
-  `define M48K 
-   
-         initial 
-         begin 
-                 int i,fd; 
-                 logic [7:0] ldbyte; 
-   
-                 reset_pc=16'h0068; 
-                 reset_sp=16'h8000; 
-   
-   
-                 #(0.1); // let M48K rom load execute 
-   
-                 fd = $fopen("dimkarom.bin","rb"); 
-                 if( !fd ) 
-                 begin 
-                         $display("Can't open 'dimkarom.bin'!"); 
-                         $stop; 
-                 end 
-   
-                 i='h0066; 
-                 begin : load_loop 
-                         while(1) 
-                         begin 
-                                 if( 1!=$fread(ldbyte,fd) ) disable load_loop; 
-                                 tb.romko.zxevo_rom.mem[i]=ldbyte; 
-                                 i=i+1; 
-                         end 
-                 end 
-                 $fclose(fd); 
-   
-   
-                 wait(res===1'b0); 
-                 #(0.2); 
-                 tb.DUT.zports.atm_turbo = 1'b1; 
-                 tb.DUT.zports.peff7_int[4] = 1'b0; 
-                  
-                  
-                 #(1000000); // 1 ms 
-   
-                 //force nmi_n = 1'b0; 
-                 @(posedge fclk); 
-                 force tb.DUT.imm_nmi = 1'b1; 
-                 @(posedge fclk); 
-                 release tb.DUT.imm_nmi; 
-         end 
- `endif 
-   
-   
-         // port #FE monitor 
-         wire fe_write; 
-         assign fe_write = (za[7:0]==8'hFE) && !wr_n && !iorq_n; 
-         always @(negedge fe_write) 
-                 $display("port #FE monitor: border is %d at %t",zd[2:0],$time()); 
-         always @(negedge nmi_n) 
-                 $display("nmi monitor: negative edge at %t",$time());    
-   
-   
-   
-   
-         // start in 48k mode 
- `ifdef M48K 
-         initial 
-         begin : force_48k_mode 
-   
-                 int i; 
-                 int fd; 
-          
-                 fd = $fopen("48.rom","rb"); 
-                 if( 16384!=$fread(tb.romko.zxevo_rom.mem,fd) ) 
-                 begin 
-                         $display("Couldn't load 48k ROM!\n"); 
-                         $stop; 
-                 end 
-                 $fclose(fd); 
-                  
-                  
-                 wait(res===1'b0); 
-                 #(0.1); 
-   
-                 tb.DUT.zports.atm_turbo = 1'b0; 
-                 tb.DUT.zports.atm_pen = 1'b0; 
-                 tb.DUT.zports.atm_cpm_n = 1'b1; 
-                 tb.DUT.zports.atm_pen2 = 1'b0; 
-   
-                 tb.DUT.zdos.dos = 1'b0; 
-   
-   
-                 tb.DUT.instantiate_atm_pagers[0].atm_pager.pages[0] = 'd0; 
-                 tb.DUT.instantiate_atm_pagers[1].atm_pager.pages[0] = 'd5; 
-                 tb.DUT.instantiate_atm_pagers[2].atm_pager.pages[0] = 'd2; 
-                 tb.DUT.instantiate_atm_pagers[3].atm_pager.pages[0] = 'd0; 
-                 tb.DUT.instantiate_atm_pagers[0].atm_pager.pages[1] = 'd0; 
-                 tb.DUT.instantiate_atm_pagers[1].atm_pager.pages[1] = 'd5; 
-                 tb.DUT.instantiate_atm_pagers[2].atm_pager.pages[1] = 'd2; 
-                 tb.DUT.instantiate_atm_pagers[3].atm_pager.pages[1] = 'd0; 
-   
-                 tb.DUT.instantiate_atm_pagers[0].atm_pager.ramnrom[0] = 'd0; 
-                 tb.DUT.instantiate_atm_pagers[1].atm_pager.ramnrom[0] = 'd1; 
-                 tb.DUT.instantiate_atm_pagers[2].atm_pager.ramnrom[0] = 'd1; 
-                 tb.DUT.instantiate_atm_pagers[3].atm_pager.ramnrom[0] = 'd1; 
-                 tb.DUT.instantiate_atm_pagers[0].atm_pager.ramnrom[1] = 'd0; 
-                 tb.DUT.instantiate_atm_pagers[1].atm_pager.ramnrom[1] = 'd1; 
-                 tb.DUT.instantiate_atm_pagers[2].atm_pager.ramnrom[1] = 'd1; 
-                 tb.DUT.instantiate_atm_pagers[3].atm_pager.ramnrom[1] = 'd1; 
-   
-                 tb.DUT.zports.atm_scr_mode = 3'b011; 
-                  
-                 tb.DUT.zports.peff7_int = 8'h14; 
-                 tb.DUT.zports.p7ffd_int = 8'h30; 
-   
-   
-   
-                 for(i=0;i<512;i=i+1) 
-                 begin : set_palette //                                            R                               G                              B 
-                         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) }; 
-                 end 
-   
-         end 
- `endif 
-   
-   
-         // load and start some code after we've reached "1982 Sinclair research ltd" 
- `ifdef START_LOAD 
-         initial 
-         begin 
-                 int i,fd; 
-                 logic [7:0] ldbyte; 
-   
-                 wait( za==16'h15e0 && zmreq_n==1'b0 && zrd_n == 1'b0 ); 
-                  
-                 $display("loading and starting..."); 
-   
-                 fd = $fopen(`START_NAME,"rb"); 
-                 for(i=`START_ADDR;i<`START_ADDR+`START_LEN;i=i+1) 
-                 begin 
-                         if( 1!=$fread(ldbyte,fd) ) 
-                         begin 
-                                 $display("can't read byte from input file!"); 
-                                 $stop; 
-                         end 
-   
-                         put_byte_48k(i,ldbyte); 
-                 end 
-                 $fclose(fd); 
-   
-                 $display("load ok!"); 
-   
-                 reset_pc = 16'h9718; 
-                 reset_sp = 16'h6000; 
-                 @(posedge clkz_in); 
-                 force tb.zrst_n = 1'b0; 
-                 repeat(3) @(posedge clkz_in); 
-                 release tb.zrst_n; 
-                 @(posedge clkz_in); 
-                 reset_pc = 16'h0000; 
-                 reset_sp = 16'hFFFF; 
-         end 
- `endif 
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
- `ifndef NO_PIXER 
-         // picture out 
-         pixer pixer 
-         ( 
-                 .clk(fclk), 
-   
-                 .vsync(vsync), 
-                 .hsync(hsync), 
-                 .red(red), 
-                 .grn(grn), 
-                 .blu(blu) 
-         ); 
- `endif 
-   
-   
- /* 
-         // time ticks 
-         always 
-         begin : timemark 
-   
-                 integer ms; 
-   
-                 ms = ($time/1000000); 
-   
- //              $display("timemark %d ms",ms); 
-   
-                 #10000000.0; // 1 ms 
-         end 
- */ 
-   
-   
-         // init dram 
- `ifndef NMITEST2 
-         initial 
-         begin : init_dram 
-                 integer i; 
-                  
-                 integer page; 
-                 integer offset; 
-                  
-                 reg [7:0] trd [0:655359]; 
-   
-                 integer fd; 
-                 integer size; 
-   
-   
-   
-   
-                 for(i=0;i<4*1024*1024;i=i+1) 
-                 begin 
-                         put_byte(i,(i%257)); 
-                 end 
-   
-                 // load TRD 
-                 fd = $fopen("boot.trd","rb"); 
-                 size=$fread(trd,fd); 
-   
-                 if( size>655360 || size<=0 ) 
-                 begin 
-                         $display("Couldn't load or wrong boot.trd!\n"); 
-                         $stop; 
-                 end 
-                 $fclose(fd); 
-   
-   
-                 // copy TRD to RAM 
-                 page = 32'h0F4; 
-                 offset = 0; 
-   
-                 for(i=0;i<size;i=i+1) 
-                 begin 
-                         put_byte( .addr(page*16384+offset), .data(trd[i]) ); 
-   
-                         offset = offset + 1; 
-                         if( offset>=16384 ) 
-                         begin 
-                                 offset = 0; 
-                                 page = page - 1; 
-                         end 
-                 end 
-                  
-   
-                 $display("boot.trd loaded!\n"); 
-         end 
- `endif 
-   
-   
-   
-   
-   
-         // cmos simulation 
-         wire [7:0] cmos_addr; 
-         wire [7:0] cmos_read; 
-         wire [7:0] cmos_write; 
-         wire       cmos_rnw; 
-         wire       cmos_req; 
-   
-         cmosemu cmosemu 
-         ( 
-                 .zclk(clkz_in), 
-   
-                 .cmos_req  (cmos_req  ), 
-                 .cmos_addr (cmos_addr ), 
-                 .cmos_rnw  (cmos_rnw  ), 
-                 .cmos_read (cmos_read ), 
-                 .cmos_write(cmos_write) 
-         ); 
-   
-         assign cmos_req   = tb.DUT.wait_start_gluclock; 
-         assign cmos_rnw   = tb.DUT.wait_rnw; 
-         assign cmos_addr  = tb.DUT.gluclock_addr; 
-         assign cmos_write = tb.DUT.wait_write; 
-   
-         always @* 
-                 force tb.DUT.wait_read = cmos_read; 
-   
-   
-   
-   
- `ifdef SPITEST 
-         // spitest printing module 
-         // does not hurt at any time (yet), so attached forever 
-   
-         spitest_print spitest_print( 
-                 .sdclk (sdclk ), 
-                 .sddi  (sddi  ), 
-                 .sddo  (sddo  ), 
-                 .sdcs_n(sdcs_n) 
-         ); 
-   
-         // spitest AVR imitator 
-   
-         spitest_avr spitest_avr( 
-                 .spick  (spick  ), 
-                 .spics_n(spics_n), 
-                 .spido  (spido  ), 
-                 .spidi  (spidi  ) 
-         ); 
- `else 
-         assign sddi = 1'b1; 
-   
-         assign spics_n = 1'b1; 
-         assign spick   = 1'b0; 
-         assign spido   = 1'b1; 
- `endif 
-   
-   
-   
-   
-   
-         // set up breakpoint 
- /* 
-         wire bpt = za===16'h3FEC && zmreq_n===1'b0 && zrd_n===1'b0 && zm1_n===1'b0; 
-         initial 
-         begin 
-                 #(1_800_000_000); 
-                 @(posedge fclk); 
-                 forever 
-                 begin 
-                         @(posedge bpt); 
-                         $display("Stop at breakpoint"); 
-                         $stop; 
-                 end 
-         end 
- */ 
-   
-         // log INI command 
-         wire [15:0] #(0.1) dza; 
-         wire [ 7:0] #(0.1) dzw; 
-         wire [ 7:0] #(0.1) dzr; 
-   
-         typedef enum {FETCH,MRD,MWR,IORD,IOWR,IACK} cycle_t; 
-   
-         cycle_t curr_cycle; 
-         cycle_t cycles[0:3]; 
-         logic [15:0] addrs[0:3]; 
-         logic [ 7:0] wdata[0:3]; 
-         logic [ 7:0] rdata[0:3]; 
-   
-         wire is_fetch, is_mrd, is_mwr, is_iord, is_iowr, is_iack; 
-   
-         wire is_any; 
-   
-   
-   
-   
-         assign dza = za; 
-         assign dzw = zd; 
-         assign dzr = zd_dut_to_z80; 
-   
-         assign is_fetch = zm1_n===1'b0 && zmreq_n===1'b0 &&                   zrd_n===1'b0; 
-         assign is_mrd   = zm1_n===1'b1 && zmreq_n===1'b0 &&                   zrd_n===1'b0; 
-         assign is_mwr   =                 zmreq_n===1'b0 &&                                   zwr_n===1'b0; 
-         assign is_iord  =                                   ziorq_n===1'b0 && zrd_n===1'b0; 
-         assign is_iowr  =                                   ziorq_n===1'b0 &&                 zwr_n===1'b0; 
-         assign is_iack  = zm1_n===1'b0 &&                   ziorq_n===1'b0; 
-   
-         assign is_any = is_fetch || is_mrd || is_mwr || is_iord || is_iowr || is_iack; 
-   
-          
-         always @(negedge is_any) 
-         begin : remember 
-                 int i; 
-   
-                 for(i=1;i<4;i++) 
-                 begin 
-                         addrs [i]  <= addrs [i-1]; 
-                         cycles[i]  <= cycles[i-1]; 
-                          
-                         wdata [i]  <= wdata [i-1]; 
-                         rdata [i]  <= rdata [i-1]; 
-                 end 
-   
-                 addrs[0] <= dza; 
-                 cycles[0] <= curr_cycle; 
-                  
-                 wdata[0] <= dzw; 
-                 rdata[0] <= dzr; 
-         end 
-   
-         always @(posedge is_any) 
-         if(      is_fetch ) curr_cycle <= FETCH; 
-         else if( is_mrd )   curr_cycle <= MRD; 
-         else if( is_mwr )   curr_cycle <= MWR; 
-         else if( is_iord )  curr_cycle <= IORD; 
-         else if( is_iowr )  curr_cycle <= IOWR; 
-         else if( is_iack )  curr_cycle <= IACK; 
-         else 
-         begin 
-                 $display("Spurious cycle detect!"); 
-                 $stop; 
-         end 
-   
-   
-         // actual break 
-         always @(negedge is_any) 
-         begin 
-                 if( cycles[3]==FETCH && addrs[3][15:0 ]==16'h3FEC && rdata[3]==8'hED && 
-                     cycles[2]==FETCH &&                              rdata[2]==8'hA2 && 
-                     cycles[1]==IORD  && 
-                     cycles[0]==MWR   && addrs[0][15:14]== 2'd0 
-                 ) 
-                 begin 
-                         $display("trd INI caught! port=%04x, wraddr=%04x, time=%t",addrs[1],addrs[0],$time()); 
-                 end 
-         end 
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-         // timestamps 
-         always 
-         begin 
-                 $display("Running for %t ms",$time()/1000000000.0); 
-                 #1000000.0; 
-         end 
-   
-   
-   
-   
-   
-         // generate nmi after 2s 
-         initial 
-         begin 
-                 #2000000000.0; 
-   
-                 force DUT.set_nmi[0] = 1'b1; 
-                 #1000000.0; 
-                 release DUT.set_nmi[0]; 
-         end 
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-         task put_byte; 
-   
-                 input [21:0] addr; 
-                 input [ 7:0] data; 
-   
-   
-   
-                 reg [19:0] arraddr; 
-   
-                 begin 
-   
-                         arraddr = { addr[21:12], addr[11:2] }; 
-   
-                         case( addr[1:0] ) // chipsel, bytesel 
-   
-                         2'b00: tb.dramko1.array[arraddr][15:8] = data; 
-                         2'b01: tb.dramko1.array[arraddr][ 7:0] = data; 
-                         2'b10: tb.dramko2.array[arraddr][15:8] = data; 
-                         2'b11: tb.dramko2.array[arraddr][ 7:0] = data; 
-   
-                         endcase 
-                 end 
-   
-         endtask 
-   
-         task put_byte_48k 
-         ( 
-                 input [15:0] addr, 
-                 input [ 7:0] data 
-         ); 
-   
-                 case( addr[15:14] ) 
-                         2'b01: put_byte(addr-16'h4000 + 22'h14000,data); 
-                         2'b10: put_byte(addr-16'h8000 + 22'h08000,data); 
-                         2'b11: put_byte(addr-16'hc000 + 22'h00000,data); 
-                 endcase 
-         endtask 
-   
-   
-   
-   
- endmodule 
-   
-   
-