Subversion Repositories pentevo

Rev

Rev 918 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed | ?url?

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