Verilog向量片选+变量隐式声明的危害
变量的隐式声明是 Verilog 中 BUG 的一大来源。
信号变量有两种声明方式:
1. 一是使用 wire 或者 assign 语句进行显示声明和定义;
2. 二是综合器的隐式声明和定义;
当你将一个未定义声明的信号连接到模块的输入输出端口时,综合器会热心地帮助你声明这个信号;
但综合器没有厉害到能通过上下文察言观色,“热心而正确”地帮你声明信号;
它只会将其声明为 1 bit wire 型信号!
当你本来需要使用一个超过 1 bit 的向量,但又忘记声明时,综合器往往就好心办坏事了。
(当然综合器会在这个生成 Warning,所以查看下 Warning 是查找 BUG 的好办法)
wire [2:0] a, c; // Two vectors
assign a = 3'b101; // a = 101
assign b = a; // b = 1 隐式声明并定于了 b
wire assign c = b; // c = 001 <-- bug 来了 b 被 coder 默认为和 a 相同的 3'b101,
但其实 b 只有 1bit宽
my_module i1 (d,e); // d e 都被隐式声明为 1bit wire
//如果模块期望的是 vector 那么 BUG 就产生了
隐式声明的错误很容易在连接 IP 核的时候产生,从 IP 核模板文件复制来 IP 核模块后。
往往会忘记声明连接 IP 模块之间的中间变量,而这些变量的隐式声明就可能被综合器“好心办了坏事”。
通过添加default_nettype none
宏定义会关闭隐式声明功能,
那么这样一来,使用未声明的变量就会变成一个 Error 而不再只是 Warning。
reg [7:0] mem [255:0]; // 256 unpacked elements, each of which is a 8-bit packed vector of reg.
reg mem2 [28:0]; // 29 unpacked elements, each of which is a 1-bit reg.
简单得说定义在向量名之前的是向量的位宽,定义在向量名之后的维度可以理解为向量数组的长度;
同 C 语言中的数组长度概念相同,一般用来对存储器建模。
获取向量元素:片选
- 在 assign 赋值操作中,如果等号左右两侧信号的位宽不同,那么就会进行截断或者补零操作;
- 左侧信号位宽大于右侧信号位宽,右值的低位赋予左值对应的低位,左值高位的部分赋零;
- 左侧信号位宽小于右侧信号位宽,右值的低位赋予左值对应的低位,右值高位的部分直接被截断。即保留右值的低位;
使用 [ ] 可以对信号进行片选,选择信号中特定几位比特,以下是一些片选的例子:
w[3:0] // Only the lower 4 bits of w
x[1] // The lowest bit of x
x[1:1] // ...also the lowest bit of x
z[-1:-2] // Z 最低两位
b[3:0] // 如果 b 在声明时 声明为 wire [0:3] b;则不能使用 b [3:0]进行选择
b[0:3] // b的高四位.
assign w[3:0] = b[0:3]; // 将 b 的高位赋予 w 的低位 w[3]=b[0], w[2]=b[1], etc.
版权声明:本文为weixin_42535005原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。