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

注意:后续技术分享,第一时间更新,以及更多更及时的技术资讯和学习技术资料,将在公众号CTO Plus发布,请关注公众号:CTO Plus

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

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

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

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

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

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

以下将详细介绍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 = ∈

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的存储器,该存储器有2568位的存储器。该存储器的地址范围是0255注意:对存储器进行地址索引的表达式必须是常数表达式。

尽管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 = ;

其中,``表示常量的数据类型,``表示常量的名称,``表示常量的值。

常量的使用方法:

在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中,变量通常用``关键字定义。变量的值可以在运行时修改。

变量的定义格式如下:

;

其中,``表示变量的数据类型,``表示变量的名称。

变量的使用方法:

在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开源项目

你可能感兴趣的:(FPGA进阶,fpga开发,Verilog数据类型)