约束块是类成员,就像变量,函数和任务一样。 它们在一个类中具有唯一的名称。 这些表达式块通常用于将随机变量的值限制在约束块内指定的某些值之内。
Syntax
constraint [name_of_constraint] { [expression 1];
[expression N]; }
花括号中列出的表达式指定了求解程序在为变量分配随机值时必须考虑的条件。不一定要对每个变量都有一个约束,也不一定要限制一个约束块只具有一个变量的条件。但是,您不能让冲突的约束分散在多个块中,除非使用constraint mode()方法关闭它们,我们将在Disable constraints中看到这个方法。空约束对随机化没有影响。
constraint valid_addr { addr [1:0] == 2'b0;
addr <= 32'hfaceface;
addr >= 32'hf0000000; }
constraint fast_burst { burst >= 3;
len >= 64;
size >= 128; }
// Error - valid_addr already declared
constraint valid_addr { ... }
// Runtime error - solver fails due to conflict on addr
constraint valid { addr >= 32'hfaceffff; }
// Valid because solver can find an address that satisfies all conditions
// eg :- f200_0000 is below f400_0000 and face_face; and above f000_0000
constraint valid2 { addr <= 32'hf4000000; }
// An empty constraint - does not affect randomization
constraint c_empty;
由于这些块的声明性,它们受到一些限制。注意,约束块被封装在大括号{}中,而不是过程性语句的begin结束关键字中。约束可以放在类体定义的内部,也可以放在类体定义的外部。当约束在类的主体外部定义时,它们被称为外部约束,并通过使用范围解析操作符::来访问它们。
In-class Constraint Example
// Let's declare a new class called "ABC" with a single variable that
// can be randomized. We want this variable to have values between 2 and 6.
// when randomized. This is achieved by a constraint called "c_mode" (you
// can name it anything else).
class ABC;
rand bit [3:0] mode;
// This constraint block ensures that the randomized
// value of "mode" meets the condition 2 < mode <= 6;
constraint c_mode { mode > 2;
mode <= 6;
};
endclass
module tb;
ABC abc;
initial begin
// Create a new object with this handle
abc = new();
// In a for loop, lets randomize this class handle
// 5 times and see how the value of mode changes
// A class can be randomized by calling its "randomize()"
for (int i = 0; i < 5; i++) begin
abc.randomize();
$display ("mode = 0x%0h", abc.mode);
end
end
endmodule
Simulation Log
ncsim> run
mode = 0x6
mode = 0x6
mode = 0x5
mode = 0x4
mode = 0x5
ncsim: *W,RNQUIE: Simulation is complete.
External Constraint Example
外部约束可以隐式或显式形式提及。 如果使用显式约束,并且在类主体外部未提供相应的约束块,则会出错。 但是隐式约束不会有任何错误,但是模拟器可能会发出警告。
// Let's declare a new class called "ABC" with a single variable that
// can be randomized. We want this variable to have values between 2 and 6.
// when randomized. This is achieved by a constraint called "c_mode" (you
// can name it anything else).
class ABC;
rand bit [3:0] mode;
constraint c_implicit; // An empty constraint without "extern" is implicit
extern constraint c_explicit; // An empty constraint with "extern" is explicit
endclass
// This is an external constraint because it is outside
// the class-endclass body of the class. The constraint
// is reference using ::
constraint ABC::c_implicit { mode > 2; };
constraint ABC::c_explicit { mode <= 6; };
module tb;
ABC abc;
initial begin
// Create a new object with this handle
abc = new();
// In a for loop, lets randomize this class handle
// 5 times and see how the value of mode changes
// A class can be randomized by calling its "randomize()"
for (int i = 0; i < 5; i++) begin
abc.randomize();
$display ("mode = 0x%0h", abc.mode);
end
end
endmodule
Simulation Log
mode = 0x3
mode = 0x5
mode = 0x6
mode = 0x4
mode = 0x6
不允许以下内容:
【1】为给定的约束原型提供多个约束块;
【2】编写另一个约束块,其名称与外部原型声明中使用的约束块相同;
参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-constraint-blocks