Verilog HDL中数的表示与运算


1 数的表示

1.1 原码、反码和补码

        谁都知道。

1.2 浮点数的表示

        计算机中的浮点数标准IEEE 754表示浮点数n的方法:

符号位   指数位   尾数位  
s   e   m  
n=(-1)^s  * m * 2^e

        s:n>0时,s=0;n<0时,s=1。

        e:可正可负。

        m:有效数字位,尾数位。

        单精度浮点数用32位存储数据:符号位1位,指数位8位,尾数位23位。

        双精度浮点数用64位存储数据:符号位1位,指数位11位,尾数位52位。

        其中,浮点数的小数点左侧必须为1,因此在保留尾数时省略小数点左侧的这个1,从而腾出一个二进制位来保存更多的尾数。

        例如对于单精度数而言,二进制的1001.101(十进制为9.625)可以表示为1.001101*2^3,因此实际保存在尾数域中的值为00110100000000000000000,此时去掉小数点左侧的1,并用0在右侧补齐,这就是归一化。但当n非常小的时候,则无须归一化,否则e会超出表示范围。由于浮点数的特殊性,IEEE 754标准采用源码方式表示尾数。

        在指数域,由于单精度数为8位,可以表示的范围为0~255,共256个指数值。但是指数e可以为正数可以为负数。为了处理负数的情况,实际的指数值按要求需要加上一个偏差值作为保存在指数域中的值,单精度的偏差值为127,双精度的偏差值为1023。

#### 1.3 定点数的表示

        对于l位的定点数n,有两部分显式表示:符号位s和数据位m,整体采用补码表示,该值记为x,表示的范围为[-2^(l-1),2^(l-1)-1];而定标的指数位e是隐含的,因此当两个定点数指数位相同时,可以直接运算。

符号位   数据位  
s   m(l-1)  
n = x * 2^e

        例如,对于l=16的定点数,如果指数为e=15,即含有15位小数位,记为Q15或S0.15,则n=x*2^-15,表示范围为-1≤n≤0.999 9695。

        Q、S表示法如表:

Q表示法   S表示法   数值表示范围     表示精度
Q15 S0.15 -1≤n≤0.999 969 5 1/2^15
Q14 S1.14 -2≤n≤1.999 939 0 1/2^14
Q13 S2.13 -4≤n≤3.999 877 9 1/2^13
Q12 S3.12 -8≤n≤7.999 755 9 1/2^12
Q11 S4.11 -16≤n≤15.999 511 7 1/2^11
Q10 S5.10 -32≤n≤31.999 023 4 1/2^10
Q9 S6.9 -64≤n≤63.998 046 9 1/2^9
Q8 S7.8 -128≤n≤127.996 093 8 1/2^8
Q7 S8.7 -256≤n≤255.992 187 5 1/2^7
Q6 S9.6 -512≤n≤511.980 437 5 1/2^6
Q5 S10.5 -1024≤n≤1023.968 75 1/2^5
Q4 S11.4 -2048≤n≤2047.937 5 1/2^4
Q3 S12.3 -4096≤n≤4095.875 1/2^3
Q2 S13.2 -8192≤n≤8191.75 1/2^2
Q1 S14.1 -16384≤n≤16383.5 1/2^1
Q0 S15.0 -32768≤n≤32767 1/2^0

        但在芯片设计中,加减乘除运算不会关心Q是多少,而是直接按照整数补码运算。

        不同的Q所表示的数不仅范围不同,而且精度也不同。在浮点表示中单精度的Q值范围为[-127,+127],但实际上可以表达更大的范围,因为定点数的定标值隐藏在编程实现中,范围可以接近无穷大。

        浮点数与定点数的转化关系

浮点数n转换为定点数nq     定点数nq转换为浮点数n    
nq=int(n*2^Q) n=float(nq*2^-Q)

        例如,浮点数n=0.5,定标Q=15,则定点数nq=int(0.5*32768)=16384。

        定标Q=15的定点数为16384,其浮点数为16384*2^-15=16384/32768=0.5。

        浮点数转化为定点数时,为了降低截尾误差,通常在最后加上0.5。

        对定点数而言,当选定字长l后,数值范围与精度互相矛盾。同样,字长l越长,能表示的范围或精度也会相应提升,但消耗的硬件资源就会更多。因此,字长、精度、表示范围和资源消耗需要整体权衡。例如FFT定点化,对于WLAN系统,只需要12位精度就可以,但对于LTE系统,至少要14位精度才能保证基本性能。


2 定点数的运算规则

        对于加减运算以及要求输入数据具备相同字长的运算,定点数必须调整到相同字长。对于乘除运算、指数、对数等运算以及不要求对等字长的运算,则无须调整定点数字长。

2.1 定点数的运算举例

        以下均假设x、y、z为L位的定点数,temp则为大于L的定点数,用于储存中间结果的定点变量。他们的定标精度分别为Px、Py和Pz。

        如果x和y的定标精度相同,即Px=Py,则直接做加法即可,但由于x+y可能溢出,所以z的字长应当扩大1位,以获得全部精度;如果维持z的字长保持不变,则需要进行溢出判断处理,即:

    assign temp = {x[L-1],x}+ {y[L-1],y};
    assign z    = (temp[L-1]!=temp[L])?{ temp[L],{ { L-1 } { ~temp[L] } } }:temp[L-1:0];

        如果两者的定位精度不同,假定Px>Py,则用以下算法可实现定点加法:

    assign temp = x>>(Px-Py)+y;
    assign z    = (Px>Py)?temp<<(Px-Py):temp>>(Py-Pz);   //没有考虑溢出和饱和截位的情况

        上述加法预算是在已知定标长度的前提下,进行加法运算。现在换另外一种常见的场景:已知a是x位宽的有符号数据,b是y位宽的有符号数据,结果是z位宽的有符号数据c,a/b/c/定标相同,这段代码的设计实现为:

    localparam  x=10;
    localparam  y=12;
    localparam  z=16;

    wire [x-1:0] a;
    wire [y-1:0] b;
    wire [z-1:0] c;

    assign c[z-1:0] = { { { z-x } {a[x-1] } },a[x-1:0] } + { { { z-y} { b[y-1] } },b[y-1:0] };

        可以发现a与b均通过扩展符号位,达到相加结果z所要求的宽度然后相加。

2.2 定点数的移位规则

        逻辑移位的规则是,逻辑左移时,高位移出,低位填0;逻辑右移时,低位移出,高位填0.

        算术移位的规则是,移位时带符号位扩展,即算术右移时,移动后空缺的位置填充符号位;而算数左移等同逻辑左移,移位后空缺位置填0。

        在不考虑溢出和提高截断精度的情况下,针对用原码、反码和补码的形式 表示的定点数,在保证移位后符号位不变的前提下,左移和右移按照下表规则进行:

数值类型     码制     填补代码    
正数 原码、补码、反码 0
  原码 0
负数 补码 左移填0,右移填1
  反码 1

        例如,,寄存器内容为01110011,逻辑左移1位为11100110,算数左移1位后的结果为01100110(最高位的1丢弃)。又如寄存器内容为10111010,逻辑右移为01011101,若将其视为补码,算术右移为11011101。

        因此Verilog中的移位符号只针对带符号位的补码和无符号位的原码有效,对有符号的原码或反码移位,数据则会出错。


        告辞。

Back to Archive
WeChat QR Code

Scan to connect