lpp_dma_SEND16B_FIFO2DMA.vhd
255 lines
| 8.9 KiB
| text/x-vhdl
|
VhdlLexer
pellion
|
r577 | ------------------------------------------------------------------------------ | ||
-- This file is a part of the LPP VHDL IP LIBRARY | ||||
-- Copyright (C) 2009 - 2010, Laboratory of Plasmas Physic - CNRS | ||||
-- | ||||
-- This program is free software; you can redistribute it and/or modify | ||||
-- it under the terms of the GNU General Public License as published by | ||||
-- the Free Software Foundation; either version 3 of the License, or | ||||
-- (at your option) any later version. | ||||
-- | ||||
-- This program is distributed in the hope that it will be useful, | ||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
-- GNU General Public License for more details. | ||||
-- | ||||
-- You should have received a copy of the GNU General Public License | ||||
-- along with this program; if not, write to the Free Software | ||||
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||||
------------------------------------------------------------------------------- | ||||
-- Author : Jean-christophe Pellion | ||||
-- Mail : jean-christophe.pellion@lpp.polytechnique.fr | ||||
-- jean-christophe.pellion@easii-ic.com | ||||
------------------------------------------------------------------------------- | ||||
-- 1.0 - initial version | ||||
------------------------------------------------------------------------------- | ||||
LIBRARY ieee; | ||||
USE ieee.std_logic_1164.ALL; | ||||
USE ieee.numeric_std.ALL; | ||||
LIBRARY grlib; | ||||
USE grlib.amba.ALL; | ||||
USE grlib.stdlib.ALL; | ||||
USE grlib.devices.ALL; | ||||
LIBRARY lpp; | ||||
USE lpp.lpp_amba.ALL; | ||||
USE lpp.apb_devices_list.ALL; | ||||
USE lpp.lpp_memory.ALL; | ||||
USE lpp.lpp_dma_pkg.ALL; | ||||
USE lpp.general_purpose.ALL; | ||||
--USE lpp.lpp_waveform_pkg.ALL; | ||||
LIBRARY techmap; | ||||
USE techmap.gencomp.ALL; | ||||
ENTITY lpp_dma_SEND16B_FIFO2DMA IS | ||||
GENERIC ( | ||||
hindex : INTEGER := 2; | ||||
vendorid : IN INTEGER := 0; | ||||
deviceid : IN INTEGER := 0; | ||||
version : IN INTEGER := 0 | ||||
); | ||||
PORT ( | ||||
clk : IN STD_LOGIC; | ||||
rstn : IN STD_LOGIC; | ||||
-- AMBA AHB Master Interface | ||||
AHB_Master_In : IN AHB_Mst_In_Type; | ||||
AHB_Master_Out : OUT AHB_Mst_Out_Type; | ||||
-- FIFO Interface | ||||
ren : OUT STD_LOGIC; | ||||
data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); | ||||
-- Controls | ||||
send : IN STD_LOGIC; | ||||
valid_burst : IN STD_LOGIC; -- (1 => BURST , 0 => SINGLE) | ||||
done : OUT STD_LOGIC; | ||||
address : IN STD_LOGIC_VECTOR(31 DOWNTO 0) | ||||
); | ||||
END; | ||||
ARCHITECTURE Behavioral OF lpp_dma_SEND16B_FIFO2DMA IS | ||||
CONSTANT HConfig : AHB_Config_Type := ( | ||||
0 => ahb_device_reg(vendorid, deviceid, 0, version, 0), | ||||
OTHERS => (OTHERS => '0')); | ||||
pellion
|
r589 | TYPE AHB_DMA_FSM_STATE IS (IDLE, s_INIT_TRANS, s_ARBITER ,s_CTRL, s_CTRL_DATA, s_DATA); | ||
pellion
|
r577 | SIGNAL state : AHB_DMA_FSM_STATE; | ||
SIGNAL address_counter_reg : STD_LOGIC_VECTOR(3 DOWNTO 0); | ||||
SIGNAL address_counter : STD_LOGIC_VECTOR(3 DOWNTO 0); | ||||
SIGNAL data_window : STD_LOGIC; | ||||
SIGNAL ctrl_window : STD_LOGIC; | ||||
SIGNAL bus_request : STD_LOGIC; | ||||
SIGNAL bus_lock : STD_LOGIC; | ||||
pellion
|
r582 | |||
SIGNAL data_reg : STD_LOGIC_VECTOR(31 DOWNTO 0); | ||||
pellion
|
r589 | |||
SIGNAL HREADY_pre : STD_LOGIC; | ||||
SIGNAL HREADY_falling : STD_LOGIC; | ||||
SIGNAL inhib_ren : STD_LOGIC; | ||||
pellion
|
r577 | |||
BEGIN | ||||
----------------------------------------------------------------------------- | ||||
AHB_Master_Out.HCONFIG <= HConfig; | ||||
AHB_Master_Out.HSIZE <= "010"; --WORDS 32b | ||||
AHB_Master_Out.HINDEX <= hindex; | ||||
AHB_Master_Out.HPROT <= "0011"; --DATA ACCESS and PRIVILEDGED ACCESS | ||||
AHB_Master_Out.HIRQ <= (OTHERS => '0'); | ||||
AHB_Master_Out.HBURST <= "111"; -- INCR --"111"; --INCR16 | ||||
AHB_Master_Out.HWRITE <= '1'; | ||||
--AHB_Master_Out.HTRANS <= HTRANS_NONSEQ WHEN ctrl_window = '1' OR data_window = '1' ELSE HTRANS_IDLE; | ||||
--AHB_Master_Out.HBUSREQ <= bus_request; | ||||
--AHB_Master_Out.HLOCK <= data_window; | ||||
--bus_request <= '0' WHEN address_counter_reg = "1111" AND AHB_Master_In.HREADY = '1' ELSE | ||||
-- '1' WHEN ctrl_window = '1' ELSE | ||||
-- '0'; | ||||
--bus_lock <= '0' WHEN address_counter_reg = "1111" ELSE | ||||
-- '1' WHEN ctrl_window = '1' ELSE '0'; | ||||
----------------------------------------------------------------------------- | ||||
AHB_Master_Out.HADDR <= address(31 DOWNTO 6) & address_counter_reg & "00"; | ||||
pellion
|
r582 | AHB_Master_Out.HWDATA <= ahbdrivedata(data) WHEN AHB_Master_In.HREADY = '1' ELSE ahbdrivedata(data_reg); | ||
pellion
|
r577 | ----------------------------------------------------------------------------- | ||
--ren <= NOT ((AHB_Master_In.HGRANT(hindex) OR LAST_READ ) AND AHB_Master_In.HREADY ); | ||||
--ren <= NOT beat; | ||||
----------------------------------------------------------------------------- | ||||
pellion
|
r589 | |||
HREADY_falling <= inhib_ren WHEN AHB_Master_In.HREADY = '0' AND HREADY_pre = '1' ELSE '1'; | ||||
pellion
|
r577 | PROCESS (clk, rstn) | ||
BEGIN -- PROCESS | ||||
IF rstn = '0' THEN -- asynchronous reset (active low) | ||||
state <= IDLE; | ||||
done <= '0'; | ||||
pellion
|
r582 | ren <= '1'; | ||
pellion
|
r577 | address_counter_reg <= (OTHERS => '0'); | ||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | ||||
AHB_Master_Out.HBUSREQ <= '0'; | ||||
AHB_Master_Out.HLOCK <= '0'; | ||||
pellion
|
r582 | |||
data_reg <= (OTHERS => '0'); | ||||
pellion
|
r589 | |||
HREADY_pre <= '0'; | ||||
inhib_ren <= '0'; | ||||
pellion
|
r577 | ELSIF clk'event AND clk = '1' THEN -- rising clock edge | ||
pellion
|
r589 | HREADY_pre <= AHB_Master_In.HREADY; | ||
pellion
|
r582 | IF AHB_Master_In.HREADY = '1' AND AHB_Master_In.HGRANT(hindex) = '1' THEN | ||
data_reg <= data; | ||||
END IF; | ||||
pellion
|
r577 | done <= '0'; | ||
pellion
|
r582 | ren <= '1'; | ||
pellion
|
r589 | inhib_ren <= '0'; | ||
pellion
|
r577 | CASE state IS | ||
WHEN IDLE => | ||||
AHB_Master_Out.HBUSREQ <= '0'; | ||||
AHB_Master_Out.HLOCK <= '0'; | ||||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | ||||
address_counter_reg <= (OTHERS => '0'); | ||||
IF send = '1' THEN | ||||
pellion
|
r589 | state <= s_INIT_TRANS; | ||
pellion
|
r577 | END IF; | ||
pellion
|
r589 | |||
WHEN s_INIT_TRANS => | ||||
AHB_Master_Out.HBUSREQ <= '1'; | ||||
AHB_Master_Out.HLOCK <= '1'; | ||||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | ||||
state <= s_ARBITER; | ||||
pellion
|
r577 | WHEN s_ARBITER => | ||
AHB_Master_Out.HBUSREQ <= '1'; | ||||
AHB_Master_Out.HLOCK <= '1'; | ||||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | ||||
address_counter_reg <= (OTHERS => '0'); | ||||
pellion
|
r580 | IF AHB_Master_In.HREADY = '1' AND AHB_Master_In.HGRANT(hindex) = '1' THEN | ||
pellion
|
r577 | AHB_Master_Out.HTRANS <= HTRANS_IDLE; | ||
state <= s_CTRL; | ||||
END IF; | ||||
WHEN s_CTRL => | ||||
pellion
|
r589 | inhib_ren <= '1'; | ||
pellion
|
r577 | AHB_Master_Out.HBUSREQ <= '1'; | ||
AHB_Master_Out.HLOCK <= '1'; | ||||
AHB_Master_Out.HTRANS <= HTRANS_NONSEQ; | ||||
IF AHB_Master_In.HREADY = '1' AND AHB_Master_In.HGRANT(hindex) = '1' THEN | ||||
pellion
|
r589 | --AHB_Master_Out.HTRANS <= HTRANS_SEQ; | ||
pellion
|
r577 | state <= s_CTRL_DATA; | ||
pellion
|
r589 | --ren <= '0'; | ||
pellion
|
r577 | END IF; | ||
WHEN s_CTRL_DATA => | ||||
AHB_Master_Out.HBUSREQ <= '1'; | ||||
AHB_Master_Out.HLOCK <= '1'; | ||||
AHB_Master_Out.HTRANS <= HTRANS_SEQ; | ||||
IF AHB_Master_In.HREADY = '1' AND AHB_Master_In.HGRANT(hindex) = '1' THEN | ||||
address_counter_reg <= STD_LOGIC_VECTOR(UNSIGNED(address_counter_reg) + 1); | ||||
END IF; | ||||
IF address_counter_reg = "1111" AND AHB_Master_In.HREADY = '1' THEN | ||||
AHB_Master_Out.HBUSREQ <= '0'; | ||||
AHB_Master_Out.HLOCK <= '1';--'0'; | ||||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | ||||
state <= s_DATA; | ||||
END IF; | ||||
pellion
|
r589 | ren <= HREADY_falling; | ||
--IF AHB_Master_In.HREADY = '1' AND AHB_Master_In.HGRANT(hindex) = '1' AND address_counter_reg /= "1111" THEN | ||||
-- ren <= '0'; | ||||
--END IF; | ||||
pellion
|
r582 | |||
pellion
|
r577 | WHEN s_DATA => | ||
pellion
|
r589 | ren <= HREADY_falling; | ||
pellion
|
r577 | AHB_Master_Out.HBUSREQ <= '0'; | ||
pellion
|
r581 | --AHB_Master_Out.HLOCK <= '0'; | ||
pellion
|
r577 | AHB_Master_Out.HTRANS <= HTRANS_IDLE; | ||
IF AHB_Master_In.HREADY = '1' THEN | ||||
pellion
|
r581 | AHB_Master_Out.HLOCK <= '0'; | ||
pellion
|
r577 | state <= IDLE; | ||
done <= '1'; | ||||
END IF; | ||||
WHEN OTHERS => NULL; | ||||
END CASE; | ||||
END IF; | ||||
END PROCESS; | ||||
ctrl_window <= '1' WHEN state = s_CTRL OR state = s_CTRL_DATA ELSE '0'; | ||||
data_window <= '1' WHEN state = s_CTRL_DATA OR state = s_DATA ELSE '0'; | ||||
----------------------------------------------------------------------------- | ||||
pellion
|
r582 | |||
--ren <= NOT(AHB_Master_In.HREADY) WHEN state = s_CTRL_DATA ELSE '1'; | ||||
pellion
|
r577 | |||
----------------------------------------------------------------------------- | ||||
--PROCESS (clk, rstn) | ||||
--BEGIN -- PROCESS | ||||
-- IF rstn = '0' THEN -- asynchronous reset (active low) | ||||
-- address_counter_reg <= (OTHERS => '0'); | ||||
-- ELSIF clk'event AND clk = '1' THEN -- rising clock edge | ||||
-- address_counter_reg <= address_counter; | ||||
-- END IF; | ||||
--END PROCESS; | ||||
--address_counter <= STD_LOGIC_VECTOR(UNSIGNED(address_counter_reg) + 1) WHEN data_window = '1' AND AHB_Master_In.HREADY = '1' AND AHB_Master_In.HGRANT(hindex) = '1' ELSE | ||||
-- address_counter_reg; | ||||
----------------------------------------------------------------------------- | ||||
END Behavioral; | ||||