Line 62... |
Line 62... |
rstn_i : in std_ulogic; -- global reset, low-active, async
|
rstn_i : in std_ulogic; -- global reset, low-active, async
|
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
|
ctrl_i : in std_ulogic_vector(ctrl_width_c-1 downto 0); -- main control bus
|
start_i : in std_ulogic; -- trigger operation
|
start_i : in std_ulogic; -- trigger operation
|
-- data input --
|
-- data input --
|
frm_i : in std_ulogic_vector(2 downto 0); -- rounding mode
|
frm_i : in std_ulogic_vector(2 downto 0); -- rounding mode
|
|
cmp_i : in std_ulogic_vector(1 downto 0); -- comparator status
|
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
|
rs1_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 1
|
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
|
rs2_i : in std_ulogic_vector(data_width_c-1 downto 0); -- rf source 2
|
-- result and status --
|
-- result and status --
|
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
|
res_o : out std_ulogic_vector(data_width_c-1 downto 0); -- operation result
|
fflags_o : out std_ulogic_vector(4 downto 0); -- exception flags
|
fflags_o : out std_ulogic_vector(4 downto 0); -- exception flags
|
Line 166... |
Line 167... |
signal op_data : op_data_t;
|
signal op_data : op_data_t;
|
signal op_class : op_class_t;
|
signal op_class : op_class_t;
|
signal fpu_operands : fpu_operands_t;
|
signal fpu_operands : fpu_operands_t;
|
|
|
-- floating-point comparator --
|
-- floating-point comparator --
|
|
signal cmp_ff : std_ulogic_vector(01 downto 0);
|
signal comp_equal_ff : std_ulogic;
|
signal comp_equal_ff : std_ulogic;
|
signal comp_less_ff : std_ulogic;
|
signal comp_less_ff : std_ulogic;
|
signal comp_less : std_ulogic;
|
|
|
|
-- functional units interface --
|
-- functional units interface --
|
type fu_interface_t is record
|
type fu_interface_t is record
|
result : std_ulogic_vector(31 downto 0);
|
result : std_ulogic_vector(31 downto 0);
|
flags : std_ulogic_vector(04 downto 0);
|
flags : std_ulogic_vector(04 downto 0);
|
Line 317... |
Line 318... |
op_e_all_one_v := and_all_f(op_data(i)(30 downto 23));
|
op_e_all_one_v := and_all_f(op_data(i)(30 downto 23));
|
|
|
-- check special cases --
|
-- check special cases --
|
op_is_zero_v := op_e_all_zero_v and op_m_all_zero_v; -- zero
|
op_is_zero_v := op_e_all_zero_v and op_m_all_zero_v; -- zero
|
op_is_inf_v := op_e_all_one_v and op_m_all_zero_v; -- infinity
|
op_is_inf_v := op_e_all_one_v and op_m_all_zero_v; -- infinity
|
op_is_denorm_v := '0'; -- FIXME / TODO op_e_all_zero_v and (not op_m_all_zero_v); -- subnormal
|
op_is_denorm_v := '0'; -- FIXME / TODO -- op_e_all_zero_v and (not op_m_all_zero_v); -- subnormal
|
op_is_nan_v := op_e_all_one_v and (not op_m_all_zero_v); -- NaN
|
op_is_nan_v := op_e_all_one_v and (not op_m_all_zero_v); -- NaN
|
|
|
-- actual attributes --
|
-- actual attributes --
|
op_class(i)(fp_class_neg_inf_c) <= op_data(i)(31) and op_is_inf_v; -- negative infinity
|
op_class(i)(fp_class_neg_inf_c) <= op_data(i)(31) and op_is_inf_v; -- negative infinity
|
op_class(i)(fp_class_neg_norm_c) <= op_data(i)(31) and (not op_is_denorm_v) and (not op_is_nan_v) and (not op_is_inf_v) and (not op_is_zero_v); -- negative normal number
|
op_class(i)(fp_class_neg_norm_c) <= op_data(i)(31) and (not op_is_denorm_v) and (not op_is_nan_v) and (not op_is_inf_v) and (not op_is_zero_v); -- negative normal number
|
Line 342... |
Line 343... |
control_engine_fsm: process(rstn_i, clk_i)
|
control_engine_fsm: process(rstn_i, clk_i)
|
begin
|
begin
|
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
ctrl_engine.state <= S_IDLE;
|
ctrl_engine.state <= S_IDLE;
|
ctrl_engine.start <= '0';
|
ctrl_engine.start <= '0';
|
fpu_operands.frm <= (others => '0');
|
fpu_operands.frm <= (others => def_rst_val_c);
|
fpu_operands.rs1 <= (others => '0');
|
fpu_operands.rs1 <= (others => def_rst_val_c);
|
fpu_operands.rs1_class <= (others => '0');
|
fpu_operands.rs1_class <= (others => def_rst_val_c);
|
fpu_operands.rs2 <= (others => '0');
|
fpu_operands.rs2 <= (others => def_rst_val_c);
|
fpu_operands.rs2_class <= (others => '0');
|
fpu_operands.rs2_class <= (others => def_rst_val_c);
|
funct_ff <= (others => '0');
|
funct_ff <= (others => def_rst_val_c);
|
|
cmp_ff <= (others => def_rst_val_c);
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
-- arbiter defaults --
|
-- arbiter defaults --
|
ctrl_engine.valid <= '0';
|
ctrl_engine.valid <= '0';
|
ctrl_engine.start <= '0';
|
ctrl_engine.start <= '0';
|
|
|
Line 359... |
Line 361... |
case ctrl_engine.state is
|
case ctrl_engine.state is
|
|
|
when S_IDLE => -- waiting for operation trigger
|
when S_IDLE => -- waiting for operation trigger
|
-- ------------------------------------------------------------
|
-- ------------------------------------------------------------
|
funct_ff <= cmd.funct; -- actual operation to execute
|
funct_ff <= cmd.funct; -- actual operation to execute
|
|
cmp_ff <= cmp_i; -- main ALU comparator
|
-- rounding mode --
|
-- rounding mode --
|
-- TODO / FIXME "round to nearest, ties to max magnitude" (0b100) is not supported yet
|
-- TODO / FIXME "round to nearest, ties to max magnitude" (0b100) is not supported yet
|
if (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "111") then
|
if (ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c) = "111") then
|
fpu_operands.frm <= '0' & frm_i(1 downto 0);
|
fpu_operands.frm <= '0' & frm_i(1 downto 0);
|
else
|
else
|
Line 423... |
Line 426... |
fu_classify.done <= fu_classify.start;
|
fu_classify.done <= fu_classify.start;
|
|
|
|
|
-- Floating-Point Comparator --------------------------------------------------------------
|
-- Floating-Point Comparator --------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
float_comparator: process(clk_i)
|
float_comparator: process(rstn_i, clk_i)
|
variable cond_v : std_ulogic_vector(1 downto 0);
|
variable cond_v : std_ulogic_vector(1 downto 0);
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if (rstn_i = '0') then
|
|
comp_equal_ff <= def_rst_val_c;
|
|
comp_less_ff <= def_rst_val_c;
|
|
fu_compare.done <= def_rst_val_c;
|
|
fu_min_max.done <= def_rst_val_c;
|
|
elsif rising_edge(clk_i) then
|
-- equal --
|
-- equal --
|
if ((fpu_operands.rs1_class(fp_class_pos_inf_c) = '1') and (fpu_operands.rs2_class(fp_class_pos_inf_c) = '1')) or -- +inf == +inf
|
if ((fpu_operands.rs1_class(fp_class_pos_inf_c) = '1') and (fpu_operands.rs2_class(fp_class_pos_inf_c) = '1')) or -- +inf == +inf
|
((fpu_operands.rs1_class(fp_class_neg_inf_c) = '1') and (fpu_operands.rs2_class(fp_class_neg_inf_c) = '1')) or -- -inf == -inf
|
((fpu_operands.rs1_class(fp_class_neg_inf_c) = '1') and (fpu_operands.rs2_class(fp_class_neg_inf_c) = '1')) or -- -inf == -inf
|
(((fpu_operands.rs1_class(fp_class_pos_zero_c) = '1') or (fpu_operands.rs1_class(fp_class_neg_zero_c) = '1')) and
|
(((fpu_operands.rs1_class(fp_class_pos_zero_c) = '1') or (fpu_operands.rs1_class(fp_class_neg_zero_c) = '1')) and
|
((fpu_operands.rs2_class(fp_class_pos_zero_c) = '1') or (fpu_operands.rs2_class(fp_class_neg_zero_c) = '1'))) or -- +/-zero == +/-zero
|
((fpu_operands.rs2_class(fp_class_pos_zero_c) = '1') or (fpu_operands.rs2_class(fp_class_neg_zero_c) = '1'))) or -- +/-zero == +/-zero
|
(fpu_operands.rs1 = fpu_operands.rs2) then -- identical in every way
|
(cmp_ff(cmp_equal_c) = '1') then -- identical in every way (comparator result from main ALU)
|
comp_equal_ff <= '1';
|
comp_equal_ff <= '1';
|
else
|
else
|
comp_equal_ff <= '0';
|
comp_equal_ff <= '0';
|
end if;
|
end if;
|
|
|
Line 449... |
Line 457... |
else
|
else
|
cond_v := fpu_operands.rs1(31) & fpu_operands.rs2(31);
|
cond_v := fpu_operands.rs1(31) & fpu_operands.rs2(31);
|
case cond_v is
|
case cond_v is
|
when "10" => comp_less_ff <= '1'; -- rs1 negative, rs2 positive
|
when "10" => comp_less_ff <= '1'; -- rs1 negative, rs2 positive
|
when "01" => comp_less_ff <= '0'; -- rs1 positive, rs2 negative
|
when "01" => comp_less_ff <= '0'; -- rs1 positive, rs2 negative
|
when "00" => comp_less_ff <= comp_less; -- both positive
|
when "00" => comp_less_ff <= cmp_ff(cmp_less_c); -- both positive (comparator result from main ALU)
|
when "11" => comp_less_ff <= not comp_less; -- both negative
|
when "11" => comp_less_ff <= not cmp_ff(cmp_less_c); -- both negative (comparator result from main ALU)
|
when others => comp_less_ff <= '0'; -- undefined
|
when others => comp_less_ff <= '0'; -- undefined
|
end case;
|
end case;
|
end if;
|
end if;
|
|
|
-- comparator latency --
|
-- comparator latency --
|
fu_compare.done <= fu_compare.start; -- for actual comparison operation
|
fu_compare.done <= fu_compare.start; -- for actual comparison operation
|
fu_min_max.done <= fu_min_max.start; -- for min/max operations
|
fu_min_max.done <= fu_min_max.start; -- for min/max operations
|
end if;
|
end if;
|
end process float_comparator;
|
end process float_comparator;
|
|
|
-- less than - only compare the "magnitude" part - sign bit has to be handled separately --
|
|
comp_less <= '1' when (unsigned(fpu_operands.rs1(30 downto 0)) < unsigned(fpu_operands.rs2(30 downto 0))) else '0';
|
|
|
|
|
|
-- Comparison (FEQ/FLT/FLE) ---------------------------------------------------------------
|
-- Comparison (FEQ/FLT/FLE) ---------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
float_comparison: process(fpu_operands, ctrl_i, comp_equal_ff, comp_less_ff)
|
float_comparison: process(fpu_operands, ctrl_i, comp_equal_ff, comp_less_ff)
|
variable snan_v : std_ulogic; -- at least one input is sNaN
|
variable snan_v : std_ulogic; -- at least one input is sNaN
|
Line 573... |
Line 578... |
fu_sign_inject.done <= fu_sign_inject.start;
|
fu_sign_inject.done <= fu_sign_inject.start;
|
|
|
|
|
-- Convert: [unsigned] Integer to Float (FCVT.W.S) ----------------------------------------
|
-- Convert: [unsigned] Integer to Float (FCVT.W.S) ----------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
convert_i2f: process(clk_i)
|
convert_i2f: process(rstn_i, clk_i)
|
begin
|
begin
|
-- this process only computes the absolute input value
|
-- this process only computes the absolute input value
|
-- the actual conversion is done by the normalizer
|
-- the actual conversion is done by the normalizer
|
if rising_edge(clk_i) then
|
if (rstn_i = '0') then
|
|
fu_conv_i2f.result <= (others => def_rst_val_c);
|
|
fu_conv_i2f.sign <= def_rst_val_c;
|
|
elsif rising_edge(clk_i) then
|
if (ctrl_i(ctrl_ir_funct12_0_c) = '0') and (rs1_i(31) = '1') then -- convert signed integer
|
if (ctrl_i(ctrl_ir_funct12_0_c) = '0') and (rs1_i(31) = '1') then -- convert signed integer
|
fu_conv_i2f.result <= std_ulogic_vector(0 - unsigned(rs1_i));
|
fu_conv_i2f.result <= std_ulogic_vector(0 - unsigned(rs1_i));
|
fu_conv_i2f.sign <= rs1_i(31); -- original sign
|
fu_conv_i2f.sign <= rs1_i(31); -- original sign
|
else -- convert unsigned integer
|
else -- convert unsigned integer
|
fu_conv_i2f.result <= rs1_i;
|
fu_conv_i2f.result <= rs1_i;
|
Line 592... |
Line 600... |
end process convert_i2f;
|
end process convert_i2f;
|
|
|
|
|
-- Multiplier Core (FMUL) -----------------------------------------------------------------
|
-- Multiplier Core (FMUL) -----------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
multiplier_core: process(clk_i)
|
multiplier_core: process(rstn_i, clk_i)
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if (rstn_i = '0') then
|
|
multiplier.opa <= (others => '-'); -- these might be DSP regs!
|
|
multiplier.opb <= (others => '-'); -- these might be DSP regs!
|
|
multiplier.buf_ff <= (others => '-'); -- these might be DSP regs!
|
|
multiplier.product <= (others => '-'); -- these might be DSP regs!
|
|
multiplier.sign <= def_rst_val_c;
|
|
multiplier.exp_res <= (others => def_rst_val_c);
|
|
multiplier.flags(fp_exc_of_c) <= def_rst_val_c;
|
|
multiplier.flags(fp_exc_uf_c) <= def_rst_val_c;
|
|
multiplier.flags(fp_exc_nv_c) <= def_rst_val_c;
|
|
multiplier.latency <= (others => def_rst_val_c);
|
|
elsif rising_edge(clk_i) then
|
-- multiplier core --
|
-- multiplier core --
|
if (multiplier.start = '1') then -- FIXME / TODO remove buffer?
|
if (multiplier.start = '1') then -- FIXME / TODO remove buffer?
|
multiplier.opa <= unsigned('1' & fpu_operands.rs1(22 downto 0)); -- append hidden one
|
multiplier.opa <= unsigned('1' & fpu_operands.rs1(22 downto 0)); -- append hidden one
|
multiplier.opb <= unsigned('1' & fpu_operands.rs2(22 downto 0));
|
multiplier.opb <= unsigned('1' & fpu_operands.rs2(22 downto 0)); -- append hidden one
|
end if;
|
end if;
|
multiplier.buf_ff <= multiplier.opa * multiplier.opb;
|
multiplier.buf_ff <= multiplier.opa * multiplier.opb;
|
multiplier.product <= std_ulogic_vector(multiplier.buf_ff(47 downto 0)); -- let the register balancing do the magic here
|
multiplier.product <= std_ulogic_vector(multiplier.buf_ff(47 downto 0)); -- let the register balancing do the magic here
|
multiplier.sign <= fpu_operands.rs1(31) xor fpu_operands.rs2(31); -- resulting sign
|
multiplier.sign <= fpu_operands.rs1(31) xor fpu_operands.rs2(31); -- resulting sign
|
|
|
Line 643... |
Line 662... |
multiplier.flags(fp_exc_dz_c) <= '0'; -- division by zero: not possible here
|
multiplier.flags(fp_exc_dz_c) <= '0'; -- division by zero: not possible here
|
multiplier.flags(fp_exc_nx_c) <= '0'; -- inexcat: not possible here
|
multiplier.flags(fp_exc_nx_c) <= '0'; -- inexcat: not possible here
|
|
|
|
|
-- result class --
|
-- result class --
|
multiplier_class_core: process(clk_i)
|
multiplier_class_core: process(rstn_i, clk_i)
|
variable a_pos_norm_v, a_neg_norm_v, b_pos_norm_v, b_neg_norm_v : std_ulogic;
|
variable a_pos_norm_v, a_neg_norm_v, b_pos_norm_v, b_neg_norm_v : std_ulogic;
|
variable a_pos_subn_v, a_neg_subn_v, b_pos_subn_v, b_neg_subn_v : std_ulogic;
|
variable a_pos_subn_v, a_neg_subn_v, b_pos_subn_v, b_neg_subn_v : std_ulogic;
|
variable a_pos_zero_v, a_neg_zero_v, b_pos_zero_v, b_neg_zero_v : std_ulogic;
|
variable a_pos_zero_v, a_neg_zero_v, b_pos_zero_v, b_neg_zero_v : std_ulogic;
|
variable a_pos_inf_v, a_neg_inf_v, b_pos_inf_v, b_neg_inf_v : std_ulogic;
|
variable a_pos_inf_v, a_neg_inf_v, b_pos_inf_v, b_neg_inf_v : std_ulogic;
|
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
|
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if (rstn_i = '0') then
|
|
multiplier.res_class(fp_class_pos_norm_c) <= def_rst_val_c;
|
|
multiplier.res_class(fp_class_neg_norm_c) <= def_rst_val_c;
|
|
multiplier.res_class(fp_class_pos_inf_c) <= def_rst_val_c;
|
|
multiplier.res_class(fp_class_neg_inf_c) <= def_rst_val_c;
|
|
multiplier.res_class(fp_class_pos_zero_c) <= def_rst_val_c;
|
|
multiplier.res_class(fp_class_neg_zero_c) <= def_rst_val_c;
|
|
elsif rising_edge(clk_i) then
|
-- minions --
|
-- minions --
|
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
|
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
|
a_neg_norm_v := fpu_operands.rs1_class(fp_class_neg_norm_c); b_neg_norm_v := fpu_operands.rs2_class(fp_class_neg_norm_c);
|
a_neg_norm_v := fpu_operands.rs1_class(fp_class_neg_norm_c); b_neg_norm_v := fpu_operands.rs2_class(fp_class_neg_norm_c);
|
a_pos_subn_v := fpu_operands.rs1_class(fp_class_pos_denorm_c); b_pos_subn_v := fpu_operands.rs2_class(fp_class_pos_denorm_c);
|
a_pos_subn_v := fpu_operands.rs1_class(fp_class_pos_denorm_c); b_pos_subn_v := fpu_operands.rs2_class(fp_class_pos_denorm_c);
|
a_neg_subn_v := fpu_operands.rs1_class(fp_class_neg_denorm_c); b_neg_subn_v := fpu_operands.rs2_class(fp_class_neg_denorm_c);
|
a_neg_subn_v := fpu_operands.rs1_class(fp_class_neg_denorm_c); b_neg_subn_v := fpu_operands.rs2_class(fp_class_neg_denorm_c);
|
Line 743... |
Line 769... |
fu_mul.flags <= (others => '0');
|
fu_mul.flags <= (others => '0');
|
|
|
|
|
-- Adder/Subtractor Core (FADD, FSUB) -----------------------------------------------------
|
-- Adder/Subtractor Core (FADD, FSUB) -----------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
adder_subtractor_core: process(clk_i)
|
adder_subtractor_core: process(rstn_i, clk_i)
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if (rstn_i = '0') then
|
|
addsub.latency <= (others => def_rst_val_c);
|
|
addsub.exp_comp <= (others => def_rst_val_c);
|
|
addsub.man_sreg <= (others => def_rst_val_c);
|
|
addsub.exp_cnt <= (others => def_rst_val_c);
|
|
addsub.man_g_ext <= def_rst_val_c;
|
|
addsub.man_r_ext <= def_rst_val_c;
|
|
addsub.man_s_ext <= def_rst_val_c;
|
|
addsub.man_comp <= def_rst_val_c;
|
|
addsub.add_stage <= (others => def_rst_val_c);
|
|
addsub.res_sign <= def_rst_val_c;
|
|
addsub.flags(fp_exc_nv_c) <= def_rst_val_c;
|
|
elsif rising_edge(clk_i) then
|
-- arbitration / latency --
|
-- arbitration / latency --
|
if (ctrl_engine.state = S_IDLE) then -- hacky "reset"
|
if (ctrl_engine.state = S_IDLE) then -- hacky "reset"
|
addsub.latency <= (others => '0');
|
addsub.latency <= (others => '0');
|
else
|
else
|
addsub.latency(0) <= addsub.start; -- input comparator delay
|
addsub.latency(0) <= addsub.start; -- input comparator delay
|
Line 863... |
Line 901... |
-- mantissa result --
|
-- mantissa result --
|
addsub.res_sum <= addsub.add_stage(27 downto 0);
|
addsub.res_sum <= addsub.add_stage(27 downto 0);
|
|
|
|
|
-- result class --
|
-- result class --
|
adder_subtractor_class_core: process(clk_i)
|
adder_subtractor_class_core: process(rstn_i, clk_i)
|
variable a_pos_norm_v, a_neg_norm_v, b_pos_norm_v, b_neg_norm_v : std_ulogic;
|
variable a_pos_norm_v, a_neg_norm_v, b_pos_norm_v, b_neg_norm_v : std_ulogic;
|
variable a_pos_subn_v, a_neg_subn_v, b_pos_subn_v, b_neg_subn_v : std_ulogic;
|
variable a_pos_subn_v, a_neg_subn_v, b_pos_subn_v, b_neg_subn_v : std_ulogic;
|
variable a_pos_zero_v, a_neg_zero_v, b_pos_zero_v, b_neg_zero_v : std_ulogic;
|
variable a_pos_zero_v, a_neg_zero_v, b_pos_zero_v, b_neg_zero_v : std_ulogic;
|
variable a_pos_inf_v, a_neg_inf_v, b_pos_inf_v, b_neg_inf_v : std_ulogic;
|
variable a_pos_inf_v, a_neg_inf_v, b_pos_inf_v, b_neg_inf_v : std_ulogic;
|
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
|
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if (rstn_i = '0') then
|
|
addsub.res_class(fp_class_pos_inf_c) <= def_rst_val_c;
|
|
addsub.res_class(fp_class_neg_inf_c) <= def_rst_val_c;
|
|
addsub.res_class(fp_class_pos_zero_c) <= def_rst_val_c;
|
|
addsub.res_class(fp_class_neg_zero_c) <= def_rst_val_c;
|
|
addsub.res_class(fp_class_qnan_c) <= def_rst_val_c;
|
|
elsif rising_edge(clk_i) then
|
-- minions --
|
-- minions --
|
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
|
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
|
a_neg_norm_v := fpu_operands.rs1_class(fp_class_neg_norm_c); b_neg_norm_v := fpu_operands.rs2_class(fp_class_neg_norm_c);
|
a_neg_norm_v := fpu_operands.rs1_class(fp_class_neg_norm_c); b_neg_norm_v := fpu_operands.rs2_class(fp_class_neg_norm_c);
|
a_pos_subn_v := fpu_operands.rs1_class(fp_class_pos_denorm_c); b_pos_subn_v := fpu_operands.rs2_class(fp_class_pos_denorm_c);
|
a_pos_subn_v := fpu_operands.rs1_class(fp_class_pos_denorm_c); b_pos_subn_v := fpu_operands.rs2_class(fp_class_pos_denorm_c);
|
a_neg_subn_v := fpu_operands.rs1_class(fp_class_neg_denorm_c); b_neg_subn_v := fpu_operands.rs2_class(fp_class_neg_denorm_c);
|
a_neg_subn_v := fpu_operands.rs1_class(fp_class_neg_denorm_c); b_neg_subn_v := fpu_operands.rs2_class(fp_class_neg_denorm_c);
|
Line 1077... |
Line 1121... |
-- FPU Core - Result
|
-- FPU Core - Result
|
-- ****************************************************************************************************************************
|
-- ****************************************************************************************************************************
|
|
|
-- Result Output to CPU Pipeline ----------------------------------------------------------
|
-- Result Output to CPU Pipeline ----------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
output_gate: process(clk_i)
|
output_gate: process(rstn_i, clk_i)
|
begin
|
begin
|
if rising_edge(clk_i) then
|
if (rstn_i = '0') then
|
|
res_o <= (others => def_rst_val_c);
|
|
fflags_o <= (others => def_rst_val_c);
|
|
elsif rising_edge(clk_i) then
|
if (ctrl_engine.valid = '1') then
|
if (ctrl_engine.valid = '1') then
|
case funct_ff is
|
case funct_ff is
|
when op_class_c =>
|
when op_class_c =>
|
res_o <= fu_classify.result;
|
res_o <= fu_classify.result;
|
fflags_o <= fu_classify.flags;
|
fflags_o <= fu_classify.flags;
|
Line 1231... |
Line 1278... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
ctrl_engine: process(rstn_i, clk_i)
|
ctrl_engine: process(rstn_i, clk_i)
|
begin
|
begin
|
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
ctrl.state <= S_IDLE;
|
ctrl.state <= S_IDLE;
|
ctrl.norm_r <= '0';
|
ctrl.norm_r <= def_rst_val_c;
|
ctrl.cnt <= (others => '0');
|
ctrl.cnt <= (others => def_rst_val_c);
|
ctrl.cnt_pre <= (others => '0');
|
ctrl.cnt_pre <= (others => def_rst_val_c);
|
ctrl.cnt_of <= '0';
|
ctrl.cnt_of <= def_rst_val_c;
|
ctrl.cnt_uf <= '0';
|
ctrl.cnt_uf <= def_rst_val_c;
|
ctrl.rounded <= '0';
|
ctrl.rounded <= def_rst_val_c;
|
ctrl.res_exp <= (others => '0');
|
ctrl.res_exp <= (others => def_rst_val_c);
|
ctrl.res_man <= (others => '0');
|
ctrl.res_man <= (others => def_rst_val_c);
|
ctrl.res_sgn <= '0';
|
ctrl.res_sgn <= def_rst_val_c;
|
ctrl.class <= (others => '0');
|
ctrl.class <= (others => def_rst_val_c);
|
ctrl.flags <= (others => '0');
|
ctrl.flags <= (others => def_rst_val_c);
|
--
|
--
|
sreg.upper <= (others => '0');
|
sreg.upper <= (others => def_rst_val_c);
|
sreg.lower <= (others => '0');
|
sreg.lower <= (others => def_rst_val_c);
|
sreg.dir <= '0';
|
sreg.dir <= def_rst_val_c;
|
sreg.ext_g <= '0';
|
sreg.ext_g <= def_rst_val_c;
|
sreg.ext_r <= '0';
|
sreg.ext_r <= def_rst_val_c;
|
sreg.ext_s <= '0';
|
sreg.ext_s <= def_rst_val_c;
|
--
|
--
|
done_o <= '0';
|
done_o <= '0';
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
-- defaults --
|
-- defaults --
|
ctrl.cnt_pre <= ctrl.cnt;
|
ctrl.cnt_pre <= ctrl.cnt;
|
Line 1607... |
Line 1654... |
-- -------------------------------------------------------------------------------------------
|
-- -------------------------------------------------------------------------------------------
|
ctrl_engine: process(rstn_i, clk_i)
|
ctrl_engine: process(rstn_i, clk_i)
|
begin
|
begin
|
if (rstn_i = '0') then
|
if (rstn_i = '0') then
|
ctrl.state <= S_IDLE;
|
ctrl.state <= S_IDLE;
|
ctrl.cnt <= (others => '0');
|
ctrl.cnt <= (others => def_rst_val_c);
|
ctrl.sign <= '0';
|
ctrl.sign <= def_rst_val_c;
|
ctrl.class <= (others => '0');
|
ctrl.class <= (others => def_rst_val_c);
|
ctrl.rounded <= '0';
|
ctrl.rounded <= def_rst_val_c;
|
ctrl.over <= '0';
|
ctrl.over <= def_rst_val_c;
|
ctrl.under <= '0';
|
ctrl.under <= def_rst_val_c;
|
ctrl.unsign <= '0';
|
ctrl.unsign <= def_rst_val_c;
|
ctrl.result <= (others => '0');
|
ctrl.result <= (others => def_rst_val_c);
|
ctrl.result_tmp <= (others => '0');
|
ctrl.result_tmp <= (others => def_rst_val_c);
|
sreg.int <= (others => '0');
|
sreg.int <= (others => def_rst_val_c);
|
sreg.mant <= (others => '0');
|
sreg.mant <= (others => def_rst_val_c);
|
sreg.ext_s <= '0';
|
sreg.ext_s <= def_rst_val_c;
|
done_o <= '0';
|
done_o <= '0';
|
elsif rising_edge(clk_i) then
|
elsif rising_edge(clk_i) then
|
-- defaults --
|
-- defaults --
|
done_o <= '0';
|
done_o <= '0';
|
|
|