0%

SV之随机约束

本节主要介绍了SystemVerilog中产生随机数的方法以及约束块的使用

随机变量

  • 任何类中的整形(bit/byte/int)变量、定长数组,动态数组、关联数组和队列都可以声明为rand/randc,可以对动态数组和队列的长度加以约束,非组合型结构体可以声明为rand

  • 只能用类这个“载体”去容纳变量以及它们之间的约束关系

  • module里面不能用rand

  • 对于rand修饰符,表示在可生成的范围内,每个值得可能性是相同的

  • 对于randc修饰符,它的值将会随机并且遍历其可取值范围,即取出后的数不放回,等全部取出后再在取值范围内重新抽取

  • 产生随机数的方式:

    • 通过系统函数std::randomize(var)产生随机数并赋予变量
    • var = $urandom() //可以产生一个32位的无符号随机数
    • var = $urandom_range(maxval, minval = 0) // 可以生成在maxval与minval之间的数
    • .randomize()的数据类型只能是类
    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
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    //类中存放一些随机数
    class packet;
    rand bit [31:0] src, dst, data[4];
    rand bit [7:0] kind;
    constraint cstr{
    src > 10;
    src < 15;
    }
    function void print();
    $display("src is %0d\n dst is %0d\n kind is %0d\n data is &p", src, dst, kind, data);
    endfuntion
    endclass

    module tb;
    packet p;
    initial begin
    p = new();
    $display("before randomize");
    p.print();
    p.randomize(); //使用.randomize()随机化类中的变量
    $display("after randomize");
    p.print();
    end
    endmodule

    //结构体中存放一些随机数
    typedef struct{
    rand bit [31:0] src;
    rand bit [31:0] dst;
    rand bit [31:0] data[4];
    rand bit [7:0] kind;
    } packet_t;

    module tb2;
    packet_t pkt;
    initial begin
    $display("before randomized packet struct:: src %0d\n kind is %0d\n kind is %0d\n data is %p", pkt.src, pkt.dst, pkt.kind, pkt.data);
    std::randomize(pkt) with {src > 10; src < 15} //in-line constraint 内联约束
    $display("before randomized packet struct:: src %0d\n kind is %0d\n kind is %0d\n data is %p", pkt.src, pkt.dst, pkt.kind, pkt.data);
    end
    endmodule

约束块

  • 约束块支持整形通过constraint操作符来设置它们的可取值范围

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    class set_rand;
    rand integer x, y, z;
    constraint c1 {x inside {3, 5, [9:15], [24:32], [y:2*y], z};}

    rand integer a, b, c;
    constraint c2 {a inside {b, c};}

    integer fives[4] = '{5, 10, 15, 20};
    rand integer v;
    constraint c3 {v inside {fives};}

    //unique可以用来约束一组变量,使得其在随机后变量之间不会有相同的数值
    rand byte a[5];
    rand byte b;
    rand byte excluded;
    constraint u {unique {b, a[2:3], exclude};}//这里a[2]、a[3]、b和excluded在随机之后将包含不相同的数值
    constraint exclusion {excluded == 5;}

    //使用->操作符来表示条件约束
    bit [3:0] a, b;
    constraint c {(a == 0) -> (b < 10)} //表示如果a等于0,那么b就随机取小于10的数
    endclass
  • 权重分布

    • 对于:=操作符,它们表示每一个值的权重是相同的

    • 对于:/操作符,它们表示权重会平均分配到每一个值

      1
      2
      x dist {[100:102] := 1, 200 := 2, 300 := 5} //x在100,101,102,200和300的权重是1-1-1-2-5
      x dist {[100:102] :/1, 200 := 2, 300 := 5} //x在100,101,102,200和300的权重是1/3-1/3-1/3-2-5
  • 软约束
    • 在没有soft描述约束时,称为硬约束,带有soft描述的约束是软约束
    • 硬约束的父类子类,若对同一变量:约束同名则覆盖,若不同名则取交集;此外,硬约束可以覆盖软约束
    • 若都是软约束,则遵循最近的软约束

随机控制与约束控制

1.随机控制

  • rand_mode()可以用来使能(1)或禁止(0)随机变量

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class packet;
    rand bit [31:0] src, dst, data[4];
    rand bit [7:0] kind;
    ...
    endclass

    Packet packet_a = new();
    packet_a.rand_mode(0); //禁止类中所有随机变量

    packet_a.src.rand_mode(1);//使能某个随机变量

2.约束控制

  • 类似的,约束中使用constraint_mode()来使能或禁止约束块
欢迎来到ssy的世界