OpenCores
URL https://opencores.org/ocsvn/neorv32/neorv32/trunk

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_cp_fpu.vhd] - Diff between revs 73 and 74

Show entire file | Details | Blame | View Log

Rev 73 Rev 74
Line 310... Line 310...
    variable op_m_all_zero_v, op_e_all_zero_v, op_e_all_one_v       : std_ulogic;
    variable op_m_all_zero_v, op_e_all_zero_v, op_e_all_one_v       : std_ulogic;
    variable op_is_zero_v, op_is_inf_v, op_is_denorm_v, op_is_nan_v : std_ulogic;
    variable op_is_zero_v, op_is_inf_v, op_is_denorm_v, op_is_nan_v : std_ulogic;
  begin
  begin
    for i in 0 to 1 loop -- for rs1 and rs2 inputs
    for i in 0 to 1 loop -- for rs1 and rs2 inputs
      -- check for all-zero/all-one --
      -- check for all-zero/all-one --
      op_m_all_zero_v := not or_reduce_f(op_data(i)(22 downto 00));
      op_m_all_zero_v := '0';
      op_e_all_zero_v := not or_reduce_f(op_data(i)(30 downto 23));
      op_e_all_zero_v := '0';
      op_e_all_one_v  := and_reduce_f(op_data(i)(30 downto 23));
      op_e_all_one_v  := '0';
 
      if (or_reduce_f(op_data(i)(22 downto 00)) = '0') then
 
        op_m_all_zero_v := '1';
 
      end if;
 
      if (or_reduce_f(op_data(i)(30 downto 23)) = '0') then
 
        op_e_all_zero_v := '1';
 
      end if;
 
      if (and_reduce_f(op_data(i)(30 downto 23)) = '1') then
 
        op_e_all_one_v  := '1';
 
      end if;
 
 
      -- 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
Line 341... Line 350...
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  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.valid      <= '0';
      ctrl_engine.start      <= '0';
      ctrl_engine.start      <= '0';
      fpu_operands.frm       <= (others => def_rst_val_c);
      fpu_operands.frm       <= (others => def_rst_val_c);
      fpu_operands.rs1       <= (others => def_rst_val_c);
      fpu_operands.rs1       <= (others => def_rst_val_c);
      fpu_operands.rs1_class <= (others => def_rst_val_c);
      fpu_operands.rs1_class <= (others => def_rst_val_c);
      fpu_operands.rs2       <= (others => def_rst_val_c);
      fpu_operands.rs2       <= (others => def_rst_val_c);
Line 669... Line 679...
    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 (rstn_i = '0') then
    if (rstn_i = '0') then
      multiplier.res_class(fp_class_pos_norm_c) <= def_rst_val_c;
      multiplier.res_class <= (others => 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
    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);
Line 754... Line 759...
      multiplier.res_class(fp_class_qnan_c) <=
      multiplier.res_class(fp_class_qnan_c) <=
        (a_snan_v or b_snan_v) or -- any input is sNaN
        (a_snan_v or b_snan_v) or -- any input is sNaN
        (a_qnan_v or b_qnan_v) or -- nay input is qNaN
        (a_qnan_v or b_qnan_v) or -- nay input is qNaN
        ((a_pos_inf_v  or a_neg_inf_v)  and (b_pos_zero_v or b_neg_zero_v)) or -- +/-inf * +/-zero
        ((a_pos_inf_v  or a_neg_inf_v)  and (b_pos_zero_v or b_neg_zero_v)) or -- +/-inf * +/-zero
        ((a_pos_zero_v or a_neg_zero_v) and (b_pos_inf_v  or b_neg_inf_v));    -- +/-zero * +/-inf
        ((a_pos_zero_v or a_neg_zero_v) and (b_pos_inf_v  or b_neg_inf_v));    -- +/-zero * +/-inf
    end if;
 
  end process multiplier_class_core;
 
 
 
  -- subnormal result --
  -- subnormal result --
  multiplier.res_class(fp_class_pos_denorm_c) <= '0'; -- is evaluated by the normalizer
  multiplier.res_class(fp_class_pos_denorm_c) <= '0'; -- is evaluated by the normalizer
  multiplier.res_class(fp_class_neg_denorm_c) <= '0'; -- is evaluated by the normalizer
  multiplier.res_class(fp_class_neg_denorm_c) <= '0'; -- is evaluated by the normalizer
 
    end if;
 
  end process multiplier_class_core;
 
 
  -- unused --
  -- unused --
  fu_mul.result <= (others => '0');
  fu_mul.result <= (others => '0');
  fu_mul.flags  <= (others => '0');
  fu_mul.flags  <= (others => '0');
 
 
Line 908... Line 913...
    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 (rstn_i = '0') then
    if (rstn_i = '0') then
      addsub.res_class(fp_class_pos_inf_c)  <= def_rst_val_c;
      addsub.res_class <= (others => 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
    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);
Line 1037... Line 1038...
      addsub.res_class(fp_class_pos_norm_c) <= (a_pos_norm_v or a_neg_norm_v) and (b_pos_norm_v or b_neg_norm_v); -- +/-norm +/- +-/norm [sign is irrelevant here]
      addsub.res_class(fp_class_pos_norm_c) <= (a_pos_norm_v or a_neg_norm_v) and (b_pos_norm_v or b_neg_norm_v); -- +/-norm +/- +-/norm [sign is irrelevant here]
      addsub.res_class(fp_class_neg_norm_c) <= (a_pos_norm_v or a_neg_norm_v) and (b_pos_norm_v or b_neg_norm_v); -- +/-norm +/- +-/norm [sign is irrelevant here]
      addsub.res_class(fp_class_neg_norm_c) <= (a_pos_norm_v or a_neg_norm_v) and (b_pos_norm_v or b_neg_norm_v); -- +/-norm +/- +-/norm [sign is irrelevant here]
 
 
      -- sNaN --
      -- sNaN --
      addsub.res_class(fp_class_snan_c) <= (a_snan_v or b_snan_v); -- any input is sNaN
      addsub.res_class(fp_class_snan_c) <= (a_snan_v or b_snan_v); -- any input is sNaN
    end if;
 
  end process adder_subtractor_class_core;
 
 
 
  -- subnormal result --
  -- subnormal result --
  addsub.res_class(fp_class_pos_denorm_c) <= '0'; -- is evaluated by the normalizer
  addsub.res_class(fp_class_pos_denorm_c) <= '0'; -- is evaluated by the normalizer
  addsub.res_class(fp_class_neg_denorm_c) <= '0'; -- is evaluated by the normalizer
  addsub.res_class(fp_class_neg_denorm_c) <= '0'; -- is evaluated by the normalizer
 
    end if;
 
  end process adder_subtractor_class_core;
 
 
  -- unused --
  -- unused --
  fu_addsub.result <= (others => '0');
  fu_addsub.result <= (others => '0');
  fu_addsub.flags  <= (others => '0');
  fu_addsub.flags  <= (others => '0');
 
 
Line 1357... Line 1358...
          sreg.upper(31 downto 02) <= (others => '0');
          sreg.upper(31 downto 02) <= (others => '0');
          sreg.upper(01 downto 00) <= mantissa_i(47 downto 46);
          sreg.upper(01 downto 00) <= mantissa_i(47 downto 46);
          sreg.lower <= mantissa_i(45 downto 23);
          sreg.lower <= mantissa_i(45 downto 23);
          sreg.ext_g <= mantissa_i(22);
          sreg.ext_g <= mantissa_i(22);
          sreg.ext_r <= mantissa_i(21);
          sreg.ext_r <= mantissa_i(21);
          sreg.ext_s <= or_reduce_f(mantissa_i(20 downto 0));
          if (or_reduce_f(mantissa_i(20 downto 0)) = '1') then
 
            sreg.ext_s <= '1';
 
          else
 
            sreg.ext_s <= '0';
 
          end if;
          -- check for special cases --
          -- check for special cases --
          if ((ctrl.class(fp_class_snan_c)       or ctrl.class(fp_class_qnan_c)       or -- NaN
          if ((ctrl.class(fp_class_snan_c)       or ctrl.class(fp_class_qnan_c)       or -- NaN
               ctrl.class(fp_class_neg_zero_c)   or ctrl.class(fp_class_pos_zero_c)   or -- zero
               ctrl.class(fp_class_neg_zero_c)   or ctrl.class(fp_class_pos_zero_c)   or -- zero
               ctrl.class(fp_class_neg_denorm_c) or ctrl.class(fp_class_pos_denorm_c) or -- subnormal
               ctrl.class(fp_class_neg_denorm_c) or ctrl.class(fp_class_pos_denorm_c) or -- subnormal
               ctrl.class(fp_class_neg_inf_c)    or ctrl.class(fp_class_pos_inf_c)    or -- infinity
               ctrl.class(fp_class_neg_inf_c)    or ctrl.class(fp_class_pos_inf_c)    or -- infinity
Line 1472... Line 1477...
      end case;
      end case;
    end if;
    end if;
  end process ctrl_engine;
  end process ctrl_engine;
 
 
  -- stop shifting when normalized --
  -- stop shifting when normalized --
  sreg.done <= (not or_reduce_f(sreg.upper(sreg.upper'left downto 1))) and sreg.upper(0); -- input is zero, hidden one is set
  sreg.done <= '1' when (or_reduce_f(sreg.upper(sreg.upper'left downto 1)) = '0') and (sreg.upper(0) = '1') else '0'; -- input is zero, hidden one is set
 
 
  -- all-zero including hidden bit --
  -- all-zero including hidden bit --
  sreg.zero <= not or_reduce_f(sreg.upper);
  sreg.zero <= '1' when (or_reduce_f(sreg.upper) = '0') else '0';
 
 
  -- result --
  -- result --
  result_o(31)           <= ctrl.res_sgn;
  result_o(31)           <= ctrl.res_sgn;
  result_o(30 downto 23) <= ctrl.res_exp;
  result_o(30 downto 23) <= ctrl.res_exp;
  result_o(22 downto  0) <= ctrl.res_man;
  result_o(22 downto  0) <= ctrl.res_man;
Line 1714... Line 1719...
            ctrl.state <= S_NORMALIZE_BUSY;
            ctrl.state <= S_NORMALIZE_BUSY;
          end if;
          end if;
 
 
        when S_NORMALIZE_BUSY => -- running normalization cycle
        when S_NORMALIZE_BUSY => -- running normalization cycle
        -- ------------------------------------------------------------
        -- ------------------------------------------------------------
          sreg.ext_s <= sreg.ext_s or or_reduce_f(sreg.mant(sreg.mant'left-2 downto 0)); -- sticky bit
          if (or_reduce_f(sreg.mant(sreg.mant'left-2 downto 0)) = '1') then
 
            sreg.ext_s <= '1'; -- sticky bit
 
          end if;
          if (or_reduce_f(ctrl.cnt(ctrl.cnt'left-1 downto 0)) = '0') then
          if (or_reduce_f(ctrl.cnt(ctrl.cnt'left-1 downto 0)) = '0') then
            if (ctrl.unsign = '0') then -- signed conversion
            if (ctrl.unsign = '0') then -- signed conversion
              ctrl.over <= ctrl.over or sreg.int(sreg.int'left); -- update overrun flag again to check for numerical overflow into sign bit
              ctrl.over <= ctrl.over or sreg.int(sreg.int'left); -- update overrun flag again to check for numerical overflow into sign bit
            end if;
            end if;
            ctrl.state <= S_ROUND;
            ctrl.state <= S_ROUND;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.