Reputation: 31
I want to have a class where I want to put all of the rand variables with some default value which should be only randomized if they are assigned non-default value from their handle
Example
typedef enum {
NORTH = 0,
SOUTH = 1,
EAST = 2,
WEST = 3,
DEFAULT_DIR = 4
} direction_t;
class dir_class;
rand direction_t dir;
// I want something like
// rand direction_t dir = DEFAULT_DIR;
constraint dir_c
{
if(dir == DEFAULT_DIR)
{
dir inside {NORTH,SOUTH,WEST,EAST};
}
}
endclass: dir_class
Now what I want is when I take handle of this class I might want to assign some non default value (which could be done with inline constraint) but I don't want to use that because I might end up having 100s of such variable.
So what I need is that initially all of the variables should be having some default enum value like DEFAULT_RAND
and only be randomized if they hold this default value otherwise keep the value that is passed via handle
Upvotes: 1
Views: 483
Reputation: 42738
A better way to write this is using a const
cast, which gives you the state of a random variable before calling randomize()
.
typedef enum {
NORTH = 0,
SOUTH = 1,
EAST = 2,
WEST = 3,
DEFAULT_DIR = 4
} direction_t;
class dir_class;
rand direction_t dir = DEFAULT_DIR;
constraint dir_c
{
if(const'(dir) != DEFAULT_DIR)
dir == const'(dir);
else
dir != DEFAULT_DIR;
}
endclass: dir_class
module dir_module;
dir_class check;
initial begin
check = new();
$display("DIR:%0s",check.dir.name);
assert(check.randomize());
$display("DIR:%0s",check.dir.name);
check.dir = EAST;
$display("DIR:%0s",check.dir.name);
assert(check.randomize());
$display("DIR:%0s",check.dir.name);
end
endmodule: dir_module
Not all tools support this cast in a constraint yet, but you can easily get the same effect using pre_randomize()
and another state variable.
class dir_class;
rand direction_t dir = DEFAULT_DIR;
direction_t p_dir = DEFAULT_DIR;
constraint dir_c
{
if(p_dir != DEFAULT_DIR)
dir == p_dir;
else
dir != DEFAULT_DIR;
}
function void pre_randomize;
p_dir = dir;
endfunction
endclass: dir_class
Upvotes: 1
Reputation: 31
This seems to work
typedef enum {
NORTH = 0,
SOUTH = 1,
EAST = 2,
WEST = 3,
DEFAULT_DIR = 4
} direction_t;
class dir_class;
rand direction_t dir;
constraint dir_c
{
if(dir == DEFAULT_DIR)
{
dir inside {NORTH,SOUTH,WEST,EAST};
}
}
function new();
endfunction
endclass: dir_class
class checker_class;
rand dir_class direct;
function new();
direct = new();
endfunction
function void pre_randomzie();
if(direct.dir != DEFAULT_DIR) begin
direct.dir_c.constraint_mode(0);
end
endfunction
endclass
module dir_module;
checker_class check;
initial begin
check = new();
check.direct.dir = DEFAULT_DIR;
$display("DIR:%0s",check.direct.dir);
check.randomize();
$display("DIR:%0s",check.direct.dir);
check.direct.dir = EAST;
$display("DIR:%0s",check.direct.dir);
check.randomize();
$display("DIR:%0s",check.direct.dir);
end
endmodule: dir_module
OTUPUT
CPU time: .433 seconds to compile + .398 seconds to elab + .380 seconds to link
Chronologic VCS simulator copyright 1991-2023
Contains Synopsys proprietary information.
Compiler version U-2023.03-SP2_Full64; Runtime version U-2023.03-SP2_Full64; May 5 01:40 2024
DIR:DEFAULT_DIR
DIR:SOUTH
DIR:EAST
DIR:EAST
V C S S i m u l a t i o n R e p o r t
Time: 0 ns
CPU Time: 0.440 seconds; Data structure size: 0.0Mb
Upvotes: -1