--- /dev/null
+-------------------------------------------------------------------------------------------
+-- converts the 40 bit input data of the mupix into
+-- 32 bit portions + padding of the last word for readout with the TRB
+-- TODO: after adding the hit time sorter the data width conversion should be moved there
+-- T. Weber
+-------------------------------------------------------------------------------------------
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+use work.Constants.all;
+
+entity DataWidthConversion is
+ generic (
+ g_datawidthfifo : integer := 40; -- data width of input fifo
+ g_datawidthtrb : integer := 32); -- data width of trb data bus
+ port (
+ clk : in std_logic; -- clock input
+ reset : in std_logic; -- reset input
+ fifo_empty : in std_logic; -- fifo empty signal
+ fifo_full : in std_logic; -- fifo full signal (unused)
+ fifo_datain : in std_logic_vector(g_datawidthfifo - 1 downto 0); -- input data
+ fifo_rden : out std_logic; -- fifo read enable
+ buff_wren : out std_logic; -- buffer write enable
+ dataout : out std_logic_vector(g_datawidthtrb - 1 downto 0)); -- data output
+end entity DataWidthConversion;
+
+architecture rtl of DataWidthConversion is
+
+ type converter_fsm_type is (idle, wait_fifo, convert);
+ signal converter_fsm_state : converter_fsm_type := idle;
+
+ type convert_mem_type is array (0 to 1) of std_logic_vector(c_mupixhitsize - 1 downto 0);
+ signal data_shift : convert_mem_type := (others => (others => '0'));
+
+ signal conversion_cnt_i : integer range 0 to 6 := 0;
+ signal empty_delay : std_logic_vector(1 downto 0) := (others => '0');
+ signal empty_start : std_logic_vector(9 downto 0) := (others => '0');
+ constant padding_0 : std_logic_vector(23 downto 0) := (others => '0');
+ constant padding_1 : std_logic_vector(15 downto 0) := (others => '0');
+ constant padding_2 : std_logic_vector(7 downto 0) := (others => '0');
+
+ signal buff_wren_i : std_logic := '0';
+ signal dataout_i : std_logic_vector(g_datawidthtrb - 1 downto 0) := (others => '0');
+
+begin -- architecture rtl
+
+ conversion : process (clk) is
+ begin -- process conversion
+ if rising_edge(clk) then -- rising clock edge
+ if reset = '1' then -- synchronous reset (active high)
+ data_shift <= (others => (others => '0'));
+ buff_wren_i <= '0';
+ dataout_i <= (others => '0');
+ converter_fsm_state <= idle;
+ fifo_rden <= '0';
+ empty_delay <= (others => '0');
+ else
+ dataout_i <= (others => '0');
+ buff_wren_i <= '0';
+ empty_delay <= empty_delay(0) & fifo_empty;
+ empty_start <= empty_start(8 downto 0) & fifo_empty;
+ fifo_rden <= '0';
+ case converter_fsm_state is
+ when idle =>
+ data_shift <= (others => (others => '0'));
+ conversion_cnt_i <= 0;
+ -- this avoids unnecessary padding in case of serdes fifos are
+ -- writen by clock slower than TRB clock
+ if empty_start = "0000000000" then
+ fifo_rden <= '1';
+ converter_fsm_state <= wait_fifo;
+ end if;
+ when wait_fifo =>
+ fifo_rden <= '1';
+ converter_fsm_state <= convert;
+ when convert =>
+ fifo_rden <= '1';
+ data_shift(1) <= data_shift(0);
+ data_shift(0) <= fifo_datain;
+ case conversion_cnt_i is -- also controls fifo readout
+ when 0 =>
+ conversion_cnt_i <= conversion_cnt_i + 1;
+ buff_wren_i <= '0';
+ dataout_i <= (others => '0');
+ when 1 =>
+ conversion_cnt_i <= conversion_cnt_i + 1;
+ buff_wren_i <= '1';
+ dataout_i <= data_shift(0)(c_mupixhitsize - 1 downto 8);
+ when 2 =>
+ conversion_cnt_i <= conversion_cnt_i + 1;
+ buff_wren_i <= '1';
+ if empty_delay = "11" then
+ dataout_i <= data_shift(1)(7 downto 0) & padding_0;
+ else
+ dataout_i <= data_shift(1)(7 downto 0) & data_shift(0)(c_mupixhitsize - 1 downto 16);
+ end if;
+ fifo_rden <= '0';
+ when 3 =>
+ conversion_cnt_i <= conversion_cnt_i + 1;
+ buff_wren_i <= '1';
+ if empty_delay = "11" then
+ dataout_i <= data_shift(1)(15 downto 0) & padding_1;
+ else
+ dataout_i <= data_shift(1)(15 downto 0) & data_shift(0)(c_mupixhitsize - 1 downto 24);
+ end if;
+ fifo_rden <= '0';
+ when 4 =>
+ conversion_cnt_i <= conversion_cnt_i + 1;
+ buff_wren_i <= '1';
+ if empty_delay = "11" then
+ dataout_i <= data_shift(1)(23 downto 0) & padding_2;
+ else
+ dataout_i <= data_shift(1)(23 downto 0) & data_shift(0)(c_mupixhitsize - 1 downto 32);
+ end if;
+ fifo_rden <= '0';
+ when 5 =>
+ conversion_cnt_i <= conversion_cnt_i + 1;
+ buff_wren_i <= '1';
+ dataout_i <= data_shift(1)(31 downto 0);
+ fifo_rden <= '0';
+ when 6 =>
+ fifo_rden <= '1';
+ conversion_cnt_i <= 0;
+ buff_wren_i <= '0';
+ dataout_i <= (others => '0');
+ converter_fsm_state <= wait_fifo;
+ end case;
+ if empty_delay = "11" then
+ converter_fsm_state <= idle;
+ end if;
+ end case;
+ end if;
+ end if;
+ end process conversion;
+
+ -- purpose: register outputs
+ output : process (clk) is
+ begin -- process output
+ if rising_edge(clk) then -- rising clock edge
+ if reset = '1' then -- synchronous reset (active high)
+ buff_wren <= '0';
+ dataout <= (others => '0');
+ else
+ buff_wren <= buff_wren_i;
+ dataout <= dataout_i;
+ end if;
+ end if;
+ end process output;
+
+end architecture rtl;
use work.StdTypes.all;
entity FiFoDataMux is
- generic(
- g_datawidth : integer := 32; -- data width
- g_inputs : integer := 4; -- number of inputs to multiplexer
- g_clockspeed : integer := 1e8 -- fpga clock speed
- );
- port(
- clk : in std_logic; -- clock input
- rst : in std_logic; -- reset input
- fifo_empty : in std_logic_vector(g_inputs - 1 downto 0); -- input FIFO empty flags
- fifo_full : in std_logic_vector(g_inputs - 1 downto 0); -- input FIFO full flags
- fifo_datain : in std_logic_vector(g_inputs*g_datawidth - 1 downto 0); -- input data from FIFOs
- fifo_mask : in std_logic_vector(g_inputs - 1 downto 0); -- enable mask for FIFO inputs
- fifo_rden : out std_logic_vector(g_inputs - 1 downto 0); -- read enable to FIFOs
- buff_wren : out std_logic; -- write enable to output buffer
- dataout : out std_logic_vector(g_datawidth - 1 downto 0); -- data output
- wordin_freq : out std_logic_vector(32*g_inputs - 1 downto 0); -- number of input words from FIFOs
- fifo_full_o : out std_logic -- or over input fifo full flags
- );
+ generic(
+ g_datawidth : integer := 32; -- data width
+ g_inputs : integer := 4; -- number of inputs to multiplexer
+ g_clockspeed : integer := 1e8 -- fpga clock speed
+ );
+ port(
+ clk : in std_logic; -- clock input
+ rst : in std_logic; -- reset input
+ fifo_empty : in std_logic_vector(g_inputs - 1 downto 0); -- input FIFO empty flags
+ fifo_full : in std_logic_vector(g_inputs - 1 downto 0); -- input FIFO full flags
+ fifo_datain : in std_logic_vector(g_inputs*g_datawidth - 1 downto 0); -- input data from FIFOs
+ fifo_mask : in std_logic_vector(g_inputs - 1 downto 0); -- enable mask for FIFO inputs
+ fifo_rden : out std_logic_vector(g_inputs - 1 downto 0); -- read enable to FIFOs
+ buff_wren : out std_logic; -- write enable to output buffer
+ dataout : out std_logic_vector(g_datawidth - 1 downto 0); -- data output
+ wordin_freq : out std_logic_vector(32*g_inputs - 1 downto 0); -- number of input words from FIFOs
+ fifo_full_o : out std_logic -- or over input fifo full flags
+ );
end entity FiFoDataMux;
architecture RTL of FiFoDataMux is
-
- signal ticks_counter : unsigned(f_log2(g_clockspeed) - 1 downto 0) := (others => '0');
- signal inword_counter : t_counter_array(0 to g_inputs - 1) := (others => (others => '0'));
- signal increase_counter : std_logic_vector(g_inputs - 1 downto 0) := (others => '0');
-
- signal fifo_full_i : std_logic;
-
- signal fifo_sel_i : integer range -1 to g_inputs - 1 := -1;
- signal fifo_sel_reg : integer range 0 to g_inputs - 1 := 0;
-
- signal request_i : std_logic_vector(g_inputs - 1 downto 0);
- signal grant_i : std_logic_vector(g_inputs - 1 downto 0);
-
- type t_mux_state is (idle, wait_fifo, write);
- signal mux_fsm : t_mux_state := idle;
-
- component RoundRobinArbiter
- generic(g_num_channels : integer := 4);
- port(
- clk : in std_logic;
- requests : in std_logic_vector(g_num_channels - 1 downto 0);
- grant : out std_logic_vector(g_num_channels - 1 downto 0)
- );
- end component RoundRobinArbiter;
-
+
+ signal ticks_counter : unsigned(f_log2(g_clockspeed) - 1 downto 0) := (others => '0');
+ signal inword_counter : t_counter32_array(0 to g_inputs - 1) := (others => (others => '0'));
+ signal increase_counter : std_logic_vector(g_inputs - 1 downto 0) := (others => '0');
+
+ signal fifo_full_i : std_logic;
+
+ signal fifo_sel_i : integer range -1 to g_inputs - 1 := -1;
+ signal fifo_sel_reg : integer range 0 to g_inputs - 1 := 0;
+
+ signal request_i : std_logic_vector(g_inputs - 1 downto 0);
+ signal grant_i : std_logic_vector(g_inputs - 1 downto 0);
+
+ type t_mux_state is (idle, wait_fifo, writedata, pause);
+ signal mux_fsm : t_mux_state := idle;
+ signal pause_cnt_i : integer range 0 to 7 := 0;
+
+ signal buff_wren_i : std_logic := '0';
+ signal dataout_i : std_logic_vector(g_datawidth - 1 downto 0) := (others => '0');
+
+ component RoundRobinArbiter
+ generic(g_num_channels : integer := 4);
+ port(
+ clk : in std_logic;
+ requests : in std_logic_vector(g_num_channels - 1 downto 0);
+ grant : out std_logic_vector(g_num_channels - 1 downto 0)
+ );
+ end component RoundRobinArbiter;
+
begin
-
- request_i <= not fifo_empty and fifo_mask;
-
- arbiter_1 : component RoundRobinArbiter
- generic map(
- g_num_channels => g_inputs
- )
- port map(
- clk => clk,
- requests => request_i,
- grant => grant_i
- );
-
- fifo_select_proc : process(grant_i) is
- variable sel : integer range -1 to g_inputs - 1;
- begin
- sel := -1;
- for i in 0 to g_inputs - 1 loop
- if grant_i(i) = '1' then
- sel := i;
- end if;
- end loop;
- fifo_sel_i <= sel;
- end process fifo_select_proc;
-
- full_flag_proc : process(fifo_full) is
- variable full : std_logic := '0';
- begin
- full := '0';
- for i in 0 to fifo_full'length - 1 loop
- full := full or fifo_full(i);
- end loop;
- fifo_full_i <= full;
- end process full_flag_proc;
-
- input_freq : process (clk) is
- begin
- if rising_edge(clk) then
- if rst = '1' then
- ticks_counter <= (others => '0');
- inword_counter <= (others => (others => '0'));
- else
- if increase_counter(fifo_sel_reg) = '1' then
- inword_counter(fifo_sel_reg) <= inword_counter(fifo_sel_reg) + 1;
- else
- inword_counter(fifo_sel_reg) <= inword_counter(fifo_sel_reg);
- end if;
- if ticks_counter = g_clockspeed - 1 then
- inword_counter <= (others => (others => '0'));
- ticks_counter <= (others => '0');
- wordin_freq <= counter_array_to_stdvec(inword_counter);
- else
- ticks_counter <= ticks_counter + 1;
- end if;
- end if;
- end if;
- end process input_freq;
-
-
- mux_proc : process(clk) is
- begin
- if rising_edge(clk) then
- if rst = '1' then
- fifo_sel_reg <= 0;
- buff_wren <= '0';
- dataout <= (others => '0');
- fifo_rden <= (others => '0');
- else
- case mux_fsm is
- when idle =>
- fifo_rden <= (others => '0');
- buff_wren <= '0';
- dataout <= (others => '0');
- if fifo_sel_i /= -1 then
- fifo_sel_reg <= fifo_sel_i;
- fifo_rden(fifo_sel_i) <= '1';
- mux_fsm <= wait_fifo;
- else
- fifo_sel_reg <= 0;
- mux_fsm <= idle;
- end if;
- when wait_fifo =>
- fifo_rden(fifo_sel_i) <= '1';
- mux_fsm <= write;
- when write =>
- dataout <= fifo_datain((fifo_sel_reg + 1)*g_datawidth - 1 downto g_datawidth*fifo_sel_reg);
- if fifo_empty(fifo_sel_reg) = '0' then
- mux_fsm <= write;
- fifo_rden(fifo_sel_reg) <= '1';
- buff_wren <= '1';
- increase_counter(fifo_sel_reg) <= '1';
- else
- mux_fsm <= idle;
- fifo_rden(fifo_sel_reg) <= '0';
- buff_wren <= '1';
- increase_counter <= (others => '0');
- end if;
- end case;
- end if;
- end if;
- end process mux_proc;
-
-
- fifo_full_o <= fifo_full_i;
-
+
+ request_i <= not fifo_empty and fifo_mask;
+
+ arbiter_1 : component RoundRobinArbiter
+ generic map(
+ g_num_channels => g_inputs
+ )
+ port map(
+ clk => clk,
+ requests => request_i,
+ grant => grant_i
+ );
+
+ fifo_select_proc : process(grant_i) is
+ variable sel : integer range -1 to g_inputs - 1;
+ begin
+ sel := -1;
+ for i in 0 to g_inputs - 1 loop
+ if grant_i(i) = '1' then
+ sel := i;
+ end if;
+ end loop;
+ fifo_sel_i <= sel;
+ end process fifo_select_proc;
+
+ full_flag_proc : process(fifo_full) is
+ variable full : std_logic := '0';
+ begin
+ full := '0';
+ for i in 0 to fifo_full'length - 1 loop
+ full := full or fifo_full(i);
+ end loop;
+ fifo_full_i <= full;
+ end process full_flag_proc;
+
+ input_freq : process (clk) is
+ begin
+ if rising_edge(clk) then
+ if rst = '1' then
+ ticks_counter <= (others => '0');
+ inword_counter <= (others => (others => '0'));
+ else
+ if increase_counter(fifo_sel_reg) = '1' then
+ inword_counter(fifo_sel_reg) <= inword_counter(fifo_sel_reg) + 1;
+ else
+ inword_counter(fifo_sel_reg) <= inword_counter(fifo_sel_reg);
+ end if;
+ if ticks_counter = g_clockspeed - 1 then
+ inword_counter <= (others => (others => '0'));
+ ticks_counter <= (others => '0');
+ wordin_freq <= counter_array_to_stdvec(inword_counter);
+ else
+ ticks_counter <= ticks_counter + 1;
+ end if;
+ end if;
+ end if;
+ end process input_freq;
+
+
+ mux_proc : process(clk) is
+ begin
+ if rising_edge(clk) then
+ if rst = '1' then
+ fifo_sel_reg <= 0;
+ buff_wren_i <= '0';
+ dataout_i <= (others => '0');
+ fifo_rden <= (others => '0');
+ else
+ buff_wren_i <= '0';
+ dataout_i <= (others => '0');
+ fifo_rden <= (others => '0');
+ case mux_fsm is
+ when idle =>
+ if fifo_sel_i /= -1 then
+ fifo_sel_reg <= fifo_sel_i;
+ fifo_rden(fifo_sel_i) <= '1';
+ mux_fsm <= wait_fifo;
+ else
+ fifo_sel_reg <= 0;
+ mux_fsm <= idle;
+ end if;
+ when wait_fifo =>
+ fifo_rden(fifo_sel_reg) <= '1';
+ mux_fsm <= writedata;
+ when writedata =>
+ pause_cnt_i <= 0;
+ dataout_i <= fifo_datain((fifo_sel_reg + 1)*g_datawidth - 1 downto g_datawidth*fifo_sel_reg);
+ increase_counter(fifo_sel_reg) <= '1';
+ fifo_rden(fifo_sel_reg) <= '1';
+ buff_wren_i <= '1';
+ if fifo_empty(fifo_sel_reg) = '0' then
+ mux_fsm <= writedata;
+ else
+ mux_fsm <= pause;
+ end if;
+ when pause => -- wait in case filling clock is slower than reading
+ -- clock
+ increase_counter <= (others => '0');
+ pause_cnt_i <= pause_cnt_i + 1;
+ mux_fsm <= pause;
+ if pause_cnt_i = 6 then
+ mux_fsm <= idle;
+ elsif fifo_empty(fifo_sel_reg) = '0' then
+ fifo_rden(fifo_sel_reg) <= '1';
+ mux_fsm <= wait_fifo;
+ end if;
+ end case;
+ end if;
+ end if;
+ end process mux_proc;
+
+ output_pipe : process (clk) is
+ begin -- process output_pipe
+ if rising_edge(clk) then
+ if rst = '1' then
+ dataout <= (others => '0');
+ buff_wren <= '0';
+ else
+ dataout <= dataout_i;
+ buff_wren <= buff_wren_i;
+ end if;
+ end if;
+ end process output_pipe;
+
+ fifo_full_o <= fifo_full_i;
+
end architecture RTL;
);
end component CircularMemory;
- component FiFoDataMuxWithConversion
- generic(
- g_datawidthfifo : integer := 40;
- g_datawidthtrb : integer := 32;
+ component FiFoDataMux is
+ generic (
+ g_datawidth : integer := 32;
g_inputs : integer := 4;
- g_clockspeed : integer := 1e8
- );
- port(
+ g_clockspeed : integer := 1e8);
+ port (
clk : in std_logic;
rst : in std_logic;
fifo_empty : in std_logic_vector(g_inputs - 1 downto 0);
fifo_full : in std_logic_vector(g_inputs - 1 downto 0);
- fifo_datain : in std_logic_vector(g_inputs*g_datawidthfifo - 1 downto 0);
+ fifo_datain : in std_logic_vector(g_inputs*g_datawidth - 1 downto 0);
fifo_mask : in std_logic_vector(g_inputs - 1 downto 0);
fifo_rden : out std_logic_vector(g_inputs - 1 downto 0);
buff_wren : out std_logic;
- dataout : out std_logic_vector(g_datawidthtrb - 1 downto 0);
+ dataout : out std_logic_vector(g_datawidth - 1 downto 0);
wordin_freq : out std_logic_vector(32*g_inputs - 1 downto 0);
- fifo_full_o : out std_logic
- );
- end component FiFoDataMuxWithConversion;
+ fifo_full_o : out std_logic);
+ end component FiFoDataMux;
+
+ component FIFO_40_512 is
+ port (
+ Data : in std_logic_vector(39 downto 0);
+ Clock : in std_logic;
+ WrEn : in std_logic;
+ RdEn : in std_logic;
+ Reset : in std_logic;
+ Q : out std_logic_vector(39 downto 0);
+ Empty : out std_logic;
+ Full : out std_logic);
+ end component FIFO_40_512;
+
+ component DataWidthConversion is
+ generic (
+ g_datawidthfifo : integer := 40;
+ g_datawidthtrb : integer := 32);
+ port (
+ clk : in std_logic;
+ reset : in std_logic;
+ fifo_empty : in std_logic;
+ fifo_full : in std_logic;
+ fifo_datain : in std_logic_vector(g_datawidthfifo - 1 downto 0);
+ fifo_rden : out std_logic;
+ buff_wren : out std_logic;
+ dataout : out std_logic_vector(g_datawidthtrb - 1 downto 0));
+ end component DataWidthConversion;
component ReadoutController
generic(
signal fifo_mux_wren : std_logic;
signal fifo_mux_data_out : std_logic_vector(g_datawidthtrb - 1 downto 0);
+ signal fifo_data_width_empty_i, fifo_data_width_full_i : std_logic;
+ signal fifo_data_width_dataout_i : std_logic_vector(g_datawidthfifo - 1 downto 0);
+ signal fifo_data_width_datain_i : std_logic_vector(g_datawidthfifo - 1 downto 0);
+ signal fifo_data_width_rd_i, fifo_data_width_wr_i : std_logic;
+
signal start_readout_slow_to_buffer : std_logic := '0';
signal start_readout : std_logic := '0';
signal readout_controller_data_in : std_logic_vector(g_datawidthtrb - 1 downto 0);
start_readout <= start_readout_slow_to_buffer or trb_trigger;
- data_mux_1 : entity work.FiFoDataMuxWithConversion
- generic map(
- g_datawidthfifo => g_datawidthfifo,
- g_datawidthtrb => g_datawidthtrb,
+ FiFoDataMux_1: entity work.FiFoDataMux
+ generic map (
+ g_datawidth => g_datawidthfifo,
g_inputs => g_mupix_links,
- g_clockspeed => 1e8
- )
- port map(
+ g_clockspeed => 1e8)
+ port map (
clk => clk,
rst => rst,
fifo_empty => fifo_empty,
fifo_datain => fifo_datain,
fifo_mask => multiplexer_mask,
fifo_rden => fifo_rden,
- buff_wren => fifo_mux_wren,
- dataout => fifo_mux_data_out,
+ buff_wren => fifo_data_width_wr_i,
+ dataout => fifo_data_width_datain_i,
wordin_freq => wordin_freq,
- fifo_full_o => fifo_full_o
- );
+ fifo_full_o => fifo_full_o);
+
+ FIFO_40_512_1: entity work.FIFO_40_512
+ port map (
+ Data => fifo_data_width_datain_i,
+ Clock => clk,
+ WrEn => fifo_data_width_wr_i,
+ RdEn => fifo_data_width_rd_i,
+ Reset => rst,
+ Q => fifo_data_width_dataout_i,
+ Empty => fifo_data_width_empty_i,
+ Full => fifo_data_width_full_i);
+
+ DataWidthConversion_1: entity work.DataWidthConversion
+ generic map (
+ g_datawidthfifo => g_datawidthfifo,
+ g_datawidthtrb => g_datawidthtrb)
+ port map (
+ clk => clk,
+ reset => rst,
+ fifo_empty => fifo_data_width_empty_i,
+ fifo_full => fifo_data_width_full_i,
+ fifo_datain => fifo_data_width_dataout_i,
+ fifo_rden => fifo_data_width_rd_i,
+ buff_wren => fifo_mux_wren,
+ dataout => fifo_mux_data_out);
cycl_buffer_1 : entity work.CircularMemory
generic map(
);
end component MupixTRBReadout;
- component STD_FIFO
- generic(
- DATA_WIDTH : positive := 8;
- FIFO_DEPTH : positive := 256
- );
- port(
- CLK : in std_logic;
- RST : in std_logic;
- WriteEn : in std_logic;
- DataIn : in std_logic_vector(DATA_WIDTH - 1 downto 0);
- ReadEn : in std_logic;
- DataOut : out std_logic_vector(DATA_WIDTH - 1 downto 0);
+ component serdes_fifo is
+ port (
+ Data : in std_logic_vector(39 downto 0);
+ WrClock : in std_logic;
+ RdClock : in std_logic;
+ WrEn : in std_logic;
+ RdEn : in std_logic;
+ Reset : in std_logic;
+ RPReset : in std_logic;
+ Q : out std_logic_vector(39 downto 0);
+ RCNT : out std_logic_vector(10 downto 0);
Empty : out std_logic;
- Full : out std_logic
- );
- end component STD_FIFO;
+ Full : out std_logic);
+ end component serdes_fifo;
constant c_clk_period : time := 10 ns;
+ constant c_wrclk_period : time := 25 ns;
constant c_mupix_links : integer := 4;
constant c_cyc_mem_address_width : integer := 12;
constant c_datawidthfifo : integer := 40;
type channel_type is array (0 to 3) of std_logic_vector(15 downto 0);
constant c_channel_id : channel_type := (x"C01C", x"C02C", x"C03C", x"C04C");
- signal clk : std_logic;
- signal rst : std_logic := '0';
- signal fifo_empty : std_logic_vector(c_mupix_links - 1 downto 0) := (others => '1');
- signal fifo_full : std_logic_vector(c_mupix_links - 1 downto 0) := (others => '0');
+ signal clk, wrclk : std_logic;
+ signal rst : std_logic := '0';
+ signal fifo_empty : std_logic_vector(c_mupix_links - 1 downto 0) := (others => '1');
+ signal fifo_full : std_logic_vector(c_mupix_links - 1 downto 0) := (others => '0');
signal fifo_data_to_mux : std_logic_vector(c_mupix_links*c_datawidthfifo - 1 downto 0) := (others => '0');
- signal fifo_rden : std_logic_vector(c_mupix_links - 1 downto 0) := (others => '0');
- signal trb_trigger : std_logic := '0';
+ signal fifo_rden : std_logic_vector(c_mupix_links - 1 downto 0) := (others => '0');
+ signal trb_trigger : std_logic := '0';
signal dataout : std_logic_vector(c_datawidthtrb - 1 downto 0);
signal data_valid : std_logic;
signal busy : std_logic;
- signal SLV_READ_IN : std_logic := '0';
- signal SLV_WRITE_IN : std_logic := '0';
+ signal SLV_READ_IN : std_logic := '0';
+ signal SLV_WRITE_IN : std_logic := '0';
signal SLV_DATA_OUT : std_logic_vector(31 downto 0);
- signal SLV_DATA_IN : std_logic_vector(31 downto 0) := (others => '0');
- signal SLV_ADDR_IN : std_logic_vector(15 downto 0) := (others => '0');
+ signal SLV_DATA_IN : std_logic_vector(31 downto 0) := (others => '0');
+ signal SLV_ADDR_IN : std_logic_vector(15 downto 0) := (others => '0');
signal SLV_ACK_OUT : std_logic;
signal SLV_NO_MORE_DATA_OUT : std_logic;
signal SLV_UNKNOWN_ADDR_OUT : std_logic;
- signal fifo_write_en : std_logic_vector(c_mupix_links - 1 downto 0) := (others => '0');
+ signal fifo_write_en : std_logic_vector(c_mupix_links - 1 downto 0) := (others => '0');
signal fifo_datain : std_logic_vector(c_mupix_links*c_datawidthfifo - 1 downto 0) := (others => '0');
begin
);
gen_input_fifo : for i in 0 to 3 generate
- input_fifo : entity work.STD_FIFO
- generic map(
- DATA_WIDTH => c_datawidthfifo,
- FIFO_DEPTH => 16
- )
- port map(
- CLK => CLK,
- RST => RST,
- WriteEn => fifo_write_en(i),
- DataIn => fifo_datain((i + 1)*c_datawidthfifo - 1 downto i*c_datawidthfifo),
- ReadEn => fifo_rden(i),
- DataOut => fifo_data_to_mux((i + 1)*c_datawidthfifo - 1 downto i*c_datawidthfifo),
+ serdes_fifo : entity work.serdes_fifo
+ port map (
+ Data => fifo_datain((i + 1)*c_datawidthfifo - 1 downto i*c_datawidthfifo),
+ WrClock => wrclk,
+ RdClock => clk,
+ WrEn => fifo_write_en(i),
+ RdEn => fifo_rden(i),
+ Reset => rst,
+ RPReset => rst,
+ Q => fifo_data_to_mux((i + 1)*c_datawidthfifo - 1 downto i*c_datawidthfifo),
+ RCNT => open,
Empty => fifo_empty(i),
- Full => fifo_full(i)
- );
+ Full => fifo_full(i));
end generate gen_input_fifo;
wait for c_clk_period/2;
end process clock_gen;
+ wrclock_gen : process is
+ begin -- process wrclock_gen
+ wrclk <= '1';
+ wait for c_wrclk_period/2;
+ wrclk <= '0';
+ wait for c_wrclk_period/2;
+ end process wrclock_gen;
+
stimulus : process is
begin
+ rst <= '1';
+ wait for 100 ns;
+ rst <= '0';
wait for 100 ns;
TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"0000000A", x"0101");
TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"0000000B", x"0102");
TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"0000000F", x"0105");
TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000000", x"0106");
wait for 5*c_clk_period;
- for i in 1 to 10 loop
- fifo_write_en <= (others => '1');
+ for i in 1 to 20 loop
+ fifo_write_en <= (others => '1');
fifo_datain(4*c_datawidthfifo - 1 downto 3*c_datawidthfifo) <= c_channel_id(0) & std_logic_vector(to_unsigned(i, 8)) & x"BEEB";
fifo_datain(3*c_datawidthfifo - 1 downto 2*c_datawidthfifo) <= c_channel_id(1) & std_logic_vector(to_unsigned(i, 8)) & x"BEEB";
fifo_datain(2*c_datawidthfifo - 1 downto 1*c_datawidthfifo) <= c_channel_id(2) & std_logic_vector(to_unsigned(i, 8)) & x"BEEB";
fifo_datain(1*c_datawidthfifo - 1 downto 0*c_datawidthfifo) <= c_channel_id(3) & std_logic_vector(to_unsigned(i, 8)) & x"BEEB";
- wait for c_clk_period;
+ wait for c_wrclk_period;
end loop;
- fifo_write_en <= (others => '0');
+ fifo_write_en <= (others => '0');
fifo_datain(4*c_datawidthfifo - 1 downto 3*c_datawidthfifo) <= (others => '0');
wait for 500 ns;
TRBRegisterWrite(SLV_WRITE_IN, SLV_DATA_IN, SLV_ADDR_IN, x"00000000", x"0100");