Verilog 数据类型
wire(线)
表示硬件单元之间的连线,由其连接的器件输出端连续驱动。如果没有驱动元件连接到wire型变量,缺省值一般位Z.
wire interrupt;
wire flag1,flag2;
wire gnd = 1'b0;
线网还有其他的一些数据类型,但是使用频率不高,包括wand、wor、wri、triand、trior、trireg,这些类型的使用频率不高,这里不做介绍。
reg(寄存器)
reg用于表示存储单元,会保持数据原有的值,直到被改写。举例如下:
reg clk_tmp;
reg flag1,flag2;
reg的值可在任意时刻通过赋值操作进行改写,如:
reg rstn;
initial begin
rstn = 1'b0;
#100 ;
rstn = 1'b1;
向量
位宽大于1时,wire或reg即可声明为向量的形式,如:
reg [3:0] counter;
wire[32-1:0] gpio_data;
wire[8:2] addr; //声明7bit位宽的线型变量addr,位宽范围为8:2
reg[0:31] data;
reg [msb:lsb] variable;
其中msb不必大于lsb,[31:0]和[0:31]开始的作用域不同。
对于上面的向量,我们可以指定某一位或者若干相邻位,作为其他逻辑使用
wire [9:0] data_low = data[0:9];
addr_tmp [3:2] = addr[8:7] + 1'b1;
还支持可变的向量域选择,如:
reg [31:0] data1;
reg [7:0] byte1 [3:0];
integer j;
alawys@* begin
for (j=0;j<=3;j=j+1) begin
byte1[j]=data1[(j+1)*8-1:j*8]
//把data1[7:0]...data1[31:24]依次赋值给byte1[0][7:0]...byte1[3][7:0]...
end
end
Verilog还支持指定bit位后固定位宽的向量域选择访问。
[bit+:width]:从起始bit位开始递增,位宽width[bit-:width]:从起始bit开始递减,位宽width
A = data1[31-:8];
A = data1[31:24];
//二者等价
B = data1[0+:8];
B = data1[0:7];
对信号重新组合成新的向量时,需要借助大括号,如:
wire [31:0] temp1,temp2;
assign temp1 = {byte1[0][7:0],data1[31:8]};//数据拼接
assign temp2 = {32{1'b0}};//赋值32bit的数值0
整数、实数、时间寄存器变量
这些也属于寄存器类型的数据类型
整数 integer
使用关键字integer来声明,不用指明位宽,位宽和编译器有关,一般为32bit,reg型变量位无符号数,而integer型为有符号数。如:
reg [31:0] data1;
reg [3:0] byte1 [7:0];
integer j;
always@* begin
for (j=0;j<=3;j=j+1) begin
byte1[j] = data1[(j+1)*8-1:j*8]
end
end
实数 real
实数用关键字real来声明,可用十进制或是科学计数法来表示。实数声明不能带有范围,默认值为0.如果将1个实数赋值给1个整数,则只有实数的整数部分会被赋值给整数。如:
rael data1;
integer temp;
initial begin
data1 = 2e3;
data1 = 3.75;
end
initial begin
temp = data1;//tmp的值为3
end
时间time
Verilog使用时间寄存器time型变量,对仿真时间进行保存,宽度一般为64bit,通过调用系统函数$time来获取当前仿真时间,如:
time current_time;
initial begin
#100;
current_time = $time;
end
数组
Verilog允许声明reg、wire、integer、time、real及其向量类型的数组。
数组的维度没有限制,可以用用于连接实例模块的端口。数组中的每个元素都可以作为1个标量或者向量来使用,形如:<数组名>[<下标>],对于多为数组,用户需要说明每一个维度的索引
integer flag [7:0];//8个整数组成的数组
reg [3:0] counter [3:0];//4个bit计数器组成的数组
wire [7:0] addr_bus[3:0];//4个8bit wire组成的数组
wire data_bit[7:0][5:0];//2维数组
reg [31:0] data_4d[11:0][3:0][3:0][255:0];//声明4维的32bit数据变量数组
对于数组元素的赋值
flag [1] = 32'd0;
counter[3] =4'hF;
counter[3][3:0] = 4'hF;
assign addr_bus[0] = 8'b0;
assign data_bit[0][1] = 1'b1;
data_4d[0][0][0][0][15:0] = 15'd3;
向量是1个单独的元件,位宽是n;
数组由多个元件组成,其中每个元件的位宽为n或者1。
存储器
就是一种寄存器数组,用于描述RAM或者ROM的行为,如:
reg membit[0:255];
reg [7:0] mem[0:1023];
mem[511] = 8'b0;
参数
参数常用于表示常量,用关键字parameter声明,只能赋值1次。如
parameter data_width = 10'd32;
parameter i=1,j=2,k=3;
parameter mem_size = data_width*10;
局部参数用关键字localparam来声明,作用和用法与parameter相同,区别在于值不能被改变,所以参数只在本模块中调用时,可用localparam来说明。
字符串
字符串保存在reg类型的变量中,每个字符占用1个字节(8bit),因此寄存器的宽度应该足够大,从而保证不会溢出。
字符串不能多行书写,即字符串中不能出现回车符。如果寄存器变量的宽度大于字符串的宽度,则多余的左边位会自己补0,如果寄存器变量的宽度小于字符串大小,则会截取去字符串左边多余的数据。如:
reg [0:128-1] str;
initial begin
str = "Here are The world"
end
一些特殊字符在显示字符串中由特殊的含义。
| 转义字符 | 显示字符 |
|---|---|
| \n | 换行 |
| \t | 制表符 |
| %% | % |
| \ | \ |
| ” | ” |
| \ooo | 1到3个8进制数字字符 |