[SV]Constraint 遇到的问题

约束冲突时:

(1)后约束覆盖前约束

(2)子类约束覆盖父类约束

(3)外部约束覆盖内部约束

(4)强约束覆盖soft约束

(5)如果两个soft 约束冲突,按上述3条处理且随机是可以成功

 


1.错误写法

constraint con{

  delay dist {0:/10};
}

上述写法可能导致constraint很难解,不要用上述写法。

 


2. 对与求和的约束的写法(防止和溢出)

bd_len_q.sum with(int'(item)) == 20

3. 数组元素不重复

class A;
  rand bit [31:0] arr[];

  constraint arr_size { arr.size() inside {[10:15]}; }
  constraint arr_uniq { unique {arr}; }

endclass

//------------------------------------------------------------------------
//solution2

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

//------------------------------------------------------------------------
//solution 3

class UniqueRandc;
	randc bit[7:0] val;
endclass

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

4. 二维数组的约束

class A;
 
   rand bit [11:0] width [];
   rand bit [11:0] height [];
 
   rand bit [11:0] rows_cols [][];
 
   constraint width_cst {
      width.size() inside{[100:5]};
      height.size() inside {[200:700]};}
 
   constraint c {rows_cols.size() == width.size();
      foreach(rows_cols[ii])
              rows_cols[ii].size == height.size();
   }
   constraint each_element {foreach(rows_cols[ii,jj])
                         rows_cols[ii][jj] inside {[1:255]};}

endclass

5.多个数组相互关联

  有三个数组,每个元素的取值范围是1-9,三个数组的和是100,三个数组中5的个数不能超过10个。

  此类问题的核心解法: 分步求解

class multi_queue_con;

rand int q1_sum;
rand int q2_sum;
rand int q3_sum;
rand int q1_size;
rand int q2_size;
rand int q3_size;
rand bit[4:0] q1[];
rand bit[4:0] q2[];
rand bit[4:0] q3[];

constraint c_sum{
  q1_sum + q2_sum + q3_sum < 100;

  q1.sum() with(int'(item)) == q1_sum;
  q2.sum() with(int'(item)) == q2_sum; 
  q3.sum() with(int'(item)) == q3_sum;

  q1.size() == q1_size;
  q2.size() == q2_size; 
  q3.size() == q3_size;
}

 针对“三个数组中5的个数不能超过10个”有两种方案:

1. 三个数组中在randomize时就让 item != 5,randomize后再向数组中填充或替换5;

constraint c_item{
  foreach(q1[ii]){
    q1[ii] inside {[1:4],[6:9]};
  }
   foreach(q2[ii]){
    q2[ii] inside {[1:4],[6:9]};
  }
 foreach(q3[ii]){
    q3[ii] inside {[1:4],[6:9]};
  }
}



function post_randomize();
  .../完成插入5或替换5,(替换策略:由于sum有约束,所以找数组中小于5的元素进行替换)


endfunction

2. 把5的权重调低点,多randomize几次,直到符合要求。

constraint c_item{
  foreach(q1[ii]){
    q1[ii] dist {[1:4]:=10,5:=5,[6:9]:=10};
  }
   foreach(q2[ii]){
    q2[ii] inside {[1:4]:=10,5:=5,[6:9]:=10};
  }
 foreach(q3[ii]){
    q3[ii] inside {[1:4]:=10,5:=5,[6:9]:=10};
  }
}


//in seq
int tq[$];
`uvm_create_on(vseq)
s_seq.new_trans.randomize()with{};

while(1)begin
  tq = s_seq.new_trans.find_index with(item ==5);
  if(tq.size()>10)
    s_seq.new_trans.randomize()with{};
  else
    break;
end
 

`uvm_send(vseq)

数独求解

class sudoku#( int M = 3 ); // M >= 1
  localparam N = M * M;
  local int unsigned puzzle[N][N];
  rand  int unsigned box   [N][N];
 
  // The value of each box must be between 1 and N.
 
  constraint box_con {
    foreach ( box[row, col] ) {
      box[row][col] inside { [ 1 : N ] };
    }
  }
 
  // The boxes on the same row must have unique values.
 
  constraint row_con {
    foreach   ( box[row, colA] ) {
      foreach ( box[   , colB] ) {
        if ( colA != colB ) { 
          box[row][colA] != box[row][colB];
        }
      }
    }
  }
 
  // The boxes on the same column must have unique values.
 
  constraint column_con {
    foreach   ( box[rowA, col] ) {
      foreach ( box[rowB,    ] ) {
        if ( rowA != rowB ) {
          box[rowA][col] != box[rowB][col];
        }
      }
    }
  }
 
  // The boxes in the same MxM block must have unique values.
 
  constraint block_con {
    foreach   ( box[rowA, colA] ) {
      foreach ( box[rowB, colB] ) {
        if ( rowA / M == rowB / M && 
             colA / M == colB / M && 
             ! ( rowA == rowB && colA == colB ) ) {
          box[rowA][colA] != box[rowB][colB];
        }
      }
    }
  }
 
  // The box must have the same value as the puzzle's if specified (!=0).
 
  constraint puzzle_con {
    foreach ( puzzle[row, col] ) {
      if ( puzzle[row][col] != 0 ) {
        box[row][col] == puzzle[row][col];
      }
    }
  }
 
  // Sudoku solver
 
  function int solve_this( int unsigned puzzle[N][N] );
    this.puzzle = puzzle;
    return this.randomize();
  endfunction: solve_this
 
  // Print the solution.
 
  function void print();
    for ( int i = 0; i < N; i++ ) begin
      if ( i % M == 0 ) $write( "\n" );
      for ( int j = 0; j < N; j++ ) begin
        if ( j % M == 0 ) $write( " " );
        $write( "%3d", box[i][j] );
      end
      $write( "\n" );
    end
  endfunction: print
 
endclass: sudoku

 

  • 11
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值