📄 div_unit_gti.vhd
字号:
Using_FPGA : if (C_TARGET /= RTL) generate signal D_Carry : std_logic_vector(0 to C_DATA_SIZE); signal D_Sel : std_logic_vector(0 to C_DATA_SIZE-1); signal D_I : std_logic_vector(0 to C_DATA_SIZE-1); signal New_Q_Carry : std_logic_vector(0 to C_DATA_SIZE); signal New_Q_Sel : std_logic_vector(0 to C_DATA_SIZE-1); signal New_Q_DI : std_logic_vector(0 to C_DATA_SIZE-1); signal New_Q_Invert : std_logic; signal New_Q_Use_Op2 : std_logic; begin ----------------------------------------------------------------------------- -- The D register -- Just loaded with ABS(EX_Op1), never changes during the iteration ----------------------------------------------------------------------------- D_Carry(C_DATA_SIZE) <= EX_Op1(EX_Op1'left) when not EX_Div_Unsigned else '0'; D_Handle : for I in C_DATA_SIZE-1 downto 0 generate D_Sel(I) <= EX_Op1(I) xor EX_Op1(EX_Op1'left) when not EX_Div_Unsigned else EX_Op1(I); D_MUXCY_L : MUXCY_L port map ( DI => '0', -- [in std_logic] CI => D_Carry(I+1), -- [in std_logic] S => D_Sel(I), -- [in std_logic] LO => D_Carry(I)); -- [out std_logic] D_XORCY : XORCY port map ( LI => D_Sel(I), -- [in std_logic] CI => D_Carry(I+1), -- [in std_logic] O => D_I(I)); -- [out std_logic] end generate D_Handle; Handle_D : process (Clk) is begin -- process Handle_D if Clk'event and Clk = '1' then -- rising clock edge if (EX_Start_Div) then D <= D_I; end if; end if; end process Handle_D; ----------------------------------------------------------------------------- -- Create the logic for New_Q -- -- Oper New_Q Start_Div Op2(MSB) Last_Cycle Sign -- 00 Op2 1 0 - - -- 01 not(Op2) + 1 1 1 - - -- 10 Q << 1 0 - 1 0 -- 11 not(Q<<1) + 1 0 - 1 1 -- -- Start_Div Op2(MSB) Last_Cycle Sign Div_Count Oper -- 1 0 - - - 00 -- 1 1 - - - 01 -- 0 - 1 0 - 10 -- 0 - 1 1 - 11 -- 0 - 0 - 1 10 -- -- -- Op2, Q -- Use_Op2,Invert 00 01 11 10 -- 00 0 1 1 0 = 1010 -- 01 1 0 0 1 = 0101 -- 11 1 1 0 0 = 0011 -- 10 0 0 1 1 = 1100 -- INIT = 0011 1100 0101 1010 = 3C5A ----------------------------------------------------------------------------- New_Q(C_DATA_SIZE) <= '1' when div_busy and res_neg = '0' else '0'; New_Q_Carry(C_DATA_SIZE) <= '1' when ((not EX_Div_Unsigned) and EX_Start_Div and (EX_Op2(EX_Op2'left) = '1')) or (Last_Cycle and make_result_neg) else '0'; New_Q_Use_Op2 <= '1' when EX_Start_Div else '0'; New_Q_Invert <= New_Q_Carry(C_DATA_SIZE); New_Q_Handle : for I in C_DATA_SIZE-1 downto 0 generate -- New_Q_Sel(I) <= Op2(I) xor New_Q_Invert when New_Q_Use_Op2 = '1' else Q(I+1) xor New_Q_Invert; New_Q_LUT4 : LUT4 generic map ( INIT => X"3C5A") -- [bit_vector] port map ( O => New_Q_Sel(I), -- [out std_logic] I0 => Q(I+1), -- [in std_logic] I1 => EX_Op2(I), -- [in std_logic] I2 => New_Q_Invert, -- [in std_logic] I3 => New_Q_Use_Op2); -- [in std_logic] New_Q_MUXCY_L : MUXCY_L port map ( DI => '0', -- [in std_logic] CI => New_Q_Carry(I+1), -- [in std_logic] S => New_Q_Sel(I), -- [in std_logic] LO => New_Q_Carry(I)); -- [out std_logic] New_Q_XORCY : XORCY port map ( LI => New_Q_Sel(I), -- [in std_logic] CI => New_Q_Carry(I+1), -- [in std_logic] O => New_Q(I)); -- [out std_logic] end generate New_Q_Handle; end generate Using_FPGA; ----------------------------------------------------------------------------- -- Register holding the result ----------------------------------------------------------------------------- Handle_Q : process (Clk) is begin -- process Handle_Q if Clk'event and Clk = '1' then -- rising clock edge if (Reset_Q) then Q <= (others => '0'); elsif (div_busy or EX_Start_Div) then Q <= new_Q(new_Q'left to new_Q'right); end if; end if; end process Handle_Q; MEM_Div_Result <= Q(Q'left to Q'right-1); ----------------------------------------------------------------------------- -- Determine of next iteration should be an addition or subtraction -- Always start with an addition ----------------------------------------------------------------------------- Next_Sub_DFF : process (Clk) is begin -- process Next_Sub_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) next_sub <= '1'; else if (EX_Start_Div) then next_sub <= '1'; -- Start with a subtraction elsif div_busy then next_sub <= not diff(diff'left); end if; end if; end if; end process Next_Sub_DFF; Mem_Div_Stall_Calc : process (Clk) is begin -- process Mem_Div_Stall_Calc if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) mem_div_stall_i <= false; else if (EX_PipeRun) then mem_div_stall_i <= div_iterations_early; if (EX_Start_Div) then mem_div_stall_i <= not EX_Op1_Zero; end if; end if; if (mem_div_stall_i) then mem_div_stall_i <= div_iterations_early; end if; end if; end if; end process Mem_Div_Stall_Calc; MEM_Div_Stall <= mem_div_stall_i; ----------------------------------------------------------------------------- -- Use a shifter as the counter so that a SRL16 will be implemented as the counter ----------------------------------------------------------------------------- div_counter: process (Clk) begin -- process div_counter if Clk'event and Clk = '1' then -- rising clock edge cnt_shifts(cnt_shifts'left to cnt_shifts'right-1) <= cnt_shifts(cnt_shifts'left+1 to cnt_shifts'right); if EX_Start_Div and not EX_Op1_Zero then cnt_shifts(cnt_shifts'right) <= '1'; else cnt_shifts(cnt_shifts'right) <= '0'; end if; end if; end process div_counter; div_count_is_2 <= (cnt_shifts(cnt_shifts'left) = '1'); ------------------------------------------------------------------------------ -- Controlling the division, counting the iterations ------------------------------------------------------------------------------- Div_Handle : process (Clk) is begin -- process Div_Handle if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) make_result_neg <= false; div_busy <= false; div_iterations_early <= false; Last_Cycle <= false; mem_last_cycle <= false; else Last_Cycle <= false; if (EX_Start_Div) then div_iterations_early <= not EX_Op1_Zero; div_busy <= not EX_Op1_Zero; make_result_neg <= (not EX_Div_Unsigned) and ((EX_Op2(EX_Op2'left) xor EX_Op1(EX_Op1'left)) = '1'); else div_busy <= div_iterations_early; if (div_count_is_2) then Last_Cycle <= true; div_iterations_early <= false; end if; end if; if (EX_Start_Div) then mem_last_cycle <= false; elsif (last_cycle) then mem_last_cycle <= true; end if; end if; end if; end process Div_Handle; ----------------------------------------------------------------------------- -- Exception handling ----------------------------------------------------------------------------- Div_by_Zero : process (Clk) is begin -- process Div_by_Zero if Clk'event and Clk = '1' then -- rising clock edge if Reset = '1' then -- synchronous reset (active high) MEM_Div_By_Zero <= false; ex_hold_div_by_zero <= false; else if (EX_Start_Div) then if (EX_PipeRun) then MEM_Div_By_Zero <= EX_Op1_Zero; ex_hold_div_by_zero <= false; else ex_hold_div_by_zero <= EX_Op1_Zero; end if; else if (EX_PipeRun) then MEM_Div_By_Zero <= ex_hold_div_by_zero; ex_hold_div_by_zero <= false; end if; end if; end if; end if; end process Div_by_Zero;end IMP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -