Shay Moskovitz
Shay Moskovitz

Reputation: 1

randcase called twice and return same value

In my Systemverilog TB I make 2 instance of module called "dcg_top":

    logic[0:1] cfi_clkreq;
    initial begin
        cfi_clkreq = '0;
            #1us;
            cfi_clkreq = 2'b11;
            #1us;
            cfi_clkreq = 2'b00;
        end

    dcg_top #(
       )cfi0(
        .clk_req('{cfi_clkreq[0]})
        );

    dcg_top #(
    )cfi1(
        .clk_req('{cfi_clkreq[1]})
        );

Each instance gets one bit of cfi_clkreq array as input. when clk_rek changed from 0 to 1 this task is called:

task clock_vc_dcg::wait_before_clk_ack();
        randcase
            20: async_delay_ps(20, 1);
            35: async_delay_ps(2500, 20);
            15: async_delay_ps(10000, 2500); 
            15: async_delay_ps(30000, 10000);
            10: async_delay_ps(30000, 10000);
            8 : async_delay_ps(100000, 30000);
            2 : async_delay_ps(200000, 100000);
        endcase
endtask : wait_before_clk_ack

As you can see in my TB I change clk_req from 00 to 11 so this task should be called twice, in the two instance. My problem is that in the both task call, the randcase returns the same value, even it called from separate instance. How can I fix it? I want randcase to return different value in each call. thanks!

Upvotes: 0

Views: 136

Answers (1)

dave_59
dave_59

Reputation: 42698

This is a problem with the definition of random stability in SystemVerilog. It expects you to write a testbench starting from a single module/program and spawn all the activity from there. All instances start with same seeded initialized random state (RNG), which is then propagated to to constructs like randcase, $urandom and randomize.

One way of working around this is some tools have switches that adds the module instance pathname to each module instance initial RNG.

You can also do this manually with

module sub;
  int myseed;
 
  string pathname = $sformatf("%m");
  process p;
  initial begin
    myseed = $urandom;
    $display("initial seed %m %h",myseed);
    foreach (pathname[i])
      myseed += pathname[i];
    $display("path seed %m %h",myseed);
    p = process::self();
    p.srandom(myseed);
    $display("next random number %h",$urandom);
  end
endmodule
 
module top;
   sub i1(), i2(),i3();
endmodule

You will notice that the initial random number is the same for all instances, but after re-seeding, the next random number is different in each instance. This would also apply to randcase

Upvotes: 2

Related Questions