首页 > 其他分享 >SystemVerilog 随机化约束速查手册

SystemVerilog 随机化约束速查手册

时间:2022-08-19 17:58:05浏览次数:75  
标签:rand constraint max inside len 随机化 速查 SystemVerilog size

SystemVerilog 随机化约束速查手册

dist关键字权重分布

使用dist关键字来实现权重分布

  • := 表示范围内每个权重是相同的
  • :/ 表示权重要均分到范围的每个值
rand int src;

constraint c_dist{
  src dist {0:/40, [1:3] := 60;};
}

inside关键字集合约束

inside运算符产生一个值的集合

rand int c;
int lo, hi;

constraint c_range{
  c inside {[lo:hi]};
}

// 指定最大最小值
constraint c_biggest{
  c inside {[$:5], [20:$]};
}

// 集合约束取反
constraint c_range {
  ! (c inside {[lo:hi]});
}

集合里的每一个值取出的概率都是相同的 , 即使值在数组中出现多次,可以把inside约束看作foreach约束。

条件约束

if else

class BusOp;
...
  constraint c_len_rw {
    if(op == READ)
      len inside {[BYTE:LWRD]};
    else
      len == LWRD;
  }
  
// ------------------ method of -> --------------

  constraint c_len_rw {
    op == READ -> len inside {[BYTE:LWRD]};
    !(op == READ) -> len == LWRD;
  }

双向约束

约束表达式同时进行求解的,因此条件约束表达式也是同时求解的

例题1

class obj;
	rand bit A;
	rand [3:0] B;
	
	constraint c {
	  A == 0 -> B == 4'd15;
	}
endclass

**B = 4'd15 的概率是2/17 **

原因请见 SystemVerilogIEEE 1800-2017 18.5.10 绿皮书上是错的

例题2

class imp2;
	rand bit x;
	rand bit [1:0] x;
	constraint c {
		y > 0;
		(x == 0) -> y == 0;
	}
endclass

// 这种约束下只有三种情况 x = 1下 y = 1/2/3

数组约束

module tb;

    // ------------------------------------------------------------
    class dyn_size;
        rand logic [31:0] d_array [];
        constraint d_size {d.size inside {[1:10]};}
    endclass

    // ------------------------------------------------------------
    // sum to generate only 4 valid channel
    parameter MAX_TRANSFER_LEN = 10;
    class strobePat;
        rand bit strobe [MAX_TRANSFER_LEN];
        constraint c_set_for {strobe.sum() == 4'h4};
    endclass

    // ------------------------------------------------------------
    // aim : 要产生1~8个包,这几个包之和为1024
    // bad_sum1 问题是:byte是有符号数据类型,会产生负的数据
    // ------------------------------------------------------------
    class bad_sum1;
        rand byte len[];
        constraint c_len {len.sum() < 1024;
                            len.size inside {[1:8]};}
    endclass

    // ------------------------------------------------------------
    // bad_sum2 问题:因为bit是8位的所以求解器计算结果也是8位的
    // 这就导致 len.sum 最大都不会超过255
    // ------------------------------------------------------------
    class bad_sum2;
        rand bit [7:0] len [];
        constraint c_len {len.sum < 1024;
                        len.size inside {[1:8]};}
    endclass

    // ------------------------------------------------------------
    // bad_sum3 问题:跟有符号类型问题一样,两个非常大的数会导致溢出
    // ------------------------------------------------------------
    class bad_sum3;
        rand uint len[];
        constraint c_len {len.sum < 1024;
                        len.size inside {[1:8]};}
    endclass


    // ------------------------------------------------------------
    // bad_sum4 问题:由于每个len的位宽都超过8位,所以随机后len的值都会超过255
    // 因此扩展位宽的方法会导致len超过255
    // ------------------------------------------------------------
    class bad_sum4;
        rand bit [9:0] len [];
        constraint c_len {
                        len.sum < 1024;
                        len.size inside {[1:8]};
        }
    endclass


    // ------------------------ right answer -------------------------------
    // 限制了len数据大小
    // 位宽扩展为32位保证了sum可以大于255
    class good_sum5;
        rand uint len [];
        constraint c_len {
                        foreach(len[i]) len[i] inside {[1:255]};
                        len.sum < 1024;
                        len.size inside {[1:8]};
        }
    endclass

endmodule

产生递增数组元素

class ascend;
	rand uint d[10];
	constraint c {
		foreach (d[i])
			if(i > 0)
				d[i] > d[i-1];
	}
endclass

产生具有唯一元素值数组

// slow method
class unislow;
	rand bit [7:0] ua[64];
	constraint c {
		foreach (ua[i])
			foreach(ua[j])
				if(i != j)
					ua[i] != ua[j];
	}
endclass

// randc good method
class randc8;
  randc bit [7:0] val;
endclass

class uniarray;
  bit [7:0] ua [64];
  
  function void pre_randomize;
    randc8 rc8;
    rc8 = new();
    foreach(ua[i])begin
      assert(rc8.randomize());
      ua[i] = rc8.val;
    end
  endfunction
endclass

// more normal method

class RandcRange;
  randc bit [15:0] value;
  int max_value;
  
  function new (int max_value = 10);
    this.max_value = max_value;
  endfunction
  
  constraint c {vlaue < max_value};
endclass

class uni_array;
  int max_array_size, max_value;
  rand bit [7:0] a[];
  constraint c {a.size() inside {[1:max_array_size]};}
  
  function new (int max_array_size = 2, max_value = 2);
    this.max_array_size = max_array_size;
    if(max_value < max_array_size)
      this.max_value = max_array_size;
    else
      this.max_value = max_value;
  endfunction
  
  function void post_randomize;
    RandcRange rr;
    rr = new(max_value);
    foreach (a[i])begin
      assert(rr.randomize());
      a[i] = rr.value;
    end
  endfunction
endclass

标签:rand,constraint,max,inside,len,随机化,速查,SystemVerilog,size
From: https://www.cnblogs.com/pu1se/p/16602844.html

相关文章

  • Docker命令速查
    Docker命令显示所有正在运行的docker容器dockerps显示所有docker容器dockerps-a运行容器dockerrun:运行一个容器并连接到它dockerrun-it:在后台运行容器......