lpp_waveform_fifo_arbiter.vhd
269 lines
| 9.1 KiB
| text/x-vhdl
|
VhdlLexer
pellion
|
r165 | ------------------------------------------------------------------------------ | ||
-- This file is a part of the LPP VHDL IP LIBRARY | ||||
-- Copyright (C) 2009 - 2012, 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 | ||||
------------------------------------------------------------------------------ | ||||
LIBRARY IEEE; | ||||
USE IEEE.std_logic_1164.ALL; | ||||
USE IEEE.numeric_std.ALL; | ||||
LIBRARY lpp; | ||||
USE lpp.lpp_waveform_pkg.ALL; | ||||
pellion
|
r230 | USE lpp.general_purpose.ALL; | ||
pellion
|
r165 | |||
ENTITY lpp_waveform_fifo_arbiter IS | ||||
GENERIC( | ||||
pellion
|
r230 | tech : INTEGER := 0; | ||
pellion
|
r286 | nb_data_by_buffer_size : INTEGER := 11 | ||
pellion
|
r165 | ); | ||
PORT( | ||||
pellion
|
r230 | clk : IN STD_LOGIC; | ||
rstn : IN STD_LOGIC; | ||||
pellion
|
r229 | --------------------------------------------------------------------------- | ||
pellion
|
r230 | run : IN STD_LOGIC; | ||
nb_data_by_buffer : IN STD_LOGIC_VECTOR(nb_data_by_buffer_size - 1 DOWNTO 0); | ||||
pellion
|
r165 | --------------------------------------------------------------------------- | ||
pellion
|
r230 | -- SNAPSHOT INTERFACE (INPUT) | ||
--------------------------------------------------------------------------- | ||||
data_in_valid : IN STD_LOGIC_VECTOR(3 DOWNTO 0); | ||||
data_in_ack : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); | ||||
data_in : IN Data_Vector(3 DOWNTO 0, 95 DOWNTO 0); | ||||
pellion
|
r439 | |||
pellion
|
r230 | time_in : IN Data_Vector(3 DOWNTO 0, 47 DOWNTO 0); | ||
pellion
|
r165 | |||
--------------------------------------------------------------------------- | ||||
pellion
|
r230 | -- FIFO INTERFACE (OUTPUT) | ||
pellion
|
r165 | --------------------------------------------------------------------------- | ||
pellion
|
r230 | data_out : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); | ||
data_out_wen : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); | ||||
pellion
|
r240 | full_almost : IN STD_LOGIC_VECTOR(3 DOWNTO 0); | ||
pellion
|
r439 | full : IN STD_LOGIC_VECTOR(3 DOWNTO 0); | ||
--------------------------------------------------------------------------- | ||||
-- TIME INTERFACE (OUTPUT) | ||||
--------------------------------------------------------------------------- | ||||
time_out : OUT STD_LOGIC_VECTOR(47 DOWNTO 0); | ||||
time_out_new : OUT STD_LOGIC_VECTOR(3 DOWNTO 0) | ||||
pellion
|
r165 | |||
); | ||||
END ENTITY; | ||||
ARCHITECTURE ar_lpp_waveform_fifo_arbiter OF lpp_waveform_fifo_arbiter IS | ||||
pellion
|
r439 | TYPE state_type_fifo_arbiter IS (IDLE,DATA1,DATA2,DATA3,LAST); | ||
pellion
|
r240 | SIGNAL state : state_type_fifo_arbiter; | ||
pellion
|
r232 | ----------------------------------------------------------------------------- | ||
-- DATA MUX | ||||
pellion
|
r230 | ----------------------------------------------------------------------------- | ||
TYPE WORD_VECTOR IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(31 DOWNTO 0); | ||||
pellion
|
r463 | SIGNAL data_0 : WORD_VECTOR(2 DOWNTO 0); | ||
SIGNAL data_1 : WORD_VECTOR(2 DOWNTO 0); | ||||
SIGNAL data_2 : WORD_VECTOR(2 DOWNTO 0); | ||||
SIGNAL data_3 : WORD_VECTOR(2 DOWNTO 0); | ||||
SIGNAL data_sel : WORD_VECTOR(2 DOWNTO 0); | ||||
pellion
|
r232 | |||
----------------------------------------------------------------------------- | ||||
-- RR and SELECTION | ||||
----------------------------------------------------------------------------- | ||||
SIGNAL valid_in_rr : STD_LOGIC_VECTOR(3 DOWNTO 0); | ||||
SIGNAL sel : STD_LOGIC_VECTOR(3 DOWNTO 0); | ||||
pellion
|
r240 | SIGNAL sel_s : STD_LOGIC_VECTOR(3 DOWNTO 0); | ||
SIGNAL sel_reg : STD_LOGIC; | ||||
SIGNAL sel_ack : STD_LOGIC; | ||||
pellion
|
r232 | SIGNAL no_sel : STD_LOGIC; | ||
----------------------------------------------------------------------------- | ||||
-- REG | ||||
pellion
|
r230 | ----------------------------------------------------------------------------- | ||
pellion
|
r232 | SIGNAL count_enable : STD_LOGIC; | ||
SIGNAL count : STD_LOGIC_VECTOR(nb_data_by_buffer_size-1 DOWNTO 0); | ||||
SIGNAL count_s : STD_LOGIC_VECTOR(nb_data_by_buffer_size-1 DOWNTO 0); | ||||
pellion
|
r439 | |||
SIGNAL time_sel : STD_LOGIC_VECTOR(47 DOWNTO 0); | ||||
pellion
|
r232 | |||
BEGIN | ||||
pellion
|
r230 | ----------------------------------------------------------------------------- | ||
pellion
|
r232 | -- CONTROL | ||
pellion
|
r230 | ----------------------------------------------------------------------------- | ||
pellion
|
r232 | PROCESS (clk, rstn) | ||
BEGIN -- PROCESS | ||||
pellion
|
r240 | IF rstn = '0' THEN -- asynchronous reset (active low) | ||
pellion
|
r232 | count_enable <= '0'; | ||
pellion
|
r240 | data_in_ack <= (OTHERS => '0'); | ||
data_out_wen <= (OTHERS => '1'); | ||||
sel_ack <= '0'; | ||||
pellion
|
r439 | state <= IDLE; | ||
time_out <= (OTHERS => '0'); | ||||
time_out_new <= (OTHERS => '0'); | ||||
pellion
|
r240 | ELSIF clk'event AND clk = '1' THEN -- rising clock edge | ||
count_enable <= '0'; | ||||
pellion
|
r232 | data_in_ack <= (OTHERS => '0'); | ||
data_out_wen <= (OTHERS => '1'); | ||||
pellion
|
r240 | sel_ack <= '0'; | ||
pellion
|
r439 | time_out_new <= (OTHERS => '0'); | ||
pellion
|
r240 | IF run = '0' THEN | ||
state <= IDLE; | ||||
pellion
|
r439 | time_out <= (OTHERS => '0'); | ||
pellion
|
r232 | ELSE | ||
pellion
|
r240 | CASE state IS | ||
WHEN IDLE => | ||||
IF no_sel = '0' THEN | ||||
pellion
|
r439 | state <= DATA1; | ||
pellion
|
r240 | END IF; | ||
pellion
|
r439 | WHEN DATA1 => | ||
pellion
|
r240 | count_enable <= '1'; | ||
IF UNSIGNED(count) = 0 THEN | ||||
pellion
|
r439 | time_out <= time_sel; | ||
time_out_new <= sel; | ||||
pellion
|
r240 | END IF; | ||
data_out_wen <= NOT sel; | ||||
pellion
|
r439 | data_out <= data_sel(0); | ||
pellion
|
r240 | state <= DATA2; | ||
WHEN DATA2 => | ||||
data_out_wen <= NOT sel; | ||||
pellion
|
r439 | data_out <= data_sel(1); | ||
pellion
|
r240 | state <= DATA3; | ||
WHEN DATA3 => | ||||
data_out_wen <= NOT sel; | ||||
pellion
|
r439 | data_out <= data_sel(2); | ||
pellion
|
r240 | state <= LAST; | ||
data_in_ack <= sel; | ||||
WHEN LAST => | ||||
state <= IDLE; | ||||
sel_ack <= '1'; | ||||
WHEN OTHERS => NULL; | ||||
END CASE; | ||||
pellion
|
r232 | END IF; | ||
END IF; | ||||
END PROCESS; | ||||
pellion
|
r240 | ----------------------------------------------------------------------------- | ||
pellion
|
r165 | |||
pellion
|
r232 | ----------------------------------------------------------------------------- | ||
-- DATA MUX | ||||
----------------------------------------------------------------------------- | ||||
pellion
|
r230 | |||
pellion
|
r439 | all_word: FOR J IN 2 DOWNTO 0 GENERATE | ||
pellion
|
r232 | all_data_bit: FOR I IN 31 DOWNTO 0 GENERATE | ||
pellion
|
r439 | data_0(J)(I) <= data_in(0,I+32*J); | ||
data_1(J)(I) <= data_in(1,I+32*J); | ||||
data_2(J)(I) <= data_in(2,I+32*J); | ||||
data_3(J)(I) <= data_in(3,I+32*J); | ||||
pellion
|
r232 | END GENERATE all_data_bit; | ||
END GENERATE all_word; | ||||
pellion
|
r230 | |||
pellion
|
r232 | data_sel <= data_0 WHEN sel(0) = '1' ELSE | ||
data_1 WHEN sel(1) = '1' ELSE | ||||
data_2 WHEN sel(2) = '1' ELSE | ||||
data_3; | ||||
pellion
|
r443 | all_time_bit: FOR I IN 47 DOWNTO 0 GENERATE | ||
pellion
|
r439 | time_sel(I) <= time_in(0,I) WHEN sel(0) = '1' ELSE | ||
time_in(1,I) WHEN sel(1) = '1' ELSE | ||||
time_in(2,I) WHEN sel(2) = '1' ELSE | ||||
time_in(3,I); | ||||
END GENERATE all_time_bit; | ||||
pellion
|
r232 | |||
pellion
|
r230 | ----------------------------------------------------------------------------- | ||
pellion
|
r232 | -- RR and SELECTION | ||
pellion
|
r230 | ----------------------------------------------------------------------------- | ||
all_input_rr : FOR I IN 3 DOWNTO 0 GENERATE | ||||
pellion
|
r240 | valid_in_rr(I) <= data_in_valid(I) AND NOT full_almost(I); | ||
pellion
|
r230 | END GENERATE all_input_rr; | ||
RR_Arbiter_4_1 : RR_Arbiter_4 | ||||
PORT MAP ( | ||||
clk => clk, | ||||
rstn => rstn, | ||||
in_valid => valid_in_rr, | ||||
pellion
|
r439 | out_grant => sel_s); | ||
pellion
|
r240 | |||
PROCESS (clk, rstn) | ||||
BEGIN -- PROCESS | ||||
IF rstn = '0' THEN -- asynchronous reset (active low) | ||||
sel <= "0000"; | ||||
sel_reg <= '0'; | ||||
ELSIF clk'event AND clk = '1' THEN -- rising clock edge | ||||
pellion
|
r451 | IF run = '0' THEN | ||
sel <= "0000"; | ||||
sel_reg <= '0'; | ||||
ELSE | ||||
IF sel_reg = '0' OR sel_ack = '1' THEN | ||||
sel <= sel_s; | ||||
IF sel_s = "0000" THEN | ||||
sel_reg <= '0'; | ||||
ELSE | ||||
sel_reg <= '1'; | ||||
END IF; | ||||
pellion
|
r240 | END IF; | ||
END IF; | ||||
END IF; | ||||
END PROCESS; | ||||
pellion
|
r232 | no_sel <= '1' WHEN sel = "0000" ELSE '0'; | ||
pellion
|
r230 | |||
----------------------------------------------------------------------------- | ||||
pellion
|
r232 | -- REG | ||
----------------------------------------------------------------------------- | ||||
reg_count_i: lpp_waveform_fifo_arbiter_reg | ||||
GENERIC MAP ( | ||||
data_size => nb_data_by_buffer_size, | ||||
data_nb => 4) | ||||
PORT MAP ( | ||||
clk => clk, | ||||
rstn => rstn, | ||||
run => run, | ||||
max_count => nb_data_by_buffer, | ||||
enable => count_enable, | ||||
sel => sel, | ||||
data => count, | ||||
data_s => count_s); | ||||
pellion
|
r231 | |||
pellion
|
r232 | |||
pellion
|
r165 | END ARCHITECTURE; | ||