📄 fpu_mul.vhd
字号:
ex_c_oper <= "00000000001" & EX_MantB_1(9 to 15); ex_d_oper <= "00" & EX_MantB_1(16 to 31); ----------------------------------------------------------------------------- -- Stage 2 ----------------------------------------------------------------------------- ---------------------------------------- -- Stage_2_MEM_Mul_REG -- Perform cross multiplication ---------------------------------------- Using_RTL: if (C_TARGET = RTL) generate Stage_2_MEM_Mul_REG : process (Clk) is begin -- process Stage_2_MEM_Mul_REG if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) mem_prod_BD_2 <= (others => '0'); mem_prod_AD_2 <= (others => '0'); mem_prod_BC_2 <= (others => '0'); mem_prod_AC_2 <= (others => '0'); elsif (EX_PipeRun) then -- The flip flop in the MULT18x18S -- CE = EX_PipeRun -- R = Reset mem_prod_BD_2 <= std_logic_vector(signed(ex_b_oper) * signed(ex_d_oper)); mem_prod_AD_2 <= std_logic_vector(signed(ex_a_oper) * signed(ex_d_oper)); mem_prod_BC_2 <= std_logic_vector(signed(ex_b_oper) * signed(ex_c_oper)); mem_prod_AC_2 <= std_logic_vector(signed(ex_a_oper) * signed(ex_c_oper)); end if; end if; end process Stage_2_MEM_Mul_REG; end generate Using_RTL; Using_Hard_Mult18x18s: if (C_TARGET /= RTL) generate Mul_1_1 : MULT18x18S port map ( A => ex_b_oper, -- [in std_logic_vector(17 downto 0)] B => ex_d_oper, -- [in std_logic_vector(17 downto 0)] C => Clk, -- [in std_logic] CE => ex_PipeRun_i, -- [in std_logic] R => '0', -- [in std_logic] P => mem_prod_BD_2); -- [out std_logic_vector(35 downto 0)] Mul_1_2 : MULT18x18S port map ( A => ex_a_oper, -- [in std_logic_vector(17 downto 0)] B => ex_d_oper, -- [in std_logic_vector(17 downto 0)] C => Clk, -- [in std_logic] CE => ex_PipeRun_i, -- [in std_logic] R => '0', -- [in std_logic] P => mem_prod_AD_2); -- [out std_logic_vector(35 downto 0)] Mul_1_3 : MULT18x18S port map ( A => ex_b_oper, -- [in std_logic_vector(17 downto 0)] B => ex_c_oper, -- [in std_logic_vector(17 downto 0)] C => Clk, -- [in std_logic] CE => ex_PipeRun_i, -- [in std_logic] R => '0', -- [in std_logic] P => mem_prod_BC_2); -- [out std_logic_vector(35 downto 0)] Mul_1_4 : MULT18x18S port map ( A => ex_a_oper, -- [in std_logic_vector(17 downto 0)] B => ex_c_oper, -- [in std_logic_vector(17 downto 0)] C => Clk, -- [in std_logic] CE => ex_PipeRun_i, -- [in std_logic] R => '0', -- [in std_logic] P => mem_prod_AC_2); -- [out std_logic_vector(35 downto 0)] end generate Using_Hard_Mult18x18s; ----------------------------------------------------------------------------- -- Stage 3 ----------------------------------------------------------------------------- ---------------------------------------- -- Stage_3_MEM_Mul_REG -- Old name: Mul_Stage_2 -- Only keep the non-zero bits (BD, AD, BC) -- And bits that are used (AD) ---------------------------------------- Stage_3_MEM_Mul_REG : process (Clk) is begin -- process Stage_3_MEM_Mul_REG if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) mem_prod_BD_3 <= (others => '0'); mem_prod_AD_3 <= (others => '0'); mem_prod_BC_3 <= (others => '0'); mem_prod_AC_3 <= (others => '0'); else mem_prod_BD_3 <= mem_prod_BD_2(4 to 35); -- Upper 4 is always 0 mem_prod_AD_3 <= mem_prod_AD_2(12 to 35); -- Upper 12 is always 0 mem_prod_BC_3 <= mem_prod_BC_2(12 to 35); -- Upper 12 is always 0 mem_prod_AC_3 <= mem_prod_AC_2(20 to 35); -- Upper 20 is always 0 end if; end if; end process Stage_3_MEM_Mul_REG; ----------------------------------------------------------------------------- -- Stage 4 ----------------------------------------------------------------------------- ---------------------------------------- -- Stage_4_Mul_Res -- First add of results ---------------------------------------- Stage_4_Mul_Res : process (mem_prod_AC_3, mem_prod_AD_3, mem_prod_BD_3) is variable add1_temp1 : std_logic_vector(0 to 24); variable add1_temp2 : std_logic_vector(0 to 24); variable mul_4_bd_ad_i : std_logic_vector(0 to 24); variable add2_temp1 : std_logic_vector(0 to 25); variable add2_temp2 : std_logic_vector(0 to 25); begin -- process Stage_3_Mul_Res -- Lower part of BD is already correct, lowest 16 bit of the result mem_lower_4_cmb <= mem_prod_BD_3(20 to 35); -- Next 16 bit of the result is an addition of 3 part values -- 16 upper part of bd and then the 24 bits of ad and bc -- Need 25 bits for the temporary result to maintain the carry output add1_temp1 := "000000000" & mem_prod_BD_3(4 to 19); add1_temp2 := '0' & mem_prod_AD_3; mul_4_bd_ad_i := std_logic_vector(unsigned(add1_temp1) + unsigned(add1_temp2)); -- Add the other 24 bits from BC -- The result is now 26 bits to maintain the carry output add2_temp1 := '0' & mul_4_bd_ad_i; add2_temp2 := "00" & mem_prod_BC_3; mul_4_bd_bc_ad <= std_logic_vector(unsigned(add2_temp1) + unsigned(add2_temp2)); end process Stage_4_Mul_Res; ---------------------------------------- -- Stage_4_Mul_Add -- Multiplication Add results for Stage 4 ---------------------------------------- Stage_4_Mul_Add : process (Clk) is variable temp : std_logic; begin -- process Stage_4_Mul_Add if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) mem_lower_sticky_4 <= '0'; mem_prod_BD_BC_AD_4 <= (others => '0'); mem_prod_AC_4 <= (others => '0'); else -- Do a vector OR on the 16 least significant bits since these are -- always part of the sticky bit temp := '0'; for I in mem_lower_4_cmb'range loop temp := temp or mem_lower_4_cmb(I); end loop; -- I mem_lower_sticky_4 <= temp; mem_prod_BD_BC_AD_4 <= mul_4_bd_bc_ad; mem_prod_AC_4 <= mem_prod_AC_3; end if; end if; end process Stage_4_Mul_Add; ----------------------------------------------------------------------------- -- Stage 5 ----------------------------------------------------------------------------- ---------------------------------------- -- Stage_5_Sticky -- Calculate the sticky bit -- Only 5 more bits is needed for the sticky bit since the lower 16 bit has -- already been ORed into mem_lower_sticky_4 ---------------------------------------- Stage_5_Sticky : process (mem_lower_sticky_4, mem_prod_BD_BC_AD_4) is variable temp_sticky : std_logic; begin -- Stage_5_Sticky temp_sticky := mem_lower_sticky_4; for I in mem_prod_BD_BC_AD_4'right-4 to mem_prod_BD_BC_AD_4'right loop temp_sticky := temp_sticky or mem_prod_BD_BC_AD_4(I); end loop; -- I mem_mul_sticky_bit_5_cmb <= temp_sticky; end process Stage_5_Sticky; -- Calculate the result mantissa, need to add the upper 16 bit with the -- temporary result mem_prod_BD_BC_AD_4 -- the lower 16 bit of mem_prod_BD_BC_AD_4 is not needed since the -- mem_prod_AC_4 is shifted left 16 bits Final_Addition: process (mem_prod_AC_4, mem_prod_BD_BC_AD_4) is variable temp1 : std_logic_vector(0 to 16); variable temp2 : std_logic_vector(0 to 16); begin -- process Final_Addition temp1 := '0' & mem_prod_AC_4; temp2 := "0000000" & mem_prod_BD_BC_AD_4(0 to 9); mul_res_5_cmb_i <= std_logic_vector(unsigned(temp1) + unsigned(temp2)); end process Final_Addition; mul_res_5_cmb(16 to 26) <= mem_prod_BD_BC_AD_4(10 to 20); mul_res_5_cmb(0 to 15) <= mul_res_5_cmb_i(1 to 16); end generate Using_MULT18; ----------------------------------------------------------------------------- -- Shared end part among all different MUL implementations -- Determine if the result is >= 2.0 -- If true, shift right one bit and set mem_mul_inc_exp_5 ----------------------------------------------------------------------------- Stage_5_Mul_Calc : process (mul_res_5_cmb, mem_mul_sticky_bit_5_cmb) is constant MANT_LEN : natural := FPU_MANT_IGRS_TYPE'length; begin -- process Stage_5_Mul_Calc if (mul_res_5_cmb(mul_res_5_cmb'left) = '0') then -- MSb is 0, then second bit is 1 -- mul_res_5_cmb(1) = '1' -- Use bits 1-26 of result mem_mul_res_5_cmb(FPU_MANT_IGRS_TYPE'left to FPU_MANT_IGRS_TYPE'right-1) <= mul_res_5_cmb(mul_res_5_cmb'left+1 to mul_res_5_cmb'left+MANT_LEN-1); mem_mul_res_5_cmb(FPU_MANT_STICKY_POS) <= mem_mul_sticky_bit_5_cmb; mem_mul_inc_exp_5_cmb <= false; else -- mul_res_5_cmb(0) = '1' -- Use bits 0-25 of result mem_mul_res_5_cmb(FPU_MANT_IGRS_TYPE'left to FPU_MANT_IGRS_TYPE'right-1) <= mul_res_5_cmb(mul_res_5_cmb'left to mul_res_5_cmb'left+MANT_LEN-2); mem_mul_res_5_cmb(FPU_MANT_STICKY_POS) <= mul_res_5_cmb(mul_res_5_cmb'left+MANT_LEN-1) or mem_mul_sticky_bit_5_cmb; mem_mul_inc_exp_5_cmb <= true; end if; end process Stage_5_Mul_Calc; ---------------------------------------- -- Non-registered outputs ---------------------------------------- -- Increment exponent MEM_Mul_Inc_Exp_4 <= mem_mul_inc_exp_5_cmb; -- Multiplier result MEM_Mul_Res_4 <= mem_mul_res_5_cmb;end architecture IMP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -