Corner cases detection

Like my dut to should show error when push and pop occurs simultaneously
Like if (push &&pop) $display (“error”).
Then how I predict and compare this feature in Scoreboard?
Do I need to declare any variable in Dut which becomes high when
Push and pop occurs simultaneously? If yes , then how I will use that variable
In Scoreboard for comparison?
Please help me

In reply to SidRaj:

Like my dut to should show error when push and pop occurs simultaneously
Like if (push &&pop) $display (“error”).
Then how I predict and compare this feature in Scoreboard?

The push, pop control signals are external signals to the FIFO.
If the FIFO is embedded in the DUT as an instance, I suggest that you write assertions in a module of a SystemVerilog checker and bind that verification unit to the design. If it’s a checker, you can instantiate the checker into the FIFO.

You talk about “scoreboard”, which is a unit written at a higher level to mimic a DUT’s behavior. The scoreboard is then used to verify the DUT, like pushing data into the fifo and later retrieving that data. That, BTW can also be done with assertions and support logic without the scoreboard.

On (push &&pop) $display (“error”) A FIFO can do a simultaneous push and pop. hat is illegal is to have a push and full and no pop, or a pop on empty.

In my SVA Handbook 4th Edition, I used thte FIFO as a model to show how requirements and verification is used in a DUT. I am including some of the assertions and coverage.


// In the DUT, but could hav also put them into a binded module. 
// Push on full with no pop error 
  property p_push_error; 
    @ (posedge clk) 
       not (b_if.push && b_if.full && !b_if.pop); 
  endproperty : p_push_error
  ap_push_error_1 : assert property (p_push_error);
  // mp_push_error : assume property (p_push_error);
  
  // No pop on empty 
  property p_pop_error; 
   @ (posedge clk) 
       not (b_if.pop && b_if.empty); 
  endproperty : p_pop_error
  ap_pop_error_1 : assert property (p_pop_error);
 // mp_pop_error : assume property (p_pop_error);
// ------------------------------------------------------------
interface fifo_if(input wire clk, reset_n);
  timeunit 1ns;
  timeprecision 100ps;
  import fifo_pkg::*;

  logic push; // push data into the fifo
  logic pop;  // pop data from the fifo
  logic almost_full;  // fifo is at 3/4 maximum level
  logic almost_empty;  // fifo is at 1/4 maximum level
  logic full;  // fifo is at maximum level
  logic empty; // fifo is at the zero level (no data)
  logic error; // fifo push or pop error   
  word_t data_in;
  word_t data_out;

  // local variables for verification purpose
  logic [BIT_DEPTH-1 : 0] wr_ptr = 0;
  logic [BIT_DEPTH-1 : 0] rd_ptr = 0;

  logic fifo_is_full;
  logic fifo_is_empty;
  logic fifo_is_almost_full;
  logic fifo_is_almost_empty;
  
  // FIFO DUV 
  modport fslave_if (output empty,
                     output almost_empty,
                     output almost_full,
                     output full,
                     output data_out,
                     output error,
                     input data_in,
                     input push,
                     input pop);

  // FIFO driver 
   modport fdrvr_if (input empty,
                     input almost_empty,
                     input almost_full,
                     input full,
                     input data_out,
                     input error,
                     output data_in,
                     output push,
                     output pop);
     
  // never a push and full and no pop
  property p_push_error; 
    @ (posedge clk) 
       not (push && full && !pop); 
  endproperty : p_push_error
  ap_push_error : assert property (p_push_error);

   // never a pop on empty 
  property p_pop_error; 
   @ (posedge clk) 
       not (pop && empty); 
  endproperty : p_pop_error
  ap_pop_error : assert property (p_pop_error);

  `ifdef SV_3.1a
    property p_error_flag; 
   @ (posedge clk) 
   p_push_error or p_pop_error |=> error;
   endproperty : p_error_flag
   ap_error_flag : assert property (p_error_flag);     
  `endif
  
 
    // sequence definition, use in cover.  FIFO_B.FULL 
  sequence qFull; 
    fifo_is_full;
  endsequence : qFull

  // sequence definition, use in cover.  empty  
  sequence qEmpty; 
      fifo_is_empty;
  endsequence : qEmpty

  // sequence definition, use in cover.  almost_empty   
  sequence qAlmost_empty; 
     fifo_is_almost_empty;
   endsequence : qAlmost_empty

  // sequence definition, use in cover.  almost_full
  sequence qAlmost_full; 
     fifo_is_almost_full;
   endsequence : qAlmost_full

  // Definition of a fifo_b.full fifo, based on environment addresses.
  property p_fifo_full; 
     @ (posedge clk)   qFull |=> full; 
  endproperty : p_fifo_full
  ap_fifo_full : assert property (p_fifo_full);
  
  // Definition of an almost_fifo_b.full fifo, based on environment addresses
  property p_fifo_almost_full; 
     @ (posedge clk)   qAlmost_full |=> almost_full; 
  endproperty : p_fifo_almost_full
  ap_fifo_almost_full : assert property (p_fifo_almost_full);

  // If empty fifo, check empty flag   
  property p_fifo_empty; 
    @ (posedge clk) 
             qEmpty |=> empty; 
  endproperty : p_fifo_empty
  ap_fifo_empty : assert property (p_fifo_empty);
  
  // Flags at reset 
  property p_fifo_ptrs_flags_at_reset; 
    @ (posedge clk) 
       !reset_n |-> almost_empty && ! full && !almost_full && empty; 
  endproperty  : p_fifo_ptrs_flags_at_reset
  ap_fifo_ptrs_flags_at_reset : assert property (p_fifo_ptrs_flags_at_reset);
  
  // Flag at almost_empty state
  property p_fifo_almost_empty; 
    @ (posedge clk)  qAlmost_empty |-> almost_empty;  // BUG: should use |=> !!!! 
  endproperty : p_fifo_almost_empty
  ap_fifo_almost_empty : assert property (p_fifo_almost_empty);

 
  // ------------------------------

  always @ (posedge clk)
  begin : status_flag
    fifo_is_empty = (wr_ptr == rd_ptr);
    fifo_is_full = (wr_ptr - rd_ptr) == FULL;
    fifo_is_almost_full = (wr_ptr - rd_ptr) >= ALMOST_FULL;
    fifo_is_almost_empty = (wr_ptr - rd_ptr) <= ALMOST_EMPTY;
  end : status_flag
  default clocking  @ ( posedge clk );endclocking  
   task push_task (word_t data);
     begin
       $display ("%0t %m Push data %0h ", $time, data);
	   data_in <= data;
	   push <= 1'b1;
	   pop  <= 1'b0;
       	   wr_ptr++;
	   ##1;
      end
    endtask : push_task 

    task pop_task;
      begin
        data_in <= 'X; // unsized Xs 
        push <= 1'b0;
        pop  <= 1'b1;
        rd_ptr++;
        ##1;
       end
    endtask : pop_task
      
    task idle_task (int num_idle_cycles);
      begin
        assert (num_idle_cycles < 10000) else 
          $warning ("%0t %0m idle_task is invoked with LARGE number of idle cycles %0d ",
                    $time, num_idle_cycles); 
        data_in <= 'X; // unsized Xs 
        push <= 1'b0;
        pop  <= 1'b0;
        repeat (num_idle_cycles) ##1;
      end
    endtask : idle_task 
endinterface : fifo_if

module fifo_props (input clk, input reset_n, fifo_if fifo_if);
  timeunit 1ns;
  timeprecision 100ps;

// Activating reset during interesting corner cases
// is covered via cover directives.

  property p_t1_full;  @ (posedge clk) 
    fifo_if.full ##1 reset_n==0;
  endproperty : p_t1_full
  cp_t1_full_1: cover property (p_t1_full);
  

  property p_t2_afull;  @ (posedge clk) 
    fifo_if.almost_full ##1 reset_n==0;
  endproperty : p_t2_afull
  cp_t2_afull_1: cover property (p_t2_afull);
  
  property p_t3_empty;  @ (posedge clk) 
     fifo_if.empty ##1 reset_n==0;
  endproperty : p_t3_empty
  cp_t3_empty_1: cover property (p_t3_empty);
  
  property p_t4_aempty;  @ (posedge clk) 
    fifo_if.almost_empty ##1  reset_n==0;
  endproperty : p_t4_aempty
  cp_t4_aempty_1 : cover property (p_t4_aempty);
  

  property p_push_pop_sequencing;
      @ (posedge clk) fifo_if.push |=> ##[0:$] fifo_if.pop;
  endproperty : p_push_pop_sequencing
     
  // coverage of sequences 
  cp_push_pop_sequencing  : cover property  (p_push_pop_sequencing);
 
  c_qFull :               cover property  ( @ (posedge clk) fifo_if.qFull);
  c_qEmpty  :              cover property  (@ (posedge clk)  fifo_if.qEmpty);
  
  c_qAlmost_empty :       cover property  (@ (posedge clk)  fifo_if.qAlmost_empty);
  c_qAlmost_full :        cover property  (@ (posedge clk)  fifo_if.qAlmost_full);
  
endmodule : fifo_props   
  
// *** In the testbench 
 fifo_if b_if(.*);		// instantiation of fifo interface
   

   fifo fifo_rtl_1(.*); // instantiation of fifo DUV

   // bind the fifo_rtl model to an implicit instantiation (fifo_props_1)
   // of property module fifo_props
   bind fifo fifo_props fifo_props_1(clk, reset_n, b_if); 

// ********************
package fifo_pkg;
  timeunit 1ns; timeprecision 100ps;
  `define TOP fifo_tb
  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
 

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact Home - My cvcblr


  1. SVA Alternative for Complex Assertions
    https://verificationacademy.com/news/verification-horizons-march-2018-issue
  2. SVA: Package for dynamic and range delays and repeats - SystemVerilog - Verification Academy
  3. SVA in a UVM Class-based Environment
    https://verificationacademy.com/verification-horizons/february-2013-volume-9-issue-1/SVA-in-a-UVM-Class-based-Environment