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}} |