Subversion Repositories pentevo

Rev

Rev 280 | Rev 469 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. // simulate fpga top-level with external dram, rom, z80
  2. // (c) 2010 NedoPC
  3.  
  4. `include "../include/tune.v"
  5.  
  6.  
  7. `define HALF_CLK_PERIOD (17.8)
  8.  
  9. `define ZCLK_DELAY      (9.5)
  10.  
  11. // toshibo
  12. //`define Z80_DELAY_DOWN  (17.0)
  13. //`define Z80_DELAY_UP    (22.0)
  14.  
  15. // z0840008
  16. `define Z80_DELAY_DOWN   34
  17. `define Z80_DELAY_UP     30
  18.  
  19. module tb;
  20.  
  21.         reg fclk;
  22.  
  23.         wire clkz_out,clkz_in;
  24.  
  25.         reg iorq_n,mreq_n,rd_n,wr_n; // has some delays relative to z*_n (below)
  26.         reg m1_n,rfsh_n;             //
  27.  
  28.         wire res;                    //
  29.         tri1 ziorq_n,zmreq_n,zrd_n,zwr_n,zm1_n,zrfsh_n; // connected to Z80
  30.  
  31.         tri1 int_n,wait_n,nmi_n;
  32.         wire zint_n,zwait_n,znmi_n;
  33.  
  34.         wire [15:0] za;
  35.         wire [7:0] zd;
  36.  
  37.  
  38.         wire csrom, romoe_n, romwe_n;
  39.         wire rompg0_n, dos_n;
  40.         wire rompg2,rompg3,rompg4;
  41.  
  42.         wire [15:0] rd;
  43.         wire [9:0] ra;
  44.         wire rwe_n,rucas_n,rlcas_n,rras0_n,rras1_n;
  45.  
  46.  
  47.         tri1 [15:0] ide_d;
  48.  
  49.  
  50.         wire hsync,vsync;
  51.         wire [1:0] red,grn,blu;
  52.  
  53.  
  54.  
  55.  
  56.         assign zwait_n = (wait_n==1'b0) ? 1'b0 : 1'b1;
  57.         assign znmi_n = (nmi_n==1'b0) ? 1'b0 : 1'b1;
  58.         assign zint_n = (int_n==1'b0) ? 1'b0 : 1'b1;
  59.  
  60.  
  61.  
  62.  
  63.  
  64.  
  65.         initial
  66.         begin
  67.  
  68.                 fclk = 1'b0;
  69.  
  70.                 forever #`HALF_CLK_PERIOD fclk = ~fclk;
  71.         end
  72.  
  73.  
  74.         assign #`ZCLK_DELAY clkz_in = ~clkz_out;
  75.  
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.         top DUT( .fclk(fclk),
  83.                  .clkz_out(clkz_out),
  84.                  .clkz_in(clkz_in),
  85.  
  86.                // z80
  87.                  .iorq_n(iorq_n),
  88.                  .mreq_n(mreq_n),
  89.                  .rd_n(rd_n),
  90.                  .wr_n(wr_n),
  91.                  .m1_n(m1_n),
  92.                  .rfsh_n(rfsh_n),
  93.                  .int_n(int_n),
  94.                  .nmi_n(nmi_n),
  95.                  .wait_n(wait_n),
  96.                  .res(res),
  97.                  //
  98.                  .d(zd),
  99.                  .a(za),
  100.  
  101.                  // ROM
  102.                  .csrom(csrom),
  103.                  .romoe_n(romoe_n),
  104.                  .romwe_n(romwe_n),
  105.                  .rompg0_n(rompg0_n),
  106.                  .dos_n(dos_n),
  107.                  .rompg2(rompg2),
  108.                  .rompg3(rompg3),
  109.                  .rompg4(rompg4),
  110.  
  111.                  // DRAM
  112.                  .rd(rd),
  113.                  .ra(ra),
  114.                  .rwe_n(rwe_n),
  115.                  .rucas_n(rucas_n),
  116.                  .rlcas_n(rlcas_n),
  117.                  .rras0_n(rras0_n),
  118.                  .rras1_n(rras1_n),
  119.  
  120.                  // ZX-bus
  121.                  .iorqge1(1'b0),
  122.                  .iorqge2(1'b0),
  123.  
  124.                  // IDE
  125.                  .ide_d(ide_d),
  126.                  .ide_rdy(1'b1),
  127.  
  128.                  // VG93
  129.                  .step(1'b0),
  130.                  .vg_sl(1'b0),
  131.                  .vg_sr(1'b0),
  132.                  .vg_tr43(1'b0),
  133.                  .rdat_b_n(1'b1),
  134.                  .vg_wf_de(1'b0),
  135.                  .vg_drq(1'b1),
  136.                  .vg_irq(1'b1),
  137.                  .vg_wd(1'b0),
  138.  
  139.                  // SDcard SPI
  140.                  .sddi(1'b1),
  141.  
  142.                  // ATmega SPI
  143.                  .spics_n(1'b1),
  144.                  .spick(1'b0),
  145.                  .spido(1'b1),
  146.  
  147.                  .vhsync(hsync),
  148.                  .vvsync(vsync),
  149.                  .vred(red),
  150.                  .vgrn(grn),
  151.                  .vblu(blu)
  152.  
  153.                );
  154.  
  155.  
  156.         wire zrst_n = ~res;
  157.  
  158.         T80a z80( .RESET_n(zrst_n),
  159.                   .CLK_n(clkz_in),
  160.                   .WAIT_n(zwait_n),
  161.                   .INT_n(zint_n),
  162.                   .NMI_n(znmi_n),
  163.                   .M1_n(zm1_n),
  164.                   .RFSH_n(zrfsh_n),
  165.                   .MREQ_n(zmreq_n),
  166.                   .IORQ_n(ziorq_n),
  167.                   .RD_n(zrd_n),
  168.                   .WR_n(zwr_n),
  169.                   .BUSRQ_n(1'b1),
  170.                   .A(za),
  171.                   .D(zd)
  172.                 );
  173.  
  174.         // now make delayed versions of signals
  175.         //
  176.         reg  mreq_wr_n;
  177.         wire iorq_wr_n, full_wr_n;
  178.         //
  179.         // first, assure there is no X's at the start
  180.         //
  181.         initial
  182.         begin
  183.                 m1_n      = 1'b1;
  184.                 rfsh_n    = 1'b1;
  185.                 mreq_n    = 1'b1;
  186.                 iorq_n    = 1'b1;
  187.                 rd_n      = 1'b1;
  188.                 wr_n      = 1'b1;
  189.                 mreq_wr_n = 1'b1;
  190.         end
  191.         //
  192.         always @(zm1_n)
  193.                 if( zm1_n )
  194.                         m1_n <= #`Z80_DELAY_UP zm1_n;
  195.                 else
  196.                         m1_n <= #`Z80_DELAY_DOWN zm1_n;
  197.         //
  198.         always @(zrfsh_n)
  199.                 if( zrfsh_n )
  200.                         rfsh_n <= #`Z80_DELAY_UP zrfsh_n;
  201.                 else
  202.                         rfsh_n <= #`Z80_DELAY_DOWN zrfsh_n;
  203.         //
  204.         always @(zmreq_n)
  205.                 if( zmreq_n )
  206.                         mreq_n <= #`Z80_DELAY_UP zmreq_n;
  207.                 else
  208.                         mreq_n <= #`Z80_DELAY_DOWN zmreq_n;
  209.         //
  210.         always @(ziorq_n)
  211.                 if( ziorq_n )
  212.                         iorq_n <= #`Z80_DELAY_UP ziorq_n;
  213.                 else
  214.                         iorq_n <= #`Z80_DELAY_DOWN ziorq_n;
  215.         //
  216.         always @(zrd_n)
  217.                 if( zrd_n )
  218.                         rd_n <= #`Z80_DELAY_UP zrd_n;
  219.                 else
  220.                         rd_n <= #`Z80_DELAY_DOWN zrd_n;
  221.         //
  222.         //
  223.         // special handling for broken T80 WR_n
  224.         //     
  225.         always @(negedge clkz_in)
  226.                 mreq_wr_n <= zwr_n;
  227.         //
  228.         assign iorq_wr_n = ziorq_n | (~zrd_n) | (~zm1_n);
  229.         //
  230.         assign full_wr_n = mreq_wr_n & iorq_wr_n;
  231.         //
  232.         // this way glitches won't affect state of wr_n
  233.         always @(full_wr_n)
  234.                 if( !full_wr_n )
  235.                         #`Z80_DELAY_DOWN wr_n <= full_wr_n;
  236.                 else
  237.                         #`Z80_DELAY_UP wr_n <= full_wr_n;
  238.  
  239.  
  240.  
  241.  
  242.  
  243.         // ROM model
  244.         rom romko(
  245.                    .addr( {rompg4,rompg3,rompg2,dos_n, (~rompg0_n), za[13:0]} ),
  246.                    .data(zd),
  247.                    .ce_n( romoe_n | (~csrom) )
  248.                  );
  249.  
  250.         // DRAM model
  251.         drammem dramko1(
  252.                          .ma(ra),
  253.                          .d(rd),
  254.                          .ras_n(rras0_n),
  255.                          .ucas_n(rucas_n),
  256.                          .lcas_n(rlcas_n),
  257.                          .we_n(rwe_n)
  258.                        );
  259.         //
  260.         drammem dramko2(
  261.                          .ma(ra),
  262.                          .d(rd),
  263.                          .ras_n(rras1_n),
  264.                          .ucas_n(rucas_n),
  265.                          .lcas_n(rlcas_n),
  266.                          .we_n(rwe_n)
  267.                        );
  268.         defparam dramko1._verbose_ = 0;
  269.         defparam dramko2._verbose_ = 0;
  270.  
  271.  
  272.  
  273. `ifndef GATE
  274.  
  275.         // trace rom page
  276.         wire rma14,rma15;
  277.  
  278.         assign rma14 = DUT.page[0][0];
  279.         assign rma15 = DUT.page[0][1];
  280.  
  281.  
  282.         always @(rma14 or rma15)
  283.         begin
  284.                 $display("at time %t us",$time/1000000);
  285.  
  286.                 case( {rma15, rma14} )
  287.  
  288.                 2'b00: $display("BASIC 48");
  289.                 2'b01: $display("TR-DOS");
  290.                 2'b10: $display("BASIC 128");
  291.                 2'b11: $display("GLUKROM");
  292.                 default: $display("unknown");
  293.  
  294.                 endcase
  295.  
  296.                 $display("");
  297.         end
  298.  
  299.  
  300.         // trace ram page
  301.         wire [5:0] rpag;
  302.  
  303.         assign rpag=DUT.page[3][5:0];
  304.  
  305.         always @(rpag)
  306.         begin
  307.                 $display("at time %t us",$time/1000000);
  308.  
  309.                 $display("RAM page is %d",rpag);
  310.  
  311.                 $display("");
  312.         end
  313.  
  314.  
  315.  
  316.         // key presses/nmi/whatsoever
  317.         initial
  318.         begin
  319.                 #1;
  320.                 tb.DUT.zkbdmus.kbd = 40'd0;
  321.                 tb.DUT.zkbdmus.kbd[36] = 1'b1;
  322.                 @(negedge int_n);
  323.                 tb.DUT.zkbdmus.kbd[36] = 1'b0;
  324.         end
  325.  
  326.         initial
  327.         begin : gen_nmi
  328.  
  329.                 reg [21:0] a;
  330.  
  331.                 #1000000000;
  332.  
  333.                 a = 22'h3FC066;
  334.  
  335.                 put_byte(a,8'hF5); a=a+1;
  336.                 put_byte(a,8'hC5); a=a+1;
  337.                 put_byte(a,8'hD5); a=a+1;
  338.                 put_byte(a,8'hE5); a=a+1;
  339.  
  340.                 put_byte(a,8'h10); a=a+1;
  341.                 put_byte(a,8'hFE); a=a+1;
  342.  
  343.                 put_byte(a,8'h14); a=a+1;
  344.  
  345.                 put_byte(a,8'h01); a=a+1;
  346.                 put_byte(a,8'hFE); a=a+1;
  347.                 put_byte(a,8'h7F); a=a+1;
  348.  
  349.                 put_byte(a,8'hED); a=a+1;
  350.                 put_byte(a,8'h51); a=a+1;
  351.  
  352.                 put_byte(a,8'hED); a=a+1;
  353.                 put_byte(a,8'h78); a=a+1;
  354.  
  355.                 put_byte(a,8'h1F); a=a+1;
  356.                
  357.                 put_byte(a,8'hDA); a=a+1;
  358.                 put_byte(a,8'h6A); a=a+1;
  359.                 put_byte(a,8'h00); a=a+1;
  360.  
  361.                 put_byte(a,8'hE1); a=a+1;
  362.                 put_byte(a,8'hD1); a=a+1;
  363.                 put_byte(a,8'hC1); a=a+1;
  364.                 put_byte(a,8'hF1); a=a+1;
  365.  
  366.                 put_byte(a,8'hD3); a=a+1;
  367.                 put_byte(a,8'hBE); a=a+1;
  368.  
  369.                 put_byte(a,8'hED); a=a+1;
  370.                 put_byte(a,8'h45); a=a+1;
  371.  
  372.  
  373.                 @(posedge fclk);
  374.                 tb.DUT.slavespi.cfg0_reg_out[1] = 1'b1;
  375.                 @(posedge fclk);
  376.                 tb.DUT.slavespi.cfg0_reg_out[1] = 1'b0;
  377.  
  378.                 #64000000;
  379.  
  380.                 tb.DUT.zkbdmus.kbd[39] = 1'b1;
  381.                 @(negedge int_n);
  382.                 tb.DUT.zkbdmus.kbd[39] = 1'b0;
  383.  
  384.         end
  385. `endif
  386.  
  387.  
  388.  
  389.  
  390.  
  391.  
  392.  
  393.  
  394.  
  395.         // picture out
  396.         pixer pixer
  397.         (
  398.                 .clk(fclk),
  399.  
  400.                 .vsync(vsync),
  401.                 .hsync(hsync),
  402.                 .red(red),
  403.                 .grn(grn),
  404.                 .blu(blu)
  405.         );
  406.  
  407.  
  408.  
  409.  
  410.         // time ticks
  411.         always
  412.         begin : timemark
  413.  
  414.                 integer ms;
  415.  
  416.                 ms = ($time/1000000);
  417.  
  418.                 $display("timemark %d ms",ms);
  419.  
  420.                 #10000000.0; // 1 ms
  421.         end
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.  
  432.  
  433.         task put_byte;
  434.  
  435.                 input [21:0] addr;
  436.                 input [ 7:0] data;
  437.  
  438.  
  439.                
  440.                 reg [19:0] arraddr;
  441.  
  442.                 begin
  443.  
  444.                         arraddr = { addr[21:12], addr[11:2] };
  445.  
  446.                         case( addr[1:0] ) // chipsel, bytesel
  447.  
  448.                         2'b00: tb.dramko1.array[arraddr][15:8] = data;
  449.                         2'b01: tb.dramko1.array[arraddr][ 7:0] = data;
  450.                         2'b10: tb.dramko2.array[arraddr][15:8] = data;
  451.                         2'b11: tb.dramko2.array[arraddr][ 7:0] = data;
  452.  
  453.                         endcase
  454.                 end
  455.  
  456.         endtask
  457.  
  458.  
  459.  
  460.  
  461.  
  462. endmodule
  463.  
  464.  
  465.