tb_fifo.v
上传用户:jin985143
上传日期:2020-09-30
资源大小:278k
文件大小:7k
源码类别:

Modem编程

开发平台:

VHDL

  1. /* *****************************************************************
  2.  *
  3.  *  This file is part of the
  4.  *
  5.  *   Tone Order and Constellation Encoder Core.
  6.  *  
  7.  *  Copyright (C) 2007 Guenter Dannoritzer
  8.  *
  9.  *   This source is free software; you can redistribute it
  10.  *   and/or modify it under the terms of the 
  11.  *             GNU General Public License
  12.  *   as published by the Free Software Foundation; 
  13.  *   either version 3 of the License,
  14.  *   or (at your option) any later version.
  15.  *
  16.  *   This source is distributed in the hope 
  17.  *   that it will be useful, but WITHOUT ANY WARRANTY;
  18.  *   without even the implied warranty of MERCHANTABILITY
  19.  *   or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.  *   GNU General Public License for more details.
  21.  *
  22.  *   You should have received a copy of the
  23.  *   GNU General Public License along with this source.
  24.  *   If not, see <http://www.gnu.org/licenses/>.
  25.  *
  26.  * *****************************************************************/
  27. module tb_fifo;
  28. parameter AWIDTH = 2;
  29. parameter DWIDTH = 8;
  30. parameter TW=10;
  31. //
  32. // to interface the dut
  33. // 
  34. reg                 clk;
  35. reg                 reset;
  36. reg   [DWIDTH-1:0]  data_i;
  37. reg                 re_i;
  38. wire                empty_o;
  39. wire                full_o;
  40. wire                one_available_o;
  41. wire                two_available_o;
  42. reg                 we_i;
  43. reg   [DWIDTH-1:0]  data_i;
  44. reg                 re_i;
  45. wire  [DWIDTH-1:0]  data_o;
  46. //
  47. // instantiate the DUT
  48. //
  49. fifo #(.AWIDTH(AWIDTH), .DWIDTH(DWIDTH))
  50.       dut ( .clk(clk),
  51.             .reset(reset),
  52.             .empty_o(empty_o),
  53.             .full_o(full_o),
  54.             .one_available_o(one_available_o),
  55.             .two_available_o(two_available_o),
  56.             .we_i(we_i),
  57.             .data_i(data_i),
  58.             .re_i(re_i),
  59.             .data_o(data_o));
  60.           
  61. //
  62. // local reg/wires
  63. //
  64. reg [DWIDTH-1:0] got_data;
  65. //
  66. // main tests
  67. // 
  68.           
  69. initial begin
  70.   clk = 0;
  71.   we_i = 0;
  72.   re_i = 0;
  73.   reset = 0;
  74. end
  75. always begin
  76.   #TW clk = ~clk;
  77. end
  78. //
  79. // dump signals
  80. //
  81. initial begin
  82.   $dumpfile("tb_fifo.vcd");
  83.   $dumpvars;
  84. end
  85. initial begin
  86.   $display("=== Verifing FIFO ===");
  87.   $display("- reset test");
  88.   test_reset;
  89.   check_control(5'b0001);
  90.   $display("- verify write followed by read");
  91.   write_data(8'haa);
  92.   check_control(5'b0100);
  93.   read_data(got_data);
  94.   check_result(got_data, 8'haa);
  95.   check_control(5'b0001);
  96.   
  97.   // fifo is empty again
  98.   
  99.   // fill it and only expect after the 4th write a full signal
  100.  
  101.   $display("- fill FIFO up");
  102.   // #1
  103.   write_data(8'h70);
  104.   check_control(5'b0100);
  105.   // #2
  106.   write_data(8'h71);
  107.   check_control(5'b1100);
  108.   // #3
  109.   write_data(8'h72);
  110.   check_control(5'b1100);
  111.   // #4
  112.   write_data(8'h73);
  113.   check_control(5'b1110);
  114.   
  115.   $display("- FIFO is full, another write should not have an affect");
  116.   write_data(8'hab);
  117.   check_control(5'b1110);
  118.   $display("- verify reading the data from the full FIFO back");
  119.   // #1  
  120.   read_data(got_data);
  121.   check_result(got_data, 8'h70);
  122.   check_control(5'b1100);
  123.   // #2  
  124.   read_data(got_data);
  125.   check_result(got_data, 8'h71);
  126.   check_control(5'b1100);
  127.   // #3  
  128.   read_data(got_data);
  129.   check_result(got_data, 8'h72);
  130.   check_control(5'b0100);
  131.   // #4  
  132.   read_data(got_data);
  133.   check_result(got_data, 8'h73);
  134.   check_control(5'b0001);
  135.   
  136.   $display("= Now test a read/write at the same clock =");
  137.   
  138.   $display("- First have an empty FIFO and do the read/write");
  139.   // read should fail but write should succeed
  140.   fork
  141.     read_data(got_data);
  142.     write_data(8'h80);
  143.   join
  144.   check_control(5'b0100);
  145.   read_data(got_data);
  146.   check_result(got_data, 8'h80);
  147.   //
  148.   $display("- Now have one entry in the FIFO and do a read/write");
  149.   // read should bring the first value back and the written value
  150.   // should stay
  151.   write_data(8'h90);
  152.   fork
  153.     read_data(got_data);
  154.     write_data(8'hA0);
  155.   join
  156.   check_control(5'b0100);
  157.   check_result(got_data, 8'h90);
  158.   read_data(got_data);
  159.   check_result(got_data, 8'hA0);
  160.   check_control(5'b0001);
  161.   
  162.   
  163.   
  164.   $display("- Finally fill up the FIFO and to the read/write");
  165.   // #1
  166.   write_data(8'h10);
  167.   check_control(5'b0100);
  168.   // #2
  169.   write_data(8'h11);
  170.   check_control(5'b1100);
  171.   // #3
  172.   write_data(8'h12);
  173.   check_control(5'b1100);
  174.   // #4
  175.   write_data(8'h13);
  176.   check_control(5'b1110);
  177.   // doing the read/write, as the FIFO is full the written value should
  178.   // not end up in the FIFO
  179.   fork
  180.     read_data(got_data);
  181.     write_data(8'h20);
  182.   join
  183.   
  184.   check_control(5'b1100);
  185.   check_result(got_data, 8'h10);
  186.   // doing a read/write with one empty spot, the read should return the
  187.   // last but one value and the write should end up in the FIFO
  188.   fork
  189.     read_data(got_data);
  190.     write_data(8'h21);
  191.   join
  192.   check_control(5'b1100);
  193.   check_result(got_data, 8'h11);
  194.   // so reading back the values, should return the 3 remaining values
  195.   // #1  
  196.   read_data(got_data);
  197.   check_result(got_data, 8'h12);
  198.   check_control(5'b1100);
  199.   // #2  
  200.   read_data(got_data);
  201.   check_result(got_data, 8'h13);
  202.   check_control(5'b0100);
  203.   // #3  
  204.   read_data(got_data);
  205.   check_result(got_data, 8'h21);
  206.   check_control(5'b0001);
  207.   $display("FIFO verification done!");
  208.   $finish();
  209. end
  210. // //////////////////////////////////////////////////////////////////// 
  211. // 
  212. // bus functional models
  213. // 
  214. // //////////////////////////////////////////////////////////////////// 
  215. task test_reset;
  216.   begin
  217.   //$display("Testing reset");
  218.   reset = 0;
  219.   #10 reset = 1;
  220.   #20 reset = 0;
  221.   
  222. end
  223. endtask
  224. // =====================================================================
  225. // check the expected control line status
  226. //
  227. // exp_ctrl[4:0] == {two_available, one_available, full, empty}
  228. //
  229. task check_control(input [4:0]exp_ctrl);
  230.   begin
  231.   
  232.     //$display("# %d expCtrl: %d", $time, exp_ctrl);
  233.   
  234.   if(empty_o !== exp_ctrl[0])
  235.     $display("ERROR! => Expected empty_o == %d, got %d", exp_ctrl[0], empty_o);
  236.   
  237.   if(full_o !== exp_ctrl[1])
  238.     $display("ERROR! => Expected full_o == %d, got %d", exp_ctrl[1], full_o);
  239.   if(one_available_o !== exp_ctrl[2])
  240.     $display("ERROR! => Expected one_available_o == %d, got %d", exp_ctrl[3], one_available_o);
  241.   
  242.   if(two_available_o !== exp_ctrl[3])
  243.     $display("ERROR! => Expected two_available_o == %d, got %d", exp_ctrl[4], two_available_o);
  244.   end
  245. endtask
  246. // =====================================================================
  247. //
  248. // write data to the fifo
  249. // 
  250. task write_data(input [DWIDTH-1:0]data);
  251.   begin
  252.     //$display("# %d Writing data", $time);
  253.     @(negedge clk);
  254.     data_i = data;
  255.     we_i = 1;
  256.     @(negedge clk);
  257.     we_i = 0;
  258.   end
  259. endtask
  260. // =====================================================================
  261. //
  262. // read data from the fifo
  263. // 
  264. // 
  265. task read_data(output [DWIDTH-1:0]data);
  266.   begin
  267.     //$display("# %d Reading data", $time);
  268.     @(negedge clk);
  269.     re_i = 1;
  270.     @(negedge clk);
  271.     data = data_o;
  272.     re_i = 0;
  273.   end
  274. endtask
  275. // =====================================================================
  276. //
  277. // check result
  278. // 
  279. // 
  280. task check_result(input [DWIDTH-1:0]got, input [DWIDTH-1:0]expected);
  281.   begin
  282.     if(got !== expected)
  283.       $display("ERROR! => Result does not match! Got: %d (%x) expected: %d (%x)", got, got, expected, expected);
  284.   end
  285. endtask
  286. endmodule