SV强制类型转换和常数

1. 强制类型转换

1.1 静态转换(编译时转换)

静态转换有三种,分别是数据类型强制转换、向量宽度强制转换和符号强制转换,格式分别为:

  • 数据类型强制转换:’()

    7 + int'(2.0 * 3.0);	//将(2.0 * 3.0)的结果转换成整型
    				    //然后加7
    
  • 向量宽度强制转换:’()

    logic	[15:0]	a, b, y;
    y = a + b ** 16'(2);	//将文本值2强制转换为16位宽
    
  • 符号强制转换:’()

    shortint	a, b;
    int			y;
    y = y - singed'({a, b});	//将拼接结果强制转换成有符号值
    

静态强制转换是编译时的转换,转换的操作总会运行,而不会检查结果的有效性

下面对数据类型强制转换和向量宽度强制转换做了仿真:

module trans_static_tb;
    int         i;
    logic [2:0] a;

    initial begin
        i = 1 + int'(1.0 + 2.0); //静态类型转换,
                                //强制转换成 int类型
        a = 3'b100;
    end

    initial begin
        $display ("\n \t the var i is: %0d", i);
        $display ("\n \t the array is: %b", 8'(a)); //静态类型转换,
                                                     //打印时将为宽拓展至8位
    end
endmodule

仿真结果如下:

SV强制类型转换和常数

1.2 动态强制类型转换

系统函数$cast是动态的,并且在运行时进行带转换数值的检查

动态强制类型转换的格式为:$cast(dest_var, source_var);,系统函数$cast有两个变量:目标变量和源变量

下面几种情况会导致无效的强制类型转换:

  • 将real类型转换成int类型,而实数太大,没有办法用int来描述

    int	radius, area;
    always @(posedge clock)
        $cast (area, 3.154 * radius ** 2);	//强制转换操作符的结果被装换为area类型
    
  • 将一个数值转换成枚举类型,而它不在枚举类型的合法值列表中

    typedef enum {s1, s2, s3} state_t;
    state_t	state, next_state;
    
    always_latch begin
        $cast (next_state, state + 1);
    end
    

$cast可以作为任务调用也可以作为函数调用,作为任务调用时,如果转换不成功,会报告运行时错误,但作为函数调用时,不会报告运行时错误

系统函数$cast具有返回值,如果转换成功,返回1;转换失败,返回0

例如:

typedef enum {s1, s2, s3} state_t;
state_t	state, next_state;

always_comb begin
    status = $cast(next_state, state + 1);
    if(status == 0)	//如果强制转换不成功
        next_state = s1;	
end

$cast函数不能和直接修改源表达式的操作符(++, +=)一块用

$cast函数主要用途是将表达式的结果赋给枚举类型变量

静态强制转换是可综合的,动态强制转换由于一些综合工具可能不支持$cast系统函数

系统函数和系统任务都是不可综合的

下面这个例子,将0.25*8动态装换成int类型,并通过系统函数$cast判断转换是否成功

module trans_auto_tb;
    bit a;
    int value;

    initial begin
        a = $cast(value, 0.25 * 8); //将0.25*8的值转换成int类型
                                    //若转换成功,a为1,否则a为0
    end

    initial begin
        $display ("\n \t a is: %b", a);
        $display ("\n \t value is: %d", value);
    end
endmodule

仿真结果如下:

SV强制类型转换和常数

2. 常数

2.1 Verilog中的常数

Verilog提供了三种常数类型parameterspecparamlocalparam

  • parameter:可以在确立时使用defparam或者内嵌参数重定义进行重新定义的常数
  • specparam:可以在确立时从SDF文件中重定义的常数
  • localparam:确立期常数,不能重定义,但其价值可以基于其他常数

确立实质上是软件工具建立模块实例代表的设计层次的过程

Verilog限制parameterspecparamlocalparam常数的声明只能在模块、静态任务和静态函数中,不允许在动态任务和动态函数中

2.2 SV中的常数

关键字const允许将任何变量声明为常数,const形式的常数直到确立完成后才被赋值

const常数的使用范围:

  • 在动态任务和函数等动态环境中声明
  • 被赋予一个线网或变量值而非常数表达式
  • 被赋予一个对象值,这个值可以在任何设计层次定义

const常数的声明必须包含数据类型,例如:

const	logic	[23:0]	C1 = 7;	//24位常数const	int		C2 = 15;	//32位常数const	real	C3 = 3.14;	//实数常数const	C4 = 5;	//错误,因为没有给定数据类型

const常数实质上是一个只能被初始化的变量

上一篇:sv assertion示例


下一篇:Wireshark按照采样通道解析IEC61850-9-2报文(SV报文)