📄 div_unit_gti.vhd
字号:
--------------------------------------------------------------------------------- $Id: div_unit_gti.vhd,v 1.2 2007/11/21 13:48:22 stefana Exp $--------------------------------------------------------------------------------- div_unit_gti.vhd - Entity and architecture---- ***************************************************************************-- ** Copyright(C) 2003 by Xilinx, Inc. All rights reserved. **-- ** **-- ** This text contains proprietary, confidential **-- ** information of Xilinx, Inc. , is distributed by **-- ** under license from Xilinx, Inc., and may be used, **-- ** copied and/or disclosed only pursuant to the terms **-- ** of a valid license agreement with Xilinx, Inc. **-- ** **-- ** Unmodified source code is guaranteed to place and route, **-- ** function and run at speed according to the datasheet **-- ** specification. Source code is provided "as-is", with no **-- ** obligation on the part of Xilinx to provide support. **-- ** **-- ** Xilinx Hotline support of source code IP shall only include **-- ** standard level Xilinx Hotline support, and will only address **-- ** issues and questions related to the standard released Netlist **-- ** version of the core (and thus indirectly, the original core source). **-- ** **-- ** The Xilinx Support Hotline does not have access to source **-- ** code and therefore cannot answer specific questions related **-- ** to source HDL. The Xilinx Support Hotline will only be able **-- ** to confirm the problem in the Netlist version of the core. **-- ** **-- ** This copyright and support notice must be retained as part **-- ** of this text at all times. **-- ***************************************************************************----------------------------------------------------------------------------------- Filename: div_unit_gti.vhd---- Description: -- -- VHDL-Standard: VHDL'93--------------------------------------------------------------------------------- Structure: -- div_unit_gti.vhd----------------------------------------------------------------------------------- Author: goran-- Revision: $Revision: 1.2 $-- Date: $Date: 2007/11/21 13:48:22 $---- History:-- goran 2005-10-18 First Version----------------------------------------------------------------------------------- Naming Conventions:-- active low signals: "*_n"-- clock signals: "clk", "clk_div#", "clk_#x" -- reset signals: "rst", "rst_n" -- generics: "C_*" -- user defined types: "*_TYPE" -- state machine next state: "*_ns" -- state machine current state: "*_cs" -- combinatorial signals: "*_com" -- pipelined or register delay signals: "*_d#" -- counter signals: "*cnt*"-- clock enable signals: "*_ce" -- internal version of output port "*_i"-- device pins: "*_pin" -- ports: - Names begin with Uppercase -- processes: "*_PROCESS" -- component instantiations: "<ENTITY_>I_<#|FUNC>-------------------------------------------------------------------------------library IEEE;use IEEE.std_logic_1164.all;use IEEE.numeric_std.all;library Microblaze_v7_10_a;use Microblaze_v7_10_a.MicroBlaze_Types.all;library unisim;use unisim.vcomponents.all;--------------------------------------------------------------------------------- Port declarations-------------------------------------------------------------------------------entity Div_unit_gti is generic ( C_TARGET : TARGET_FAMILY_TYPE; -- Device family C_DATA_SIZE : natural range 8 to 64 := 32 ); port ( Clk : in std_logic; Reset : in std_logic; OF_PipeRun : in boolean; EX_PipeRun : in boolean; EX_Start_Div : in boolean; EX_Op1_Zero : in boolean; EX_Div_Unsigned : in boolean; EX_Op1 : in std_logic_vector(0 to C_DATA_SIZE-1); EX_Op2 : in std_logic_vector(0 to C_DATA_SIZE-1); MEM_Is_Div_Instr: in boolean; MEM_Div_Result : out std_logic_vector(0 to C_DATA_SIZE-1); MEM_Div_By_Zero : out boolean; MEM_Div_Stall : out boolean );end Div_unit_gti;--------------------------------------------------------------------------------- Architecture section-------------------------------------------------------------------------------architecture IMP of Div_unit_gti is signal R : std_logic_vector(0 to C_DATA_SIZE) := (others => '0'); signal Q : std_logic_vector(0 to C_DATA_SIZE); signal D : std_logic_vector(0 to C_DATA_SIZE-1) := (others => '0'); signal new_Q : std_logic_vector(0 to C_DATA_SIZE); signal diff : std_logic_vector(0 to C_DATA_SIZE); signal Res_Neg : std_logic; signal next_sub : std_logic; signal make_result_neg : boolean; signal reset_Q : boolean; signal cnt_shifts : std_logic_vector(0 to 31) := (others => '0'); signal div_busy : boolean; signal div_iterations_early : boolean; signal div_count_is_2 : boolean; signal last_cycle : boolean; signal mem_last_cycle : boolean; signal Index : natural range 0 to 36; signal mem_div_stall_i : boolean; signal ex_hold_div_by_zero : boolean; begin -- IMP -- Need to clear the result on reset or if the ex_op1 is 0 or -- this is not a valid divide instruction. Reseting_div_output: process (EX_Op1_Zero, EX_Start_Div, Reset, mem_last_cycle, MEM_Is_Div_Instr) is begin -- process Reseting_div_output -- Need to reset when MicroBlaze is resetting if (Reset = '1') then reset_Q <= true; -- Need to reset when the div_result is Zero elsif (EX_Op1_Zero and EX_Start_Div) then reset_Q <= true; -- Need to reset when the div_result is done and the pipe will move so that -- the next clock cycle we are driving '0' from this unit. elsif (mem_last_cycle) and MEM_Is_Div_Instr then reset_Q <= true; -- This is when a division is in progress else reset_Q <= false; end if; end process Reseting_div_output; ----------------------------------------------------------------------------- -- The R register -- Is loaded with ABS(EX_Op2) on start of division -- During the iteration, the add/sub result is shifted in with one bit -- for the Q register ----------------------------------------------------------------------------- Handle_R : process (Clk) is begin -- process Handle_R if Clk'event and Clk = '1' then -- rising clock edge if (EX_Start_Div) then R <= (others => '0'); R(R'right) <= new_Q(new_Q'left); elsif (div_busy) then R <= diff(diff'left+1 to diff'right) & new_Q(new_Q'left); end if; end if; end process Handle_R; ------------------------------------------------------------------------------- -- The add/sub unit which R +- D, -- subtract if previous iteration result was positive -- and add if it was negative ------------------------------------------------------------------------------- diff <= std_logic_vector(unsigned(R) - unsigned('0' & D)) when next_sub = '1' else std_logic_vector(unsigned(R) + unsigned('0' & D)); -- msb of result shows if the result was negative or positive Res_Neg <= diff(diff'left); ----------------------------------------------------------------------------- -- RTL part of the code ----------------------------------------------------------------------------- Using_RTL : if (C_TARGET = RTL) generate begin ----------------------------------------------------------------------------- -- The D register -- Just loaded with ABS(EX_Op1), never changes during the iteration ----------------------------------------------------------------------------- Handle_D : process (Clk) is begin -- process Handle_D if Clk'event and Clk = '1' then -- rising clock edge if (EX_Start_Div) then if (EX_Op1(EX_Op1'left) = '1') and (not EX_Div_Unsigned) then D <= std_logic_vector(unsigned(not EX_Op1) + 1); else D <= EX_Op1; end if; end if; end if; end process Handle_D; ----------------------------------------------------------------------------- -- Combined unit for multiple purposes since this can be merge into a 1 -- LUT/bit implementation -- 1. On start of division, calculate ABS(EX_Op2) -- 2. During the iteration (except last cycle) shift in 1 bit of result -- 3. Last cycle generate right sign value if the division is signed ----------------------------------------------------------------------------- Handle_new_Q : process (EX_Div_Unsigned, EX_Op2, EX_Start_Div, Q, Res_Neg, div_busy, last_cycle, make_result_neg, new_Q) is begin -- process Handle_new_Q new_Q <= Q; if (EX_Start_Div) then if (EX_Op2(EX_Op2'left) = '1') and (not EX_Div_Unsigned) then new_Q(new_Q'left to new_Q'right-1) <= std_logic_vector(unsigned(not EX_Op2) + 1); new_Q(new_Q'right) <= '0'; else new_Q <= EX_Op2 & '0'; end if; elsif (last_cycle) then if (make_result_neg) then new_Q(new_Q'left to new_Q'right-1) <= std_logic_vector(unsigned(not Q(Q'left+1 to Q'right)) + 1); new_Q(new_Q'right) <= '0'; else new_Q(new_Q'left to new_Q'right-1) <= Q(Q'left+1 to Q'right); new_Q(new_Q'right) <= '0'; end if; elsif (div_busy) then new_Q <= Q(Q'left+1 to Q'right) & not Res_Neg; end if; end process Handle_new_Q; end generate Using_RTL; ----------------------------------------------------------------------------- -- FPGA version of the code -----------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -