- Question:我认为随机化单个变量给验证工程师提供了更大的灵活性。 也许systemverilog的设计者没有足够的预见到这一点。 也许他们可以看看其他语言,并借鉴一些良好的语言功能。LRM中的12.10节(在线随机变量控制)似乎表明我们可以将参数传递给randomize()来指定要随机化的特定变量。 你能否对此发表评论?
- Answer: 我同意随机化单个变量给验证工程师提供了更大的灵活性,但这本身并不意味着是一件好事。从个别语言特征中退出来,站在更高的视角并更好地了解您正在尝试做什么将是一个更好的出发点。
无论如何,让我解释一下in-line随机变量控制。当你调用一个类的randomize方法(不是std :: randomize)时,你可以提供一个类属性的列表,这些属性将被视为该调用的随机变量(即使该类属性没有声明成rand类型)。这相当于将每个类属性的当前rand_mode()推入堆栈,打开列表中出现的所有类属性的rand_mode(),并关闭所有未出现类属性的rand_mode()在列表中。在对randomize()的调用之后,每个类属性的rand_mode()通过将它们弹出堆栈来恢复。和其他任何对randomize()的调用一样,约束求解器将尝试满足当前为该类的所有约束。
你也可以调用randomize(null)。在这种情况下,所有类属性的rand_mode()都会关闭,如果所有类属性的当前状态都在约束范围内,则该调用将返回true。也就是说:调用没有随机变量的类的randomize方法会导致该方法表现为检查器。constraint求解器将所有变量视为状态变量,并仅检查约束是否满足约束。 success = a.randomize( null ); // no random variables
当你向randomize()方法提供随机变量列表时,该列表必须仅包含由此隐式指向的对象的类属性。该列表不能包含该对象之外的变量。
当你调用std :: randomize()时,你并没有调用一个类的方法,而是调用了一个内建函数。变量列表现在可以指向作为随机变量合法的任何变量。 (例如,实际变量将不被允许)。除非列表中的变量是类对象,否则与列表中的任何变量都没有关联。添加约束的唯一方法是使用with分句。
举例如下:
class A; rand bit [7:0] x=2; rand bit [7:0] y=11; constraint C1 {y inside {[1:10]};} constraint C2 {x < y; } endclass module top; A a1,a2; initial begin a1 = new(); a2 = new(); assert(a1.randomize(y)); // x=2(unchanged state), y=3-10 (random) assert(std::randomize(a2.x,a1.y) with {a2.x > 0; a1.y < a2.y;}); //Constraints C1 and C2 do not apply // a1.x = 2 (unchanged state variable) // a1.y = 0-10 // a2.x = 1-255 // a2.y = 11(unchanged state variable) end endmodule