(转帖)如何計算浮點數? (Verilog)

原创地址:http://www.cnblogs.com/oomusou/archive/2008/10/11/verilog_floating.html

Abstract
演算法常常會遇到浮點數運算,如何計算浮點數是Verilog初學者常問的問題。

Introduction
使用環境:Quartus II 8.0

在DE2的DE2_TV與DE2-70的DE2_70_TV範例中,有個YCbCr2RGB.v,負責將YCbCr轉成RGB,其公式如下:

R = 1.164(Y-16) + 1.596(Cr-128)
G
= 1.164(Y-16) - 0.391(Cb-128) - 0.813(Cr-128
)
B
= 1.164(Y-16) + 2.018(Cb-128)


將YCbCr轉成RGB牽涉到浮點數運算,這在Verilog是一項挑戰,並不像C那麼簡單,由於YCbCr2RGB.v比較複雜些,比較不適合當範例,而攝氏溫度轉華氏溫度可能是最簡單的浮點運算。

F = C * 1.8 + 32


C為攝氏溫度,F為華氏溫度,我們來看看如何用Verilog實現。

CF2_bad.v / Verilog 

1 module C2F_bad (
2   input
         iCLK,
3   input
         iRST_N,
4   input  [7:0
]  iC,
5   output [10:0
] oF
6 
);
7 

8 reg [7:0]  c;
9 reg [10:0
] f;
10 

11 assign oF = f;
12 

13 always@(posedge iCLK, negedge iRST_N) begin
14   if (!iRST_N) begin
15     c <= 0;
16     f <= 0
;
17   end

18   else begin
19     f <= c * 1.8 + 32;
20   end

21 end
22 
23 endmodule


Quartus II編譯後,出現以下錯誤訊息:

Error (10125): Verilog HDL error at C2F_bad.v(19): must use only constant operands for operator "*"


看來Verilog果然不能直接使用浮點數做運算。

C2F_good.v / Verilog

1 /* 
2 (C) OOMusou 2008 http://oomusou.cnblogs.com

3 
4 Filename    : C2F_good.v
5 
Compiler    : Quartus II 8.0
6 
Description : Demo how to calculate float;
7 
Release     : 10/11/2008 1.0
8 */

9 
10 module C2F_good (
11   input
         iCLK,
12   input
         iRST_N,
13   input  [7:0
]  iC,
14   output [10:0
] oF
15 
);
16 

17 reg [7:0]  c;
18 reg [10:0
] f;
19 reg [10:0
] sum;
20 

21 assign oF = f;
22 

23 always@(posedge iCLK, negedge iRST_N) begin
24   if (!iRST_N) begin
25     c   <= 0;
26     f   <= 0
;
27     sum <= 0
;
28   end

29   else begin
30     c   <= iC;
31     sum <= c * 7 + 128
;
32     f   <= sum >> 2
;
33   end

34 end
35 
36 endmodule


模擬結果

float00


除了第2個clock由於sum的值還沒來,所以32是錯的外,從第3個clock起的值都是對的。

合成結果

float01

Fmax為237.19MHz

float02

目前還沒用pipeline就已經237.19MHz,若加上pipeline還可更高。

31行

sum <= c * 7 + 128;
f  
<= sum >> 2;


關鍵程式碼只有這兩行,為什麼這樣就能計算浮點數呢?

原來的算式如下

F = C * 1.8 + 32


現在將F向左移兩位,所以右邊每一項要乘以2 ^ 2 = 4 ,1.8 * 4 = 7.2,近似取7,32 * 4 = 128。

至於要放大幾位,並沒有一定的方式,由於shift的特性,只能放大2的n次方,讓浮點數放大後,能儘量接近整數即可。

F << 2 = C * 7 + 128


32行

f   <= sum >> 2;


因為之前放大了4倍,所以在右移2位回來。

完整程式下載
C2F_good.7z

Conclusion
這種方式的優點是:速度快,且面積小,硬體容易實現,缺點是準確度較差,且受限於表示位數,必要時需搭配軟體模擬。

See Also
(原創) 如何使用Verilog將YCbCr轉RGB? (SOC) (Verilog) (DE2-70)

posted on 2010-07-23 22:47  小麻同学  阅读(3037)  评论(0编辑  收藏  举报

导航