diff --git a/top/firmware/hdl/LinkCombinerCore.vhd b/top/firmware/hdl/LinkCombinerCore.vhd index f1f2a0e76f37c5fe842e115e62f60d132ea8d5ce..c500d55ffe56a90e5891137361e3c6edbbafe19f 100644 --- a/top/firmware/hdl/LinkCombinerCore.vhd +++ b/top/firmware/hdl/LinkCombinerCore.vhd @@ -9,21 +9,20 @@ use work.dtc_link_maps.all; entity LinkCombinerCore is generic ( - N_INPUT_LINKS : integer := 8; - N_OUTPUT_LINKS : integer := 1 + N_INPUT_LINKS : integer := 8 ); port ( --- Input Ports --- clk_p : in std_logic; reset : in std_logic; output_reset : in std_logic := '0'; - output_rd_en : in std_logic_vector(N_OUTPUT_LINKS - 1 downto 0) := (others => '0'); + output_enable : in std_logic := '0'; links_in : in ldata(N_INPUT_LINKS - 1 downto 0); packet_start : in std_logic; header_in : in tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); header_user_bits : in std_logic_vector(31 downto 0) := (others => '0'); --- Ouput Ports --- - links_out : out ldata(N_OUTPUT_LINKS - 1 downto 0); + link_out : out lword := LWORD_NULL; --- Debug Ports --- debug : out lword := LWORD_NULL; debug_super_id : out std_logic_vector(31 downto 0); @@ -80,11 +79,9 @@ architecture Behavioral of LinkCombinerCore is -- Type Definitions type tWordArray is array(integer range <>) of std_logic_vector(cWordWidth - 1 downto 0); - type tOutputWordArray is array(integer range <>) of std_logic_vector(cOutputWordWidth - 1 downto 0); type tStatusShiftRegister is array(1 downto 0) of std_logic_vector(cNumberOfFEModules * cNumberOfCICs * 9 - 1 downto 0); type tBCIDShiftRegister is array(1 downto 0) of std_logic_vector(12 - 1 downto 0); type tInputDataCountArray is array(integer range <>) of std_logic_vector(5 downto 0); - type tOutputDataCountArray is array(integer range <>) of std_logic_vector(7 downto 0); -- Constants constant cNullValidArray : std_logic_vector(N_INPUT_LINKS - 1 downto 0) := (others => '0'); @@ -98,12 +95,22 @@ architecture Behavioral of LinkCombinerCore is signal input_data_valid : std_logic := '0'; signal input_data_count : tInputDataCountArray(N_INPUT_LINKS - 1 downto 0) := (others => (others => '0')); - signal output_din_array, output_din_array_buf : tOutputWordArray(0 to N_OUTPUT_LINKS - 1) := (others => (others => '0')); - signal output_wr_en_array, output_wr_en_array_buf, output_full_array : std_logic_vector(N_OUTPUT_LINKS - 1 downto 0) := (others => '0'); - signal output_almost_full_array, output_overflow_array : std_logic_vector(N_OUTPUT_LINKS - 1 downto 0) := (others => '0'); + signal output_din, output_din_buf : std_logic_vector(cOutputWordWidth - 1 downto 0) := (others => '0'); + signal output_wr_en, output_wr_en_buf, output_full : std_logic := '0'; + signal output_almost_full, output_overflow : std_logic := '0'; signal output_pointer : integer range 0 to N_INPUT_LINKS - 1 := 0; signal output_pointer_buffered : integer range 0 to N_INPUT_LINKS - 1 := 0; - signal output_data_count : tOutputDataCountArray(N_OUTPUT_LINKS - 1 downto 0) := (others => (others => '0')); + signal output_data_count : std_logic_vector(7 downto 0) := (others => '0'); + signal output_empty : std_logic; + signal output_valid : std_logic; + signal output_dout : std_logic_vector(cOutputWordWidth - 1 downto 0); + signal output_almost_empty : std_logic; + signal output_underflow : std_logic; + signal output_readout_countdown : integer range 0 to 256 := 0; + signal output_valid_previous : std_logic := '0'; + signal output_strobe_buffer, output_strobe_buffer_2 : std_logic := '0'; + signal output_rd_en_check : std_logic := '0'; + signal output_rd_en : std_logic := '0'; signal counter : integer := 0; signal status_sr : tStatusShiftRegister := (others => (others => '0')); @@ -159,98 +166,78 @@ begin end generate genInputLinkBuffers; - - + --==============================-- - genOutputLinkBuffers : for i in 0 to N_OUTPUT_LINKS - 1 generate + OutputLinkBufferInstance : link_combin_buffer --==============================-- - signal empty : std_logic; - signal valid : std_logic; - signal dout : std_logic_vector(cOutputWordWidth - 1 downto 0); - signal rd_en : std_logic := '0'; - signal almost_empty : std_logic; - signal data_count : std_logic_vector(6 downto 0) := (others => '0'); - signal underflow : std_logic; - signal readout_countdown : integer range 0 to 256 := 0; - signal valid_previous : std_logic := '0'; - signal strobe_buffer, strobe_buffer_2 : std_logic := '0'; - signal rd_en_check : std_logic := '0'; - - begin + PORT MAP ( + clk => clk_p, + srst => output_reset, + din => output_din_buf, + wr_en => output_wr_en_buf, + rd_en => output_rd_en, + dout => output_dout, + empty => output_empty, + almost_full => output_almost_full, + full => output_full, + overflow => output_overflow, + valid => output_valid, + underflow => output_underflow, + data_count => output_data_count, + almost_empty => output_almost_empty + ); - --==============================-- - OutputLinkBufferInstance : link_combin_buffer - --==============================-- - PORT MAP ( - clk => clk_p, - srst => output_reset, - din => output_din_array_buf(i), - wr_en => output_wr_en_array_buf(i), - rd_en => rd_en, - dout => dout, - empty => empty, - almost_full => output_almost_full_array(i), - full => output_full_array(i), - overflow => output_overflow_array(i), - valid => valid, - underflow => underflow, - data_count => output_data_count(i), - almost_empty => almost_empty - ); - - --==============================-- - pOutput: process(clk_p) - --==============================-- - variable data_count : unsigned(7 downto 0); - begin - if rising_edge(clk_p) then - valid_previous <= valid; - if valid = '1' and rd_en_check = '1' then - links_out(i).valid <= '1'; - if valid_previous = '0' then - links_out(i).start <= '1'; - else - links_out(i).start <= '0'; - end if; - links_out(i).strobe <= strobe_buffer_2; - links_out(i).data <= dout; + --==============================-- + pOutput: process(clk_p) + --==============================-- + variable data_count : unsigned(7 downto 0); + begin + if rising_edge(clk_p) then + output_valid_previous <= output_valid; + if output_valid = '1' and output_rd_en_check = '1' then + link_out.valid <= '1'; + if output_valid_previous = '0' then + link_out.start <= '1'; else - links_out(i) <= LWORD_NULL; + link_out.start <= '0'; end if; - - data_count := unsigned(output_data_count(i)); - if input_data_valid = '0' then - if data_count >= 2 and readout_countdown = 0 then - rd_en_check <= output_rd_en(i); - readout_countdown <= to_integer(data_count); - elsif output_almost_full_array(i) = '1' and readout_countdown = 0 then - rd_en_check <= output_rd_en(i); - readout_countdown <= to_integer(data_count); - end if; - else - if output_almost_full_array(i) = '1' and readout_countdown = 0 then - rd_en_check <= output_rd_en(i); - readout_countdown <= to_integer(data_count); - end if; + link_out.strobe <= output_strobe_buffer_2; + link_out.data <= output_dout; + else + link_out <= LWORD_NULL; + end if; + + data_count := unsigned(output_data_count); + if input_data_valid = '0' then + if data_count >= 2 and output_readout_countdown = 0 then + output_rd_en_check <= output_enable; + output_readout_countdown <= to_integer(data_count); + elsif output_almost_full = '1' and output_readout_countdown = 0 then + output_rd_en_check <= output_enable; + output_readout_countdown <= to_integer(data_count); end if; - if readout_countdown > 0 then - readout_countdown <= readout_countdown - 1; - rd_en <= '1'; - if readout_countdown = 1 then - strobe_buffer <= '1'; - else - strobe_buffer <= '0'; - end if; + else + if output_almost_full = '1' and output_readout_countdown = 0 then + output_rd_en_check <= output_enable; + output_readout_countdown <= to_integer(data_count); + end if; + end if; + if output_readout_countdown > 0 then + output_readout_countdown <= output_readout_countdown - 1; + output_rd_en <= '1'; + if output_readout_countdown = 1 then + output_strobe_buffer <= '1'; else - rd_en <= '0'; - strobe_buffer <= '0'; + output_strobe_buffer <= '0'; end if; - - strobe_buffer_2 <= strobe_buffer; + else + output_rd_en <= '0'; + output_strobe_buffer <= '0'; end if; - end process pOutput; - - end generate genOutputLinkBuffers; + + output_strobe_buffer_2 <= output_strobe_buffer; + end if; + end process pOutput; @@ -311,8 +298,8 @@ begin end if; end if; output_pointer_buffered <= output_pointer; - output_din_array(0) <= input_dout_array(output_pointer_buffered); - output_wr_en_array(0) <= input_valid_array(output_pointer_buffered); + output_din <= input_dout_array(output_pointer_buffered); + output_wr_en <= input_valid_array(output_pointer_buffered); if reset = '1' then @@ -331,28 +318,28 @@ begin end if; if counter = 1 then - output_wr_en_array_buf(0) <= '1'; - output_din_array_buf(0)(63 downto 32) <= header_user_bits; - output_din_array_buf(0)(31 downto 0) <= std_logic_vector(super_id); + output_wr_en_buf <= '1'; + output_din_buf(63 downto 32) <= header_user_bits; + output_din_buf(31 downto 0) <= std_logic_vector(super_id); elsif counter = 2 then - output_din_array_buf(0) <= (others => '0'); - output_din_array_buf(0)(63 downto 56) <= std_logic_vector(packet_stub_count_previous); - output_din_array_buf(0)(47 downto 36) <= bcid_sr(bcid_sr'high); - output_wr_en_array_buf(0) <= '1'; + output_din_buf <= (others => '0'); + output_din_buf(63 downto 56) <= std_logic_vector(packet_stub_count_previous); + output_din_buf(47 downto 36) <= bcid_sr(bcid_sr'high); + output_wr_en_buf <= '1'; if cNumberOfFEModules < 3 then - output_din_array_buf(0)(cNumberOfFEModules * cNumberOfCICs * 9 - 1 downto 0) <= status_sr(status_sr'high); + output_din_buf(cNumberOfFEModules * cNumberOfCICs * 9 - 1 downto 0) <= status_sr(status_sr'high); else - output_din_array_buf(0)(2 * cNumberOfCICs * 9 - 1 downto 0) <= status_sr(status_sr'high)(2 * cNumberOfCICs * 9 - 1 downto 0); + output_din_buf(2 * cNumberOfCICs * 9 - 1 downto 0) <= status_sr(status_sr'high)(2 * cNumberOfCICs * 9 - 1 downto 0); end if; elsif counter = 3 then - output_din_array_buf(0) <= (others => '0'); - output_wr_en_array_buf(0) <= '1'; + output_din_buf <= (others => '0'); + output_wr_en_buf <= '1'; if cNumberOfFEModules >= 3 and cNumberOfFEModules < 6 then - output_din_array_buf(0)((cNumberOfFEModules - 2) * cNumberOfCICs * 9 - 1 downto 0) <= status_sr(status_sr'high)(cNumberOfFEModules * cNumberOfCICs * 9 - 1 downto 2 * cNumberOfCICs * 9); + output_din_buf((cNumberOfFEModules - 2) * cNumberOfCICs * 9 - 1 downto 0) <= status_sr(status_sr'high)(cNumberOfFEModules * cNumberOfCICs * 9 - 1 downto 2 * cNumberOfCICs * 9); end if; else - output_wr_en_array_buf <= output_wr_en_array; - output_din_array_buf(0) <= output_din_array(0); + output_wr_en_buf <= output_wr_en; + output_din_buf <= output_din; end if; end if; @@ -389,19 +376,19 @@ begin -- Debug --==============================-- debug.data(31 downto 0) <= std_logic_vector(super_id); - debug.data(39 downto 32) <= output_data_count(0); + debug.data(39 downto 32) <= output_data_count; debug.data(47 downto 40) <= "00" & input_data_count(0); debug.data(51 downto 48) <= std_logic_vector(to_unsigned(counter, 4)); - debug.data(52) <= output_rd_en(0); + debug.data(52) <= output_rd_en; debug.data(56) <= packet_start; debug.data(57) <= reset; debug.data(58) <= input_data_valid; debug.valid <= '1'; debug.strobe <= '1'; debug_super_id <= std_logic_vector(super_id); - debug_fifo(7 downto 0) <= output_data_count(0); - debug_fifo(8) <= output_full_array(0); - debug_fifo(9) <= output_rd_en(0); - debug_fifo(10) <= output_overflow_array(0); + debug_fifo(7 downto 0) <= output_data_count; + debug_fifo(8) <= output_full; + debug_fifo(9) <= output_rd_en; + debug_fifo(10) <= output_overflow; end Behavioral; diff --git a/top/firmware/hdl/LinkCombinerIPBus.vhd b/top/firmware/hdl/LinkCombinerIPBus.vhd index 1ceb50e1d2f2b2876f663d2e44b10dfd3c3fd617..61ef3b53e7fa56ec73ad13ad9612ac6d48f1b592 100644 --- a/top/firmware/hdl/LinkCombinerIPBus.vhd +++ b/top/firmware/hdl/LinkCombinerIPBus.vhd @@ -24,7 +24,7 @@ entity LinkCombinerIPBus is header_in : in tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); lff : in std_logic; --- Ouput Ports --- - links_out : out ldata(1 - 1 downto 0); + link_out : out lword := LWORD_NULL; --- IPBus Ports --- ipb_clk : in std_logic; ipb_rst : in std_logic; @@ -36,7 +36,7 @@ end LinkCombinerIPBus; architecture Behavioral of LinkCombinerIPBus is signal link_combiner_debug : lword := LWORD_NULL; - signal link_combiner_rd_en : std_logic_vector(0 downto 0) := "0"; + signal link_combiner_rd_en : std_logic := '0'; signal link_combiner_debug_super_id : std_logic_vector(31 downto 0); signal masked_stubs : ldata(cNumberOfFEModules - 1 downto 0) := (others => LWORD_NULL); signal masked_input : ldata(8 - 1 downto 0) := (others => LWORD_NULL); @@ -85,9 +85,7 @@ begin --==============================-- begin if rising_edge(clk_p) then - for i in 0 downto 0 loop - link_combiner_rd_en(i) <= not lff and control_registers(0)(N_INPUT_LINKS + 2 - 1); - end loop; + link_combiner_rd_en <= not lff and control_registers(0)(N_INPUT_LINKS + 2 - 1); end if; end process pReadEnable; @@ -102,13 +100,13 @@ begin clk_p => clk_p, reset => reset, output_reset => control_registers(0)(N_INPUT_LINKS + 1 - 1), - output_rd_en => link_combiner_rd_en, + output_enable => link_combiner_rd_en, links_in => masked_input, packet_start => packet_start, header_in => header_in, header_user_bits => control_registers(1), --- Output Ports --- - links_out => links_out + link_out => link_out --- Debug Ports --- -- debug => link_combiner_debug, -- debug_super_id => link_combiner_debug_super_id, diff --git a/top/firmware/hdl/MProcessor.vhd b/top/firmware/hdl/MProcessor.vhd index 8922ea9e9be537663ecb19e39fde38bf39061106..892eee64b315c35c18d42343945bcfe35b801c7d 100644 --- a/top/firmware/hdl/MProcessor.vhd +++ b/top/firmware/hdl/MProcessor.vhd @@ -45,7 +45,6 @@ architecture Behavorial of MProcessor is signal readout_reset : std_logic := '0'; signal aggregated_stubs : ldata(7 downto 0) := (others => LWORD_NULL); signal link_aggregator_input : ldata(N_LINKS - 1 downto 0) := (others => LWORD_NULL); - signal eth_link_out : ldata(0 downto 0) := (others => LWORD_NULL); signal status_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0')); signal control_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0')); @@ -124,7 +123,7 @@ begin header_in => header_in, lff => gbe_backpressure, --- Output Ports --- - links_out => eth_link_out, + link_out => link_out, --- IPBus Ports --- ipb_clk => ipb_clk, ipb_rst => ipb_rst, @@ -142,7 +141,6 @@ begin -- ); link_aggregator_input(N_LINKS - 1 downto 0) <= links_in; - link_out <= eth_link_out(0); status_registers(0)(0) <= gbe_backpressure; packet_start <= header_start_array(to_integer(unsigned(control_registers(0)(2 downto 0))))(0);