赞
踩
在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 <type> <name> = <value>;
其中,`<type>`表示常量的数据类型,`<name>`表示常量的名称,`<value>`表示常量的值。
常量的使用方法:
在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中,变量通常用`<type>`关键字定义。变量的值可以在运行时修改。
变量的定义格式如下:
<type> <name>;
其中,`<type>`表示变量的数据类型,`<name>`表示变量的名称。
变量的使用方法:
在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型数据常用来表示用以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。通过赋值语句可以改变寄存器储存的值,其作用与改变触发器储存的值相当。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型信号常常是寄存器或触发器的输出,但并不一定总是这样。
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
进行寻址的地址索引可以是表达式,这样就可以对存储器中的不同单元进行操作。表达式的值可以取决于电路中其他的寄存器的值。
FPGA专栏
https://blog.csdn.net/zhouruifu2015/category_5690253
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。