FPGA设计Verilog基础之数据类型的作用和特点、常量和变量的代码示例详解

         在Verilog中,有多种数据类型可供使用,包括位向量类型、整数类型、实数类型、布尔型、时间类型和字符串类型等。下面详细介绍Verilog的所有数据类型、常量和变量的定义和使用方法。

        整型和实型用于表示数字,布尔型用于表示逻辑值。向量型用于表示多位数据,例如:

reg [7:0] data; // 8位向量型寄存器

wire [3:0] addr; // 4位向量型线网

        Verilog中的变量有线网类型和寄存器类型。线网型变量综合成wire,而寄存器可能综合成WIRE,锁存器和触发器,还有可能被优化掉。

所有类型的作用、特点和代码示例介绍

        以下将详细介绍FPGA设计中Verilog数据类型的定义、作用、特点和详细的代码示例。

1. bit

        bit类型用于表示单个二进制位。在FPGA设计中,bit类型通常用于表示FPGA的输入输出、寄存器等信号的值。

        作用:用于表示单个比特位(二进制位),只能取0或1。

        特点:占用存储空间最小。

代码示例:

module bit_module (

input bit a,

input bit b,

output bit c

);



assign c = a & b;



endmodule

2. logic

        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

3. reg

        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型信号常常是寄存器或触发器的输出,但并不一定总是这样。

4. wire

        wire类型用于连接模块中的端口。在FPGA设计中,wire类型通常用于模块之间的信号连接,如模块之间的输入输出信号连接。

        作用:用于表示连线或线路中的数据,只能在模块实例化时赋值。

        特点:只能在模块实例化时赋值。

代码示例:

module wire_module (

input bit a,

input bit b,

output wire c

);



and gate1(c, a, b);



endmodule

5. integer

        integer类型用于表示整数值。在FPGA设计中,integer类型通常用于计数器、延时器等电路中。

        作用:用于表示整数。

        特点:占用存储空间为32位。

代码示例:

module integer_module (

input integer a,

input integer b,

output integer c

);



assign c = a + b;



endmodule

6. time

        time类型用于表示时间。在FPGA设计中,time类型通常用于表示延迟器、时钟周期等时间。

作用:用于表示时间。

        特点:占用存储空间为64位。

代码示例:

module time_module (

input time a,

input time b,

output time c

);



assign c = a + b;



endmodule

7. real

        real类型用于表示实数。在FPGA设计中,real类型通常用于表示浮点数的计算。

        作用:用于表示实数。

        特点:占用存储空间为64位。

代码示例:

module real_module (

input real a,

input real b,

output real c

);



assign c = a + b;



endmodule

8. realtime

        realtime类型用于表示当前的时间。在FPGA设计中,realtime类型通常用于设计模拟器中,表示仿真当前的时间。

        作用:用于表示实时数。

        特点:占用存储空间为64位。

代码示例:

module realtime_module (

input realtime a,

input realtime b,

output realtime c

);



assign c = a + b;



endmodule

9. shortint

        shortint类型用于表示带符号的16位整数值。在FPGA设计中,shortint类型通常用于计数器等电路中。

        作用:用于表示短整数。

        特点:占用存储空间为16位。

代码示例:

module shortint_module (

input shortint a,

input shortint b,

output shortint c

);



assign c = a + b;



endmodule

10. int

        int类型用于表示带符号的32位整数值。在FPGA设计中,int类型通常用于计算逻辑、内部数据储存等。

        作用:用于表示整数。

        特点:占用存储空间为32位。

代码示例:

module int_module (

input int a,

input int b,

output int c

);



assign c = a + b;



endmodule

11. longint

        longint类型用于表示带符号的64位整数值。在FPGA设计中,longint类型通常用于精度要求很高的计算逻辑。

        作用:用于表示长整数。

        特点:占用存储空间为64位。

代码示例:

module longint_module (

input longint a,

input longint b,

output longint c

);



assign c = a + b;



endmodule

12. byte

        byte类型用于表示带符号的8位数值。在FPGA设计中,byte类型通常用于存储压缩和图像数据等。

        作用:用于表示字节。

        特点:占用存储空间为8位。

代码示例:

module byte_module (

input byte a,

input byte b,

output byte c

);



assign c = a + b;



endmodule

13. wand

        wand类型用于实现与逻辑。在FPGA设计中,wand类型适合表示AND电路。

        作用:用于表示与非门输出的值。

        特点:只能取0或1。

代码示例:

module wand_module (

input bit a,

input bit b,

output wand c

);



assign c = ~(a & b);



endmodule

14. wor

        wor类型用于实现或逻辑。在FPGA设计中,wor类型适合表示OR电路。

        作用:用于表示或非门输出的值。

        特点:只能取0或1。

代码示例:

module wor_module (

input bit a,

input bit b,

output wor c

);



assign c = ~(a | b);



endmodule

15. tri

        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

16. triand

        triand类型用于表示与逻辑+三态输出。在FPGA设计中,triand类型适合表示总线信号。

        作用:用于表示三态与门输出的值。

        特点:可以取0、1、Z、X等值。

代码示例:

module triand_module (

input bit a,

input bit b,

output triand c

);



assign c = a & b;



endmodule

17. trior

        trior类型用于表示或逻辑+三态输出。在FPGA设计中,trior类型适合表示总线信号。

        作用:用于表示三态或门输出的值。

        特点:可以取0、1、Z、X等值。

代码示例:

module trior_module (

input bit a,

input bit b,

output trior c

);



assign c = a | b;



endmodule

18. trireg

        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

19. supply0/supply1

        supply0/supply1类型用于表示逻辑值。在FPGA设计中,用于保证在仿真器中存在的常量值(供电值)。

        作用:用于表示电源和地。

        特点:只能取0或1。

代码示例:

module supply_module (

input supply0 a,

input supply1 b,

output supply0 c

);



assign c = a & b;



endmodule

20. small

        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

21. trio

        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

22. large

        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

23. signed

        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

24. unsigned

        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

25. enum

        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

26. medium

        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

27. scalared

        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

28. tril

        作用:tril型是一种数据类型,用于表示与逻辑+三态输出。在FPGA设计中,tril型适合表示总线信号。

        特点:tril型的取值范围为0和Z,其中Z表示高阻态。

代码示例:

module tri_and(

inout tri out,

input [3:0] in

);



assign out = &in;



endmodule

29. vectored

        作用: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

30. parametr

        作用: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

31. real

        作用: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

32. memory

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信号上。

2、数据类型

        VerilogHDL数据类型是用来表示数字电路硬件中的数据储存和传送元素的。其中4个最基本的数据类型,它们是:reg类型、wire类型、integer类型和parameter类型。

        其他的类型是:large类型、medium类型、scalared类型、time类型、small类型、tri类型、trio类型、tril类型、triand类型、trior类型、trireg类型、vectored类型、wand类型、wor类型。这14种数据类型除time型外都与基本逻辑单元建库有关,与系统设计没有很大的关系。

1. 位向量类型

        位向量类型是Verilog中最常用的数据类型之一,用于表示二进制数值。位向量类型包括有符号位向量(signed)、无符号位向量(unsigned)和逻辑位向量(wire)。位向量类型的定义语法格式如下:

//有符号位向量

reg signed [n-1:0] 变量名;

//无符号位向量

reg [n-1:0] 变量名;

//逻辑位向量

wire [n-1:0] 变量名;

        其中,n为位数,可以是任意正整数。有符号位向量表示带符号的二进制数值,无符号位向量表示无符号的二进制数值,逻辑位向量表示逻辑电路的输出值。

2. 整数类型

        整数类型用于表示整数数值,包括有符号整数类型(integer)和无符号整数类型(unsigned)。整数类型的定义语法格式如下:

//有符号整数

integer 变量名;

//无符号整数

integer unsigned 变量名;

        其中,有符号整数表示带符号的整数数值,无符号整数表示无符号的整数数值。

3. 实数类型

        实数类型用于表示实数数值,包括单精度实数类型(real)和双精度实数类型(realtime)。实数类型的定义语法格式如下:

//单精度实数

real 变量名;

//双精度实数

realtime 变量名;

        其中,单精度实数表示单精度的实数数值,双精度实数表示双精度的实数数值。 

4. 时间类型

        时间类型用于表示时间数值,包括时钟周期类型(timescale)和时间类型(time)。时间类型的定义语法格式如下:

//时钟周期类型

`timescale 时间单位/时间精度

//时间类型

time 变量名;

        其中,时间单位可以是ns、us、ms、s等,时间精度可以是1、10、100、1000等。时间类型表示时间数值,单位为时间单位。

5. 字符串类型

        字符串类型用于表示字符串数值,包括字符串类型(string)和文件类型(file)。字符串类型的定义语法格式如下:

//字符串类型

string 变量名;

//文件类型

file 变量名;

        其中,字符串类型表示字符串数值,文件类型表示文件句柄。

3、常量和变量

Verilog HDL语言中也有常量和变量之分,它们分别属于以上这些类型。下面就最常用的几种进行介绍。

常量和变量的定义和使用方法

        在VerilogHDL中,常量和变量都是用来存储数据的,定义和使用方法与其他编程语言类似。常量是指在程序中不可改变的变量(数据),而变量是可以改变的变量(数据)。常量和变量的定义语法格式如下:

//常量定义

parameter 常量名 = 常量值;

//变量定义

reg 变量名;

        其中,常量名为常量的名称,常量值为常量的值,变量名为变量的名称。

        常量和变量的使用方法如下:

//常量使用

常量名

//变量使用

变量名 = 值;

        其中,常量名表示常量的值,变量名表示变量的值,值为常量值或变量值。

3.1 常量

常量的定义和使用方法:

        在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;   //用常数表达式赋值

3.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型

        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

        进行寻址的地址索引可以是表达式,这样就可以对存储器中的不同单元进行操作。表达式的值可以取决于电路中其他的寄存器的值。

FPGA专栏
https://blog.csdn.net/zhouruifu2015/category_5690253

猜你喜欢

转载自blog.csdn.net/jk_101/article/details/131311895