如何为事务 class 编写约束条件,其中我只需要将 50% 的数据包随机化?
How to write constraint for a transaction class in which I need only 50% packets to be randomized?
我需要编写一个事务class,使每个数据包都有一个随机的 SA[7:0] 字段、DA[7:0] 字段和一个 DATA 字段。
数据的长度在 1 字节到 64 字节之间是随机的。 DATA 字段的内容可以是随机的(或)其他一些固定模式。50% 的数据包在所有数据字节中具有随机数据。 25% 的数据包在所有数据字节中都有 8'h55。 25% 的数据包在所有数据字节中都有 8'hAA
class my_transaction extends uvm_sequence_item;
'uvm_object_utils(my_transaction);
function new(string name="my_transaction")
super.new(name);
endfunction
rand bit[7:0] SA;
rand bit[7:0] DA;
rand bit[7:0] data[];
constraint my_c { data.size() inside [1:64] };
????how to write constraint for dynamic array data[] here ??
endclass
有两件事是你的朋友:
i) 控制旋钮。控制旋钮是为了控制随机化过程而被随机化的变量。因此,让我们随机化一个变量来决定 data
数组是随机的,55 还是 AA。
typedef enum {RANDOM, FIVE_FIVE, A_A} control_knob_t;
rand control_knob_t control_knob;
constraint dist_constraint { control_knob dist {RANDOM := 2, FIVE_FIVE := 1, A_A := 1}; }
ii) post_randomize
方法。这是 SystemVerilog,不是 UVM。 post_randomize
在 class 的随机化发生后调用,并允许您在随机化发生后执行操作。在这种情况下,我们将让标准随机化随机化 data
数组的长度,然后我们将在 post_randomize
方法中填充 data
的值。
function void post_randomize;
case (control_knob)
RANDOM: foreach (data[i])
data[i] = $urandom_range(0,255);
FIVE_FIVE: foreach (data[i])
data[i] = 8'h55;
A_A: foreach (data[i])
data[i] = 8'haa;
endcase
endfunction
[MCVE] :
module M;
class C;
rand bit[7:0] data[];
typedef enum {RANDOM, FIVE_FIVE, A_A} control_knob_t;
rand control_knob_t control_knob;
constraint my_c { data.size() inside {[1:4]}; }
constraint dist_constraint { control_knob dist {RANDOM := 2, FIVE_FIVE := 1, A_A := 1}; }
function void post_randomize;
case (control_knob)
RANDOM: foreach (data[i])
data[i] = $urandom_range(0,255);
FIVE_FIVE: foreach (data[i])
data[i] = 8'h55;
A_A: foreach (data[i])
data[i] = 8'haa;
endcase
endfunction
endclass
C c;
initial
begin
c = new;
repeat (100)
begin
c.randomize;
$display("c = %p", c);
end
end
endmodule
我正在研究与 Matthew 类似的方法,但如果很容易避免,我不希望使用 post_randomize 进行随机化
module top;
class A;
rand bit[7:0] data[];
typedef enum {RAND, h55, hAA} knob_t;
rand knob_t knobs[];
constraint size_c { data.size() inside {[1:64]}; data.size == knobs.size; }
constraint dist_c {
foreach(knobs[i]) knobs[i] dist {RAND := 50, h55 := 25, hAA := 25}; }
constraint data_element_c {
foreach (data[i]) {
knobs[i] == h55 -> data[i] == 8'h55;
knobs[i] == hAA -> data[i] == 8'hAA;
} }
endclass
A a = new;
initial
repeat (10)
begin
assert(a.randomize);
$display("%p", a);
end
endmodule
我需要编写一个事务class,使每个数据包都有一个随机的 SA[7:0] 字段、DA[7:0] 字段和一个 DATA 字段。 数据的长度在 1 字节到 64 字节之间是随机的。 DATA 字段的内容可以是随机的(或)其他一些固定模式。50% 的数据包在所有数据字节中具有随机数据。 25% 的数据包在所有数据字节中都有 8'h55。 25% 的数据包在所有数据字节中都有 8'hAA
class my_transaction extends uvm_sequence_item;
'uvm_object_utils(my_transaction);
function new(string name="my_transaction")
super.new(name);
endfunction
rand bit[7:0] SA;
rand bit[7:0] DA;
rand bit[7:0] data[];
constraint my_c { data.size() inside [1:64] };
????how to write constraint for dynamic array data[] here ??
endclass
有两件事是你的朋友:
i) 控制旋钮。控制旋钮是为了控制随机化过程而被随机化的变量。因此,让我们随机化一个变量来决定 data
数组是随机的,55 还是 AA。
typedef enum {RANDOM, FIVE_FIVE, A_A} control_knob_t;
rand control_knob_t control_knob;
constraint dist_constraint { control_knob dist {RANDOM := 2, FIVE_FIVE := 1, A_A := 1}; }
ii) post_randomize
方法。这是 SystemVerilog,不是 UVM。 post_randomize
在 class 的随机化发生后调用,并允许您在随机化发生后执行操作。在这种情况下,我们将让标准随机化随机化 data
数组的长度,然后我们将在 post_randomize
方法中填充 data
的值。
function void post_randomize;
case (control_knob)
RANDOM: foreach (data[i])
data[i] = $urandom_range(0,255);
FIVE_FIVE: foreach (data[i])
data[i] = 8'h55;
A_A: foreach (data[i])
data[i] = 8'haa;
endcase
endfunction
[MCVE] :
module M;
class C;
rand bit[7:0] data[];
typedef enum {RANDOM, FIVE_FIVE, A_A} control_knob_t;
rand control_knob_t control_knob;
constraint my_c { data.size() inside {[1:4]}; }
constraint dist_constraint { control_knob dist {RANDOM := 2, FIVE_FIVE := 1, A_A := 1}; }
function void post_randomize;
case (control_knob)
RANDOM: foreach (data[i])
data[i] = $urandom_range(0,255);
FIVE_FIVE: foreach (data[i])
data[i] = 8'h55;
A_A: foreach (data[i])
data[i] = 8'haa;
endcase
endfunction
endclass
C c;
initial
begin
c = new;
repeat (100)
begin
c.randomize;
$display("c = %p", c);
end
end
endmodule
我正在研究与 Matthew 类似的方法,但如果很容易避免,我不希望使用 post_randomize 进行随机化
module top;
class A;
rand bit[7:0] data[];
typedef enum {RAND, h55, hAA} knob_t;
rand knob_t knobs[];
constraint size_c { data.size() inside {[1:64]}; data.size == knobs.size; }
constraint dist_c {
foreach(knobs[i]) knobs[i] dist {RAND := 50, h55 := 25, hAA := 25}; }
constraint data_element_c {
foreach (data[i]) {
knobs[i] == h55 -> data[i] == 8'h55;
knobs[i] == hAA -> data[i] == 8'hAA;
} }
endclass
A a = new;
initial
repeat (10)
begin
assert(a.randomize);
$display("%p", a);
end
endmodule