Subversion Repositories zxusbnet

Rev

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