Subversion Repositories zxusbnet

Rev

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

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