Propose :
在Verilog 中, 要如何計算"浮點數"跟"負數"乘法運算可以利用shift 的方式,把小數點以下的bit 當成 int 來做運算,之後再根據 point 的 position, shit 出 "整數" 跟 "小數" 的部份
ex : 1.625 * 3 = 4.875
float 1.625 = 16'h1.A = 2'b0001.1010
constrain : 整數 8 bit width, 小數 8 bit width
Step1 : 把point拿掉, 讓 16'h1.A 當成 16'h1A
Step2 : 16'h1A * 16'h3 = 32'h4E
Step3 : 加入先前的 point, 32'h4E -> 32'h4.E = float 4.875
Step4 : 4捨5入(positive), 5捨6入(negative) 取整數部份
Simulation Results
tools :
iverilog
Verilog codes :
float.v
module FLOAT( ot_c,
in_a
);
parameter WIDTH = 8;
output [WIDTH-1 : 0 ] ot_c;
input [WIDTH-1 : 0 ] in_a;
wire [0 : 0 ] p_n;
wire [WIDTH*2-1 : 0 ] ex_f;
wire [WIDTH-1 : 0 ] w_in_a;
wire [WIDTH*2+7 : 0 ] w_rst;
wire [WIDTH-1 : 0 ] w_ot_c;
//2'd 1.625 = 2'b 1.101
assign ex_f[15:8] = 16'h01;
assign ex_f[7 :0] = 16'ha0;
//define positive or negative
assign p_n = ( in_a[WIDTH-1] ==1'b1 )? 1'b1 : 1'b0;
assign w_in_a = ( p_n == 1'b1 )? ( 16'hff - in_a + 16'h01) : in_a;
assign w_rst = ( ex_f*w_in_a );
assign w_ot_c = w_rst[15:8];
assign ot_c = ( p_n ==1'b0 && w_rst[7] == 1'b1 )? w_ot_c + 16'h01 :
( p_n ==1'b0 && w_rst[7] == 1'b0 )? w_ot_c :
( p_n ==1'b1 && w_rst[7:0] >= 16'h99 )? 16'hff - w_ot_c :
( p_n ==1'b1 && w_rst[7:0] < 16'h99 )?16'hff - w_ot_c + 16'h01;
endmodule
float_tb.v
module FLOAT_TB;
reg [7:0] t_in_a;
initial begin
# 10 t_in_a = 10;
# 10 t_in_a = -10;
# 10 t_in_a = 0;
# 10 t_in_a = 77;
# 10 t_in_a = -77;
# 100 $stop;
end
// range -128 ~ +127
// 127/1.625 ~= 77
wire [7:0] t_ot_c;
FLOAT f1 (t_ot_c, t_in_a);
initial
$monitor("At time %t, t_in_a = %h :: t_ot_c = %h",
$time, t_in_a, t_ot_c);
endmodule //FLOAT_TB
compiler
% iverilog -o float float.v float_tb.v
% ./float
results
At time 0, t_in_a = xx :: t_ot_c = xx
At time 10, t_in_a = 0a :: t_ot_c = 10
At time 20, t_in_a = f6 :: t_ot_c = f0
At time 30, t_in_a = 00 :: t_ot_c = 00
At time 40, t_in_a = 4D :: t_ot_c = 7D
At time 50, t_in_a = b3 :: t_ot_c = 83
other refs:
(原創) 如何處理signed integer的加法運算與overflow? (SOC) (Verilog)
(原創) 如何計算浮點數? (SOC) (Verilog)
不知道可不可以簡單說一下每一行的功能@@
回覆刪除