Subversion Repositories zxusbnet

Rev

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

  1. // ZXiznet project
  2. // (c) NedoPC 2012
  3. //
  4. // testbench
  5.  
  6.  
  7. `timescale 1ns/100ps
  8.  
  9. //// CPU at 14MHz
  10. `define HALF_CPU_PERIOD (35)
  11.  
  12. // CPU at 7MHz
  13. //`define HALF_CPU_PERIOD (70)
  14.  
  15. // filter clock
  16. `define HALF_FCLK_PERIOD (20.7)
  17.  
  18. module tb;
  19.  
  20.         reg rst_n;
  21.         reg clk;
  22.  
  23.         reg fclk;
  24.  
  25.  
  26.         tri1 iorq_n,
  27.              mreq_n,
  28.              rd_n,
  29.              wr_n;
  30.  
  31.         tri1 int_n;
  32.  
  33.         wire csrom_n;
  34.  
  35.         wire iorqge,
  36.              blkrom;
  37.        
  38.  
  39.         wire [15:0] a;
  40.         wire [ 7:0] d;
  41.  
  42.         tri1 [ 7:0] #1 bd;
  43.  
  44.         wire brd_n, bwr_n;
  45.  
  46.  
  47.         reg [7:0] tmp;
  48.  
  49.  
  50.  
  51.  
  52.         wire [9:0] w5300_addr;
  53.         wire       w5300_rst_n;
  54.         wire       w5300_cs_n;
  55.         wire       w5300_int_n;
  56.  
  57.         wire       sl811_rst_n;
  58.         wire       sl811_a0;
  59.         wire       sl811_cs_n;
  60.         wire       sl811_ms_n;
  61.         wire       sl811_intrq;
  62.  
  63.        
  64.        
  65.         reg usb_power;
  66.  
  67.  
  68.         reg [1:0] where_rom;
  69.  
  70.  
  71.  
  72.  
  73.         // filter clock
  74.         initial
  75.         begin
  76.                 fclk = 1'b1;
  77.  
  78.                 forever #`HALF_FCLK_PERIOD fclk = ~fclk;
  79.         end
  80.  
  81.  
  82.         initial
  83.         begin
  84.                 clk = 1'b1;
  85.  
  86.                 forever #`HALF_CPU_PERIOD clk = ~clk;
  87.         end
  88.  
  89.  
  90.         initial
  91.         begin
  92.                 rst_n = 1'b0;
  93.  
  94.                 repeat(3) @(posedge clk);
  95.  
  96.                 rst_n <= 1'b1;
  97.         end
  98.  
  99.  
  100.  
  101.         initial
  102.         begin
  103.                 where_rom = 2'b00;
  104.  
  105.                 usb_power = 1'b0;
  106.         end
  107.  
  108.  
  109.  
  110.  
  111.  
  112.  
  113.  
  114.  
  115.         top DUT
  116.         (
  117. `ifdef CLOCKED_FILTER
  118.                 .fclk(fclk),
  119. `endif
  120.                 .za(a),
  121.                 .zd(d),
  122.  
  123.                 .ziorq_n(iorq_n),
  124.                 .zmreq_n(mreq_n),
  125.                 .zrd_n(rd_n),
  126.                 .zwr_n(wr_n),
  127.  
  128.                 .zcsrom_n(csrom_n),
  129.                
  130.                 .ziorqge(iorqge),
  131.                 .zblkrom(blkrom),
  132.  
  133.                 .zrst_n(rst_n),
  134.                 .zint_n(int_n),
  135.  
  136.                 .bd(bd),
  137.  
  138.                 .bwr_n(bwr_n),
  139.                 .brd_n(brd_n),
  140.  
  141.  
  142.                 .w5300_rst_n(w5300_rst_n),
  143.                 .w5300_addr (w5300_addr ),
  144.                 .w5300_cs_n (w5300_cs_n ),
  145.                 .w5300_int_n(w5300_int_n),
  146.                
  147.                 .sl811_rst_n(sl811_rst_n),
  148.                 .sl811_intrq(sl811_intrq),
  149.                 .sl811_ms_n (sl811_ms_n ),
  150.                 .sl811_cs_n (sl811_cs_n ),
  151.                 .sl811_a0   (sl811_a0   ),
  152.  
  153.                 .usb_power(usb_power)
  154.  
  155.         );
  156.  
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163.  
  164.  
  165.  
  166.  
  167.  
  168.         ssz80 z
  169.         (
  170.                 .clk  (clk  ),
  171.                 .rst_n(rst_n),
  172.  
  173.                 .iorq_n(iorq_n),
  174.                 .mreq_n(mreq_n),
  175.                 .rd_n  (rd_n  ),
  176.                 .wr_n  (wr_n  ),
  177.  
  178.                 .a(a),
  179.                 .d(d)
  180.         );
  181.  
  182.  
  183.  
  184.  
  185.  
  186.         w5300 w
  187.         (
  188.                 .rst_n(w5300_rst_n),
  189.                 .addr (w5300_addr ),
  190.                 .cs_n (w5300_cs_n ),
  191.                 .rd_n (brd_n      ),
  192.                 .wr_n (bwr_n      ),
  193.                 .int_n(w5300_int_n),
  194.                 .d(bd)
  195.         );
  196.  
  197.  
  198.         sl811 s
  199.         (
  200.                 .rst_n(sl811_rst_n),
  201.                 .a0   (sl811_a0   ),
  202.                 .cs_n (sl811_cs_n ),
  203.                 .wr_n (bwr_n      ),
  204.                 .rd_n (brd_n      ),
  205.                 .ms   (~sl811_ms_n),
  206.                 .intrq(sl811_intrq),
  207.                 .d(bd)
  208.         );
  209.  
  210.  
  211.         // csrom gen
  212.         assign csrom_n = !(a[15:14]==where_rom[1:0]);
  213.  
  214.        
  215.        
  216.        
  217.        
  218.        
  219. ////////////////////////////////////////////////////////////////////////////////       
  220. ////////////////////////////////////////////////////////////////////////////////       
  221. ////////////////////////////////////////////////////////////////////////////////       
  222. /// here start tests
  223.  
  224.         reg [15:0] rstint_port = 16'h83_AB;
  225.         reg [15:0] w5300_port  = 16'h82_AB;
  226.         reg [15:0] sl811_port  = 16'h81_AB;
  227.         reg [15:0] sl_addr     = 16'h80_AB;
  228.         reg [15:0] sl_data     = 16'h7F_AB;
  229.        
  230.         initial
  231.         begin : tests
  232.        
  233.        
  234.                 reg [7:0] tmp;
  235.                 reg [7:0] tmp2;
  236.  
  237.                
  238.                 wait(rst_n===1'b1);
  239.  
  240.                 repeat(10) @(posedge clk);
  241.        
  242.        
  243.  
  244.                 test_pwon_resets();
  245.                 test_pwon_ints();
  246.  
  247.  
  248.  
  249.                 forever // repeat(10000)
  250.                 begin
  251.                         case( $random%6 )
  252.                         0: check_sl811_access();
  253.                         1: check_w5300_mem_access();
  254.                         2: check_w5300_port_access();
  255.                         3: test_resets();
  256.                         4: check_sl811_port();
  257.                         5: test_ints();
  258.                         endcase
  259.                 end
  260.  
  261.                
  262.  
  263.  
  264.  
  265.  
  266.  
  267.  
  268.  
  269.  
  270.                
  271.  
  272.  
  273.  
  274.  
  275.                
  276.                
  277.                 $display("all tests passed!");
  278.                 $stop;
  279.         end
  280.  
  281.        
  282.        
  283.  
  284.        
  285.        
  286.        
  287.        
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.         // translates memory address to w5300 address in accordance with specs
  296.         function [9:0] mk_w5300_addr( input [13:0] mem_addr );
  297.  
  298.                 if( mem_addr<14'h2000 )
  299.                 begin
  300.                         mk_w5300_addr = mem_addr[9:0];
  301.                 end
  302.                 else if( mem_addr<14'h3000 )
  303.                 begin
  304.                         mk_w5300_addr[9] = 1'b1;
  305.                         mk_w5300_addr[8:6] = mem_addr[11:9];
  306.                         mk_w5300_addr[5:1] = 5'b10111;
  307.                         mk_w5300_addr[0] = mem_addr[0];
  308.                 end
  309.                 else // if( mem_addr<14'h4000 )
  310.                 begin
  311.                         mk_w5300_addr[9] = 1'b1;
  312.                         mk_w5300_addr[8:6] = mem_addr[11:9];
  313.                         mk_w5300_addr[5:1] = 5'b11000;
  314.                         mk_w5300_addr[0] = mem_addr[0];
  315.                 end
  316.  
  317.         endfunction
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.         task check_w5300_port_access();
  325.  
  326.                 reg [7:0] tmp,rddata,wrdata;
  327.                 reg [9:0] waddr;
  328.                 reg       a0_inv;
  329.  
  330.                 reg [15:0] port;
  331.  
  332.  
  333.                 a0_inv = $random>>31;
  334.  
  335.                 waddr = $random>>22;
  336.  
  337.  
  338.  
  339.                 z.iowr(w5300_port,{waddr[9:7],1'b1,a0_inv,3'd0});
  340.  
  341.                 z.iord(w5300_port,tmp);
  342.                 if( tmp!=={waddr[9:7],1'b1,a0_inv,3'd0} )
  343.                 begin
  344.                         $display("can't set w5300 port!");
  345.                         $stop;
  346.                 end
  347.                
  348.                 // make access port address
  349.                 port = sl_data;
  350.                 port[14:8] = waddr[6:0];
  351.  
  352.  
  353.                 w.init_access(); // clear access_* to X
  354.  
  355.  
  356.                 if( $random>>31 )
  357.                 begin
  358.                         wrdata = $random>>24;
  359.                         z.iowr(port,wrdata);
  360.                         if( w.get_addr()!==(waddr^a0_inv) ||
  361.                             w.get_rnw()!==1'b0            ||
  362.                             w.get_wr_data()!==wrdata      )
  363.                         begin
  364.                                 $display("w5300 port write failed!");
  365.                                 $stop;
  366.                         end
  367.                 end
  368.                 else
  369.                 begin
  370.                         rddata = $random>>24;
  371.                         w.set_rd_data(rddata);
  372.                         z.iord(port,tmp);
  373.                         @(negedge clk);
  374.                         if( w.get_addr()!==(waddr^a0_inv) ||
  375.                             w.get_rnw()!==1'b1            ||
  376.                             tmp!==rddata                  )
  377.                         begin
  378.                                 $display("w5300 port read failed!");
  379.                                 $stop;
  380.                         end
  381.                 end
  382.  
  383.         endtask
  384.  
  385.  
  386.  
  387.  
  388.         task check_w5300_mem_access;
  389.  
  390.                 reg [7:0] tmp,rddata,wrdata;
  391.                 reg [15:0] memaddr;
  392.                 reg [ 9:0] waddr;
  393.  
  394.                 reg [1:0] rom;
  395.                 reg       a0_inv;
  396.                 reg       sub_ena;
  397.  
  398.  
  399.                 rom    = $random>>30;
  400.                 a0_inv = $random>>31;
  401.                 sub_ena= $random>>31;
  402.  
  403.                 z.iowr(w5300_port,{4'd0,a0_inv,sub_ena,rom});
  404.  
  405.                 z.iord(w5300_port,tmp);
  406.                 if( tmp!=={4'd0,a0_inv,sub_ena,rom} )
  407.                 begin
  408.                         $display("can't set w5300 port!");
  409.                         $stop;
  410.                 end
  411.  
  412.  
  413.                 if( $random>>31 )
  414.                         where_rom = rom;
  415.                 else
  416.                 begin
  417.                         where_rom = $random>>30;
  418.                         while( where_rom==rom )
  419.                                 where_rom = $random>>30;
  420.                 end
  421.  
  422.  
  423.  
  424.                 w.init_access(); // clear access_* to X
  425.  
  426.  
  427.                 memaddr = $random>>18;
  428.                 memaddr[15:14] = where_rom;
  429.  
  430.  
  431.  
  432.                 if( $random>>31 )
  433.                 begin
  434.                         wrdata = $random>>24;
  435.                         z.memwr(memaddr,wrdata);
  436.                         if( where_rom==rom && sub_ena )
  437.                         begin
  438.                                 if( w.get_addr()!==(mk_w5300_addr(memaddr[13:0])^a0_inv) ||
  439.                                     w.get_rnw()!==1'b0                                   ||
  440.                                     w.get_wr_data()!==wrdata                             )
  441.                                 begin
  442.                                         $display("w5300 write failed!");
  443.                                         $stop;
  444.                                 end
  445.                         end
  446.                         else
  447.                         begin
  448.                                 if( w.get_addr()!=={10{1'bX}} || w.get_rnw()!==1'bX || w.get_wr_data()!=={8{1'bX}} )
  449.                                 begin
  450.                                         $display("write succeeded with wrong ROM mapping!");
  451.                                         $stop;
  452.                                 end
  453.                         end
  454.                 end
  455.                 else
  456.                 begin
  457.                         rddata = $random>>24;
  458.                         w.set_rd_data(rddata);
  459.                         z.memrd(memaddr,tmp);
  460.                         @(negedge clk);
  461.                         if( where_rom==rom && sub_ena )
  462.                         begin
  463.                                 if( w.get_addr()!==(mk_w5300_addr(memaddr[13:0])^a0_inv) ||
  464.                                     w.get_rnw()!==1'b1                                   ||
  465.                                     tmp!==rddata                                         )
  466.                                 begin
  467.                                         $display("w5300 read failed!");
  468.                                         $stop;
  469.                                 end
  470.                         end
  471.                         else
  472.                         begin
  473.                                 if( w.get_addr()!=={10{1'bX}} || w.get_rnw()!==1'bX )
  474.                                 begin
  475.                                         $display("read succeeded with wrong ROM mapping!");
  476.                                         $stop;
  477.                                 end
  478.                         end
  479.                 end
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.  
  492.  
  493.         endtask
  494.  
  495.  
  496.  
  497.  
  498.  
  499.  
  500.  
  501.         task check_sl811_access;
  502.  
  503.                 reg [7:0] tmp, rddata, wrdata;
  504.  
  505.                 reg [15:0] rdport;
  506.  
  507.  
  508.                 // turn off w5300 port access
  509.                 z.iord(w5300_port,tmp);
  510.                 if( tmp[4]!==1'b0 )
  511.                 begin
  512.                         tmp[4]=1'b0;
  513.                         z.iowr(w5300_port,tmp);
  514.                 end
  515.  
  516.  
  517.                 // check address reg
  518.                 wrdata=$random>>24;
  519.                 z.iowr(sl_addr,wrdata);
  520.                 if( s.get_rnw()!==1'b0 || s.get_addr()!==1'b0 || s.get_wr_data()!==wrdata )
  521.                 begin
  522.                         $display("sl811 address write failed!");
  523.                         $stop;
  524.                 end
  525.                 //
  526.                 rddata=$random>>24;
  527.                 s.set_rd_data(rddata);
  528.                 z.iord(sl_addr,tmp);
  529.                 @(negedge clk);
  530.                 if( s.get_rnw()!==1'b1 || s.get_addr()!==1'b0 || tmp!==rddata )
  531.                 begin
  532.                         $display("sl811 address read failed!");
  533.                         $stop;
  534.                 end
  535.  
  536.  
  537.  
  538.                 // check data reg
  539.                 rdport=sl_data;
  540.                 rdport[14:8]=$random>>25;
  541.                 wrdata=$random>>24;
  542.                 z.iowr(rdport,wrdata);
  543.                 if( s.get_rnw()!==1'b0 || s.get_addr()!==1'b1 || s.get_wr_data()!==wrdata )
  544.                 begin
  545.                         $display("sl811 data write failed!");
  546.                         $stop;
  547.                 end
  548.                 //
  549.                 rddata=$random>>24;
  550.                 s.set_rd_data(rddata);
  551.                 z.iord(rdport,tmp);
  552.                 @(negedge clk);
  553.                 if( s.get_rnw()!==1'b1 || s.get_addr()!==1'b1 || tmp!==rddata )
  554.                 begin
  555.                         $display("sl811 data read failed!");
  556.                         $stop;
  557.                 end
  558.  
  559.         endtask
  560.  
  561.  
  562.  
  563.  
  564.         task check_sl811_port;
  565.  
  566.                 reg [7:0] tmp;
  567.  
  568.                 reg ms;
  569.  
  570.                 ms=$random>>31;
  571.  
  572.                 z.iowr(sl811_port,ms);
  573.  
  574.                 @(posedge clk);
  575.                 if( (rst_n===1'b1 && s.get_ms()!==ms   ) ||
  576.                     (rst_n===1'b0 && s.get_ms()!==1'b1 ) )
  577.                 begin
  578.                         $display("sl811_ms_n behaves wrong!");
  579.                         $stop;
  580.                 end
  581.  
  582.                
  583.                 usb_power <= $random>>31;
  584.                 @(posedge clk);
  585.                 z.iord(sl811_port,tmp);
  586.                 if( tmp[1]!==usb_power )
  587.                 begin
  588.                         $display("can't sense usb_power!");
  589.                         $stop;
  590.                 end
  591.  
  592.         endtask
  593.  
  594.  
  595.  
  596.  
  597.  
  598.         task test_pwon_ints;
  599.  
  600.                 reg [7:0] tmp;
  601.  
  602.                 // check ints
  603.                 z.iord(rstint_port,tmp);
  604.                 if( tmp[1:0]!==2'b00 )
  605.                 begin
  606.                         $display("int requests after reset!");
  607.                         $stop;
  608.                 end
  609.                 if( tmp[3:2]!==2'b00 )
  610.                 begin
  611.                         $display("ints enabled after reset!");
  612.                         $stop;
  613.                 end
  614.                 if( tmp[7]!==1'b0 )
  615.                 begin
  616.                         $display("internal int is on after reset!");
  617.                         $stop;
  618.                 end
  619.                 if( tmp[6]!==1'b0 )
  620.                 begin
  621.                         $display("ext.int assertion enabled after reset!");
  622.                         $stop;
  623.                 end
  624.                 if( int_n!==1'b1 )
  625.                 begin
  626.                         $display("ext.int asserted after reset!");
  627.                         $stop;
  628.                 end
  629.         endtask
  630.        
  631.  
  632.  
  633.  
  634.  
  635.         task test_ints;
  636.  
  637.                 reg [7:0] tmp;
  638.  
  639.                 reg [1:0] ints,intena;
  640.  
  641.                 reg eintena;
  642.  
  643.                
  644.                 ints = $random>>30;
  645.  
  646.                 intena = $random>>30;
  647.  
  648.                 eintena = $random>>31;
  649.  
  650.                
  651.                 s.set_intrq(ints[1]);
  652.                 w.set_int_n(~ints[0]);
  653.  
  654.                 @(posedge clk);
  655.  
  656.  
  657.                 z.iord(rstint_port,tmp);
  658.                 tmp[3:2]=intena;
  659.                 tmp[6]=eintena;
  660.                 z.iowr(rstint_port,tmp);
  661.  
  662.                
  663.                 z.iord(rstint_port,tmp);
  664.  
  665.                 if( tmp[1]!==ints[1] || tmp[0]!==ints[0] )
  666.                 begin
  667.                         $display("wrong int signals states!");
  668.                         $stop;
  669.                 end
  670.  
  671.                 if( (  (ints&intena) && tmp[7]!==1'b1) ||
  672.                     ( !(ints&intena) && tmp[7]!==1'b0) )
  673.                 begin
  674.                         $display("wrong internal int state!");
  675.                         $stop;
  676.                 end
  677.  
  678.                 if( tmp[6]!==eintena )
  679.                 begin
  680.                         $display("wrong eintena state!");
  681.                         $stop;
  682.                 end
  683.  
  684.                 if( (eintena && (ints&intena)) ? (int_n!==1'b0) : (int_n!==1'b1) )
  685.                 begin
  686.                         $display("wrong int_n forming!");
  687.                         $stop;
  688.                 end
  689.  
  690.  
  691.  
  692.  
  693.         endtask
  694.  
  695.        
  696.        
  697.  
  698.  
  699.  
  700.         task test_resets;
  701.  
  702.                 reg [7:0] tmp;
  703.  
  704.                 reg [1:0] resets;
  705.  
  706.  
  707.                
  708.                 resets = $random>>30;
  709.  
  710.  
  711.                 // read-modify-write reset register
  712.                 z.iord(rstint_port,tmp);
  713.  
  714.                 tmp[5:4] = resets[1:0];
  715.  
  716.                 z.iowr(rstint_port,tmp);
  717.  
  718.                 if( s.get_rst_n() !== resets[1] )
  719.                 begin
  720.                         $display("no control of sl811 reset!");
  721.                         $stop;
  722.                 end
  723.  
  724.                 if( w.get_rst_n() !== resets[0] )
  725.                 begin
  726.                         $display("no control of w5300 reset!");
  727.                         $stop;
  728.                 end
  729.  
  730.         endtask
  731.        
  732.  
  733.  
  734.  
  735.         task test_pwon_resets;
  736.  
  737.                 reg [7:0] tmp;
  738.  
  739.                 // test resets state after reset
  740.                 if( w.get_rst_n() !== 1'b0 )
  741.                 begin
  742.                         $display("w5300 hasn't rst_n=0 after reset!");
  743.                         $stop;
  744.                 end
  745.                 //
  746.                 if( s.get_rst_n() !== 1'b0 )
  747.                 begin
  748.                         $display("sl811 hasn't rst_n=0 after reset!");
  749.                         $stop;
  750.                 end
  751.  
  752.                 // read reset register and check it
  753.                 z.iord(rstint_port,tmp);
  754.                 if( tmp[5:4]!==2'b00 )
  755.                 begin
  756.                         $display("reset bits in #83AB not 0 after reset!");
  757.                         $stop;
  758.                 end
  759.  
  760.         endtask
  761.  
  762.  
  763.  
  764.  
  765.  
  766.  
  767.  
  768.  
  769.  
  770.  
  771.  
  772.         // time marks
  773.         always
  774.         begin : timemarks
  775.  
  776.                 int ms;
  777.  
  778.                 ms = ($time/1000000);
  779.  
  780.                 #1000000.0;
  781.  
  782.                 $display("time mark: %d ms",ms);
  783.         end
  784.  
  785.  
  786.  
  787.  
  788.  
  789. endmodule
  790.  
  791.