Verilog 学习笔记 02 - Verilog 中的向量
向量(Vector)的基本用法
之前使用 [[01 - Verilog 基础语法#Wire 类型和 Assign 关键字 |wire]] 关键字声明的变量都是一比特的,想要声明多比特的变量就要用到向量,比如 wire[7:0] w 就声明了一个 8bit 的 wire 向量,可以表示一个 8 位宽的地址总线。同时,也可以把向量中的某一位分配到端口上(想象下从总线上分出一路线来),比如 assign out = w[0]。
也可以用连接运算符将数个端口接到总线上,比如
1  | wire[0:2] bus;  | 
向量的细节
1  | wire [7:0] w; // 8bit wire 小端序  | 
向量的字节顺序(Endianness)区分大端序(Big Endian)[lower, upper] 与小端序(Little Endian)[upper, lower],对于同一个变量,端序必须一致,在同一项目中最好保持一致。
例如,对于数据 1A2B3C4D:
内存地址增长方向====>
- 大端序:1A2B3C4D
 - 小端序:D4C3B2A1
 
向量切片
可以通过切片访问向量的一部分:
1  | w[3:0] // w 的低四位  | 
避免隐式连接
看下面的例子:
1  | wire [2:0] a, c; // Two vectors  | 
在这个例子中,a 是一个 3bit 的 wire 向量,而 b 只是个 1bit 的 wire 变量,所以将 a 分配到 b 时,b 只被分配了 a[0],再将 b 分配到 3bit wire 向量 c 时,c 只能是 001 而非 101。
在模块文件中添加:
1  | 
来使上述代码中的第二行报错。
封装与未封装的数组(Unpacked Vs. Packed Arrays)
1  | reg [7:0] mem [255:0];  | 
封装定义在名称前,表示有多少位被“打包”在一起,未封装定义在名称后,通常用于定义内存数组。
按位运算与逻辑运算
[[01 - Verilog 基础语法#按位操作符]] 中提到了按位运算,此外,还有一种逻辑运算符:逻辑非 !、逻辑和 &&、逻辑或 ||,没有逻辑异或。
对于 1bit 的值而言,按位运算和逻辑运算的结果并无区别,但对于向量而言,逻辑运算会将整个向量当作布尔值处理,非零值为 True,零值为 False,并只输出一个 1bit 布尔值。按位运算符则将两个 N bit 的值按位做运算,返回的也是一个 N bit 的向量。
从上图可以看出按位或与逻辑或的区别。
向量的连接
可以用连接运算符 {a, b, c} 将向量连接在一起。
1  | wire [2:0] a, b;  | 
连接运算符可以在赋值的左右两侧使用。
1  | input [15:0] in;  | 
向量的复制
与连接运算符类似,可以使用复制运算符复制向量(同时扩充长度)。
1  | {5{1'b1}}  |