📄 mul_unit.vhd
字号:
ex_PipeRun_i <= '1' when EX_PipeRun else '0'; mem_PipeRun_i <= '1' when MEM_PipeRun else '0'; -- Sign bits Using_Mul64_1 : if (C_USE_MUL64) generate ex_sign_A <= '0' when EX_Mulhu_Instr else EX_Op1(EX_Op1'left); ex_sign_C <= '0' when EX_Mulhu_Instr or EX_Mulhsu_Instr else EX_Op2(EX_Op2'left); ---------------------------------------- -- MEM_Mul64_Instr_PROCESS -- MEM stage instruction ---------------------------------------- MEM_Mul64_Instr_PROCESS : process (Clk) is begin -- process MEM_Instr if Clk'event and Clk = '1' then if Reset = '1' then mem_mulh_Instr <= false; mem_mulhu_Instr <= false; elsif (EX_PipeRun) then mem_mulh_Instr <= EX_Mulh_Instr or EX_Mulhsu_Instr; mem_mulhu_Instr <= EX_Mulhu_Instr; end if; end if; end process MEM_Mul64_Instr_PROCESS; mem_mul64_instr <= mem_mulhu_Instr or mem_mulh_Instr; mem_PipeRun_and_not_mul64_op <= '0' when not(MEM_Not_Mul_Op) and mem_mul64_instr else '1'; mem_PipeRun_and_not_mul32_op <= '0' when not(MEM_Not_Mul_Op) and not(mem_mul64_instr) else '1'; end generate Using_Mul64_1; No_Mul64_1 : if (not C_USE_MUL64) generate ex_sign_A <= EX_Op1(EX_Op1'left); ex_sign_C <= EX_Op2(EX_Op2'left); mem_PipeRun_and_not_mul_op <= '0' when not(MEM_Not_Mul_Op) else '1'; end generate No_Mul64_1; --------------------------------------------------------------------------- -- The target architecture does NOT have DSP48 hard blocks --------------------------------------------------------------------------- Using_MULT18x18_Architecture : if (not DSP48_ARCHITECTURE) generate -- Sign extend the upper bits -- Zero fill the lower bits ex_a_oper <= ex_sign_A & ex_sign_A & EX_Op1(DATA_UPPER_HW); ex_b_oper <= "00" & EX_Op1(DATA_LOWER_HW); ex_c_oper <= ex_sign_C & ex_sign_C & EX_Op2(DATA_UPPER_HW); ex_d_Oper <= "00" & EX_Op2(DATA_LOWER_HW); Using_RTL : if C_TARGET = RTL generate ---------------------------------------- -- Mult_BD -- B * D ---------------------------------------- Mult_BD : process (Clk) is begin -- process Mult_BD if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) mem_prod_BD <= (others => '0'); elsif (EX_PipeRun) then mem_prod_BD <= std_logic_vector(signed(ex_b_oper) * signed(ex_d_oper)); end if; end if; end process Mult_BD; ---------------------------------------- -- Mult_AD -- A * D ---------------------------------------- Mult_AD : process (Clk) is begin -- process Mult_AD if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) mem_prod_AD <= (others => '0'); elsif (EX_PipeRun) then mem_prod_AD <= std_logic_vector(signed(ex_a_oper) * signed(ex_d_oper)); end if; end if; end process Mult_AD; ---------------------------------------- -- Mult_BC -- B * C ---------------------------------------- Mult_BC : process (Clk) is begin -- process Mult_BC if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) mem_prod_bc <= (others => '0'); elsif (EX_PipeRun) then mem_prod_bc <= std_logic_vector(signed(ex_b_oper) * signed(ex_c_oper)); end if; end if; end process Mult_BC; end generate Using_RTL; Using_FPGA : if C_TARGET /= RTL generate ---------------------------------------- -- Mult_BD -- B * D ---------------------------------------- MULT18x18S_BD : 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 => reset, -- [in std_logic] P => mem_prod_BD); -- [out std_logic_vector(35 downto 0)] ---------------------------------------- -- Mult_AD -- A * D ---------------------------------------- MULT18x18S_AD : 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 => reset, -- [in std_logic] P => mem_prod_AD); -- [out std_logic_vector(35 downto 0)] ---------------------------------------- -- Mult_BC -- B * C ---------------------------------------- MULT18x18S_BC : 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 => reset, -- [in std_logic] P => mem_prod_BC); -- [out std_logic_vector(35 downto 0)] end generate Using_FPGA; -- For 32-bit result the lower 16-bits of A*D + B*C -- are used for the upper 16-bits of the result mem_prod_AD_plus_BC_I <= std_logic_vector(signed('0' & mem_prod_AD(MUL_RES_LOWER_HW)) + signed('0' & mem_prod_BC(MUL_RES_LOWER_HW))); mem_prod_BD_plus_AD_plus_BC <= std_logic_vector(signed('0' & mem_prod_AD_plus_BC_I(1 to 16)) + signed('0' & mem_prod_BD(4 to 19))); Using_Mul64_2 : if (C_USE_MUL64) generate signal wb_prod_BD_plus_AD_plus_BC_Carry : std_logic; begin Using_RTL : if C_TARGET = RTL generate ---------------------------------------- -- Mult_AC -- A * C ---------------------------------------- Mult_AC : process (Clk) is begin -- process Mult_AC if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) mem_prod_AC <= (others => '0'); elsif (EX_PipeRun) then mem_prod_AC <= std_logic_vector(signed(ex_a_oper) * signed(ex_c_oper)); end if; end if; end process Mult_AC; end generate Using_RTL; Using_FPGA : if C_TARGET /= RTL generate ---------------------------------------- -- Mult_AC -- A * C ---------------------------------------- MULT18x18S_AC : 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 => reset, -- [in std_logic] P => mem_prod_AC); -- [out std_logic_vector(35 downto 0)] end generate Using_FPGA; ---------------------------------------- -- Prod_BD_DFF -- WB stage -- Take bits 4-35 of B*D for the 32-bit result ---------------------------------------- Prod_BD_DFF : process (Clk) is begin -- process Prod_BD_DFF if Clk'event and Clk = '1' then -- rising clock edge if mem_PipeRun_and_not_mul32_op = '1' then wb_prod_BD <= (others => '0'); elsif (MEM_PipeRun) then wb_prod_BD <= mem_prod_BD(MUL_RES_WORD); end if; -- MEM_PipeRun end if; end process Prod_BD_DFF; ---------------------------------------- -- Prod_BD_Plus_AD_Plus_BC_DFF -- WB stage AD+BC ---------------------------------------- Prod_BD_Plus_AD_Plus_BC_DFF : process (Clk) is begin -- process Prod_BD_Plus_AD_Plus_BC_DFF if Clk'event and Clk = '1' then -- rising clock edge if mem_PipeRun_and_not_mul32_op = '1' then wb_prod_BD_plus_AD_plus_BC <= (others => '0'); elsif (MEM_PipeRun) then wb_prod_BD_plus_AD_plus_BC <= mem_prod_BD_plus_AD_plus_BC; end if; -- MEM_PipeRun end if; end process Prod_BD_Plus_AD_Plus_BC_DFF; -- For upper 32 bits of 64-bit result the upper 20-bits of A*D + B*C and -- carry of A*D + B*C are used for bits 8-27 of the upper 32-bits of the result Prod_AD_plus_BC_high_Adder: process (mem_prod_AD_plus_BC_I, mem_prod_AD, mem_prod_BC) is variable Carry : std_logic_vector(mem_prod_AD_plus_BC_high_I'range); begin -- process Prod_AD_plus_BC_high_Adder Carry := (others => '0'); Carry(Carry'right) := mem_prod_AD_plus_BC_I(0); mem_prod_AD_plus_BC_high_I <= std_logic_vector(signed(mem_prod_AD(0 to 19)) + signed(mem_prod_BC(0 to 19)) + signed(Carry)); end process Prod_AD_plus_BC_high_Adder; ---------------------------------------- -- Prod_AC_DFF -- WB stage -- Take bits 4-35 of A*C for the 32-bit MSW result ---------------------------------------- Prod_AC_DFF : process (Clk) is begin -- process Prod_AC_DFF if Clk'event and Clk = '1' then -- rising clock edge if mem_PipeRun_and_not_mul64_op = '1' then wb_prod_AC <= (others => '0'); elsif (MEM_PipeRun) then wb_prod_AC <= mem_prod_AC(4 to 35); -- Only 32 bits needed end if; -- MEM_PipeRun end if; end process Prod_AC_DFF; ---------------------------------------- -- Prod_AD_Plus_BC_high_DFF -- WB stage AD+BC ---------------------------------------- Prod_AD_Plus_BC_high_DFF : process (Clk) is begin -- process Prod_AD_Plus_BC_high_DFF if Clk'event and Clk = '1' then -- rising clock edge if mem_PipeRun_and_not_mul64_op = '1' then wb_prod_BD_plus_AD_plus_BC_Carry <= '0'; wb_prod_AD_plus_BC_high <= (others => '0'); elsif (MEM_PipeRun) then wb_prod_BD_plus_AD_plus_BC_Carry <= mem_prod_BD_plus_AD_plus_BC(0); if mem_mulhu_instr then wb_prod_AD_plus_BC_high <=
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -