• 【从零开始学习 SystemVerilog】8.5、SystemVerilog 约束—— Constraint Examples(约束示例)


    现在,让我们看看在约束块中编写约束表达式的一些常见方法。

    Simple expressions

    请注意,表达式中只能有一个关系运算符< <= > >=

    class MyClass;
    	rand bit [7:0] min, typ, max;
    
    	// Valid expression
    	constraint my_range { 0 < min;
    	                      typ < max; typ > min;
    	                      max < 128; }
    
    	// Use of multiple operators in a single expression is not allowed
    	constraint my_error { 0 < min < typ < max < 128; } // This will set min to 16 and randomize all others constraint my_min { min == 16; } // This will set max to a random value greater than or equal to 64 constraint my_max { max >= 64; }
    endclass
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    不能在约束块内进行指定,因为它只包含表达式。相反,您必须使用等价运算符==如上面示例中名为my_min的约束所示,其中min将获得16的值,所有其他变量都将随机化。这是一种将特定值固定到变量的方法,即使解算器尝试将其随机化。

    constraint my_min { min == temp.low * 9/5 + 32; }
    
    • 1

    您还可以使用更复杂的表达式,如上面所示,其中min表示存储华氏温度的变量,low是类对象temp中的一个变量,该变量保存摄氏温度。

    Example

    class myClass;
          rand bit [3:0] min, typ, max;
          rand bit [3:0] fixed;
    
          constraint my_range { 3 < min;
                                typ < max; typ > min;
                                max < 14; }
    
          constraint c_fixed { fixed == 5; }
    
          function string display ();
            return $sformatf ("min=%0d typ=%0d max=%0d fixed=%d", min, typ, max, fixed);
          endfunction
    
    endclass
    
        module tb;
           initial begin
              for (int i = 0; i < 10; i++) begin
                 myClass cls = new ();
                 cls.randomize();
                 $display ("itr=%0d %s", i, cls.display());
              end
           end
        endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    请注意,fixed 变量固定为值5,而其他变量已随机化为满足所有约束的值。

    # KERNEL: itr=0 min=7 typ=9 max=12 fixed= 5
    # KERNEL: itr=1 min=4 typ=9 max=12 fixed= 5
    # KERNEL: itr=2 min=7 typ=10 max=13 fixed= 5
    # KERNEL: itr=3 min=4 typ=6 max=11 fixed= 5
    # KERNEL: itr=4 min=8 typ=12 max=13 fixed= 5
    # KERNEL: itr=5 min=5 typ=6 max=13 fixed= 5
    # KERNEL: itr=6 min=6 typ=9 max=13 fixed= 5
    # KERNEL: itr=7 min=10 typ=12 max=13 fixed= 5
    # KERNEL: itr=8 min=5 typ=11 max=13 fixed= 5
    # KERNEL: itr=9 min=6 typ=9 max=11 fixed= 5
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    inside operator

    可以使用inside 运算符指定下限和上限,以替代下面显示的表达式。

    constraint my_range { typ > 32;
                          typ < 256; } // typ >= 32 and typ <= 256
    constraint new_range { typ inside {[32:256]}; }
    
    // Choose from the following values
    constraint spec_range { type inside {32, 64, 128}; }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    请注意,内部构造包括下限和上限。SystemVerilog收集所有值,并以相等的概率在值之间进行选择,除非变量有其他约束。

    Inverted inside operator

    如果需要特定范围之外的任何值,则可以按如下方式编写反向约束。这将产生一个从0到31的随机值,因为typ是一个8位变量,并且上限已经覆盖了它可以保持的最大值。

    rand bit [2:0] typ;
    constraint inv_range { ! (typ inside {[3:6]}); }
    
    • 1
    • 2

    注意,重复随机化给出了除落在范围3至6内的值之外的所有值。

    # KERNEL: itr=0 typ=7
    # KERNEL: itr=1 typ=0
    # KERNEL: itr=2 typ=7
    # KERNEL: itr=3 typ=0
    # KERNEL: itr=4 typ=0
    # KERNEL: itr=5 typ=0
    # KERNEL: itr=6 typ=7
    # KERNEL: itr=7 typ=1
    # KERNEL: itr=8 typ=1
    # KERNEL: itr=9 typ=7
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Weighted distributions

    dist运算符允许您创建加权分布,以便选择某些值的频率高于其他值。:=运算符指定范围内的每个指定值的权重相同,而 /= 运算符指定权重在所有值之间等分

    := operator

    rand bit [2:0] typ;
    constraint dist1 	{  typ dist { 0:=20, [1:5]:=50, 6:=40, 7:=10}; }
    
    • 1
    • 2

    在dist1中,0的权重为20,6为40,7为10,而1到5为50,总共为320。因此,选择0的概率为20/320,选择1到5之间的值的概率为50/320。让我们来看一个简单的示例。

    class myClass;
    	rand bit [2:0] typ;
    	constraint dist1 	{  typ dist { 0:=20, [1:5]:=50, 6:=40, 7:=10}; }
    endclass
    
    module tb;
    	initial begin
    		for (int i = 0; i < 10; i++) begin
    			myClass cls = new ();
    			cls.randomize();
    			$display ("itr=%0d typ=%0d", i, cls.typ);
    		end
    	end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在下面显示的日志中,请注意,1到5出现的次数超过0、6或7,因为它们的权重更高,选择频率更高。

    # KERNEL: itr=0 typ=5
    # KERNEL: itr=1 typ=1
    # KERNEL: itr=2 typ=6
    # KERNEL: itr=3 typ=3
    # KERNEL: itr=4 typ=2
    # KERNEL: itr=5 typ=3
    # KERNEL: itr=6 typ=0
    # KERNEL: itr=7 typ=5
    # KERNEL: itr=8 typ=1
    # KERNEL: itr=9 typ=4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    /= operator

    rand bit [2:0] typ;
    constraint dist2  	{  typ dist { 0:/20, [1:5]:/50, 6:/10, 7:/20}; }
    
    • 1
    • 2

    在dist2中,0的权重为20,6为10,7为20,而1到5的总权重为50,因此各有10。因此,选择0的概率是20/100,选择1和5之间的值的概率是10/100。

    class myClass;
    	rand bit [2:0] typ;
    	constraint dist2 	{  typ dist { 0:/20, [1:5]:/50, 6:/40, 7:/10}; }
    endclass
    
    module tb;
    	initial begin
    		for (int i = 0; i < 10; i++) begin
    			myClass cls = new ();
    			cls.randomize();
    			$display ("itr=%0d typ=%0d", i, cls.typ);
    		end
    	end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在下面显示的日志中,请注意,6出现的次数比其他的多,因为它的权重最高。

    # KERNEL: itr=0 typ=5
    # KERNEL: itr=1 typ=6
    # KERNEL: itr=2 typ=4
    # KERNEL: itr=3 typ=6
    # KERNEL: itr=4 typ=6
    # KERNEL: itr=5 typ=4
    # KERNEL: itr=6 typ=2
    # KERNEL: itr=7 typ=3
    # KERNEL: itr=8 typ=4
    # KERNEL: itr=9 typ=6
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Bidirectional constraints(双向约束)

    约束块不像过程代码那样从上到下执行,而是同时处于活动状态。让我们用另一个例子来看。

    class myClass;
    	rand bit [3:0] val;
    	constraint  c1 { val > 3;
    	                 val < 12; } constraint c2 {val >= 10; }
    endclass
    
    module tb;
    	initial begin
    		for (int i = 0; i < 10; i++) begin
    			myClass cls = new ();
    			cls.randomize();
    			$display ("itr=%0d typ=%0d", i, cls.val);
    		end
    	end
    endmodule
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注意,约束c1和c2将值限制为10和11。

    # KERNEL: itr=0 typ=11
    # KERNEL: itr=1 typ=11
    # KERNEL: itr=2 typ=11
    # KERNEL: itr=3 typ=10
    # KERNEL: itr=4 typ=11
    # KERNEL: itr=5 typ=10
    # KERNEL: itr=6 typ=10
    # KERNEL: itr=7 typ=10
    # KERNEL: itr=8 typ=10
    # KERNEL: itr=9 typ=10
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  • 相关阅读:
    【深度学习】pytorch——常用工具模块
    ✨ StarRocks 10 月社区动态
    Java Socket实现简易多人聊天室传输聊天内容或文件
    C++信息学奥赛1181:整数奇偶排序
    poium测试库之JavaScript API封装原理
    标准RBAC模型表设计
    用python实现给女朋友自动发微信
    免费活动】11月4日敏捷武林上海站 | Scrum.org CEO 亲临现场
    1397. 找到所有好字符串(kmp理解 + 数位dp)(好题!!!)
    Arduino与Proteus仿真实例-简单信号频率计数仿真
  • 原文地址:https://blog.csdn.net/claylovetoo/article/details/126811184