📄 div_unit.vhd
字号:
--SINGLE_FILE_TAG--------------------------------------------------------------------------------- $Id: div_unit.vhd,v 1.1 2007/10/12 09:11:36 stefana Exp $--------------------------------------------------------------------------------- Div_unit - entity/architecture----------------------------------------------------------------------------------- ****************************-- ** Copyright Xilinx, Inc. **-- ** All rights reserved. **-- ****************************----------------------------------------------------------------------------------- Filename: div_unit.vhd-- Version: v1.00a-- Description: Implements a 32x32 = 32 multiplier-- --------------------------------------------------------------------------------- Structure: -- div_unit.vhd----------------------------------------------------------------------------------- Author: goran-- History:-- goran 2001-03-05 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;--------------------------------------------------------------------------------- Port declarations-------------------------------------------------------------------------------entity Div_unit is generic ( C_TARGET : TARGET_FAMILY_TYPE; C_DATA_SIZE : natural range 8 to 64 := 32 ); port ( Clk : in std_logic; Reset : in boolean; OF_PipeRun : in boolean; Start_Div : in std_logic; Not_Div_Op : in std_logic; Reg_Zero : in std_logic; Unsigned_op : in std_logic; Op1 : in std_logic_vector(0 to C_DATA_SIZE-1); Op2 : in std_logic_vector(0 to C_DATA_SIZE-1); Div_Result : out std_logic_vector(0 to C_DATA_SIZE-1); Div_By_Zero : out std_logic; Div_Done : out std_logic := '0' );end Div_unit;--------------------------------------------------------------------------------- Architecture section-------------------------------------------------------------------------------library Unisim;use Unisim.vcomponents.all;architecture IMP of Div_unit is signal Rst : std_logic; signal CE : std_logic;--------------------------------------------------------------------------------- Begin architecture------------------------------------------------------------------------------- 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) := (others => '0'); signal new_Q : std_logic_vector(0 to C_DATA_SIZE); signal diff : std_logic_vector(0 to C_DATA_SIZE); signal next_sub : std_logic; signal sign : std_logic; signal div_result_is_zero : std_logic; signal reset_Q : std_logic; signal div_count : std_logic := '0'; signal Res_Neg : std_logic; signal Last_Cycle : std_logic; begin -- IMP Rst <= '1' when Reset else '0'; CE <= '1'; Using_RTL: if (C_TARGET = RTL) generate signal Index : natural range 0 to 36; begin diff <= std_logic_vector(unsigned(R) - unsigned(D)) when next_sub = '1' else std_logic_vector(unsigned(R) + unsigned(D)); div_result_is_zero <= Reg_Zero; reset_Q <= '1' when reset else div_result_is_zero or Not_Div_Op; Div_Count <= '1' when (Index > 0) else '0'; Res_Neg <= diff(diff'left); Last_Cycle <= '1' when Index = 1 else '0'; Handle_new_Q : process (Start_Div, Q, Op2, Div_Count, Res_Neg, Last_Cycle, Sign) is begin -- process Handle_new_Q new_Q <= Q; if (Start_Div = '1') then if (Op2(Op2'left) = '1') and (Unsigned_op = '0') then new_Q(new_Q'left to new_Q'right-1) <= std_logic_vector(unsigned(not Op2) + 1); new_Q(new_Q'right) <= '0'; else new_Q <= Op2 & '0'; end if; elsif (Last_Cycle = '1') then if (sign = '1') and (Unsigned_op = '0') 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_Count = '1') then new_Q <= Q(Q'left+1 to Q'right) & not Res_Neg; end if; end process Handle_new_Q; Handle_Q : process (Clk) is begin -- process Handle_Q if Clk'event and Clk = '1' then -- rising clock edge if (Reset_Q = '1') then Q <= (others => '0'); elsif (Div_Count = '1') or (Start_Div = '1') then Q <= new_Q(new_Q'left to new_Q'right); end if; end if; end process Handle_Q; Div_Result <= Q(Q'left to Q'right-1); Handle_R : process (Clk) is begin -- process Handle_R if Clk'event and Clk = '1' then -- rising clock edge if (Start_Div = '1') then R <= (others => '0'); R(R'right) <= new_Q(new_Q'left); elsif (div_count = '1') then R <= diff(diff'left+1 to diff'right) & new_Q(new_Q'left); end if; end if; end process Handle_R; Handle_D : process (Clk) is begin -- process Handle_D if Clk'event and Clk = '1' then -- rising clock edge if (Start_Div = '1') then if (Op1(Op1'left) = '1') and (Unsigned_op = '0') then D <= std_logic_vector(unsigned(not Op1) + 1); else D <= '0' & Op1; end if; end if; end if; end process Handle_D; Next_Sub_DFF : process (Clk) is begin -- process Next_Sub_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then next_sub <= '1'; else if (Start_Div = '1') then next_sub <= '1'; elsif (div_count = '1') then next_sub <= not Res_Neg; end if; end if; end if; end process Next_Sub_DFF; Div_Handle : process (Clk) is begin -- process Div_Handle if Clk'event and Clk = '1' then -- rising clock edge if Reset then Index <= 0; Div_By_Zero <= '0'; Div_Done <= '0'; Sign <= '0'; else if (OF_PipeRun) then Div_By_Zero <= '0'; end if; if (Index > 0) then Index <= Index - 1; end if; Div_Done <= '0'; if (Start_Div = '1') then if Reg_Zero = '0' then Index <= 33; else Div_By_Zero <= '1'; Div_Done <= '1'; end if; Sign <= Op2(Op2'left) xor Op1(Op1'left); end if; if (Index = 1) then Div_Done <= '1'; end if; end if; end if; end process Div_Handle; end generate Using_RTL; Using_FPGA : if (C_TARGET /= RTL) generate -- signal Index : natural range 0 to 36; signal Diff_Carry : std_logic_vector(0 to C_DATA_SIZE+1); signal Diff_Sel : std_logic_vector(0 to C_DATA_SIZE); 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; signal Start_Div_1 : std_logic; signal Start_Div_16 : std_logic; signal Start_Div_31 : std_logic; signal Start_Div_32 : std_logic; begin ---------------------------------------------------------------------------- -- Implement the diff ---------------------------------------------------------------------------- Diff_Carry(Diff_Carry'right) <= next_sub;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -