quick.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

   

space.gif

   

space.gif

  ../images/main/bullet_green_ball.gif Verification Of FIFO

Our first example is the verification of a synchronous FIFO. Here we will build a simple testbench around the FIFO model and use simple assertions to show how they can be used to check simple protocols. If you have any better suggestion, please let me know.

   

space.gif

   

space.gif

  ../images/main/bulllet_4dots_orange.gif FIFO Model

Below is the original code found in examples directory.


   1 //-----------------------------------------------------
   2 // Design Name : syn_fifo
   3 // File Name   : syn_fifo.v
   4 // Function    : Synchronous (single clock) FIFO
   5 // Coder       : Deepak Kumar Tala
   6 //-----------------------------------------------------
   7 module syn_fifo (
   8 clk      , // Clock input
   9 rst      , // Active high reset
  10 wr_cs    , // Write chip select
  11 rd_cs    , // Read chipe select
  12 data_in  , // Data input
  13 rd_en    , // Read enable
  14 wr_en    , // Write Enable
  15 data_out , // Data Output
  16 empty    , // FIFO empty
  17 full       // FIFO full
  18 );    
  19  
  20 // FIFO constants
  21 parameter DATA_WIDTH = 8;
  22 parameter ADDR_WIDTH = 8;
  23 parameter RAM_DEPTH = (1 << ADDR_WIDTH);
  24 // Port Declarations
  25 input clk ;
  26 input rst ;
  27 input wr_cs ;
  28 input rd_cs ;
  29 input rd_en ;
  30 input wr_en ;
  31 input [DATA_WIDTH-1:0] data_in ;
  32 output full ;
  33 output empty ;
  34 output [DATA_WIDTH-1:0] data_out ;
  35 
  36 //-----------Internal variables-------------------
  37 reg [ADDR_WIDTH-1:0] wr_pointer;
  38 reg [ADDR_WIDTH-1:0] rd_pointer;
  39 reg [ADDR_WIDTH :0] status_cnt;
  40 reg [DATA_WIDTH-1:0] data_out ;
  41 wire [DATA_WIDTH-1:0] data_ram ;
  42 
  43 //-----------Variable assignments---------------
  44 assign full = (status_cnt == (RAM_DEPTH-1));
  45 assign empty = (status_cnt == 0);
  46 
  47 //-----------Code Start---------------------------
  48 always @ (posedge clk or posedge rst)
  49 begin : WRITE_POINTER
  50   if (rst) begin
  51     wr_pointer <= 0;
  52   end else if (wr_cs && wr_en ) begin
  53     wr_pointer <= wr_pointer + 1;
  54   end
  55 end
  56 
  57 always @ (posedge clk or posedge rst)
  58 begin : READ_POINTER
  59   if (rst) begin
  60     rd_pointer <= 0;
  61   end else if (rd_cs && rd_en ) begin
  62     rd_pointer <= rd_pointer + 1;
  63   end
  64 end
  65 
  66 always  @ (posedge clk or posedge rst)
  67 begin : READ_DATA
  68   if (rst) begin
  69     data_out <= 0;
  70   end else if (rd_cs && rd_en ) begin
  71     data_out <= data_ram;
  72   end
  73 end
  74 
  75 always @ (posedge clk or posedge rst)
  76 begin : STATUS_COUNTER
  77   if (rst) begin
  78     status_cnt <= 0;
  79   // Read but no write.
  80   end else if ((rd_cs && rd_en) &&  ! (wr_cs && wr_en) 
  81                 && (status_cnt  ! = 0)) begin
  82     status_cnt <= status_cnt - 1;
  83   // Write but no read.
  84   end else if ((wr_cs && wr_en) &&  ! (rd_cs && rd_en) 
  85                && (status_cnt  ! = RAM_DEPTH)) begin
  86     status_cnt <= status_cnt + 1;
  87   end
  88 end 
  89    
  90 ram_dp_ar_aw #(DATA_WIDTH,ADDR_WIDTH)DP_RAM (
  91 .address_0 (wr_pointer) , // address_0 input 
  92 .data_0    (data_in)    , // data_0 bi-directional
  93 .cs_0      (wr_cs)      , // chip select
  94 .we_0      (wr_en)      , // write enable
  95 .oe_0      (1'b0)       , // output enable
  96 .address_1 (rd_pointer) , // address_q input
  97 .data_1    (data_ram)   , // data_1 bi-directional
  98 .cs_1      (rd_cs)      , // chip select
  99 .we_1      (1'b0)       , // Read enable
 100 .oe_1      (rd_en)        // output enable
 101 );     
 102 
 103 endmodule
You could download file here
   

space.gif

  ../images/main/bulllet_4dots_orange.gif Ram Model
   

space.gif


  1 //-----------------------------------------------------
  2 // Design Name : ram_dp_ar_aw
  3 // File Name   : ram_dp_ar_aw.v
  4 // Function    : Asynchronous read write RAM
  5 // Coder       : Deepak Kumar Tala
  6 //-----------------------------------------------------
  7 module ram_dp_ar_aw (
  8 address_0 , // address_0 Input
  9 data_0    , // data_0 bi-directional
 10 cs_0      , // Chip Select
 11 we_0      , // Write Enable/Read Enable
 12 oe_0      , // Output Enable
 13 address_1 , // address_1 Input
 14 data_1    , // data_1 bi-directional
 15 cs_1      , // Chip Select
 16 we_1      , // Write Enable/Read Enable
 17 oe_1        // Output Enable
 18 ); 
 19 
 20 parameter DATA_WIDTH = 8 ;
 21 parameter ADDR_WIDTH = 8 ;
 22 parameter RAM_DEPTH = 1 << ADDR_WIDTH;
 23 
 24 //--------------Input Ports----------------------- 
 25 input [ADDR_WIDTH-1:0] address_0 ;
 26 input cs_0 ;
 27 input we_0 ;
 28 input oe_0 ; 
 29 input [ADDR_WIDTH-1:0] address_1 ;
 30 input cs_1 ;
 31 input we_1 ;
 32 input oe_1 ; 
 33 
 34 //--------------Inout Ports----------------------- 
 35 inout [DATA_WIDTH-1:0] data_0 ; 
 36 inout [DATA_WIDTH-1:0] data_1 ;
 37 
 38 //--------------Internal variables---------------- 
 39 reg [DATA_WIDTH-1:0] data_0_out ; 
 40 reg [DATA_WIDTH-1:0] data_1_out ;
 41 reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
 42 
 43 //--------------Code Starts Here------------------ 
 44 // Memory Write Block 
 45 // Write Operation : When we_0 = 1, cs_0 = 1
 46 always @ (address_0 or cs_0 or we_0 or data_0
 47 or address_1 or cs_1 or we_1 or data_1)
 48 begin : MEM_WRITE
 49   if ( cs_0 && we_0 ) begin
 50      mem[address_0] <= data_0;
 51   end else if  (cs_1 && we_1) begin
 52      mem[address_1] <= data_1;
 53   end
 54 end
 55 
 56 // Tri-State Buffer control 
 57 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
 58 assign data_0 = (cs_0 && oe_0 &&  ! we_0) ? data_0_out : 8'bz; 
 59 
 60 // Memory Read Block 
 61 // Read Operation : When we_0 = 0, oe_0 = 1, cs_0 = 1
 62 always @ (address_0 or cs_0 or we_1 or oe_0)
 63 begin : MEM_READ_0
 64   if (cs_0 &&  ! we_0 && oe_0) begin
 65     data_0_out <= mem[address_0]; 
 66   end else begin
 67     data_0_out <= 0; 
 68   end
 69 end 
 70 
 71 //Second Port of RAM
 72 // Tri-State Buffer control 
 73 // output : When we_0 = 0, oe_0 = 1, cs_0 = 1
 74 assign data_1 = (cs_1 && oe_1 &&  ! we_1) ? data_1_out : 8'bz; 
 75 // Memory Read Block 1 
 76 // Read Operation : When we_1 = 0, oe_1 = 1, cs_1 = 1
 77 always @ (address_1 or cs_1 or we_1 or oe_1)
 78 begin : MEM_READ_1
 79   if (cs_1 &&  ! we_1 && oe_1) begin
 80     data_1_out <= mem[address_1]; 
 81   end else begin
 82     data_1_out <= 0; 
 83   end
 84 end
 85 
 86 endmodule // End of Module ram_dp_ar_aw
You could download file here
   

space.gif

  ../images/main/bulllet_4dots_orange.gif Testbench Code

In the testbench code below, we are causing overflow and underflow conditions. What I mean to say is that FIFO depth is 8, so we can do 8 writes without reading from FIFO. If we do 9 writes then 9th data overwrites the content of FIFO.

   

space.gif

Similarly if we read from FIFO, when FIFO is empty it causes underflow. This kind of things happen when the code interface block is buggy. We can code assertion either in RTL or in the testbench. For assertions like our example, it is better that the RTL designer codes it along with his code.

   

space.gif


  1 module fifo_tb ();
  2 parameter DATA_WIDTH = 8;
  3 // Limit depth to 8
  4 parameter ADDR_WIDTH = 3; 
  5 
  6 reg clk, rst, rd_en, wr_en;
  7 reg [DATA_WIDTH-1:0] data_in ;
  8 wire [DATA_WIDTH-1:0] data_out ;
  9 wire empty, full;
 10 integer i;
 11 
 12 initial begin
 13   $monitor ("%g wr:%h wr_data:%h rd:%h rd_data:%h", 
 14     $time, wr_en, data_in,  rd_en, data_out);
 15   clk = 0;
 16   rst = 0;
 17   rd_en = 0;
 18   wr_en = 0;
 19   data_in = 0;
 20    #5  rst = 1;
 21    #5  rst = 0;
 22   @ (negedge clk);
 23   wr_en = 1;
 24   // We are causing over flow
 25   for (i = 0 ; i < 10; i = i + 1) begin
 26      data_in  = i;
 27      @ (negedge clk);
 28   end
 29   wr_en  = 0;
 30   @ (negedge clk);
 31   rd_en = 1;
 32   // We are causing under flow 
 33   for (i = 0 ; i < 10; i = i + 1) begin
 34      @ (negedge clk);
 35   end
 36   rd_en = 0;
 37    #100  $finish;
 38 end  
 39 
 40 always  #1  clk =  ! clk;
 41 
 42 syn_fifo #(DATA_WIDTH,ADDR_WIDTH) fifo(
 43 .clk      (clk)     , // Clock input
 44 .rst      (rst)     , // Active high reset
 45 .wr_cs    (1'b1)    , // Write chip select
 46 .rd_cs    (1'b1)    , // Read chipe select
 47 .data_in  (data_in) , // Data input
 48 .rd_en    (rd_en)   , // Read enable
 49 .wr_en    (wr_en)   , // Write Enable
 50 .data_out (data_out), // Data Output
 51 .empty    (empty)   , // FIFO empty
 52 .full     (full)      // FIFO full
 53 );   
 54 
 55 endmodule
You could download file fifo_tb.v here
   

space.gif

   

space.gif

   

space.gif

   

space.gif

space2.gif

space2.gif

space2.gif

space2.gif

space2.gif

  

Copyright 1998-2014

Deepak Kumar Tala - All rights reserved

Do you have any Comment? mail me at:deepak@asic-world.com