天天看點

IC設計錯誤案例001:位寬不比對的錯誤

1、位寬不比對

Verilog編碼中,常見的位寬不比對錯誤,有指派左右位寬不比對(<=,=),比較位寬(>,<,>=,<=)不比對,計算位寬(+,-)不比對

位寬不比對會導緻DC之後的網表與預期差異較大,導緻功能不正确,通過spyglass lint檢測可以發現所有位寬不比對的情況,而vcs編譯隻能發現少數連線位寬不比對的情況。

2、位寬不比對的危害

下文以比較位寬不比對為例,講解位寬不比對的危害。

注意:

1) 在條件判斷中(if語句),不建議使用加減後結果直接進行比較,禁止進行加減運算後與位寬不比對的資料/變量進行比較。

2) 拼接符号中“{}”,不允許使用加減乘除等運算,綜合類軟體無法正确判斷資料運算結果位寬。數字運算必須先通過wire指定位寬,然後通過assign得到運算結果

錯誤案例1

如下代碼,代碼本意是:當cnt0與cnt1之和大于8的時候,count加1。

錯誤代碼中:

比較資料是4’h8,此時綜合完成後的網表中,會将cnt0與cnt1之和截位成4bit,再與4’h8比較,如果cnt0與cnt1之和為5’h10000,在此會截位為4’h0000,反而小于4’h8,與預期功能不符

正确代碼&推薦代碼中:

先定義:wire [4:0] cnt_add ; 指定cnt_add位寬為5bit,然後assign  cnt_add  = (cnt0+cnt1) ;最後與5’h8比較,因為通過wire指定了位寬,是以對于各類綜合軟體而言都不會發生截位,不會發生錯誤。

正确代碼&不推薦中

直接将4’h8修改為5’h8,也避免了cnt0+cnt1累加截位,但是spyglass lint會報warning,

不推薦。

reg  [3:0]   cnt0  ;
reg  [3:0]   cnt1  ;
reg  [4:0]   count ;
reg          ov_nc ;

//-------------case 1-----------------
//wrong code  
always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
		count     <= 5'b0 ;
    end 
    else if((cnt0+cnt1)>4'h8) //should be 5'h8
		begin
       {ov_nc, count} <= count +1'b1;
    end 
//right  ,but not recommended
always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
		count     <= 5'b0 ;
    end 
    else if((cnt0+cnt1)>5'h8) //should be 5'h8
		begin
       {ov_nc, count} <= count +1'b1;

//right code and recommended  正确且推薦
wire [4:0] cnt_add ;
assign  cnt_add  = (cnt0+cnt1) ;

always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
		count     <= 5'b0 ;
    end 
    else if(cnt_add >5'h8) // (cnt0+cnt1) is 5 bits
		begin
         {ov_nc, count} <= count +1'b1;
    end 
           

錯誤案例2

NOTE: 拼接符号中“{}”,不允許使用加減乘除等運算,綜合類軟體無法正确判斷資料運算結果位寬。數字運算必須先通過wire指定位寬,然後通過assign得到運算結果。

錯誤代碼中:

{1'b0,(cnt0+cnt1)} ,在if語句()拼接符号中,綜合軟體無法識别 (cnt0+cnt1)應該是多少bit,(cnt0+cnt1)可能會是5bit,也可能是4bit。

正确代碼&推薦代碼中

通過 wire [4:0] cnt_add ;  assign  cnt_add  = (cnt0+cnt1) ; 指定了(cnt0+cnt1)之和為5bit,利用拼接符指定{1'b0,cnt_add}為6bit,然後與6bit的cnt2比較。

正确代碼&不推薦中

通過 wire [4:0] cnt_add ;  assign  cnt_add  = (cnt0+cnt1) ; 指定了(cnt0+cnt1)之和為5bit,但是直接與6bit的cnt2比較,各類綜合軟體也會正确識别位寬,不會發生截位,但是spyglass lint會報warning,雖然功能正确,但是不推薦。

//-------------case 2-----------------//
 reg  [3:0]   cnt0  ;
 reg  [3:0]   cnt1  ;
 reg  [5:0]   cnt2  ;
 
 //wrong code
 always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
		count     <= 5'b0 ;
    end 
    else if({1'b0,(cnt0+cnt1)}<cnt2) //
		begin
       {ov_nc, count} <= count +1'b1;
    end 
	
//right code and not recommended  正确不推薦
wire [4:0] cnt_add ;
assign  cnt_add  = (cnt0+cnt1) ;

 always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
		count     <= 5'b0 ;
    end 
    else if(cnt_add<cnt2) //
		begin
       {ov_nc, count} <= count +1'b1;
    end 

//right code and recommended  正确且推薦
wire [4:0] cnt_add ;
assign  cnt_add  = (cnt0+cnt1) ;

 always @ (posedge clk or negedge rst_n) 
    if(!rst_n)begin
		count     <= 5'b0 ;
    end 
    else if({1'b0,cnt_add}<cnt2) //
		begin
       {ov_nc, count} <= count +1'b1;
    end 
           

繼續閱讀