当前位置:   article > 正文

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

verilog 数值定义

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

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

  1. reg [7:0] data; // 8位向量型寄存器
  2. wire [3:0] addr; // 4位向量型线网

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

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

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

1. bit

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

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

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

代码示例:

  1. module bit_module (
  2. input bit a,
  3. input bit b,
  4. output bit c
  5. );
  6. assign c = a & b;
  7. endmodule

2. logic

        logic类型用于表示逻辑值。在FPGA设计中,logic类型通常用于表示数据的真假值。与bit类型不同的是,logic类型可以取三态逻辑值(0、1、X),可用于检测与模拟器中的信号值。

        作用:用于表示单个比特位,可以取0、1、X、Z、L、H等值。

        特点:适用于仿真和综合。

代码示例:

  1. module logic_module (
  2. input logic a,
  3. input logic b,
  4. output logic c
  5. );
  6. assign c = a & b;
  7. endmodule

3. reg

        reg类型用于表示可赋值的寄存器。在FPGA设计中,reg类型通常用于存储逻辑电路中的状态(状态机的状态)或者存储数据(RAM控制器的数据缓存区)。

        作用:用于表示存储器或寄存器中的数据,可以在always块中赋值。

        特点:只能在always块中赋值。

代码示例:

  1. module reg_module (
  2. input bit a,
  3. input bit b,
  4. output reg c
  5. );
  6. always @(a or b)
  7. begin
  8. c = a & b;
  9. end
  10. endmodule

        在“always”块内被赋值的每一个信号都必须定义成reg型。

        reg型数据的缺省初始值是不定值。

        reg型只表示被定义的信号将用在“always”块内,理解这一点很重要。并不是说reg型信号一定是寄存器或触发器的输出。虽然reg型信号常常是寄存器或触发器的输出,但并不一定总是这样。

4. wire

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

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

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

代码示例:

  1. module wire_module (
  2. input bit a,
  3. input bit b,
  4. output wire c
  5. );
  6. and gate1(c, a, b);
  7. endmodule

5. integer

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

        作用:用于表示整数。

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

代码示例:

  1. module integer_module (
  2. input integer a,
  3. input integer b,
  4. output integer c
  5. );
  6. assign c = a + b;
  7. endmodule

6. time

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

作用:用于表示时间。

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

代码示例:

  1. module time_module (
  2. input time a,
  3. input time b,
  4. output time c
  5. );
  6. assign c = a + b;
  7. endmodule

7. real

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

        作用:用于表示实数。

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

代码示例:

  1. module real_module (
  2. input real a,
  3. input real b,
  4. output real c
  5. );
  6. assign c = a + b;
  7. endmodule

8. realtime

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

        作用:用于表示实时数。

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

代码示例:

  1. module realtime_module (
  2. input realtime a,
  3. input realtime b,
  4. output realtime c
  5. );
  6. assign c = a + b;
  7. endmodule

9. shortint

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

        作用:用于表示短整数。

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

代码示例:

  1. module shortint_module (
  2. input shortint a,
  3. input shortint b,
  4. output shortint c
  5. );
  6. assign c = a + b;
  7. endmodule

10. int

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

        作用:用于表示整数。

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

代码示例:

  1. module int_module (
  2. input int a,
  3. input int b,
  4. output int c
  5. );
  6. assign c = a + b;
  7. endmodule

11. longint

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

        作用:用于表示长整数。

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

代码示例:

  1. module longint_module (
  2. input longint a,
  3. input longint b,
  4. output longint c
  5. );
  6. assign c = a + b;
  7. endmodule

12. byte

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

        作用:用于表示字节。

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

代码示例:

  1. module byte_module (
  2. input byte a,
  3. input byte b,
  4. output byte c
  5. );
  6. assign c = a + b;
  7. endmodule

13. wand

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

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

        特点:只能取0或1。

代码示例:

  1. module wand_module (
  2. input bit a,
  3. input bit b,
  4. output wand c
  5. );
  6. assign c = ~(a & b);
  7. endmodule

14. wor

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

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

        特点:只能取0或1。

代码示例:

  1. module wor_module (
  2. input bit a,
  3. input bit b,
  4. output wor c
  5. );
  6. assign c = ~(a | b);
  7. endmodule

15. tri

        tri类型用于表示三态缓冲器。在FPGA设计中,tri类型适合表示总线信号。

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

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

代码示例:

  1. module tri_module (
  2. input bit a,
  3. input bit b,
  4. output tri c
  5. );
  6. assign c = a ? b : 1'bz;
  7. endmodule

16. triand

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

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

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

代码示例:

  1. module triand_module (
  2. input bit a,
  3. input bit b,
  4. output triand c
  5. );
  6. assign c = a & b;
  7. endmodule

17. trior

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

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

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

代码示例:

  1. module trior_module (
  2. input bit a,
  3. input bit b,
  4. output trior c
  5. );
  6. assign c = a | b;
  7. endmodule

18. trireg

        trireg类型用于表示三态输出+存储器。在FPGA设计中,trireg类型适合表示内存存储器控制器的数据输出。

        作用:用于表示三态寄存器输出的值。

        特点:只能在always块中赋值。

代码示例:

  1. module trireg_module (
  2. input bit a,
  3. input bit b,
  4. output trireg c
  5. );
  6. always @(a or b)
  7. begin
  8. c <= a ? b : 1'bz;
  9. end
  10. endmodule

19. supply0/supply1

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

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

        特点:只能取0或1。

代码示例:

  1. module supply_module (
  2. input supply0 a,
  3. input supply1 b,
  4. output supply0 c
  5. );
  6. assign c = a & b;
  7. endmodule

20. small

        small类型用于表示带符号的8位整数值。

        作用:small型是一种数据类型,用于表示带符号的8位整数值。在FPGA设计中,small型通常用于计数器等电路中。

        特点:small型的取值范围为-128到127,占用8位二进制位。

代码示例:

  1. module counter(
  2. input clk,
  3. input rst,
  4. output reg [7:0] count
  5. );
  6. always @(posedge clk or posedge rst) begin
  7. if(rst) begin
  8. count <= 8'sd0;
  9. end else begin
  10. count <= count + 1;
  11. end
  12. end
  13. endmodule

21. trio

        trio类型用于表示与或非逻辑组合,支持三态输出。在FPGA设计中,trio类型适合表示总线信号。

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

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

代码示例:

  1. module tri_buffer(
  2. inout tri [7:0] data,
  3. input enable
  4. );
  5. assign data = enable ? data : 'z;
  6. endmodule

22. large

        large类型用于表示大整数值。在FPGA设计中,large类型通常用于高精度计算、加密解密等应用中。

        作用:large型是一种数据类型,用于表示大整数值。在FPGA设计中,large型通常用于高精度计算、加密解密等应用中。

        特点:large型的取值范围很大,可达到2^63-1。

代码示例:

  1. module rsa(
  2. input clk,
  3. input [63:0] p,
  4. input [63:0] q,
  5. input [63:0] e,
  6. input [63:0] m,
  7. output reg [63:0] c
  8. );
  9. reg [127:0] n;
  10. reg [127:0] d;
  11. reg [127:0] phi;
  12. reg [127:0] temp1;
  13. reg [127:0] temp2;
  14. always @(p or q) begin
  15. n = p * q;
  16. phi = (p - 1) * (q - 1);
  17. end
  18. always @(e or phi) begin
  19. d = e^-1 % phi;
  20. end
  21. always @(posedge clk) begin
  22. temp1 = m^e % n;
  23. temp2 = temp1^d % n;
  24. c <= temp1;
  25. end
  26. endmodule

23. signed

        signed类型用于表示带符号的整数值。在FPGA设计中,signed类型通常用于计算机算术运算、数字信号处理等应用中。

1. Verilog中signed型是一种数据类型,用于表示带符号的标量类型。

2. signed型通常用于表示带符号的数值类型,其取值范围为-2^(n-1)到2^(n-1)-1,其中n为位宽。

3. signed型的特点是可以进行带符号的运算,如加减乘除等。

4. signed型的代码示例:

代码示例

  1. module signed_adder(
  2. input signed [31:0] a,
  3. input signed [31:0] b,
  4. output reg signed [31:0] sum
  5. );
  6. always @(a or b) begin
  7. sum = a + b;
  8. end
  9. endmodule

24. unsigned

        unsigned类型用于表示无符号的整数值。在FPGA设计中,unsigned类型通常用于计算机算术运算、数字信号处理等应用中。

        作用:unsigned型是一种数据类型,用于表示无符号的标量类型。在FPGA设计中,unsigned型通常用于表示无符号的数值类型。

        特点:unsigned型的取值范围为0到2^32-1。

代码示例:

  1. module unsigned_adder(
  2. input [31:0] a,
  3. input [31:0] b,
  4. output reg [31:0] sum
  5. );
  6. always @(a or b) begin
  7. sum = a + b;
  8. end
  9. endmodule

25. enum

        enum类型用于表示枚举类型。在FPGA设计中,enum类型通常用于表示状态机的状态、控制信号等。

1. Verilog中enum型是一种数据类型,用于表示枚举类型。

2. enum型通常用于定义一组有限的取值范围,如状态机的状态等。

3. enum型的特点是可以使用可读性更高的名称来表示取值,而不是使用数字。

4. enum型的代码示例:

代码示例

  1. typedef enum logic [1:0] {IDLE, READ, WRITE} state;
  2. module state_machine(
  3. input clk,
  4. input reset,
  5. output reg [1:0] current_state
  6. );
  7. state next_state;
  8. always @(posedge clk, posedge reset) begin
  9. if (reset) begin
  10. current_state <= IDLE;
  11. end else begin
  12. case (current_state)
  13. IDLE: next_state = READ;
  14. READ: next_state = WRITE;
  15. WRITE: next_state = IDLE;
  16. endcase
  17.   current_state <= next_state;
  18. end
  19. end
  20. endmodule

26. medium

        medium类型用于表示中等精度的整数值。在FPGA设计中,medium类型通常用于计算逻辑、内部数据储存等应用中。

        作用:medium型是一种数据类型,用于表示中等精度的整数值。在FPGA设计中,medium型通常用于计算逻辑、内部数据储存等应用中。

        特点:medium型的取值范围为-2^23到2^23-1。

代码示例:

  1. module multiplier(
  2. input clk,
  3. input [23:0] a,
  4. input [23:0] b,
  5. output reg [47:0] p
  6. );
  7. always @(posedge clk) begin
  8. p <= a * b;
  9. end
  10. endmodule

27. scalared

        scalared类型用于表示带时间戳的信号值。在FPGA设计中,scalared类型通常用于仿真器中,用于记录仿真器中的信号值及其变化时间。

        作用:scalared型是一种数据类型,用于表示带符号的标量类型。在FPGA设计中,scalared型通常用于表示带符号的数值类型。

        特点:scalared型的取值范围为-2^31到2^31-1。

代码示例:

  1. module signed_adder(
  2. input signed [31:0] a,
  3. input signed [31:0] b,
  4. output reg signed [31:0] sum
  5. );
  6. always @(a or b) begin
  7. sum = a + b;
  8. end
  9. endmodule

28. tril

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

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

代码示例:

  1. module tri_and(
  2. inout tri out,
  3. input [3:0] in
  4. );
  5. assign out = &in;
  6. endmodule

29. vectored

        作用:vectored型是一种数据类型,用于表示向量类型。在FPGA设计中,vectored型通常用于表示寄存器、存储器等。

        特点:vectored型的取值范围为多个位,可以使用冒号(:)表示范围。

代码示例:

  1. module reg_file(
  2. input clk,
  3. input [4:0] addr1,
  4. input [4:0] addr2,
  5. input [31:0] data_in,
  6. output reg [31:0] data_out1,
  7. output reg [31:0] data_out2
  8. );
  9. reg [31:0] regs [0:31];
  10. always @(posedge clk) begin
  11. regs[addr1] <= data_in;
  12. regs[addr2] <= data_in;
  13. end
  14. assign data_out1 = regs[addr1];
  15. assign data_out2 = regs[addr2];
  16. endmodule

30. parametr

        作用:parametr是一种数据类型,用于表示常量值。在FPGA设计中,parametr通常用于定义常量、参数等。

        特点:parametr的值在编译时确定,不能被修改。

代码示例:

  1. module adder(
  2. input [7:0] a,
  3. input [7:0] b,
  4. output [7:0] sum
  5. );
  6. parameter WIDTH = 8;
  7. assign sum = a + b;
  8. endmodule

31. real

        作用:real型是一种数据类型,用于表示浮点数类型。在FPGA设计中,real型通常用于模拟器中的仿真计算。

        特点:real型的取值范围为IEEE 754标准的单精度浮点数。

代码示例:

  1. module floating_point_multiplier(
  2. input [31:0] a,
  3. input [31:0] b,
  4. output reg [31:0] product
  5. );
  6. real r_a;
  7. real r_b;
  8. real r_product;
  9. always @(a or b) begin
  10. r_a = $bitstoreal(a);
  11. r_b = $bitstoreal(b);
  12. r_product = r_a * r_b;
  13. product = $realtobits(r_product);
  14. end
  15. 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[2550];

        这个例子定义了一个名为mema的存储器,该存储器有256个8位的存储器。该存储器的地址范围是0到255。注意:对存储器进行地址索引的表达式必须是常数表达式。

        尽管memory型数据和reg型数据的定义格式很相似,但要注意其不同之处。如一个由n个1位寄存器构成的存储器组是不同于一个n位的寄存器的。见下例: 

  1. reg [n-1:0] rega; //一个n位的寄存器
  2. reg mema [n-1:0]; //一个由n个1位寄存器构成的存储器组 

        一个n位的寄存器可以在一条赋值语句里进行赋值,而一个完整的存储器则不行。见下例:

  1. rega =0; //合法赋值语句
  2. mema =0; //非法赋值语句

        如果想对memory中的存储单元进行读写操作,必须指定该单元在存储器中的地址。下面的写法是正确的。

mema[3]=0; //给memory中的第3个存储单元赋值为0。

memory型的代码示例:

  1. module memory_controller(
  2. input clk,
  3. input [7:0] address,
  4. input [7:0] write_data,
  5. input read_enable,
  6. input write_enable,
  7. output reg [7:0] read_data
  8. );
  9. reg [7:0] memory [255:0];
  10. always @(posedge clk) begin
  11. if (write_enable) begin
  12. memory[address] <= write_data;
  13. end
  14. if (read_enable) begin
  15. read_data <= memory[address];
  16. end
  17. end
  18. 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)。位向量类型的定义语法格式如下:

  1. //有符号位向量
  2. reg signed [n-1:0] 变量名;
  3. //无符号位向量
  4. reg [n-1:0] 变量名;
  5. //逻辑位向量
  6. wire [n-1:0] 变量名;

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

2. 整数类型

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

  1. //有符号整数
  2. integer 变量名;
  3. //无符号整数
  4. integer unsigned 变量名;

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

3. 实数类型

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

  1. //单精度实数
  2. real 变量名;
  3. //双精度实数
  4. realtime 变量名;

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

4. 时间类型

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

  1. //时钟周期类型
  2. `timescale 时间单位/时间精度
  3. //时间类型
  4. time 变量名;

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

5. 字符串类型

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

  1. //字符串类型
  2. string 变量名;
  3. //文件类型
  4. file 变量名;

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

3、常量和变量

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

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

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

  1. //常量定义
  2. parameter 常量名 = 常量值;
  3. //变量定义
  4. reg 变量名;

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

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

  1. //常量使用
  2. 常量名
  3. //变量使用
  4. 变量名 = 值;

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

3.1 常量

常量的定义和使用方法:

        在VerilogHDL中,常量通常用`parameter`关键字定义。`parameter`定义的常量在编译时就确定了,不能在运行时修改。

        常量的定义格式如下:

parameter <type> <name> = <value>;

        其中,`<type>`表示常量的数据类型,`<name>`表示常量的名称,`<value>`表示常量的值。

常量的使用方法:

        在VerilogHDL中,常量可以在任何地方使用,包括模块实例化、端口连接、赋值语句等。

        例如,下面是一个使用常量的示例:

  1. module my_module (
  2. input [7:0] a,
  3. input [7:0] b,
  4. output [7:0] c
  5. );
  6. parameter WIDTH = 8;
  7. assign c = a + b + WIDTH;
  8. 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表达式时建议使用这种写法,以提高程序的可读性。如

  1. 4'b10x0    //位宽为4的二进制数从低位起第2位为不定值
  2. 4'b101z    //位宽为4的二进制数从低位起第1位为高阻值
  3. 12'dz      //位宽为12的十进制数,其值为高阻值(第1种表达方式)
  4. 12'd?      //位宽为12的十进制数,其值为高阻值(第2种表达方式)
  5. 8'h4x      //位宽为8的十六进制数,其低4位值为不定值

(3) 负数

        一个数字可以被定义为负数,只需在位宽表达式前加一个减号,减号必须写在数字定义表达式的最前面。

        注:减号不可以放在位宽和进制之间,也不可以放在进制和具体的数之间。如

  1. -8'd5    //5的补数(用八位二进制数表示)
  2. 8'd-5    //非法格式

(4)下划线

        下划线可以用来分隔开数的表达以提高程序的可读性。下划线不可以用在位宽和进制处,只能用在具体的数字之间。

  1. 16'b1010_1011_1111_1010    //合法格式
  2. 8'b_0011_1010              //非法格式

当常量不说明位数时,默认是32位,每个字符用8位ASCII值表示。如:

  1. 10 = 32'd10 = 32'b1010
  2. 1 = 32'd1 = 32'b1
  3. -1 = -32'd1 = 32'hFFFFFFFF
  4. `BX = 32'BX = 32'BXXXXXXX...X
  5. "AB" = 16'B01000001_01000010        //字符串AB,为十六进制数16'h4142
参数型

        在Verilog HDL中用parameter来定义常量,即用parameter来定义一个标识符代表一个常量,格式如下:

parameter 参数名1 = 表达式, 参数名2 = 表达式, … , 参数名n = 表达式;

        parameter是参数型数据的确认符。确认符后跟着一个用逗号分隔开的赋值语句表。在每一个赋值语句的右边必须是一个常数表达式。也就是说,该表达式只能包含数字或先前已定义过的参数。

  1. parameter msb = 7;         //定义参数msb为常量7
  2. parameter e = 25, f = 29;    //定义两个常数参数parameterr=5.7;∥声明r为一个实型参数
  3. parameter byte_size = 8, byte_msb = byte_size - 1;    //用常数表达式赋值
  4. parameter average_delay = (r + f) / 2;   //用常数表达式赋值

3.2 变量

        变量的定义和使用方法:

        在VerilogHDL中,变量通常用`<type>`关键字定义。变量的值可以在运行时修改。

变量的定义格式如下:

<type> <name>;

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

变量的使用方法:

        在VerilogHDL中,变量可以在任何地方使用,包括模块实例化、端口连接、赋值语句等。

        例如,下面是一个使用变量的示例:

  1. module my_module (
  2. input [7:0] a,
  3. input [7:0] b,
  4. output [7:0] c
  5. );
  6. reg [7:0] sum;
  7. always @(a or b)
  8. begin
  9. sum <= a + b;
  10. end
  11. assign c = sum;
  12. 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]代表该数据的位宽,即该数据有几位;最后跟着的是数据的名字。如果一次定义多个数据,数据名之间用逗号隔开。声明语句的最后要用分号表示语句结束。

  1. wire a;             //定义了一个1位的wire型数据
  2. wire[70]b;        //定义了一个8位的wire 型数据
  3. wire[41]c, d;     //定义了二个4位的wire型数据
reg型

        寄存器是数据储存单元的抽象。寄存器数据类型的关键字是reg。通过赋值语句可以改变寄存器储存的值,其作用与改变触发器储存的值相当。Verilog HDL语言提供了功能强大的结构语句,使设计者能有效地控制是否执行这些赋值语句。这些控制结构用来描述硬件触发条件,例如时钟的上升沿和多路器的选通信号。reg类型数据的默认初始值为不定值x。

        reg型数据常用来表示“always”模块内的指定信号,常代表触发器。通常,在设计中要由“always”模块通过使用行为描述语句来表达逻辑关系。在“always”模块内被赋值的每一个信号都必须定义成reg型。

reg型数据的格式如下:

reg[n-10]数据名1,数据名2…,数据名i;或reg[n:1]数据名1,数据名2,…,数据名i;

        reg是reg型数据的确认标识符;[n-1:0]和[n:1]代表该数据的位宽,即该数据有几位(bit);最后跟着的是数据的名字。如果一次定义多个数据,数据名之间用逗号隔开。声明语句的最后要用分号表示语句结束。看下面的几个例子:

  1. reg rega;    //定义了一个1位的名为rega的reg型数据
  2. reg[30]regb;   ∥定义了一个4位的名为regb的reg型数据
  3. reg[41]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-10]存储器名[m一10];或reg[n-10]存储器名[m:1];

        在这里,reg[n-1:0]定义了存储器中每一个存储单元的大小,即该存储单元是一个n位的寄存器;存储器名后的[m-1:0]或[m:1]则定义了该存储器中有多少个这样的寄存器;最后用分号结束定义语句。下面举例说明:

reg[70] mema[2550];

        这个例子定义了一个名为mema的存储器,该存储器有256个8位的存储器。该存储器的地址范围是0到255。注意:对存储器进行地址索引的表达式必须是常数表达式。

        另外,在同一个数据类型声明语句里,可以同时定义存储器型数据和reg型数据。见下例:

  1. parameter wordsize=16//定义两个参数
  2. memsize=256
  3. reg[wordsize-10]mem[memsize-10],writereg,readreg;

        尽管memory型数据和reg型数据的定义格式很相似,但要注意其不同之处。如一个由n个1位寄存器构成的存储器组是不同于一个n位的寄存器的。见下例:

  1. reg[n-10]rega;//一个n位的寄存器
  2. reg mema[n-10];//一个由n个1位寄存器构成的存储器组

        一个n位的寄存器可以在一条赋值语句里进行赋值,而一个完整的存储器则不行。见下例:

  1. rega=0;    //合法赋值语句
  2. mema=0;    //非法赋值语句

        如果想对memory中的存储单元进行读写操作,必须指定该单元在存储器中的地址。下面的写法是正确的:

mema[3]=0; //给memory中的第3个存储单元赋值为0

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

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/743452
推荐阅读
相关标签
  

闽ICP备14008679号