##// END OF EJS Templates
Few fixes....
Few fixes. Whole LFR simulation WIP.

File last commit:

r229:8ff242376ddf JC
r682:c53e1b6b3045 default
Show More
lpp_waveform_dma.vhd
377 lines | 14.3 KiB | text/x-vhdl | VhdlLexer
------------------------------------------------------------------------------
-- 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
-- 1.1 - (01/11/2013) FIX boundary error (1kB address should not be crossed by BURSTS)
-------------------------------------------------------------------------------
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;
USE lpp.lpp_dma_pkg.ALL;
USE lpp.lpp_waveform_pkg.ALL;
LIBRARY techmap;
USE techmap.gencomp.ALL;
ENTITY lpp_waveform_dma IS
GENERIC (
data_size : INTEGER := 160;
tech : INTEGER := inferred;
hindex : INTEGER := 2;
nb_burst_available_size : INTEGER := 11
);
PORT (
-- AMBA AHB system signals
HCLK : IN STD_ULOGIC;
HRESETn : IN STD_ULOGIC;
--
run : IN STD_LOGIC;
-- AMBA AHB Master Interface
AHB_Master_In : IN AHB_Mst_In_Type;
AHB_Master_Out : OUT AHB_Mst_Out_Type;
--
enable : IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- todo
time_ready : IN STD_LOGIC_VECTOR(3 DOWNTO 0); -- todo
data_ready : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
data : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
data_data_ren : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
data_time_ren : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
-- Reg
nb_burst_available : IN STD_LOGIC_VECTOR(nb_burst_available_size-1 DOWNTO 0);
status_full : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
status_full_ack : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
status_full_err : OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
-- status_new_err : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); -- New data f(i) before the current data is write by dma
addr_data_f0 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
addr_data_f1 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
addr_data_f2 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
addr_data_f3 : IN STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END;
ARCHITECTURE Behavioral OF lpp_waveform_dma IS
-----------------------------------------------------------------------------
SIGNAL DMAIn : DMA_In_Type;
SIGNAL DMAOut : DMA_OUt_Type;
-----------------------------------------------------------------------------
TYPE state_DMAWriteBurst IS (IDLE,TRASH_FIFO_TIME,TRASH_FIFO_DATA,
SEND_TIME_0, WAIT_TIME_0,
SEND_TIME_1, WAIT_TIME_1,
SEND_5_TIME,
SEND_DATA, WAIT_DATA);
SIGNAL state : state_DMAWriteBurst ;
-----------------------------------------------------------------------------
-- CONTROL
SIGNAL sel_data_s : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL sel_data_ss : STD_LOGIC;
SIGNAL sel_time_s : STD_LOGIC;
SIGNAL sel_data : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL update : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL time_select : STD_LOGIC;
SIGNAL enable_sel : STD_LOGIC;
SIGNAL time_write : STD_LOGIC;
SIGNAL time_already_send : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL time_already_send_s : STD_LOGIC;
-----------------------------------------------------------------------------
-- SEND TIME MODULE
SIGNAL time_dmai : DMA_In_Type;
SIGNAL time_send : STD_LOGIC;
SIGNAL time_send_ok : STD_LOGIC;
SIGNAL time_send_ko : STD_LOGIC;
SIGNAL time_fifo_ren : STD_LOGIC;
SIGNAL time_ren : STD_LOGIC;
-----------------------------------------------------------------------------
-- SEND DATA MODULE
SIGNAL data_dmai : DMA_In_Type;
SIGNAL data_send : STD_LOGIC;
SIGNAL data_send_ok : STD_LOGIC;
SIGNAL data_send_ko : STD_LOGIC;
SIGNAL data_fifo_ren : STD_LOGIC;
SIGNAL trash_fifo_ren : STD_LOGIC;
SIGNAL data_ren : STD_LOGIC;
-----------------------------------------------------------------------------
-- SELECT ADDRESS
SIGNAL data_address : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL update_and_sel : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL addr_data_reg_vector : STD_LOGIC_VECTOR(32*4-1 DOWNTO 0);
SIGNAL addr_data_vector : STD_LOGIC_VECTOR(32*4-1 DOWNTO 0);
-----------------------------------------------------------------------------
SIGNAL send_16_3_time_reg : STD_LOGIC_VECTOR(3*4-1 DOWNTO 0);
SIGNAL send_16_3_time_reg_s : STD_LOGIC_VECTOR(3*4-1 DOWNTO 0);
-----------------------------------------------------------------------------
SIGNAL send_16_3_time : STD_LOGIC;
SIGNAL count_send_time : INTEGER;
-----------------------------------------------------------------------------
SIGNAL data_2_halfword : STD_LOGIC_VECTOR(31 DOWNTO 0); -- todo
BEGIN
-----------------------------------------------------------------------------
-- DMA to AHB interface
DMA2AHB_1 : DMA2AHB
GENERIC MAP (
hindex => hindex,
vendorid => VENDOR_LPP,
deviceid => 10,
version => 0,
syncrst => 1,
boundary => 1) -- FIX 11/01/2013
PORT MAP (
HCLK => HCLK,
HRESETn => HRESETn,
DMAIn => DMAIn,
DMAOut => DMAOut,
AHBIn => AHB_Master_In,
AHBOut => AHB_Master_Out);
-----------------------------------------------------------------------------
-----------------------------------------------------------------------------
-- This module memorises when the Times info are write. When FSM send
-- the Times info, the "reg" is set and when a full_ack is received the "reg" is reset.
all_time_write : FOR I IN 3 DOWNTO 0 GENERATE
PROCESS (HCLK, HRESETn)
BEGIN -- PROCESS
IF HRESETn = '0' THEN -- asynchronous reset (active low)
time_already_send(I) <= '0';
ELSIF HCLK'EVENT AND HCLK = '1' THEN -- rising clock edge
IF time_write = '1' AND UNSIGNED(sel_data) = I THEN
time_already_send(I) <= '1';
ELSIF status_full_ack(I) = '1' THEN
time_already_send(I) <= '0';
END IF;
END IF;
END PROCESS;
END GENERATE all_time_write;
-----------------------------------------------------------------------------
sel_data_s <= "00" WHEN data_ready(0) = '1' ELSE
"01" WHEN data_ready(1) = '1' ELSE
"10" WHEN data_ready(2) = '1' ELSE
"11";
sel_data_ss <= data_ready(0) WHEN sel_data = "00" ELSE
data_ready(1) WHEN sel_data = "01" ELSE
data_ready(2) WHEN sel_data = "10" ELSE
data_ready(3);
sel_time_s <= time_ready(0) WHEN sel_data = "00" ELSE
time_ready(1) WHEN sel_data = "01" ELSE
time_ready(2) WHEN sel_data = "10" ELSE
time_ready(3);
enable_sel <= enable(0) WHEN sel_data = "00" ELSE
enable(1) WHEN sel_data = "01" ELSE
enable(2) WHEN sel_data = "10" ELSE
enable(3);
time_already_send_s <= time_already_send(0) WHEN data_ready(0) = '1' ELSE
time_already_send(1) WHEN data_ready(1) = '1' ELSE
time_already_send(2) WHEN data_ready(2) = '1' ELSE
time_already_send(3);
-- DMA control
DMAWriteFSM_p : PROCESS (HCLK, HRESETn)
BEGIN -- PROCESS DMAWriteBurst_p
IF HRESETn = '0' THEN
state <= IDLE;
sel_data <= "00";
update <= "00";
time_select <= '0';
time_fifo_ren <= '1';
trash_fifo_ren <= '1';
data_send <= '0';
time_send <= '0';
time_write <= '0';
count_send_time <= 0;
ELSIF HCLK'EVENT AND HCLK = '1' THEN
CASE state IS
WHEN IDLE =>
count_send_time <= 0;
sel_data <= "00";
update <= "00";
time_select <= '0';
time_fifo_ren <= '1';
data_send <= '0';
time_send <= '0';
time_write <= '0';
trash_fifo_ren <= '1';
IF data_ready = "0000" THEN
state <= IDLE;
ELSE
sel_data <= sel_data_s;
IF enable_sel = '1' THEN
state <= SEND_5_TIME;
ELSE
state <= TRASH_FIFO_TIME;
END IF;
END IF;
WHEN TRASH_FIFO_TIME =>
time_select <= '1';
time_fifo_ren <= '0';
IF sel_time_s = '1' THEN
time_fifo_ren <= '1';
state <= TRASH_FIFO_DATA;
END IF;
WHEN TRASH_FIFO_DATA =>
time_select <= '1';
trash_fifo_ren <= '0';
IF sel_data_ss = '1' THEN
trash_fifo_ren <= '1';
state <= IDLE;
END IF;
WHEN SEND_5_TIME =>
update <= "00";
time_select <= '1';
time_fifo_ren <= '0';
count_send_time <= count_send_time + 1;
IF count_send_time = 10 THEN
state <= SEND_DATA;
END IF;
WHEN SEND_DATA =>
time_fifo_ren <= '1';
time_write <= '0';
time_send <= '0';
time_select <= '0';
data_send <= '1';
update <= "00";
state <= WAIT_DATA;
WHEN WAIT_DATA =>
data_send <= '0';
IF data_send_ok = '1' OR data_send_ko = '1' THEN
state <= IDLE;
update <= "10";
END IF;
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 => time_dmai,
DMAOut => DMAOut,
send => time_send,
address => data_address,
data => data,
send_ok => time_send_ok,
send_ko => time_send_ko
);
-----------------------------------------------------------------------------
-- SEND 16 word by DMA (in burst mode)
-----------------------------------------------------------------------------
data_2_halfword(31 DOWNTO 0) <= data(15 DOWNTO 0) & data (31 DOWNTO 16);
lpp_dma_send_16word_1 : lpp_dma_send_16word
PORT MAP (
HCLK => HCLK,
HRESETn => HRESETn,
DMAIn => data_dmai,
DMAOut => DMAOut,
send => data_send,
address => data_address,
data => data_2_halfword,
ren => data_fifo_ren,
send_ok => data_send_ok,
send_ko => data_send_ko);
DMAIn <= time_dmai WHEN time_select = '1' ELSE data_dmai;
data_ren <= trash_fifo_ren WHEN time_select = '1' ELSE data_fifo_ren;
time_ren <= time_fifo_ren WHEN time_select = '1' ELSE '1';
all_data_ren : FOR I IN 3 DOWNTO 0 GENERATE
data_data_ren(I) <= data_ren WHEN UNSIGNED(sel_data) = I ELSE '1';
data_time_ren(I) <= time_ren WHEN UNSIGNED(sel_data) = I ELSE '1';
END GENERATE all_data_ren;
-----------------------------------------------------------------------------
-- SELECT ADDRESS
addr_data_reg_vector <= addr_data_f3 & addr_data_f2 & addr_data_f1 & addr_data_f0;
gen_select_address : FOR I IN 3 DOWNTO 0 GENERATE
update_and_sel((2*I)+1 DOWNTO 2*I) <= update WHEN UNSIGNED(sel_data) = I ELSE "00";
lpp_waveform_dma_selectaddress_I : lpp_waveform_dma_selectaddress
GENERIC MAP (
nb_burst_available_size => nb_burst_available_size)
PORT MAP (
HCLK => HCLK,
HRESETn => HRESETn,
run => run,
enable => enable(I),
update => update_and_sel((2*I)+1 DOWNTO 2*I),
nb_burst_available => nb_burst_available,
addr_data_reg => addr_data_reg_vector(32*I+31 DOWNTO 32*I),
addr_data => addr_data_vector(32*I+31 DOWNTO 32*I),
status_full => status_full(I),
status_full_ack => status_full_ack(I),
status_full_err => status_full_err(I));
END GENERATE gen_select_address;
data_address <= addr_data_vector(31 DOWNTO 0) WHEN UNSIGNED(sel_data) = 0 ELSE
addr_data_vector(32*1+31 DOWNTO 32*1) WHEN UNSIGNED(sel_data) = 1 ELSE
addr_data_vector(32*2+31 DOWNTO 32*2) WHEN UNSIGNED(sel_data) = 2 ELSE
addr_data_vector(32*3+31 DOWNTO 32*3);
-----------------------------------------------------------------------------
END Behavioral;