2010年6月25日 星期五

float point @ verilog

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)

1 則留言: