Trung tâm đào tạo thiết kế vi mạch Semicon


  • ĐĂNG KÝ TÀI KHOẢN ĐỂ TRUY CẬP NHIỀU TÀI LIỆU HƠN!
  • Create an account
    *
    *
    *
    *
    *
    Fields marked with an asterisk (*) are required.
wafer.jpg

Assertions In Verilog Part - II

E-mail Print PDF

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.

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

Ram Model

  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

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.

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.

  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

 Bạn Có Đam Mê Với Vi Mạch hay Nhúng      -     Bạn Muốn Trau Dồi Thêm Kĩ Năng

Mong Muốn Có Thêm Cơ Hội Trong Công Việc

Và Trở Thành Một Người Có Giá Trị Hơn

Bạn Chưa Biết Phương Thức Nào Nhanh Chóng Để Đạt Được Chúng

Hãy Để Chúng Tôi Hỗ Trợ Cho Bạn. SEMICON  

Last Updated ( Tuesday, 29 March 2022 01:02 )  
Chat Zalo