I need help in writing a checker task to verify the following scenario:
Suppose we have a arbiter with two inputs(request) and outputs(grants). All are one bit wide. If a request goes high then it’s corresponding grant can come in 1-4 clock cycles. Also I have to match the grant with it’s corresponding request.
So my req in Cycle 1 should match with grant in Cycle 4. Req in cycle 3 should only match with grant in cycle 6 but not with grant in cycle 4.
My initial approach is to write a automatic task and call that task whenever a req is asserted. But I am stuck at coming with a code.
Any help on this,please?
Idea - you will need tags/IDs to mark requests and grants.
// Edited - removed use of $sampled for local variables
// But will be needed for subroutine calls in some cases
// Thanks Ben Cohen for pointing this out.
The $sampled is not needed here, but is needed in an action block.
Because local variables (the IDs) are needed to support the assertions, it is recommended that you put your assertions inside a SystemVerilog checker and either instantiate that checker directly into your DUT, or bind it to your DUT. Below is such an example. You could, of course declare a module instead of a checker.
Putting assertions outside the DUT is a good idea.
Without assertion , this can be achieved through the following snippet of code .
Logic is not fully tested
int unsigned req_cnt =0;
int unsigned gnt_cnt =0;
int unsigned req_clk_cnt =0 ;
int unsigned gnt_clk_cnt =0;
forever begin
@(posedge clk)
if(req) begin
req_cnt++;
req_clk_cnt=0;
end
else req_clk_cnt++;
if (gnt) begin
if(req_cnt !=0) req_cnt--;
if(req_cnt ==0) $error ("Gnt is asserted without Req");
if((req_clk_cnt < gnt_clk_cnt) && (gnt_clk_cnt >4)) gnt_clk_cnt -=req_clk_cnt;
end
else begin
if(req_cnt !=0) gnt_clk_cnt++;
end
if (gnt_clk_cnt >4) $error ("gnt is not asserted within [1:4] cycles");
end