URL
https://opencores.org/ocsvn/pcie_sg_dma/pcie_sg_dma/trunk
Subversion Repositories pcie_sg_dma
[/] [pcie_sg_dma/] [trunk/] [rtl/] [DMA_Calculate.vhd] - Rev 2
Compare with Previous | Blame | View Log
---------------------------------------------------------------------------------- -- Company: ziti, Uni. HD -- Engineer: wgao -- -- Design Name: -- Module Name: DMA_Calculate - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision 1.00 - first release. 09.02.2007 -- -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; library work; use work.abb64Package.all; -- Uncomment the following library declaration if instantiating -- any Xilinx primitives in this code. --library UNISIM; --use UNISIM.VComponents.all; entity DMA_Calculate is port ( -- Downstream Registers from MWr Channel DMA_PA : IN std_logic_vector(C_DBUS_WIDTH-1 downto 0); -- EP (local) DMA_HA : IN std_logic_vector(C_DBUS_WIDTH-1 downto 0); -- Host (remote) DMA_BDA : IN std_logic_vector(C_DBUS_WIDTH-1 downto 0); DMA_Length : IN std_logic_vector(C_DBUS_WIDTH-1 downto 0); DMA_Control : IN std_logic_vector(C_DBUS_WIDTH-1 downto 0); -- Calculation in advance, for better timing HA_is_64b : IN std_logic; BDA_is_64b : IN std_logic; -- Calculation in advance, for better timing Leng_Hi19b_True : IN std_logic; Leng_Lo7b_True : IN std_logic; -- Parameters fed to DMA_FSM DMA_PA_Loaded : OUT std_logic_vector(C_DBUS_WIDTH-1 downto 0); DMA_PA_Var : OUT std_logic_vector(C_DBUS_WIDTH-1 downto 0); DMA_HA_Var : OUT std_logic_vector(C_DBUS_WIDTH-1 downto 0); DMA_BDA_fsm : OUT std_logic_vector(C_DBUS_WIDTH-1 downto 0); BDA_is_64b_fsm : OUT std_logic; DMA_0_Leng : OUT std_logic; DMA_Snout_Length : OUT std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto 0); DMA_Body_Length : OUT std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto 0); DMA_Tail_Length : OUT std_logic_vector(C_TLP_FLD_WIDTH_OF_LENG+1 downto 0); -- Only for downstream channel DMA_PA_Snout : OUT std_logic_vector(C_DBUS_WIDTH-1 downto 0); DMA_BAR_Number : OUT std_logic_vector(C_ENCODE_BAR_NUMBER-1 downto 0); -- Engine control signals DMA_Start : IN std_logic; DMA_Start2 : IN std_logic; -- out of consecutive dex -- Control signals to FSM No_More_Bodies : OUT std_logic; -- No more block(s) of Max_Size ThereIs_Snout : OUT std_logic; -- 1st packet before Body blocks ThereIs_Body : OUT std_logic; -- Block(s) of Max_Size ThereIs_Tail : OUT std_logic; -- Last packet with size less than Max_Size ThereIs_Dex : OUT std_logic; -- Not the last descriptor HA64bit : OUT std_logic; -- Host Address is 64-bit Addr_Inc : OUT std_logic; -- Peripheral Address increase token -- FSM indicators State_Is_LoadParam : IN std_logic; State_Is_Snout : IN std_logic; State_Is_Body : IN std_logic; -- State_Is_Tail : IN std_logic; -- Additional Param_Max_Cfg : IN std_logic_vector(2 downto 0); -- Common ports dma_clk : IN std_logic; dma_reset : IN std_logic ); end entity DMA_Calculate; architecture Behavioral of DMA_Calculate is -- Significant bits from the MaXSiZe parameter signal Max_TLP_Size : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto 0); signal mxsz_left : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT); signal mxsz_mid : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT); signal mxsz_right : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT); -- Signals masked by MaxSize signal DMA_Leng_Left_Msk : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT); signal DMA_Leng_Mid_Msk : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT); signal DMA_Leng_Right_Msk : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT); -- Alias signal Lo_Leng_Left_Msk_is_True : std_logic; signal Lo_Leng_Mid_Msk_is_True : std_logic; signal Lo_Leng_Right_Msk_is_True : std_logic; -- Masked values of HA and Length signal DMA_HA_Msk : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto 0); signal DMA_Length_Msk : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto 0); -- Indicates whether the DMA_PA is already accepted signal PA_is_taken : std_logic; -- Calculation for the PA of the next DMA, if UPA bit = 0 signal DMA_PA_next : std_logic_vector(C_DBUS_WIDTH-1 downto 0); signal DMA_PA_current : std_logic_vector(C_DBUS_WIDTH-1 downto 0); -- eventual PA parameter for the current DMA transaction signal DMA_PA_Loaded_i : std_logic_vector(C_DBUS_WIDTH-1 downto 0); -- Calculation in advance, only for better timing signal Carry_PA_plus_Leng : std_logic_vector(CBIT_CARRY downto 0); signal Carry_PAx_plus_Leng : std_logic_vector(CBIT_CARRY downto 0); signal Leng_Hi_plus_PA_Hi : std_logic_vector(C_DBUS_WIDTH-1 downto CBIT_CARRY); signal Leng_Hi_plus_PAx_Hi : std_logic_vector(C_DBUS_WIDTH-1 downto CBIT_CARRY); -- DMA parameters from the register module signal DMA_PA_i : std_logic_vector(C_DBUS_WIDTH-1 downto 0); signal DMA_HA_i : std_logic_vector(C_DBUS_WIDTH-1 downto 0); signal DMA_BDA_i : std_logic_vector(C_DBUS_WIDTH-1 downto 0); signal DMA_Length_i : std_logic_vector(C_DBUS_WIDTH-1 downto 0); signal DMA_Control_i : std_logic_vector(C_DBUS_WIDTH-1 downto 0); -- delay signal State_Is_Snout_r1 : std_logic; signal State_Is_Body_r1 : std_logic; -- from control word signal Dex_is_Last : std_logic; signal Engine_Ends : std_logic; -- Major FSM control signals signal ThereIs_Snout_i : std_logic; signal ThereIs_Body_i : std_logic; signal ThereIs_Tail_i : std_logic; signal Snout_Only : std_logic; signal ThereIs_Dex_i : std_logic; signal No_More_Bodies_i : std_logic; -- Address/Length combination signal ALc : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto 0); -- Compressed ALc -- ALc_B bit means the ALc has carry in, making an extra Body block. signal ALc_B : std_logic; signal ALc_B_wire : std_logic; -- ALc_T bit means the ALc has trailer, making a final Tail block. signal ALc_T : std_logic; signal ALc_T_wire : std_logic; -- Compressed Length -- Leng_Two bit means Length >= 2 Max_Size. signal Leng_Two : std_logic; -- Leng_One bit means Length >= 1 Max_Size. signal Leng_One : std_logic; -- Leng_nint bit means Length is not integral of Max_Sizes. signal Leng_nint : std_logic; signal Length_analysis : std_logic_vector(2 downto 0); signal Snout_Body_Tail : std_logic_vector(2 downto 0); -- Byte counter signal DMA_Byte_Counter : std_logic_vector(C_DBUS_WIDTH-1 downto 0); -- !!! Elastic signal Length_minus : std_logic_vector(C_DBUS_WIDTH-1 downto 0); signal DMA_BC_Carry : std_logic_vector(CBIT_CARRY downto 0); -- Remote & Local Address variable signal DMA_HA_Var_i : std_logic_vector(C_DBUS_WIDTH-1 downto 0); signal DMA_HA_Carry32 : std_logic_vector(C_DBUS_WIDTH/2 downto 0); signal DMA_PA_Var_i : std_logic_vector(C_DBUS_WIDTH-1 downto 0); -- BDA parameter is buffered for FSM module signal DMA_BDA_fsm_i : std_logic_vector(C_DBUS_WIDTH-1 downto 0); signal BDA_is_64b_fsm_i : std_logic; -- Token bits out of Control word signal HA64bit_i : std_logic; signal Addr_Inc_i : std_logic; signal use_PA : std_logic; signal DMA_Start_r1 : std_logic; signal DMA_Start2_r1 : std_logic; signal DMA_Leng_sub : std_logic_vector(4-1 downto 0); signal DMA_0_Leng_i : std_logic; -- for better timing signal HA_gap : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto 0); -- signal DMA_Snout_Length_i : std_logic_vector(C_MAXSIZE_FLD_BIT_TOP downto 0); signal DMA_Tail_Length_i : std_logic_vector(C_TLP_FLD_WIDTH_OF_LENG+1 downto 0); -- for better timing signal raw_Tail_Length : std_logic_vector(C_TLP_FLD_WIDTH_OF_LENG+1 downto 0); signal DMA_PA_Snout_Carry : std_logic_vector(CBIT_CARRY downto 0); signal DMA_PA_Body_Carry : std_logic_vector(CBIT_CARRY downto 0); signal DMA_BAR_Number_i : std_logic_vector(C_ENCODE_BAR_NUMBER-1 downto 0); begin -- Partition indicators No_More_Bodies <= No_More_Bodies_i ; ThereIs_Snout <= ThereIs_Snout_i ; ThereIs_Body <= ThereIs_Body_i ; ThereIs_Tail <= ThereIs_Tail_i ; ThereIs_Dex <= ThereIs_Dex_i ; HA64bit <= HA64bit_i ; Addr_Inc <= Addr_Inc_i ; DMA_0_Leng <= DMA_0_Leng_i ; -- DMA_PA_Loaded <= DMA_PA_Loaded_i ; DMA_PA_Var <= DMA_PA_Var_i ; DMA_HA_Var <= DMA_HA_Var_i ; DMA_BDA_fsm <= DMA_BDA_fsm_i ; BDA_is_64b_fsm <= BDA_is_64b_fsm_i; -- Only for downstream channel DMA_PA_Snout <= DMA_PA_current(C_DBUS_WIDTH-1 downto 0); DMA_BAR_Number <= DMA_BAR_Number_i; -- different lengths DMA_Snout_Length <= DMA_Snout_Length_i ; DMA_Body_Length <= Max_TLP_Size ; DMA_Tail_Length <= DMA_Tail_Length_i ; -- Register stubs DMA_PA_i <= DMA_PA; DMA_HA_i <= DMA_HA; DMA_BDA_i <= DMA_BDA; DMA_Length_i <= DMA_Length; DMA_Control_i <= DMA_Control; -- --------------------------------------------------------------- -- Parameters should be captured by the start/start2 and be kept -- in case Pause command comes. -- Syn_Param_Capture: process ( dma_clk, dma_reset) begin if dma_reset = '1' then Addr_Inc_i <= '0'; use_PA <= '0'; Dex_is_Last <= '0'; Engine_Ends <= '1'; DMA_BAR_Number_i <= (OTHERS=>'0'); DMA_BDA_fsm_i <= (OTHERS=>'0'); BDA_is_64b_fsm_i <= '0'; elsif dma_clk'event and dma_clk = '1' then if DMA_Start ='1' or DMA_Start2 ='1' then Addr_Inc_i <= DMA_Control_i(CINT_BIT_DMA_CTRL_AINC); use_PA <= DMA_Control_i(CINT_BIT_DMA_CTRL_UPA); Dex_is_Last <= DMA_Control_i(CINT_BIT_DMA_CTRL_LAST); Engine_Ends <= DMA_Control_i(CINT_BIT_DMA_CTRL_END); DMA_BAR_Number_i <= DMA_Control_i(CINT_BIT_DMA_CTRL_BAR_TOP downto CINT_BIT_DMA_CTRL_BAR_BOT); DMA_BDA_fsm_i <= DMA_BDA_i ; BDA_is_64b_fsm_i <= BDA_is_64b ; else Addr_Inc_i <= Addr_Inc_i ; use_PA <= use_PA ; Dex_is_Last <= Dex_is_Last ; Engine_Ends <= Engine_Ends ; DMA_BAR_Number_i <= DMA_BAR_Number_i; DMA_BDA_fsm_i <= DMA_BDA_fsm_i ; BDA_is_64b_fsm_i <= BDA_is_64b_fsm_i ; end if; end if; end process; -- ----------------------------------------------------------------- -- DMA has zero length. -- for sake of timing convergence, divided calculating is used. -- Syn_DMA_0_Leng: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_Start_r1 <= '0'; DMA_Start2_r1 <= '0'; DMA_Leng_sub <= (OTHERS=>'0'); DMA_0_Leng_i <= '1'; elsif dma_clk'event and dma_clk = '1' then DMA_Start_r1 <= DMA_Start; DMA_Start2_r1 <= DMA_Start2; if DMA_Length(C_DBUS_WIDTH/2-1 downto C_DBUS_WIDTH/2-8) =C_ALL_ZEROS(C_DBUS_WIDTH/2-1 downto C_DBUS_WIDTH/2-8) then DMA_Leng_sub(3) <= '0'; else DMA_Leng_sub(3) <= '1'; end if; if DMA_Length(C_DBUS_WIDTH/2-9 downto C_DBUS_WIDTH/2-16) =C_ALL_ZEROS(C_DBUS_WIDTH/2-9 downto C_DBUS_WIDTH/2-16) then DMA_Leng_sub(2) <= '0'; else DMA_Leng_sub(2) <= '1'; end if; if DMA_Length(C_DBUS_WIDTH/2-17 downto C_DBUS_WIDTH/2-24) =C_ALL_ZEROS(C_DBUS_WIDTH/2-17 downto C_DBUS_WIDTH/2-24) then DMA_Leng_sub(1) <= '0'; else DMA_Leng_sub(1) <= '1'; end if; if DMA_Length(C_DBUS_WIDTH/2-25 downto 2) =C_ALL_ZEROS(C_DBUS_WIDTH/2-25 downto 2) then DMA_Leng_sub(0) <= '0'; else DMA_Leng_sub(0) <= '1'; end if; if DMA_Start_r1 ='1' or DMA_Start2_r1 ='1' then if DMA_Leng_sub=C_ALL_ZEROS(4-1 downto 0) then DMA_0_Leng_i <= '1'; else DMA_0_Leng_i <= '0'; end if; else DMA_0_Leng_i <= DMA_0_Leng_i; end if; end if; end process; -- Addr_Inc_i <= DMA_Control_i(CINT_BIT_DMA_CTRL_AINC); -- use_PA <= DMA_Control_i(CINT_BIT_DMA_CTRL_UPA); -- Dex_is_Last <= DMA_Control_i(CINT_BIT_DMA_CTRL_LAST); -- Engine_Ends <= DMA_Control_i(CINT_BIT_DMA_CTRL_END); -- use_Irpt_Done <= not DMA_Control_i(CINT_BIT_DMA_CTRL_EDI); -- Means there is consecutive descriptor(s) ThereIs_Dex_i <= not Dex_is_Last and not Engine_Ends; -- --------------------------------------------------------------- -- PA_i selection -- Syn_Calc_DMA_PA: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_PA_current <= (Others=>'0'); PA_is_taken <= '0'; elsif dma_clk'event and dma_clk = '1' then if DMA_Start = '1' and PA_is_taken='0' then DMA_PA_current <= DMA_PA_i(C_DBUS_WIDTH-1 downto 2) &"00"; PA_is_taken <= '1'; elsif DMA_Start2 = '1' and PA_is_taken='0' and DMA_Control_i(CINT_BIT_DMA_CTRL_UPA) = '1' then DMA_PA_current <= DMA_PA_i(C_DBUS_WIDTH-1 downto 2) &"00"; PA_is_taken <= '1'; elsif DMA_Start2 = '1' and PA_is_taken='0' and DMA_Control_i(CINT_BIT_DMA_CTRL_UPA) = '0' then DMA_PA_current(C_DBUS_WIDTH-1 downto 0) <= DMA_PA_next; PA_is_taken <= '1'; else DMA_PA_current <= DMA_PA_current; if DMA_Start='0' and DMA_Start2='0' then PA_is_taken <= '0'; else PA_is_taken <= PA_is_taken; end if; end if; end if; end process; -- --------------------------------------------------------------- -- PA_next Calculation -- Syn_Calc_DMA_PA_next: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_PA_next <= (Others=>'0'); elsif dma_clk'event and dma_clk = '1' then if DMA_Start = '1' and PA_is_taken='0' then if DMA_Control_i(CINT_BIT_DMA_CTRL_AINC) = '1' then DMA_PA_next(CBIT_CARRY-1 downto 0) <= Carry_PA_plus_Leng(CBIT_CARRY-1 downto 0); DMA_PA_next(C_DBUS_WIDTH-1 downto CBIT_CARRY) <= Leng_Hi_plus_PA_Hi + Carry_PA_plus_Leng(CBIT_CARRY); else DMA_PA_next <= DMA_PA_i(C_DBUS_WIDTH-1 downto 2) &"00"; end if; elsif DMA_Start2 = '1' and PA_is_taken='0' then if DMA_Control_i(CINT_BIT_DMA_CTRL_AINC) = '1' then DMA_PA_next(CBIT_CARRY-1 downto 0) <= Carry_PAx_plus_Leng(CBIT_CARRY-1 downto 0); DMA_PA_next(C_DBUS_WIDTH-1 downto CBIT_CARRY) <= Leng_Hi_plus_PAx_Hi + Carry_PAx_plus_Leng(CBIT_CARRY); else DMA_PA_next <= DMA_PA_next; end if; else DMA_PA_next <= DMA_PA_next; end if; end if; end process; -- --------------------------------------------------------------- -- Carry_PA_plus_Leng(16 downto 0) -- Syn_Calc_Carry_PA_plus_Leng: process ( dma_clk, dma_reset) begin if dma_reset = '1' then Carry_PA_plus_Leng <= (Others=>'0'); elsif dma_clk'event and dma_clk = '1' then Carry_PA_plus_Leng <= ('0'& DMA_PA_i(CBIT_CARRY-1 downto 2) &"00") + ('0'& DMA_Length_i(CBIT_CARRY-1 downto 2) &"00"); end if; end process; -- --------------------------------------------------------------- -- Carry_PAx_plus_Leng(16 downto 0) -- Syn_Calc_Carry_PAx_plus_Leng: process ( dma_clk, dma_reset) begin if dma_reset = '1' then Carry_PAx_plus_Leng <= (Others=>'0'); elsif dma_clk'event and dma_clk = '1' then Carry_PAx_plus_Leng <= ('0'& DMA_PA_next (CBIT_CARRY-1 downto 2) &"00") + ('0'& DMA_Length_i(CBIT_CARRY-1 downto 2) &"00"); end if; end process; -- --------------------------------------------------------------- -- Leng_Hi_plus_PA_Hi(31 downto 16) -- Syn_Calc_Leng_Hi_plus_PA_Hi: process ( dma_clk, dma_reset) begin if dma_reset = '1' then Leng_Hi_plus_PA_Hi <= (Others=>'0'); elsif dma_clk'event and dma_clk = '1' then Leng_Hi_plus_PA_Hi <= DMA_Length_i(C_DBUS_WIDTH-1 downto CBIT_CARRY) + DMA_PA_i(C_DBUS_WIDTH-1 downto CBIT_CARRY); end if; end process; -- --------------------------------------------------------------- -- Leng_Hi_plus_PAx_Hi(31 downto 16) -- Syn_Calc_Leng_Hi_plus_PAx_Hi: process ( dma_clk, dma_reset) begin if dma_reset = '1' then Leng_Hi_plus_PAx_Hi <= (Others=>'0'); elsif dma_clk'event and dma_clk = '1' then Leng_Hi_plus_PAx_Hi <= DMA_Length_i(C_DBUS_WIDTH-1 downto CBIT_CARRY) + DMA_PA_next(C_DBUS_WIDTH-1 downto CBIT_CARRY); end if; end process; -- ----------------------------------------------------------------------------------------------------------------------------------- DMA_Leng_Left_Msk <= DMA_Length_i(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_left; DMA_Leng_Mid_Msk <= DMA_Length_i(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_mid; DMA_Leng_Right_Msk <= DMA_Length_i(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_right; -- ----------------------------------------------------------------------------------------------------------------------------------- DMA_HA_Msk <= (DMA_HA_i(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_right) & DMA_HA_i(C_MAXSIZE_FLD_BIT_BOT-1 downto 2) & "00"; DMA_Length_Msk <= (DMA_Length_i(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_right) & DMA_Length_i(C_MAXSIZE_FLD_BIT_BOT-1 downto 2) & "00"; -- ----------------------------------------------------------------------------------------------------------------------------------- Lo_Leng_Left_Msk_is_True <= '0' when DMA_Leng_Left_Msk =C_ALL_ZEROS(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) else '1'; Lo_Leng_Mid_Msk_is_True <= '0' when DMA_Leng_Mid_Msk =C_ALL_ZEROS(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) else '1'; Lo_Leng_Right_Msk_is_True <= '0' when DMA_Leng_Right_Msk=C_ALL_ZEROS(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) else '1'; -- ---------------------------------------------------------- -- Synchronous Register: Leng_Info(Compressed Length Information) --- Syn_Calc_Parameter_Leng_Info: process ( dma_clk, dma_reset) begin if dma_reset = '1' then Leng_Two <= '0'; Leng_One <= '0'; Leng_nint <= '0'; elsif dma_clk'event and dma_clk = '1' then Leng_Two <= Leng_Hi19b_True or Lo_Leng_Left_Msk_is_True; Leng_One <= Lo_Leng_Mid_Msk_is_True; Leng_nint <= Leng_Lo7b_True or Lo_Leng_Right_Msk_is_True; end if; end process; -- ----------------------------------------------------------------------------------------------------------------------------------- ALc_B_wire <= '0' when (ALc(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_mid)=C_ALL_ZEROS(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) else '1'; ALc_T_wire <= '0' when (ALc(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_right)=C_ALL_ZEROS(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and ALc(C_MAXSIZE_FLD_BIT_BOT-1 downto 0)=C_ALL_ZEROS(C_MAXSIZE_FLD_BIT_BOT-1 downto 0) else '1'; -- ----------------------------------------------------------------------------------------------------------------------------------- -- ------------------------------------------------------- -- Synchronous Register: ALc (Address-Length combination) --- Syn_Calc_Parameter_ALc: process ( dma_clk, dma_reset) begin if dma_reset = '1' then ALc <= (Others=>'0'); ALc_B <= '0'; ALc_T <= '0'; elsif dma_clk'event and dma_clk = '1' then ALc <= DMA_Length_Msk + DMA_HA_Msk; ALc_B <= ALc_B_wire; ALc_T <= ALc_T_wire; end if; end process; -- concatenation of the Length information Length_analysis <= Leng_Two & Leng_One & Leng_nint; -- ------------------------------------------- -- Analysis on the DMA division -- truth-table expressions -- Comb_S_B_T: process ( Length_analysis , ALc_B , ALc_T ) begin case Length_analysis is -- Zero-length DMA, nothing to send when "000" => Snout_Body_Tail <= "000"; -- Length < Max_Size. Always Snout and never Body, Tail depends on ALc. when "001" => Snout_Body_Tail <= '1' & '0' & (ALc_B and ALc_T); -- Length = Max_Size. Division depends only on ALc-Tail. when "010" => Snout_Body_Tail <= ALc_T & not ALc_T & ALc_T; -- Length = (k+1) Max_Size, k>=1. Always Body. Snout and Tail depend on ALc-Tail. -- Body = Leng_Two or not ALc_T when "100" => Snout_Body_Tail <= ALc_T & '1' & ALc_T; when "110" => Snout_Body_Tail <= ALc_T & '1' & ALc_T; -- Length = (1+d) Max_Size, 0<d<1. Always Snout. Body and Tail copy ALc. when "011" => Snout_Body_Tail <= '1' & ALc_B & ALc_T; -- Length = (k+1+d) Max_Size, k>=1, 0<d<1. Always Snout and Body. Tail copies ALc-Tail. -- Body = Leng_Two or ALc_B when "101" => Snout_Body_Tail <= '1' & '1' & ALc_T; when "111" => Snout_Body_Tail <= '1' & '1' & ALc_T; -- dealt as zero-length DMA when Others => Snout_Body_Tail <= "000"; end case; end process; -- ----------------------------------------------- -- Synchronous Register: -- ThereIs_Snout -- ThereIs_Body -- ThereIs_Tail -- Syn_Calc_Parameters_SBT: process ( dma_clk, dma_reset) begin if dma_reset = '1' then ThereIs_Snout_i <= '0'; ThereIs_Body_i <= '0'; ThereIs_Tail_i <= '0'; Snout_Only <= '0'; elsif dma_clk'event and dma_clk = '1' then ThereIs_Snout_i <= Snout_Body_Tail(2); ThereIs_Body_i <= Snout_Body_Tail(1); ThereIs_Tail_i <= Snout_Body_Tail(0); Snout_Only <= ALc_T and not Snout_Body_Tail(0); end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: -- HA_gap -- Syn_Calc_HA_gap: process ( dma_clk, dma_reset) begin if dma_reset = '1' then HA_gap <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then HA_gap <= Max_TLP_Size - DMA_HA_Msk; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: -- DMA_PA_Snout_Carry -- FSM_Calc_DMA_PA_Snout_Carry: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_PA_Snout_Carry <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then DMA_PA_Snout_Carry <= ('0'& DMA_PA_current(CBIT_CARRY-1 downto 0)) + HA_gap; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: -- DMA_PA_Body_Carry -- FSM_Calc_DMA_PA_Body_Carry: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_PA_Body_Carry <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then DMA_PA_Body_Carry <= ('0'& DMA_PA_Var_i(CBIT_CARRY-1 downto 0)) + Max_TLP_Size; end if; end process; -- ------------------------------------------------------------------ -- Synchronous Register: Length_minus -- Sync_Calc_Length_minus: process ( dma_clk, dma_reset) begin if dma_reset = '1' then Length_minus <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then Length_minus <= DMA_Length_i - Max_TLP_Size; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: -- DMA_BC_Carry -- FSM_Calc_DMA_BC_Carry: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_BC_Carry <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then DMA_BC_Carry <= ('0'& DMA_Byte_Counter(CBIT_CARRY-1 downto 0)) - Max_TLP_Size; end if; end process; -- -------------------------------------------- -- Synchronous reg: DMA_Snout_Length -- DMA_Tail_Length -- FSM_Calc_DMA_Snout_Tail_Lengths: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_Snout_Length_i <= (OTHERS =>'0'); DMA_Tail_Length_i <= (OTHERS =>'0'); raw_Tail_Length <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then DMA_Tail_Length_i(C_TLP_FLD_WIDTH_OF_LENG+1 downto 0) <= (raw_Tail_Length(C_TLP_FLD_WIDTH_OF_LENG+1 downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_right(C_TLP_FLD_WIDTH_OF_LENG+1 downto C_MAXSIZE_FLD_BIT_BOT) ) & raw_Tail_Length( C_MAXSIZE_FLD_BIT_BOT-1 downto 0); if State_Is_LoadParam ='1' then raw_Tail_Length(C_TLP_FLD_WIDTH_OF_LENG+1 downto 0) <= DMA_Length_Msk(C_TLP_FLD_WIDTH_OF_LENG+1 downto 0) + DMA_HA_Msk(C_TLP_FLD_WIDTH_OF_LENG+1 downto 0); if Snout_Only='1' then DMA_Snout_Length_i <= DMA_Length_i(C_MAXSIZE_FLD_BIT_TOP downto 2) &"00"; else DMA_Snout_Length_i <= Max_TLP_Size - DMA_HA_Msk; end if; else DMA_Snout_Length_i <= DMA_Snout_Length_i; raw_Tail_Length <= raw_Tail_Length; end if; end if; end process; -- ------------------------------------------------------------- -- Synchronous Delays: -- State_Is_Snout_r1 -- State_Is_Body_r1 -- Syn_Delay_State_is_x: process ( dma_clk ) begin if dma_clk'event and dma_clk = '1' then State_Is_Snout_r1 <= State_Is_Snout; State_Is_Body_r1 <= State_Is_Body; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: -- DMA_HA_Carry32 -- FSM_Calc_DMA_HA_Carry32: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_HA_Carry32 <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then if State_Is_LoadParam = '1' then DMA_HA_Carry32 <= '0' & DMA_HA_i(C_DBUS_WIDTH/2-1 downto 2) & "00"; -- temp elsif State_Is_Snout = '1' or State_Is_Body = '1' then DMA_HA_Carry32(C_DBUS_WIDTH/2 downto C_MAXSIZE_FLD_BIT_BOT) <= ('0'& DMA_HA_Var_i(C_DBUS_WIDTH/2-1 downto C_MAXSIZE_FLD_BIT_TOP+1) & (DMA_HA_Var_i(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and not mxsz_right) ) + mxsz_mid; else DMA_HA_Carry32 <= DMA_HA_Carry32; end if; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: -- DMA_HA_Var -- FSM_Calc_DMA_HA_Var: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_HA_Var_i <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then if State_Is_LoadParam = '1' then DMA_HA_Var_i <= DMA_HA_i(C_DBUS_WIDTH-1 downto 2) & "00"; -- temp elsif State_Is_Snout_r1 = '1' or State_Is_Body_r1 = '1' then -- elsif State_Is_Snout = '1' or State_Is_Body = '1' then DMA_HA_Var_i(C_DBUS_WIDTH-1 downto C_DBUS_WIDTH/2) <= DMA_HA_Var_i(C_DBUS_WIDTH-1 downto C_DBUS_WIDTH/2) + DMA_HA_Carry32(C_DBUS_WIDTH/2); DMA_HA_Var_i(C_DBUS_WIDTH-1 downto C_MAXSIZE_FLD_BIT_BOT) <= (DMA_HA_Var_i(C_DBUS_WIDTH-1 downto C_MAXSIZE_FLD_BIT_TOP+1) & (DMA_HA_Var_i(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and not mxsz_right)) + mxsz_mid; DMA_HA_Var_i(C_MAXSIZE_FLD_BIT_BOT-1 downto 0) <= (Others => '0'); -- MaxSize aligned else DMA_HA_Var_i <= DMA_HA_Var_i; end if; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: -- HA64bit -- FSM_Calc_HA64bit: process ( dma_clk, dma_reset) begin if dma_reset = '1' then HA64bit_i <= '0'; elsif dma_clk'event and dma_clk = '1' then if State_Is_LoadParam = '1' then HA64bit_i <= HA_is_64b; elsif DMA_HA_Carry32(C_DBUS_WIDTH/2) = '1' then HA64bit_i <= '1'; else HA64bit_i <= HA64bit_i; end if; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: -- DMA_PA_Var -- FSM_Calc_DMA_PA_Var: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_PA_Var_i <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then if State_Is_LoadParam = '1' then if Addr_Inc_i='1' and ThereIs_Snout_i='1' then DMA_PA_Var_i(CBIT_CARRY-1 downto 0) <= DMA_PA_current(CBIT_CARRY-1 downto 0) + HA_gap(C_MAXSIZE_FLD_BIT_TOP downto 0); DMA_PA_Var_i(C_DBUS_WIDTH-1 downto CBIT_CARRY) <= DMA_PA_current(C_DBUS_WIDTH-1 downto CBIT_CARRY); else DMA_PA_Var_i(C_DBUS_WIDTH-1 downto 0) <= DMA_PA_current(C_DBUS_WIDTH-1 downto 0); end if; elsif State_Is_Snout_r1 = '1' then ---- elsif State_Is_Snout = '1' then if Addr_Inc_i= '1' then DMA_PA_Var_i(CBIT_CARRY-1 downto 0) <= DMA_PA_Var_i(CBIT_CARRY-1 downto 0); DMA_PA_Var_i(C_DBUS_WIDTH-1 downto CBIT_CARRY) <= DMA_PA_Var_i(C_DBUS_WIDTH-1 downto CBIT_CARRY) + DMA_PA_Snout_Carry(CBIT_CARRY); else DMA_PA_Var_i <= DMA_PA_Var_i; end if; elsif State_Is_Body_r1 = '1' then ---- elsif State_Is_Body = '1' then if Addr_Inc_i= '1' then DMA_PA_Var_i(CBIT_CARRY-1 downto 0) <= DMA_PA_Body_Carry(CBIT_CARRY-1 downto 0); DMA_PA_Var_i(C_DBUS_WIDTH-1 downto CBIT_CARRY) <= DMA_PA_Var_i(C_DBUS_WIDTH-1 downto CBIT_CARRY) + DMA_PA_Body_Carry(CBIT_CARRY); else DMA_PA_Var_i <= DMA_PA_Var_i; end if; else DMA_PA_Var_i <= DMA_PA_Var_i; end if; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: -- DMA_PA_Loaded_i -- FSM_Calc_DMA_PA_Loaded_i: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_PA_Loaded_i <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then if State_Is_LoadParam = '1' then DMA_PA_Loaded_i <= DMA_PA_current(C_DBUS_WIDTH-1 downto 0); else DMA_PA_Loaded_i <= DMA_PA_Loaded_i; end if; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: DMA_Byte_Counter --- FSM_Calc_DMA_Byte_Counter: process ( dma_clk, dma_reset) begin if dma_reset = '1' then DMA_Byte_Counter <= (OTHERS =>'0'); elsif dma_clk'event and dma_clk = '1' then if State_Is_LoadParam = '1' then if ALc_B='0' and ALc_T='1' then DMA_Byte_Counter <= Length_minus; else DMA_Byte_Counter <= DMA_Length_i(C_DBUS_WIDTH-1 downto 2) & "00"; end if; -- elsif State_Is_Body_r1 = '1' then elsif State_Is_Body = '1' then DMA_Byte_Counter(C_DBUS_WIDTH-1 downto CBIT_CARRY) <= DMA_Byte_Counter(C_DBUS_WIDTH-1 downto CBIT_CARRY) - DMA_BC_Carry(CBIT_CARRY); DMA_Byte_Counter(CBIT_CARRY-1 downto C_MAXSIZE_FLD_BIT_BOT) <= DMA_BC_Carry(CBIT_CARRY-1 downto C_MAXSIZE_FLD_BIT_BOT); else DMA_Byte_Counter <= DMA_Byte_Counter; end if; end if; end process; -- ------------------------------------------------------------- -- Synchronous reg: No_More_Bodies --- FSM_Calc_No_More_Bodies: process ( dma_clk, dma_reset) begin if dma_reset = '1' then No_More_Bodies_i <= '0'; elsif dma_clk'event and dma_clk = '1' then if State_Is_LoadParam = '1' then No_More_Bodies_i <= not ThereIs_Body_i; -- elsif State_Is_Body_r1 = '1' then elsif State_Is_Body = '1' then if DMA_Byte_Counter(C_DBUS_WIDTH-1 downto C_MAXSIZE_FLD_BIT_TOP+1)=C_ALL_ZEROS(C_DBUS_WIDTH-1 downto C_MAXSIZE_FLD_BIT_TOP+1) and (DMA_Byte_Counter(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_left)=C_ALL_ZEROS(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and (DMA_Byte_Counter(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) and mxsz_mid)/=C_ALL_ZEROS(C_MAXSIZE_FLD_BIT_TOP downto C_MAXSIZE_FLD_BIT_BOT) then No_More_Bodies_i <= '1'; else No_More_Bodies_i <= '0'; end if; else No_More_Bodies_i <= No_More_Bodies_i; end if; end if; end process; -- ------------------------------------------ -- Configuration pamameters: Param_Max_Cfg -- Syn_Config_Param_Max_Cfg: process ( dma_clk, dma_reset) begin if dma_reset = '1' then -- 0x0080 Bytes mxsz_left <= "111110"; -- 6 bits mxsz_mid <= "000001"; -- 6 bits mxsz_right <= "000000"; -- 6 bits elsif dma_clk'event and dma_clk = '1' then case Param_Max_Cfg is when "000" => -- 0x0080 Bytes mxsz_left <= "111110"; mxsz_mid <= "000001"; mxsz_right <= "000000"; when "001" => -- 0x0100 Bytes mxsz_left <= "111100"; mxsz_mid <= "000010"; mxsz_right <= "000001"; when "010" => -- 0x0200 Bytes mxsz_left <= "111000"; mxsz_mid <= "000100"; mxsz_right <= "000011"; when "011" => -- 0x0400 Bytes mxsz_left <= "110000"; mxsz_mid <= "001000"; mxsz_right <= "000111"; when "100" => -- 0x0800 Bytes mxsz_left <= "100000"; mxsz_mid <= "010000"; mxsz_right <= "001111"; when "101" => -- 0x1000 Bytes mxsz_left <= "000000"; mxsz_mid <= "100000"; mxsz_right <= "011111"; when Others => -- as 0x0080 Bytes mxsz_left <= "111110"; mxsz_mid <= "000001"; mxsz_right <= "000000"; end case; end if; end process; Max_TLP_Size <= mxsz_mid & CONV_STD_LOGIC_VECTOR(0, C_MAXSIZE_FLD_BIT_BOT); end architecture Behavioral;