FIFO verification with "n" unique elements

In reply to ben@SystemVerilog.us:
This is an updated model
http://systemverilog.us/vf/unique_entry.sv


I corrected the push/pop, the maintenance of number of unique entries in the associative array, and the assertion itself.


// I have a synchronous FIFO. The depth of the FIFO is 32. 
// Everytime the FIFO has 7 or any "n" unique elements inside it, 
// "unique" signal goes HIGH. How do I test the "unique" signal going high 
// in SystemVerilog or UVM? How would my scoreboard look like?
import uvm_pkg::*; `include "uvm_macros.svh" 
module top; 
	bit clk, pop, push;  
	int data=8, q1_size, q_num, just_popped; 
	int aa[int]; // associative array
	int q1[$];  // queue, emulating the fifo
	int num_unique=0; 
	always @(posedge clk)  begin 
		automatic int temp_pop; 
		if(push) begin : push1  // if(push && !pop) begin : push_no_pop  
			if(!aa.exists(data)) begin : is_unique
				aa[data]=1;  // flag data into associative array 
				num_unique <=  num_unique+1'b1; // incremnet number of uniques 
				q1.push_front(data); // maintain the queue
			end  : is_unique
		    else  begin : is_not_unique // but is in the queue
			   aa[data]+=1'b1;  // keep track of count 
			   // num_unique <=  num_unique+1'b1; // incremnet number of uniques 
			   q1.push_front(data); // maintain the queue			
		    end  : is_not_unique 
		end : push1
		if(pop && q1.size != 0) begin : pop_q  // if(pop && !push && q1.size != 0) 
			temp_pop=q1.pop_back(); // maintain the queue
			aa[temp_pop]-=1'b1;  // keep track of count
			just_popped <= temp_pop;
			if(aa[temp_pop]==0) begin : flushed 
			  num_unique <= num_unique - 1'b1; // decrement uniques 
			  aa.delete(temp_pop); // delete the associative array entry 		   
			end  : flushed 
		end : pop_q
		a_unique: assert(num_unique <= 7); 
	end 
	
	always_comb begin 
		q1_size=q1.size; // for debug 
		q_num=aa.num;
	end
	
	initial forever #10 clk=!clk;  
 
	initial begin 
		repeat(5) push <= 1'b1; 
		repeat(200) begin 
			@(posedge clk);   #2; 
			if (!randomize(push, pop, data)  with 
					{ push dist {1'b1:=1, 1'b0:=2};
					  pop  dist {1'b1:=1, 1'b0:=8};
					  data dist {[1:12]:=1, [0:0]:=3};
					}) `uvm_error("MYERR", "This is a randomize error")
		end 
		$stop; 
	end 
endmodule   

Ben Cohen
http://www.systemverilog.us/ ben@systemverilog.us
For training, consulting, services: contact http://cvcblr.com/home