VERIFICATION ASYNCHRONOUS FIFO CUMMINGS

In reply to GiuseppeT:

In reply to ben@SystemVerilog.us:
My supervisor told me to not use Assertions so for the moment, don’t want to lie but I don’t even know what they are. He told me to just focus on those 5 situations that I need to verify and to do that, I was trying to realize 2 agents which, if I understood correctly, means to realize one sequencer (or generator), one driver and one monitor for each agent.

[Ben] You can specify the kind of situation to test thru the use of a variable of enum type
and then based on the value of the variable fire concurrent tasks using the fork-join construct. for example, (conceptual code


// Updated from the link of my VMM model 
package fifo_pkg;
  timeunit 1ns; timeprecision 100ps;
  `define TOP fifo_tb
  // My update for the situation
  //  read only, write only, read/write at the same time, 
  //  write when the FIFO is full, and read when the FIFO is empty.
  typedef enum {RD, WR, RD_WR, WR_FULL, RD_MT} situation_e;

  typedef enum {PUSH, POP, PUSH_POP, IDLE, RESET} fifo_scen_e;
  typedef enum {PUSH_MODE, POP_MODE} mode_e;
  typedef enum {PASSED, FAILED} fifo_status_e;
  typedef enum {DONE_GEN, DONE_BFM} notification_e;
  parameter BIT_DEPTH = 4;
  parameter FULL = 16;    
  parameter WIDTH = 32;
  typedef   logic [WIDTH-1 : 0] word_t;
  typedef   logic[31:0] wword_t;
  typedef   logic [WIDTH-1 : 0] wire_word_t;
  typedef   word_t [0 : (2**BIT_DEPTH-1)] buffer_t;

  parameter 		 ALM_EMPTY_REG = 2'b00;
  parameter 		 ALM_FULL_REG = 2'b01;

endpackage : fifo_pkg

The two agents then should share a common Scoreboard to check the results and apply the operations; that at least is the idea that I am currently following.

Again, I would use one agent because it is much simpler. For example,


// package alsready imported 
task Fifo_cmd_xactor::main();
    Fifo_xactn  fifo_xactn_0;  // transaction to get 
    Fifo_response  fifo_response; // response to generator
    // typedef enum {RD, WR, RD_WR, WR_FULL, RD_MT} situation_e;
    situation_e situation; 
      fifo_xactn_0 =new(); 
    // DIrected tests with some randomness depending upon the situation 
    // Do  5 reads
    situation=RD; 
    bit[0:2] delay; 
// READ 
    randomize(delay);
    repeat(5) @(posedge rd_clk) 
       fork rd_task(delay); 
       join // joins at end of task processing 
    randomize(delay);
// WRITE
    repeat(4) @(posedge wr_clk) 
       fork wr_task(delay); 
       join // joins at end of task processing 
... 
// If you want to mix those five situations: 
// RD, WR, RD_WR, WR_FULL, RD_MT
     if (!randomize(situation) with {
        situation dist {RD:=1, WR:=2, RD_WR:=1, WR_FULL:=0, RD_MT:=0};
      }) $error(" randomization failed"); 
 
      case (situation)
        RD: this.rd_task(dealy); 
        WR  : ...  
      endcase 
  endtask : main
// THose task calls above are calls to the driver and to the monitor.


Point is, I kinda feel insecure about the SystemVerilog code that I am writing since I have no one to check on it and literally I have finished a SV course without absorbing concepts yet.
About using the Queue, I thought about using this in the Reference Model, the one which gets the inputs from the Stimulus Monitor, to recreate the behaviour of the design somehow; I should basically recreate those 5 situations mentioned early in the Sequencer/Driver, like creating some tasks I guess? Sorry, I know what to do but maybe I cannot translate it in SV syntax

10 years ago I wrote a UVM model for a counter. I didn’t touch it since.
I am giving you this model in the hope that it might guide you in modeling what you need.
You can commentt out all those UVM includes and simplify the model.
http://systemverilog.us/vf/uvm_counter.zip

Best of luck,
Ben

1 Like