注意:后续技术分享,第一时间更新,以及更多更及时的技术资讯和学习技术资料,将在公众号CTO Plus发布,请关注公众号:CTO Plus
在Verilog中,有多种数据类型可供使用,包括位向量类型、整数类型、实数类型、布尔型、时间类型和字符串类型等。下面详细介绍Verilog的所有数据类型、常量和变量的定义和使用方法。
整型和实型用于表示数字,布尔型用于表示逻辑值。向量型用于表示多位数据,例如:
reg [7:0] data; // 8位向量型寄存器
wire [3:0] addr; // 4位向量型线网
Verilog中的变量有线网类型和寄存器类型。线网型变量综合成wire,而寄存器可能综合成WIRE,锁存器和触发器,还有可能被优化掉。
以下将详细介绍FPGA设计中Verilog数据类型的定义、作用、特点和详细的代码示例。
bit类型用于表示单个二进制位。在FPGA设计中,bit类型通常用于表示FPGA的输入输出、寄存器等信号的值。
作用:用于表示单个比特位(二进制位),只能取0或1。
特点:占用存储空间最小。
代码示例:
module bit_module (
input bit a,
input bit b,
output bit c
);
assign c = a & b;
endmodule
logic类型用于表示逻辑值。在FPGA设计中,logic类型通常用于表示数据的真假值。与bit类型不同的是,logic类型可以取三态逻辑值(0、1、X),可用于检测与模拟器中的信号值。
作用:用于表示单个比特位,可以取0、1、X、Z、L、H等值。
特点:适用于仿真和综合。
代码示例:
module logic_module (
input logic a,
input logic b,
output logic c
);
assign c = a & b;
endmodule
reg类型用于表示可赋值的寄存器。在FPGA设计中,reg类型通常用于存储逻辑电路中的状态(状态机的状态)或者存储数据(RAM控制器的数据缓存区)。
作用:用于表示存储器或寄存器中的数据,可以在always块中赋值。
特点:只能在always块中赋值。
代码示例:
module reg_module (
input bit a,
input bit b,
output reg c
);
always @(a or b)
begin
c = a & b;
end
endmodule
在“always”块内被赋值的每一个信号都必须定义成reg型。
reg型数据的缺省初始值是不定值。
reg型只表示被定义的信号将用在“always”块内,理解这一点很重要。并不是说reg型信号一定是寄存器或触发器的输出。虽然reg型信号常常是寄存器或触发器的输出,但并不一定总是这样。
wire类型用于连接模块中的端口。在FPGA设计中,wire类型通常用于模块之间的信号连接,如模块之间的输入输出信号连接。
作用:用于表示连线或线路中的数据,只能在模块实例化时赋值。
特点:只能在模块实例化时赋值。
代码示例:
module wire_module (
input bit a,
input bit b,
output wire c
);
and gate1(c, a, b);
endmodule
integer类型用于表示整数值。在FPGA设计中,integer类型通常用于计数器、延时器等电路中。
作用:用于表示整数。
特点:占用存储空间为32位。
代码示例:
module integer_module (
input integer a,
input integer b,
output integer c
);
assign c = a + b;
endmodule
time类型用于表示时间。在FPGA设计中,time类型通常用于表示延迟器、时钟周期等时间。
作用:用于表示时间。
特点:占用存储空间为64位。
代码示例:
module time_module (
input time a,
input time b,
output time c
);
assign c = a + b;
endmodule
real类型用于表示实数。在FPGA设计中,real类型通常用于表示浮点数的计算。
作用:用于表示实数。
特点:占用存储空间为64位。
代码示例:
module real_module (
input real a,
input real b,
output real c
);
assign c = a + b;
endmodule
realtime类型用于表示当前的时间。在FPGA设计中,realtime类型通常用于设计模拟器中,表示仿真当前的时间。
作用:用于表示实时数。
特点:占用存储空间为64位。
代码示例:
module realtime_module (
input realtime a,
input realtime b,
output realtime c
);
assign c = a + b;
endmodule
shortint类型用于表示带符号的16位整数值。在FPGA设计中,shortint类型通常用于计数器等电路中。
作用:用于表示短整数。
特点:占用存储空间为16位。
代码示例:
module shortint_module (
input shortint a,
input shortint b,
output shortint c
);
assign c = a + b;
endmodule
int类型用于表示带符号的32位整数值。在FPGA设计中,int类型通常用于计算逻辑、内部数据储存等。
作用:用于表示整数。
特点:占用存储空间为32位。
代码示例:
module int_module (
input int a,
input int b,
output int c
);
assign c = a + b;
endmodule
longint类型用于表示带符号的64位整数值。在FPGA设计中,longint类型通常用于精度要求很高的计算逻辑。
作用:用于表示长整数。
特点:占用存储空间为64位。
代码示例:
module longint_module (
input longint a,
input longint b,
output longint c
);
assign c = a + b;
endmodule
byte类型用于表示带符号的8位数值。在FPGA设计中,byte类型通常用于存储压缩和图像数据等。
作用:用于表示字节。
特点:占用存储空间为8位。
代码示例:
module byte_module (
input byte a,
input byte b,
output byte c
);
assign c = a + b;
endmodule
wand类型用于实现与逻辑。在FPGA设计中,wand类型适合表示AND电路。
作用:用于表示与非门输出的值。
特点:只能取0或1。
代码示例:
module wand_module (
input bit a,
input bit b,
output wand c
);
assign c = ~(a & b);
endmodule
wor类型用于实现或逻辑。在FPGA设计中,wor类型适合表示OR电路。
作用:用于表示或非门输出的值。
特点:只能取0或1。
代码示例:
module wor_module (
input bit a,
input bit b,
output wor c
);
assign c = ~(a | b);
endmodule
tri类型用于表示三态缓冲器。在FPGA设计中,tri类型适合表示总线信号。
作用:用于表示三态门输出的值。
特点:可以取0、1、Z、X等值。
代码示例:
module tri_module (
input bit a,
input bit b,
output tri c
);
assign c = a ? b : 1'bz;
endmodule
triand类型用于表示与逻辑+三态输出。在FPGA设计中,triand类型适合表示总线信号。
作用:用于表示三态与门输出的值。
特点:可以取0、1、Z、X等值。
代码示例:
module triand_module (
input bit a,
input bit b,
output triand c
);
assign c = a & b;
endmodule
trior类型用于表示或逻辑+三态输出。在FPGA设计中,trior类型适合表示总线信号。
作用:用于表示三态或门输出的值。
特点:可以取0、1、Z、X等值。
代码示例:
module trior_module (
input bit a,
input bit b,
output trior c
);
assign c = a | b;
endmodule
trireg类型用于表示三态输出+存储器。在FPGA设计中,trireg类型适合表示内存存储器控制器的数据输出。
作用:用于表示三态寄存器输出的值。
特点:只能在always块中赋值。
代码示例:
module trireg_module (
input bit a,
input bit b,
output trireg c
);
always @(a or b)
begin
c <= a ? b : 1'bz;
end
endmodule
supply0/supply1类型用于表示逻辑值。在FPGA设计中,用于保证在仿真器中存在的常量值(供电值)。
作用:用于表示电源和地。
特点:只能取0或1。
代码示例:
module supply_module (
input supply0 a,
input supply1 b,
output supply0 c
);
assign c = a & b;
endmodule
small类型用于表示带符号的8位整数值。
作用:small型是一种数据类型,用于表示带符号的8位整数值。在FPGA设计中,small型通常用于计数器等电路中。
特点:small型的取值范围为-128到127,占用8位二进制位。
代码示例:
module counter(
input clk,
input rst,
output reg [7:0] count
);
always @(posedge clk or posedge rst) begin
if(rst) begin
count <= 8'sd0;
end else begin
count <= count + 1;
end
end
endmodule
trio类型用于表示与或非逻辑组合,支持三态输出。在FPGA设计中,trio类型适合表示总线信号。
作用:trio型是一种数据类型,用于表示与或非逻辑组合,支持三态输出。在FPGA设计中,trio型适合表示总线信号。
特点:trio型的取值范围为0、1和Z,其中Z表示高阻态。
代码示例:
module tri_buffer(
inout tri [7:0] data,
input enable
);
assign data = enable ? data : 'z;
endmodule
large类型用于表示大整数值。在FPGA设计中,large类型通常用于高精度计算、加密解密等应用中。
作用:large型是一种数据类型,用于表示大整数值。在FPGA设计中,large型通常用于高精度计算、加密解密等应用中。
特点:large型的取值范围很大,可达到2^63-1。
代码示例:
module rsa(
input clk,
input [63:0] p,
input [63:0] q,
input [63:0] e,
input [63:0] m,
output reg [63:0] c
);
reg [127:0] n;
reg [127:0] d;
reg [127:0] phi;
reg [127:0] temp1;
reg [127:0] temp2;
always @(p or q) begin
n = p * q;
phi = (p - 1) * (q - 1);
end
always @(e or phi) begin
d = e^-1 % phi;
end
always @(posedge clk) begin
temp1 = m^e % n;
temp2 = temp1^d % n;
c <= temp1;
end
endmodule
signed类型用于表示带符号的整数值。在FPGA设计中,signed类型通常用于计算机算术运算、数字信号处理等应用中。
1. Verilog中signed型是一种数据类型,用于表示带符号的标量类型。
2. signed型通常用于表示带符号的数值类型,其取值范围为-2^(n-1)到2^(n-1)-1,其中n为位宽。
3. signed型的特点是可以进行带符号的运算,如加减乘除等。
4. signed型的代码示例:
代码示例
module signed_adder(
input signed [31:0] a,
input signed [31:0] b,
output reg signed [31:0] sum
);
always @(a or b) begin
sum = a + b;
end
endmodule
unsigned类型用于表示无符号的整数值。在FPGA设计中,unsigned类型通常用于计算机算术运算、数字信号处理等应用中。
作用:unsigned型是一种数据类型,用于表示无符号的标量类型。在FPGA设计中,unsigned型通常用于表示无符号的数值类型。
特点:unsigned型的取值范围为0到2^32-1。
代码示例:
module unsigned_adder(
input [31:0] a,
input [31:0] b,
output reg [31:0] sum
);
always @(a or b) begin
sum = a + b;
end
endmodule
enum类型用于表示枚举类型。在FPGA设计中,enum类型通常用于表示状态机的状态、控制信号等。
1. Verilog中enum型是一种数据类型,用于表示枚举类型。
2. enum型通常用于定义一组有限的取值范围,如状态机的状态等。
3. enum型的特点是可以使用可读性更高的名称来表示取值,而不是使用数字。
4. enum型的代码示例:
代码示例
typedef enum logic [1:0] {IDLE, READ, WRITE} state;
module state_machine(
input clk,
input reset,
output reg [1:0] current_state
);
state next_state;
always @(posedge clk, posedge reset) begin
if (reset) begin
current_state <= IDLE;
end else begin
case (current_state)
IDLE: next_state = READ;
READ: next_state = WRITE;
WRITE: next_state = IDLE;
endcase
current_state <= next_state;
end
end
endmodule
medium类型用于表示中等精度的整数值。在FPGA设计中,medium类型通常用于计算逻辑、内部数据储存等应用中。
作用:medium型是一种数据类型,用于表示中等精度的整数值。在FPGA设计中,medium型通常用于计算逻辑、内部数据储存等应用中。
特点:medium型的取值范围为-2^23到2^23-1。
代码示例:
module multiplier(
input clk,
input [23:0] a,
input [23:0] b,
output reg [47:0] p
);
always @(posedge clk) begin
p <= a * b;
end
endmodule
scalared类型用于表示带时间戳的信号值。在FPGA设计中,scalared类型通常用于仿真器中,用于记录仿真器中的信号值及其变化时间。
作用:scalared型是一种数据类型,用于表示带符号的标量类型。在FPGA设计中,scalared型通常用于表示带符号的数值类型。
特点:scalared型的取值范围为-2^31到2^31-1。
代码示例:
module signed_adder(
input signed [31:0] a,
input signed [31:0] b,
output reg signed [31:0] sum
);
always @(a or b) begin
sum = a + b;
end
endmodule
作用:tril型是一种数据类型,用于表示与逻辑+三态输出。在FPGA设计中,tril型适合表示总线信号。
特点:tril型的取值范围为0和Z,其中Z表示高阻态。
代码示例:
module tri_and(
inout tri out,
input [3:0] in
);
assign out = ∈
endmodule
作用:vectored型是一种数据类型,用于表示向量类型。在FPGA设计中,vectored型通常用于表示寄存器、存储器等。
特点:vectored型的取值范围为多个位,可以使用冒号(:)表示范围。
代码示例:
module reg_file(
input clk,
input [4:0] addr1,
input [4:0] addr2,
input [31:0] data_in,
output reg [31:0] data_out1,
output reg [31:0] data_out2
);
reg [31:0] regs [0:31];
always @(posedge clk) begin
regs[addr1] <= data_in;
regs[addr2] <= data_in;
end
assign data_out1 = regs[addr1];
assign data_out2 = regs[addr2];
endmodule
作用:parametr是一种数据类型,用于表示常量值。在FPGA设计中,parametr通常用于定义常量、参数等。
特点:parametr的值在编译时确定,不能被修改。
代码示例:
module adder(
input [7:0] a,
input [7:0] b,
output [7:0] sum
);
parameter WIDTH = 8;
assign sum = a + b;
endmodule
作用:real型是一种数据类型,用于表示浮点数类型。在FPGA设计中,real型通常用于模拟器中的仿真计算。
特点:real型的取值范围为IEEE 754标准的单精度浮点数。
代码示例:
module floating_point_multiplier(
input [31:0] a,
input [31:0] b,
output reg [31:0] product
);
real r_a;
real r_b;
real r_product;
always @(a or b) begin
r_a = $bitstoreal(a);
r_b = $bitstoreal(b);
r_product = r_a * r_b;
product = $realtobits(r_product);
end
endmodule
1. Verilog中memory型是一种数据类型,用于表示存储器类型。
2. memory型通常用于表示随机访问存储器(RAM)或只读存储器(ROM)。
3. memory型的特点是可以使用二维数组来表示存储器,其中第一维表示存储器的地址,第二维表示存储器的数据。
4. memory型数据是通过扩展reg型数据的地址范围来生成的。其格式如下:
reg [n-1:0] 存储器名[m-1:0];
或
reg [n-1:0] 存储器名[m:1];
在这里,reg[n-1:0]定义了存储器中每一个存储单元的大小,即该存储单元是一个n位的寄存器。存储器名后的[m-1:0]或[m:1]则定义了该存储器中有多少个这样的寄存器。
reg [7:0] mema[255:0];
这个例子定义了一个名为mema的存储器,该存储器有256个8位的存储器。该存储器的地址范围是0到255。注意:对存储器进行地址索引的表达式必须是常数表达式。
尽管memory型数据和reg型数据的定义格式很相似,但要注意其不同之处。如一个由n个1位寄存器构成的存储器组是不同于一个n位的寄存器的。见下例:
reg [n-1:0] rega; //一个n位的寄存器
reg mema [n-1:0]; //一个由n个1位寄存器构成的存储器组
一个n位的寄存器可以在一条赋值语句里进行赋值,而一个完整的存储器则不行。见下例:
rega =0; //合法赋值语句
mema =0; //非法赋值语句
如果想对memory中的存储单元进行读写操作,必须指定该单元在存储器中的地址。下面的写法是正确的。
mema[3]=0; //给memory中的第3个存储单元赋值为0。
memory型的代码示例:
module memory_controller(
input clk,
input [7:0] address,
input [7:0] write_data,
input read_enable,
input write_enable,
output reg [7:0] read_data
);
reg [7:0] memory [255:0];
always @(posedge clk) begin
if (write_enable) begin
memory[address] <= write_data;
end
if (read_enable) begin
read_data <= memory[address];
end
end
endmodule
在这个示例中,我们使用了一个256字节的存储器,每个字节都是8位宽。存储器的地址和写入数据都是8位宽,读取数据也是8位宽。我们使用了二维数组memory来表示存储器,其中第一维表示存储器的地址,第二维表示存储器的数据。在时钟上升沿处,如果写使能信号write_enable为高电平,我们将写入数据write_data写入存储器的地址address处。如果读使能信号read_enable为高电平,我们从存储器的地址address处读取数据,并将其输出到read_data信号上。
VerilogHDL数据类型是用来表示数字电路硬件中的数据储存和传送元素的。其中4个最基本的数据类型,它们是:reg类型、wire类型、integer类型和parameter类型。
其他的类型是:large类型、medium类型、scalared类型、time类型、small类型、tri类型、trio类型、tril类型、triand类型、trior类型、trireg类型、vectored类型、wand类型、wor类型。这14种数据类型除time型外都与基本逻辑单元建库有关,与系统设计没有很大的关系。
位向量类型是Verilog中最常用的数据类型之一,用于表示二进制数值。位向量类型包括有符号位向量(signed)、无符号位向量(unsigned)和逻辑位向量(wire)。位向量类型的定义语法格式如下:
//有符号位向量
reg signed [n-1:0] 变量名;
//无符号位向量
reg [n-1:0] 变量名;
//逻辑位向量
wire [n-1:0] 变量名;
其中,n为位数,可以是任意正整数。有符号位向量表示带符号的二进制数值,无符号位向量表示无符号的二进制数值,逻辑位向量表示逻辑电路的输出值。
整数类型用于表示整数数值,包括有符号整数类型(integer)和无符号整数类型(unsigned)。整数类型的定义语法格式如下:
//有符号整数
integer 变量名;
//无符号整数
integer unsigned 变量名;
其中,有符号整数表示带符号的整数数值,无符号整数表示无符号的整数数值。
实数类型用于表示实数数值,包括单精度实数类型(real)和双精度实数类型(realtime)。实数类型的定义语法格式如下:
//单精度实数
real 变量名;
//双精度实数
realtime 变量名;
其中,单精度实数表示单精度的实数数值,双精度实数表示双精度的实数数值。
时间类型用于表示时间数值,包括时钟周期类型(timescale)和时间类型(time)。时间类型的定义语法格式如下:
//时钟周期类型
`timescale 时间单位/时间精度
//时间类型
time 变量名;
其中,时间单位可以是ns、us、ms、s等,时间精度可以是1、10、100、1000等。时间类型表示时间数值,单位为时间单位。
字符串类型用于表示字符串数值,包括字符串类型(string)和文件类型(file)。字符串类型的定义语法格式如下:
//字符串类型
string 变量名;
//文件类型
file 变量名;
其中,字符串类型表示字符串数值,文件类型表示文件句柄。
Verilog HDL语言中也有常量和变量之分,它们分别属于以上这些类型。下面就最常用的几种进行介绍。
在VerilogHDL中,常量和变量都是用来存储数据的,定义和使用方法与其他编程语言类似。常量是指在程序中不可改变的变量(数据),而变量是可以改变的变量(数据)。常量和变量的定义语法格式如下:
//常量定义
parameter 常量名 = 常量值;
//变量定义
reg 变量名;
其中,常量名为常量的名称,常量值为常量的值,变量名为变量的名称。
常量和变量的使用方法如下:
//常量使用
常量名
//变量使用
变量名 = 值;
其中,常量名表示常量的值,变量名表示变量的值,值为常量值或变量值。
常量的定义和使用方法:
在VerilogHDL中,常量通常用`parameter`关键字定义。`parameter`定义的常量在编译时就确定了,不能在运行时修改。
常量的定义格式如下:
parameter
其中,`
常量的使用方法:
在VerilogHDL中,常量可以在任何地方使用,包括模块实例化、端口连接、赋值语句等。
例如,下面是一个使用常量的示例:
module my_module (
input [7:0] a,
input [7:0] b,
output [7:0] c
);
parameter WIDTH = 8;
assign c = a + b + WIDTH;
endmodule
在上面的示例中,定义了一个常量`WIDTH`,并在赋值语句中使用了它。
在程序运行过程中,其值不能被改变的量称为常量。以下为Verilog HDL语言中使用的数字及其表示方式。
数字
(1)整数在Verilog HDL中,整型常量即整常数有以下4种进制表示形式:
1)二进制整数(b或B);
2)十进制整数(d或D);
3)十六进制整数(h或H);
4)八进制整数(o或O)。
数字表达方式有以下3种:
1) <位宽><进制><数字> ,这是一种全面的描述方式。
2)在<进制><数字> 这种描述方式中,数字的位宽采用默认位宽(这由具体的机器系统决定,但至少32位)。
3)在<数字>这种描述方式中,采用默认进制(十进制)。
在表达式中,位宽指明了数字的精确位数。例如:一个4位二进制数的数字的位宽为4,一个4位十六进制数数字的位宽为16(因为每单个十六进制数就要用4位二进制数来表示)。如:
8'b10101100 //位宽为8的数的二进制表示,'b表示二进制
(2)x和z值
在数字电路中,x表示不定值,z代表高阻值。一个x可以用来定义十六进制数的4位二进制数的状态,八进制数的3位,二进制数的1位。z的表示方式同x类似。z还有一种表达方法是可以写作“?”。在使用case表达式时建议使用这种写法,以提高程序的可读性。如
4'b10x0 //位宽为4的二进制数从低位起第2位为不定值
4'b101z //位宽为4的二进制数从低位起第1位为高阻值
12'dz //位宽为12的十进制数,其值为高阻值(第1种表达方式)
12'd? //位宽为12的十进制数,其值为高阻值(第2种表达方式)
8'h4x //位宽为8的十六进制数,其低4位值为不定值
(3) 负数
一个数字可以被定义为负数,只需在位宽表达式前加一个减号,减号必须写在数字定义表达式的最前面。
注:减号不可以放在位宽和进制之间,也不可以放在进制和具体的数之间。如
-8'd5 //5的补数(用八位二进制数表示)
8'd-5 //非法格式
(4)下划线
下划线可以用来分隔开数的表达以提高程序的可读性。下划线不可以用在位宽和进制处,只能用在具体的数字之间。
16'b1010_1011_1111_1010 //合法格式
8'b_0011_1010 //非法格式
当常量不说明位数时,默认是32位,每个字符用8位ASCII值表示。如:
10 = 32'd10 = 32'b1010
1 = 32'd1 = 32'b1
-1 = -32'd1 = 32'hFFFFFFFF
`BX = 32'BX = 32'BXXXXXXX...X
"AB" = 16'B01000001_01000010 //字符串AB,为十六进制数16'h4142
参数型
在Verilog HDL中用parameter来定义常量,即用parameter来定义一个标识符代表一个常量,格式如下:
parameter 参数名1 = 表达式, 参数名2 = 表达式, … , 参数名n = 表达式;
parameter是参数型数据的确认符。确认符后跟着一个用逗号分隔开的赋值语句表。在每一个赋值语句的右边必须是一个常数表达式。也就是说,该表达式只能包含数字或先前已定义过的参数。
parameter msb = 7; //定义参数msb为常量7
parameter e = 25, f = 29; //定义两个常数参数parameterr=5.7;∥声明r为一个实型参数
parameter byte_size = 8, byte_msb = byte_size - 1; //用常数表达式赋值
parameter average_delay = (r + f) / 2; //用常数表达式赋值
变量的定义和使用方法:
在VerilogHDL中,变量通常用`
变量的定义格式如下:
其中,`
变量的使用方法:
在VerilogHDL中,变量可以在任何地方使用,包括模块实例化、端口连接、赋值语句等。
例如,下面是一个使用变量的示例:
module my_module (
input [7:0] a,
input [7:0] b,
output [7:0] c
);
reg [7:0] sum;
always @(a or b)
begin
sum <= a + b;
end
assign c = sum;
endmodule
在上面的示例中,定义了一个变量`sum`,并在`always`块中对它进行了赋值。最后,将变量`sum`赋值给输出端口`c`。
wire型
wire型数据常用来表示用以assign关键字指定的组合逻辑信号。Verilog程序模块中输入、输出信号类型默认时自动定义为wire型。wire型信号可以用做任何方程式的输入,也可以用做“assign”语句或实例元件的输出。
wire型信号的格式同reg型信号的格式很类似。
wire[n-1:0]数据名1,数据名2…数据名i;/共有i条总线,每条总线内有n条线路,或wire[n:1]数据名1,数据名2…数据名i。
wire是wire型数据的确认符;[n-1:0]和[n:1]代表该数据的位宽,即该数据有几位;最后跟着的是数据的名字。如果一次定义多个数据,数据名之间用逗号隔开。声明语句的最后要用分号表示语句结束。
wire a; //定义了一个1位的wire型数据
wire[7:0]b; //定义了一个8位的wire 型数据
wire[4:1]c, d; //定义了二个4位的wire型数据
reg型
寄存器是数据储存单元的抽象。寄存器数据类型的关键字是reg。通过赋值语句可以改变寄存器储存的值,其作用与改变触发器储存的值相当。Verilog HDL语言提供了功能强大的结构语句,使设计者能有效地控制是否执行这些赋值语句。这些控制结构用来描述硬件触发条件,例如时钟的上升沿和多路器的选通信号。reg类型数据的默认初始值为不定值x。
reg型数据常用来表示“always”模块内的指定信号,常代表触发器。通常,在设计中要由“always”模块通过使用行为描述语句来表达逻辑关系。在“always”模块内被赋值的每一个信号都必须定义成reg型。
reg型数据的格式如下:
reg[n-1:0]数据名1,数据名2…,数据名i;或reg[n:1]数据名1,数据名2,…,数据名i;
reg是reg型数据的确认标识符;[n-1:0]和[n:1]代表该数据的位宽,即该数据有几位(bit);最后跟着的是数据的名字。如果一次定义多个数据,数据名之间用逗号隔开。声明语句的最后要用分号表示语句结束。看下面的几个例子:
reg rega; //定义了一个1位的名为rega的reg型数据
reg[3:0]regb; ∥定义了一个4位的名为regb的reg型数据
reg[4:1]regc,regd; ∥定义了二个4位的名为regc和regd的reg型数据
reg型数据的默认初始值是不定值。reg型数据可以赋正值,也可以赋负值。但当一个reg型数据是一个表达式中的操作数时,它的值被当作是无符号值,即正值。例如,当一个4位的寄存器用做表达式中的操作数时,如果开始寄存器被赋以值-1,则在表达式中进行运算时,其值被认为是+15。
注意:reg型只表示被定义的信号将用在“always”模块内,理解这一点很重要。并不是说reg型信号一定是寄存器或触发器的输出,虽然reg型信号常常是寄存器或触发器的输出,但并不一定总是这样。
memory型
Verilog HDL通过对reg型变量建立数组来对存储器建模,可以描述RAM型存储器、ROM存储器和reg文件。数组中的每一个单元通过一个数组索引进行寻址。在Verilog语言中没有多维数组存在。memory型数据是通过扩展reg型数据的地址范围来生成的。其格式如下:
reg[n-1:0]存储器名[m一1:0];或reg[n-1:0]存储器名[m:1];
在这里,reg[n-1:0]定义了存储器中每一个存储单元的大小,即该存储单元是一个n位的寄存器;存储器名后的[m-1:0]或[m:1]则定义了该存储器中有多少个这样的寄存器;最后用分号结束定义语句。下面举例说明:
reg[7:0] mema[255:0];
这个例子定义了一个名为mema的存储器,该存储器有256个8位的存储器。该存储器的地址范围是0到255。注意:对存储器进行地址索引的表达式必须是常数表达式。
另外,在同一个数据类型声明语句里,可以同时定义存储器型数据和reg型数据。见下例:
parameter wordsize=16,//定义两个参数
memsize=256;
reg[wordsize-1:0]mem[memsize-1:0],writereg,readreg;
尽管memory型数据和reg型数据的定义格式很相似,但要注意其不同之处。如一个由n个1位寄存器构成的存储器组是不同于一个n位的寄存器的。见下例:
reg[n-1:0]rega;//一个n位的寄存器
reg mema[n-1:0];//一个由n个1位寄存器构成的存储器组
一个n位的寄存器可以在一条赋值语句里进行赋值,而一个完整的存储器则不行。见下例:
rega=0; //合法赋值语句
mema=0; //非法赋值语句
如果想对memory中的存储单元进行读写操作,必须指定该单元在存储器中的地址。下面的写法是正确的:
mema[3]=0; //给memory中的第3个存储单元赋值为0
进行寻址的地址索引可以是表达式,这样就可以对存储器中的不同单元进行操作。表达式的值可以取决于电路中其他的寄存器的值。
SteveRocket的博客_CSDN博客-Python进阶,Django进阶,C进阶领域博主SteveRocket擅长Python进阶,Django进阶,C进阶,等方面的知识https://blog.csdn.net/zhouruifu2015/
更多资料 · 微信公众号搜索【CTO Plus】关注后,获取更多,我们一起学习交流。
关于公众号的描述访问如下链接
关于Articulate“做一个知识和技术的搬运工。做一个终身学习的爱好者。做一个有深度和广度的技术圈。”一直以来都想把专业领域的技https://mp.weixin.qq.com/s/0yqGBPbOI6QxHqK17WxU8Q
推荐阅读:
FPGA在工业缺陷检测上的应用实践
FPGA设计Verilog基础之Verilog全局变量和局部变量定义
FPGA设计Verilog基础之Verilog中clk为什么要用posedge,而不用negedge
初学者必须弄懂的一些基本FPGA设计概念(1)
工作总结之全网最全的103个Verilog关键字总结(上)
工作总结之全网最全的103个Verilog关键字总结(下)
5G时代的FPGA发展趋势和应用分析
FPGA结合chatgpt的应用开发实践
FPGA | FPGA设计流程指南 v2.0
设计规范 | 总结开发过程中DDR3和FPGA部分的设计规范
术语一览 | 总结开发过程中关于FPGA的专业术语
用AI帮我写一篇关于FPGA的文章,并推荐最热门的FPGA开源项目