浅谈IC设计中的位宽不匹配的危害

01 位宽不匹配
verilog编码中,常见的位宽不匹配错误,有赋值左右位宽不匹配(《=,=),比较位宽(》,《,》=,《=)不匹配,计算位宽(+,-)不匹配
位宽不匹配会导致dc之后的网表与预期差异较大,导致功能不正确,通过spyglass lint检测可以发现所有位宽不匹配的情况,而vcs编译只能发现少数连线位宽不匹配的情况。
02 位宽不匹配的危害
下文以比较位宽不匹配为例,讲解位宽不匹配的危害。
注意:
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
跨时钟模块错用软复位造成的危害
01 配置信号跨时钟要求使用硬复位
在ic设计中,硬复位用于配置寄存器和配置信号的跨时钟模块。即一个配置信号cfg_mac_mode是由硬复位驱动的,如果要同步到其他时钟域,跨时钟模块需要使用硬复位,而不能使用软复位。
02    配置信号跨时钟错用软复位的危害
而在上电复位过程中,硬复位和软复位一般处于复位状态,需要依次释放,一般先释放硬复位,配置好配置信号,然后才释放软复位。
正确设计:
采用硬复位做为同步跨时钟模块的复位信号,跨时钟同步的配置信号在软复位释放前已经保持稳定,在软复位释放后,数据流进入模块的时候,不会随数据流一块跳变。
错误设计:
采用软复位做为同步跨时钟模块的复位信号,只有当软复位释放后才能变成我们期待的值,因此,在软复位释放后,数据流进入模块的时候,同步后的配置信号会随数据流一块跳变,造成功能错误。
来源:
https://blog.csdn.net/icxiaoge/article/details/93305256
https://blog.csdn.net/icxiaoge/article/details/102632152

MCU国产替代之路还有多远?便宜好用是王道
怎样用PC或手机远程控制树莓派
推荐清单:图像识别、机器学习和预测等有关的50多个API
C语言中定义4个内存区间
不止中国,iPhone 12系列的生产地点还包括巴西和印度
浅谈IC设计中的位宽不匹配的危害
高频头基本原理
聊聊Spartan-7到底有哪些特色与优势
预测:2021年自发光Micro LED电视有望问世
华为全联接大会2023|华为面向中小企业发布四大产品组合,构建高品质联接
汽车电子的发展对于集成电路有什么影响
车路协同技术的优势、进展和挑战!
代币发售(ICO)难分清?人工智能”火眼金睛”帮你轻松搞定!
清华大学首次实现具有亚1纳米栅极长度的晶体管
全音域空间音频技术打造“360°强劲立体声场”,览邦让科技更无界
RFID技术在远程监控系统中的应用
土壤肥料养分速测仪的测试项目
4K电视普及浪潮来袭 推动4K生态系统发展
初识FPGA CLB之LUT实现逻辑函数
简易磁感应线圈磁性检测装置