Verilog语言之向量vector和解压缩数组unpacked array

今天在HDLbits网站学习的时候遇到一个有趣的东西,记录一下,也是第一次翻译文章。

为了更加方便操作,将相关联的信号用一个名字组成向量。比如,wire [ 7:0 ] w ; 声明了一个8位的向量w,这等价于w拥有8根分离的线。

声明向量

向量必须被声明:  类型  [ 最高位:最低位 ]  向量名字

类型指的是向量的数据类型,最常用的是wire和reg。当声明输出或输入端口时,类型除数据类型外,还包括端口类型。比如:

wire [7:0] w;         // 8位wire
reg  [4:1] x;         // 4位reg
output reg [0:0] y;   // 1位输出端口reg(仍是向量)
input wire [3:-2] z;  // 6位输入wire(允许负数范围)
output [3:0] a;       // 4位输出wire。未声明类型时默认为wire
wire [0:7] b;         // 8位wire,b[0]为最高有效位

向量的字节顺序(或者通俗的来说,方向)决定了最低有效位是较低的指针(小端:[ 3:0 ])还是较高的指针(大端:[ 0:3 ])。在Verilog中,一旦向量被声明为特定的字节顺序,被使用时也必须以这个顺序。比如,声明为wire [3:0] vec时,在代码中如果出现vec[0:3] 则是非法的。和声明时的字节顺序保持一致是一个很好的习惯,因为如果使用不同的字节顺序去赋值或者使用将会出现奇怪的bugs。

 

隐式网络

隐式网络经常是很难发现的bugs来源之一。在Verilog中,网络类型信号可以通过2种方式被隐含的创造出来,一是赋值语句,二是被附加到未被声明的模块端口上。隐式网络总是1位wire类型,并且在你试图使用一个向量时出现bugs。可以使用“default_nettype none“指令禁用隐式网络的创建。

wire [2:0] a,c;     // 2个向量
assign a = 3'b101;        // a = 101
assign b = a[1:1];      // b = 1 隐含的被创造出wire类型
assign c = b; // c = 001 <--bug 结果不是想传递的a的值
my_module i1(d,e);      // 如果没有声明,d和e就是隐含的一位宽,如果端口是一个向量将会出现bug

添加 "default_nettype none "指令会使第三行报错,这会使bug更加明显。

 

解压缩数组和压缩数组

你可能已经注意到了在声明中,向量的指针写在向量名字的前面。这声明了数组的“压缩”维度,这些位宽被压缩为一团(只和仿真有关,和硬件没有关系),解压缩维度声明在向量名字的后面。以上通常用来声明内存数组。真正的压缩数组用于systemVerilog中,使用bit数据类型,了解更多传送门http://www.asic-world.com/systemverilog/data_types10.html

reg [7:0] mem [255:0];   // 256 个解压缩元素,其中每一个都是8位reg类型向量
reg mem2 [28:0];         // 29 个解压缩元素,其中每一个都是1位reg类型向量

 

访问向量元素:部分选择

访问一整个向量可以用向量的名字,例如:

assign w = a;

将整个4位向量a赋值给整个8位向量w。如果左右位宽不匹配,将会适当的用0扩充或者截断。

访问一个向量的一部分时可以用部分选择操作:

w[3:0]      // 只有w的低4位
x[1]        // x的最低位
x[1:1]      // 同上
z[-1:-2]    // z的最低2位
b[3:0]      // 非法的,向量的部分选择必须和声明的方向相匹配
b[0:3]      // b的“高”4位
assign w[3:0] = b[0:3];    //把b的高4位赋给w的低4位 w[3]=b[0], w[2]=b[1]等等

你可能感兴趣的:(HDLBits)