Add fpu verilog files
diff --git a/verilog/rtl/ips/fpu b/verilog/rtl/ips/fpu
deleted file mode 160000
index 42b9437..0000000
--- a/verilog/rtl/ips/fpu
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 42b943772a6467ac91b58b051c6f5798b204173b
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/control_tp.v b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/control_tp.v
new file mode 100644
index 0000000..0f32b98
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/control_tp.v
@@ -0,0 +1,599 @@
+module control_tp
+#(
+ parameter Precision_ctl_Enable_S = 1
+)
+(
+ Clk_CI,
+ Rst_RBI,
+ Div_start_SI,
+ Sqrt_start_SI,
+ Start_SI,
+ Precision_ctl_SI,
+ Numerator_DI,
+ Exp_num_DI,
+ Denominator_DI,
+ Exp_den_DI,
+ First_iteration_cell_sum_DI,
+ First_iteration_cell_carry_DI,
+ Sqrt_Da0,
+ Sec_iteration_cell_sum_DI,
+ Sec_iteration_cell_carry_DI,
+ Sqrt_Da1,
+ Thi_iteration_cell_sum_DI,
+ Thi_iteration_cell_carry_DI,
+ Sqrt_Da2,
+ Fou_iteration_cell_sum_DI,
+ Fou_iteration_cell_carry_DI,
+ Sqrt_Da3,
+ Div_start_dly_SO,
+ Sqrt_start_dly_SO,
+ Div_enable_SO,
+ Sqrt_enable_SO,
+ Sqrt_D0,
+ Sqrt_D1,
+ Sqrt_D2,
+ Sqrt_D3,
+ First_iteration_cell_a_DO,
+ First_iteration_cell_b_DO,
+ Sec_iteration_cell_a_DO,
+ Sec_iteration_cell_b_DO,
+ Thi_iteration_cell_a_DO,
+ Thi_iteration_cell_b_DO,
+ Fou_iteration_cell_a_DO,
+ Fou_iteration_cell_b_DO,
+ Ready_SO,
+ Done_SO,
+ Mant_result_prenorm_DO,
+ Exp_result_prenorm_DO
+);
+parameter C_DIV_RM = 2;
+parameter C_DIV_RM_NEAREST = 2'h0;
+parameter C_DIV_RM_TRUNC = 2'h1;
+parameter C_DIV_RM_PLUSINF = 2'h2;
+parameter C_DIV_RM_MINUSINF = 2'h3;
+parameter C_DIV_PC = 5;
+parameter C_DIV_OP = 32;
+parameter C_DIV_MANT = 23;
+parameter C_DIV_EXP = 8;
+parameter C_DIV_BIAS = 127;
+parameter C_DIV_BIAS_AONE = 8'h80;
+parameter C_DIV_HALF_BIAS = 63;
+parameter C_DIV_MANT_PRENORM = C_DIV_MANT+1;
+parameter C_DIV_EXP_ZERO = 8'h00;
+parameter C_DIV_EXP_ONE = 8'h01;
+parameter C_DIV_EXP_INF = 8'hff;
+parameter C_DIV_MANT_ZERO = 23'h0;
+parameter C_DIV_MANT_NAN = 23'h400000;
+
+
+
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+parameter C_FFLAG = 5;
+ //parameter Precision_ctl_Enable_S = 1;
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire Div_start_SI;
+ input wire Sqrt_start_SI;
+ input wire Start_SI;
+ input wire [C_DIV_PC - 1:0] Precision_ctl_SI;
+ input wire [C_DIV_MANT:0] Numerator_DI;
+ input wire [C_DIV_EXP:0] Exp_num_DI;
+ input wire [C_DIV_MANT:0] Denominator_DI;
+ input wire [C_DIV_EXP:0] Exp_den_DI;
+ input wire [C_DIV_MANT + 1:0] First_iteration_cell_sum_DI;
+ input wire First_iteration_cell_carry_DI;
+ input wire [1:0] Sqrt_Da0;
+ input wire [C_DIV_MANT + 1:0] Sec_iteration_cell_sum_DI;
+ input wire Sec_iteration_cell_carry_DI;
+ input wire [1:0] Sqrt_Da1;
+ input wire [C_DIV_MANT + 1:0] Thi_iteration_cell_sum_DI;
+ input wire Thi_iteration_cell_carry_DI;
+ input wire [1:0] Sqrt_Da2;
+ input wire [C_DIV_MANT + 1:0] Fou_iteration_cell_sum_DI;
+ input wire Fou_iteration_cell_carry_DI;
+ input wire [1:0] Sqrt_Da3;
+ output wire Div_start_dly_SO;
+ output wire Sqrt_start_dly_SO;
+ output reg Div_enable_SO;
+ output reg Sqrt_enable_SO;
+ output reg [1:0] Sqrt_D0;
+ output reg [1:0] Sqrt_D1;
+ output reg [1:0] Sqrt_D2;
+ output reg [1:0] Sqrt_D3;
+ output wire [C_DIV_MANT + 1:0] First_iteration_cell_a_DO;
+ output wire [C_DIV_MANT + 1:0] First_iteration_cell_b_DO;
+ output wire [C_DIV_MANT + 1:0] Sec_iteration_cell_a_DO;
+ output wire [C_DIV_MANT + 1:0] Sec_iteration_cell_b_DO;
+ output wire [C_DIV_MANT + 1:0] Thi_iteration_cell_a_DO;
+ output wire [C_DIV_MANT + 1:0] Thi_iteration_cell_b_DO;
+ output wire [C_DIV_MANT + 1:0] Fou_iteration_cell_a_DO;
+ output wire [C_DIV_MANT + 1:0] Fou_iteration_cell_b_DO;
+ output reg Ready_SO;
+ output reg Done_SO;
+ output wire [C_DIV_MANT:0] Mant_result_prenorm_DO;
+ output wire [C_DIV_EXP + 1:0] Exp_result_prenorm_DO;
+ reg [C_DIV_MANT + 1:0] Partial_remainder_DN;
+ reg [C_DIV_MANT + 1:0] Partial_remainder_DP;
+ reg [C_DIV_MANT:0] Quotient_DP;
+ wire [C_DIV_MANT + 1:0] Numerator_se_D;
+ wire [C_DIV_MANT + 1:0] Denominator_se_D;
+ wire [C_DIV_MANT + 1:0] Denominator_se_DB;
+ assign Numerator_se_D = {1'b0, Numerator_DI};
+ assign Denominator_se_D = {1'b0, Denominator_DI};
+ assign Denominator_se_DB = ~Denominator_se_D;
+ wire [C_DIV_MANT + 1:0] Mant_D_sqrt_Norm;
+ assign Mant_D_sqrt_Norm = (Exp_num_DI[0] ? {1'b0, Numerator_DI} : {Numerator_DI, 1'b0});
+ reg [C_DIV_PC - 1:0] Precision_ctl_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Precision_ctl_S <= 'b0;
+ else if (Start_SI) begin
+ if (Precision_ctl_Enable_S == 1)
+ Precision_ctl_S <= Precision_ctl_SI;
+ else
+ Precision_ctl_S <= 5'b10111;
+ end
+ else
+ Precision_ctl_S <= Precision_ctl_S;
+ reg [2:0] State_ctl_S;
+ always @(*)
+ if (Precision_ctl_Enable_S == 1)
+ case (Precision_ctl_S)
+ 5'b01000, 5'b01001, 5'b01010, 5'b01011: State_ctl_S <= 3'b010;
+ 5'b01100, 5'b01101, 5'b01110, 5'b01111: State_ctl_S <= 3'b011;
+ 5'b10000, 5'b10001, 5'b10010, 5'b10011: State_ctl_S <= 3'b100;
+ 5'b10100, 5'b10101, 5'b10110, 5'b10111: State_ctl_S <= 3'b101;
+ default: State_ctl_S <= 3'b101;
+ endcase
+ else
+ State_ctl_S <= 3'b101;
+ reg Div_start_dly_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Div_start_dly_S <= 1'b0;
+ else if (Div_start_SI)
+ Div_start_dly_S <= 1'b1;
+ else
+ Div_start_dly_S <= 1'b0;
+ assign Div_start_dly_SO = Div_start_dly_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Div_enable_SO <= 1'b0;
+ else if (Div_start_SI)
+ Div_enable_SO <= 1'b1;
+ else if (Done_SO)
+ Div_enable_SO <= 1'b0;
+ else
+ Div_enable_SO <= Div_enable_SO;
+ reg Sqrt_start_dly_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Sqrt_start_dly_S <= 1'b0;
+ else if (Sqrt_start_SI)
+ Sqrt_start_dly_S <= 1'b1;
+ else
+ Sqrt_start_dly_S <= 1'b0;
+ assign Sqrt_start_dly_SO = Sqrt_start_dly_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Sqrt_enable_SO <= 1'b0;
+ else if (Sqrt_start_SI)
+ Sqrt_enable_SO <= 1'b1;
+ else if (Done_SO)
+ Sqrt_enable_SO <= 1'b0;
+ else
+ Sqrt_enable_SO <= Sqrt_enable_SO;
+ reg [2:0] Crtl_cnt_S;
+ wire Start_dly_S;
+ assign Start_dly_S = Div_start_dly_S | Sqrt_start_dly_S;
+ wire Fsm_enable_S;
+ assign Fsm_enable_S = Start_dly_S | |Crtl_cnt_S[2:0];
+ wire Final_state_S;
+ assign Final_state_S = Crtl_cnt_S == State_ctl_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Crtl_cnt_S <= 1'sb0;
+ else if (Final_state_S)
+ Crtl_cnt_S <= 1'sb0;
+ else if (Fsm_enable_S)
+ Crtl_cnt_S <= Crtl_cnt_S + 1;
+ else
+ Crtl_cnt_S <= 1'sb0;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Done_SO <= 1'b0;
+ else if (Start_SI)
+ Done_SO <= 1'b0;
+ else if (Final_state_S)
+ Done_SO <= 1'b1;
+ else
+ Done_SO <= 1'b0;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Ready_SO <= 1'b1;
+ else if (Start_SI)
+ Ready_SO <= 1'b0;
+ else if (Final_state_S)
+ Ready_SO <= 1'b1;
+ else
+ Ready_SO <= Ready_SO;
+ wire [C_DIV_MANT + 1:0] Sqrt_R0;
+ wire [C_DIV_MANT + 1:0] Sqrt_R1;
+ wire [C_DIV_MANT + 1:0] Sqrt_R2;
+ wire [C_DIV_MANT + 1:0] Sqrt_R3;
+ wire [C_DIV_MANT + 1:0] Sqrt_R4;
+ wire [3:0] Qcnt0;
+ wire [3:0] Q_cnt_cmp_0;
+ wire [6:0] Qcnt1;
+ wire [6:0] Q_cnt_cmp_1;
+ wire [10:0] Qcnt2;
+ wire [10:0] Q_cnt_cmp_2;
+ wire [14:0] Qcnt3;
+ wire [14:0] Q_cnt_cmp_3;
+ wire [18:0] Qcnt4;
+ wire [18:0] Q_cnt_cmp_4;
+ wire [22:0] Qcnt5;
+ wire [22:0] Q_cnt_cmp_5;
+ reg [C_DIV_MANT + 1:0] Sqrt_Q0;
+ reg [C_DIV_MANT + 1:0] Sqrt_Q1;
+ reg [C_DIV_MANT + 1:0] Sqrt_Q2;
+ reg [C_DIV_MANT + 1:0] Sqrt_Q3;
+ wire [C_DIV_MANT + 1:0] Sqrt_Q4;
+ reg [C_DIV_MANT + 1:0] Q_sqrt0;
+ reg [C_DIV_MANT + 1:0] Q_sqrt1;
+ reg [C_DIV_MANT + 1:0] Q_sqrt2;
+ reg [C_DIV_MANT + 1:0] Q_sqrt3;
+ reg [C_DIV_MANT + 1:0] Q_sqrt4;
+ reg [C_DIV_MANT + 1:0] Q_sqrt_com_0;
+ reg [C_DIV_MANT + 1:0] Q_sqrt_com_1;
+ reg [C_DIV_MANT + 1:0] Q_sqrt_com_2;
+ reg [C_DIV_MANT + 1:0] Q_sqrt_com_3;
+ reg [C_DIV_MANT + 1:0] Q_sqrt_com_4;
+ assign Qcnt0 = {1'b0, ~First_iteration_cell_sum_DI[24], ~Sec_iteration_cell_sum_DI[24], ~Thi_iteration_cell_sum_DI[24]};
+ assign Qcnt1 = {Quotient_DP[3:0], ~First_iteration_cell_sum_DI[24], ~Sec_iteration_cell_sum_DI[24], ~Thi_iteration_cell_sum_DI[24]};
+ assign Qcnt2 = {Quotient_DP[7:0], ~First_iteration_cell_sum_DI[24], ~Sec_iteration_cell_sum_DI[24], ~Thi_iteration_cell_sum_DI[24]};
+ assign Qcnt3 = {Quotient_DP[11:0], ~First_iteration_cell_sum_DI[24], ~Sec_iteration_cell_sum_DI[24], ~Thi_iteration_cell_sum_DI[24]};
+ assign Qcnt4 = {Quotient_DP[15:0], ~First_iteration_cell_sum_DI[24], ~Sec_iteration_cell_sum_DI[24], ~Thi_iteration_cell_sum_DI[24]};
+ assign Qcnt5 = {Quotient_DP[19:0], ~First_iteration_cell_sum_DI[24], ~Sec_iteration_cell_sum_DI[24], ~Thi_iteration_cell_sum_DI[24]};
+ assign Q_cnt_cmp_0 = ~Qcnt0;
+ assign Q_cnt_cmp_1 = ~Qcnt1;
+ assign Q_cnt_cmp_2 = ~Qcnt2;
+ assign Q_cnt_cmp_3 = ~Qcnt3;
+ assign Q_cnt_cmp_4 = ~Qcnt4;
+ assign Q_cnt_cmp_5 = ~Qcnt5;
+ always @(*)
+ case (Crtl_cnt_S)
+ 3'b000: begin
+ Sqrt_D0 = Mant_D_sqrt_Norm[C_DIV_MANT + 1:C_DIV_MANT];
+ Sqrt_D1 = Mant_D_sqrt_Norm[C_DIV_MANT - 1:C_DIV_MANT - 2];
+ Sqrt_D2 = Mant_D_sqrt_Norm[C_DIV_MANT - 3:C_DIV_MANT - 4];
+ Sqrt_D3 = Mant_D_sqrt_Norm[C_DIV_MANT - 5:C_DIV_MANT - 6];
+ Q_sqrt0 = {24'h000000, Qcnt0[3]};
+ Q_sqrt1 = {23'h000000, Qcnt0[3:2]};
+ Q_sqrt2 = {22'h000000, Qcnt0[3:1]};
+ Q_sqrt3 = {21'h000000, Qcnt0[3:0]};
+ Q_sqrt_com_0 = {24'hffffff, Q_cnt_cmp_0[3]};
+ Q_sqrt_com_1 = {23'h7fffff, Q_cnt_cmp_0[3:2]};
+ Q_sqrt_com_2 = {22'h3fffff, Q_cnt_cmp_0[3:1]};
+ Q_sqrt_com_3 = {21'h1fffff, Q_cnt_cmp_0[3:0]};
+ Sqrt_Q0 = Q_sqrt_com_0;
+ Sqrt_Q1 = (First_iteration_cell_sum_DI[24] ? Q_sqrt1 : Q_sqrt_com_1);
+ Sqrt_Q2 = (Sec_iteration_cell_sum_DI[24] ? Q_sqrt2 : Q_sqrt_com_2);
+ Sqrt_Q3 = (Thi_iteration_cell_sum_DI[24] ? Q_sqrt3 : Q_sqrt_com_3);
+ end
+ 3'b001: begin
+ Sqrt_D0 = Mant_D_sqrt_Norm[C_DIV_MANT - 7:C_DIV_MANT - 8];
+ Sqrt_D1 = Mant_D_sqrt_Norm[C_DIV_MANT - 9:C_DIV_MANT - 10];
+ Sqrt_D2 = Mant_D_sqrt_Norm[C_DIV_MANT - 11:C_DIV_MANT - 12];
+ Sqrt_D3 = Mant_D_sqrt_Norm[C_DIV_MANT - 13:C_DIV_MANT - 14];
+ Q_sqrt0 = {21'h000000, Qcnt1[6:3]};
+ Q_sqrt1 = {20'h00000, Qcnt1[6:2]};
+ Q_sqrt2 = {19'h00000, Qcnt1[6:1]};
+ Q_sqrt3 = {18'h00000, Qcnt1[6:0]};
+ Q_sqrt_com_0 = {21'h1fffff, Q_cnt_cmp_1[6:3]};
+ Q_sqrt_com_1 = {20'hfffff, Q_cnt_cmp_1[6:2]};
+ Q_sqrt_com_2 = {19'h7ffff, Q_cnt_cmp_1[6:1]};
+ Q_sqrt_com_3 = {18'h3ffff, Q_cnt_cmp_1[6:0]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_Q1 = (First_iteration_cell_sum_DI[24] ? Q_sqrt1 : Q_sqrt_com_1);
+ Sqrt_Q2 = (Sec_iteration_cell_sum_DI[24] ? Q_sqrt2 : Q_sqrt_com_2);
+ Sqrt_Q3 = (Thi_iteration_cell_sum_DI[24] ? Q_sqrt3 : Q_sqrt_com_3);
+ end
+ 3'b010: begin
+ Sqrt_D0 = Mant_D_sqrt_Norm[C_DIV_MANT - 15:C_DIV_MANT - 16];
+ Sqrt_D1 = Mant_D_sqrt_Norm[C_DIV_MANT - 17:C_DIV_MANT - 18];
+ Sqrt_D2 = Mant_D_sqrt_Norm[C_DIV_MANT - 19:C_DIV_MANT - 20];
+ Sqrt_D3 = Mant_D_sqrt_Norm[C_DIV_MANT - 21:C_DIV_MANT - 22];
+ Q_sqrt0 = {17'h00000, Qcnt2[10:3]};
+ Q_sqrt1 = {16'h0000, Qcnt2[10:2]};
+ Q_sqrt2 = {15'h0000, Qcnt2[10:1]};
+ Q_sqrt3 = {14'h0000, Qcnt2[10:0]};
+ Q_sqrt_com_0 = {17'h1ffff, Q_cnt_cmp_2[10:3]};
+ Q_sqrt_com_1 = {16'hffff, Q_cnt_cmp_2[10:2]};
+ Q_sqrt_com_2 = {15'h7fff, Q_cnt_cmp_2[10:1]};
+ Q_sqrt_com_3 = {14'h3fff, Q_cnt_cmp_2[10:0]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_Q1 = (First_iteration_cell_sum_DI[24] ? Q_sqrt1 : Q_sqrt_com_1);
+ Sqrt_Q2 = (Sec_iteration_cell_sum_DI[24] ? Q_sqrt2 : Q_sqrt_com_2);
+ Sqrt_Q3 = (Thi_iteration_cell_sum_DI[24] ? Q_sqrt3 : Q_sqrt_com_3);
+ end
+ 3'b011: begin
+ Sqrt_D0 = {Mant_D_sqrt_Norm[0], 1'b0};
+ Sqrt_D1 = 1'sb0;
+ Sqrt_D2 = 1'sb0;
+ Sqrt_D3 = 1'sb0;
+ Q_sqrt0 = {13'h0000, Qcnt3[14:3]};
+ Q_sqrt1 = {12'h000, Qcnt3[14:2]};
+ Q_sqrt2 = {11'h000, Qcnt3[14:1]};
+ Q_sqrt3 = {10'h000, Qcnt3[14:0]};
+ Q_sqrt_com_0 = {13'h1fff, Q_cnt_cmp_3[14:3]};
+ Q_sqrt_com_1 = {12'hfff, Q_cnt_cmp_3[14:2]};
+ Q_sqrt_com_2 = {11'h7ff, Q_cnt_cmp_3[14:1]};
+ Q_sqrt_com_3 = {10'h3ff, Q_cnt_cmp_3[14:0]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_Q1 = (First_iteration_cell_sum_DI[24] ? Q_sqrt1 : Q_sqrt_com_1);
+ Sqrt_Q2 = (Sec_iteration_cell_sum_DI[24] ? Q_sqrt2 : Q_sqrt_com_2);
+ Sqrt_Q3 = (Thi_iteration_cell_sum_DI[24] ? Q_sqrt3 : Q_sqrt_com_3);
+ end
+ 3'b100: begin
+ Sqrt_D0 = 1'sb0;
+ Sqrt_D1 = 1'sb0;
+ Sqrt_D2 = 1'sb0;
+ Sqrt_D3 = 1'sb0;
+ Q_sqrt0 = {9'h000, Qcnt4[18:3]};
+ Q_sqrt1 = {8'h00, Qcnt4[18:2]};
+ Q_sqrt2 = {7'h00, Qcnt4[18:1]};
+ Q_sqrt3 = {6'h00, Qcnt4[18:0]};
+ Q_sqrt_com_0 = {9'h1ff, Q_cnt_cmp_4[18:3]};
+ Q_sqrt_com_1 = {8'hff, Q_cnt_cmp_4[18:2]};
+ Q_sqrt_com_2 = {7'h7f, Q_cnt_cmp_4[18:1]};
+ Q_sqrt_com_3 = {6'h3f, Q_cnt_cmp_4[18:0]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_Q1 = (First_iteration_cell_sum_DI[24] ? Q_sqrt1 : Q_sqrt_com_1);
+ Sqrt_Q2 = (Sec_iteration_cell_sum_DI[24] ? Q_sqrt2 : Q_sqrt_com_2);
+ Sqrt_Q3 = (Thi_iteration_cell_sum_DI[24] ? Q_sqrt3 : Q_sqrt_com_3);
+ end
+ 3'b101: begin
+ Sqrt_D0 = 1'sb0;
+ Sqrt_D1 = 1'sb0;
+ Sqrt_D2 = 1'sb0;
+ Sqrt_D3 = 1'sb0;
+ Q_sqrt0 = {5'h00, Qcnt5[22:3]};
+ Q_sqrt1 = {4'h0, Qcnt5[22:2]};
+ Q_sqrt2 = {3'h0, Qcnt5[22:1]};
+ Q_sqrt3 = {2'h0, Qcnt5[22:0]};
+ Q_sqrt_com_0 = {5'h1f, Q_cnt_cmp_5[22:3]};
+ Q_sqrt_com_1 = {4'hf, Q_cnt_cmp_5[22:2]};
+ Q_sqrt_com_2 = {3'h7, Q_cnt_cmp_5[22:1]};
+ Q_sqrt_com_3 = {2'h3, Q_cnt_cmp_5[22:0]};
+ Sqrt_Q0 = (Quotient_DP[0] ? Q_sqrt_com_0 : Q_sqrt0);
+ Sqrt_Q1 = (First_iteration_cell_sum_DI[24] ? Q_sqrt1 : Q_sqrt_com_1);
+ Sqrt_Q2 = (Sec_iteration_cell_sum_DI[24] ? Q_sqrt2 : Q_sqrt_com_2);
+ Sqrt_Q3 = (Thi_iteration_cell_sum_DI[24] ? Q_sqrt3 : Q_sqrt_com_3);
+ end
+ default: begin
+ Sqrt_D0 = 1'sb0;
+ Sqrt_D1 = 1'sb0;
+ Sqrt_D2 = 1'sb0;
+ Sqrt_D3 = 1'sb0;
+ Q_sqrt0 = 1'sb0;
+ Q_sqrt1 = 1'sb0;
+ Q_sqrt2 = 1'sb0;
+ Q_sqrt3 = 1'sb0;
+ Q_sqrt4 = 1'sb0;
+ Q_sqrt_com_0 = 1'sb0;
+ Q_sqrt_com_1 = 1'sb0;
+ Q_sqrt_com_2 = 1'sb0;
+ Q_sqrt_com_3 = 1'sb0;
+ Q_sqrt_com_4 = 1'sb0;
+ Sqrt_Q0 = 1'sb0;
+ Sqrt_Q1 = 1'sb0;
+ Sqrt_Q2 = 1'sb0;
+ Sqrt_Q3 = 1'sb0;
+ end
+ endcase
+ assign Sqrt_R0 = (Sqrt_start_dly_S ? {((C_DIV_MANT + 1) >= 0 ? C_DIV_MANT + 2 : 1 - (C_DIV_MANT + 1)) {1'sb0}} : Partial_remainder_DP);
+ assign Sqrt_R1 = {First_iteration_cell_sum_DI[24], First_iteration_cell_sum_DI[21:0], Sqrt_Da0};
+ assign Sqrt_R2 = {Sec_iteration_cell_sum_DI[24], Sec_iteration_cell_sum_DI[21:0], Sqrt_Da1};
+ assign Sqrt_R3 = {Thi_iteration_cell_sum_DI[24], Thi_iteration_cell_sum_DI[21:0], Sqrt_Da2};
+ assign Sqrt_R4 = {Fou_iteration_cell_sum_DI[24], Fou_iteration_cell_sum_DI[21:0], Sqrt_Da3};
+ wire [C_DIV_MANT + 1:0] First_iteration_cell_div_a_D;
+ wire [C_DIV_MANT + 1:0] First_iteration_cell_div_b_D;
+ wire Sel_b_for_first_S;
+ assign First_iteration_cell_div_a_D = (Div_start_dly_S ? Numerator_se_D : {Partial_remainder_DP[C_DIV_MANT:0], Quotient_DP[0]});
+ assign Sel_b_for_first_S = (Div_start_dly_S ? 1 : Quotient_DP[0]);
+ assign First_iteration_cell_div_b_D = (Sel_b_for_first_S ? Denominator_se_DB : Denominator_se_D);
+ assign First_iteration_cell_a_DO = (Sqrt_enable_SO ? Sqrt_R0 : First_iteration_cell_div_a_D);
+ assign First_iteration_cell_b_DO = (Sqrt_enable_SO ? Sqrt_Q0 : First_iteration_cell_div_b_D);
+ wire [C_DIV_MANT + 1:0] Sec_iteration_cell_div_a_D;
+ wire [C_DIV_MANT + 1:0] Sec_iteration_cell_div_b_D;
+ wire Sel_b_for_sec_S;
+ assign Sec_iteration_cell_div_a_D = {First_iteration_cell_sum_DI[C_DIV_MANT:0], First_iteration_cell_carry_DI};
+ assign Sel_b_for_sec_S = First_iteration_cell_carry_DI;
+ assign Sec_iteration_cell_div_b_D = (Sel_b_for_sec_S ? Denominator_se_DB : Denominator_se_D);
+ assign Sec_iteration_cell_a_DO = (Sqrt_enable_SO ? Sqrt_R1 : Sec_iteration_cell_div_a_D);
+ assign Sec_iteration_cell_b_DO = (Sqrt_enable_SO ? Sqrt_Q1 : Sec_iteration_cell_div_b_D);
+ wire [C_DIV_MANT + 1:0] Thi_iteration_cell_div_a_D;
+ wire [C_DIV_MANT + 1:0] Thi_iteration_cell_div_b_D;
+ wire Sel_b_for_thi_S;
+ assign Thi_iteration_cell_div_a_D = {Sec_iteration_cell_sum_DI[C_DIV_MANT:0], Sec_iteration_cell_carry_DI};
+ assign Sel_b_for_thi_S = Sec_iteration_cell_carry_DI;
+ assign Thi_iteration_cell_div_b_D = (Sel_b_for_thi_S ? Denominator_se_DB : Denominator_se_D);
+ assign Thi_iteration_cell_a_DO = (Sqrt_enable_SO ? Sqrt_R2 : Thi_iteration_cell_div_a_D);
+ assign Thi_iteration_cell_b_DO = (Sqrt_enable_SO ? Sqrt_Q2 : Thi_iteration_cell_div_b_D);
+ wire [C_DIV_MANT + 1:0] Fou_iteration_cell_div_a_D;
+ wire [C_DIV_MANT + 1:0] Fou_iteration_cell_div_b_D;
+ wire Sel_b_for_fou_S;
+ assign Fou_iteration_cell_div_a_D = {Thi_iteration_cell_sum_DI[C_DIV_MANT:0], Thi_iteration_cell_carry_DI};
+ assign Sel_b_for_fou_S = Thi_iteration_cell_carry_DI;
+ assign Fou_iteration_cell_div_b_D = (Sel_b_for_fou_S ? Denominator_se_DB : Denominator_se_D);
+ assign Fou_iteration_cell_a_DO = (Sqrt_enable_SO ? Sqrt_R3 : Fou_iteration_cell_div_a_D);
+ assign Fou_iteration_cell_b_DO = (Sqrt_enable_SO ? Sqrt_Q3 : Fou_iteration_cell_div_b_D);
+ always @(*)
+ if (Fsm_enable_S)
+ Partial_remainder_DN = (Sqrt_enable_SO ? Sqrt_R4 : Fou_iteration_cell_sum_DI);
+ else
+ Partial_remainder_DN = Partial_remainder_DP;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Partial_remainder_DP <= 1'sb0;
+ else
+ Partial_remainder_DP <= Partial_remainder_DN;
+ reg [C_DIV_MANT:0] Quotient_DN;
+ always @(*)
+ if (Fsm_enable_S)
+ Quotient_DN = {Quotient_DP[C_DIV_MANT - 4:0], First_iteration_cell_carry_DI, Sec_iteration_cell_carry_DI, Thi_iteration_cell_carry_DI, Fou_iteration_cell_carry_DI};
+ else
+ Quotient_DN = Quotient_DP;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Quotient_DP <= 1'sb0;
+ else
+ Quotient_DP <= Quotient_DN;
+ wire Msc_D;
+ wire [C_DIV_MANT + 1:0] Sum_msc_D;
+ assign {Msc_D, Sum_msc_D} = First_iteration_cell_div_a_D + First_iteration_cell_div_b_D;
+ reg [C_DIV_MANT:0] Mant_result_prenorm_noncorrect_D;
+ reg [C_DIV_MANT:0] Msc_forcorrect_D;
+ wire [C_DIV_MANT + 1:0] Mant_result_prenorm_correct_D;
+ always @(*)
+ if (Precision_ctl_Enable_S == 1)
+ case (Precision_ctl_S)
+ 5'b01000: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 12:3], 15'b000000000000000};
+ Msc_forcorrect_D = {8'b00000000, Quotient_DP[2], 15'b000000000000000};
+ end
+ 5'b01001: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 12:2], 14'b00000000000000};
+ Msc_forcorrect_D = {9'b000000000, Quotient_DP[1], 14'b00000000000000};
+ end
+ 5'b01010: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 12:1], 13'b0000000000000};
+ Msc_forcorrect_D = {10'b0000000000, Quotient_DP[0], 13'b0000000000000};
+ end
+ 5'b01011: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 12:0], 12'b000000000000};
+ Msc_forcorrect_D = {11'b00000000000, Msc_D, 12'b000000000000};
+ end
+ 5'b01100: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 8:3], 11'b00000000000};
+ Msc_forcorrect_D = {12'b000000000000, Quotient_DP[2], 11'b00000000000};
+ end
+ 5'b01101: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 8:2], 10'b0000000000};
+ Msc_forcorrect_D = {13'b0000000000000, Quotient_DP[1], 10'b0000000000};
+ end
+ 5'b01110: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 8:1], 9'b000000000};
+ Msc_forcorrect_D = {14'b00000000000000, Quotient_DP[0], 9'b000000000};
+ end
+ 5'b01111: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 8:0], 8'b00000000};
+ Msc_forcorrect_D = {15'b000000000000000, Msc_D, 8'b00000000};
+ end
+ 5'b10000: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 4:3], 7'b0000000};
+ Msc_forcorrect_D = {16'b0000000000000000, Quotient_DP[2], 7'b0000000};
+ end
+ 5'b10001: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 4:2], 6'b000000};
+ Msc_forcorrect_D = {17'b00000000000000000, Quotient_DP[1], 6'b000000};
+ end
+ 5'b10010: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 4:1], 5'b00000};
+ Msc_forcorrect_D = {18'b000000000000000000, Quotient_DP[0], 5'b00000};
+ end
+ 5'b10011: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT - 4:0], 4'b0000};
+ Msc_forcorrect_D = {19'b0000000000000000000, Msc_D, 4'b0000};
+ end
+ 5'b10100: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT:3], 3'b000};
+ Msc_forcorrect_D = {20'b00000000000000000000, Quotient_DP[2], 3'b000};
+ end
+ 5'b10101: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT:2], 2'b00};
+ Msc_forcorrect_D = {21'b000000000000000000000, Quotient_DP[1], 2'b00};
+ end
+ 5'b10110: begin
+ Mant_result_prenorm_noncorrect_D = {Quotient_DP[C_DIV_MANT:1], 1'b0};
+ Msc_forcorrect_D = {22'b0000000000000000000000, Quotient_DP[0], 1'b0};
+ end
+ 5'b10111: begin
+ Mant_result_prenorm_noncorrect_D = Quotient_DP[C_DIV_MANT:0];
+ Msc_forcorrect_D = {23'b00000000000000000000000, Msc_D};
+ end
+ default: begin
+ Mant_result_prenorm_noncorrect_D = Quotient_DP[C_DIV_MANT:0];
+ Msc_forcorrect_D = {23'b00000000000000000000000, Msc_D};
+ end
+ endcase
+ else begin
+ Mant_result_prenorm_noncorrect_D = Quotient_DP[C_DIV_MANT:0];
+ Msc_forcorrect_D = {23'b00000000000000000000000, Msc_D};
+ end
+ assign Mant_result_prenorm_correct_D = Mant_result_prenorm_noncorrect_D + {(Div_enable_SO ? Msc_forcorrect_D : 24'b000000000000000000000000)};
+ assign Mant_result_prenorm_DO = (Mant_result_prenorm_correct_D[C_DIV_MANT + 1] ? Mant_result_prenorm_noncorrect_D : Mant_result_prenorm_correct_D[C_DIV_MANT:0]);
+ wire [C_DIV_EXP + 1:0] Exp_result_prenorm_DN;
+ reg [C_DIV_EXP + 1:0] Exp_result_prenorm_DP;
+ wire [C_DIV_EXP + 1:0] Exp_add_a_D;
+ wire [C_DIV_EXP + 1:0] Exp_add_b_D;
+ wire [C_DIV_EXP + 1:0] Exp_add_c_D;
+ assign Exp_add_a_D = {(Sqrt_start_dly_S ? {Exp_num_DI[C_DIV_EXP], Exp_num_DI[C_DIV_EXP], Exp_num_DI[C_DIV_EXP], Exp_num_DI[C_DIV_EXP:1]} : {Exp_num_DI[C_DIV_EXP], Exp_num_DI[C_DIV_EXP], Exp_num_DI})};
+ assign Exp_add_b_D = {(Sqrt_start_dly_S ? {1'b0, {C_DIV_EXP_ZERO}, Exp_num_DI[0]} : {~Exp_den_DI[C_DIV_EXP], ~Exp_den_DI[C_DIV_EXP], ~Exp_den_DI})};
+ assign Exp_add_c_D = {(Div_start_dly_S ? {2'b00, {C_DIV_BIAS_AONE}} : {2'b00, {C_DIV_HALF_BIAS}})};
+ assign Exp_result_prenorm_DN = (Start_dly_S ? {(Exp_add_a_D + Exp_add_b_D) + Exp_add_c_D} : Exp_result_prenorm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Exp_result_prenorm_DP <= 1'sb0;
+ else
+ Exp_result_prenorm_DP <= Exp_result_prenorm_DN;
+ assign Exp_result_prenorm_DO = Exp_result_prenorm_DP;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/div_sqrt_top_tp.v b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/div_sqrt_top_tp.v
new file mode 100644
index 0000000..b5353d3
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/div_sqrt_top_tp.v
@@ -0,0 +1,139 @@
+module div_sqrt_top_tp
+#(
+ parameter Precision_ctl_Enable_S = 1
+)
+(
+ Clk_CI,
+ Rst_RBI,
+ Div_start_SI,
+ Sqrt_start_SI,
+ Operand_a_DI,
+ Operand_b_DI,
+ RM_SI,
+ Precision_ctl_SI,
+ Result_DO,
+ Exp_OF_SO,
+ Exp_UF_SO,
+ Div_zero_SO,
+ Ready_SO,
+ Done_SO
+);
+parameter C_DIV_RM = 2;
+parameter C_DIV_RM_NEAREST = 2'h0;
+parameter C_DIV_RM_TRUNC = 2'h1;
+parameter C_DIV_RM_PLUSINF = 2'h2;
+parameter C_DIV_RM_MINUSINF = 2'h3;
+parameter C_DIV_PC = 5;
+parameter C_DIV_OP = 32;
+parameter C_DIV_MANT = 23;
+parameter C_DIV_EXP = 8;
+parameter C_DIV_BIAS = 127;
+parameter C_DIV_BIAS_AONE = 8'h80;
+parameter C_DIV_HALF_BIAS = 63;
+parameter C_DIV_MANT_PRENORM = C_DIV_MANT+1;
+parameter C_DIV_EXP_ZERO = 8'h00;
+parameter C_DIV_EXP_ONE = 8'h01;
+parameter C_DIV_EXP_INF = 8'hff;
+parameter C_DIV_MANT_ZERO = 23'h0;
+parameter C_DIV_MANT_NAN = 23'h400000;
+ //parameter Precision_ctl_Enable_S = 1;
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire Div_start_SI;
+ input wire Sqrt_start_SI;
+ input wire [C_DIV_OP - 1:0] Operand_a_DI;
+ input wire [C_DIV_OP - 1:0] Operand_b_DI;
+ input wire [C_DIV_RM - 1:0] RM_SI;
+ input wire [C_DIV_PC - 1:0] Precision_ctl_SI;
+ output wire [31:0] Result_DO;
+ output wire Exp_OF_SO;
+ output wire Exp_UF_SO;
+ output wire Div_zero_SO;
+ output wire Ready_SO;
+ output wire Done_SO;
+ wire [C_DIV_MANT - 1:0] Mant_res_DO;
+ wire [C_DIV_EXP - 1:0] Exp_res_DO;
+ wire Sign_res_DO;
+ assign Result_DO = {Sign_res_DO, Exp_res_DO, Mant_res_DO};
+ wire Sign_a_D;
+ wire Sign_b_D;
+ wire [C_DIV_EXP:0] Exp_a_D;
+ wire [C_DIV_EXP:0] Exp_b_D;
+ wire [C_DIV_MANT:0] Mant_a_D;
+ wire [C_DIV_MANT:0] Mant_b_D;
+ wire [C_DIV_EXP + 1:0] Exp_z_D;
+ wire [C_DIV_MANT:0] Mant_z_D;
+ wire Sign_z_D;
+ wire Start_S;
+ wire [C_DIV_RM - 1:0] RM_dly_S;
+ wire Mant_zero_S_a;
+ wire Mant_zero_S_b;
+ wire Div_enable_S;
+ wire Sqrt_enable_S;
+ wire Inf_a_S;
+ wire Inf_b_S;
+ wire Zero_a_S;
+ wire Zero_b_S;
+ wire NaN_a_S;
+ wire NaN_b_S;
+ preprocess precess_U0(
+ .Clk_CI(Clk_CI),
+ .Rst_RBI(Rst_RBI),
+ .Div_start_SI(Div_start_SI),
+ .Sqrt_start_SI(Sqrt_start_SI),
+ .Operand_a_DI(Operand_a_DI),
+ .Operand_b_DI(Operand_b_DI),
+ .RM_SI(RM_SI),
+ .Start_SO(Start_S),
+ .Exp_a_DO_norm(Exp_a_D),
+ .Exp_b_DO_norm(Exp_b_D),
+ .Mant_a_DO_norm(Mant_a_D),
+ .Mant_b_DO_norm(Mant_b_D),
+ .RM_dly_SO(RM_dly_S),
+ .Sign_z_DO(Sign_z_D),
+ .Inf_a_SO(Inf_a_S),
+ .Inf_b_SO(Inf_b_S),
+ .Zero_a_SO(Zero_a_S),
+ .Zero_b_SO(Zero_b_S),
+ .NaN_a_SO(NaN_a_S),
+ .NaN_b_SO(NaN_b_S)
+ );
+ nrbd_nrsc_tp #(Precision_ctl_Enable_S) nrbd_nrsc_U0(
+ .Clk_CI(Clk_CI),
+ .Rst_RBI(Rst_RBI),
+ .Div_start_SI(Div_start_SI),
+ .Sqrt_start_SI(Sqrt_start_SI),
+ .Start_SI(Start_S),
+ .Div_enable_SO(Div_enable_S),
+ .Sqrt_enable_SO(Sqrt_enable_S),
+ .Precision_ctl_SI(Precision_ctl_SI),
+ .Exp_a_DI(Exp_a_D),
+ .Exp_b_DI(Exp_b_D),
+ .Mant_a_DI(Mant_a_D),
+ .Mant_b_DI(Mant_b_D),
+ .Ready_SO(Ready_SO),
+ .Done_SO(Done_SO),
+ .Exp_z_DO(Exp_z_D),
+ .Mant_z_DO(Mant_z_D)
+ );
+ fpu_norm_div_sqrt fpu_norm_U0(
+ .Mant_in_DI(Mant_z_D),
+ .Exp_in_DI(Exp_z_D),
+ .Sign_in_DI(Sign_z_D),
+ .Div_enable_SI(Div_enable_S),
+ .Sqrt_enable_SI(Sqrt_enable_S),
+ .Inf_a_SI(Inf_a_S),
+ .Inf_b_SI(Inf_b_S),
+ .Zero_a_SI(Zero_a_S),
+ .Zero_b_SI(Zero_b_S),
+ .NaN_a_SI(NaN_a_S),
+ .NaN_b_SI(NaN_b_S),
+ .RM_SI(RM_dly_S),
+ .Mant_res_DO(Mant_res_DO),
+ .Exp_res_DO(Exp_res_DO),
+ .Sign_res_DO(Sign_res_DO),
+ .Exp_OF_SO(Exp_OF_SO),
+ .Exp_UF_SO(Exp_UF_SO),
+ .Div_zero_SO(Div_zero_SO)
+ );
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/fpu_defs_div_sqrt_tp.sv b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/fpu_defs_div_sqrt_tp.sv
new file mode 100644
index 0000000..9193c40
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/fpu_defs_div_sqrt_tp.sv
@@ -0,0 +1,39 @@
+// Copyright 2017 ETH Zurich and University of Bologna.
+// Copyright and related rights are licensed under the Solderpad Hardware
+// License, Version 0.51 (the “License”); you may not use this file except in
+// compliance with the License. You may obtain a copy of the License at
+// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
+// or agreed to in writing, software, hardware and materials distributed under
+// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+///////////////////////////////////////////////////////////////////////////////
+// This file contains all div_sqrt_top parameters //
+// //
+// Authors : Lei Li (lile@iis.ee.ethz.ch) //
+// Copyright (c) 2017 Integrated Systems Laboratory, ETH Zurich //
+///////////////////////////////////////////////////////////////////////////////
+
+
+package fpu_defs_div_sqrt_tp;
+
+ parameter C_DIV_RM = 2;
+ parameter C_DIV_RM_NEAREST = 2'h0;
+ parameter C_DIV_RM_TRUNC = 2'h1;
+ parameter C_DIV_RM_PLUSINF = 2'h2;
+ parameter C_DIV_RM_MINUSINF = 2'h3;
+ parameter C_DIV_PC = 5;
+ parameter C_DIV_OP = 32;
+ parameter C_DIV_MANT = 23;
+ parameter C_DIV_EXP = 8;
+ parameter C_DIV_BIAS = 127;
+ parameter C_DIV_BIAS_AONE = 8'h80;
+ parameter C_DIV_HALF_BIAS = 63;
+ parameter C_DIV_MANT_PRENORM = C_DIV_MANT+1;
+ parameter C_DIV_EXP_ZERO = 8'h00;
+ parameter C_DIV_EXP_ONE = 8'h01;
+ parameter C_DIV_EXP_INF = 8'hff;
+ parameter C_DIV_MANT_ZERO = 23'h0;
+ parameter C_DIV_MANT_NAN = 23'h400000;
+
+endpackage : fpu_defs_div_sqrt_tp
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/fpu_norm_div_sqrt.v b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/fpu_norm_div_sqrt.v
new file mode 100644
index 0000000..4c91f98
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/fpu_norm_div_sqrt.v
@@ -0,0 +1,283 @@
+module fpu_norm_div_sqrt (
+ Mant_in_DI,
+ Exp_in_DI,
+ Sign_in_DI,
+ Div_enable_SI,
+ Sqrt_enable_SI,
+ Inf_a_SI,
+ Inf_b_SI,
+ Zero_a_SI,
+ Zero_b_SI,
+ NaN_a_SI,
+ NaN_b_SI,
+ RM_SI,
+ Mant_res_DO,
+ Exp_res_DO,
+ Sign_res_DO,
+ Exp_OF_SO,
+ Exp_UF_SO,
+ Div_zero_SO
+);
+parameter C_DIV_RM = 2;
+parameter C_DIV_RM_NEAREST = 2'h0;
+parameter C_DIV_RM_TRUNC = 2'h1;
+parameter C_DIV_RM_PLUSINF = 2'h2;
+parameter C_DIV_RM_MINUSINF = 2'h3;
+parameter C_DIV_PC = 5;
+parameter C_DIV_OP = 32;
+parameter C_DIV_MANT = 23;
+parameter C_DIV_EXP = 8;
+parameter C_DIV_BIAS = 127;
+parameter C_DIV_BIAS_AONE = 8'h80;
+parameter C_DIV_HALF_BIAS = 63;
+parameter C_DIV_MANT_PRENORM = C_DIV_MANT+1;
+parameter C_DIV_EXP_ZERO = 8'h00;
+parameter C_DIV_EXP_ONE = 8'h01;
+parameter C_DIV_EXP_INF = 8'hff;
+parameter C_DIV_MANT_ZERO = 23'h0;
+parameter C_DIV_MANT_NAN = 23'h400000;
+ input wire [C_DIV_MANT_PRENORM - 1:0] Mant_in_DI;
+ input wire signed [C_DIV_EXP + 1:0] Exp_in_DI;
+ input wire Sign_in_DI;
+ input wire Div_enable_SI;
+ input wire Sqrt_enable_SI;
+ input wire Inf_a_SI;
+ input wire Inf_b_SI;
+ input wire Zero_a_SI;
+ input wire Zero_b_SI;
+ input wire NaN_a_SI;
+ input wire NaN_b_SI;
+ input wire [C_DIV_RM - 1:0] RM_SI;
+ output wire [C_DIV_MANT - 1:0] Mant_res_DO;
+ output wire [C_DIV_EXP - 1:0] Exp_res_DO;
+ output reg Sign_res_DO;
+ output reg Exp_OF_SO;
+ output reg Exp_UF_SO;
+ output reg Div_zero_SO;
+ reg [C_DIV_MANT:0] Mant_res_norm_D;
+ reg [C_DIV_EXP - 1:0] Exp_res_norm_D;
+ wire [C_DIV_EXP + 1:0] Exp_Max_RS_D;
+ assign Exp_Max_RS_D = (Exp_in_DI[C_DIV_EXP:0] + C_DIV_MANT) + 1;
+ wire [C_DIV_EXP + 1:0] Num_RS_D;
+ assign Num_RS_D = ~Exp_in_DI + 2;
+ wire [C_DIV_MANT_PRENORM + 1:0] Mant_RS_D;
+ wire [C_DIV_MANT - 2:0] Mant_forsticky_D;
+ assign {Mant_RS_D, Mant_forsticky_D} = {Mant_in_DI, 1'b0, 1'b0, 22'h000000} >> Num_RS_D;
+ wire Mant_sticky_D;
+ assign Mant_sticky_D = (Exp_in_DI[C_DIV_EXP + 1] && Exp_Max_RS_D[C_DIV_EXP + 1]) && |Mant_forsticky_D;
+ reg [1:0] Mant_lower_D;
+ always @(*)
+ if (NaN_a_SI) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {1'b0, C_DIV_MANT_NAN};
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = 1'b0;
+ end
+ else if (NaN_b_SI) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {1'b0, C_DIV_MANT_NAN};
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = 1'b0;
+ end
+ else if (Inf_a_SI) begin
+ if (Div_enable_SI && Inf_b_SI) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {1'b0, C_DIV_MANT_NAN};
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = 1'b0;
+ end
+ else begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ end
+ else if (Div_enable_SI && Inf_b_SI) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ else if (Zero_a_SI) begin
+ if (Div_enable_SI && Zero_b_SI) begin
+ Div_zero_SO = 1'b1;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {1'b0, C_DIV_MANT_NAN};
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = 1'b0;
+ end
+ else begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ end
+ else if (Div_enable_SI && Zero_b_SI) begin
+ Div_zero_SO = 1'b1;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ else if (Sign_in_DI && Sqrt_enable_SI) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {1'b0, C_DIV_MANT_NAN};
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = 1'b0;
+ end
+ else if (Exp_in_DI[C_DIV_EXP:0] == {(C_DIV_EXP >= 0 ? C_DIV_EXP + 1 : 1 - C_DIV_EXP) {1'sb0}}) begin
+ if (Mant_in_DI != {C_DIV_MANT_PRENORM {1'sb0}}) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b1;
+ Mant_res_norm_D = {2'b00, Mant_in_DI[C_DIV_MANT_PRENORM - 1:1]};
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = {Mant_in_DI[0], 1'b0};
+ Sign_res_DO = Sign_in_DI;
+ end
+ else begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ end
+ else if ((Exp_in_DI[C_DIV_EXP:0] == C_DIV_EXP_ONE) && ~Mant_in_DI[C_DIV_MANT_PRENORM - 1]) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b1;
+ Mant_res_norm_D = Mant_in_DI[C_DIV_MANT_PRENORM - 1:0];
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ else if (Exp_in_DI[C_DIV_EXP + 1]) begin
+ if (~Exp_Max_RS_D[C_DIV_EXP + 1]) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ else begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b1;
+ Mant_res_norm_D = {1'b0, Mant_RS_D[C_DIV_MANT + 1:2]};
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = Mant_RS_D[1:0];
+ Sign_res_DO = Sign_in_DI;
+ end
+ end
+ else if (Exp_in_DI[C_DIV_EXP]) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ else if (Exp_in_DI[C_DIV_EXP - 1:0] == {C_DIV_EXP {1'sb1}}) begin
+ if (~Mant_in_DI[C_DIV_MANT_PRENORM - 1]) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {Mant_in_DI[C_DIV_MANT_PRENORM - 2:0], 1'b0};
+ Exp_res_norm_D = Exp_in_DI[C_DIV_EXP - 1:0] - 1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ else if (Mant_in_DI != {C_DIV_MANT_PRENORM {1'sb0}}) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ else begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ end
+ else if (Mant_in_DI[C_DIV_MANT_PRENORM - 1]) begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = Mant_in_DI[C_DIV_MANT_PRENORM - 1:0];
+ Exp_res_norm_D = Exp_in_DI[C_DIV_EXP - 1:0];
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ else begin
+ Div_zero_SO = 1'b0;
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {Mant_in_DI[C_DIV_MANT_PRENORM - 2:0], 1'b0};
+ Exp_res_norm_D = Exp_in_DI[C_DIV_EXP - 1:0] - 1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ end
+ wire [C_DIV_MANT:0] Mant_upper_D;
+ wire [C_DIV_MANT + 1:0] Mant_upperRounded_D;
+ reg Mant_roundUp_S;
+ wire Mant_rounded_S;
+ assign Mant_upper_D = Mant_res_norm_D;
+ assign Mant_rounded_S = |Mant_lower_D | Mant_sticky_D;
+ always @(*) begin
+ Mant_roundUp_S = 1'b0;
+ case (RM_SI)
+ C_DIV_RM_NEAREST: Mant_roundUp_S = Mant_lower_D[1] && ((Mant_lower_D[0] | Mant_sticky_D) || Mant_upper_D[0]);
+ C_DIV_RM_TRUNC: Mant_roundUp_S = 0;
+ C_DIV_RM_PLUSINF: Mant_roundUp_S = Mant_rounded_S & ~Sign_in_DI;
+ C_DIV_RM_MINUSINF: Mant_roundUp_S = Mant_rounded_S & Sign_in_DI;
+ default: Mant_roundUp_S = 0;
+ endcase
+ end
+ wire Mant_renorm_S;
+ assign Mant_upperRounded_D = Mant_upper_D + Mant_roundUp_S;
+ assign Mant_renorm_S = Mant_upperRounded_D[C_DIV_MANT + 1];
+ wire Rounded_SO;
+ assign Mant_res_DO = (Mant_renorm_S ? Mant_upperRounded_D[C_DIV_MANT:1] : Mant_upperRounded_D[C_DIV_MANT - 1:0]);
+ assign Exp_res_DO = Exp_res_norm_D + Mant_renorm_S;
+ assign Rounded_SO = Mant_rounded_S;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/iteration_div_sqrt.v b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/iteration_div_sqrt.v
new file mode 100644
index 0000000..4254739
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/iteration_div_sqrt.v
@@ -0,0 +1,46 @@
+module iteration_div_sqrt (
+ A_DI,
+ B_DI,
+ Div_enable_SI,
+ Sqrt_enable_SI,
+ D_DI,
+ D_DO,
+ Sum_DO,
+ Carry_out_DO
+);
+parameter C_DIV_RM = 2;
+parameter C_DIV_RM_NEAREST = 2'h0;
+parameter C_DIV_RM_TRUNC = 2'h1;
+parameter C_DIV_RM_PLUSINF = 2'h2;
+parameter C_DIV_RM_MINUSINF = 2'h3;
+parameter C_DIV_PC = 5;
+parameter C_DIV_OP = 32;
+parameter C_DIV_MANT = 23;
+parameter C_DIV_EXP = 8;
+parameter C_DIV_BIAS = 127;
+parameter C_DIV_BIAS_AONE = 8'h80;
+parameter C_DIV_HALF_BIAS = 63;
+parameter C_DIV_MANT_PRENORM = C_DIV_MANT+1;
+parameter C_DIV_EXP_ZERO = 8'h00;
+parameter C_DIV_EXP_ONE = 8'h01;
+parameter C_DIV_EXP_INF = 8'hff;
+parameter C_DIV_MANT_ZERO = 23'h0;
+parameter C_DIV_MANT_NAN = 23'h400000;
+ input wire [C_DIV_MANT + 1:0] A_DI;
+ input wire [C_DIV_MANT + 1:0] B_DI;
+ input wire Div_enable_SI;
+ input wire Sqrt_enable_SI;
+ input wire [1:0] D_DI;
+ output wire [1:0] D_DO;
+ output wire [C_DIV_MANT + 1:0] Sum_DO;
+ output wire Carry_out_DO;
+ wire D_carry_D;
+ wire Sqrt_cin_D;
+ wire Cin_D;
+ assign D_DO[0] = ~D_DI[0];
+ assign D_DO[1] = ~(D_DI[1] ^ D_DI[0]);
+ assign D_carry_D = D_DI[1] | D_DI[0];
+ assign Sqrt_cin_D = Sqrt_enable_SI && D_carry_D;
+ assign Cin_D = (Div_enable_SI ? 0 : Sqrt_cin_D);
+ assign {Carry_out_DO, Sum_DO} = (A_DI + B_DI) + Cin_D;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/iteration_div_sqrt_first.v b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/iteration_div_sqrt_first.v
new file mode 100644
index 0000000..e108aa3
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/iteration_div_sqrt_first.v
@@ -0,0 +1,48 @@
+module iteration_div_sqrt_first (
+ A_DI,
+ B_DI,
+ Div_enable_SI,
+ Div_start_dly_SI,
+ Sqrt_enable_SI,
+ D_DI,
+ D_DO,
+ Sum_DO,
+ Carry_out_DO
+);
+parameter C_DIV_RM = 2;
+parameter C_DIV_RM_NEAREST = 2'h0;
+parameter C_DIV_RM_TRUNC = 2'h1;
+parameter C_DIV_RM_PLUSINF = 2'h2;
+parameter C_DIV_RM_MINUSINF = 2'h3;
+parameter C_DIV_PC = 5;
+parameter C_DIV_OP = 32;
+parameter C_DIV_MANT = 23;
+parameter C_DIV_EXP = 8;
+parameter C_DIV_BIAS = 127;
+parameter C_DIV_BIAS_AONE = 8'h80;
+parameter C_DIV_HALF_BIAS = 63;
+parameter C_DIV_MANT_PRENORM = C_DIV_MANT+1;
+parameter C_DIV_EXP_ZERO = 8'h00;
+parameter C_DIV_EXP_ONE = 8'h01;
+parameter C_DIV_EXP_INF = 8'hff;
+parameter C_DIV_MANT_ZERO = 23'h0;
+parameter C_DIV_MANT_NAN = 23'h400000;
+ input wire [C_DIV_MANT + 1:0] A_DI;
+ input wire [C_DIV_MANT + 1:0] B_DI;
+ input wire Div_enable_SI;
+ input wire Div_start_dly_SI;
+ input wire Sqrt_enable_SI;
+ input wire [1:0] D_DI;
+ output wire [1:0] D_DO;
+ output wire [C_DIV_MANT + 1:0] Sum_DO;
+ output wire Carry_out_DO;
+ wire D_carry_D;
+ wire Sqrt_cin_D;
+ wire Cin_D;
+ assign D_DO[0] = ~D_DI[0];
+ assign D_DO[1] = ~(D_DI[1] ^ D_DI[0]);
+ assign D_carry_D = D_DI[1] | D_DI[0];
+ assign Sqrt_cin_D = Sqrt_enable_SI && D_carry_D;
+ assign Cin_D = (Div_enable_SI ? Div_start_dly_SI : Sqrt_cin_D);
+ assign {Carry_out_DO, Sum_DO} = (A_DI + B_DI) + Cin_D;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/nrbd_nrsc_tp.v b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/nrbd_nrsc_tp.v
new file mode 100644
index 0000000..7b3b0cf
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/nrbd_nrsc_tp.v
@@ -0,0 +1,169 @@
+module nrbd_nrsc_tp
+#(
+ parameter Precision_ctl_Enable_S = 1
+)
+(
+ Clk_CI,
+ Rst_RBI,
+ Div_start_SI,
+ Sqrt_start_SI,
+ Start_SI,
+ Precision_ctl_SI,
+ Mant_a_DI,
+ Mant_b_DI,
+ Exp_a_DI,
+ Exp_b_DI,
+ Div_enable_SO,
+ Sqrt_enable_SO,
+ Ready_SO,
+ Done_SO,
+ Mant_z_DO,
+ Exp_z_DO
+);
+parameter C_DIV_RM = 2;
+parameter C_DIV_RM_NEAREST = 2'h0;
+parameter C_DIV_RM_TRUNC = 2'h1;
+parameter C_DIV_RM_PLUSINF = 2'h2;
+parameter C_DIV_RM_MINUSINF = 2'h3;
+parameter C_DIV_PC = 5;
+parameter C_DIV_OP = 32;
+parameter C_DIV_MANT = 23;
+parameter C_DIV_EXP = 8;
+parameter C_DIV_BIAS = 127;
+parameter C_DIV_BIAS_AONE = 8'h80;
+parameter C_DIV_HALF_BIAS = 63;
+parameter C_DIV_MANT_PRENORM = C_DIV_MANT+1;
+parameter C_DIV_EXP_ZERO = 8'h00;
+parameter C_DIV_EXP_ONE = 8'h01;
+parameter C_DIV_EXP_INF = 8'hff;
+parameter C_DIV_MANT_ZERO = 23'h0;
+parameter C_DIV_MANT_NAN = 23'h400000;
+ //parameter Precision_ctl_Enable_S = 1;
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire Div_start_SI;
+ input wire Sqrt_start_SI;
+ input wire Start_SI;
+ input wire [C_DIV_PC - 1:0] Precision_ctl_SI;
+ input wire [C_DIV_MANT:0] Mant_a_DI;
+ input wire [C_DIV_MANT:0] Mant_b_DI;
+ input wire [C_DIV_EXP:0] Exp_a_DI;
+ input wire [C_DIV_EXP:0] Exp_b_DI;
+ output wire Div_enable_SO;
+ output wire Sqrt_enable_SO;
+ output wire Ready_SO;
+ output wire Done_SO;
+ output wire [C_DIV_MANT:0] Mant_z_DO;
+ output wire [C_DIV_EXP + 1:0] Exp_z_DO;
+ wire [C_DIV_MANT + 1:0] First_iteration_cell_sum_D;
+ wire [C_DIV_MANT + 1:0] Sec_iteration_cell_sum_D;
+ wire [C_DIV_MANT + 1:0] Thi_iteration_cell_sum_D;
+ wire [C_DIV_MANT + 1:0] Fou_iteration_cell_sum_D;
+ wire First_iteration_cell_carry_D;
+ wire Sec_iteration_cell_carry_D;
+ wire Thi_iteration_cell_carry_D;
+ wire Fou_iteration_cell_carry_D;
+ wire [1:0] Sqrt_Da0;
+ wire [1:0] Sqrt_Da1;
+ wire [1:0] Sqrt_Da2;
+ wire [1:0] Sqrt_Da3;
+ wire [1:0] Sqrt_D0;
+ wire [1:0] Sqrt_D1;
+ wire [1:0] Sqrt_D2;
+ wire [1:0] Sqrt_D3;
+ wire [C_DIV_MANT + 1:0] First_iteration_cell_a_D;
+ wire [C_DIV_MANT + 1:0] First_iteration_cell_b_D;
+ wire [C_DIV_MANT + 1:0] Sec_iteration_cell_a_D;
+ wire [C_DIV_MANT + 1:0] Sec_iteration_cell_b_D;
+ wire [C_DIV_MANT + 1:0] Thi_iteration_cell_a_D;
+ wire [C_DIV_MANT + 1:0] Thi_iteration_cell_b_D;
+ wire [C_DIV_MANT + 1:0] Fou_iteration_cell_a_D;
+ wire [C_DIV_MANT + 1:0] Fou_iteration_cell_b_D;
+ wire Div_start_dly_S;
+ wire Sqrt_start_dly_S;
+ control_tp #(Precision_ctl_Enable_S) control_U0(
+ .Clk_CI(Clk_CI),
+ .Rst_RBI(Rst_RBI),
+ .Div_start_SI(Div_start_SI),
+ .Sqrt_start_SI(Sqrt_start_SI),
+ .Start_SI(Start_SI),
+ .Precision_ctl_SI(Precision_ctl_SI),
+ .Numerator_DI(Mant_a_DI),
+ .Exp_num_DI(Exp_a_DI),
+ .Denominator_DI(Mant_b_DI),
+ .Exp_den_DI(Exp_b_DI),
+ .First_iteration_cell_sum_DI(First_iteration_cell_sum_D),
+ .First_iteration_cell_carry_DI(First_iteration_cell_carry_D),
+ .Sqrt_Da0(Sqrt_Da0),
+ .Sec_iteration_cell_sum_DI(Sec_iteration_cell_sum_D),
+ .Sec_iteration_cell_carry_DI(Sec_iteration_cell_carry_D),
+ .Sqrt_Da1(Sqrt_Da1),
+ .Thi_iteration_cell_sum_DI(Thi_iteration_cell_sum_D),
+ .Thi_iteration_cell_carry_DI(Thi_iteration_cell_carry_D),
+ .Sqrt_Da2(Sqrt_Da2),
+ .Fou_iteration_cell_sum_DI(Fou_iteration_cell_sum_D),
+ .Fou_iteration_cell_carry_DI(Fou_iteration_cell_carry_D),
+ .Sqrt_Da3(Sqrt_Da3),
+ .Div_start_dly_SO(Div_start_dly_S),
+ .Sqrt_start_dly_SO(Sqrt_start_dly_S),
+ .Div_enable_SO(Div_enable_SO),
+ .Sqrt_enable_SO(Sqrt_enable_SO),
+ .Sqrt_D0(Sqrt_D0),
+ .Sqrt_D1(Sqrt_D1),
+ .Sqrt_D2(Sqrt_D2),
+ .Sqrt_D3(Sqrt_D3),
+ .First_iteration_cell_a_DO(First_iteration_cell_a_D),
+ .First_iteration_cell_b_DO(First_iteration_cell_b_D),
+ .Sec_iteration_cell_a_DO(Sec_iteration_cell_a_D),
+ .Sec_iteration_cell_b_DO(Sec_iteration_cell_b_D),
+ .Thi_iteration_cell_a_DO(Thi_iteration_cell_a_D),
+ .Thi_iteration_cell_b_DO(Thi_iteration_cell_b_D),
+ .Fou_iteration_cell_a_DO(Fou_iteration_cell_a_D),
+ .Fou_iteration_cell_b_DO(Fou_iteration_cell_b_D),
+ .Ready_SO(Ready_SO),
+ .Done_SO(Done_SO),
+ .Mant_result_prenorm_DO(Mant_z_DO),
+ .Exp_result_prenorm_DO(Exp_z_DO)
+ );
+ iteration_div_sqrt_first iteration_unit_U0(
+ .A_DI(First_iteration_cell_a_D),
+ .B_DI(First_iteration_cell_b_D),
+ .Div_enable_SI(Div_enable_SO),
+ .Div_start_dly_SI(Div_start_dly_S),
+ .Sqrt_enable_SI(Sqrt_enable_SO),
+ .D_DI(Sqrt_D0),
+ .D_DO(Sqrt_Da0),
+ .Sum_DO(First_iteration_cell_sum_D),
+ .Carry_out_DO(First_iteration_cell_carry_D)
+ );
+ iteration_div_sqrt iteration_unit_U1(
+ .A_DI(Sec_iteration_cell_a_D),
+ .B_DI(Sec_iteration_cell_b_D),
+ .Div_enable_SI(Div_enable_SO),
+ .Sqrt_enable_SI(Sqrt_enable_SO),
+ .D_DI(Sqrt_D1),
+ .D_DO(Sqrt_Da1),
+ .Sum_DO(Sec_iteration_cell_sum_D),
+ .Carry_out_DO(Sec_iteration_cell_carry_D)
+ );
+ iteration_div_sqrt iteration_unit_U2(
+ .A_DI(Thi_iteration_cell_a_D),
+ .B_DI(Thi_iteration_cell_b_D),
+ .Div_enable_SI(Div_enable_SO),
+ .Sqrt_enable_SI(Sqrt_enable_SO),
+ .D_DI(Sqrt_D2),
+ .D_DO(Sqrt_Da2),
+ .Sum_DO(Thi_iteration_cell_sum_D),
+ .Carry_out_DO(Thi_iteration_cell_carry_D)
+ );
+ iteration_div_sqrt iteration_unit_U3(
+ .A_DI(Fou_iteration_cell_a_D),
+ .B_DI(Fou_iteration_cell_b_D),
+ .Div_enable_SI(Div_enable_SO),
+ .Sqrt_enable_SI(Sqrt_enable_SO),
+ .D_DI(Sqrt_D3),
+ .D_DO(Sqrt_Da3),
+ .Sum_DO(Fou_iteration_cell_sum_D),
+ .Carry_out_DO(Fou_iteration_cell_carry_D)
+ );
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/preprocess.v b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/preprocess.v
new file mode 100644
index 0000000..1f6f916
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_div_sqrt_tp_nlp/preprocess.v
@@ -0,0 +1,215 @@
+module preprocess (
+ Clk_CI,
+ Rst_RBI,
+ Div_start_SI,
+ Sqrt_start_SI,
+ Operand_a_DI,
+ Operand_b_DI,
+ RM_SI,
+ Start_SO,
+ Exp_a_DO_norm,
+ Exp_b_DO_norm,
+ Mant_a_DO_norm,
+ Mant_b_DO_norm,
+ RM_dly_SO,
+ Sign_z_DO,
+ Inf_a_SO,
+ Inf_b_SO,
+ Zero_a_SO,
+ Zero_b_SO,
+ NaN_a_SO,
+ NaN_b_SO
+);
+parameter C_DIV_RM = 2;
+parameter C_DIV_RM_NEAREST = 2'h0;
+parameter C_DIV_RM_TRUNC = 2'h1;
+parameter C_DIV_RM_PLUSINF = 2'h2;
+parameter C_DIV_RM_MINUSINF = 2'h3;
+parameter C_DIV_PC = 5;
+parameter C_DIV_OP = 32;
+parameter C_DIV_MANT = 23;
+parameter C_DIV_EXP = 8;
+parameter C_DIV_BIAS = 127;
+parameter C_DIV_BIAS_AONE = 8'h80;
+parameter C_DIV_HALF_BIAS = 63;
+parameter C_DIV_MANT_PRENORM = C_DIV_MANT+1;
+parameter C_DIV_EXP_ZERO = 8'h00;
+parameter C_DIV_EXP_ONE = 8'h01;
+parameter C_DIV_EXP_INF = 8'hff;
+parameter C_DIV_MANT_ZERO = 23'h0;
+parameter C_DIV_MANT_NAN = 23'h400000;
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire Div_start_SI;
+ input wire Sqrt_start_SI;
+ input wire [C_DIV_OP - 1:0] Operand_a_DI;
+ input wire [C_DIV_OP - 1:0] Operand_b_DI;
+ input wire [C_DIV_RM - 1:0] RM_SI;
+ output wire Start_SO;
+ output wire [C_DIV_EXP:0] Exp_a_DO_norm;
+ output wire [C_DIV_EXP:0] Exp_b_DO_norm;
+ output wire [C_DIV_MANT:0] Mant_a_DO_norm;
+ output wire [C_DIV_MANT:0] Mant_b_DO_norm;
+ output wire [C_DIV_RM - 1:0] RM_dly_SO;
+ output wire Sign_z_DO;
+ output wire Inf_a_SO;
+ output wire Inf_b_SO;
+ output wire Zero_a_SO;
+ output wire Zero_b_SO;
+ output wire NaN_a_SO;
+ output wire NaN_b_SO;
+ wire Hb_a_D;
+ wire Hb_b_D;
+ wire [C_DIV_EXP - 1:0] Exp_a_D;
+ wire [C_DIV_EXP - 1:0] Exp_b_D;
+ wire [C_DIV_MANT:0] Mant_a_D;
+ wire [C_DIV_MANT:0] Mant_b_D;
+ wire Sign_a_D;
+ wire Sign_b_D;
+ wire Start_S;
+ assign Sign_a_D = Operand_a_DI[C_DIV_OP - 1];
+ assign Sign_b_D = Operand_b_DI[C_DIV_OP - 1];
+ assign Exp_a_D = Operand_a_DI[C_DIV_OP - 2:C_DIV_MANT];
+ assign Exp_b_D = Operand_b_DI[C_DIV_OP - 2:C_DIV_MANT];
+ assign Mant_a_D = {Hb_a_D, Operand_a_DI[C_DIV_MANT - 1:0]};
+ assign Mant_b_D = {Hb_b_D, Operand_b_DI[C_DIV_MANT - 1:0]};
+ assign Hb_a_D = |Exp_a_D;
+ assign Hb_b_D = |Exp_b_D;
+ assign Start_S = Div_start_SI | Sqrt_start_SI;
+ wire Mant_a_prenorm_zero_S;
+ wire Mant_b_prenorm_zero_S;
+ assign Mant_a_prenorm_zero_S = Operand_a_DI[C_DIV_MANT - 1:0] == C_DIV_MANT_ZERO;
+ assign Mant_b_prenorm_zero_S = Operand_b_DI[C_DIV_MANT - 1:0] == C_DIV_MANT_ZERO;
+ wire Exp_a_prenorm_zero_S;
+ wire Exp_b_prenorm_zero_S;
+ assign Exp_a_prenorm_zero_S = Exp_a_D == C_DIV_EXP_ZERO;
+ assign Exp_b_prenorm_zero_S = Exp_b_D == C_DIV_EXP_ZERO;
+ wire Exp_a_prenorm_Inf_NaN_S;
+ wire Exp_b_prenorm_Inf_NaN_S;
+ assign Exp_a_prenorm_Inf_NaN_S = Exp_a_D == C_DIV_EXP_INF;
+ assign Exp_b_prenorm_Inf_NaN_S = Exp_b_D == C_DIV_EXP_INF;
+ wire Zero_a_SN;
+ reg Zero_a_SP;
+ wire Zero_b_SN;
+ reg Zero_b_SP;
+ wire Inf_a_SN;
+ reg Inf_a_SP;
+ wire Inf_b_SN;
+ reg Inf_b_SP;
+ wire NaN_a_SN;
+ reg NaN_a_SP;
+ wire NaN_b_SN;
+ reg NaN_b_SP;
+ assign Zero_a_SN = (Start_S ? Exp_a_prenorm_zero_S && Mant_a_prenorm_zero_S : Zero_a_SP);
+ assign Zero_b_SN = (Start_S ? Exp_b_prenorm_zero_S && Mant_b_prenorm_zero_S : Zero_b_SP);
+ assign Inf_a_SN = (Start_S ? Exp_a_prenorm_Inf_NaN_S && Mant_a_prenorm_zero_S : Inf_a_SP);
+ assign Inf_b_SN = (Start_S ? Exp_b_prenorm_Inf_NaN_S && Mant_b_prenorm_zero_S : Inf_b_SP);
+ assign NaN_a_SN = (Start_S ? Exp_a_prenorm_Inf_NaN_S && ~Mant_a_prenorm_zero_S : NaN_a_SP);
+ assign NaN_b_SN = (Start_S ? Exp_b_prenorm_Inf_NaN_S && ~Mant_b_prenorm_zero_S : NaN_b_SP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI) begin
+ Zero_a_SP <= 1'sb0;
+ Zero_b_SP <= 1'sb0;
+ Inf_a_SP <= 1'sb0;
+ Inf_b_SP <= 1'sb0;
+ NaN_a_SP <= 1'sb0;
+ NaN_b_SP <= 1'sb0;
+ end
+ else begin
+ Inf_a_SP <= Inf_a_SN;
+ Inf_b_SP <= Inf_b_SN;
+ Zero_a_SP <= Zero_a_SN;
+ Zero_b_SP <= Zero_b_SN;
+ NaN_a_SP <= NaN_a_SN;
+ NaN_b_SP <= NaN_b_SN;
+ end
+ reg Sign_z_DN;
+ reg Sign_z_DP;
+ always @(*)
+ if (~Rst_RBI)
+ Sign_z_DN = 1'sb0;
+ else if (Div_start_SI)
+ Sign_z_DN = Sign_a_D ^ Sign_b_D;
+ else if (Sqrt_start_SI)
+ Sign_z_DN = Sign_a_D;
+ else
+ Sign_z_DN = Sign_z_DP;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Sign_z_DP <= 1'sb0;
+ else
+ Sign_z_DP <= Sign_z_DN;
+ reg [C_DIV_RM - 1:0] RM_DN;
+ reg [C_DIV_RM - 1:0] RM_DP;
+ always @(*)
+ if (~Rst_RBI)
+ RM_DN = 1'sb0;
+ else if (Start_S)
+ RM_DN = RM_SI;
+ else
+ RM_DN = RM_DP;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ RM_DP <= 1'sb0;
+ else
+ RM_DP <= RM_DN;
+ assign RM_dly_SO = RM_DP;
+ wire [4:0] Mant_leadingOne_a;
+ wire [4:0] Mant_leadingOne_b;
+ wire Mant_zero_S_a;
+ wire Mant_zero_S_b;
+ fpu_ff #(.LEN(C_DIV_MANT + 1)) LOD_Ua(
+ .in_i(Mant_a_D),
+ .first_one_o(Mant_leadingOne_a),
+ .no_ones_o(Mant_zero_S_a)
+ );
+ wire [C_DIV_MANT:0] Mant_a_norm_DN;
+ reg [C_DIV_MANT:0] Mant_a_norm_DP;
+ assign Mant_a_norm_DN = (Start_S ? Mant_a_D << Mant_leadingOne_a : Mant_a_norm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Mant_a_norm_DP <= 1'sb0;
+ else
+ Mant_a_norm_DP <= Mant_a_norm_DN;
+ wire [C_DIV_EXP:0] Exp_a_norm_DN;
+ reg [C_DIV_EXP:0] Exp_a_norm_DP;
+ assign Exp_a_norm_DN = (Start_S ? (Exp_a_D - Mant_leadingOne_a) + |Mant_leadingOne_a : Exp_a_norm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Exp_a_norm_DP <= 1'sb0;
+ else
+ Exp_a_norm_DP <= Exp_a_norm_DN;
+ fpu_ff #(.LEN(C_DIV_MANT + 1)) LOD_Ub(
+ .in_i(Mant_b_D),
+ .first_one_o(Mant_leadingOne_b),
+ .no_ones_o(Mant_zero_S_b)
+ );
+ wire [C_DIV_MANT:0] Mant_b_norm_DN;
+ reg [C_DIV_MANT:0] Mant_b_norm_DP;
+ assign Mant_b_norm_DN = (Start_S ? Mant_b_D << Mant_leadingOne_b : Mant_b_norm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Mant_b_norm_DP <= 1'sb0;
+ else
+ Mant_b_norm_DP <= Mant_b_norm_DN;
+ wire [C_DIV_EXP:0] Exp_b_norm_DN;
+ reg [C_DIV_EXP:0] Exp_b_norm_DP;
+ assign Exp_b_norm_DN = (Start_S ? (Exp_b_D - Mant_leadingOne_b) + |Mant_leadingOne_b : Exp_b_norm_DP);
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI)
+ Exp_b_norm_DP <= 1'sb0;
+ else
+ Exp_b_norm_DP <= Exp_b_norm_DN;
+ assign Start_SO = Start_S;
+ assign Exp_a_DO_norm = Exp_a_norm_DP;
+ assign Exp_b_DO_norm = Exp_b_norm_DP;
+ assign Mant_a_DO_norm = Mant_a_norm_DP;
+ assign Mant_b_DO_norm = Mant_b_norm_DP;
+ assign Sign_z_DO = Sign_z_DP;
+ assign Inf_a_SO = Inf_a_SP;
+ assign Inf_b_SO = Inf_b_SP;
+ assign Zero_a_SO = Zero_a_SP;
+ assign Zero_b_SO = Zero_b_SP;
+ assign NaN_a_SO = NaN_a_SP;
+ assign NaN_b_SO = NaN_b_SP;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/CSA.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/CSA.v
new file mode 100644
index 0000000..3d16722
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/CSA.v
@@ -0,0 +1,25 @@
+module CSA
+#( parameter n=49 )
+(
+ A_DI,
+ B_DI,
+ C_DI,
+ Sum_DO,
+ Carry_DO
+);
+ //parameter n = 49;
+ input wire [n - 1:0] A_DI;
+ input wire [n - 1:0] B_DI;
+ input wire [n - 1:0] C_DI;
+ output reg [n - 1:0] Sum_DO;
+ output reg [n - 1:0] Carry_DO;
+ genvar i;
+ generate
+ for (i = 0; i <= (n - 1); i = i + 1) begin : genblk1
+ always @(*) begin
+ Sum_DO[i] = (A_DI[i] ^ B_DI[i]) ^ C_DI[i];
+ Carry_DO[i] = ((A_DI[i] & B_DI[i]) | (A_DI[i] & C_DI[i])) | (B_DI[i] & C_DI[i]);
+ end
+ end
+ endgenerate
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/LZA.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/LZA.v
new file mode 100644
index 0000000..a3d872f
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/LZA.v
@@ -0,0 +1,67 @@
+module LZA
+#( parameter C_WIDTH = 74)
+(
+ A_DI,
+ B_DI,
+ Leading_one_DO,
+ No_one_SO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+ //parameter C_WIDTH = 74;
+ input wire [C_WIDTH - 1:0] A_DI;
+ input wire [C_WIDTH - 1:0] B_DI;
+ output wire [C_LEADONE_WIDTH - 1:0] Leading_one_DO;
+ output wire No_one_SO;
+ reg [C_WIDTH - 1:0] T_D;
+ reg [C_WIDTH - 1:0] G_D;
+ reg [C_WIDTH - 1:0] Z_D;
+ reg [C_WIDTH - 1:0] F_S;
+ genvar i;
+ generate
+ for (i = 0; i <= (C_WIDTH - 1); i = i + 1) begin : genblk1
+ always @(*) begin
+ T_D[i] = A_DI[i] ^ B_DI[i];
+ G_D[i] = A_DI[i] && B_DI[i];
+ Z_D[i] = ~(A_DI[i] | B_DI[i]);
+ end
+ end
+ endgenerate
+ wire [1:1] sv2v_tmp_CEAFB;
+ assign sv2v_tmp_CEAFB = ~T_D[C_WIDTH - 1] & T_D[C_WIDTH - 2];
+ always @(*) F_S[C_WIDTH - 1] = sv2v_tmp_CEAFB;
+ genvar j;
+ generate
+ for (j = 1; j < (C_WIDTH - 1); j = j + 1) begin : genblk2
+ always @(*) F_S[j] = (T_D[j + 1] & ((G_D[j] & ~Z_D[j - 1]) | (Z_D[j] & ~G_D[j - 1]))) | (~T_D[j + 1] & ((Z_D[j] && ~Z_D[j - 1]) | (G_D[j] & ~G_D[j - 1])));
+ end
+ endgenerate
+ wire [1:1] sv2v_tmp_42D88;
+ assign sv2v_tmp_42D88 = (T_D[1] & Z_D[0]) | (~T_D[1] & (T_D[0] | G_D[0]));
+ always @(*) F_S[0] = sv2v_tmp_42D88;
+ wire [C_LEADONE_WIDTH - 1:0] Leading_one_D;
+ wire No_one_S;
+ fpu_ff #(.LEN(C_WIDTH)) LOD_Ub(
+ .in_i(F_S),
+ .first_one_o(Leading_one_D),
+ .no_ones_o(No_one_S)
+ );
+ assign Leading_one_DO = Leading_one_D;
+ assign No_one_SO = No_one_S;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/adders.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/adders.v
new file mode 100644
index 0000000..884c174
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/adders.v
@@ -0,0 +1,65 @@
+`include "fpu_defs_fmac.sv"
+
+module adders (
+ AL_DI,
+ BL_DI,
+ Sub_SI,
+ Sign_cor_SI,
+ Sign_amt_DI,
+ Sft_stop_SI,
+ BH_DI,
+ Sign_postalig_DI,
+ Sum_pos_DO,
+ Sign_out_DO,
+ A_LZA_DO,
+ B_LZA_DO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+ input wire [(2 * C_MANT) + 1:0] AL_DI;
+ input wire [(2 * C_MANT) + 1:0] BL_DI;
+ input wire Sub_SI;
+ input wire [2:0] Sign_cor_SI;
+ input wire Sign_amt_DI;
+ input wire Sft_stop_SI;
+ input wire [C_MANT + 3:0] BH_DI;
+ input wire Sign_postalig_DI;
+ output wire [(3 * C_MANT) + 4:0] Sum_pos_DO;
+ output wire Sign_out_DO;
+ output wire [(3 * C_MANT) + 4:0] A_LZA_DO;
+ output wire [(3 * C_MANT) + 4:0] B_LZA_DO;
+ wire Carry_postcor_D;
+ assign Carry_postcor_D = (Sign_amt_DI ? 1'b0 : {~(|Sign_cor_SI) ^ BL_DI[(2 * C_MANT) + 1]});
+ wire Carry_uninv_LS;
+ wire [(2 * C_MANT) + 1:0] Sum_uninv_LD;
+ assign {Carry_uninv_LS, Sum_uninv_LD} = {1'b0, AL_DI} + {Carry_postcor_D, BL_DI[2 * C_MANT:0], Sub_SI};
+ wire Carry_inv_LS;
+ wire [(2 * C_MANT) + 2:0] Sum_inv_LD;
+ assign {Carry_inv_LS, Sum_inv_LD} = ({1'b1, ~AL_DI, 1'b1} + {~Carry_postcor_D, ~BL_DI[2 * C_MANT:0], 2'b11}) + 2;
+ wire [C_MANT + 3:0] BH_inv_D;
+ wire [C_MANT + 3:0] Sum_uninv_HD;
+ wire [C_MANT + 3:0] Sum_inv_HD;
+ assign BH_inv_D = ~BH_DI;
+ assign {Carryout_uninv_HS, Sum_uninv_HD} = (Carry_uninv_LS ? {BH_DI + 1} : BH_DI);
+ assign {Carryout_inv_HS, Sum_inv_HD} = (Carry_inv_LS ? BH_inv_D : {BH_inv_D - 1});
+ assign Sum_pos_DO = (Sft_stop_SI ? {26'h0000000, Sum_uninv_LD[(2 * C_MANT) + 1:0]} : {(Sign_amt_DI ? {BH_DI[C_MANT + 2:0], 48'b000000000000000000000000000000000000000000000000} : {(Sum_uninv_HD[C_MANT + 3] ? {Sum_inv_HD[C_MANT + 2:0], Sum_inv_LD[(2 * C_MANT) + 2:1]} : {Sum_uninv_HD[C_MANT + 2:0], Sum_uninv_LD})})});
+ assign Sign_out_DO = (Sign_amt_DI ? Sign_postalig_DI : Sum_uninv_HD[C_MANT + 3] ^ Sign_postalig_DI);
+ assign A_LZA_DO = (Sign_amt_DI ? {BH_DI[C_MANT + 2:0], 48'b000000000000000000000000000000000000000000000000} : {BH_DI[C_MANT + 2:0], 48'b000000000000000000000000000000000000000000000000});
+ assign B_LZA_DO = (Sign_amt_DI ? 74'h0000000000000000000 : {25'h0000000, Carry_uninv_LS, Sum_uninv_LD});
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/aligner.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/aligner.v
new file mode 100644
index 0000000..f1eb93c
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/aligner.v
@@ -0,0 +1,78 @@
+`include "fpu_defs_fmac.sv"
+
+module aligner (
+ Exp_a_DI,
+ Exp_b_DI,
+ Exp_c_DI,
+ Mant_a_DI,
+ Sign_a_DI,
+ Sign_b_DI,
+ Sign_c_DI,
+ Pp_sum_DI,
+ Pp_carry_DI,
+ Sub_SO,
+ Mant_postalig_a_DO,
+ Exp_postalig_DO,
+ Sign_postalig_DO,
+ Sign_amt_DO,
+ Sft_stop_SO,
+ Pp_sum_postcal_DO,
+ Pp_carry_postcal_DO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+ input wire [C_EXP - 1:0] Exp_a_DI;
+ input wire [C_EXP - 1:0] Exp_b_DI;
+ input wire [C_EXP - 1:0] Exp_c_DI;
+ input wire [C_MANT:0] Mant_a_DI;
+ input wire Sign_a_DI;
+ input wire Sign_b_DI;
+ input wire Sign_c_DI;
+ input wire [(2 * C_MANT) + 2:0] Pp_sum_DI;
+ input wire [(2 * C_MANT) + 2:0] Pp_carry_DI;
+ output wire Sub_SO;
+ output wire [74:0] Mant_postalig_a_DO;
+ output wire [C_EXP + 1:0] Exp_postalig_DO;
+ output wire Sign_postalig_DO;
+ output wire Sign_amt_DO;
+ output wire Sft_stop_SO;
+ output wire [(2 * C_MANT) + 2:0] Pp_sum_postcal_DO;
+ output wire [(2 * C_MANT) + 2:0] Pp_carry_postcal_DO;
+ wire [C_EXP + 1:0] Exp_dif_D;
+ wire [C_EXP + 1:0] Sft_amt_D;
+ assign Sub_SO = (Sign_a_DI ^ Sign_b_DI) ^ Sign_c_DI;
+ assign Exp_dif_D = ((Exp_a_DI - Exp_b_DI) - Exp_c_DI) + C_BIAS;
+ assign Sft_amt_D = (((Exp_b_DI + Exp_c_DI) - Exp_a_DI) - C_BIAS) + 27;
+ assign Sign_amt_DO = Sft_amt_D[C_EXP + 1];
+ wire Sft_stop_S;
+ assign Sft_stop_S = ~Sft_amt_D[C_EXP + 1] && (Sft_amt_D[C_EXP:0] >= 74);
+ assign Sft_stop_SO = Sft_stop_S;
+ function automatic [0:0] sv2v_cast_1;
+ input reg [0:0] inp;
+ sv2v_cast_1 = inp;
+ endfunction
+ assign Exp_postalig_DO = (Sft_amt_D[C_EXP + 1] ? Exp_a_DI : {sv2v_cast_1(((Exp_b_DI + Exp_c_DI) - C_BIAS) + 27)});
+ wire [73:0] Mant_postalig_a_D;
+ wire [C_MANT:0] Bit_sftout_D;
+ assign {Mant_postalig_a_D, Bit_sftout_D} = {Mant_a_DI, 74'h0000000000000000000} >> {(Sft_stop_S ? 0 : Sft_amt_D)};
+ assign Mant_postalig_a_DO = (Sft_amt_D[C_EXP + 1] ? {1'b0, Mant_a_DI, 50'h0000000000000} : {(Sft_stop_S ? 75'h0000000000000000000 : {(Sub_SO ? {1'b1, ~Mant_postalig_a_D} : {1'b0, Mant_postalig_a_D})})});
+ assign Sign_postalig_DO = (Sft_amt_D[C_EXP + 1] ? Sign_a_DI : Sign_b_DI ^ Sign_c_DI);
+ assign Pp_sum_postcal_DO = (Sft_amt_D[C_EXP + 1] ? {(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)) {1'sb0}} : Pp_sum_DI);
+ assign Pp_carry_postcal_DO = (Sft_amt_D[C_EXP + 1] ? {(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)) {1'sb0}} : Pp_carry_DI);
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/booth_encoder.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/booth_encoder.v
new file mode 100644
index 0000000..b494d5a
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/booth_encoder.v
@@ -0,0 +1,16 @@
+module booth_encoder (
+ Booth_b_DI,
+ Sel_1x_SO,
+ Sel_2x_SO,
+ Sel_sign_SO
+);
+ input wire [2:0] Booth_b_DI;
+ output wire Sel_1x_SO;
+ output wire Sel_2x_SO;
+ output wire Sel_sign_SO;
+ wire Sel_xnor_S;
+ assign Sel_1x_SO = ^Booth_b_DI[1:0];
+ assign Sel_xnor_S = ~(^Booth_b_DI[2:1]);
+ assign Sel_2x_SO = ~(Sel_1x_SO | Sel_xnor_S);
+ assign Sel_sign_SO = Booth_b_DI[2];
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/booth_selector.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/booth_selector.v
new file mode 100644
index 0000000..17f7944
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/booth_selector.v
@@ -0,0 +1,14 @@
+module booth_selector (
+ Booth_a_DI,
+ Sel_1x_SI,
+ Sel_2x_SI,
+ Sel_sign_SI,
+ Booth_pp_DO
+);
+ input wire [1:0] Booth_a_DI;
+ input wire Sel_1x_SI;
+ input wire Sel_2x_SI;
+ input wire Sel_sign_SI;
+ output wire Booth_pp_DO;
+ assign Booth_pp_DO = ~(~((Sel_1x_SI && Booth_a_DI[1]) | (Sel_2x_SI && Booth_a_DI[0])) ^ Sel_sign_SI);
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/fmac.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/fmac.v
new file mode 100644
index 0000000..f4cbe17
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/fmac.v
@@ -0,0 +1,190 @@
+module fmac (
+ Operand_a_DI,
+ Operand_b_DI,
+ Operand_c_DI,
+ RM_SI,
+ Result_DO,
+ Exp_OF_SO,
+ Exp_UF_SO,
+ Exp_NX_SO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+ input wire [C_OP - 1:0] Operand_a_DI;
+ input wire [C_OP - 1:0] Operand_b_DI;
+ input wire [C_OP - 1:0] Operand_c_DI;
+ input wire [C_RM - 1:0] RM_SI;
+ output wire [31:0] Result_DO;
+ output wire Exp_OF_SO;
+ output wire Exp_UF_SO;
+ output wire Exp_NX_SO;
+ wire [C_MANT - 1:0] Mant_res_DO;
+ wire [C_EXP - 1:0] Exp_res_DO;
+ wire Sign_res_DO;
+ wire DeN_a_S;
+ wire Sub_S;
+ wire Sign_postalig_D;
+ wire Sign_amt_D;
+ wire Sft_stop_S;
+ wire Sign_out_D;
+ assign Result_DO = {Sign_res_DO, Exp_res_DO, Mant_res_DO};
+ wire Sign_a_D;
+ wire Sign_b_D;
+ wire Sign_c_D;
+ wire [C_EXP - 1:0] Exp_a_D;
+ wire [C_EXP - 1:0] Exp_b_D;
+ wire [C_EXP - 1:0] Exp_c_D;
+ wire [C_MANT:0] Mant_a_D;
+ wire [C_MANT:0] Mant_b_D;
+ wire [C_MANT:0] Mant_c_D;
+ wire Inf_a_S;
+ wire Inf_b_S;
+ wire Inf_c_S;
+ wire NaN_a_S;
+ wire NaN_b_S;
+ wire NaN_c_S;
+ wire Zero_a_S;
+ wire Zero_b_S;
+ wire Zero_c_S;
+ preprocess_fmac precess_U0(
+ .Operand_a_DI(Operand_a_DI),
+ .Operand_b_DI(Operand_b_DI),
+ .Operand_c_DI(Operand_c_DI),
+ .Exp_a_DO(Exp_a_D),
+ .Mant_a_DO(Mant_a_D),
+ .Sign_a_DO(Sign_a_D),
+ .Exp_b_DO(Exp_b_D),
+ .Mant_b_DO(Mant_b_D),
+ .Sign_b_DO(Sign_b_D),
+ .Exp_c_DO(Exp_c_D),
+ .Mant_c_DO(Mant_c_D),
+ .Sign_c_DO(Sign_c_D),
+ .DeN_a_SO(DeN_a_S),
+ .Inf_a_SO(Inf_a_S),
+ .Inf_b_SO(Inf_b_S),
+ .Inf_c_SO(Inf_c_S),
+ .Zero_a_SO(Zero_a_S),
+ .Zero_b_SO(Zero_b_S),
+ .Zero_c_SO(Zero_c_S),
+ .NaN_a_SO(NaN_a_S),
+ .NaN_b_SO(NaN_b_S),
+ .NaN_c_SO(NaN_c_S)
+ );
+ wire [(((2 * C_MANT) + 2) >= 0 ? (13 * ((2 * C_MANT) + 3)) - 1 : (13 * (1 - ((2 * C_MANT) + 2))) + ((2 * C_MANT) + 1)):(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2)] Pp_index_D;
+ pp_generation pp_gneration_U0(
+ .Mant_a_DI(Mant_b_D),
+ .Mant_b_DI(Mant_c_D),
+ .Pp_index_DO(Pp_index_D)
+ );
+ wire [(2 * C_MANT) + 2:0] Pp_sum_D;
+ wire [(2 * C_MANT) + 2:0] Pp_carry_D;
+ wire MSB_cor_D;
+ wallace wallace_U0(
+ .Pp_index_DI(Pp_index_D),
+ .Pp_sum_DO(Pp_sum_D),
+ .Pp_carry_DO(Pp_carry_D),
+ .MSB_cor_DO(MSB_cor_D)
+ );
+ wire [74:0] Mant_postalig_a_D;
+ wire signed [C_EXP + 1:0] Exp_postalig_D;
+ wire [(2 * C_MANT) + 2:0] Pp_sum_postcal_D;
+ wire [(2 * C_MANT) + 2:0] Pp_carry_postcal_D;
+ aligner aligner_U0(
+ .Exp_a_DI(Exp_a_D),
+ .Exp_b_DI(Exp_b_D),
+ .Mant_a_DI(Mant_a_D),
+ .Exp_c_DI(Exp_c_D),
+ .Sign_a_DI(Sign_a_D),
+ .Sign_b_DI(Sign_b_D),
+ .Sign_c_DI(Sign_c_D),
+ .Pp_sum_DI(Pp_sum_D),
+ .Pp_carry_DI(Pp_carry_D),
+ .Sub_SO(Sub_S),
+ .Mant_postalig_a_DO(Mant_postalig_a_D),
+ .Exp_postalig_DO(Exp_postalig_D),
+ .Sign_postalig_DO(Sign_postalig_D),
+ .Sign_amt_DO(Sign_amt_D),
+ .Sft_stop_SO(Sft_stop_S),
+ .Pp_sum_postcal_DO(Pp_sum_postcal_D),
+ .Pp_carry_postcal_DO(Pp_carry_postcal_D)
+ );
+ wire [(2 * C_MANT) + 1:0] Csa_sum_D;
+ wire [(2 * C_MANT) + 1:0] Csa_carry_D;
+ CSA #((2 * C_MANT) + 2) CSA_U0(
+ .A_DI(Mant_postalig_a_D[(2 * C_MANT) + 1:0]),
+ .B_DI({Pp_sum_postcal_D[(2 * C_MANT) + 1:0]}),
+ .C_DI({Pp_carry_postcal_D[2 * C_MANT:0], 1'b0}),
+ .Sum_DO(Csa_sum_D),
+ .Carry_DO(Csa_carry_D)
+ );
+ wire [73:0] Sum_pos_D;
+ wire [(3 * C_MANT) + 4:0] A_LZA_D;
+ wire [(3 * C_MANT) + 4:0] B_LZA_D;
+ adders adders_U0(
+ .AL_DI(Csa_sum_D),
+ .BL_DI(Csa_carry_D),
+ .Sub_SI(Sub_S),
+ .Sign_cor_SI({MSB_cor_D, Pp_carry_postcal_D[(2 * C_MANT) + 2], {Pp_sum_postcal_D[(2 * C_MANT) + 2] && Pp_carry_postcal_D[(2 * C_MANT) + 1]}}),
+ .Sign_amt_DI(Sign_amt_D),
+ .Sft_stop_SI(Sft_stop_S),
+ .BH_DI(Mant_postalig_a_D[(3 * C_MANT) + 5:(2 * C_MANT) + 2]),
+ .Sign_postalig_DI(Sign_postalig_D),
+ .Sum_pos_DO(Sum_pos_D),
+ .Sign_out_DO(Sign_out_D),
+ .A_LZA_DO(A_LZA_D),
+ .B_LZA_DO(B_LZA_D)
+ );
+ wire [C_LEADONE_WIDTH - 1:0] Leading_one_D;
+ wire No_one_S;
+ LZA #((3 * C_MANT) + 5) LZA_U0(
+ .A_DI(A_LZA_D),
+ .B_DI(B_LZA_D),
+ .Leading_one_DO(Leading_one_D),
+ .No_one_SO(No_one_S)
+ );
+ fpu_norm_fmac fpu_norm_U0(
+ .Mant_in_DI(Sum_pos_D),
+ .Exp_in_DI(Exp_postalig_D),
+ .Sign_in_DI(Sign_out_D),
+ .Leading_one_DI(Leading_one_D),
+ .No_one_SI(No_one_S),
+ .Sign_amt_DI(Sign_amt_D),
+ .Sub_SI(Sub_S),
+ .Exp_a_DI(Operand_a_DI[C_OP - 2:C_MANT]),
+ .Mant_a_DI(Mant_a_D),
+ .Sign_a_DI(Sign_a_D),
+ .DeN_a_SI(DeN_a_S),
+ .RM_SI(RM_SI),
+ .Inf_a_SI(Inf_a_S),
+ .Inf_b_SI(Inf_b_S),
+ .Inf_c_SI(Inf_c_S),
+ .Zero_a_SI(Zero_a_S),
+ .Zero_b_SI(Zero_b_S),
+ .Zero_c_SI(Zero_c_S),
+ .NaN_a_SI(NaN_a_S),
+ .NaN_b_SI(NaN_b_S),
+ .NaN_c_SI(NaN_c_S),
+ .Mant_res_DO(Mant_res_DO),
+ .Exp_res_DO(Exp_res_DO),
+ .Sign_res_DO(Sign_res_DO),
+ .Exp_OF_SO(Exp_OF_SO),
+ .Exp_UF_SO(Exp_UF_SO),
+ .Flag_Inexact_SO(Exp_NX_SO)
+ );
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/fpu_defs_fmac.sv b/verilog/rtl/ips/fpu/hdl/fpu_fmac/fpu_defs_fmac.sv
new file mode 100644
index 0000000..e0d5eaf
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/fpu_defs_fmac.sv
@@ -0,0 +1,41 @@
+// Copyright 2017 ETH Zurich and University of Bologna.
+// Copyright and related rights are licensed under the Solderpad Hardware
+// License, Version 0.51 (the “License”); you may not use this file except in
+// compliance with the License. You may obtain a copy of the License at
+// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
+// or agreed to in writing, software, hardware and materials distributed under
+// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+///////////////////////////////////////////////////////////////////////////////
+// This file contains all fmac parameters //
+// //
+// Authors : Lei Li (lile@iis.ee.ethz.ch) //
+// //
+// //
+// Copyright (c) 2017 Integrated Systems Laboratory, ETH Zurich //
+///////////////////////////////////////////////////////////////////////////////
+
+
+package fpu_defs_fmac;
+
+ parameter C_RM = 2;
+ parameter C_RM_NEAREST = 2'h0;
+ parameter C_RM_TRUNC = 2'h1;
+ parameter C_RM_PLUSINF = 2'h2;
+ parameter C_RM_MINUSINF = 2'h3;
+ parameter C_PC = 5;
+ parameter C_OP = 32;
+ parameter C_MANT = 23;
+ parameter C_EXP = 8;
+ parameter C_BIAS = 127;
+ parameter C_HALF_BIAS = 63;
+ parameter C_LEADONE_WIDTH = 7;
+ parameter C_MANT_PRENORM = C_MANT+1;
+ parameter C_EXP_ZERO = 8'h00;
+ parameter C_EXP_ONE = 8'h01;
+ parameter C_EXP_INF = 8'hff;
+ parameter C_MANT_ZERO = 23'h0;
+ parameter C_MANT_NAN = 23'h400000;
+
+endpackage : fpu_defs_fmac
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/fpu_norm_fmac.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/fpu_norm_fmac.v
new file mode 100644
index 0000000..00417db
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/fpu_norm_fmac.v
@@ -0,0 +1,280 @@
+module fpu_norm_fmac (
+ Mant_in_DI,
+ Exp_in_DI,
+ Sign_in_DI,
+ Leading_one_DI,
+ No_one_SI,
+ Sign_amt_DI,
+ Sub_SI,
+ Exp_a_DI,
+ Mant_a_DI,
+ Sign_a_DI,
+ DeN_a_SI,
+ RM_SI,
+ Stick_one_SI,
+ Inf_a_SI,
+ Inf_b_SI,
+ Inf_c_SI,
+ Zero_a_SI,
+ Zero_b_SI,
+ Zero_c_SI,
+ NaN_a_SI,
+ NaN_b_SI,
+ NaN_c_SI,
+ Mant_res_DO,
+ Exp_res_DO,
+ Sign_res_DO,
+ Exp_OF_SO,
+ Exp_UF_SO,
+ Flag_Inexact_SO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+ input wire [(3 * C_MANT) + 4:0] Mant_in_DI;
+ input wire signed [C_EXP + 1:0] Exp_in_DI;
+ input wire Sign_in_DI;
+ input wire [C_LEADONE_WIDTH - 1:0] Leading_one_DI;
+ input wire No_one_SI;
+ input wire Sign_amt_DI;
+ input wire Sub_SI;
+ input wire [C_EXP - 1:0] Exp_a_DI;
+ input wire [C_MANT:0] Mant_a_DI;
+ input wire Sign_a_DI;
+ input wire DeN_a_SI;
+ input wire [C_RM - 1:0] RM_SI;
+ input wire Stick_one_SI;
+ input wire Inf_a_SI;
+ input wire Inf_b_SI;
+ input wire Inf_c_SI;
+ input wire Zero_a_SI;
+ input wire Zero_b_SI;
+ input wire Zero_c_SI;
+ input wire NaN_a_SI;
+ input wire NaN_b_SI;
+ input wire NaN_c_SI;
+ output wire [C_MANT - 1:0] Mant_res_DO;
+ output wire [C_EXP - 1:0] Exp_res_DO;
+ output reg Sign_res_DO;
+ output reg Exp_OF_SO;
+ output reg Exp_UF_SO;
+ output wire Flag_Inexact_SO;
+ reg [C_MANT:0] Mant_res_norm_D;
+ reg [C_EXP - 1:0] Exp_res_norm_D;
+ reg [1:0] Mant_lower_D;
+ wire Stick_one_HD;
+ wire [(3 * C_MANT) + 4:0] Mant_postsft_D;
+ wire [C_EXP + 1:0] Exp_postsft_D;
+ wire [C_EXP + 1:0] Exp_postsft_addone_D;
+ wire [C_LEADONE_WIDTH - 1:0] Leading_one_D;
+ wire [C_EXP:0] LSt_Mant_D;
+ assign Leading_one_D = (Sign_amt_DI | Mant_in_DI[(3 * C_MANT) + 4] ? 0 : Leading_one_DI);
+ wire Exp_lg_S;
+ assign Exp_lg_S = Exp_in_DI > Leading_one_D;
+ assign LSt_Mant_D = (Exp_in_DI[C_EXP + 1] ? 0 : (Exp_lg_S ? Leading_one_D : Exp_in_DI[C_EXP:0] - 1));
+ assign Mant_postsft_D = Mant_in_DI << LSt_Mant_D;
+ assign Exp_postsft_D = (Exp_in_DI[C_EXP + 1] ? 0 : (Exp_lg_S ? Exp_in_DI - Leading_one_D : 1));
+ assign Exp_postsft_addone_D = (Exp_in_DI - Leading_one_D) - 1;
+ wire [C_EXP + 1:0] Exp_Max_RS_D;
+ assign Exp_Max_RS_D = Exp_in_DI[C_EXP:0] + 74;
+ wire [C_EXP + 1:0] Num_RS_D;
+ assign Num_RS_D = ~Exp_in_DI + 2;
+ wire [(3 * C_MANT) + 6:0] Mant_RS_D;
+ assign Mant_RS_D = {Mant_in_DI, 1'b0, 1'b0} >> Num_RS_D;
+ wire [(2 * C_MANT) + 1:0] Mant_StickCh_D;
+ assign Mant_StickCh_D = (Exp_postsft_D[C_EXP + 1] ? Mant_RS_D[(2 * C_MANT) + 3:2] : (Exp_postsft_D[C_EXP + 1:0] == {((C_EXP + 1) >= 0 ? C_EXP + 2 : 1 - (C_EXP + 1)) {1'sb0}} ? Mant_postsft_D[(2 * C_MANT) + 2:1] : (Mant_postsft_D[(3 * C_MANT) + 4] | (Exp_postsft_D == 0) ? Mant_postsft_D[(2 * C_MANT) + 1:0] : {Mant_postsft_D[2 * C_MANT:0], 1'b0})));
+ assign Stick_one_HD = |Mant_StickCh_D;
+ wire Stick_one_D;
+ assign Stick_one_D = Stick_one_HD;
+ reg Mant_sticky_D;
+ always @(*)
+ if (((((NaN_a_SI | NaN_b_SI) | NaN_c_SI) | (Zero_b_SI && Inf_c_SI)) | (Zero_c_SI && Inf_b_SI)) | ((Sub_SI && Inf_a_SI) && (Inf_b_SI | Inf_c_SI))) begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {1'b0, C_MANT_NAN};
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = 1'b0;
+ Mant_sticky_D = 1'b0;
+ end
+ else if ((Inf_a_SI | Inf_b_SI) | Inf_c_SI) begin
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = 1'b0;
+ end
+ else if (Sign_amt_DI) begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = DeN_a_SI;
+ Mant_res_norm_D = Mant_a_DI;
+ Exp_res_norm_D = Exp_a_DI;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_a_DI;
+ Mant_sticky_D = 1'b0;
+ end
+ else if (No_one_SI) begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = 1'b0;
+ end
+ else if (Exp_in_DI[C_EXP + 1]) begin
+ if (~Exp_Max_RS_D[C_EXP + 1]) begin
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = 1'b0;
+ end
+ else begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b1;
+ Mant_res_norm_D = {1'b0, Mant_RS_D[(3 * C_MANT) + 6:(2 * C_MANT) + 6]};
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = Mant_RS_D[(2 * C_MANT) + 5:(2 * C_MANT) + 4];
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = Stick_one_D;
+ end
+ end
+ else if (((Exp_postsft_D[C_EXP:0] == 256) && ~Mant_postsft_D[(3 * C_MANT) + 4]) && (Mant_postsft_D[(3 * C_MANT) + 3:(2 * C_MANT) + 3] != {(((3 * C_MANT) + 3) >= ((2 * C_MANT) + 3) ? (((3 * C_MANT) + 3) - ((2 * C_MANT) + 3)) + 1 : (((2 * C_MANT) + 3) - ((3 * C_MANT) + 3)) + 1) {1'sb0}})) begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {1'b0, C_MANT_NAN};
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = 1'b0;
+ Mant_sticky_D = 1'b0;
+ end
+ else if (Exp_postsft_D[C_EXP - 1:0] == {C_EXP {1'sb1}}) begin
+ if (Mant_postsft_D[(3 * C_MANT) + 4]) begin
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {1'b0, C_MANT_NAN};
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = 1'b0;
+ end
+ else if (Mant_postsft_D[(3 * C_MANT) + 4:(2 * C_MANT) + 4] == {(((3 * C_MANT) + 4) >= ((2 * C_MANT) + 4) ? (((3 * C_MANT) + 4) - ((2 * C_MANT) + 4)) + 1 : (((2 * C_MANT) + 4) - ((3 * C_MANT) + 4)) + 1) {1'sb0}}) begin
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = 1'b0;
+ end
+ else begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = Mant_postsft_D[(3 * C_MANT) + 3:(2 * C_MANT) + 3];
+ Exp_res_norm_D = 254;
+ Mant_lower_D = Mant_postsft_D[(2 * C_MANT) + 2:(2 * C_MANT) + 1];
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = Stick_one_D;
+ end
+ end
+ else if (Exp_postsft_D[C_EXP]) begin
+ Exp_OF_SO = 1'b1;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = 1'sb0;
+ Exp_res_norm_D = 1'sb1;
+ Mant_lower_D = 2'b00;
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = 1'b0;
+ end
+ else if (Exp_postsft_D[C_EXP + 1:0] == {((C_EXP + 1) >= 0 ? C_EXP + 2 : 1 - (C_EXP + 1)) {1'sb0}}) begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b1;
+ Mant_res_norm_D = {1'b0, Mant_postsft_D[(3 * C_MANT) + 4:(2 * C_MANT) + 5]};
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = Mant_postsft_D[(2 * C_MANT) + 4:(2 * C_MANT) + 3];
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = Stick_one_D;
+ end
+ else if (Exp_postsft_D[C_EXP + 1:0] == 1) begin
+ if (Mant_postsft_D[(3 * C_MANT) + 4]) begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = {Mant_postsft_D[(3 * C_MANT) + 4:(2 * C_MANT) + 4]};
+ Exp_res_norm_D = 1;
+ Mant_lower_D = Mant_postsft_D[(2 * C_MANT) + 3:(2 * C_MANT) + 2];
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = Stick_one_D;
+ end
+ else begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b1;
+ Mant_res_norm_D = {Mant_postsft_D[(3 * C_MANT) + 4:(2 * C_MANT) + 4]};
+ Exp_res_norm_D = 1'sb0;
+ Mant_lower_D = Mant_postsft_D[(2 * C_MANT) + 3:(2 * C_MANT) + 2];
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = Stick_one_D;
+ end
+ end
+ else if (~Mant_postsft_D[(3 * C_MANT) + 4]) begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = Mant_postsft_D[(3 * C_MANT) + 3:(2 * C_MANT) + 3];
+ Exp_res_norm_D = Exp_postsft_addone_D[C_EXP - 1:0];
+ Mant_lower_D = Mant_postsft_D[(2 * C_MANT) + 2:(2 * C_MANT) + 1];
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = Stick_one_D;
+ end
+ else begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ Mant_res_norm_D = Mant_postsft_D[(3 * C_MANT) + 4:(2 * C_MANT) + 4];
+ Exp_res_norm_D = Exp_postsft_D[C_EXP - 1:0];
+ Mant_lower_D = Mant_postsft_D[(2 * C_MANT) + 3:(2 * C_MANT) + 2];
+ Sign_res_DO = Sign_in_DI;
+ Mant_sticky_D = Stick_one_D;
+ end
+ wire [C_MANT:0] Mant_upper_D;
+ wire [C_MANT + 1:0] Mant_upperRounded_D;
+ reg Mant_roundUp_S;
+ wire Mant_rounded_S;
+ assign Mant_upper_D = Mant_res_norm_D;
+ assign Flag_Inexact_SO = Mant_rounded_S;
+ assign Mant_rounded_S = |Mant_lower_D | Mant_sticky_D;
+ always @(*) begin
+ Mant_roundUp_S = 1'b0;
+ case (RM_SI)
+ C_RM_NEAREST: Mant_roundUp_S = Mant_lower_D[1] && ((Mant_lower_D[0] | Mant_sticky_D) || Mant_upper_D[0]);
+ C_RM_TRUNC: Mant_roundUp_S = 0;
+ C_RM_PLUSINF: Mant_roundUp_S = Mant_rounded_S & ~Sign_in_DI;
+ C_RM_MINUSINF: Mant_roundUp_S = Mant_rounded_S & Sign_in_DI;
+ default: Mant_roundUp_S = 0;
+ endcase
+ end
+ wire Mant_renorm_S;
+ assign Mant_upperRounded_D = Mant_upper_D + Mant_roundUp_S;
+ assign Mant_renorm_S = Mant_upperRounded_D[C_MANT + 1];
+ wire Rounded_SO;
+ assign Mant_res_DO = (Mant_renorm_S ? Mant_upperRounded_D[C_MANT:1] : Mant_upperRounded_D[C_MANT - 1:0]);
+ assign Exp_res_DO = Exp_res_norm_D + Mant_renorm_S;
+ assign Rounded_SO = Mant_rounded_S;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/pp_generation.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/pp_generation.v
new file mode 100644
index 0000000..10f6be5
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/pp_generation.v
@@ -0,0 +1,106 @@
+module pp_generation (
+ Mant_a_DI,
+ Mant_b_DI,
+ Pp_index_DO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+parameter C_FFLAG = 5;
+ input wire [C_MANT:0] Mant_a_DI;
+ input wire [C_MANT:0] Mant_b_DI;
+ output wire [(((2 * C_MANT) + 2) >= 0 ? (13 * ((2 * C_MANT) + 3)) - 1 : (13 * (1 - ((2 * C_MANT) + 2))) + ((2 * C_MANT) + 1)):(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2)] Pp_index_DO;
+ wire Sel_xnor_S;
+ wire [C_MANT + 5:0] Mant_b_D;
+ assign Mant_b_D = {2'b00, Mant_b_DI, 2'b00};
+ wire [12:0] Sel_1x_S;
+ wire [12:0] Sel_2x_S;
+ wire [12:0] Sel_sign_S;
+ genvar i;
+ generate
+ for (i = 1; i <= 13; i = i + 1) begin : genblk1
+ booth_encoder booth_encoding(
+ .Booth_b_DI(Mant_b_D[(2 * i) + 1:(2 * i) - 1]),
+ .Sel_1x_SO(Sel_1x_S[i - 1]),
+ .Sel_2x_SO(Sel_2x_S[i - 1]),
+ .Sel_sign_SO(Sel_sign_S[i - 1])
+ );
+ end
+ endgenerate
+ wire [C_MANT + 2:0] Mant_a_D;
+ assign Mant_a_D = {Mant_a_DI, 1'b0};
+ wire [((C_MANT + 1) >= 0 ? (13 * (C_MANT + 2)) - 1 : (13 * (1 - (C_MANT + 1))) + C_MANT):((C_MANT + 1) >= 0 ? 0 : C_MANT + 1)] Booth_pp_D;
+ genvar l;
+ genvar j;
+ generate
+ for (l = 1; l <= 13; l = l + 1) begin : genblk2
+ for (j = 1; j <= (C_MANT + 2); j = j + 1) begin : genblk1
+ booth_selector booth_selection(
+ .Booth_a_DI(Mant_a_D[j:j - 1]),
+ .Sel_1x_SI(Sel_1x_S[l - 1]),
+ .Sel_2x_SI(Sel_2x_S[l - 1]),
+ .Sel_sign_SI(Sel_sign_S[l - 1]),
+ .Booth_pp_DO(Booth_pp_D[((l - 1) * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))) + ((C_MANT + 1) >= 0 ? j - 1 : (C_MANT + 1) - (j - 1))])
+ );
+ end
+ end
+ endgenerate
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2)+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {21'h000000, ~Sel_sign_S[0], Sel_sign_S[0], Sel_sign_S[0], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1)+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))]};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {21'b000000000000000000001, ~Sel_sign_S[1], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[0]};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (2 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {19'b0000000000000000001, ~Sel_sign_S[2], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (2 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[1], 2'h0};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (3 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {17'b00000000000000001, ~Sel_sign_S[3], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (3 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[2], 4'h0};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (4 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {15'b000000000000001, ~Sel_sign_S[4], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (4 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[3], 6'h00};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (5 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {13'b0000000000001, ~Sel_sign_S[5], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (5 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[4], 8'h00};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (6 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {11'b00000000001, ~Sel_sign_S[6], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (6 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[5], 10'h000};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (7 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {9'b000000001, ~Sel_sign_S[7], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (7 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[6], 12'h000};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (8 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {7'b0000001, ~Sel_sign_S[8], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (8 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[7], 14'h0000};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (9 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {5'b00001, ~Sel_sign_S[9], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (9 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[8], 16'h0000};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (10 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {3'b001, ~Sel_sign_S[10], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (10 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[9], 18'h00000};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (11 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {1'b1, ~Sel_sign_S[11], Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (11 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[10], 20'h00000};
+ assign Pp_index_DO[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (12 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))] = {Booth_pp_D[((C_MANT + 1) >= 0 ? 0 : C_MANT + 1) + (12 * ((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1)))+:((C_MANT + 1) >= 0 ? C_MANT + 2 : 1 - (C_MANT + 1))], 1'b0, Sel_sign_S[11], 22'h000000};
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/preprocess_fmac.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/preprocess_fmac.v
new file mode 100644
index 0000000..17b20b3
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/preprocess_fmac.v
@@ -0,0 +1,163 @@
+module preprocess_fmac (
+ Operand_a_DI,
+ Operand_b_DI,
+ Operand_c_DI,
+ Exp_a_DO,
+ Mant_a_DO,
+ Sign_a_DO,
+ Exp_b_DO,
+ Mant_b_DO,
+ Sign_b_DO,
+ Exp_c_DO,
+ Mant_c_DO,
+ Sign_c_DO,
+ Inf_a_SO,
+ Inf_b_SO,
+ Inf_c_SO,
+ Zero_a_SO,
+ Zero_b_SO,
+ Zero_c_SO,
+ NaN_a_SO,
+ NaN_b_SO,
+ NaN_c_SO,
+ DeN_a_SO,
+ DeN_b_SO,
+ DeN_c_SO
+);
+parameter C_DIV_RM = 2;
+parameter C_DIV_RM_NEAREST = 2'h0;
+parameter C_DIV_RM_TRUNC = 2'h1;
+parameter C_DIV_RM_PLUSINF = 2'h2;
+parameter C_DIV_RM_MINUSINF = 2'h3;
+parameter C_DIV_PC = 5;
+parameter C_DIV_OP = 32;
+parameter C_DIV_MANT = 23;
+parameter C_DIV_EXP = 8;
+parameter C_DIV_BIAS = 127;
+parameter C_DIV_BIAS_AONE = 8'h80;
+parameter C_DIV_HALF_BIAS = 63;
+parameter C_DIV_MANT_PRENORM = C_DIV_MANT+1;
+parameter C_DIV_EXP_ZERO = 8'h00;
+parameter C_DIV_EXP_ONE = 8'h01;
+parameter C_DIV_EXP_INF = 8'hff;
+parameter C_DIV_MANT_ZERO = 23'h0;
+parameter C_DIV_MANT_NAN = 23'h400000;
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+parameter C_FFLAG = 5;
+ input wire [C_OP - 1:0] Operand_a_DI;
+ input wire [C_OP - 1:0] Operand_b_DI;
+ input wire [C_OP - 1:0] Operand_c_DI;
+ output wire [C_EXP - 1:0] Exp_a_DO;
+ output wire [C_MANT:0] Mant_a_DO;
+ output wire Sign_a_DO;
+ output wire [C_EXP - 1:0] Exp_b_DO;
+ output wire [C_MANT:0] Mant_b_DO;
+ output wire Sign_b_DO;
+ output wire [C_EXP - 1:0] Exp_c_DO;
+ output wire [C_MANT:0] Mant_c_DO;
+ output wire Sign_c_DO;
+ output wire Inf_a_SO;
+ output wire Inf_b_SO;
+ output wire Inf_c_SO;
+ output wire Zero_a_SO;
+ output wire Zero_b_SO;
+ output wire Zero_c_SO;
+ output wire NaN_a_SO;
+ output wire NaN_b_SO;
+ output wire NaN_c_SO;
+ output wire DeN_a_SO;
+ output wire DeN_b_SO;
+ output wire DeN_c_SO;
+ wire Hb_a_D;
+ wire Hb_b_D;
+ wire Hb_c_D;
+ assign Sign_a_DO = Operand_a_DI[C_OP - 1];
+ assign Sign_b_DO = Operand_b_DI[C_OP - 1];
+ assign Sign_c_DO = Operand_c_DI[C_OP - 1];
+ assign Exp_a_DO = (DeN_a_SO ? C_EXP_ONE : Operand_a_DI[C_OP - 2:C_MANT]);
+ assign Exp_b_DO = (DeN_b_SO ? C_EXP_ONE : Operand_b_DI[C_OP - 2:C_MANT]);
+ assign Exp_c_DO = (DeN_c_SO ? C_EXP_ONE : Operand_c_DI[C_OP - 2:C_MANT]);
+ assign Mant_a_DO = {Hb_a_D, Operand_a_DI[C_MANT - 1:0]};
+ assign Mant_b_DO = {Hb_b_D, Operand_b_DI[C_MANT - 1:0]};
+ assign Mant_c_DO = {Hb_c_D, Operand_c_DI[C_MANT - 1:0]};
+ assign Hb_a_D = |Operand_a_DI[C_OP - 2:C_MANT];
+ assign Hb_b_D = |Operand_b_DI[C_OP - 2:C_MANT];
+ assign Hb_c_D = |Operand_c_DI[C_OP - 2:C_MANT];
+ wire Mant_a_zero_S;
+ wire Mant_b_zero_S;
+ wire Mant_c_zero_S;
+ assign Mant_a_zero_S = Operand_a_DI[C_MANT - 1:0] == C_MANT_ZERO;
+ assign Mant_b_zero_S = Operand_b_DI[C_MANT - 1:0] == C_MANT_ZERO;
+ assign Mant_c_zero_S = Operand_c_DI[C_MANT - 1:0] == C_MANT_ZERO;
+ wire Exp_a_zero_S;
+ wire Exp_b_zero_S;
+ wire Exp_c_zero_S;
+ assign Exp_a_zero_S = ~Hb_a_D;
+ assign Exp_b_zero_S = ~Hb_b_D;
+ assign Exp_c_zero_S = ~Hb_c_D;
+ wire Exp_a_Inf_NaN_S;
+ wire Exp_b_Inf_NaN_S;
+ wire Exp_c_Inf_NaN_S;
+ assign Exp_a_Inf_NaN_S = Exp_a_DO == C_EXP_INF;
+ assign Exp_b_Inf_NaN_S = Exp_b_DO == C_EXP_INF;
+ assign Exp_c_Inf_NaN_S = Exp_c_DO == C_EXP_INF;
+ assign Zero_a_SO = Exp_a_zero_S && Mant_a_zero_S;
+ assign Zero_b_SO = Exp_b_zero_S && Mant_b_zero_S;
+ assign Zero_c_SO = Exp_c_zero_S && Mant_c_zero_S;
+ assign Inf_a_SO = Exp_a_Inf_NaN_S && Mant_a_zero_S;
+ assign Inf_b_SO = Exp_b_Inf_NaN_S && Mant_b_zero_S;
+ assign Inf_c_SO = Exp_c_Inf_NaN_S && Mant_c_zero_S;
+ assign NaN_a_SO = Exp_a_Inf_NaN_S && ~Mant_a_zero_S;
+ assign NaN_b_SO = Exp_b_Inf_NaN_S && ~Mant_b_zero_S;
+ assign NaN_c_SO = Exp_c_Inf_NaN_S && ~Mant_c_zero_S;
+ assign DeN_a_SO = Exp_a_zero_S && ~Mant_a_zero_S;
+ assign DeN_b_SO = Exp_b_zero_S && ~Mant_b_zero_S;
+ assign DeN_c_SO = Exp_c_zero_S && ~Mant_c_zero_S;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_fmac/wallace.v b/verilog/rtl/ips/fpu/hdl/fpu_fmac/wallace.v
new file mode 100644
index 0000000..f3645a5
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_fmac/wallace.v
@@ -0,0 +1,127 @@
+module wallace (
+ Pp_index_DI,
+ Pp_sum_DO,
+ Pp_carry_DO,
+ MSB_cor_DO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+ input wire [(((2 * C_MANT) + 2) >= 0 ? (13 * ((2 * C_MANT) + 3)) - 1 : (13 * (1 - ((2 * C_MANT) + 2))) + ((2 * C_MANT) + 1)):(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2)] Pp_index_DI;
+ output wire [(2 * C_MANT) + 2:0] Pp_sum_DO;
+ output wire [(2 * C_MANT) + 2:0] Pp_carry_DO;
+ output wire MSB_cor_DO;
+ wire [(2 * C_MANT) + 2:0] CSA_u0_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u0_Carry_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u1_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u1_Carry_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u2_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u2_Carry_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u3_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u3_Carry_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u4_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u4_Carry_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u5_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u5_Carry_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u6_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u6_Carry_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u7_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u7_Carry_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u8_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u8_Carry_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u9_Sum_DI;
+ wire [(2 * C_MANT) + 2:0] CSA_u9_Carry_DI;
+ CSA #((2 * C_MANT) + 3) CSA_U0(
+ .A_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2)+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .B_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .C_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (2 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .Sum_DO(CSA_u0_Sum_DI),
+ .Carry_DO(CSA_u0_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U1(
+ .A_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (3 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .B_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (4 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .C_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (5 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .Sum_DO(CSA_u1_Sum_DI),
+ .Carry_DO(CSA_u1_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U2(
+ .A_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (6 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .B_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (7 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .C_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (8 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .Sum_DO(CSA_u2_Sum_DI),
+ .Carry_DO(CSA_u2_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U3(
+ .A_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (9 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .B_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (10 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .C_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (11 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .Sum_DO(CSA_u3_Sum_DI),
+ .Carry_DO(CSA_u3_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U4(
+ .A_DI(CSA_u0_Sum_DI),
+ .B_DI({CSA_u0_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .C_DI(CSA_u1_Sum_DI),
+ .Sum_DO(CSA_u4_Sum_DI),
+ .Carry_DO(CSA_u4_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U5(
+ .A_DI({CSA_u1_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .B_DI({CSA_u2_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .C_DI(CSA_u2_Sum_DI),
+ .Sum_DO(CSA_u5_Sum_DI),
+ .Carry_DO(CSA_u5_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U6(
+ .A_DI(CSA_u3_Sum_DI),
+ .B_DI({CSA_u3_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .C_DI(CSA_u4_Sum_DI),
+ .Sum_DO(CSA_u6_Sum_DI),
+ .Carry_DO(CSA_u6_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U7(
+ .A_DI({CSA_u4_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .B_DI({CSA_u5_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .C_DI(CSA_u5_Sum_DI),
+ .Sum_DO(CSA_u7_Sum_DI),
+ .Carry_DO(CSA_u7_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U8(
+ .A_DI(CSA_u6_Sum_DI),
+ .B_DI({CSA_u6_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .C_DI(CSA_u7_Sum_DI),
+ .Sum_DO(CSA_u8_Sum_DI),
+ .Carry_DO(CSA_u8_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U9(
+ .A_DI({CSA_u7_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .B_DI({CSA_u8_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .C_DI(CSA_u8_Sum_DI),
+ .Sum_DO(CSA_u9_Sum_DI),
+ .Carry_DO(CSA_u9_Carry_DI)
+ );
+ CSA #((2 * C_MANT) + 3) CSA_U10(
+ .A_DI(CSA_u9_Sum_DI),
+ .B_DI({CSA_u9_Carry_DI[(2 * C_MANT) + 1:0], 1'b0}),
+ .C_DI(Pp_index_DI[(((2 * C_MANT) + 2) >= 0 ? 0 : (2 * C_MANT) + 2) + (12 * (((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2)))+:(((2 * C_MANT) + 2) >= 0 ? (2 * C_MANT) + 3 : 1 - ((2 * C_MANT) + 2))]),
+ .Sum_DO(Pp_sum_DO),
+ .Carry_DO(Pp_carry_DO)
+ );
+ assign MSB_cor_DO = (((((CSA_u9_Carry_DI[(2 * C_MANT) + 2] | CSA_u8_Carry_DI[(2 * C_MANT) + 2]) | CSA_u7_Carry_DI[(2 * C_MANT) + 2]) | CSA_u6_Carry_DI[(2 * C_MANT) + 2]) | CSA_u5_Carry_DI[(2 * C_MANT) + 2]) | CSA_u4_Carry_DI[(2 * C_MANT) + 2]) | CSA_u3_Carry_DI[(2 * C_MANT) + 2];
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_utils/fpu_ff.v b/verilog/rtl/ips/fpu/hdl/fpu_utils/fpu_ff.v
new file mode 100644
index 0000000..4ed778c
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_utils/fpu_ff.v
@@ -0,0 +1,57 @@
+module fpu_ff
+#(
+ parameter LEN = 32
+)
+(
+ in_i,
+ first_one_o,
+ no_ones_o
+);
+ //parameter LEN = 32;
+ input wire [LEN - 1:0] in_i;
+ output wire [$clog2(LEN) - 1:0] first_one_o;
+ output wire no_ones_o;
+ localparam NUM_LEVELS = $clog2(LEN);
+ wire [(LEN * NUM_LEVELS) - 1:0] index_lut;
+ wire [(2 ** NUM_LEVELS) - 1:0] sel_nodes;
+ wire [((2 ** NUM_LEVELS) * NUM_LEVELS) - 1:0] index_nodes;
+ wire [LEN - 1:0] in_flipped;
+ genvar j;
+ generate
+ for (j = 0; j < LEN; j = j + 1) begin : genblk1
+ assign index_lut[j * NUM_LEVELS+:NUM_LEVELS] = $unsigned(j);
+ assign in_flipped[j] = in_i[(LEN - j) - 1];
+ end
+ endgenerate
+ genvar k;
+ genvar l;
+ genvar level;
+ generate
+ for (level = 0; level < NUM_LEVELS; level = level + 1) begin : genblk2
+ if (level < (NUM_LEVELS - 1)) begin : genblk1
+ for (l = 0; l < (2 ** level); l = l + 1) begin : genblk1
+ assign sel_nodes[((2 ** level) - 1) + l] = sel_nodes[((2 ** (level + 1)) - 1) + (l * 2)] | sel_nodes[(((2 ** (level + 1)) - 1) + (l * 2)) + 1];
+ assign index_nodes[(((2 ** level) - 1) + l) * NUM_LEVELS+:NUM_LEVELS] = (sel_nodes[((2 ** (level + 1)) - 1) + (l * 2)] == 1'b1 ? index_nodes[(((2 ** (level + 1)) - 1) + (l * 2)) * NUM_LEVELS+:NUM_LEVELS] : index_nodes[((((2 ** (level + 1)) - 1) + (l * 2)) + 1) * NUM_LEVELS+:NUM_LEVELS]);
+ end
+ end
+ if (level == (NUM_LEVELS - 1)) begin : genblk2
+ for (k = 0; k < (2 ** level); k = k + 1) begin : genblk1
+ if ((k * 2) < (LEN - 1)) begin : genblk1
+ assign sel_nodes[((2 ** level) - 1) + k] = in_flipped[k * 2] | in_flipped[(k * 2) + 1];
+ assign index_nodes[(((2 ** level) - 1) + k) * NUM_LEVELS+:NUM_LEVELS] = (in_flipped[k * 2] == 1'b1 ? index_lut[(k * 2) * NUM_LEVELS+:NUM_LEVELS] : index_lut[((k * 2) + 1) * NUM_LEVELS+:NUM_LEVELS]);
+ end
+ if ((k * 2) == (LEN - 1)) begin : genblk2
+ assign sel_nodes[((2 ** level) - 1) + k] = in_flipped[k * 2];
+ assign index_nodes[(((2 ** level) - 1) + k) * NUM_LEVELS+:NUM_LEVELS] = index_lut[(k * 2) * NUM_LEVELS+:NUM_LEVELS];
+ end
+ if ((k * 2) > (LEN - 1)) begin : genblk3
+ assign sel_nodes[((2 ** level) - 1) + k] = 1'b0;
+ assign index_nodes[(((2 ** level) - 1) + k) * NUM_LEVELS+:NUM_LEVELS] = 1'sb0;
+ end
+ end
+ end
+ end
+ endgenerate
+ assign first_one_o = index_nodes[0+:NUM_LEVELS];
+ assign no_ones_o = ~sel_nodes[0];
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/defines_fpu.sv b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/defines_fpu.sv
new file mode 100644
index 0000000..0b0f9e4
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/defines_fpu.sv
@@ -0,0 +1,43 @@
+// Copyright 2017 ETH Zurich and University of Bologna.
+// Copyright and related rights are licensed under the Solderpad Hardware
+// License, Version 0.51 (the “License”); you may not use this file except in
+// compliance with the License. You may obtain a copy of the License at
+// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
+// or agreed to in writing, software, hardware and materials distributed under
+// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+////////////////////////////////////////////////////////////////////////////////
+// Company: IIS @ ETHZ - Federal Institute of Technology //
+// //
+// Engineers: Lukas Mueller -- lukasmue@student.ethz.ch //
+// //
+// Additional contributions by: //
+// //
+// //
+// //
+// Create Date: 08/10/2014 //
+// Design Name: FPU //
+// Module Name: defines.sv //
+// Project Name: Private FPU //
+// Language: SystemVerilog //
+// //
+// Description: Defines for the FPU //
+// //
+// //
+// //
+// Revision: //
+////////////////////////////////////////////////////////////////////////////////
+
+`define RM_NEAREST 2'h0
+`define RM_TRUNC 2'h1
+`define RM_PLUSINF 2'h2
+`define RM_MINUSINF 2'h3
+
+`define FP_OP_ADD 4'h0
+`define FP_OP_SUB 4'h1
+`define FP_OP_MUL 4'h2
+`define FP_OP_DIV 4'h3
+`define FP_OP_ITOF 4'h4
+`define FP_OP_FTOI 4'h5
+
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fp_fma_wrapper.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fp_fma_wrapper.v
new file mode 100644
index 0000000..22d38c3
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fp_fma_wrapper.v
@@ -0,0 +1,126 @@
+module fp_fma_wrapper
+#(
+ parameter C_MAC_PIPE_REGS = 2,
+ parameter RND_WIDTH = 2,
+ parameter STAT_WIDTH = 5
+)
+(
+ clk_i,
+ rst_ni,
+ En_i,
+ OpA_i,
+ OpB_i,
+ OpC_i,
+ Op_i,
+ Rnd_i,
+ Status_o,
+ Res_o,
+ Valid_o,
+ Ready_o,
+ Ack_i
+);
+ //parameter C_MAC_PIPE_REGS = 2;
+ //parameter RND_WIDTH = 2;
+ //parameter STAT_WIDTH = 5;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire En_i;
+ input wire [31:0] OpA_i;
+ input wire [31:0] OpB_i;
+ input wire [31:0] OpC_i;
+ input wire [1:0] Op_i;
+ input wire [RND_WIDTH - 1:0] Rnd_i;
+ output wire [STAT_WIDTH - 1:0] Status_o;
+ output wire [31:0] Res_o;
+ output wire Valid_o;
+ output wire Ready_o;
+ input wire Ack_i;
+ parameter C_PRE_PIPE_REGS = C_MAC_PIPE_REGS - 1;
+ parameter C_POST_PIPE_REGS = 1;
+ reg [31:0] OpA_DP [0:C_PRE_PIPE_REGS];
+ reg [31:0] OpB_DP [0:C_PRE_PIPE_REGS];
+ reg [31:0] OpC_DP [0:C_PRE_PIPE_REGS];
+ reg En_SP [0:C_PRE_PIPE_REGS];
+ reg [RND_WIDTH - 1:0] Rnd_DP [0:C_PRE_PIPE_REGS];
+ reg EnPost_SP [0:C_POST_PIPE_REGS];
+ reg [31:0] Res_DP [0:C_POST_PIPE_REGS];
+ reg [STAT_WIDTH - 1:0] Status_DP [0:C_POST_PIPE_REGS];
+ wire [7:0] status;
+ wire [32:1] sv2v_tmp_29B01;
+ assign sv2v_tmp_29B01 = (En_i ? OpA_i : {32 {1'sb0}});
+ always @(*) OpA_DP[0] = sv2v_tmp_29B01;
+ wire [32:1] sv2v_tmp_0E9BB;
+ assign sv2v_tmp_0E9BB = (En_i ? {OpB_i[31] ^ Op_i[1], OpB_i[30:0]} : {32 {1'sb0}});
+ always @(*) OpB_DP[0] = sv2v_tmp_0E9BB;
+ wire [32:1] sv2v_tmp_8E8DA;
+ assign sv2v_tmp_8E8DA = (En_i ? {OpC_i[31] ^ Op_i[0], OpC_i[30:0]} : {32 {1'sb0}});
+ always @(*) OpC_DP[0] = sv2v_tmp_8E8DA;
+ wire [1:1] sv2v_tmp_1D7A2;
+ assign sv2v_tmp_1D7A2 = En_i;
+ always @(*) En_SP[0] = sv2v_tmp_1D7A2;
+ wire [RND_WIDTH:1] sv2v_tmp_A3B99;
+ assign sv2v_tmp_A3B99 = Rnd_i;
+ always @(*) Rnd_DP[0] = sv2v_tmp_A3B99;
+ wire [1:1] sv2v_tmp_45B84;
+ assign sv2v_tmp_45B84 = En_SP[C_PRE_PIPE_REGS];
+ always @(*) EnPost_SP[0] = sv2v_tmp_45B84;
+ assign Res_o = Res_DP[C_POST_PIPE_REGS];
+ assign Valid_o = EnPost_SP[C_POST_PIPE_REGS];
+ assign Status_o = Status_DP[C_POST_PIPE_REGS];
+ assign Ready_o = 1'b1;
+ wire [STAT_WIDTH:1] sv2v_tmp_04800;
+ assign sv2v_tmp_04800 = {2'b00, status[4], status[3], 1'b0};
+ always @(*) Status_DP[0] = sv2v_tmp_04800;
+ fmac fp_fma_i(
+ .Operand_a_DI(OpC_DP[C_PRE_PIPE_REGS]),
+ .Operand_b_DI(OpB_DP[C_PRE_PIPE_REGS]),
+ .Operand_c_DI(OpA_DP[C_PRE_PIPE_REGS]),
+ .RM_SI(Rnd_DP[C_PRE_PIPE_REGS]),
+ .Result_DO(Res_DP[0]),
+ .Exp_OF_SO(status[4]),
+ .Exp_UF_SO(status[3]),
+ .Exp_NX_SO(status[5])
+ );
+ genvar i;
+ generate
+ for (i = 1; i <= C_PRE_PIPE_REGS; i = i + 1) begin : g_pre_regs
+ always @(posedge clk_i or negedge rst_ni) begin : p_pre_regs
+ if (~rst_ni) begin
+ En_SP[i] <= 1'sb0;
+ OpA_DP[i] <= 1'sb0;
+ OpB_DP[i] <= 1'sb0;
+ OpC_DP[i] <= 1'sb0;
+ Rnd_DP[i] <= 1'sb0;
+ end
+ else begin
+ En_SP[i] <= En_SP[i - 1];
+ if (En_SP[i - 1]) begin
+ OpA_DP[i] <= OpA_DP[i - 1];
+ OpB_DP[i] <= OpB_DP[i - 1];
+ OpC_DP[i] <= OpC_DP[i - 1];
+ Rnd_DP[i] <= Rnd_DP[i - 1];
+ end
+ end
+ end
+ end
+ endgenerate
+ genvar j;
+ generate
+ for (j = 1; j <= C_POST_PIPE_REGS; j = j + 1) begin : g_post_regs
+ always @(posedge clk_i or negedge rst_ni) begin : p_post_regs
+ if (~rst_ni) begin
+ EnPost_SP[j] <= 1'sb0;
+ Res_DP[j] <= 1'sb0;
+ Status_DP[j] <= 1'sb0;
+ end
+ else begin
+ EnPost_SP[j] <= EnPost_SP[j - 1];
+ if (EnPost_SP[j - 1]) begin
+ Res_DP[j] <= Res_DP[j - 1];
+ Status_DP[j] <= Status_DP[j - 1];
+ end
+ end
+ end
+ end
+ endgenerate
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpexc.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpexc.v
new file mode 100644
index 0000000..a35d275
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpexc.v
@@ -0,0 +1,158 @@
+//`include "fpu_defs.sv"
+//`include "fpu_defs_fmac.sv"
+
+
+
+module fpexc (
+ Mant_a_DI,
+ Mant_b_DI,
+ Exp_a_DI,
+ Exp_b_DI,
+ Sign_a_DI,
+ Sign_b_DI,
+ Mant_norm_DI,
+ Exp_res_DI,
+ Op_SI,
+ Mant_rounded_SI,
+ Exp_OF_SI,
+ Exp_UF_SI,
+ OF_SI,
+ UF_SI,
+ Zero_SI,
+ IX_SI,
+ IV_SI,
+ Inf_SI,
+ Exp_toZero_SO,
+ Exp_toInf_SO,
+ Mant_toZero_SO,
+ OF_SO,
+ UF_SO,
+ Zero_SO,
+ IX_SO,
+ IV_SO,
+ Inf_SO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+
+
+ input wire [C_MANT:0] Mant_a_DI;
+ input wire [C_MANT:0] Mant_b_DI;
+ input wire [C_EXP - 1:0] Exp_a_DI;
+ input wire [C_EXP - 1:0] Exp_b_DI;
+ input wire Sign_a_DI;
+ input wire Sign_b_DI;
+ input wire [C_MANT:0] Mant_norm_DI;
+ input wire [C_EXP - 1:0] Exp_res_DI;
+ input wire [C_CMD - 1:0] Op_SI;
+ input wire Mant_rounded_SI;
+ input wire Exp_OF_SI;
+ input wire Exp_UF_SI;
+ input wire OF_SI;
+ input wire UF_SI;
+ input wire Zero_SI;
+ input wire IX_SI;
+ input wire IV_SI;
+ input wire Inf_SI;
+ output wire Exp_toZero_SO;
+ output wire Exp_toInf_SO;
+ output wire Mant_toZero_SO;
+ output wire OF_SO;
+ output wire UF_SO;
+ output wire Zero_SO;
+ output wire IX_SO;
+ output reg IV_SO;
+ output wire Inf_SO;
+ wire Inf_a_S;
+ wire Inf_b_S;
+ wire Zero_a_S;
+ wire Zero_b_S;
+ wire NaN_a_S;
+ wire NaN_b_S;
+ wire Mant_zero_S;
+ assign Inf_a_S = (Exp_a_DI == C_EXP_INF) & (Mant_a_DI[C_MANT - 1:0] == C_MANT_NoHB_ZERO);
+ assign Inf_b_S = (Exp_b_DI == C_EXP_INF) & (Mant_b_DI[C_MANT - 1:0] == C_MANT_NoHB_ZERO);
+ assign Zero_a_S = (Exp_a_DI == C_EXP_ZERO) & (Mant_a_DI == C_MANT_ZERO);
+ assign Zero_b_S = (Exp_b_DI == C_EXP_ZERO) & (Mant_b_DI == C_MANT_ZERO);
+ assign NaN_a_S = (Exp_a_DI == C_EXP_INF) & (Mant_a_DI[C_MANT - 1:0] != C_MANT_NoHB_ZERO);
+ assign NaN_b_S = (Exp_b_DI == C_EXP_INF) & (Mant_b_DI[C_MANT - 1:0] != C_MANT_NoHB_ZERO);
+ assign Mant_zero_S = Mant_norm_DI == C_MANT_ZERO;
+ assign OF_SO = (Op_SI == C_FPU_F2I_CMD ? OF_SI : (Exp_OF_SI & ~Mant_zero_S) | ((~IV_SO & (Inf_a_S ^ Inf_b_S)) & (Op_SI != C_FPU_I2F_CMD)));
+ assign UF_SO = (Op_SI == C_FPU_F2I_CMD ? UF_SI : Exp_UF_SI & Mant_rounded_SI);
+ assign Zero_SO = (Op_SI == C_FPU_F2I_CMD ? Zero_SI : Mant_zero_S & ~IV_SO);
+ assign IX_SO = (Op_SI == C_FPU_F2I_CMD ? IX_SI : Mant_rounded_SI | OF_SO);
+ always @(*) begin
+ IV_SO = 1'b0;
+ case (Op_SI)
+ C_FPU_ADD_CMD, C_FPU_SUB_CMD:
+ if ((((Inf_a_S & Inf_b_S) & (Sign_a_DI ^ Sign_b_DI)) | NaN_a_S) | NaN_b_S)
+ IV_SO = 1'b1;
+ C_FPU_MUL_CMD:
+ if ((((Inf_a_S & Zero_b_S) | (Inf_b_S & Zero_a_S)) | NaN_a_S) | NaN_b_S)
+ IV_SO = 1'b1;
+ C_FPU_F2I_CMD: IV_SO = IV_SI;
+ endcase
+ end
+ reg Inf_temp_S;
+ always @(*) begin
+ Inf_temp_S = 1'b0;
+ case (Op_SI)
+ C_FPU_ADD_CMD, C_FPU_SUB_CMD:
+ if ((Inf_a_S ^ Inf_b_S) | ((Inf_a_S & Inf_b_S) & ~(Sign_a_DI ^ Sign_b_DI)))
+ Inf_temp_S = 1'b1;
+ C_FPU_MUL_CMD:
+ if ((Inf_a_S & ~Zero_b_S) | (Inf_b_S & ~Zero_a_S))
+ Inf_temp_S = 1'b1;
+ endcase
+ end
+ assign Inf_SO = (Op_SI == C_FPU_F2I_CMD ? Inf_SI : Inf_temp_S | (Exp_OF_SI & ~Mant_zero_S));
+ assign Exp_toZero_SO = (Op_SI == C_FPU_I2F_CMD ? Zero_a_S & ~Sign_a_DI : Exp_UF_SI | (Mant_zero_S & ~Exp_toInf_SO));
+ assign Exp_toInf_SO = OF_SO | IV_SO;
+ assign Mant_toZero_SO = Inf_SO;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu.v
new file mode 100644
index 0000000..b097343
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu.v
@@ -0,0 +1,130 @@
+module fpu (
+ Clk_CI,
+ Rst_RBI,
+ Operand_a_DI,
+ Operand_b_DI,
+ RM_SI,
+ OP_SI,
+ Enable_SI,
+ Stall_SI,
+ Result_DO,
+ OF_SO,
+ UF_SO,
+ Zero_SO,
+ IX_SO,
+ IV_SO,
+ Inf_SO
+);
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+
+parameter C_RM = 3;
+parameter C_RM_NEAREST = 3'h0;
+parameter C_RM_TRUNC = 3'h1;
+parameter C_RM_PLUSINF = 3'h3;
+parameter C_RM_MINUSINF = 3'h2;
+parameter C_RM_NEAREST_MAX = 3'h4;
+
+parameter C_PC = 5;
+
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_PRENORM = C_MANT*2+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_BIAS = 10'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 24'h0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire [C_OP - 1:0] Operand_a_DI;
+ input wire [C_OP - 1:0] Operand_b_DI;
+ input wire [C_RM - 1:0] RM_SI;
+ input wire [C_CMD - 1:0] OP_SI;
+ input wire Enable_SI;
+ input wire Stall_SI;
+ output wire [C_OP - 1:0] Result_DO;
+ output wire OF_SO;
+ output wire UF_SO;
+ output wire Zero_SO;
+ output wire IX_SO;
+ output wire IV_SO;
+ output wire Inf_SO;
+ reg [C_OP - 1:0] Operand_a_D;
+ reg [C_OP - 1:0] Operand_b_D;
+ reg [C_RM - 1:0] RM_S;
+ reg [C_CMD - 1:0] OP_S;
+ wire Stall_S;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI) begin
+ Operand_a_D <= 1'sb0;
+ Operand_b_D <= 1'sb0;
+ RM_S <= 1'sb0;
+ OP_S <= 1'sb0;
+ end
+ else if (~Stall_SI) begin
+ Operand_a_D <= Operand_a_DI;
+ Operand_b_D <= Operand_b_DI;
+ RM_S <= RM_SI;
+ OP_S <= OP_SI;
+ end
+ wire UF_S;
+ wire OF_S;
+ wire Zero_S;
+ wire IX_S;
+ wire IV_S;
+ wire Inf_S;
+ wire [C_OP - 1:0] Result_D;
+ fpu_core fpcore(
+ .Clk_CI(Clk_CI),
+ .Rst_RBI(Rst_RBI),
+ .Enable_SI(Enable_SI),
+ .Operand_a_DI(Operand_a_D),
+ .Operand_b_DI(Operand_b_D),
+ .RM_SI(RM_S),
+ .OP_SI(OP_S),
+ .Stall_SI(Stall_SI),
+ .Result_DO(Result_D),
+ .OF_SO(OF_S),
+ .UF_SO(UF_S),
+ .Zero_SO(Zero_S),
+ .IX_SO(IX_S),
+ .IV_SO(IV_S),
+ .Inf_SO(Inf_S)
+ );
+ assign Result_DO = Result_D;
+ assign OF_SO = OF_S;
+ assign UF_SO = UF_S;
+ assign Zero_SO = Zero_S;
+ assign IX_SO = IX_S;
+ assign IV_SO = IV_S;
+ assign Inf_SO = Inf_S;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_add.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_add.v
new file mode 100644
index 0000000..bb6c6c5
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_add.v
@@ -0,0 +1,158 @@
+module fpu_add (
+ Sign_a_DI,
+ Sign_b_DI,
+ Exp_a_DI,
+ Exp_b_DI,
+ Mant_a_DI,
+ Mant_b_DI,
+ Sign_prenorm_DO,
+ Exp_prenorm_DO,
+ Mant_prenorm_DO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+ input wire Sign_a_DI;
+ input wire Sign_b_DI;
+ input wire [C_EXP - 1:0] Exp_a_DI;
+ input wire [C_EXP - 1:0] Exp_b_DI;
+ input wire [C_MANT:0] Mant_a_DI;
+ input wire [C_MANT:0] Mant_b_DI;
+ output wire Sign_prenorm_DO;
+ output wire signed [C_EXP_PRENORM - 1:0] Exp_prenorm_DO;
+ output wire [C_MANT_PRENORM - 1:0] Mant_prenorm_DO;
+ wire Sign_a_D;
+ wire Sign_b_D;
+ wire [C_EXP - 1:0] Exp_a_D;
+ wire [C_EXP - 1:0] Exp_b_D;
+ wire [C_MANT:0] Mant_a_D;
+ wire [C_MANT:0] Mant_b_D;
+ reg Sign_norm_D;
+ assign Sign_a_D = Sign_a_DI;
+ assign Sign_b_D = Sign_b_DI;
+ assign Exp_a_D = Exp_a_DI;
+ assign Exp_b_D = Exp_b_DI;
+ assign Mant_a_D = Mant_a_DI;
+ assign Mant_b_D = Mant_b_DI;
+ wire Exp_agtb_S;
+ wire Exp_equal_S;
+ reg [C_EXP - 1:0] Exp_diff_D;
+ reg [C_EXP - 1:0] Exp_prenorm_D;
+ assign Exp_agtb_S = Exp_a_D > Exp_b_D;
+ assign Exp_equal_S = Exp_diff_D == 0;
+ always @(*)
+ if (Exp_agtb_S) begin
+ Exp_diff_D = Exp_a_D - Exp_b_D;
+ Exp_prenorm_D = Exp_a_D;
+ end
+ else begin
+ Exp_diff_D = Exp_b_D - Exp_a_D;
+ Exp_prenorm_D = Exp_b_D;
+ end
+ wire Mant_agtb_S;
+ wire [C_MANT_SHIFTIN - 1:0] Mant_shiftIn_D;
+ wire [C_MANT_SHIFTED - 1:0] Mant_shifted_D;
+ reg Mant_sticky_D;
+ wire [C_MANT_SHIFTED - 1:0] Mant_unshifted_D;
+ wire [C_MANT_ADDIN - 1:0] Mant_addInA_D;
+ wire [C_MANT_ADDIN - 1:0] Mant_addInB_D;
+ wire [C_MANT_ADDOUT - 1:0] Mant_addOut_D;
+ wire [C_MANT_PRENORM - 1:0] Mant_prenorm_D;
+ wire Mant_addCarryIn_D;
+ reg Mant_invA_S;
+ reg Mant_invB_S;
+ wire Subtract_S;
+ assign Mant_agtb_S = Mant_a_D > Mant_b_D;
+ assign Mant_unshifted_D = {(Exp_agtb_S ? Mant_a_D : Mant_b_D), 3'b000};
+ assign Mant_shiftIn_D = {(Exp_agtb_S ? Mant_b_D : Mant_a_D), 2'b00};
+ always @(*) begin
+ Mant_sticky_D = 1'b0;
+ if (Exp_diff_D >= (C_MANT + 3))
+ Mant_sticky_D = |Mant_shiftIn_D;
+ else
+ Mant_sticky_D = |(Mant_shiftIn_D << ((C_MANT + 3) - Exp_diff_D));
+ end
+ assign Mant_shifted_D = {Mant_shiftIn_D >> Exp_diff_D, Mant_sticky_D};
+ always @(*) begin
+ Mant_invA_S = 1'sb0;
+ Mant_invB_S = 1'sb0;
+ if (Subtract_S)
+ if (Exp_agtb_S)
+ Mant_invA_S = 1'b1;
+ else if (Exp_equal_S) begin
+ if (Mant_agtb_S)
+ Mant_invB_S = 1'b1;
+ else
+ Mant_invA_S = 1'b1;
+ end
+ else
+ Mant_invA_S = 1'b1;
+ end
+ assign Mant_addCarryIn_D = Subtract_S;
+ assign Mant_addInA_D = (Mant_invA_S ? ~Mant_shifted_D : Mant_shifted_D);
+ assign Mant_addInB_D = (Mant_invB_S ? ~Mant_unshifted_D : Mant_unshifted_D);
+ assign Mant_addOut_D = (Mant_addInA_D + Mant_addInB_D) + Mant_addCarryIn_D;
+ assign Mant_prenorm_D = {Mant_addOut_D[C_MANT_ADDOUT - 1] & ~Subtract_S, Mant_addOut_D[C_MANT_ADDOUT - 2:0], 20'b00000000000000000000};
+ assign Subtract_S = Sign_a_D ^ Sign_b_D;
+ always @(*) begin
+ Sign_norm_D = 1'b0;
+ if (Exp_agtb_S)
+ Sign_norm_D = Sign_a_D;
+ else if (Exp_equal_S) begin
+ if (Mant_agtb_S)
+ Sign_norm_D = Sign_a_D;
+ else
+ Sign_norm_D = Sign_b_D;
+ end
+ else
+ Sign_norm_D = Sign_b_D;
+ end
+ assign Sign_prenorm_DO = Sign_norm_D;
+ assign Exp_prenorm_DO = $signed({2'b00, Exp_prenorm_D});
+ assign Mant_prenorm_DO = Mant_prenorm_D;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_core.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_core.v
new file mode 100644
index 0000000..1a164c0
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_core.v
@@ -0,0 +1,283 @@
+module fpu_core (
+ Clk_CI,
+ Rst_RBI,
+ Enable_SI,
+ Operand_a_DI,
+ Operand_b_DI,
+ RM_SI,
+ OP_SI,
+ Result_DO,
+ Valid_SO,
+ OF_SO,
+ UF_SO,
+ Zero_SO,
+ IX_SO,
+ IV_SO,
+ Inf_SO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input wire Enable_SI;
+ input wire [C_OP - 1:0] Operand_a_DI;
+ input wire [C_OP - 1:0] Operand_b_DI;
+ input wire [C_RM - 1:0] RM_SI;
+ input wire [C_CMD - 1:0] OP_SI;
+ output wire [C_OP - 1:0] Result_DO;
+ output wire Valid_SO;
+ output wire OF_SO;
+ output wire UF_SO;
+ output wire Zero_SO;
+ output wire IX_SO;
+ output wire IV_SO;
+ output wire Inf_SO;
+ wire Sign_a_D;
+ wire Sign_b_D;
+ wire [C_EXP - 1:0] Exp_a_D;
+ wire [C_EXP - 1:0] Exp_b_D;
+ wire [C_MANT:0] Mant_a_D;
+ wire [C_MANT:0] Mant_b_D;
+ wire Hb_a_D;
+ wire Hb_b_D;
+ reg signed [C_EXP_PRENORM - 1:0] Exp_prenorm_D;
+ reg [C_MANT_PRENORM - 1:0] Mant_prenorm_D;
+ reg Sign_norm_D;
+ wire [C_EXP - 1:0] Exp_norm_D;
+ wire [C_MANT:0] Mant_norm_D;
+ wire [C_OP - 1:0] Result_D;
+ wire Sign_res_D;
+ reg [C_EXP - 1:0] Exp_res_D;
+ wire [C_MANT:0] Mant_res_D;
+ reg [C_RM - 1:0] RM_SP;
+ reg [C_CMD - 1:0] OP_SP;
+ reg [C_OP - 1:0] Operand_a_DP;
+ reg [C_OP - 1:0] Operand_b_DP;
+ reg Enable_SP;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI) begin
+ Operand_a_DP <= 1'sb0;
+ Operand_b_DP <= 1'sb0;
+ OP_SP <= 1'sb0;
+ RM_SP <= 1'sb0;
+ Enable_SP <= 1'sb0;
+ end
+ else begin
+ Operand_a_DP <= Operand_a_DI;
+ Operand_b_DP <= Operand_b_DI;
+ OP_SP <= OP_SI;
+ RM_SP <= RM_SI;
+ Enable_SP <= Enable_SI;
+ end
+ assign Valid_SO = Enable_SP;
+ assign Sign_a_D = Operand_a_DP[C_OP - 1];
+ assign Sign_b_D = (OP_SP == C_FPU_SUB_CMD ? ~Operand_b_DP[C_OP - 1] : Operand_b_DP[C_OP - 1]);
+ assign Exp_a_D = Operand_a_DP[C_OP - 2:C_MANT];
+ assign Exp_b_D = Operand_b_DP[C_OP - 2:C_MANT];
+ assign Mant_a_D = {Hb_a_D, Operand_a_DP[C_MANT - 1:0]};
+ assign Mant_b_D = {Hb_b_D, Operand_b_DP[C_MANT - 1:0]};
+ assign Hb_a_D = |Exp_a_D;
+ assign Hb_b_D = |Exp_b_D;
+ wire Sign_prenorm_add_D;
+ wire signed [C_EXP_PRENORM - 1:0] Exp_prenorm_add_D;
+ wire [C_MANT_PRENORM - 1:0] Mant_prenorm_add_D;
+ wire EnableAdd_S;
+ assign EnableAdd_S = Enable_SP & ((OP_SP == C_FPU_ADD_CMD) | (OP_SP == C_FPU_SUB_CMD));
+ fpu_add adder(
+ .Sign_a_DI((EnableAdd_S ? Sign_a_D : 1'b0)),
+ .Sign_b_DI((EnableAdd_S ? Sign_b_D : 1'b0)),
+ .Exp_a_DI((EnableAdd_S ? Exp_a_D : {C_EXP {1'sb0}})),
+ .Exp_b_DI((EnableAdd_S ? Exp_b_D : {C_EXP {1'sb0}})),
+ .Mant_a_DI((EnableAdd_S ? Mant_a_D : {(C_MANT >= 0 ? C_MANT + 1 : 1 - C_MANT) {1'sb0}})),
+ .Mant_b_DI((EnableAdd_S ? Mant_b_D : {(C_MANT >= 0 ? C_MANT + 1 : 1 - C_MANT) {1'sb0}})),
+ .Sign_prenorm_DO(Sign_prenorm_add_D),
+ .Exp_prenorm_DO(Exp_prenorm_add_D),
+ .Mant_prenorm_DO(Mant_prenorm_add_D)
+ );
+ wire Sign_prenorm_mult_D;
+ wire signed [C_EXP_PRENORM - 1:0] Exp_prenorm_mult_D;
+ wire [C_MANT_PRENORM - 1:0] Mant_prenorm_mult_D;
+ wire EnableMult_S;
+ assign EnableMult_S = Enable_SP & (OP_SP == C_FPU_MUL_CMD);
+ fpu_mult multiplier(
+ .Sign_a_DI((EnableMult_S ? Sign_a_D : 1'b0)),
+ .Sign_b_DI((EnableMult_S ? Sign_b_D : 1'b0)),
+ .Exp_a_DI((EnableMult_S ? Exp_a_D : {C_EXP {1'sb0}})),
+ .Exp_b_DI((EnableMult_S ? Exp_b_D : {C_EXP {1'sb0}})),
+ .Mant_a_DI((EnableMult_S ? Mant_a_D : {(C_MANT >= 0 ? C_MANT + 1 : 1 - C_MANT) {1'sb0}})),
+ .Mant_b_DI((EnableMult_S ? Mant_b_D : {(C_MANT >= 0 ? C_MANT + 1 : 1 - C_MANT) {1'sb0}})),
+ .Sign_prenorm_DO(Sign_prenorm_mult_D),
+ .Exp_prenorm_DO(Exp_prenorm_mult_D),
+ .Mant_prenorm_DO(Mant_prenorm_mult_D)
+ );
+ wire Sign_prenorm_itof_D;
+ wire signed [C_EXP_PRENORM - 1:0] Exp_prenorm_itof_D;
+ wire [C_MANT_PRENORM - 1:0] Mant_prenorm_itof_D;
+ wire EnableITOF_S;
+ assign EnableITOF_S = Enable_SP & (OP_SP == C_FPU_I2F_CMD);
+ fpu_itof int2fp(
+ .Operand_a_DI((EnableITOF_S ? Operand_a_DP : {C_OP {1'sb0}})),
+ .Sign_prenorm_DO(Sign_prenorm_itof_D),
+ .Exp_prenorm_DO(Exp_prenorm_itof_D),
+ .Mant_prenorm_DO(Mant_prenorm_itof_D)
+ );
+ wire [C_OP - 1:0] Result_ftoi_D;
+ wire UF_ftoi_S;
+ wire OF_ftoi_S;
+ wire Zero_ftoi_S;
+ wire IX_ftoi_S;
+ wire IV_ftoi_S;
+ wire Inf_ftoi_S;
+ wire EnableFTOI_S;
+ assign EnableFTOI_S = Enable_SP & (OP_SP == C_FPU_F2I_CMD);
+ fpu_ftoi fp2int(
+ .Sign_a_DI((EnableFTOI_S ? Sign_a_D : 1'b0)),
+ .Exp_a_DI((EnableFTOI_S ? Exp_a_D : {C_EXP {1'sb0}})),
+ .Mant_a_DI((EnableFTOI_S ? Mant_a_D : {(C_MANT >= 0 ? C_MANT + 1 : 1 - C_MANT) {1'sb0}})),
+ .Result_DO(Result_ftoi_D),
+ .UF_SO(UF_ftoi_S),
+ .OF_SO(OF_ftoi_S),
+ .Zero_SO(Zero_ftoi_S),
+ .IX_SO(IX_ftoi_S),
+ .IV_SO(IV_ftoi_S),
+ .Inf_SO(Inf_ftoi_S)
+ );
+ wire Mant_rounded_S;
+ wire Exp_OF_S;
+ wire Exp_UF_S;
+ always @(*) begin
+ Sign_norm_D = 1'sb0;
+ Exp_prenorm_D = 1'sb0;
+ Mant_prenorm_D = 1'sb0;
+ case (OP_SP)
+ C_FPU_ADD_CMD, C_FPU_SUB_CMD: begin
+ Sign_norm_D = Sign_prenorm_add_D;
+ Exp_prenorm_D = Exp_prenorm_add_D;
+ Mant_prenorm_D = Mant_prenorm_add_D;
+ end
+ C_FPU_MUL_CMD: begin
+ Sign_norm_D = Sign_prenorm_mult_D;
+ Exp_prenorm_D = Exp_prenorm_mult_D;
+ Mant_prenorm_D = Mant_prenorm_mult_D;
+ end
+ C_FPU_I2F_CMD: begin
+ Sign_norm_D = Sign_prenorm_itof_D;
+ Exp_prenorm_D = Exp_prenorm_itof_D;
+ Mant_prenorm_D = Mant_prenorm_itof_D;
+ end
+ endcase
+ end
+ fpu_norm normalizer(
+ .Mant_in_DI(Mant_prenorm_D),
+ .Exp_in_DI(Exp_prenorm_D),
+ .Sign_in_DI(Sign_norm_D),
+ .RM_SI(RM_SP),
+ .OP_SI(OP_SP),
+ .Mant_res_DO(Mant_norm_D),
+ .Exp_res_DO(Exp_norm_D),
+ .Rounded_SO(Mant_rounded_S),
+ .Exp_OF_SO(Exp_OF_S),
+ .Exp_UF_SO(Exp_UF_S)
+ );
+ wire UF_S;
+ wire OF_S;
+ wire Zero_S;
+ wire IX_S;
+ wire IV_S;
+ wire Inf_S;
+ wire Exp_toZero_S;
+ wire Exp_toInf_S;
+ wire Mant_toZero_S;
+ fpexc except(
+ .Mant_a_DI(Mant_a_D),
+ .Mant_b_DI(Mant_b_D),
+ .Exp_a_DI(Exp_a_D),
+ .Exp_b_DI(Exp_b_D),
+ .Sign_a_DI(Sign_a_D),
+ .Sign_b_DI(Sign_b_D),
+ .Mant_norm_DI(Mant_norm_D),
+ .Exp_res_DI(Exp_norm_D),
+ .Op_SI(OP_SP),
+ .UF_SI(UF_ftoi_S),
+ .OF_SI(OF_ftoi_S),
+ .Zero_SI(Zero_ftoi_S),
+ .IX_SI(IX_ftoi_S),
+ .IV_SI(IV_ftoi_S),
+ .Inf_SI(Inf_ftoi_S),
+ .Mant_rounded_SI(Mant_rounded_S),
+ .Exp_OF_SI(Exp_OF_S),
+ .Exp_UF_SI(Exp_UF_S),
+ .Exp_toZero_SO(Exp_toZero_S),
+ .Exp_toInf_SO(Exp_toInf_S),
+ .Mant_toZero_SO(Mant_toZero_S),
+ .UF_SO(UF_S),
+ .OF_SO(OF_S),
+ .Zero_SO(Zero_S),
+ .IX_SO(IX_S),
+ .IV_SO(IV_S),
+ .Inf_SO(Inf_S)
+ );
+ assign Sign_res_D = (Zero_S ? 1'b0 : Sign_norm_D);
+ always @(*) begin
+ Exp_res_D = Exp_norm_D;
+ if (Exp_toZero_S)
+ Exp_res_D = C_EXP_ZERO;
+ else if (Exp_toInf_S)
+ Exp_res_D = C_EXP_INF;
+ end
+ assign Mant_res_D = (Mant_toZero_S ? C_MANT_ZERO : Mant_norm_D);
+ assign Result_D = (IV_S ? F_QNAN : (OP_SP == C_FPU_F2I_CMD ? Result_ftoi_D : {Sign_res_D, Exp_res_D, Mant_res_D[C_MANT - 1:0]}));
+ assign Result_DO = Result_D;
+ assign UF_SO = UF_S;
+ assign OF_SO = OF_S;
+ assign Zero_SO = Zero_S;
+ assign IX_SO = IX_S;
+ assign IV_SO = IV_S;
+ assign Inf_SO = Inf_S;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_defs.sv b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_defs.sv
new file mode 100644
index 0000000..5e49413
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_defs.sv
@@ -0,0 +1,105 @@
+// Copyright 2017 ETH Zurich and University of Bologna.
+// Copyright and related rights are licensed under the Solderpad Hardware
+// License, Version 0.51 (the “License”); you may not use this file except in
+// compliance with the License. You may obtain a copy of the License at
+// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
+// or agreed to in writing, software, hardware and materials distributed under
+// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
+// CONDITIONS OF ANY KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations under the License.
+///////////////////////////////////////////////////////////////////////////////
+// This file contains all FPU parameters //
+// //
+// Authors : Michael Gautschi (gautschi@iis.ee.ethz.ch) //
+// Michael Schaffner (schaffner@iis.ee.ethz.ch) //
+// Lei Li (lile@iis.ee.ethz.ch) //
+// Copyright (c) 2015 Integrated Systems Laboratory, ETH Zurich //
+///////////////////////////////////////////////////////////////////////////////
+
+
+package fpu_defs;
+
+ // op command
+ parameter C_CMD = 4;
+ parameter C_FPU_ADD_CMD = 4'h0;
+ parameter C_FPU_SUB_CMD = 4'h1;
+ parameter C_FPU_MUL_CMD = 4'h2;
+ parameter C_FPU_DIV_CMD = 4'h3;
+ parameter C_FPU_I2F_CMD = 4'h4;
+ parameter C_FPU_F2I_CMD = 4'h5;
+ parameter C_FPU_SQRT_CMD = 4'h6;
+ parameter C_FPU_NOP_CMD = 4'h7;
+ parameter C_FPU_FMADD_CMD = 4'h8;
+ parameter C_FPU_FMSUB_CMD = 4'h9;
+ parameter C_FPU_FNMADD_CMD = 4'hA;
+ parameter C_FPU_FNMSUB_CMD = 4'hB;
+
+ parameter C_RM = 3;
+ parameter C_RM_NEAREST = 3'h0;
+ parameter C_RM_TRUNC = 3'h1;
+ parameter C_RM_PLUSINF = 3'h3;
+ parameter C_RM_MINUSINF = 3'h2;
+ parameter C_RM_NEAREST_MAX = 3'h4;
+
+ parameter C_PC = 5;
+
+
+// to be verified if it works in half precision mode!!!
+//`define HALFPREC
+
+`ifdef HALFPREC
+ parameter C_OP = 16;
+ parameter C_MANT = 10;
+ parameter C_EXP = 5;
+
+ parameter C_EXP_PRENORM = 7;
+ parameter C_MANT_PRENORM = 22;
+ parameter C_MANT_ADDIN = 14;
+ parameter C_MANT_ADDOUT = 15;
+ parameter C_MANT_SHIFTIN = 13;
+ parameter C_MANT_SHIFTED = 14;
+ parameter C_MANT_INT = 15;
+ parameter C_INF = 32'h7fff;
+ parameter C_MINF = 32'h8000;
+ parameter C_EXP_SHIFT = 7;
+ parameter C_SHIFT_BIAS = 6'd15;
+ parameter C_BIAS = 7'd15;
+ parameter C_UNKNOWN = 8'd157;
+ parameter C_PADMANT = 6'b0;
+ parameter C_EXP_ZERO = 5'h00;
+ parameter C_EXP_INF = 5'hff;
+ parameter C_MANT_ZERO = 11'h0;
+ parameter C_MANT_NoHB_ZERO = 10'h0;
+ parameter C_MANT_PRENORM_IND = 5;
+ parameter F_QNAN =16'h7E00;
+
+`else
+ parameter C_OP = 32;
+ parameter C_MANT = 23;
+ parameter C_EXP = 8;
+
+ parameter C_EXP_PRENORM = C_EXP+2;
+ parameter C_MANT_PRENORM = C_MANT*2+2;
+ parameter C_MANT_ADDIN = C_MANT+4;
+ parameter C_MANT_ADDOUT = C_MANT+5;
+ parameter C_MANT_SHIFTIN = C_MANT+3;
+ parameter C_MANT_SHIFTED = C_MANT+4;
+ parameter C_MANT_INT = C_OP-1;
+ parameter C_INF = 32'h7fffffff;
+ parameter C_MINF = 32'h80000000;
+ parameter C_EXP_SHIFT = C_EXP_PRENORM;
+ parameter C_SHIFT_BIAS = 9'd127;
+ parameter C_BIAS = 10'd127;
+ parameter C_UNKNOWN = 8'd157;
+ parameter C_PADMANT = 16'b0;
+ parameter C_EXP_ZERO = 8'h00;
+ parameter C_EXP_INF = 8'hff;
+ parameter C_MANT_ZERO = 24'h0;
+ parameter C_MANT_NoHB_ZERO = 23'h0;
+ parameter C_MANT_PRENORM_IND = 6;
+ parameter F_QNAN =32'h7FC00000;
+`endif
+
+ parameter C_FFLAG = 5;
+
+endpackage : fpu_defs
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_ftoi.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_ftoi.v
new file mode 100644
index 0000000..789b85c
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_ftoi.v
@@ -0,0 +1,98 @@
+module fpu_ftoi (
+ Sign_a_DI,
+ Exp_a_DI,
+ Mant_a_DI,
+ Result_DO,
+ OF_SO,
+ UF_SO,
+ Zero_SO,
+ IX_SO,
+ IV_SO,
+ Inf_SO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+ input wire Sign_a_DI;
+ input wire [C_EXP - 1:0] Exp_a_DI;
+ input wire [C_MANT:0] Mant_a_DI;
+ output wire [C_OP - 1:0] Result_DO;
+ output wire OF_SO;
+ output wire UF_SO;
+ output wire Zero_SO;
+ output wire IX_SO;
+ output wire IV_SO;
+ output wire Inf_SO;
+ wire Sign_a_D;
+ wire [C_EXP - 1:0] Exp_a_D;
+ wire [C_MANT:0] Mant_a_D;
+ wire [C_OP - 1:0] Result_D;
+ assign Sign_a_D = Sign_a_DI;
+ assign Exp_a_D = Exp_a_DI;
+ assign Mant_a_D = Mant_a_DI;
+ wire signed [C_EXP_SHIFT - 1:0] Shift_amount_D;
+ wire [(C_MANT + C_OP) - 2:0] Temp_shift_D;
+ wire [C_OP - 1:0] Temp_twos_D;
+ wire Shift_amount_neg_S;
+ wire Result_zero_S;
+ wire Input_zero_S;
+ assign Shift_amount_D = $signed({1'b0, Exp_a_D}) - $signed(C_SHIFT_BIAS);
+ assign Shift_amount_neg_S = Shift_amount_D[C_EXP_SHIFT - 1];
+ assign Temp_shift_D = (Shift_amount_neg_S ? {(((C_MANT + C_OP) - 2) >= 0 ? (C_MANT + C_OP) - 1 : 3 - (C_MANT + C_OP)) {1'sb0}} : Mant_a_D << Shift_amount_D);
+ assign Temp_twos_D = ~{1'b0, Temp_shift_D[(C_MANT + C_OP) - 2:C_MANT]} + 1'b1;
+ assign Result_D = (OF_SO ? (Sign_a_D ? C_MINF : C_INF) : (Sign_a_D ? Temp_twos_D : {Sign_a_D, Temp_shift_D[(C_MANT + C_OP) - 2:C_MANT]}));
+ assign Result_DO = Result_D;
+ assign Result_zero_S = ~|Result_D;
+ assign Input_zero_S = ~|{Exp_a_D, Mant_a_D};
+ assign UF_SO = 1'b0;
+ assign OF_SO = Shift_amount_D > (C_OP - 2);
+ assign Zero_SO = Result_zero_S & ~OF_SO;
+ assign IX_SO = ((|Temp_shift_D[C_MANT - 1:0] | Shift_amount_neg_S) | OF_SO) & ~Input_zero_S;
+ assign IV_SO = &Exp_a_D && |Mant_a_D;
+ assign Inf_SO = 1'b0;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_itof.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_itof.v
new file mode 100644
index 0000000..6293c3c
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_itof.v
@@ -0,0 +1,80 @@
+module fpu_itof (
+ Operand_a_DI,
+ Sign_prenorm_DO,
+ Exp_prenorm_DO,
+ Mant_prenorm_DO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+ input wire [C_OP - 1:0] Operand_a_DI;
+ output wire Sign_prenorm_DO;
+ output wire signed [C_EXP_PRENORM - 1:0] Exp_prenorm_DO;
+ output wire [C_MANT_PRENORM - 1:0] Mant_prenorm_DO;
+ wire [C_OP - 1:0] Operand_a_D;
+ wire Sign_int_D;
+ wire Sign_prenorm_D;
+ wire [C_MANT_INT - 1:0] Mant_int_D;
+ wire [C_OP - 1:0] Temp_twos_to_unsigned_D;
+ wire [C_MANT_PRENORM - 1:0] Mant_prenorm_D;
+ wire Hb_a_D;
+ wire signed [C_EXP_PRENORM - 1:0] Exp_prenorm_D;
+ assign Operand_a_D = Operand_a_DI;
+ assign Sign_int_D = Operand_a_D[C_OP - 1];
+ assign Mant_int_D = Operand_a_D[C_MANT_INT - 1:0];
+ wire Twos_to_unsigned_zero;
+ assign Temp_twos_to_unsigned_D = ~Operand_a_D + 1'b1;
+ wire Twos_to_unsigned_zero_D;
+ assign Twos_to_unsigned_zero_D = ~(|Temp_twos_to_unsigned_D[C_MANT_INT - 1:0]);
+ assign Sign_prenorm_D = Sign_int_D;
+ assign Exp_prenorm_D = $signed({2'd0, C_UNKNOWN});
+ assign Mant_prenorm_D = (Sign_int_D ? {Twos_to_unsigned_zero_D, Temp_twos_to_unsigned_D[C_MANT_INT - 1:0], C_PADMANT} : {1'b0, Mant_int_D, C_PADMANT});
+ assign Sign_prenorm_DO = Sign_prenorm_D;
+ assign Exp_prenorm_DO = Exp_prenorm_D;
+ assign Mant_prenorm_DO = Mant_prenorm_D;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_mult.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_mult.v
new file mode 100644
index 0000000..e010b3d
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_mult.v
@@ -0,0 +1,90 @@
+module fpu_mult (
+ Sign_a_DI,
+ Sign_b_DI,
+ Exp_a_DI,
+ Exp_b_DI,
+ Mant_a_DI,
+ Mant_b_DI,
+ Sign_prenorm_DO,
+ Exp_prenorm_DO,
+ Mant_prenorm_DO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+ input wire Sign_a_DI;
+ input wire Sign_b_DI;
+ input wire [C_EXP - 1:0] Exp_a_DI;
+ input wire [C_EXP - 1:0] Exp_b_DI;
+ input wire [C_MANT:0] Mant_a_DI;
+ input wire [C_MANT:0] Mant_b_DI;
+ output wire Sign_prenorm_DO;
+ output wire signed [C_EXP_PRENORM - 1:0] Exp_prenorm_DO;
+ output wire [C_MANT_PRENORM - 1:0] Mant_prenorm_DO;
+ wire Sign_a_D;
+ wire Sign_b_D;
+ wire Sign_prenorm_D;
+ wire [C_EXP - 1:0] Exp_a_D;
+ wire [C_EXP - 1:0] Exp_b_D;
+ wire [C_MANT:0] Mant_a_D;
+ wire [C_MANT:0] Mant_b_D;
+ wire signed [C_EXP_PRENORM - 1:0] Exp_prenorm_D;
+ wire [C_MANT_PRENORM - 1:0] Mant_prenorm_D;
+ assign Sign_a_D = Sign_a_DI;
+ assign Sign_b_D = Sign_b_DI;
+ assign Exp_a_D = Exp_a_DI;
+ assign Exp_b_D = Exp_b_DI;
+ assign Mant_a_D = Mant_a_DI;
+ assign Mant_b_D = Mant_b_DI;
+ assign Sign_prenorm_D = Sign_a_D ^ Sign_b_D;
+ assign Exp_prenorm_D = ($signed({2'b00, Exp_a_D}) + $signed({2'b00, Exp_b_D})) - $signed(C_BIAS);
+ assign Mant_prenorm_D = Mant_a_D * Mant_b_D;
+ assign Sign_prenorm_DO = Sign_prenorm_D;
+ assign Exp_prenorm_DO = Exp_prenorm_D;
+ assign Mant_prenorm_DO = Mant_prenorm_D;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_norm.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_norm.v
new file mode 100644
index 0000000..3e9b993
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_norm.v
@@ -0,0 +1,144 @@
+module fpu_norm (
+ Mant_in_DI,
+ Exp_in_DI,
+ Sign_in_DI,
+ RM_SI,
+ OP_SI,
+ Mant_res_DO,
+ Exp_res_DO,
+ Rounded_SO,
+ Exp_OF_SO,
+ Exp_UF_SO
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+ input wire [C_MANT_PRENORM - 1:0] Mant_in_DI;
+ input wire signed [C_EXP_PRENORM - 1:0] Exp_in_DI;
+ input wire Sign_in_DI;
+ input wire [C_RM - 1:0] RM_SI;
+ input wire [C_CMD - 1:0] OP_SI;
+ output wire [C_MANT:0] Mant_res_DO;
+ output wire [C_EXP - 1:0] Exp_res_DO;
+ output wire Rounded_SO;
+ output reg Exp_OF_SO;
+ output reg Exp_UF_SO;
+ wire [C_MANT_PRENORM_IND - 1:0] Mant_leadingOne_D;
+ wire Mant_zero_S;
+ reg [C_MANT + 4:0] Mant_norm_D;
+ wire signed [C_EXP_PRENORM - 1:0] Exp_norm_D;
+ wire signed [C_EXP_PRENORM - 1:0] Mant_shAmt_D;
+ wire signed [C_EXP_PRENORM:0] Mant_shAmt2_D;
+ wire [C_EXP - 1:0] Exp_final_D;
+ wire signed [C_EXP_PRENORM - 1:0] Exp_rounded_D;
+ reg Mant_sticky_D;
+ wire Denormal_S;
+ wire Mant_renorm_S;
+ fpu_ff #(.LEN(C_MANT_PRENORM)) LOD(
+ .in_i(Mant_in_DI),
+ .first_one_o(Mant_leadingOne_D),
+ .no_ones_o(Mant_zero_S)
+ );
+ wire Denormals_shift_add_D;
+ wire Denormals_exp_add_D;
+ assign Denormals_shift_add_D = (~Mant_zero_S & (Exp_in_DI == C_EXP_ZERO)) & ((OP_SI != C_FPU_MUL_CMD) | (~Mant_in_DI[C_MANT_PRENORM - 1] & ~Mant_in_DI[C_MANT_PRENORM - 2]));
+ assign Denormals_exp_add_D = (Mant_in_DI[C_MANT_PRENORM - 2] & (Exp_in_DI == C_EXP_ZERO)) & ((OP_SI == C_FPU_ADD_CMD) | (OP_SI == C_FPU_SUB_CMD));
+ assign Denormal_S = (C_EXP_PRENORM'($signed(Mant_leadingOne_D)) >= Exp_in_DI) || Mant_zero_S;
+ assign Mant_shAmt_D = (Denormal_S ? Exp_in_DI + Denormals_shift_add_D : Mant_leadingOne_D);
+ assign Mant_shAmt2_D = {Mant_shAmt_D[C_EXP_PRENORM - 1], Mant_shAmt_D} + (C_MANT + 5);
+ function automatic [(((C_MANT_PRENORM + C_MANT) + 4) >= 0 ? (C_MANT_PRENORM + C_MANT) + 5 : 1 - ((C_MANT_PRENORM + C_MANT) + 4)) - 1:0] sv2v_cast_F3481;
+ input reg [(((C_MANT_PRENORM + C_MANT) + 4) >= 0 ? (C_MANT_PRENORM + C_MANT) + 5 : 1 - ((C_MANT_PRENORM + C_MANT) + 4)) - 1:0] inp;
+ sv2v_cast_F3481 = inp;
+ endfunction
+ always @(*) begin : sv2v_autoblock_1
+ reg [(C_MANT_PRENORM + C_MANT) + 4:0] temp;
+ temp = sv2v_cast_F3481(Mant_in_DI) << Mant_shAmt2_D;
+ Mant_norm_D = temp[(C_MANT_PRENORM + C_MANT) + 4:C_MANT_PRENORM];
+ end
+ always @(*) begin
+ Mant_sticky_D = 1'b0;
+ if (Mant_shAmt2_D <= 0)
+ Mant_sticky_D = |Mant_in_DI;
+ else if (Mant_shAmt2_D <= C_MANT_PRENORM)
+ Mant_sticky_D = |(Mant_in_DI << Mant_shAmt2_D);
+ end
+ assign Exp_norm_D = ((Exp_in_DI - C_EXP_PRENORM'($signed(Mant_leadingOne_D))) + 1) + Denormals_exp_add_D;
+ assign Exp_rounded_D = Exp_norm_D + Mant_renorm_S;
+ assign Exp_final_D = Exp_rounded_D[C_EXP - 1:0];
+ always @(*) begin
+ Exp_OF_SO = 1'b0;
+ Exp_UF_SO = 1'b0;
+ if (Exp_rounded_D >= $signed({2'b00, C_EXP_INF}))
+ Exp_OF_SO = 1'b1;
+ else if (Exp_rounded_D <= $signed({2'b00, C_EXP_ZERO}))
+ Exp_UF_SO = 1'b1;
+ end
+ wire [C_MANT:0] Mant_upper_D;
+ wire [3:0] Mant_lower_D;
+ wire [C_MANT + 1:0] Mant_upperRounded_D;
+ reg Mant_roundUp_S;
+ wire Mant_rounded_S;
+ assign Mant_lower_D = Mant_norm_D[3:0];
+ assign Mant_upper_D = Mant_norm_D[C_MANT + 4:4];
+ assign Mant_rounded_S = |Mant_lower_D | Mant_sticky_D;
+ always @(*) begin
+ Mant_roundUp_S = 1'b0;
+ case (RM_SI)
+ C_RM_NEAREST: Mant_roundUp_S = Mant_lower_D[3] && ((|Mant_lower_D[2:0] | Mant_sticky_D) || Mant_upper_D[0]);
+ C_RM_TRUNC: Mant_roundUp_S = 0;
+ C_RM_PLUSINF: Mant_roundUp_S = Mant_rounded_S & ~Sign_in_DI;
+ C_RM_MINUSINF: Mant_roundUp_S = Mant_rounded_S & Sign_in_DI;
+ default: Mant_roundUp_S = 0;
+ endcase
+ end
+ assign Mant_upperRounded_D = Mant_upper_D + Mant_roundUp_S;
+ assign Mant_renorm_S = Mant_upperRounded_D[C_MANT + 1];
+ assign Mant_res_DO = Mant_upperRounded_D >> (Mant_renorm_S & ~Denormal_S);
+ assign Exp_res_DO = Exp_final_D;
+ assign Rounded_SO = Mant_rounded_S;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_private.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_private.v
new file mode 100644
index 0000000..1f32e0d
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_private.v
@@ -0,0 +1,189 @@
+module fpu_private (
+ clk_i,
+ rst_ni,
+ fpu_en_i,
+ operand_a_i,
+ operand_b_i,
+ operand_c_i,
+ rm_i,
+ fpu_op_i,
+ prec_i,
+ result_o,
+ valid_o,
+ flags_o,
+ divsqrt_busy_o
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+parameter C_FFLAG = 5;
+ input wire clk_i;
+ input wire rst_ni;
+ input wire fpu_en_i;
+ input wire [C_OP - 1:0] operand_a_i;
+ input wire [C_OP - 1:0] operand_b_i;
+ input wire [C_OP - 1:0] operand_c_i;
+ input wire [C_RM - 1:0] rm_i;
+ input wire [C_CMD - 1:0] fpu_op_i;
+ input wire [C_PC - 1:0] prec_i;
+ output wire [C_OP - 1:0] result_o;
+ output wire valid_o;
+ output wire [C_FFLAG - 1:0] flags_o;
+ output wire divsqrt_busy_o;
+ wire divsqrt_enable;
+ wire fpu_enable;
+ wire fma_enable;
+ assign divsqrt_enable = fpu_en_i & ((fpu_op_i == C_FPU_DIV_CMD) | (fpu_op_i == C_FPU_SQRT_CMD));
+ assign fpu_enable = fpu_en_i & (((((fpu_op_i == C_FPU_ADD_CMD) | (fpu_op_i == C_FPU_SUB_CMD)) | (fpu_op_i == C_FPU_MUL_CMD)) | (fpu_op_i == C_FPU_I2F_CMD)) | (fpu_op_i == C_FPU_F2I_CMD));
+ assign fma_enable = fpu_en_i & ((((fpu_op_i == C_FPU_FMADD_CMD) | (fpu_op_i == C_FPU_FMSUB_CMD)) | (fpu_op_i == C_FPU_FNMADD_CMD)) | (fpu_op_i == C_FPU_FNMSUB_CMD));
+ wire [31:0] fpu_operand_a;
+ wire [31:0] fpu_operand_b;
+ wire [31:0] fpu_result;
+ wire [C_FFLAG - 1:0] fpu_flags;
+ wire fpu_of;
+ wire fpu_uf;
+ wire fpu_zero;
+ wire fpu_ix;
+ wire fpu_iv;
+ wire fpu_inf;
+ assign fpu_operand_a = (fpu_enable ? operand_a_i : {32 {1'sb0}});
+ assign fpu_operand_b = (fpu_enable ? operand_b_i : {32 {1'sb0}});
+ wire fpu_valid;
+ fpu_core fpu_core(
+ .Clk_CI(clk_i),
+ .Rst_RBI(rst_ni),
+ .Enable_SI(fpu_enable),
+ .Operand_a_DI(fpu_operand_a),
+ .Operand_b_DI(fpu_operand_b),
+ .RM_SI(rm_i),
+ .OP_SI(fpu_op_i),
+ .Result_DO(fpu_result),
+ .Valid_SO(fpu_valid),
+ .OF_SO(fpu_of),
+ .UF_SO(fpu_uf),
+ .Zero_SO(fpu_zero),
+ .IX_SO(fpu_ix),
+ .IV_SO(fpu_iv),
+ .Inf_SO(fpu_inf)
+ );
+ assign fpu_flags = {fpu_iv, 1'b0, fpu_of, fpu_uf, fpu_ix};
+ wire div_start;
+ wire sqrt_start;
+ wire [31:0] divsqrt_operand_a;
+ wire [31:0] divsqrt_operand_b;
+ wire [31:0] divsqrt_result;
+ wire [C_FFLAG - 1:0] divsqrt_flags;
+ wire divsqrt_nv;
+ wire divsqrt_ix;
+ assign sqrt_start = divsqrt_enable & (fpu_op_i == C_FPU_SQRT_CMD);
+ assign div_start = divsqrt_enable & (fpu_op_i == C_FPU_DIV_CMD);
+ assign divsqrt_operand_a = (div_start | sqrt_start ? operand_a_i : {32 {1'sb0}});
+ assign divsqrt_operand_b = (div_start ? operand_b_i : {32 {1'sb0}});
+ wire divsqrt_of;
+ wire divsqrt_uf;
+ wire divsqrt_zero;
+ wire divsqrt_valid;
+ div_sqrt_top_tp fpu_divsqrt_tp(
+ .Clk_CI(clk_i),
+ .Rst_RBI(rst_ni),
+ .Div_start_SI(div_start),
+ .Sqrt_start_SI(sqrt_start),
+ .Operand_a_DI(divsqrt_operand_a),
+ .Operand_b_DI(divsqrt_operand_b),
+ .RM_SI(rm_i[1:0]),
+ .Precision_ctl_SI(prec_i),
+ .Result_DO(divsqrt_result),
+ .Exp_OF_SO(divsqrt_of),
+ .Exp_UF_SO(divsqrt_uf),
+ .Div_zero_SO(divsqrt_zero),
+ .Ready_SO(divsqrt_busy_o),
+ .Done_SO(divsqrt_valid)
+ );
+ assign divsqrt_nv = 1'b0;
+ assign divsqrt_ix = 1'b0;
+ assign divsqrt_flags = {divsqrt_nv, divsqrt_zero, divsqrt_of, divsqrt_uf, divsqrt_ix};
+ wire [31:0] fma_operand_a;
+ wire [31:0] fma_operand_b;
+ wire [31:0] fma_operand_c;
+ wire [31:0] fma_result;
+ reg [1:0] fma_op;
+ wire fma_valid;
+ wire [C_FFLAG - 1:0] fma_flags;
+ always @(*) begin
+ fma_op = 2'b00;
+ case (fpu_op_i)
+ C_FPU_FMADD_CMD: fma_op = 2'b00;
+ C_FPU_FMSUB_CMD: fma_op = 2'b01;
+ C_FPU_FNMADD_CMD: fma_op = 2'b11;
+ C_FPU_FNMSUB_CMD: fma_op = 2'b10;
+ default: fma_op = 2'b00;
+ endcase
+ end
+ fp_fma_wrapper #(
+ .C_MAC_PIPE_REGS(2),
+ .RND_WIDTH(2),
+ .STAT_WIDTH(5)
+ ) fp_fma_wrap_i(
+ .clk_i(clk_i),
+ .rst_ni(rst_ni),
+ .En_i(fma_enable),
+ .OpA_i(operand_a_i),
+ .OpB_i(operand_b_i),
+ .OpC_i(operand_c_i),
+ .Op_i(fma_op),
+ .Rnd_i(rm_i[1:0]),
+ .Status_o(fma_flags),
+ .Res_o(fma_result),
+ .Valid_o(fma_valid),
+ .Ready_o(),
+ .Ack_i(1'b1)
+ );
+ assign valid_o = (divsqrt_valid | fpu_valid) | fma_valid;
+ assign result_o = (divsqrt_valid ? divsqrt_result : (fpu_valid ? fpu_result : (fma_valid ? fma_result : {C_OP {1'sb0}})));
+ assign flags_o = (divsqrt_valid ? divsqrt_flags : (fpu_valid ? fpu_flags : (fma_valid ? fma_flags : {C_FFLAG {1'sb0}})));
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_shared.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_shared.v
new file mode 100644
index 0000000..89efef4
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/fpu_shared.v
@@ -0,0 +1,117 @@
+module fpu_shared
+#(
+ parameter ADD_REGISTER = 1
+ )
+(
+ Clk_CI,
+ Rst_RBI,
+ Interface
+);
+ //parameter ADD_REGISTER = 1;
+ input wire Clk_CI;
+ input wire Rst_RBI;
+ input marx_apu_if.apu Interface;
+ reg [C_OP - 1:0] Operand_a_D;
+ reg [C_OP - 1:0] Operand_b_D;
+ reg [C_CMD - 1:0] Op_S;
+ reg [C_RM - 1:0] RM_S;
+ reg Valid_S;
+ reg [C_TAG - 1:0] Tag_D;
+ generate
+ if (ADD_REGISTER == 1) begin : genblk1
+ wire [C_OP - 1:0] Operand_a_DN;
+ wire [C_OP - 1:0] Operand_b_DN;
+ wire [C_RM - 1:0] RM_SN;
+ wire [C_CMD - 1:0] Op_SN;
+ wire Valid_SN;
+ wire [C_TAG - 1:0] Tag_DN;
+ assign Operand_a_DN = Interface.arga_ds_d;
+ assign Operand_b_DN = Interface.argb_ds_d;
+ assign RM_SN = Interface.flags_ds_d;
+ assign Op_SN = Interface.op_ds_d;
+ assign Valid_SN = Interface.valid_ds_s;
+ assign Tag_DN = Interface.tag_ds_d;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI) begin
+ Operand_a_D <= 1'sb0;
+ Operand_b_D <= 1'sb0;
+ Op_S <= 1'sb0;
+ RM_S <= 1'sb0;
+ Valid_S <= 1'sb0;
+ Tag_D <= 1'sb0;
+ end
+ else begin
+ Operand_a_D <= Operand_a_DN;
+ Operand_b_D <= Operand_b_DN;
+ RM_S <= RM_SN;
+ Op_S <= Op_SN;
+ Valid_S <= Valid_SN;
+ Tag_D <= Tag_DN;
+ end
+ end
+ else begin : genblk1
+ wire [C_OP:1] sv2v_tmp_6B435;
+ assign sv2v_tmp_6B435 = Interface.arga_ds_d;
+ always @(*) Operand_a_D = sv2v_tmp_6B435;
+ wire [C_OP:1] sv2v_tmp_8961F;
+ assign sv2v_tmp_8961F = Interface.argb_ds_d;
+ always @(*) Operand_b_D = sv2v_tmp_8961F;
+ wire [C_RM:1] sv2v_tmp_A4AE8;
+ assign sv2v_tmp_A4AE8 = Interface.flags_ds_d;
+ always @(*) RM_S = sv2v_tmp_A4AE8;
+ wire [C_CMD:1] sv2v_tmp_AEC49;
+ assign sv2v_tmp_AEC49 = Interface.op_ds_d;
+ always @(*) Op_S = sv2v_tmp_AEC49;
+ wire [1:1] sv2v_tmp_078D4;
+ assign sv2v_tmp_078D4 = Interface.valid_ds_s;
+ always @(*) Valid_S = sv2v_tmp_078D4;
+ wire [C_TAG:1] sv2v_tmp_37E7A;
+ assign sv2v_tmp_37E7A = Interface.tag_ds_d;
+ always @(*) Tag_D = sv2v_tmp_37E7A;
+ end
+ endgenerate
+ wire [C_OP - 1:0] Result_D;
+ wire [C_FLAG - 1:0] Flags_S;
+ wire UF_S;
+ wire OF_S;
+ wire Zero_S;
+ wire IX_S;
+ wire IV_S;
+ wire Inf_S;
+ fpu_core core(
+ .Clk_CI(Clk_CI),
+ .Rst_RBI(Rst_RBI),
+ .Enable_SI(Valid_S),
+ .Operand_a_DI(Operand_a_D),
+ .Operand_b_DI(Operand_b_D),
+ .RM_SI(RM_S),
+ .OP_SI(Op_S),
+ .Result_DO(Result_D),
+ .OF_SO(OF_S),
+ .UF_SO(UF_S),
+ .Zero_SO(Zero_S),
+ .IX_SO(IX_S),
+ .IV_SO(IV_S),
+ .Inf_SO(Inf_S)
+ );
+ reg ValidDelayed_SP;
+ wire ValidDelayed_SN;
+ reg [C_TAG - 1:0] TagDelayed_DP;
+ wire [C_TAG - 1:0] TagDelayed_DN;
+ assign ValidDelayed_SN = Valid_S;
+ assign TagDelayed_DN = Tag_D;
+ always @(posedge Clk_CI or negedge Rst_RBI)
+ if (~Rst_RBI) begin
+ ValidDelayed_SP <= 1'sb0;
+ TagDelayed_DP <= 1'sb0;
+ end
+ else begin
+ ValidDelayed_SP <= ValidDelayed_SN;
+ TagDelayed_DP <= TagDelayed_DN;
+ end
+ assign Interface.result_us_d = Result_D;
+ assign Interface.flags_us_d = {1'b0, Inf_S, IV_S, IX_S, Zero_S, 2'b00, UF_S, OF_S};
+ assign Interface.tag_us_d = TagDelayed_DP;
+ assign Interface.req_us_s = ValidDelayed_SP;
+ assign Interface.ready_ds_s = 1'b1;
+endmodule
diff --git a/verilog/rtl/ips/fpu/hdl/fpu_v0.1/riscv_fpu.v b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/riscv_fpu.v
new file mode 100644
index 0000000..e846a46
--- /dev/null
+++ b/verilog/rtl/ips/fpu/hdl/fpu_v0.1/riscv_fpu.v
@@ -0,0 +1,116 @@
+module riscv_fpu (
+ clk,
+ rst_n,
+ operand_a_i,
+ operand_b_i,
+ rounding_mode_i,
+ operator_i,
+ enable_i,
+ stall_i,
+ result_o,
+ fpu_ready_o,
+ result_valid_o
+);
+parameter C_RM = 2;
+parameter C_RM_NEAREST = 2'h0;
+parameter C_RM_TRUNC = 2'h1;
+parameter C_RM_PLUSINF = 2'h2;
+parameter C_RM_MINUSINF = 2'h3;
+parameter C_PC = 5;
+parameter C_OP = 32;
+parameter C_MANT = 23;
+parameter C_EXP = 8;
+parameter C_BIAS = 127;
+parameter C_HALF_BIAS = 63;
+parameter C_LEADONE_WIDTH = 7;
+parameter C_MANT_PRENORM = C_MANT+1;
+parameter C_EXP_ZERO = 8'h00;
+parameter C_EXP_ONE = 8'h01;
+parameter C_EXP_INF = 8'hff;
+parameter C_MANT_ZERO = 23'h0;
+parameter C_MANT_NAN = 23'h400000;
+
+parameter C_CMD = 4;
+parameter C_FPU_ADD_CMD = 4'h0;
+parameter C_FPU_SUB_CMD = 4'h1;
+parameter C_FPU_MUL_CMD = 4'h2;
+parameter C_FPU_DIV_CMD = 4'h3;
+parameter C_FPU_I2F_CMD = 4'h4;
+parameter C_FPU_F2I_CMD = 4'h5;
+parameter C_FPU_SQRT_CMD = 4'h6;
+parameter C_FPU_NOP_CMD = 4'h7;
+parameter C_FPU_FMADD_CMD = 4'h8;
+parameter C_FPU_FMSUB_CMD = 4'h9;
+parameter C_FPU_FNMADD_CMD = 4'hA;
+parameter C_FPU_FNMSUB_CMD = 4'hB;
+parameter C_RM_NEAREST_MAX = 3'h4;
+parameter C_EXP_PRENORM = C_EXP+2;
+parameter C_MANT_ADDIN = C_MANT+4;
+parameter C_MANT_ADDOUT = C_MANT+5;
+parameter C_MANT_SHIFTIN = C_MANT+3;
+parameter C_MANT_SHIFTED = C_MANT+4;
+parameter C_MANT_INT = C_OP-1;
+parameter C_INF = 32'h7fffffff;
+parameter C_MINF = 32'h80000000;
+parameter C_EXP_SHIFT = C_EXP_PRENORM;
+parameter C_SHIFT_BIAS = 9'd127;
+parameter C_UNKNOWN = 8'd157;
+parameter C_PADMANT = 16'b0;
+parameter C_MANT_NoHB_ZERO = 23'h0;
+parameter C_MANT_PRENORM_IND = 6;
+parameter F_QNAN =32'h7FC00000;
+parameter C_FFLAG = 5;
+ input wire clk;
+ input wire rst_n;
+ input wire [C_OP - 1:0] operand_a_i;
+ input wire [C_OP - 1:0] operand_b_i;
+ input wire [C_RM - 1:0] rounding_mode_i;
+ input wire [C_CMD - 1:0] operator_i;
+ input wire enable_i;
+ input wire stall_i;
+ output wire [C_OP - 1:0] result_o;
+ output reg fpu_ready_o;
+ output wire result_valid_o;
+ localparam CYCLES = 2;
+ wire [C_OP - 1:0] operand_a_q;
+ wire [C_OP - 1:0] operand_b_q;
+ wire [C_RM - 1:0] rounding_mode_q;
+ wire [C_CMD - 1:0] operator_q;
+ reg [1:0] valid_count_q;
+ reg [1:0] valid_count_n;
+ assign result_valid_o = (valid_count_q == 1 ? 1'b1 : 1'b0);
+ always @(*) begin
+ valid_count_n = valid_count_q;
+ fpu_ready_o = 1'b1;
+ if (enable_i) begin
+ valid_count_n = valid_count_q + 1;
+ fpu_ready_o = 1'b0;
+ if (valid_count_q == 1) begin
+ fpu_ready_o = 1'b1;
+ valid_count_n = 2'd0;
+ end
+ end
+ end
+ always @(posedge clk or negedge rst_n)
+ if (~rst_n)
+ valid_count_q <= 1'b0;
+ else if (enable_i && ~stall_i)
+ valid_count_q <= valid_count_n;
+ fpu_core fpcore(
+ .Clk_CI(clk),
+ .Rst_RBI(rst_n),
+ .Enable_SI(enable_i),
+ .Operand_a_DI(operand_a_i),
+ .Operand_b_DI(operand_b_i),
+ .RM_SI(rounding_mode_i),
+ .OP_SI(operator_i),
+ .Stall_SI(stall_i),
+ .Result_DO(result_o),
+ .OF_SO(),
+ .UF_SO(),
+ .Zero_SO(),
+ .IX_SO(),
+ .IV_SO(),
+ .Inf_SO()
+ );
+endmodule