Verilog初级教程(3)Verilog 数据类型

前言

这是本系列的第三篇博文,依然很基础,这个系列文章,主要是在没有其他事情的时候,休闲所作!
如问,有没有意义,我觉得对我来说是有意义的:

  • 首先,对于我写博客的条理性来说,是有意义的,以前写博客,想到什么写什么,现在需要条理性,也是对知识的一种回顾!
  • 其次,对于初学者以及看我博客的人来说,可以作为一种资料来源用作参考!
  • 最后,保持写作,写着写着也许就有思路了呢?

我的微信公众号: FPGA LAB

正文

本篇博客讲的是Verilog HDL中的数据类型,我最常用的数据类型,无非就三种,reg、wire,integer;其中integer 主要在for 循环中使用。

变量可以取什么样的值?

变量的取值有四种,由于是数字电路,固然是0和1,那第三种、第四种呢?
高阻态 Z以及未知态X。我们在仿真中常见到这两种状态,有的时候还弄得人很不爽快!

  • 何为高阻态?

高阻态是一个数字电路里常见的术语,指的是电路的一种输出状态,既不是高电平也不是低电平,如果高阻态再输入下一级电路的话,对下级电路无任何影响,和没接一样,类似于引脚悬空,如果用万用表测的话有可能是高电平也有可能是低电平,随它后面接的东西定。

更详细的解释见博客:

三态之高阻态

FPGA基础知识极简教程(8)详解三态缓冲器

  • 何为未知态?

未知态,顾名思义,代表不知道的逻辑值,可以是0也可以是1.

如下总结:

logic value meaning
0 represents a logic zero, or a false condition
1 represents a logic one, or a true condition
x represents an unknown logic value (can be zero or one)
z represents a high-impedance state

示意图:

四种状态

变量的取值意味着什么?

Verilog是一种硬件描述语言,用于描述触发器,与非门等等一系列的硬件逻辑,因此,其逻辑取值应该在硬件电路中有所对应!

  • 逻辑1代表着电源电压Vdd,逻辑0代表着接地!
  • 未知态X可以是0也可以是1,这与布尔代数有所差异,其表示无关!
  • 高阻态Z表示未连接任何导线,悬空。

主要的数据类型

主要的数据类型,莫过于reg类型和wire类型,Verilog几乎可以用这两种类型通吃了。

  • wire类似于将两个部件在电路板上连接起来:

电路板连线

它用于硬件实体之间的连接,因此不会存储任何值,仅仅起到连接元件的作用:

连线

如果需要多个连线,还可以设置wire的位宽,相当于将几个线捆扎在一起:

wire [3:0] n0;

位宽为4的wire类型变量

最后关于wire类型需要注意的是,重复声明或定义是不合规的。

module design;
  wire    abc;
  wire   a;
  wire   b;
  wire   c;
 
  wire    abc;   // Error: Identifier "abc" previously declared
 
  assign abc = a & b | c;
endmodule
  • reg类型变量可用于数据的存储,其可以看做是register的缩写,也即是寄存器!

如下:

reg型变量

上面的定义,相当于分别定义了一个4bit的存储空间和一个8bit的存储空间,可以用来存储数值。

下图显示了,这种变量在硬件电路中的等价:

寄存器变量的等价

其他数据类型

integer

除了wire以及reg型变量,另一个比较常用的便是integer数据类型了,它表示了32bit的数据宽度,用来存储整型值,我们在for循环中常常用到它,例如:

for(integer i = 0; i < 10; i = i + 1) begin
//......
end

或者:

integer i = 0;
for(i = 0; i < 10; i = i + 1) begin
//......
end

time / realtime

这两种类型一般用于仿真,time类型是一个无符号,64bit宽的数据类型,可以用来存储仿真时间用于调试。
realtime的区别在于仅存储浮点型数据。

例如:

    time        end_time;           // end_time can be stored a time value like 50ns
    realtime    rtime;              // rtime = 40.25ps 

real

real型变量可以存储浮点值,可以像整数和reg一样进行赋值。

如:

    real        float;              // float = 12.344  - can store floating numbers

例子

module testbench;
  integer    int_a;         // Integer variable
  real     real_b;       // Real variable
  time     time_c;       // Time variable
 
  initial begin
    int_a   = 32'hcafe_1234;   // Assign an integer value
    real_b   = 0.1234567;     // Assign a floating point value
 
    #20;             // Advance simulation time by 20 units
    time_c   = $time;       // Assign current simulation time
 
    // Now print all variables using $display system task
    $display ("int_a   = 0x%0h", int_a);
    $display ("real_b   = %0.5f", real_b);
    $display ("time_c   = %0t", time_c);
  end
endmodule

仿真结果:

ncsim> run
int_a 	= 0xcafe1234
real_b 	= 0.12346
time_c 	= 20
ncsim: *W,RNQUIE: Simulation is complete.

Verilog的字符串

字符串在reg中被还原,reg变量的宽度必须足够大,以容纳字符串。字符串中的每个字符代表一个ASCll值,需要1个字节。如果变量的大小小于字符串,那么Verilog会截断字符串的最左边的位。如果变量的大小大于字符串,那么Verilog会在字符串的左边添加0。

 
// "Hello World" requires 11 bytes
 
reg [8*11:1] str = "Hello World";         // Variable can store 11 bytes, str = "Hello World"
reg [8*5:1]  str = "Hello World";         // Variable stores only 5 bytes (rest is truncated), str = "World"
reg [8*20:1] str = "Hello World";         // Variable can store 20 bytes (rest is padded with zeros), str = "         Hello World"
 

下面举一个例子进行仿真:

module testbench;
  reg [8*11:1] str1;
  reg [8*5:1]  str2;
  reg [8*20:1] str3;
 
  initial begin
    str1 = "Hello World";
    str2 = "Hello World";
    str3 = "Hello World";
 
    $display ("str1 = %s", str1);
    $display ("str2 = %s", str2);
    $display ("str3 = %s", str3);
  end
endmodule

仿真结果:

ncsim> run
str1 = Hello World
str2 = World
str3 =          Hello World
ncsim: *W,RNQUIE: Simulation is complete.

写在最后

猜你喜欢

转载自blog.csdn.net/Reborn_Lee/article/details/106970881
今日推荐