Search code examples
verilogsystem-verilogiverilog

Verilog Oracle, Expected Value doesn't work properly


I am fixing some problem of source code below. I am creating oracle that compare expected value to actually value I get. the expected value that I try to calculate is variable 'e'. and the actual value that I get is variable 'z'.

so, variable 'ok' should be '1' when 'e===z'. But it doesn't set 'ok' to '1' even tho 'e===z' is true.

Here is source code.

module lab9;
reg [31:0] d;
reg clk, enable, flag;
wire [31:0] z;
reg [31:0] e,ok;
register #(32) mine(z, d, clk, enable);


always begin

#1 clk = ~clk; 
end

initial
$monitor("%5d: clk=%b,d=%d,z=%d,expect=%d, ok=%d", $time,clk,d,z, e, ok); 

initial begin
clk=0;

flag = $value$plusargs("enable=%b", enable);

repeat (20) begin

#2 d = $random;
e=d; 

if(e === z)
ok = 1;
else
ok = 0;

end

$finish; 

end
endmodule 

And here is sample output

0: clk=0,d=         x,z=         x,expect=         x, ok=         x
 1: clk=1,d=         x,z=         x,expect=         x, ok=         x
    2: clk=0,d= 303379748,z=         x,expect= 303379748, ok=         0
    3: clk=1,d= 303379748,z= 303379748,expect= 303379748, ok=         0
    4: clk=0,d=3230228097,z= 303379748,expect=3230228097, ok=         0
    5: clk=1,d=3230228097,z=3230228097,expect=3230228097, ok=         0
    6: clk=0,d=2223298057,z=3230228097,expect=2223298057, ok=         0
    7: clk=1,d=2223298057,z=2223298057,expect=2223298057, ok=         0
    8: clk=0,d=2985317987,z=2223298057,expect=2985317987, ok=         0
    9: clk=1,d=2985317987,z=2985317987,expect=2985317987, ok=         0
   10: clk=0,d= 112818957,z=2985317987,expect= 112818957, ok=         0
   11: clk=1,d= 112818957,z= 112818957,expect= 112818957, ok=         0
   12: clk=0,d=1189058957,z= 112818957,expect=1189058957, ok=         0
   13: clk=1,d=1189058957,z=1189058957,expect=1189058957, ok=         0
   14: clk=0,d=2999092325,z=1189058957,expect=2999092325, ok=         0
   15: clk=1,d=2999092325,z=2999092325,expect=2999092325, ok=         0
   16: clk=0,d=2302104082,z=2999092325,expect=2302104082, ok=         0
   17: clk=1,d=2302104082,z=2302104082,expect=2302104082, ok=         0
   18: clk=0,d=  15983361,z=2302104082,expect=  15983361, ok=         0
   19: clk=1,d=  15983361,z=  15983361,expect=  15983361, ok=         0
   20: clk=0,d= 114806029,z=  15983361,expect= 114806029, ok=         0

As you see, it shows that some of them do have same 'z' and 'expect' values. But 'ok' always set to '0'. Even tho I coded it to behave to set 1 when they are same.

This is what I don't know. Please help me, thank you.


Solution

  • It's difficult to be sure, because you cannot provide the code for register. However, I suspect you have a scheduling problem. Verilog has 4 scheduling regions:

    from prev time step
            |
          ACTIVE
            |
         INACTIVE
            |
           NBA
            |
        POSTPONED
            |
            V
     to next time step
    

    This line will be executed in the ACTIVE region:

    e=d; 
    

    z is probably being updated in the NBA region (I can't be sure without the code, but if register is some D-type flip-flops and has been coded properly, it should be).

    These lines will also be executed in the ACTIVE region:

    if(e === z)
      ok = 1;
      else
    ok = 0;
    

    so z will still have its previous value at that point. This line

    $monitor("%5d: clk=%b,d=%d,z=%d,expect=%d, ok=%d", $time,clk,d,z, e, ok); 
    

    will be executed in the POSTPONED region, so by this time z will have its new value.

    To solve this, try putting #1 before if(e === z). This will delay the comparison until the next time step, by which time z will have had time to change.

    This is a common situation with HDLs. You need to wait some short, but real, time before comparing outputs to allow the actual outputs to settle.