Verilog 继承了C语言的多种操作符和结构,与硬件描述语言VHDL相比,代码更简洁,更易上手。
二、向量部分
当位宽大于1时,wire型或reg型便可声明为向量的形式。例如:
wire [99:0] my_vector; //声明100bit位宽的线型变量my_vector
reg [3:0] x; //声明4bit位宽的寄存器x
1、向量声明
type [upper:lower] vector_name;
type是指向量的数据类型,通常为wire型或reg型。如果声明的是输入、输出向量,类型前还可以加上input和output,如下所示:
input wire [3:0] x; //4bit位宽wire型,也是输入端口
output reg [3:0] y; //4bit位宽寄存器,也是输出端口
向量声明时,数字的顺序很重要,它决定了向量是以大端存储还是小端存储。若声明wire [3:0] w; 则w[0]为w的最低位,w[3]为w的最高位。若声明wire [0:3] w; 则w[3]为w的最低位,w[0]为w的最高位。所以在向量的定义和使用时一定要保持大小端一致。
需要注意:向量名前为维度,向量名后为数目,不写统一视作1。
reg [7:0] mem [255:0]; //256个未定义的元素,每一个元素都是8bit寄存器型向量
reg mem2 [28:0]; //29个未定义的元素,每一个元素都是1bit寄存器型向量
2、向量元素:部分选择
访问整个向量是使用向量名完成的,如果左右两边的长度不匹配,可以适当地进行零扩展或截断。取用向量中特定维度的数时,一定注意要与向量的定义一致,注意大小端匹配的问题。在向量赋值的左右两端都可以选择对部分数据进行操作。
向量中的任意位(向量索引范围内)都可以被单独选择,并且可以对其单独赋值。
wire [3:0] my_vector; //声明4bit位宽的线型变量my_vector
my_vector[0] = 1; //将1赋值给my_vector的0bit位宽处
my_vector[2] = 0; //将0赋值给my_vector的2bit位宽处
同时还可以进行范围选择,对选择的连续范围相邻的多位进行赋值。
reg [31:0] vector; //声明32bit位宽的寄存器vector
vector [23:16] = 8'h23; //寄存器vector的23bit至16bit被赋值'h23
当然还支持指定bit位后固定位宽的向量域选择访问,如下:
[bit+ : width] 从起始bit位开始递增,位宽为width。
[bit- : width] 从起始bit位开始递减,位宽为width。
举例如下:
//以下两者赋值是等效的
a = w[16-:5];
a = w[16:12];
//以下两者赋值是等效的
b = w[0+:8];
b = w[0:7];
注意!!! Verilog中的向量与数组是两个不同的概念,别混为一谈了。reg [3:0] a 表示一个4bit位宽的向量;reg a [3:0]表示一个数组,数组中的元素都是1bit变量。我们可以对整个向量进行赋值,也可以对某位向量进行赋值,不能对整个数组进行直接赋值,只能对数组的某个变量或者数组的某个变量的某些位赋值。
3、向量逻辑和按位运算
在刷题笔记整理(1)中我们提到了各种布尔运算符的按位和逻辑运算。在使用向量时,两种运算符类型之间的区别变得很重要。两个N bit位宽的向量,按位操作输出为N bit位宽向量;然而逻辑操作是将整个向量看作布尔值(true=非零,false=零),并产生一个1bit的输出。
4、向量连接(拼接)操作
向量连接操作需要明确知道带连接的各向量的位宽比特数,不然不知道连接操作结果的位宽。所以{1,2,3}是非法的、错误的。
向量的连接操作在赋值语句的左右两端都可以实现,最好左右两端位宽相同,否则未被指定的数据会被置零。
连接操作符用大括号{ , }来表示,用于将多个向量(操作数)连接起来,信号之间用逗号隔开(英文逗号)。连接向量必须指定位宽,常数也需要指定位宽。如:
a = 4'b1100;
b = 1'b1;
y = {b, a[3:1], 4'h3}; //连接结果为y1 = 8'b1110_0011,二进制用b表示,八进制用o表示,十进制用d表示,十六进制用h表示
5、向量翻转
向量翻转很好理解,如给定一个8bit输入向量[7:0],颠倒它的位顺序即可。也即是最低位变成最高位,依次颠倒。
注意:直接assign out[7:0] = in[0:7]是不对的,因为Verilog不允许翻转向量位排序。
正确方法如下:
module top_module(
input [7:0] in,
output [7:0] out
);
assign out[7:0] = {in[0], in[1], in[2],in[3],in[4],in[5],in[6],in[7]};
endmodule
6、向量复制
向量复制操作允许重复一个向量并将它们连接在一起,操作语句:{num{vector}},num表示复制几次,vector表示待操作向量。复制向量有捷径,花括号外面带数字,主要用于符号位的拓展。比如4’b0101带符号拓展为8bit的话为8’b00000101,4’b1101带符号拓展为8bit的话为8’b11111101。
{5{1'b1}}; //结果为5'b11111
{2{a, b, c}}; //结果为{a, b, c, a, b, c}
以上是HDLBits Verilog语言刷题网站中的Vectors部分,后续部分会继续更新。对一些基础性知识点进行归纳总结,有错误请指正。仅供学习参考,谢谢!!!