diff --git a/Makefile b/Makefile --- a/Makefile +++ b/Makefile @@ -61,6 +61,7 @@ Patched-dist: Patch-GRLIB doc: + mkdir -p doc/html cp doc/ressources/*.jpg doc/html/ cp doc/ressources/doxygen.css doc/html/ make -C lib/lpp doc diff --git a/lib/lpp/lpp_dma/fifo_latency_correction.vhd b/lib/lpp/lpp_dma/fifo_latency_correction.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_dma/fifo_latency_correction.vhd @@ -0,0 +1,190 @@ + +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; +USE GRLIB.DMA2AHB_Package.ALL; +LIBRARY lpp; +USE lpp.lpp_amba.ALL; +USE lpp.apb_devices_list.ALL; +USE lpp.lpp_memory.ALL; +LIBRARY techmap; +USE techmap.gencomp.ALL; + +ENTITY fifo_latency_correction IS + + PORT ( + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + + fifo_data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + fifo_empty : IN STD_LOGIC; + fifo_ren : OUT STD_LOGIC; + + dma_data : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + dma_empty : OUT STD_LOGIC; + dma_ren : IN STD_LOGIC + ); + +END fifo_latency_correction; + +ARCHITECTURE beh OF fifo_latency_correction IS + + SIGNAL valid_s1 : STD_LOGIC; + SIGNAL valid_s2 : STD_LOGIC; + + SIGNAL data_s1 : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL data_s2 : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL dma_data_s : STD_LOGIC_VECTOR(31 DOWNTO 0); + + + SIGNAL ren_s1 : STD_LOGIC; + SIGNAL ren_s2 : STD_LOGIC; + + SIGNAL fifo_ren_s : STD_LOGIC; +BEGIN -- beh + + + --fifo_data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + --fifo_empty : IN STD_LOGIC; + + --dma_ren : IN STD_LOGIC + + + PROCESS (HCLK, HRESETn) + BEGIN + IF HRESETn = '0' THEN + ren_s1 <= '1'; + ren_s2 <= '1'; + ELSIF HCLK'event AND HCLK = '1' THEN + ren_s1 <= fifo_ren_s; + ren_s2 <= fifo_ren_s; + END IF; + END PROCESS; + fifo_ren <= fifo_ren_s; + + PROCESS (HCLK, HRESETn) + BEGIN + IF HRESETn = '0' THEN + valid_s1 <= '0'; + --data_s1 <= (OTHERS => 'X'); -- TODO just for simulation + data_s1 <= (OTHERS => '0'); + ELSIF HCLK'event AND HCLK = '1' THEN + IF valid_s1 = '0' THEN + IF valid_s2 = '1' AND ren_s2 = '0' AND dma_ren = '1' THEN + valid_s1 <= '1'; + data_s1 <= fifo_data; + END IF; + ELSE + IF valid_s2 = '0' THEN + IF ren_s2 = '0' AND dma_ren = '1' THEN + valid_s1 <= '1'; + data_s1 <= fifo_data; + ELSE + valid_s1 <= '0'; +-- data_s1 <= (OTHERS => 'X'); -- TODO just for simulation + END IF; + ELSE + IF dma_ren = '1' THEN + valid_s1 <= '1'; + data_s1 <= data_s1; + ELSE + IF ren_s2 = '0' THEN + valid_s1 <= '1'; + data_s1 <= fifo_data; + ELSE + valid_s1 <= '0'; +-- data_s1 <= (OTHERS => 'X'); -- TODO just for simulation + END IF; + END IF; + END IF; + END IF; + END IF; + END PROCESS; + + PROCESS (HCLK, HRESETn) + BEGIN + IF HRESETn = '0' THEN + valid_s2 <= '0'; +-- data_s2 <= (OTHERS => 'X'); -- TODO just for simulation + data_s2 <= (OTHERS => '0'); + ELSIF HCLK'event AND HCLK = '1' THEN + IF valid_s2 = '0' THEN + IF dma_ren = '1' THEN + IF valid_s1 = '1' THEN + valid_s2 <= '1'; + data_s2 <= data_s1; + ELSE + IF ren_s2 = '0' THEN + valid_s2 <= '1'; + data_s2 <= fifo_data; + END IF; + END IF; + END IF; + ELSE + IF dma_ren = '1' THEN + valid_s2 <= '1'; + data_s2 <= data_s2; + ELSE + IF valid_s1 = '1' THEN + valid_s2 <= '1'; + data_s2 <= data_s1; + ELSE + IF ren_s2 = '0' THEN + valid_s2 <= '1'; + data_s2 <= fifo_data; + ELSE + valid_s2 <= '0'; +-- data_s2 <= (OTHERS => 'X'); -- TODO just for simulation + END IF; + END IF; + END IF; + END IF; + END IF; + END PROCESS; + +-- PROCESS (HCLK, HRESETn) +-- BEGIN +-- IF HRESETn = '0' THEN +-- dma_data <= (OTHERS => 'X'); +-- ELSIF HCLK'event AND HCLK = '1' THEN +-- IF valid_s2 = '1' THEN +-- dma_data <= data_s2; +-- ELSIF valid_s1 = '1' THEN +-- dma_data <= data_s1; +-- ELSIF ren_s2 = '0' THEN +-- dma_data <= fifo_data; +-- ELSE +-- dma_data <= (OTHERS => 'X'); +-- END IF; +-- END IF; +-- END PROCESS; + + + + dma_data_s <= data_s2 WHEN valid_s2 = '1' ELSE + data_s1 WHEN valid_s1 = '1' ELSE + fifo_data; + + PROCESS (HCLK, HRESETn) + BEGIN -- PROCESS + IF HRESETn = '0' THEN -- asynchronous reset (active low) + dma_data <= (OTHERS => '0'); + ELSIF HCLK'event AND HCLK = '1' THEN -- rising clock edge + IF dma_ren = '0' THEN + dma_data <= dma_data_s; + END IF; + END IF; + END PROCESS; + + fifo_ren_s <= '1' WHEN fifo_empty = '1' ELSE +-- '0' WHEN valid_s1 = '0' OR valid_s2 = '0' ELSE -- FIX test0 + '0' WHEN (valid_s1 = '0' OR valid_s2 = '0') AND ren_s2 = '1' ELSE -- FIX test0 + dma_ren; + + dma_empty <= fifo_empty AND (NOT valid_s1) AND (NOT valid_s2); + +END beh; diff --git a/lib/lpp/lpp_dma/fifo_test_dma.vhd b/lib/lpp/lpp_dma/fifo_test_dma.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_dma/fifo_test_dma.vhd @@ -0,0 +1,168 @@ +------------------------------------------------------------------------------ +-- 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 +---------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +LIBRARY grlib; +USE grlib.amba.ALL; +USE grlib.stdlib.ALL; +USE grlib.devices.ALL; +USE GRLIB.DMA2AHB_Package.ALL; +--USE GRLIB.DMA2AHB_TestPackage.ALL; +LIBRARY lpp; +USE lpp.lpp_amba.ALL; +USE lpp.apb_devices_list.ALL; +USE lpp.lpp_memory.ALL; +LIBRARY techmap; +USE techmap.gencomp.ALL; + +ENTITY fifo_test_dma IS + GENERIC ( + tech : INTEGER := apa3; + pindex : INTEGER := 0; + paddr : INTEGER := 0; + pmask : INTEGER := 16#fff# + ); + PORT ( + -- AMBA AHB system signals + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + + -- AMBA APB Slave Interface + apbi : IN apb_slv_in_type; + apbo : OUT apb_slv_out_type; + + -- FIFO Read interface + fifo_data : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + fifo_empty : OUT STD_LOGIC; + fifo_ren : IN STD_LOGIC; + + -- header + header : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + header_val : OUT STD_LOGIC; + header_ack : IN STD_LOGIC + ); +END; + +ARCHITECTURE Behavioral OF fifo_test_dma IS + CONSTANT REVISION : INTEGER := 1; + CONSTANT pconfig : apb_config_type := ( + 0 => ahb_device_reg (VENDOR_LPP, 0 , 0, REVISION, 0), + 1 => apb_iobar(paddr, pmask)); + + TYPE lpp_test_dma_regs IS RECORD + tt : STD_LOGIC; + END RECORD; + SIGNAL reg : lpp_test_dma_regs; + + SIGNAL prdata : STD_LOGIC_VECTOR(31 DOWNTO 0); + ----------------------------------------------------------------------------- + SIGNAL fifo_empty_s : STD_LOGIC; + SIGNAL fifo_raddr : STD_LOGIC_VECTOR(7 DOWNTO 0); + SIGNAL fifo_wen : STD_LOGIC; + SIGNAL fifo_wdata : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL fifo_full : STD_LOGIC; + SIGNAL fifo_waddr : STD_LOGIC_VECTOR(7 DOWNTO 0); + ----------------------------------------------------------------------------- + SIGNAL fifo_nb_data : STD_LOGIC_VECTOR( 7 DOWNTO 0); + SIGNAL fifo_nb_data_s : STD_LOGIC_VECTOR( 7 DOWNTO 0); + ----------------------------------------------------------------------------- + SIGNAL header_s : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL header_val_s : STD_LOGIC; +BEGIN + + lpp_fifo_i : lpp_fifo + GENERIC MAP ( + tech => tech, + Enable_ReUse => '0', + DataSz => 32, + abits => 8) + PORT MAP ( + rstn => HRESETn, + ReUse => '0', + + rclk => HCLK, + ren => fifo_ren, + rdata => fifo_data, + empty => fifo_empty_s, + raddr => fifo_raddr, + + wclk => HCLK, + wen => fifo_wen, + wdata => fifo_wdata, + full => fifo_full, + waddr => fifo_waddr); -- OUT + + fifo_nb_data_s(7) <= '1' WHEN (fifo_waddr < fifo_raddr) ELSE '0'; + fifo_nb_data_s(6 DOWNTO 0) <= (OTHERS => '0'); + fifo_nb_data <= (fifo_waddr - fifo_raddr) + fifo_nb_data_s; + + fifo_empty <= fifo_empty_s; + header <= header_s; + header_val <= header_val_s; + ----------------------------------------------------------------------------- + + apb_reg_p : PROCESS (HCLK, HRESETn) + VARIABLE paddr : STD_LOGIC_VECTOR(7 DOWNTO 2); + BEGIN -- PROCESS lpp_dma_top + IF HRESETn = '0' THEN -- asynchronous reset (active low) + prdata <= (OTHERS => '0'); + fifo_wdata <= (OTHERS => '0'); + fifo_wen <= '1'; + header_val_s <= '0'; + header_s <= (OTHERS => '0'); + ELSIF HCLK'EVENT AND HCLK = '1' THEN -- rising clock edge + paddr := "000000"; + paddr(7 DOWNTO 2) := apbi.paddr(7 DOWNTO 2); + fifo_wen <= '1'; + header_val_s <= header_val_s AND (NOT header_ack); + IF (apbi.psel(pindex)) = '1' THEN + -- APB DMA READ -- + CASE paddr(7 DOWNTO 2) IS + WHEN "000000" => prdata( 7 DOWNTO 0) <= fifo_waddr; + prdata(15 DOWNTO 8) <= fifo_raddr; + prdata(23 DOWNTO 16) <= fifo_nb_data; + prdata(24) <= fifo_full; + prdata(25) <= fifo_empty_s; + WHEN "000001" => prdata(31 DOWNTO 0) <= header_s; + + WHEN OTHERS => prdata <= (OTHERS => '0'); + END CASE; + IF (apbi.pwrite AND apbi.penable) = '1' THEN + -- APB DMA WRITE -- + CASE paddr(7 DOWNTO 2) IS + WHEN "000000" => fifo_wdata <= apbi.pwdata; + fifo_wen <= '0'; + WHEN "000001" => header_s <= apbi.pwdata; + header_val_s <= '1'; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + END IF; + END PROCESS apb_reg_p; + apbo.pirq <= (OTHERS => '0'); + apbo.pindex <= pindex; + apbo.pconfig <= pconfig; + apbo.prdata <= prdata; + +END Behavioral; diff --git a/lib/lpp/lpp_dma/lpp_dma.vhd b/lib/lpp/lpp_dma/lpp_dma.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_dma/lpp_dma.vhd @@ -0,0 +1,366 @@ +------------------------------------------------------------------------------ +-- 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 +---------------------------------------------------------------------------- +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; +USE GRLIB.DMA2AHB_Package.ALL; +--USE GRLIB.DMA2AHB_TestPackage.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; +LIBRARY techmap; +USE techmap.gencomp.ALL; + + +ENTITY lpp_dma IS + GENERIC ( + tech : INTEGER := inferred; + hindex : INTEGER := 2; + pindex : INTEGER := 4; + paddr : INTEGER := 4; + pmask : INTEGER := 16#fff#; + pirq : INTEGER := 0); + PORT ( + -- AMBA AHB system signals + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + + -- AMBA APB Slave Interface + apbi : IN apb_slv_in_type; + apbo : OUT apb_slv_out_type; + + -- AMBA AHB Master Interface + AHB_Master_In : IN AHB_Mst_In_Type; + AHB_Master_Out : OUT AHB_Mst_Out_Type; + + -- fifo interface + fifo_data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + fifo_empty : IN STD_LOGIC; + fifo_ren : OUT STD_LOGIC; + + -- header + header : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + header_val : IN STD_LOGIC; + header_ack : OUT STD_LOGIC + ); +END; + +ARCHITECTURE Behavioral OF lpp_dma IS + ----------------------------------------------------------------------------- + SIGNAL DMAIn : DMA_In_Type; + SIGNAL header_dmai : DMA_In_Type; + SIGNAL component_dmai : DMA_In_Type; + SIGNAL DMAOut : DMA_OUt_Type; + + SIGNAL ready_matrix_f0_0 : STD_LOGIC; + SIGNAL ready_matrix_f0_1 : STD_LOGIC; + SIGNAL ready_matrix_f1 : STD_LOGIC; + SIGNAL ready_matrix_f2 : STD_LOGIC; + SIGNAL error_anticipating_empty_fifo : STD_LOGIC; + SIGNAL error_bad_component_error : STD_LOGIC; + + SIGNAL config_active_interruption_onNewMatrix : STD_LOGIC; + SIGNAL config_active_interruption_onError : STD_LOGIC; + SIGNAL status_ready_matrix_f0_0 : STD_LOGIC; + SIGNAL status_ready_matrix_f0_1 : STD_LOGIC; + SIGNAL status_ready_matrix_f1 : STD_LOGIC; + SIGNAL status_ready_matrix_f2 : STD_LOGIC; + SIGNAL status_error_anticipating_empty_fifo : STD_LOGIC; + SIGNAL status_error_bad_component_error : STD_LOGIC; + SIGNAL addr_matrix_f0_0 : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL addr_matrix_f0_1 : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL addr_matrix_f1 : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL addr_matrix_f2 : STD_LOGIC_VECTOR(31 DOWNTO 0); + ----------------------------------------------------------------------------- + + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + TYPE state_DMAWriteBurst IS (IDLE, + TRASH_FIFO, + WAIT_HEADER_ACK, + SEND_DATA, + WAIT_DATA_ACK, + CHECK_LENGTH + ); + SIGNAL state : state_DMAWriteBurst := IDLE; + + SIGNAL nbSend : INTEGER; + SIGNAL matrix_type : STD_LOGIC_VECTOR(1 DOWNTO 0); + SIGNAL component_type : STD_LOGIC_VECTOR(3 DOWNTO 0); + SIGNAL component_type_pre : STD_LOGIC_VECTOR(3 DOWNTO 0); + SIGNAL header_check_ok : STD_LOGIC; + SIGNAL address_matrix : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL send_matrix : STD_LOGIC; + SIGNAL request : STD_LOGIC; + SIGNAL remaining_data_request : INTEGER; + SIGNAL Address : STD_LOGIC_VECTOR(31 DOWNTO 0); + ----------------------------------------------------------------------------- + ----------------------------------------------------------------------------- + SIGNAL header_select : STD_LOGIC; + + SIGNAL header_send : STD_LOGIC; + SIGNAL header_data : STD_LOGIC_VECTOR(31 DOWNTO 0); + SIGNAL header_send_ok : STD_LOGIC; + SIGNAL header_send_ko : STD_LOGIC; + + SIGNAL component_send : STD_LOGIC; + SIGNAL component_send_ok : STD_LOGIC; + SIGNAL component_send_ko : STD_LOGIC; + ----------------------------------------------------------------------------- + SIGNAL fifo_ren_trash : STD_LOGIC; + SIGNAL component_fifo_ren : STD_LOGIC; + +BEGIN + + ----------------------------------------------------------------------------- + -- DMA to AHB interface + ----------------------------------------------------------------------------- + + DMA2AHB_1 : DMA2AHB + GENERIC MAP ( + hindex => hindex, + vendorid => VENDOR_LPP, + deviceid => 0, + version => 0, + syncrst => 1, + boundary => 0) + PORT MAP ( + HCLK => HCLK, + HRESETn => HRESETn, + DMAIn => DMAIn, + DMAOut => DMAOut, + AHBIn => AHB_Master_In, + AHBOut => AHB_Master_Out); + + matrix_type <= header(1 DOWNTO 0); + component_type <= header(5 DOWNTO 2); + + send_matrix <= '1' WHEN matrix_type = "00" AND status_ready_matrix_f0_0 = '0' ELSE + '1' WHEN matrix_type = "01" AND status_ready_matrix_f0_1 = '0' ELSE + '1' WHEN matrix_type = "10" AND status_ready_matrix_f1 = '0' ELSE + '1' WHEN matrix_type = "11" AND status_ready_matrix_f2 = '0' ELSE + '0'; + + header_check_ok <= '0' WHEN component_type = "1111" ELSE + '1' WHEN component_type = "0000" AND component_type_pre = "1110" ELSE + '1' WHEN component_type = component_type_pre + "0001" ELSE + '0'; + + address_matrix <= addr_matrix_f0_0 WHEN matrix_type = "00" ELSE + addr_matrix_f0_1 WHEN matrix_type = "01" ELSE + addr_matrix_f1 WHEN matrix_type = "10" ELSE + addr_matrix_f2 WHEN matrix_type = "11" ELSE + (OTHERS => '0'); + + ----------------------------------------------------------------------------- + -- DMA control + ----------------------------------------------------------------------------- + DMAWriteFSM_p : PROCESS (HCLK, HRESETn) + BEGIN -- PROCESS DMAWriteBurst_p + IF HRESETn = '0' THEN -- asynchronous reset (active low) + state <= IDLE; + header_ack <= '0'; + ready_matrix_f0_0 <= '0'; + ready_matrix_f0_1 <= '0'; + ready_matrix_f1 <= '0'; + ready_matrix_f2 <= '0'; + error_anticipating_empty_fifo <= '0'; + error_bad_component_error <= '0'; + component_type_pre <= "1110"; + fifo_ren_trash <= '1'; + component_send <= '0'; + address <= (OTHERS => '0'); + header_select <= '0'; + ELSIF HCLK'EVENT AND HCLK = '1' THEN -- rising clock edge + + CASE state IS + WHEN IDLE => + ready_matrix_f0_0 <= '0'; + ready_matrix_f0_1 <= '0'; + ready_matrix_f1 <= '0'; + ready_matrix_f2 <= '0'; + error_bad_component_error <= '0'; + header_select <= '1'; + IF header_val = '1' AND fifo_empty = '0' AND send_matrix = '1' THEN + IF header_check_ok = '1' THEN + header_data <= header; + component_type_pre <= header(5 DOWNTO 2); + header_ack <= '1'; + -- + header_send <= '1'; + IF component_type = "0000" THEN + address <= address_matrix; + END IF; + header_data <= header; + -- + state <= WAIT_HEADER_ACK; + ELSE + error_bad_component_error <= '1'; + component_type_pre <= "1110"; + header_ack <= '1'; + state <= TRASH_FIFO; + END IF; + END IF; + + WHEN TRASH_FIFO => + error_bad_component_error <= '0'; + error_anticipating_empty_fifo <= '0'; + IF fifo_empty = '1' THEN + state <= IDLE; + fifo_ren_trash <= '1'; + ELSE + fifo_ren_trash <= '0'; + END IF; + + WHEN WAIT_HEADER_ACK => + header_send <= '0'; + IF header_send_ko = '1' THEN + state <= TRASH_FIFO; + error_anticipating_empty_fifo <= '1'; + -- TODO : error sending header + ELSIF header_send_ok = '1' THEN + header_select <= '0'; + state <= SEND_DATA; + address <= address + 4; + END IF; + + WHEN SEND_DATA => + IF fifo_empty = '1' THEN + state <= IDLE; + IF component_type = "1110" THEN + CASE matrix_type IS + WHEN "00" => ready_matrix_f0_0 <= '1'; + WHEN "01" => ready_matrix_f0_1 <= '1'; + WHEN "10" => ready_matrix_f1 <= '1'; + WHEN "11" => ready_matrix_f2 <= '1'; + WHEN OTHERS => NULL; + END CASE; + END IF; + ELSE + component_send <= '1'; + address <= address; + state <= WAIT_DATA_ACK; + END IF; + + WHEN WAIT_DATA_ACK => + component_send <= '0'; + IF component_send_ok = '1' THEN + address <= address + 64; + state <= SEND_DATA; + ELSIF component_send_ko = '1' THEN + error_anticipating_empty_fifo <= '0'; + state <= TRASH_FIFO; + END IF; + + WHEN CHECK_LENGTH => + state <= IDLE; + WHEN OTHERS => NULL; + END CASE; + + END IF; + END PROCESS DMAWriteFSM_p; + + ----------------------------------------------------------------------------- + -- SEND 1 word by DMA + ----------------------------------------------------------------------------- + lpp_dma_send_1word_1 : lpp_dma_send_1word + PORT MAP ( + HCLK => HCLK, + HRESETn => HRESETn, + DMAIn => header_dmai, + DMAOut => DMAOut, + + send => header_send, + address => address, + data => header_data, + send_ok => header_send_ok, + send_ko => header_send_ko + ); + + ----------------------------------------------------------------------------- + -- SEND 16 word by DMA (in burst mode) + ----------------------------------------------------------------------------- + lpp_dma_send_16word_1 : lpp_dma_send_16word + PORT MAP ( + HCLK => HCLK, + HRESETn => HRESETn, + DMAIn => component_dmai, + DMAOut => DMAOut, + + send => component_send, + address => address, + data => fifo_data, + ren => component_fifo_ren, + send_ok => component_send_ok, + send_ko => component_send_ko); + + DMAIn <= header_dmai WHEN header_select = '1' ELSE component_dmai; + fifo_ren <= fifo_ren_trash WHEN header_select = '1' ELSE component_fifo_ren; + + + ----------------------------------------------------------------------------- + -- APB REGISTER + ----------------------------------------------------------------------------- + + lpp_dma_apbreg_2 : lpp_dma_apbreg + GENERIC MAP ( + pindex => pindex, + paddr => paddr, + pmask => pmask, + pirq => pirq) + PORT MAP ( + HCLK => HCLK, + HRESETn => HRESETn, + apbi => apbi, + apbo => apbo, + -- IN + ready_matrix_f0_0 => ready_matrix_f0_0, + ready_matrix_f0_1 => ready_matrix_f0_1, + ready_matrix_f1 => ready_matrix_f1, + ready_matrix_f2 => ready_matrix_f2, + error_anticipating_empty_fifo => error_anticipating_empty_fifo, + error_bad_component_error => error_bad_component_error, + -- OUT + status_ready_matrix_f0_0 => status_ready_matrix_f0_0, + status_ready_matrix_f0_1 => status_ready_matrix_f0_1, + status_ready_matrix_f1 => status_ready_matrix_f1, + status_ready_matrix_f2 => status_ready_matrix_f2, + status_error_anticipating_empty_fifo => status_error_anticipating_empty_fifo, + status_error_bad_component_error => status_error_bad_component_error, + config_active_interruption_onNewMatrix => config_active_interruption_onNewMatrix, -- TODO + config_active_interruption_onError => config_active_interruption_onError, -- TODO + addr_matrix_f0_0 => addr_matrix_f0_0, + addr_matrix_f0_1 => addr_matrix_f0_1, + addr_matrix_f1 => addr_matrix_f1, + addr_matrix_f2 => addr_matrix_f2); + + ----------------------------------------------------------------------------- + +END Behavioral; + diff --git a/lib/lpp/lpp_dma/lpp_dma_apbreg.vhd b/lib/lpp/lpp_dma/lpp_dma_apbreg.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_dma/lpp_dma_apbreg.vhd @@ -0,0 +1,193 @@ +------------------------------------------------------------------------------ +-- 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 +---------------------------------------------------------------------------- +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; +LIBRARY techmap; +USE techmap.gencomp.ALL; +ENTITY lpp_dma_apbreg IS + GENERIC ( + pindex : INTEGER := 4; + paddr : INTEGER := 4; + pmask : INTEGER := 16#fff#; + pirq : INTEGER := 0); + PORT ( + -- AMBA AHB system signals + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + + -- AMBA APB Slave Interface + apbi : IN apb_slv_in_type; + apbo : OUT apb_slv_out_type; + + -- IN + ready_matrix_f0_0 : IN STD_LOGIC; + ready_matrix_f0_1 : IN STD_LOGIC; + ready_matrix_f1 : IN STD_LOGIC; + ready_matrix_f2 : IN STD_LOGIC; + error_anticipating_empty_fifo : IN STD_LOGIC; + error_bad_component_error : IN STD_LOGIC; + + -- OUT + status_ready_matrix_f0_0 : OUT STD_LOGIC; + status_ready_matrix_f0_1 : OUT STD_LOGIC; + status_ready_matrix_f1 : OUT STD_LOGIC; + status_ready_matrix_f2 : OUT STD_LOGIC; + status_error_anticipating_empty_fifo : OUT STD_LOGIC; + status_error_bad_component_error : OUT STD_LOGIC; + + config_active_interruption_onNewMatrix : OUT STD_LOGIC; + config_active_interruption_onError : OUT STD_LOGIC; + addr_matrix_f0_0 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f0_1 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f1 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f2 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0) + ); + +END lpp_dma_apbreg; + +ARCHITECTURE beh OF lpp_dma_apbreg IS + + CONSTANT REVISION : INTEGER := 1; + + CONSTANT pconfig : apb_config_type := ( + 0 => ahb_device_reg (VENDOR_LPP, LPP_DMA_TYPE, 0, REVISION, pirq), + 1 => apb_iobar(paddr, pmask)); + + TYPE lpp_dma_regs IS RECORD + config_active_interruption_onNewMatrix : STD_LOGIC; + config_active_interruption_onError : STD_LOGIC; + status_ready_matrix_f0_0 : STD_LOGIC; + status_ready_matrix_f0_1 : STD_LOGIC; + status_ready_matrix_f1 : STD_LOGIC; + status_ready_matrix_f2 : STD_LOGIC; + status_error_anticipating_empty_fifo : STD_LOGIC; + status_error_bad_component_error : STD_LOGIC; + addr_matrix_f0_0 : STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f0_1 : STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f1 : STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f2 : STD_LOGIC_VECTOR(31 DOWNTO 0); + END RECORD; + + SIGNAL reg : lpp_dma_regs; + + SIGNAL prdata : STD_LOGIC_VECTOR(31 DOWNTO 0); + +BEGIN -- beh + + status_ready_matrix_f0_0 <= reg.status_ready_matrix_f0_0; + status_ready_matrix_f0_1 <= reg.status_ready_matrix_f0_1; + status_ready_matrix_f1 <= reg.status_ready_matrix_f1; + status_ready_matrix_f2 <= reg.status_ready_matrix_f2; + status_error_anticipating_empty_fifo <= reg.status_error_anticipating_empty_fifo; + status_error_bad_component_error <= reg.status_error_bad_component_error; + + config_active_interruption_onNewMatrix <= reg.config_active_interruption_onNewMatrix; + config_active_interruption_onError <= reg.config_active_interruption_onError; + addr_matrix_f0_0 <= reg.addr_matrix_f0_0; + addr_matrix_f0_1 <= reg.addr_matrix_f0_1; + addr_matrix_f1 <= reg.addr_matrix_f1; + addr_matrix_f2 <= reg.addr_matrix_f2; + + lpp_dma_apbreg : PROCESS (HCLK, HRESETn) + VARIABLE paddr : STD_LOGIC_VECTOR(7 DOWNTO 2); + BEGIN -- PROCESS lpp_dma_top + IF HRESETn = '0' THEN -- asynchronous reset (active low) + reg.config_active_interruption_onNewMatrix <= '0'; + reg.config_active_interruption_onError <= '0'; + reg.status_ready_matrix_f0_0 <= '0'; + reg.status_ready_matrix_f0_1 <= '0'; + reg.status_ready_matrix_f1 <= '0'; + reg.status_ready_matrix_f2 <= '0'; + reg.status_error_anticipating_empty_fifo <= '0'; + reg.status_error_bad_component_error <= '0'; + reg.addr_matrix_f0_0 <= (OTHERS => '0'); + reg.addr_matrix_f0_1 <= (OTHERS => '0'); + reg.addr_matrix_f1 <= (OTHERS => '0'); + reg.addr_matrix_f2 <= (OTHERS => '0'); + prdata <= (OTHERS => '0'); + ELSIF HCLK'EVENT AND HCLK = '1' THEN -- rising clock edge + + reg.status_ready_matrix_f0_0 <= reg.status_ready_matrix_f0_0 OR ready_matrix_f0_0; + reg.status_ready_matrix_f0_1 <= reg.status_ready_matrix_f0_1 OR ready_matrix_f0_1; + reg.status_ready_matrix_f1 <= reg.status_ready_matrix_f1 OR ready_matrix_f1; + reg.status_ready_matrix_f2 <= reg.status_ready_matrix_f2 OR ready_matrix_f2; + + reg.status_error_anticipating_empty_fifo <= reg.status_error_anticipating_empty_fifo OR error_anticipating_empty_fifo; + reg.status_error_bad_component_error <= reg.status_error_bad_component_error OR error_bad_component_error; + + paddr := "000000"; + paddr(7 DOWNTO 2) := apbi.paddr(7 DOWNTO 2); + prdata <= (OTHERS => '0'); + IF apbi.psel(pindex) = '1' THEN + -- APB DMA READ -- + CASE paddr(7 DOWNTO 2) IS + WHEN "000000" => prdata(0) <= reg.config_active_interruption_onNewMatrix; + prdata(1) <= reg.config_active_interruption_onError; + WHEN "000001" => prdata(0) <= reg.status_ready_matrix_f0_0; + prdata(1) <= reg.status_ready_matrix_f0_1; + prdata(2) <= reg.status_ready_matrix_f1; + prdata(3) <= reg.status_ready_matrix_f2; + prdata(4) <= reg.status_error_anticipating_empty_fifo; + prdata(5) <= reg.status_error_bad_component_error; + WHEN "000010" => prdata <= reg.addr_matrix_f0_0; + WHEN "000011" => prdata <= reg.addr_matrix_f0_1; + WHEN "000100" => prdata <= reg.addr_matrix_f1; + WHEN "000101" => prdata <= reg.addr_matrix_f2; + WHEN OTHERS => NULL; + END CASE; + IF (apbi.pwrite AND apbi.penable) = '1' THEN + -- APB DMA WRITE -- + CASE paddr(7 DOWNTO 2) IS + WHEN "000000" => reg.config_active_interruption_onNewMatrix <= apbi.pwdata(0); + reg.config_active_interruption_onError <= apbi.pwdata(1); + WHEN "000001" => reg.status_ready_matrix_f0_0 <= apbi.pwdata(0); + reg.status_ready_matrix_f0_1 <= apbi.pwdata(1); + reg.status_ready_matrix_f1 <= apbi.pwdata(2); + reg.status_ready_matrix_f2 <= apbi.pwdata(3); + reg.status_error_anticipating_empty_fifo <= apbi.pwdata(4); + reg.status_error_bad_component_error <= apbi.pwdata(5); + WHEN "000010" => reg.addr_matrix_f0_0 <= apbi.pwdata; + WHEN "000011" => reg.addr_matrix_f0_1 <= apbi.pwdata; + WHEN "000100" => reg.addr_matrix_f1 <= apbi.pwdata; + WHEN "000101" => reg.addr_matrix_f2 <= apbi.pwdata; + WHEN OTHERS => NULL; + END CASE; + END IF; + END IF; + END IF; + END PROCESS lpp_dma_apbreg; + apbo.pirq <= (OTHERS => '0'); + apbo.pindex <= pindex; + apbo.pconfig <= pconfig; + apbo.prdata <= prdata; + +END beh; diff --git a/lib/lpp/lpp_dma/lpp_dma_fsm.vhd b/lib/lpp/lpp_dma/lpp_dma_fsm.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_dma/lpp_dma_fsm.vhd @@ -0,0 +1,164 @@ +------------------------------------------------------------------------------ +-- 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 +---------------------------------------------------------------------------- +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; +LIBRARY techmap; +USE techmap.gencomp.ALL; + +ENTITY lpp_dma_fsm IS + PORT ( + -- AMBA AHB system signals + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + + -- AMBA APB Slave Interface + apbi : IN apb_slv_in_type; + apbo : OUT apb_slv_out_type; + + -- AMBA AHB Master Interface + AHB_Master_In : IN AHB_Mst_In_Type; + AHB_Master_Out : OUT AHB_Mst_Out_Type; + + -- fifo interface + fifo_data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + fifo_empty : IN STD_LOGIC; + fifo_ren : OUT STD_LOGIC; + + -- header + header : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + header_val : IN STD_LOGIC; + header_ack : OUT STD_LOGIC; + + + -- OUT + ready_matrix_f0_0 : OUT STD_LOGIC; -- TODO + ready_matrix_f0_1 : OUT STD_LOGIC; -- TODO + ready_matrix_f1 : OUT STD_LOGIC; -- TODO + ready_matrix_f2 : OUT STD_LOGIC; -- TODO + error_anticipating_empty_fifo : OUT STD_LOGIC; -- TODO + error_bad_component_error : OUT STD_LOGIC; -- TODO + + -- IN + status_ready_matrix_f0_0 : IN STD_LOGIC; + status_ready_matrix_f0_1 : IN STD_LOGIC; + status_ready_matrix_f1 : IN STD_LOGIC; + status_ready_matrix_f2 : IN STD_LOGIC; + status_error_anticipating_empty_fifo : IN STD_LOGIC; -- TODO + status_error_bad_component_error : IN STD_LOGIC; -- TODO + + config_active_interruption_onNewMatrix : IN STD_LOGIC; + config_active_interruption_onError : IN STD_LOGIC; + addr_matrix_f0_0 : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f0_1 : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f1 : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f2 : IN STD_LOGIC_VECTOR(31 DOWNTO 0) + ); +END lpp_dma_fsm; + +ARCHITECTURE beh OF lpp_dma_fsm IS + ----------------------------------------------------------------------------- + -- HEADER check and update + ----------------------------------------------------------------------------- + SIGNAL send_matrix_val : STD_LOGIC; + SIGNAL current_header : STD_LOGIC_VECTOR(31 DOWNTO 0); + ----------------------------------------------------------------------------- + SIGNAL send_matrix : STD_LOGIC; + SIGNAL trash_matrix : STD_LOGIC; + SIGNAL get_new_header : STD_LOGIC; + ----------------------------------------------------------------------------- + -- CONTROL SEND COMPONENT + ----------------------------------------------------------------------------- + TYPE state_fsm_send_component IS (IDLE, + CHECK_HEADER, + TRASH_FIFO, + + PACKET_IDLE,REQUEST_BUS,SEND_DATA_nextADDRESS,FAULT1,FAULT2); +BEGIN -- beh + + ----------------------------------------------------------------------------- + -- HEADER check and update + ----------------------------------------------------------------------------- + + PROCESS (HCLK, HRESETn) + BEGIN -- PROCESS + IF HRESETn = '0' THEN -- asynchronous reset (active low) + current_header <= (OTHERS => '0'); + header_ack <= '0'; + ELSIF HCLK'EVENT AND HCLK = '1' THEN -- rising clock edge + IF get_new_header = '1' AND header_val = '1' THEN + IF send_matrix_val = '1' THEN + current_header <= header; + header_ack <= '1'; + send_matrix <= component_val; + trash_matrix <= (NOT component_val) OR (trash_matrix AND NOT (header(5 DOWNTO 2) = "0000")); + END IF; + ELSE + current_header <= current_header; + header_ack <= '0'; + send_matrix <= '0'; + trash_matrix <= '0'; + END IF; + END IF; + END PROCESS; + + send_matrix_val <= '1' WHEN header(1 DOWNTO 0) = "00" AND status_ready_matrix_f0_0 = '0' ELSE + '1' WHEN header(1 DOWNTO 0) = "01" AND status_ready_matrix_f0_1 = '0' ELSE + '1' WHEN header(1 DOWNTO 0) = "10" AND status_ready_matrix_f1 = '0' ELSE + '1' WHEN header(1 DOWNTO 0) = "11" AND status_ready_matrix_f2 = '0' ELSE + '0'; + + component_val <= '0' WHEN header(5 DOWNTO 2) = "1111" ELSE + '1' WHEN header(5 DOWNTO 2) = "0000" ELSE + '1' WHEN header(5 DOWNTO 2) = current_header(5 DOWNTO 2) + "0001" ELSE + '0'; + + --OUT + --send_matrix + --trash_matrix + + --IN + --get_new_header + + ----------------------------------------------------------------------------- + -- CONTROL SEND COMPONENT + ----------------------------------------------------------------------------- + fsm_send_component: PROCESS (HCLK, HRESETn) + BEGIN -- PROCESS fsm_send_component + IF HRESETn = '0' THEN -- asynchronous reset (active low) + + ELSIF HCLK'event AND HCLK = '1' THEN -- rising clock edge + + END IF; + END PROCESS fsm_send_component; + + +END beh; diff --git a/lib/lpp/lpp_dma/lpp_dma_pkg.vhd b/lib/lpp/lpp_dma/lpp_dma_pkg.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_dma/lpp_dma_pkg.vhd @@ -0,0 +1,163 @@ +------------------------------------------------------------------------------ +-- 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 +---------------------------------------------------------------------------- +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +LIBRARY grlib; +USE grlib.amba.ALL; +USE std.textio.ALL; +LIBRARY grlib; +USE grlib.amba.ALL; +USE grlib.stdlib.ALL; +USE GRLIB.DMA2AHB_Package.ALL; +LIBRARY techmap; +USE techmap.gencomp.ALL; +LIBRARY lpp; +USE lpp.lpp_amba.ALL; +USE lpp.apb_devices_list.ALL; +USE lpp.lpp_memory.ALL; + +PACKAGE lpp_dma_pkg IS + + COMPONENT lpp_dma + GENERIC ( + tech : INTEGER; + hindex : INTEGER; + pindex : INTEGER; + paddr : INTEGER; + pmask : INTEGER; + pirq : INTEGER); + PORT ( + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + apbi : IN apb_slv_in_type; + apbo : OUT apb_slv_out_type; + AHB_Master_In : IN AHB_Mst_In_Type; + AHB_Master_Out : OUT AHB_Mst_Out_Type; + -- fifo interface + fifo_data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + fifo_empty : IN STD_LOGIC; + fifo_ren : OUT STD_LOGIC; + -- header + header : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + header_val : IN STD_LOGIC; + header_ack : OUT STD_LOGIC); + END COMPONENT; + + COMPONENT fifo_test_dma + GENERIC ( + tech : INTEGER; + pindex : INTEGER; + paddr : INTEGER; + pmask : INTEGER); + PORT ( + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + apbi : IN apb_slv_in_type; + apbo : OUT apb_slv_out_type; + -- fifo interface + fifo_data : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + fifo_empty : OUT STD_LOGIC; + fifo_ren : IN STD_LOGIC; + -- header + header : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + header_val : OUT STD_LOGIC; + header_ack : IN STD_LOGIC + ); + END COMPONENT; + + COMPONENT lpp_dma_apbreg + GENERIC ( + pindex : INTEGER; + paddr : INTEGER; + pmask : INTEGER; + pirq : INTEGER); + PORT ( + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + apbi : IN apb_slv_in_type; + apbo : OUT apb_slv_out_type; + -- IN + ready_matrix_f0_0 : IN STD_LOGIC; + ready_matrix_f0_1 : IN STD_LOGIC; + ready_matrix_f1 : IN STD_LOGIC; + ready_matrix_f2 : IN STD_LOGIC; + error_anticipating_empty_fifo : IN STD_LOGIC; + error_bad_component_error : IN STD_LOGIC; + + -- OUT + status_ready_matrix_f0_0 : OUT STD_LOGIC; + status_ready_matrix_f0_1 : OUT STD_LOGIC; + status_ready_matrix_f1 : OUT STD_LOGIC; + status_ready_matrix_f2 : OUT STD_LOGIC; + status_error_anticipating_empty_fifo : OUT STD_LOGIC; + status_error_bad_component_error : OUT STD_LOGIC; + + config_active_interruption_onNewMatrix : OUT STD_LOGIC; + config_active_interruption_onError : OUT STD_LOGIC; + addr_matrix_f0_0 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f0_1 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f1 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + addr_matrix_f2 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0) + ); + END COMPONENT; + + COMPONENT lpp_dma_send_1word + PORT ( + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + DMAIn : OUT DMA_In_Type; + DMAOut : IN DMA_OUt_Type; + send : IN STD_LOGIC; + address : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + send_ok : OUT STD_LOGIC; + send_ko : OUT STD_LOGIC); + END COMPONENT; + + COMPONENT lpp_dma_send_16word + PORT ( + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + DMAIn : OUT DMA_In_Type; + DMAOut : IN DMA_OUt_Type; + send : IN STD_LOGIC; + address : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + ren : OUT STD_LOGIC; + send_ok : OUT STD_LOGIC; + send_ko : OUT STD_LOGIC); + END COMPONENT; + + COMPONENT fifo_latency_correction + PORT ( + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + fifo_data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + fifo_empty : IN STD_LOGIC; + fifo_ren : OUT STD_LOGIC; + dma_data : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); + dma_empty : OUT STD_LOGIC; + dma_ren : IN STD_LOGIC); + END COMPONENT; + +END; diff --git a/lib/lpp/lpp_dma/lpp_dma_send_16word.vhd b/lib/lpp/lpp_dma/lpp_dma_send_16word.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_dma/lpp_dma_send_16word.vhd @@ -0,0 +1,160 @@ + +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; +USE GRLIB.DMA2AHB_Package.ALL; +LIBRARY lpp; +USE lpp.lpp_amba.ALL; +USE lpp.apb_devices_list.ALL; +USE lpp.lpp_memory.ALL; +LIBRARY techmap; +USE techmap.gencomp.ALL; + +ENTITY lpp_dma_send_16word IS + PORT ( + -- AMBA AHB system signals + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + + -- DMA + DMAIn : OUT DMA_In_Type; + DMAOut : IN DMA_OUt_Type; + + -- + send : IN STD_LOGIC; + address : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + ren : OUT STD_LOGIC; + -- + send_ok : OUT STD_LOGIC; + send_ko : OUT STD_LOGIC + ); +END lpp_dma_send_16word; + +ARCHITECTURE beh OF lpp_dma_send_16word IS + + TYPE state_fsm_send_16word IS (IDLE, REQUEST_BUS, SEND_DATA, ERROR0, ERROR1,WAIT_LAST_READY); + SIGNAL state : state_fsm_send_16word; + + SIGNAL data_counter : INTEGER; + SIGNAL grant_counter : INTEGER; + +BEGIN -- beh + + DMAIn.Beat <= HINCR16; + DMAIn.Size <= HSIZE32; + + PROCESS (HCLK, HRESETn) + BEGIN -- PROCESS + IF HRESETn = '0' THEN -- asynchronous reset (active low) + state <= IDLE; + send_ok <= '0'; + send_ko <= '0'; + + DMAIn.Reset <= '0'; + DMAIn.Address <= (OTHERS => '0'); +-- DMAIn.Data <= (others => '0'); + DMAIn.Request <= '0'; + DMAIn.Store <= '0'; + DMAIn.Burst <= '1'; + DMAIn.Lock <= '0'; + data_counter <= 0; + ELSIF HCLK'EVENT AND HCLK = '1' THEN -- rising clock edge + + CASE state IS + WHEN IDLE => +-- ren <= '1'; + DMAIn.Store <= '1'; + DMAIn.Request <= '0'; + send_ok <= '0'; + send_ko <= '0'; + DMAIn.Address <= address; + data_counter <= 0; + DMAIn.Lock <= '0'; -- FIX test + IF send = '1' THEN + state <= REQUEST_BUS; + DMAIn.Request <= '1'; + DMAIn.Lock <= '1'; -- FIX test + DMAIn.Store <= '1'; + END IF; + WHEN REQUEST_BUS => +-- ren <= '1'; + IF DMAOut.Grant='1' THEN + data_counter <= 1; + grant_counter <= 1; +-- ren <= '0'; + state <= SEND_DATA; + END IF; + WHEN SEND_DATA => +-- ren <= '1'; + + IF DMAOut.Fault = '1' THEN + DMAIn.Reset <= '0'; + DMAIn.Address <= (others => '0'); +-- DMAIn.Data <= (others => '0'); + DMAIn.Request <= '0'; + DMAIn.Store <= '0'; + DMAIn.Burst <= '0'; + state <= ERROR0; + ELSE + + IF DMAOut.Grant = '1' THEN + if grant_counter = 15 then + DMAIn.Reset <= '0'; + DMAIn.Request <= '0'; + DMAIn.Store <= '0'; + DMAIn.Burst <= '0'; + else + grant_counter <= grant_counter+1; + end if; + END IF; + + IF DMAOut.OKAY = '1' THEN + IF data_counter = 15 THEN + DMAIn.Address <= (others => '0'); + state <= WAIT_LAST_READY; + ELSE + --DMAIn.Data <= data; + data_counter <= data_counter + 1; +-- ren <= '0'; + END IF; + END IF; + END IF; + + + WHEN WAIT_LAST_READY => +-- ren <= '1'; + IF DMAOut.Ready = '1' THEN + IF grant_counter = 15 THEN + state <= IDLE; + send_ok <= '1'; + send_ko <= '0'; + ELSE + state <= ERROR0; + END IF; + END IF; + + WHEN ERROR0 => +-- ren <= '1'; + state <= ERROR1; + WHEN ERROR1 => + send_ok <= '0'; + send_ko <= '1'; +-- ren <= '1'; + state <= IDLE; + WHEN OTHERS => NULL; + END CASE; + END IF; + END PROCESS; + + DMAIn.Data <= data; + + ren <= '0' WHEN DMAOut.OKAY = '1' AND state = SEND_DATA ELSE + '0' WHEN state = REQUEST_BUS AND DMAOut.Grant = '1' ELSE + '1'; + +END beh; diff --git a/lib/lpp/lpp_dma/lpp_dma_send_1word.vhd b/lib/lpp/lpp_dma/lpp_dma_send_1word.vhd new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_dma/lpp_dma_send_1word.vhd @@ -0,0 +1,101 @@ + +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; +USE GRLIB.DMA2AHB_Package.ALL; +LIBRARY lpp; +USE lpp.lpp_amba.ALL; +USE lpp.apb_devices_list.ALL; +USE lpp.lpp_memory.ALL; +LIBRARY techmap; +USE techmap.gencomp.ALL; + +ENTITY lpp_dma_send_1word IS + PORT ( + -- AMBA AHB system signals + HCLK : IN STD_ULOGIC; + HRESETn : IN STD_ULOGIC; + + -- DMA + DMAIn : OUT DMA_In_Type; + DMAOut : IN DMA_OUt_Type; + -- + send : IN STD_LOGIC; + address : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + data : IN STD_LOGIC_VECTOR(31 DOWNTO 0); + -- + send_ok : OUT STD_LOGIC; + send_ko : OUT STD_LOGIC + ); +END lpp_dma_send_1word; + +ARCHITECTURE beh OF lpp_dma_send_1word IS + + TYPE state_fsm_send_1word IS (IDLE, REQUEST_BUS, SEND_DATA, ERROR0, ERROR1); + SIGNAL state : state_fsm_send_1word; + +BEGIN -- beh + + DMAIn.Reset <= '0'; + DMAIn.Address <= address; + DMAIn.Data <= data; + DMAIn.Beat <= (OTHERS => '0'); + DMAIn.Size <= HSIZE32; + DMAIn.Burst <= '0'; + + PROCESS (HCLK, HRESETn) + BEGIN -- PROCESS + IF HRESETn = '0' THEN -- asynchronous reset (active low) + state <= IDLE; + DMAIn.Request <= '0'; + DMAIn.Store <= '0'; + send_ok <= '0'; + send_ko <= '0'; + DMAIn.Lock <= '0'; + ELSIF HCLK'EVENT AND HCLK = '1' THEN -- rising clock edge + CASE state IS + WHEN IDLE => + DMAIn.Store <= '1'; + DMAIn.Request <= '0'; + send_ok <= '0'; + send_ko <= '0'; + DMAIn.Lock <= '0'; + IF send = '1' THEN + DMAIn.Request <= '1'; + DMAIn.Lock <= '1'; + state <= REQUEST_BUS; + END IF; + WHEN REQUEST_BUS => + IF DMAOut.Grant = '1' THEN + DMAIn.Request <= '0'; + DMAIn.Store <= '0'; + state <= SEND_DATA; + END IF; + WHEN SEND_DATA => + IF DMAOut.Fault = '1' THEN + DMAIn.Request <= '0'; + DMAIn.Store <= '0'; + state <= ERROR0; + ELSIF DMAOut.Ready = '1' THEN + DMAIn.Request <= '0'; + DMAIn.Store <= '0'; + send_ok <= '1'; + send_ko <= '0'; + state <= IDLE; + END IF; + WHEN ERROR0 => + state <= ERROR1; + WHEN ERROR1 => + send_ok <= '0'; + send_ko <= '1'; + state <= IDLE; + WHEN OTHERS => NULL; + END CASE; + END IF; + END PROCESS; + +END beh; diff --git a/lib/lpp/lpp_dma/vhdlsyn.txt b/lib/lpp/lpp_dma/vhdlsyn.txt new file mode 100644 --- /dev/null +++ b/lib/lpp/lpp_dma/vhdlsyn.txt @@ -0,0 +1,7 @@ +fifo_test_dma.vhd +fifo_latency_correction.vhd +lpp_dma_send_1word.vhd +lpp_dma_send_16word.vhd +lpp_dma_apbreg.vhd +lpp_dma.vhd +lpp_dma_pkg.vhd