System Verilog 中小数的计算、四舍五入的实现

目录

system verilog 中四舍五入问题:

1、real类型数据:

2、int / bit类型数据:

SV中小数的计算:


system verilog 中四舍五入问题:

1、real类型数据:

SV中小数用real类型来表示,IEEE中说明,real类型相当于C中的double类型,shortreal相当于C中的single类型,real的取值范围是3.4E-38 ~3.4E+38 。

real类型的小数想要进行四舍五入,可以扩大一定的倍数后int取整,然后再转换为real类型,再缩小相同的倍数。例:

real     check_a;
real     check_b;

check_a = 3.0853; 
check_b = (real'(int'(check_a*100)))/100;   //保留两位小数
check_c = (real'(int'(check_a*1000)))/1000; //保留三位小数
$display("check_b = %0f",check_b);
$display("check_c = %0f",check_c);
打印结果:
check_a = 3.090000;
check_b = 3.085000;

2、int / bit类型数据:

(1)直接赋值小数,会进行四舍五入取整;

(2)计算过程中,如果有小数,会把小数部分直接截掉,不进行四舍五入;

(3)计算过程中,如果等号右侧表达式中各项乘以1.0,就不会直接截掉小数,会把数据进行四舍五入取整。

int/bit [7:0]     check_a;
int/bit [7:0]     check_b;
int/bit [7:0]     check_c;
int/bit [7:0]     check_d;

check_a = 3.99;
check_b = 3.5;
check_c = 3.093;
check_d = check_a + check_b + check_c; // 4+4+3
$display("check_a = %0f",check_a);
$display("check_b = %0f",check_b);
$display("check_c = %0f",check_c);
$display("check_d = %0f",check_d);
打印结果:
check_a = 4.000000;
check_b = 4.000000;
check_c = 3.000000;
check_d = 11.000000;
-----------------------------------
int/bit [7:0]     check_e;
int/bit [7:0]     check_f;

check_e = 7/4 + 7/4; //相当于1+1 而不是1.75 + 1.75
check_e = 1.0*7/4 + 1.0*7/4; //相当于2+2
$display("check_e = %0f",check_e);
$display("check_f = %0f",check_f);
打印结果:
check_e = 2.000000;
check_f = 4.000000; 

计算时如果想要四舍五入,可以在表达式的最左侧乘以1.0,,乘在右侧无效。

例:

int      check_c;

check_c = 1.0*6/4;
$display("check_c = %0f",check_c);
check_c = (6/4)*1.0; //乘在右侧无法四舍五入
$display("check_c = %0f",check_c);
打印结果:
check_c = 2.000000;
check_c = 1.000000;

SV中小数的计算:

如果是real类型的数据,直接计算就可以;

如果是int类型的数据,想让小数参与运算,可以将数据按一定的倍数增大计算完后再缩小相同的倍数,缩回原来的倍数后如果结果有小数会被直接截掉取整,不会进行四舍五入。 

如果0.2 x 8= 1.6,那么verilog是取1.6中的整数进行计算,误差就是(1.6-1)/1.6 = 0.375 左右;

如果0.2 x 16= 3.2,那么verilog是用3进行计算,误差范围是0.2/3.2 = 0.0625;

相比之下增大倍数越大同倍数减少时误差范围越来越小,但是不需要夸张的增加放大倍数,通过实际情况,在合理的误差范围内就可以了。

例:

int      check_a;
int      check_b;

check_a = 7/4 + 7/4; //1+1
check_b = (100*7/4 + 100*7/4)/100; //350/100=3.5 截掉小数

$display("check_a = %0f",check_a);
$display("check_b = %0f",check_b);
打印结果:
check_c = 2.000000;
check_c = 3.000000;


版权声明:本文为zhangduang_KHKW原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。