Reinitializing randc

Hi,

I was wondering if there is a way to reinitialize a randc variable. I am trying to set several registers, but need to make sure they can be set in arbitrary order. My code looks something like this:

typedef enum bit[N:0] { REG1, REG2, REG3, REG4, ... } reg_order_e;
local randc reg_order_e reg_order;

function void set_regs();
    repeat( reg_order.num() ) begin
        case( reg_order )
            REG1: set_reg1();
            REG2: set_reg2();
            REG3: set_reg3();
            REG4: set_reg4();
        endcase
        assert(randomize( reg_order ));
    end
endfunction : set_regs

Alternatively, can a randc be declared within a function?

Thanks,
-Tim

Yes, of course.

In reply to gaurson:

Can you elaborate? Randc cannot be declared in a function. Is there any version of std::randomize that will guarantee a variable is randomized in a cyclic way?

You are actually calling std::randomize() and the rand or randc modifier is ignored. You could put reg_order inside a separate class object and randomize it.

A simpler thing to do is to create an array of indexes and shuffle the array.

reg_order_e reg_order[$] = { REG1, REG2, REG3, REG4, ... } ;
or
for (int i=0;i<reg_order[0].num();i++)
   reg_order.push_back(reg_order[0].next(i));

Then you can do

reg_order.shuffle();
foreach(reg_order[i])
case(reg_order[i])

In reply to dave_59:

Thanks Dave. I’ll look into that. Why is calling randomize from within a function calling std::randomize? I assumed it was calling this.randomize() on reg_order, keeping any modifiers and constraints, but only changing the values specified in the argument. Will all calls to randomize within a function call std::randomize?

In reply to tkramer:

Yes, you are correct; it is calling this.randomize(). I missed the fact that your example must have been declared inside a class that was not shown.

Your original code should work if you put the call to randomize before the case statement. But I’m not sure I understand what you mean by “Re-initializing” in the title of your post.

In reply to dave_59:

I should have given more example code. Here is a simplified example of what’s going on:

class A; rand int foo; rand int bar; //etc local randc reg_order_e reg_order; task do_some_work(); //do some work involving foo, bar repeat( reg_order.num ) begin case( reg_order ) REG1: set_reg1(); REG2: set_reg2(); endcase end endtask : do_some_work endclass : A

class B;
rand A my_obj;
task foo();
my_obj = new();
assert( my_obj.randomize() );
my_obj.do_some_work();

    //do some other stuff here, maybe change my_obj's state
    assert( my_obj.randomize() );
    my_obj.do_some_work();
endtask : foo

endclass : B

There are other random members in class A. I need to create it, randomize the other members (and randomize this order member in the process), and have it do some work, which involves setting the registers. At some point later, it gets re-randomized and then does more work, setting the registers again. It should not be the responsibility of the class B to manage the randc, and in fact B does not even know about A’s reg_order enum, as it is declared as a local. Hopefully this gives a better picture of the problem, and maybe some potential solutions.

In reply to tkramer:

OK, that explains it much better. Basically, you do not want the my_obj.randomize() to affect the local variables in class A. Then do not declare those variables as rand or randc and use my earlier suggestion of creating a separate class object to randomize or array that you shuffle from within class A.

In reply to dave_59:

Ok, that’s what I will do. It does seem like a deficiency in the language that I cannot reset the internal state of a randc. Thanks for the assistance.

In reply to tkramer:

FYI, each random variable cannot have its own internal random state, otherwise you would not be able to have constraints involving more than one random variable and get proper distribution of results. You need to look at the solution space as sets of all random numbers in the object that meet the constraints and each call to randomize picks one of those sets.