Menu Close

Verilog 变量声明与数据类型二

上节介绍了wire,reg数据类型及其用法,并对变量定义中的向量的定义及使用做了说明。本节主要介绍其它几种类型。常用的有如下几种:整数integer,实数 real, 时间time,字符串等,他们本质上也是寄存器类型。

1.整型integer

整形变量用关键字integer 声明,在声明时不用指定位宽,位宽的大小和编译器有关,一般默认为32位。和reg关键字不同,如没有特别指定,reg型变量是无符号数,而integer声明的变量是有符号数的。integer类型的数据一般作为循环变量用在循环语句中。

例:

reg [31:0] a;
reg [31:0] b;
 
integer  i;
 
always@(*)
    for (i = 1; i <= 4; i = i + 1)
        b[(i*8-1)-:8] = a[(i*8-1)-:8];

 

上例中,变量i只起到循环辅助作用,真正综合后该变量不存在,实际综合后与下面的代码等效。

reg [31:0] a;
reg [31:0] b;
 
integer  i;
 
always@(*)
    b[31:0] = a[31:0];

 

2. 实数(real)类型

实数用关键字 real 来声明,可用十进制或科学计数法来表示。实数声明不能带有范围,默认值为 0。如果将一个实数赋值给一个整数,则只有实数的整数部分会赋值给整数(采用四舍五入)。例如:

real      ra ;
integer   ib ;
reg [7:0] temp;
   
initial  begin
    ib = 0;
    ra = 4e5 ;
    #10
    ra = 8.7;          //ra可以真实得到8.7
    ib = ra ;   //ib=9 
    #10 ib = 8.49;  //ib=8
end
     
always@(*)
    temp = ib ; //temp 值变化0----9---8

 

实数类型是不可以综合的类型,一般在高层建模时用做算法仿真。真正在RTL现实时应使用浮点RTL逻辑实现。

  • 整数,实数仿真文件:
`timescale 1ns/1ps

module tb_sim();

reg [31:0] a = 0;
reg [31:0] b = 0;

integer i;

always@(*)
for (i = 1; i <= 4; i = i + 1)
    b[(i*8-1)-:8] = a[(i*8-1)-:8];

initial begin
    a = 0;
    b = 0;
    #10

    a = 32'habcd_ef98;

    #10;
end

//==========================================================


real ra;
integer ib;
reg [7:0] temp;

initial begin
    ib = 0;
    ra = 4e5;
    #10

    ra = 8.7; //ra可以真实得到8.7
    ib = ra;  //ib=9 

    #10 ib = 8.49; //ib=8

    #10 ra = 8.49; //ra = 8.49
    #10 ib = ra;   //ib=8

    #200;
    $stop();
end

always@(*)
    temp = ib; //temp 值变化0----9---8


endmodule

 

  • modelsim下的仿真波形如图1,

%title插图%num

图1

 

3. 时间(time

Verilog 使用特殊的时间寄存器 time 型变量,对仿真时间进行保存。其宽度一般为 64 bit,通过调用系统函数 $time 获取当前仿真时间。例如:

time current_time ;
initial begin
    #100 ;
    current_time = $time ;
//current_time 的大小为 100

end

 


time类型也是不可综合的,但在仿真时可以提供非常方便的时间统计信息。

4. 存储器类型

存储器变量不是一个新的的变量类型,是reg类型的数组。可用来描述 RAM ,ROM ,FIFO等存储器的行为。

例如:

reg membit [0:15] ;
// 16个1bit存储器,位宽1bit

reg [7:0] mem [0:1023];
// 1Kbyte存储器,位宽8bit

mem[0] = 8'b0 ;
// 令第0个8bit的存储单元值为0

 


存储器赋初值可以用for循环语句实现。目前在

Intel,Xilinx的FPGA中都有block memory, 只要设置得当在综合时会自动引用block memory。

细节内容见 Verilog ROM 的建模与使用及Verilog RAM 的建模与使用。

5. 字符串

字符串保存在 reg 类型的变量中,每个字符占用一个字节(8bit)。因此寄存器变量的宽度应该足够大,以保证不会溢出。

字符串不能多行书写,即字符串中不能包含回车符。如果寄存器变量的宽度大于字符串的大小,则使用 0 来填充左边的空余位;如果寄存器变量的宽度小于字符串大小,则会截去字符串左边多余的数据。例如,为存储字符串 “www.icfedu.cn”, 需要 14*8byte 的存储单元:

  • 实例
reg [0: 14*8-1]       str ;

initial
begin
     str = “www.ica123.com”;
end

 

对应视频:

Posted in FPGA, FPGA 教材教案, IC, Verilog, Verilog, 文章

1 Comment

  1. wangff

    学习本篇文章后有几点收获,1、整型(integer)变量一般默认为32bit,有符号数;2、实数类型(real)变量赋值给整数变量时,只有整数部分(四舍五入)赋值给整数变量;3、实数类型不可综合;4、时间类型(time)变量位宽64bit,不可综合;5、存储器类型是reg类型数组;6、字符串保存在reg类型变量中,每个字符占用1个字节(8bit);

    文中对每一种类型均配有案例分析以及仿真图形,对比效果十分鲜明,非常有利于理解,谢谢老师!

发表回复

相关链接