其他分享
首页 > 其他分享> > 随机约束、随机分布、随机数组等-systemverilog

随机约束、随机分布、随机数组等-systemverilog

作者:互联网

一、简介

why

what

二、随机化种类

class packet;
//定义随机变量
rand bit[31:0] src,dst,data[8];
randc bit[7:0] kind;
//约束变量
constraint c//约束需要有实例名
{
  src > 10;
  src < 15;
}//注意没有;号
endclass

program test;
packet p;
initial begin
  p = new();
  assert(p.randomize)
  else $fatal(0,"Packet :: randomize failed");
  transmit(p);
end
endprogram
assert(condition) expression;
else              expression;
assert(condition) 
else              expression;

2.1布尔表达式

一般是在约束里所有表达式进行判断进行逻辑判断.

class order;
rand bit [7:0] lo,med,hi;
constraint bad
{
  lo<med<hi;
  }
endclass
class order;
rand bit [15:0] lo,med,hi;
constraint good
{
  lo < med;
  med <hi;
}
endclass

2.2 权重分配(weighted distributions)

符号含义
:=表示值范围内的每一个值的权重都是相同的;
: /表示权重要均分到值范围内的每一个值
rand int src,dst;
constraint c_dist
{
  src dist{0:=40,[1:3]:=60};
  //src = 0,weight = 40/220
  //src = 1,weight = 60/220
  //src = 2,weight = 60/220
  //src = 3,weight = 60/220
  dst dist{0:/40,[1:3]:/60};
  //dst = 0,weight = 40/100
  //dst = 1,weight = 20/100
  //dst = 2,weight = 20/100
  //dst = 3,weight = 20/100
}

带变量的权重分配

typedef enum {READ8,READ16,READ32} read_e;
class ReadCommands;
rand read_e read_cmd;
int read8_wt = 1,read16_wt = 1,read32_wt = 1;
constraint c_read
{
  read_cmd dist
  {
    READ8  := read8_wt;
    READ16 := read16_wt;
    READ32 := read32_wt;
  };
}
endclass

2.3 范围表达式随机(range expressions)

inside运算符产生一个值的集合,除非对变量还有其他约束,否则sv在值的集合中取随机值时,各个值的选取机会是相等的,在集合中也可以使用变量

rand int c;
int lo,hi;
constraint c_range
{
  c inside{[lo:hi]};//!(c inside{[lo:hi]};c<lo or c >hi
}

可以使用$代表取值范围的最小值和最大值

rand bit [6:0]b;//0<=b<=127
rand bit [5:0]e;
constraint c_range
{
  b inside {[$:4],[20:$]};
  c inside {[$:4],[20:$]};
}

在集合中使用数据

rand int f;
int fib[5] = '{1,2,3,5,8};
constraint c_fibonacci
{
 f inside fib;
}

2.4 条件表达式

通常约束块里面的所有约束都是有效的,但是有时我们只想让约束在某些时刻有效,例如在总线支持字节、半字、字的读操作,但是我们想只支持字的操作时。

class stim;
bit flag;
rand bit [31:0] dst;
constraint c_stim
{
  if(flag)
  {
    dst inside {[40:80]};
  }
  else
    dst inside {[2:10],[50:67]};
}
endclass
class stim;
bit flag;
rand bit [31:0] dst;
constraint c_stim
{
  flag -> dst inside {[40:80]};
  !flag -> dst inside {[2:10],[50:67]};
}
endclass

2.5 外部约束

外部约束可以在需要的时候才添加约束,也可以不加约束;

class packet;
rand bit [7:0] length;
rand bit [7:0] payload[];
constraint c_valid 
{
  length > 0;
  payload.size() == length;
}
constraint c_external;
endclass

program test;
  constraint packet::c_external{length ==  1;}
endprogram

显示外部约束的格式:在使用之前如果没有前面的extern会报错;

extern constraint c_ext

2.6 双向约束

约束块不想自上而下执行程序性代码,它们是声明性的代码,是并行执行的,所有的约束表达式同时有效,古SV会同时计算所有的随机标量约束,取他们的交集

rand logic[15:0] r,s,t;
constraint c_bitir
{
  r < t;
  s == r;
  t <30;
  s >25;
}

有一个练习:

parameter MAX_SIZE = 10;
class packet;
rand bit [31:0] src,dst,data[8];
randc bit [2:0] kind;
constraint c
{
  src > 10;
  src < 15;
}
endclass:packet
//随机化句柄数组
class randarray;
rand packet array[];
constraint c
{
  array.size() inside{[1:MAX_SIZE]};
}
function new();
  array = new[MAX_SIZE];
  foreach(array[i])
    array[i] = new();
endfunction
endclass:randarry

module top_tb;
packet p;
initial begin
  p = new();
  assert (p.randomize)
  else $fatal(0,"packet::randomize failied");
  foreach(p.array[i])begin
    $display("src =%d",p.array[i].src);
    $display("dst =%d",p.array[i].dst);
    $display("data = ",p.array[i].data);
    $display("kind = %d",p.array[i].kind);
  end
end
endmodule

三、随机约束分布概率

3.1 没有约束的类

class unconstrained;
rand bit x;//0、1
rand bit[1:0]y;//0、1、2、3
endclass
module top_tb;
unconstrained u;
int cnt000,cnt001,cnt010,cnt011,cnt100,cnt101,cnt110,cnt111;
initial begin
  u = new();
  for(int i = 1;i<20000;i++)begin
  assert(u.randomize());
  case({u.x,u.y})
  3'b000:cnt000 = cnt000+1'b1;
  3'b001:cnt001 = cnt001+1'b1;
  3'b010:cnt010 = cnt010+1'b1;
  3'b011:cnt011 = cnt011+1'b1;
  3'b100:cnt100 = cnt100+1'b1;
  3'b101:cnt101 = cnt101+1'b1;
  3'b110:cnt110 = cnt110+1'b1;
  3'b111:cnt111 = cnt111+1'b1;
  endcase
  end
  $display("{u.x,u.y} is 000 time %0d",cnt000);
  $display("{u.x,u.y} is 001 time %0d",cnt001);
  $display("{u.x,u.y} is 010 time %0d",cnt010);
  $display("{u.x,u.y} is 011 time %0d",cnt011);
  $display("{u.x,u.y} is 100 time %0d",cnt100);
  $display("{u.x,u.y} is 101 time %0d",cnt101);
  $display("{u.x,u.y} is 110 time %0d",cnt110);
  $display("{u.x,u.y} is 111 time %0d",cnt111);
  end
endmodule
xy概率
A001/8
B011/8
C021/8
D031/8
E101/8
F111/8
G121/8
H131/8

在这里插入图片描述

3.2 关系操作

class impact1;
rand bit x;//0、1
rand bit[1:0]y;//0、1、2、3

constraint c_xy
{
  (x == 0)->y == 0;
}
endclass
module top_tb;
impact1 u;
int cnt000,cnt001,cnt010,cnt011,cnt100,cnt101,cnt110,cnt111;
initial begin
  u = new();
  for(int i = 1;i<20000;i++)begin
  assert(u.randomize());
  case({u.x,u.y})
  3'b000:cnt000 = cnt000+1'b1;
  3'b001:cnt001 = cnt001+1'b1;
  3'b010:cnt010 = cnt010+1'b1;
  3'b011:cnt011 = cnt011+1'b1;
  3'b100:cnt100 = cnt100+1'b1;
  3'b101:cnt101 = cnt101+1'b1;
  3'b110:cnt110 = cnt110+1'b1;
  3'b111:cnt111 = cnt111+1'b1;
  endcase
  end
  $display("{u.x,u.y} is 000 time %0d",cnt000);
  $display("{u.x,u.y} is 001 time %0d",cnt001);
  $display("{u.x,u.y} is 010 time %0d",cnt010);
  $display("{u.x,u.y} is 011 time %0d",cnt011);
  $display("{u.x,u.y} is 100 time %0d",cnt100);
  $display("{u.x,u.y} is 101 time %0d",cnt101);
  $display("{u.x,u.y} is 110 time %0d",cnt110);
  $display("{u.x,u.y} is 111 time %0d",cnt111);
  end
endmodule
xy概率
A001/5
B010
C020
D030
E101/5
F111/5
G121/5
H131/5

在这里插入图片描述

class impact2;
randc bit x;//0、1
rand bit[1:0]y;//0、1、2、3

constraint c_xy
{
  (x == 0)->y == 0;
}
endclass
module top_tb;
impact2 u;
int cnt000,cnt001,cnt010,cnt011,cnt100,cnt101,cnt110,cnt111;
initial begin
  u = new();
  for(int i = 1;i<20000;i++)begin
  assert(u.randomize());
  case({u.x,u.y})
  3'b000:cnt000 = cnt000+1'b1;
  3'b001:cnt001 = cnt001+1'b1;
  3'b010:cnt010 = cnt010+1'b1;
  3'b011:cnt011 = cnt011+1'b1;
  3'b100:cnt100 = cnt100+1'b1;
  3'b101:cnt101 = cnt101+1'b1;
  3'b110:cnt110 = cnt110+1'b1;
  3'b111:cnt111 = cnt111+1'b1;
  endcase
  end
  $display("{u.x,u.y} is 000 time %0d",cnt000);
  $display("{u.x,u.y} is 001 time %0d",cnt001);
  $display("{u.x,u.y} is 010 time %0d",cnt010);
  $display("{u.x,u.y} is 011 time %0d",cnt011);
  $display("{u.x,u.y} is 100 time %0d",cnt100);
  $display("{u.x,u.y} is 101 time %0d",cnt101);
  $display("{u.x,u.y} is 110 time %0d",cnt110);
  $display("{u.x,u.y} is 111 time %0d",cnt111);
  end
endmodule
xy概率
A001/2
B010
C020
D030
E101/8
F111/8
G121/8
H131/8

在这里插入图片描述

class impact3;
rand bit x;//0、1
randc bit[1:0]y;//0、1、2、3

constraint c_xy
{
  (x == 0)->y == 0;
}
endclass
module top_tb;
impact3 u;
int cnt000,cnt001,cnt010,cnt011,cnt100,cnt101,cnt110,cnt111;
initial begin
  u = new();
  for(int i = 1;i<20000;i++)begin
  assert(u.randomize());
  case({u.x,u.y})
  3'b000:cnt000 = cnt000+1'b1;
  3'b001:cnt001 = cnt001+1'b1;
  3'b010:cnt010 = cnt010+1'b1;
  3'b011:cnt011 = cnt011+1'b1;
  3'b100:cnt100 = cnt100+1'b1;
  3'b101:cnt101 = cnt101+1'b1;
  3'b110:cnt110 = cnt110+1'b1;
  3'b111:cnt111 = cnt111+1'b1;
  endcase
  end
  $display("{u.x,u.y} is 000 time %0d",cnt000);
  $display("{u.x,u.y} is 001 time %0d",cnt001);
  $display("{u.x,u.y} is 010 time %0d",cnt010);
  $display("{u.x,u.y} is 011 time %0d",cnt011);
  $display("{u.x,u.y} is 100 time %0d",cnt100);
  $display("{u.x,u.y} is 101 time %0d",cnt101);
  $display("{u.x,u.y} is 110 time %0d",cnt110);
  $display("{u.x,u.y} is 111 time %0d",cnt111);
  end
endmodule
xy概率
A001/8
B010
C020
D030
E101/8
F111/4
G121/4
H131/4

在这里插入图片描述

class impact1;
randc bit x;//0、1
randc bit[1:0]y;//0、1、2、3

constraint c_xy
{
  (x == 0)->y == 0;
}
endclass
xy概率
A001/4
B010
C020
D030
E100
F111/4
G121/4
H131/4
class impact5;
rand bit x;//0、1
rand bit[1:0]y;//0、1、2、3

constraint c_xy
{
  y > 0;
  (x == 0)->y == 0;
}
endclass
module top_tb;
impact5 u;
int cnt000,cnt001,cnt010,cnt011,cnt100,cnt101,cnt110,cnt111;
initial begin
  u = new();
  for(int i = 1;i<20000;i++)begin
  assert(u.randomize());
  case({u.x,u.y})
  3'b000:cnt000 = cnt000+1'b1;
  3'b001:cnt001 = cnt001+1'b1;
  3'b010:cnt010 = cnt010+1'b1;
  3'b011:cnt011 = cnt011+1'b1;
  3'b100:cnt100 = cnt100+1'b1;
  3'b101:cnt101 = cnt101+1'b1;
  3'b110:cnt110 = cnt110+1'b1;
  3'b111:cnt111 = cnt111+1'b1;
  endcase
  end
  $display("{u.x,u.y} is 000 time %0d",cnt000);
  $display("{u.x,u.y} is 001 time %0d",cnt001);
  $display("{u.x,u.y} is 010 time %0d",cnt010);
  $display("{u.x,u.y} is 011 time %0d",cnt011);
  $display("{u.x,u.y} is 100 time %0d",cnt100);
  $display("{u.x,u.y} is 101 time %0d",cnt101);
  $display("{u.x,u.y} is 110 time %0d",cnt110);
  $display("{u.x,u.y} is 111 time %0d",cnt111);
  end
endmodule
xy概率
A000
B010
C020
D030
E100
F111/3
G121/3
H131/3

3.3 solve…before

class slovebefore;
rand bit x;//0、1
rand bit[1:0]y;//0、1、2、3

constraint c_xy
{
  (x == 0)->y == 0;
  solve x before y;
}
endclass
module top_tb;
slovebefore u;
int cnt000,cnt001,cnt010,cnt011,cnt100,cnt101,cnt110,cnt111;
initial begin
  u = new();
  for(int i = 1;i<20000;i++)begin
  assert(u.randomize());
  case({u.x,u.y})
  3'b000:cnt000 = cnt000+1'b1;
  3'b001:cnt001 = cnt001+1'b1;
  3'b010:cnt010 = cnt010+1'b1;
  3'b011:cnt011 = cnt011+1'b1;
  3'b100:cnt100 = cnt100+1'b1;
  3'b101:cnt101 = cnt101+1'b1;
  3'b110:cnt110 = cnt110+1'b1;
  3'b111:cnt111 = cnt111+1'b1;
  endcase
  end
  $display("{u.x,u.y} is 000 time %0d",cnt000);
  $display("{u.x,u.y} is 001 time %0d",cnt001);
  $display("{u.x,u.y} is 010 time %0d",cnt010);
  $display("{u.x,u.y} is 011 time %0d",cnt011);
  $display("{u.x,u.y} is 100 time %0d",cnt100);
  $display("{u.x,u.y} is 101 time %0d",cnt101);
  $display("{u.x,u.y} is 110 time %0d",cnt110);
  $display("{u.x,u.y} is 111 time %0d",cnt111);
  end
endmodule
xy概率
A001/2
B010
C020
D030
E101/8
F111/8
G121/8
H131/8

在这里插入图片描述

四、随机约束控制

4.1 控制多个约束块constraint_mode()

class packet;
rand int length;
constraint c_short {length inside{[1:32]};}
constraint c_long {length inside{[1000:1023]};}
endclass
module top_tb;
packet p;
initial begin
p = new();
p.c_short.constraint_mode(0);//disabling short constraint
assert(p.randomize());
$display("p::length = %d",p.length);
p.constraint_mode(0);
p.c_short.constraint_mode(1);
assert(p.randomize());
$display("p::length = %d",p.length);
end
endmodule

4.2 控制随机变量rand_mode()

class packet;
rand bit [7:0] length,payload[];
constraint c_valid {length > 0;payload.size() ==length;}
endclass
module top_tb;
packet p;
initial begin
p = new();
p.length.rand_mode(0);
p.length = 42;
assert(p.randomize());
$display("p::length = %d",p.length);
p.length.rand_mode(1);
assert(p.randomize());
$display("p::length = %d",p.length);
end
endmodule

4.3 控制随机变量randomize() with{}

class transaction;
rand bit [31:0]addr,data;
constraint c1{addr inside{[0:100],[1000:2000]};}
endclass

module top_tb;
transaction t;
initial begin
  t = new();
  assert(tr.randomize() with {addr >= 50;addr <= 1500;data < 10;});
  $display("t::addr is %d",t.addr);
  $display("t:data is %d",t.data);
  assert(t.randomize() with{addr == 2000;data >10;});//force addr to a specific value,data >10
  $display("t::addr is %d",t.addr);
  $display("t:data is %d",t.data);
end
endmodule

4.4 randomize单独控制变量

class rising;
byte low;
rand byte med,hi;
constraint c_up{low<med;med<hi;}
endclass
module top_tb;
rising r;
initial begin
  r = new();
  r.randomize();
  $display("r::low is %d,r:med is %d,r::hi is %d",r.low,r.med,r.hi);
  r.randomize(med);
  $display("r::low is %d,r:med is %d,r::hi is %d",r.low,r.med,r.hi);
  r.randomize(low);
  $display("r::low is %d,r:med is %d,r::hi is %d",r.low,r.med,r.hi);
end
endmodule

在这里插入图片描述

4.5 pre_randomize与post_randomize

它们的特点:

class wr_tran;
  int constraint_en;
  int broadcast;
  rand int wr_addr;
  rand int wr_data;
  rand bit valid;
  constraint generic_c
  { 
    valid == 1;
    wr_addr < 100;
  }
  function void pre_randomize();
      $display("call the pre_randomize !");
      if(!constraint_en)
        generic_c.constraint_mode(0);
   endfunction
  function void post_randomize();
     $display("call post_randomize!");
     if(wr_addr == 1)
       broadcast = 1;
     else broadcast = 0;
   endfunction
 endclass
module top_tb;
  wr_tran tr;
  initial begin
    tr = new();
    tr.constraint_en = 0;
    tr.randomize() with
    {
      wr_addr == 200;
      wr_data == 3;
      valid   == 0;
    };
    $display("wr_addr = %d,
              wr_data = %d,
              valid   = %d,
              broadcast = %d",
              tr.wr_addr,tr.wr_data,tr.valid,tr.broadcast);
              end
              endmodule          

在这里插入图片描述

五、随机化常见错误

sig1:12345678
sig 1 &000FF 000
class test;
  rand bit[7:0]sig1;
  rand int unsigned sig1;
constrain c
{
  sig2>1000;
  sig1>sig2;//sig1的最大值256,无法达到1000,需要注意位宽、符号
rand bit[7:0]sig1;
rand bit[7:0]sig2;
constraint c1{sig1>5;}
constraint c2{sig2>10;}
constraint c2{sig1+sig2 ==13;}//这里也是不对的,多随机变量的出现形式可能会出现相互矛盾的;

所以我们在使用随机化时需要注意

标签:rand,组等,constraint,b1,0d,time,display,systemverilog,随机
来源: https://blog.csdn.net/weixin_42705678/article/details/121275666