lpp_dma_SEND16B_FIFO2DMA.vhd
250 lines
| 9.1 KiB
| text/x-vhdl
|
VhdlLexer
|
r611 | ------------------------------------------------------------------------------ | |
-- 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')); | |||
TYPE AHB_DMA_FSM_STATE IS (IDLE, s_INIT_TRANS, s_ARBITER ,s_CTRL, s_CTRL_DATA, s_DATA); | |||
SIGNAL state : AHB_DMA_FSM_STATE; | |||
SIGNAL address_counter_reg : STD_LOGIC_VECTOR(3 DOWNTO 0); | |||
SIGNAL data_window : STD_LOGIC; | |||
SIGNAL ctrl_window : STD_LOGIC; | |||
SIGNAL data_reg : STD_LOGIC_VECTOR(31 DOWNTO 0); | |||
SIGNAL HREADY_pre : STD_LOGIC; | |||
SIGNAL HREADY_falling : STD_LOGIC; | |||
SIGNAL inhib_ren : STD_LOGIC; | |||
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"; | |||
AHB_Master_Out.HWDATA <= ahbdrivedata(data) WHEN AHB_Master_In.HREADY = '1' ELSE ahbdrivedata(data_reg); | |||
----------------------------------------------------------------------------- | |||
--ren <= NOT ((AHB_Master_In.HGRANT(hindex) OR LAST_READ ) AND AHB_Master_In.HREADY ); | |||
--ren <= NOT beat; | |||
----------------------------------------------------------------------------- | |||
HREADY_falling <= inhib_ren WHEN AHB_Master_In.HREADY = '0' AND HREADY_pre = '1' ELSE '1'; | |||
PROCESS (clk, rstn) | |||
BEGIN -- PROCESS | |||
IF rstn = '0' THEN -- asynchronous reset (active low) | |||
state <= IDLE; | |||
done <= '0'; | |||
ren <= '1'; | |||
address_counter_reg <= (OTHERS => '0'); | |||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | |||
AHB_Master_Out.HBUSREQ <= '0'; | |||
AHB_Master_Out.HLOCK <= '0'; | |||
data_reg <= (OTHERS => '0'); | |||
HREADY_pre <= '0'; | |||
inhib_ren <= '0'; | |||
ELSIF clk'event AND clk = '1' THEN -- rising clock edge | |||
HREADY_pre <= AHB_Master_In.HREADY; | |||
IF AHB_Master_In.HREADY = '1' AND AHB_Master_In.HGRANT(hindex) = '1' THEN | |||
data_reg <= data; | |||
END IF; | |||
done <= '0'; | |||
ren <= '1'; | |||
inhib_ren <= '0'; | |||
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 | |||
state <= s_INIT_TRANS; | |||
END IF; | |||
WHEN s_INIT_TRANS => | |||
AHB_Master_Out.HBUSREQ <= '1'; | |||
AHB_Master_Out.HLOCK <= '1'; | |||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | |||
state <= s_ARBITER; | |||
WHEN s_ARBITER => | |||
AHB_Master_Out.HBUSREQ <= '1'; | |||
AHB_Master_Out.HLOCK <= '1'; | |||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | |||
address_counter_reg <= (OTHERS => '0'); | |||
IF AHB_Master_In.HREADY = '1' AND AHB_Master_In.HGRANT(hindex) = '1' THEN | |||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | |||
state <= s_CTRL; | |||
END IF; | |||
WHEN s_CTRL => | |||
inhib_ren <= '1'; | |||
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 | |||
--AHB_Master_Out.HTRANS <= HTRANS_SEQ; | |||
state <= s_CTRL_DATA; | |||
--ren <= '0'; | |||
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; | |||
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; | |||
WHEN s_DATA => | |||
ren <= HREADY_falling; | |||
AHB_Master_Out.HBUSREQ <= '0'; | |||
--AHB_Master_Out.HLOCK <= '0'; | |||
AHB_Master_Out.HTRANS <= HTRANS_IDLE; | |||
IF AHB_Master_In.HREADY = '1' THEN | |||
AHB_Master_Out.HLOCK <= '0'; | |||
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'; | |||
----------------------------------------------------------------------------- | |||
--ren <= NOT(AHB_Master_In.HREADY) WHEN state = s_CTRL_DATA ELSE '1'; | |||
----------------------------------------------------------------------------- | |||
--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; |