lpp_waveform_fifo_arbiter.vhd
394 lines
| 12.9 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; | ||
nb_data_by_buffer_size : INTEGER | ||||
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); | ||||
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
|
r230 | full : IN STD_LOGIC_VECTOR(3 DOWNTO 0) | ||
pellion
|
r165 | |||
); | ||||
END ENTITY; | ||||
ARCHITECTURE ar_lpp_waveform_fifo_arbiter OF lpp_waveform_fifo_arbiter IS | ||||
pellion
|
r240 | TYPE state_type_fifo_arbiter IS (IDLE,TIME1,TIME2,DATA1,DATA2,DATA3,LAST); | ||
SIGNAL state : state_type_fifo_arbiter; | ||||
pellion
|
r232 | ----------------------------------------------------------------------------- | ||
-- DATA MUX | ||||
pellion
|
r230 | ----------------------------------------------------------------------------- | ||
pellion
|
r232 | SIGNAL data_0_v : STD_LOGIC_VECTOR(32*5-1 DOWNTO 0); | ||
SIGNAL data_1_v : STD_LOGIC_VECTOR(32*5-1 DOWNTO 0); | ||||
SIGNAL data_2_v : STD_LOGIC_VECTOR(32*5-1 DOWNTO 0); | ||||
SIGNAL data_3_v : STD_LOGIC_VECTOR(32*5-1 DOWNTO 0); | ||||
pellion
|
r230 | TYPE WORD_VECTOR IS ARRAY (NATURAL RANGE <>) OF STD_LOGIC_VECTOR(31 DOWNTO 0); | ||
pellion
|
r232 | SIGNAL data_0 : WORD_VECTOR(4 DOWNTO 0); | ||
SIGNAL data_1 : WORD_VECTOR(4 DOWNTO 0); | ||||
SIGNAL data_2 : WORD_VECTOR(4 DOWNTO 0); | ||||
SIGNAL data_3 : WORD_VECTOR(4 DOWNTO 0); | ||||
SIGNAL data_sel : WORD_VECTOR(4 DOWNTO 0); | ||||
----------------------------------------------------------------------------- | ||||
-- 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
|
r240 | --SIGNAL shift_data_enable : STD_LOGIC; | ||
--SIGNAL shift_data : STD_LOGIC_VECTOR(1 DOWNTO 0); | ||||
--SIGNAL shift_data_s : STD_LOGIC_VECTOR(1 DOWNTO 0); | ||||
pellion
|
r232 | |||
pellion
|
r240 | --SIGNAL shift_time_enable : STD_LOGIC; | ||
--SIGNAL shift_time : STD_LOGIC_VECTOR(1 DOWNTO 0); | ||||
--SIGNAL shift_time_s : STD_LOGIC_VECTOR(1 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'; | ||||
state <= IDLE; | ||||
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'; | ||
IF run = '0' THEN | ||||
state <= IDLE; | ||||
pellion
|
r232 | ELSE | ||
pellion
|
r240 | CASE state IS | ||
WHEN IDLE => | ||||
IF no_sel = '0' THEN | ||||
state <= TIME1; | ||||
END IF; | ||||
WHEN TIME1 => | ||||
count_enable <= '1'; | ||||
IF UNSIGNED(count) = 0 THEN | ||||
state <= TIME2; | ||||
data_out_wen <= NOT sel; | ||||
data_out <= data_sel(0); | ||||
ELSE | ||||
state <= DATA1; | ||||
END IF; | ||||
WHEN TIME2 => | ||||
data_out_wen <= NOT sel; | ||||
data_out <= data_sel(1) ; | ||||
state <= DATA1; | ||||
WHEN DATA1 => | ||||
data_out_wen <= NOT sel; | ||||
data_out <= data_sel(2); | ||||
state <= DATA2; | ||||
WHEN DATA2 => | ||||
data_out_wen <= NOT sel; | ||||
data_out <= data_sel(3); | ||||
state <= DATA3; | ||||
WHEN DATA3 => | ||||
data_out_wen <= NOT sel; | ||||
data_out <= data_sel(4); | ||||
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 | ----------------------------------------------------------------------------- | ||
--PROCESS (clk, rstn) | ||||
--BEGIN -- PROCESS | ||||
-- IF rstn = '0' THEN -- asynchronous reset (active low) | ||||
-- count_enable <= '0'; | ||||
-- shift_time_enable <= '0'; | ||||
-- shift_data_enable <= '0'; | ||||
-- data_in_ack <= (OTHERS => '0'); | ||||
-- data_out_wen <= (OTHERS => '1'); | ||||
-- sel_ack <= '0'; | ||||
-- ELSIF clk'event AND clk = '1' THEN -- rising clock edge | ||||
-- IF run = '0' OR no_sel = '1' THEN | ||||
-- count_enable <= '0'; | ||||
-- shift_time_enable <= '0'; | ||||
-- shift_data_enable <= '0'; | ||||
-- data_in_ack <= (OTHERS => '0'); | ||||
-- data_out_wen <= (OTHERS => '1'); | ||||
-- sel_ack <= '0'; | ||||
-- ELSE | ||||
-- --COUNT | ||||
-- IF shift_data_s = "10" THEN | ||||
-- count_enable <= '1'; | ||||
-- ELSE | ||||
-- count_enable <= '0'; | ||||
-- END IF; | ||||
-- --DATA | ||||
-- IF shift_time_s = "10" THEN | ||||
-- shift_data_enable <= '1'; | ||||
-- ELSE | ||||
-- shift_data_enable <= '0'; | ||||
-- END IF; | ||||
-- --TIME | ||||
-- IF ((shift_data_s = "10") AND (count = nb_data_by_buffer)) OR | ||||
-- shift_time_s = "00" OR | ||||
-- shift_time_s = "01" | ||||
-- THEN | ||||
-- shift_time_enable <= '1'; | ||||
-- ELSE | ||||
-- shift_time_enable <= '0'; | ||||
-- END IF; | ||||
-- --ACK | ||||
-- IF shift_data_s = "10" THEN | ||||
-- data_in_ack <= sel; | ||||
-- sel_ack <= '1'; | ||||
-- ELSE | ||||
-- data_in_ack <= (OTHERS => '0'); | ||||
-- sel_ack <= '0'; | ||||
-- END IF; | ||||
-- --VALID OUT | ||||
-- all_wen: FOR I IN 3 DOWNTO 0 LOOP | ||||
-- IF sel(I) = '1' AND count_enable = '0' THEN | ||||
-- data_out_wen(I) <= '0'; | ||||
-- ELSE | ||||
-- data_out_wen(I) <= '1'; | ||||
-- END IF; | ||||
-- END LOOP all_wen; | ||||
-- END IF; | ||||
-- END IF; | ||||
--END PROCESS; | ||||
pellion
|
r165 | |||
pellion
|
r232 | ----------------------------------------------------------------------------- | ||
-- DATA MUX | ||||
----------------------------------------------------------------------------- | ||||
all_bit_data_in: FOR I IN 32*5-1 DOWNTO 0 GENERATE | ||||
I_time_in: IF I < 48 GENERATE | ||||
data_0_v(I) <= time_in(0,I); | ||||
data_1_v(I) <= time_in(1,I); | ||||
data_2_v(I) <= time_in(2,I); | ||||
data_3_v(I) <= time_in(3,I); | ||||
END GENERATE I_time_in; | ||||
I_null: IF (I > 47) AND (I < 32*2) GENERATE | ||||
data_0_v(I) <= '0'; | ||||
data_1_v(I) <= '0'; | ||||
data_2_v(I) <= '0'; | ||||
data_3_v(I) <= '0'; | ||||
END GENERATE I_null; | ||||
I_data_in: IF I > 32*2-1 GENERATE | ||||
data_0_v(I) <= data_in(0,I-32*2); | ||||
data_1_v(I) <= data_in(1,I-32*2); | ||||
data_2_v(I) <= data_in(2,I-32*2); | ||||
data_3_v(I) <= data_in(3,I-32*2); | ||||
END GENERATE I_data_in; | ||||
END GENERATE all_bit_data_in; | ||||
pellion
|
r230 | |||
pellion
|
r232 | all_word: FOR J IN 4 DOWNTO 0 GENERATE | ||
all_data_bit: FOR I IN 31 DOWNTO 0 GENERATE | ||||
data_0(J)(I) <= data_0_v(J*32+I); | ||||
data_1(J)(I) <= data_1_v(J*32+I); | ||||
data_2(J)(I) <= data_2_v(J*32+I); | ||||
data_3(J)(I) <= data_3_v(J*32+I); | ||||
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
|
r240 | --data_out <= data_sel(0) WHEN shift_time = "00" ELSE | ||
-- data_sel(1) WHEN shift_time = "01" ELSE | ||||
-- data_sel(2) WHEN shift_data = "00" ELSE | ||||
-- data_sel(3) WHEN shift_data = "01" ELSE | ||||
-- data_sel(4); | ||||
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(I); | ||
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
|
r240 | out_grant => sel_s); --sel_s); | ||
pellion
|
r230 | |||
pellion
|
r240 | -- sel <= sel_s; | ||
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 | ||||
-- sel_reg | ||||
-- sel_ack | ||||
-- sel_s | ||||
-- sel = "0000 " | ||||
--sel <= sel_s; | ||||
IF sel_reg = '0' OR sel_ack = '1' | ||||
--OR shift_data_s = "10" | ||||
THEN | ||||
sel <= sel_s; | ||||
IF sel_s = "0000" THEN | ||||
sel_reg <= '0'; | ||||
ELSE | ||||
sel_reg <= '1'; | ||||
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
|
r230 | |||
pellion
|
r240 | --reg_shift_data_i: lpp_waveform_fifo_arbiter_reg | ||
-- GENERIC MAP ( | ||||
-- data_size => 2, | ||||
-- data_nb => 4) | ||||
-- PORT MAP ( | ||||
-- clk => clk, | ||||
-- rstn => rstn, | ||||
-- run => run, | ||||
-- max_count => "10", -- 2 | ||||
-- enable => shift_data_enable, | ||||
-- sel => sel, | ||||
-- data => shift_data, | ||||
-- data_s => shift_data_s); | ||||
pellion
|
r230 | |||
pellion
|
r240 | --reg_shift_time_i: lpp_waveform_fifo_arbiter_reg | ||
-- GENERIC MAP ( | ||||
-- data_size => 2, | ||||
-- data_nb => 4) | ||||
-- PORT MAP ( | ||||
-- clk => clk, | ||||
-- rstn => rstn, | ||||
-- run => run, | ||||
-- max_count => "10", -- 2 | ||||
-- enable => shift_time_enable, | ||||
-- sel => sel, | ||||
-- data => shift_time, | ||||
-- data_s => shift_time_s); | ||||
pellion
|
r232 | |||
pellion
|
r231 | |||
pellion
|
r232 | |||
pellion
|
r165 | END ARCHITECTURE; | ||