Subversion Repositories pentevo

Rev

Rev 37 | Rev 425 | 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.  
  3. `include "../include/tune.v"
  4.  
  5.  
  6. `define HALF_CLK_PERIOD (17.8)
  7.  
  8. `define ZCLK_DELAY      (9.5)
  9.  
  10. // toshibo
  11. //`define Z80_DELAY_DOWN  (17.0)
  12. //`define Z80_DELAY_UP    (22.0)
  13.  
  14. // z0840008
  15. `define Z80_DELAY_DOWN   34
  16. `define Z80_DELAY_UP     30
  17.  
  18. module tb;
  19.  
  20.         reg fclk;
  21.  
  22.         wire clkz_out,clkz_in;
  23.  
  24.         reg iorq_n,mreq_n,rd_n,wr_n; // has some delays relative to z*_n (below)
  25.         reg m1_n,rfsh_n;             //
  26.  
  27.         wire int_n,res;                    //
  28.         tri1 ziorq_n,zmreq_n,zrd_n,zwr_n,zm1_n,zrfsh_n; // connected to Z80
  29.  
  30.         tri1 wait_n,nmi_n;
  31.  
  32.         assign nmi_n = 1'b1;
  33.         assign wait_n = 1'b1;
  34.  
  35.  
  36.         wire [15:0] za;
  37.         wire [7:0] zd;
  38.  
  39.  
  40.         wire csrom, romoe_n, romwe_n;
  41.         wire rompg0_n, dos_n;
  42.  
  43.         wire [15:0] rd;
  44.         wire [9:0] ra;
  45.         wire rwe_n,rucas_n,rlcas_n,rras0_n,rras1_n;
  46.  
  47.  
  48.         tri1 [15:0] ide_d;
  49.  
  50.  
  51.  
  52.         initial
  53.         begin
  54.  
  55.                 fclk = 1'b0;
  56.  
  57.                 forever #`HALF_CLK_PERIOD fclk = ~fclk;
  58.         end
  59.  
  60.  
  61.         assign #`ZCLK_DELAY clkz_in = ~clkz_out;
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69.         top DUT( .fclk(fclk),
  70.                  .clkz_out(clkz_out),
  71.                  .clkz_in(clkz_in),
  72.  
  73.                // z80
  74.                  .iorq_n(iorq_n),
  75.                  .mreq_n(mreq_n),
  76.                  .rd_n(rd_n),
  77.                  .wr_n(wr_n),
  78.                  .m1_n(m1_n),
  79.                  .rfsh_n(rfsh_n),
  80.                  .int_n(int_n),
  81.                  .nmi_n(nmi_n),
  82.                  .wait_n(wait_n),
  83.                  .res(res),
  84.                  //
  85.                  .d(zd),
  86.                  .a(za),
  87.  
  88.                  // ROM
  89.                  .csrom(csrom),
  90.                  .romoe_n(romoe_n),
  91.                  .romwe_n(romwe_n),
  92.                  .rompg0_n(rompg0_n),
  93.                  .dos_n(dos_n),
  94.  
  95.                  // DRAM
  96.                  .rd(rd),
  97.                  .ra(ra),
  98.                  .rwe_n(rwe_n),
  99.                  .rucas_n(rucas_n),
  100.                  .rlcas_n(rlcas_n),
  101.                  .rras0_n(rras0_n),
  102.                  .rras1_n(rras1_n),
  103.  
  104.                  // ZX-bus
  105.                  .iorqge1(1'b0),
  106.                  .iorqge2(1'b0),
  107.  
  108.                  // IDE
  109.                  .ide_d(ide_d),
  110.                  .ide_rdy(1'b1),
  111.  
  112.                  // VG93
  113.                  .step(1'b0),
  114.                  .vg_sl(1'b0),
  115.                  .vg_sr(1'b0),
  116.                  .vg_tr43(1'b0),
  117.                  .rdat_b_n(1'b1),
  118.                  .vg_wf_de(1'b0),
  119.                  .vg_drq(1'b1),
  120.                  .vg_irq(1'b1),
  121.                  .vg_wd(1'b0),
  122.  
  123.                  // SDcard SPI
  124.                  .sddi(1'b1),
  125.  
  126.                  // ATmega SPI
  127.                  .spics_n(1'b1),
  128.                  .spick(1'b0),
  129.                  .spido(1'b1)
  130.  
  131.                );
  132.  
  133.  
  134.         wire zrst_n = ~res;
  135.  
  136.         T80a z80( .RESET_n(zrst_n),
  137.                   .CLK_n(clkz_in),
  138.                   .WAIT_n(wait_n),
  139.                   .INT_n(int_n),
  140.                   .NMI_n(nmi_n),
  141.                   .M1_n(zm1_n),
  142.                   .RFSH_n(zrfsh_n),
  143.                   .MREQ_n(zmreq_n),
  144.                   .IORQ_n(ziorq_n),
  145.                   .RD_n(zrd_n),
  146.                   .WR_n(zwr_n),
  147.                   .BUSRQ_n(1'b1),
  148.                   .A(za),
  149.                   .D(zd)
  150.                 );
  151.  
  152.         // now make delayed versions of signals
  153.         //
  154.         always @(zm1_n)
  155.                 if( zm1_n )
  156.                         m1_n <= #`Z80_DELAY_UP zm1_n;
  157.                 else
  158.                         m1_n <= #`Z80_DELAY_DOWN zm1_n;
  159.         //
  160.         always @(zrfsh_n)
  161.                 if( zrfsh_n )
  162.                         rfsh_n <= #`Z80_DELAY_UP zrfsh_n;
  163.                 else
  164.                         rfsh_n <= #`Z80_DELAY_DOWN zrfsh_n;
  165.         //
  166.         always @(zmreq_n)
  167.                 if( zmreq_n )
  168.                         mreq_n <= #`Z80_DELAY_UP zmreq_n;
  169.                 else
  170.                         mreq_n <= #`Z80_DELAY_DOWN zmreq_n;
  171.         //
  172.         always @(ziorq_n)
  173.                 if( ziorq_n )
  174.                         iorq_n <= #`Z80_DELAY_UP ziorq_n;
  175.                 else
  176.                         iorq_n <= #`Z80_DELAY_DOWN ziorq_n;
  177.         //
  178.         always @(zrd_n)
  179.                 if( zrd_n )
  180.                         rd_n <= #`Z80_DELAY_UP zrd_n;
  181.                 else
  182.                         rd_n <= #`Z80_DELAY_DOWN zrd_n;
  183.         //
  184.         // special handling for broken WR_n
  185.         always @(negedge clkz_in)
  186.                 if( zwr_n )
  187.                         wr_n <= #`Z80_DELAY_UP zwr_n;
  188.                 else
  189.                         wr_n <= #`Z80_DELAY_DOWN zwr_n;
  190.  
  191.  
  192.         // ROM model
  193.         rom romko(
  194.                    .addr( {dos_n, (~rompg0_n), za[13:0]} ),
  195.                    .data(zd),
  196.                    .ce_n( romoe_n | (~csrom) )
  197.                  );
  198.  
  199.         // DRAM model
  200.         drammem dramko1(
  201.                          .ma(ra),
  202.                          .d(rd),
  203.                          .ras_n(rras0_n),
  204.                          .ucas_n(rucas_n),
  205.                          .lcas_n(rlcas_n),
  206.                          .we_n(rwe_n)
  207.                        );
  208.         //
  209.         drammem dramko2(
  210.                          .ma(ra),
  211.                          .d(rd),
  212.                          .ras_n(rras1_n),
  213.                          .ucas_n(rucas_n),
  214.                          .lcas_n(rlcas_n),
  215.                          .we_n(rwe_n)
  216.                        );
  217.         defparam dramko1._verbose_ = 0;
  218.         defparam dramko2._verbose_ = 0;
  219.  
  220.  
  221.  
  222.  
  223.         // trace rom page
  224.         wire rma14,rma15;
  225.  
  226.         assign rma14 = DUT.page[0][0];
  227.         assign rma15 = DUT.page[0][1];
  228.  
  229.  
  230.         always @(rma14 or rma15)
  231.         begin
  232.                 $display("at time %t us",$time/10000);
  233.  
  234.                 case( {~rma14, ~rma15} )
  235.  
  236.                 2'b00: $display("GLUKROM");
  237.                 2'b01: $display("TR-DOS");
  238.                 2'b10: $display("BASIC 128");
  239.                 2'b11: $display("BASIC 48");
  240.                 default: $display("unknown");
  241.  
  242.                 endcase
  243.  
  244.                 $display("");
  245.         end
  246.  
  247.  
  248.         // trace ram page
  249.         wire [5:0] rpag;
  250.  
  251.         assign rpag=DUT.page[3][5:0];
  252.  
  253.         always @(rpag)
  254.         begin
  255.                 $display("at time %t us",$time/10000);
  256.  
  257.                 $display("RAM page is %d",rpag);
  258.  
  259.                 $display("");
  260.         end
  261.  
  262.  
  263.  
  264.         // time ticks
  265.         always
  266.         begin : timemark
  267.  
  268.                 integer ms;
  269.  
  270.                 ms = ($time/1000000);
  271.  
  272.                 $display("timemark %d ms",ms);
  273.  
  274.                 #10000000.0; // 1 ms
  275.         end
  276.  
  277.  
  278.  
  279.  
  280.         // emulate key presses
  281.         initial
  282.         begin
  283.                 tb.DUT.zkbdmus.kbd = 40'd0;
  284.                
  285.                 #600000000;
  286.  
  287.                 @(negedge int_n);
  288.  
  289.                 tb.DUT.zkbdmus.kbd[13] = 1'b1;
  290.  
  291.                 @(negedge int_n);
  292.                 @(negedge int_n);
  293.  
  294.                 tb.DUT.zkbdmus.kbd[13] = 1'b0;
  295.                
  296. //              $stop;
  297.         end
  298.  
  299.  
  300.  
  301.  
  302.  
  303.  
  304. endmodule
  305.  
  306.  
  307.