teacup. [ 掲示板 ] [ 掲示板作成 ] [ 有料掲示板 ] [ ブログ ]

新着順:8/62 記事一覧表示 | 《前のページ | 次のページ》

修正してみたverilog

 投稿者:管理人  投稿日:2009年 1月 9日(金)23時01分7秒
  通報
  /************************************************************************/
/* floating point multiplier (float) */
/* 2006.03.07 */
/************************************************************************/

module fl_multa (
fl_o, // floating output
fl_ia, // floating input a
fl_ib ); // floating input b

input [31:00] fl_ia; // floating input a
input [31:00] fl_ib; // floating input b

output [31:00] fl_o; // floating output

parameter Ofst = 8'b01111111; //parameter: 定数定義

parameter Zero = 31'b0000000000000000000000000000000; // { 8'h00, 23'h000000 };
parameter Inf = 31'b1111111100000000000000000000000; // { 8'hff, 23'h000000 };
parameter Nan = 31'b1111111110000000000000000000000; // { 8'hff, 23'h400000 };

//  function (round to even)
    // step0 ( detect exception )
wire exp00a;
assign exp00a = (fl_ia[30:23] == 8'b00000000) ? 1'b1 : 1'b0;
wire exp00b;
assign exp00b = (fl_ib[30:23] == 8'b00000000) ? 1'b1 : 1'b0;
wire expffa;
assign expffa = (fl_ia[30:23] == 8'b11111111) ? 1'b1 : 1'b0;
wire expffb;
assign expffb = (fl_ib[30:23] == 8'b11111111) ? 1'b1 : 1'b0;
wire snf_0a;
assign snf_0a = (fl_ia[22:00] == 23'b00000000000000000000000) ? 1'b1 : 1'b0; // reduction NOR
wire snf_0b;
assign snf_0b = (fl_ib[22:00] == 23'b00000000000000000000000) ? 1'b1 : 1'b0; // reduction NOR

    // step1 ( multiply )
wire [47:00] snf_1a;
assign snf_1a = { (~exp00a), fl_ia[22:00] } * { (~exp00b), fl_ib[22:00] };
wire [09:00] exp_1a;
assign exp_1a = { 2'b00, fl_ia[30:23]} + { 2'b00, fl_ib[30:23] } - { 2'b00, Ofst };
wire sin_1a;
assign sin_1a = fl_ia[31] ^ fl_ib[31];

    // step2 ( standardize )
wire [47:21] snf_2a;
wire snf_2a_tmp;
assign snf_2a_tmp = (snf_1a[21:00] == 0) ? 1'b0 : 1'b1; // reduction OR
assign snf_2a = { snf_1a[47:22], snf_2a_tmp };
wire [46:20] snf_2b;
assign snf_2b = (snf_1a[47] == 1'b1) ? snf_2a[47:21] : { snf_2a[46:21], 1'b0 };
wire [09:00] exp_2a;
assign exp_2a = exp_1a + snf_1a[47];

    // step3 ( round )
wire b_least;
assign b_least = snf_2b[23];
wire b_guard;
assign b_guard = snf_2b[22];
wire b_round;
assign b_round = snf_2b[21];
wire b_stiky;
assign b_stiky = snf_2b[20];

wire all_1;
assign all_1 = ((~snf_2a[46:24]) == 0) ? 1'b1 : 1'b0; // reduction AND
wire en_inc;
assign en_inc =  b_guard & ( b_least | b_round | b_stiky );
/******************************************************************
lp Guard Round Sticky operation
0 0 - -
0 1 0 0 round even
0 1 0 1 increment
0 1 1 - increment
1 0 - -
1 1 0 0 increment round even
1 1 0 1 increment
1 1 1 - increment
******************************************************************/

wire [23:00] snf_3a;
assign snf_3a = snf_2b[46:23] +   en_inc;
wire [09:00] exp_3a;
assign exp_3a = exp_2a        + ( en_inc & all_1 );

    // step4 ( limit )
wire [22:00] snf_4a;
assign snf_4a = (exp_3a[09] == 1'b1) ? 23'b00000000000000000000000 :
(exp_3a[08] == 1'b1) ? 23'b00000000000000000000000 : snf_3a[22:00];
wire [07:00] exp_4a;
assign exp_4a = (exp_3a[09] == 1'b1) ? 8'b00000000 :
(exp_3a[08] == 1'b1) ? 8'b11111111 : exp_3a[07:00];

    // step5 ( exception compensation )
/**** denormalized number not supported ***************************
exp_a snf_a exp_b snf_b exp_o snf_o description
00 any 00 any 00 000000 0   * 0   = 0
ff ==0 00 400000 0   * inf = NaN
!=0 00 400000 0   * NaN = NaN
else any 00 000000 0   * nom = 0
ff ==0 00 any 00 000000 inf * 0   = NaN
ff ==0 00 400000 inf * inf = inf
!=0 00 400000 inf * NaN = NaN
else any 00 000000 inf * nom = inf
!=0 00 any 00 000000 NaN * 0   = NaN
ff ==0 00 400000 NaN * inf = NaN
!=0 00 400000 NaN * NaN = NaN
else any 00 000000 NaN * nom = NaN
else any 00 any 00 000000 nom * 0   = 0
ff ==0 00 400000 nom * inf = inf
!=0 00 400000 nom * NaN = NaN
else any 00 000000 nom * nom = nom
******************************************************************/
function [30:00] fexcpt;
input exp00a, exp00b;
input expffa, expffb;
input snf_0a, snf_0b;
input [30:00] nom_in;
reg [5:0] sel;
begin
sel = { exp00a, expffa, snf_0a, exp00b, expffb, snf_0b };
case (sel)
6'b100100 : fexcpt = Zero ; // 0   * 0   = 0
6'b100101 : fexcpt = Zero ; // 0   * 0   = 0
6'b101100 : fexcpt = Zero ; // 0   * 0   = 0
6'b101101 : fexcpt = Zero ; // 0   * 0   = 0

6'b100011 : fexcpt = Nan ; // 0   * inf = NaN
6'b101011 : fexcpt = Nan ; // 0   * inf = NaN

6'b100010 : fexcpt = Nan ; // 0   * NaN = NaN
6'b101010 : fexcpt = Nan ; // 0   * NaN = NaN

6'b100000 : fexcpt = Zero ; // 0   * nom = 0
6'b100001 : fexcpt = Zero ; // 0   * nom = 0
6'b101000 : fexcpt = Zero ; // 0   * nom = 0
6'b101001 : fexcpt = Zero ; // 0   * nom = 0

6'b011100 : fexcpt = Nan ; // inf * 0   = NaN
6'b011101 : fexcpt = Nan ; // inf * 0   = NaN

6'b011011 : fexcpt = Inf ; // inf * inf = inf

6'b011010 : fexcpt = Nan ; // inf * NaN = NaN

6'b011000 : fexcpt = Inf ; // inf * nom = inf
6'b011001 : fexcpt = Inf ; // inf * nom = inf

6'b010000 : fexcpt = Nan ; // NaN * any = NaN
6'b010001 : fexcpt = Nan ; // NaN * any = NaN
6'b010010 : fexcpt = Nan ; // NaN * any = NaN
6'b010011 : fexcpt = Nan ; // NaN * any = NaN
6'b010100 : fexcpt = Nan ; // NaN * any = NaN
6'b010101 : fexcpt = Nan ; // NaN * any = NaN
6'b010110 : fexcpt = Nan ; // NaN * any = NaN
6'b010111 : fexcpt = Nan ; // NaN * any = NaN

6'b000100 : fexcpt = Zero ; // nom * 0   = 0
6'b000101 : fexcpt = Zero ; // nom * 0   = 0
6'b001100 : fexcpt = Zero ; // nom * 0   = 0
6'b001101 : fexcpt = Zero ; // nom * 0   = 0

6'b000011 : fexcpt = Inf ; // nom * inf = inf
6'b001011 : fexcpt = Inf ; // nom * inf = inf

6'b000010 : fexcpt = Nan ; // nom * NaN = NaN
6'b001010 : fexcpt = Nan ; // nom * NaN = NaN

6'b000000 : fexcpt = nom_in; // nom * nom = nom
6'b000001 : fexcpt = nom_in; // nom * nom = nom
6'b001000 : fexcpt = nom_in; // nom * nom = nom
6'b001001 : fexcpt = nom_in; // nom * nom = nom

default    : fexcpt = Nan ; // error     = NaN
endcase
end
endfunction

wire [22:00] snf_5a;
wire [07:00] exp_5a;
wire [30:00] fexcpt_tmp;
assign fexcpt_tmp
= fexcpt(exp00a, exp00b,
expffa, expffb,
snf_0a, snf_0b,
{exp_4a, snf_4a});
assign exp_5a = fexcpt_tmp[30:23];
assign snf_5a = fexcpt_tmp[22:00];

    // output
wire [22:00] fl_snf;
assign fl_snf = snf_5a;
wire [07:00] fl_exp;
assign fl_exp = exp_5a;
wire fl_sin;
assign fl_sin = sin_1a;

assign fl_o = { fl_sin, fl_exp, fl_snf };

endmodule
 
 
》記事一覧表示

新着順:8/62 《前のページ | 次のページ》
/62