diff --git a/README.md b/README.md index 796343e6761886a27640dbf912b9ffee5333032e..aea2de9c5605855ed25ca65038165369c8f9c8b6 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# MProcessor Firmware +# MProcessor Firmware - 2x10gbe ## Instructions to Run ```bash # Pull the package onto the Serenity card diff --git a/dependencies.yml b/dependencies.yml index 84de3fc6ae30163ac6b76c7ef90e6344ccbc2ff7..0eab637d15dc099d71b8d6d9b5ab3d70a25c1e1a 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -49,5 +49,5 @@ sources: url: https://github.com/KristianHahn/verilog-ethernet.git 10gb-ethernet: - tag: v1.0.0 + tag: v2.0.0 url: https://gitlab.cern.ch/cms-tracker-phase2-data-processing/BE_firmware/10gb-ethernet.git diff --git a/replacements/emp-fwk/components/top/addr_table/top_emp.xml b/replacements/emp-fwk/components/top/addr_table/top_emp.xml index d18a7fd07d948d566e678a7c26aaa2e8a6a27c2e..1dbfd363469346dc91c8246cdb91dd03529efd01 100644 --- a/replacements/emp-fwk/components/top/addr_table/top_emp.xml +++ b/replacements/emp-fwk/components/top/addr_table/top_emp.xml @@ -3,7 +3,7 @@ <node id="ctrl" module="file://emp_ctrl.xml" address="0x200"/> <node id="ttc" module="file://emp_ttc.xml" address="0x400"/> <node id="datapath" module="file://emp_datapath.xml" address="0x2000"/> - <node id="eth10g" module="file://emp_eth10g.xml" address="0x4000"/> + <node id="eth10g" module="file://emp_eth10g_interface.xml" address="0x4000"/> <node id="freq" module="file://ipbus_freq_ctr.xml" address="0x40000000"/> <node id="payload" module="file://emp_payload.xml" address="0x80000000" fwinfo="endpoint;width=31"/> </node> diff --git a/replacements/emp-fwk/components/top/firmware/hdl/emp_top_pcie_both_ttc.vhd b/replacements/emp-fwk/components/top/firmware/hdl/emp_top_pcie_both_ttc.vhd index 4325d53fdd4647e92239ece5bceb818d1ba7c0e2..092073ff1e78995b1e4b4baf347c743a645b25ef 100644 --- a/replacements/emp-fwk/components/top/firmware/hdl/emp_top_pcie_both_ttc.vhd +++ b/replacements/emp-fwk/components/top/firmware/hdl/emp_top_pcie_both_ttc.vhd @@ -57,10 +57,10 @@ entity top is tcds_tx_p : out std_logic; tcds_tx_n : out std_logic; -- 10g eth signals - gbe_rx_p : in std_logic; - gbe_rx_n : in std_logic; - gbe_tx_p : out std_logic; - gbe_tx_n : out std_logic; + gbe_rx_p : in std_logic_vector(1 downto 0); + gbe_rx_n : in std_logic_vector(1 downto 0); + gbe_tx_p : out std_logic_vector(1 downto 0); + gbe_tx_n : out std_logic_vector(1 downto 0); gbe_mgt_refclk_p : in std_logic; gbe_mgt_refclk_n : in std_logic; -- Transceiver ref-clocks @@ -115,18 +115,10 @@ architecture rtl of top is signal clk125_s : std_logic; - signal gbe_ldata : lword; - - signal dbg_pause_count : std_logic_vector(31 downto 0); - signal dbg_pkt_count : std_logic_vector(15 downto 0); - signal dbg_pkt_ctrl : std_logic_vector(2 downto 0); - signal dbg_pkt_rdy : std_logic; - signal dbg_pkt_go : std_logic; - - -- aug28 - signal lff,lff_rcvd : std_logic; - signal payload_rst : std_logic; -- sep2 - + -- 10g + signal gbe_ldata : ldata(1 downto 0); + signal gbe_lff : std_logic_vector(1 downto 0); + -- KH tmp signal clk_40_div, clk_p_div : std_logic; @@ -298,34 +290,40 @@ begin q => payload_q, gpio => open, gpio_en => open, - -- - ldata_out => gbe_ldata, - lff => lff + -- 10g + gbe_q => gbe_ldata, + gbe_backpressure => gbe_lff ); - eth : entity work.emp_eth10g - generic map( ILA_DEBUG => true) - --ILA_DEBUG_MORE => false) - port map ( + -- + -- 10g + -- + eth10g : entity work.emp_eth10g_interface + generic map ( ETH10G_CHANNELS => 2 ) + port map ( clk_ipb => ipb_clk, rst_ipb => ipb_rst, ipb_in => ipb_w_array(N_SLV_ETH10G), ipb_out => ipb_r_array(N_SLV_ETH10G), -- - clk_p => clk_p, - rst_p => rst_p, - clk125 => clk125, - gbe_rx_p => gbe_rx_p, - gbe_rx_n => gbe_rx_n, - gbe_tx_p => gbe_tx_p, - gbe_tx_n => gbe_tx_n, - gbe_mgt_refclk_p => gbe_mgt_refclk_p, - gbe_mgt_refclk_n => gbe_mgt_refclk_n, - ldata_in => gbe_ldata, - -- - lff => lff + clk_p => clk_p, + rst_p => rst_p, + clk125 => clk125, + -- Input from payload + ldata_in => gbe_ldata, + -- backpressure to payload + lff => gbe_lff, + --10g + gbe_rx_p => gbe_rx_p, + gbe_rx_n => gbe_rx_n, + gbe_tx_p => gbe_tx_p, + gbe_tx_n => gbe_tx_n, + gbe_mgt_refclk_p => gbe_mgt_refclk_p, + gbe_mgt_refclk_n => gbe_mgt_refclk_n ); + + -- KH tmp to check clk_p diff --git a/top/addr_table/emp_payload.xml b/top/addr_table/emp_payload.xml index 15d20dcb009db551c6e412d035ca5f23fb510146..2eaa7ffad503522e0fe60c40af66ecc7205788f1 100644 --- a/top/addr_table/emp_payload.xml +++ b/top/addr_table/emp_payload.xml @@ -14,43 +14,11 @@ </node> <node id="fe_chan" address="0x040" description="FE channel control and status" module="file://link_interface.xml" fwinfo="endpoint;width=6"/> - - <node id="mprocessor" address="0x080" description="Link Aggregator control and status" fwinfo="endpoint;width=3"> - <node id="link_aggregator_control" address="0x0"> - <node id="reset" mask="0x0001"/> - </node> - <node id="link_combiner_control" address="0x1"> - <node id="reset" mask="0x0001"/> - <node id="enable" mask="0x0002"/> - </node> - <node id="input_link_mask" address="0x2"> - <node id="link_aggregator" mask="0xf"/> - <node id="link_combiner" mask="0xff0"/> - <node id="head_start_select" mask="0x3000"/> - </node> - <node id="header_user_bits" address="0x3"/> - - <node id="super_id" address="0x4"/> - <node id="lff" address="0x5" mask="0x0001"/> - <node id="link_combiner_fifo" address="0x6"> - <node id="data_count" mask="0xff"/> - <node id="full" mask="0x100"/> - <node id="rd_en" mask="0x200"/> - <node id="overflow" mask="0x400"/> - </node> - <node id="status" address="0x7"> - <node id="link_aggregator_output_0_overflow" mask="0x1"/> - <node id="link_aggregator_output_1_overflow" mask="0x2"/> - <node id="link_aggregator_output_2_overflow" mask="0x4"/> - <node id="link_aggregator_output_3_overflow" mask="0x8"/> - <node id="link_aggregator_output_4_overflow" mask="0x10"/> - <node id="link_aggregator_output_5_overflow" mask="0x20"/> - <node id="link_aggregator_output_6_overflow" mask="0x40"/> - <node id="link_aggregator_output_7_overflow" mask="0x80"/> - <node id="link_aggregator_cache_0_0_overflow" mask="0x100"/> - <node id="link_aggregator_route_0_0_overflow" mask="0x200"/> - </node> + + <node id="mproc_ctrl" address="0x1ff" description="MProcessor channel control" fwinfo="endpoint;width=0"> + <node id="chan_sel" mask="0x7f"/> </node> + <node id="mprocessor" address="0x200" description="MProcessor control and status" module="file://mprocessor.xml" fwinfo="endpoint;width=7"/> <node id="mem1" address="0x1000" size="0x200" mode="incremental" fwinfo="endpoint;width=9"/> <node id="mem2" address="0x2000" size="0x200" mode="incremental" fwinfo="endpoint;width=9"/> diff --git a/top/addr_table/link_aggregator.xml b/top/addr_table/link_aggregator.xml new file mode 100644 index 0000000000000000000000000000000000000000..a6ab3964ed27d2a1a7dfae821b7f8819e3b06e2a --- /dev/null +++ b/top/addr_table/link_aggregator.xml @@ -0,0 +1,15 @@ +<node description="Link Aggregator control and status" fwinfo="endpoint"> + <node id="chan_sel" address="0x000" description="Bx channel select" fwinfo="endpoint;width=0"/> + <node id="control" address="0x001" fwinfo="endpoint;width=0"> + <node id="input_link_mask" mask="0x03f"/> + <node id="reset" mask="0x40"/> + </node> + <node id="monitoring" address="0x008" fwinfo="endpoint;width=3"> + <node id="non_empty_count_0" address="0x0"/> + <node id="non_empty_count_1" address="0x1"/> + <node id="non_empty_count_2" address="0x2"/> + <node id="non_empty_count_3" address="0x3"/> + <node id="non_empty_count_4" address="0x4"/> + <node id="non_empty_count_5" address="0x5"/> + </node> +</node> diff --git a/top/addr_table/mprocessor.xml b/top/addr_table/mprocessor.xml new file mode 100644 index 0000000000000000000000000000000000000000..57de74f4a685f1dfc83ce13ac3df042663237bb8 --- /dev/null +++ b/top/addr_table/mprocessor.xml @@ -0,0 +1,17 @@ +<node description="MProcessor Control and Status" fwinfo="endpoint"> + <node id="link_aggregator" address="0x0" description="Link Aggregator control and status" module="file://link_aggregator.xml" fwinfo="endpoint;width=5"/> + + <node id="link_combiner" address="0x20" description="Link Combiner control and status" fwinfo="endpoint;width=1"> + <node id="control" address="0x000"> + <node id="input_link_mask" mask="0x0ff"/> + <node id="reset" mask="0x100"/> + <node id="enable" mask="0x200"/> + </node> + <node id="header_user_bits" address="0x1"/> + </node> + + <node id="csr" address="0x22" description="MProcessor control and status" fwinfo="endpoint;width=1"> + <node id="header_start_select" address="0x0" mask="0x7"/> + <node id="lff" address="0x1" mask="0x0001"/> + </node> +</node> diff --git a/top/firmware/cfg/top.dep b/top/firmware/cfg/top.dep index 0bb0b67169fd2743d2d1fa2987cf3a4aaa4df205..3c062d39ee76f45ee98d5288ea826c403ff0a0a0 100644 --- a/top/firmware/cfg/top.dep +++ b/top/firmware/cfg/top.dep @@ -22,10 +22,16 @@ src emp_project_decl.vhd src emp_payload.vhd src link_maps.vhd src ipbus_decode_emp_payload.vhd -src LinkAggregator.vhd +src mprocessor_constants.vhd +src MProcessor.vhd +src ipbus_decode_mprocessor.vhd +src LinkAggregatorCore.vhd +src LinkAggregatorIPBus.vhd +src ipbus_decode_link_aggregator.vhd src fixed_pkg_2008.vhd src --vhdl2008 TrackReconstructor.vhd -src LinkCombiner.vhd +src LinkCombinerCore.vhd +src LinkCombinerIPBus.vhd src --cd ../cgn link_agg_single_link_fifo.xci setup -f --cd ../cgn link_agg_single_link_fifo.tcl @@ -40,4 +46,6 @@ src --cd ../cgn link_combin_buffer.xci setup -f --cd ../cgn link_combin_buffer.tcl +addrtab link_aggregator.xml addrtab emp_payload.xml +addrtab mprocessor.xml diff --git a/top/firmware/hdl/LinkAggregator.vhd b/top/firmware/hdl/LinkAggregatorCore.vhd similarity index 59% rename from top/firmware/hdl/LinkAggregator.vhd rename to top/firmware/hdl/LinkAggregatorCore.vhd index 351ccfd1860902acd0c0044260435cefd93cbea0..609f1499e10917b19cd0eda63c956c51f2391cba 100644 --- a/top/firmware/hdl/LinkAggregator.vhd +++ b/top/firmware/hdl/LinkAggregatorCore.vhd @@ -3,31 +3,38 @@ use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use work.emp_data_types.all; -entity LinkAggregator is - generic ( - N_LINKS : integer - ); - port ( - --- Input Ports --- - clk_p : in std_logic; - reset : in std_logic; - packet_start : in std_logic; - links_in : in ldata(N_LINKS - 1 downto 0); - --- Output Ports --- - links_out : out ldata(7 downto 0) := (others => LWORD_NULL); - uncompressed_stubs : out ldata(N_LINKS * 8 - 1 downto 0) := (others => LWORD_NULL); - readout_reset : out std_logic := '0'; - --- Debug Ports --- - status_bits : out std_logic_vector(15 downto 0) - ); -end LinkAggregator; - -architecture compressed of LinkAggregator is +use work.ipbus.all; +use work.ipbus_reg_types.all; + + +entity LinkAggregatorCore is + generic ( + N_LINKS : integer + ); + port ( + --- Input Ports --- + clk_p : in std_logic; + reset : in std_logic; + packet_start : in std_logic; + links_in : in ldata(N_LINKS - 1 downto 0); + --- Output Ports --- + links_out : out ldata(7 downto 0) := (others => LWORD_NULL); + uncompressed_stubs : out ldata(N_LINKS * 8 - 1 downto 0) := (others => LWORD_NULL); + readout_reset : out std_logic := '0'; + --- Debug Ports --- + status_bits : out std_logic_vector(15 downto 0); + --- IPBus Ports --- + non_empty_counts : out ipb_reg_v(8*N_LINKS - 1 downto 0) + ); +end LinkAggregatorCore; + + +architecture compressed of LinkAggregatorCore is constant cFIFOWidth : integer := 64; - -- FIFO IP Cores + -- FIFO IP Coress COMPONENT link_agg_single_link_fifo PORT ( @@ -117,8 +124,11 @@ architecture compressed of LinkAggregator is end function; signal output_overflow_array : std_logic_vector(cBoxcarBx - 1 downto 0) := (others => '0'); - signal route_overflow_array : tEnableArray := cNullEnableArray; - signal cache_overflow_array : tEnableArray := cNullEnableArray; + signal route_overflow_array : tEnableArray := cNullEnableArray; + signal cache_overflow_array : tEnableArray := cNullEnableArray; + + + signal non_empty_fifo_count : ipb_reg_v(8*N_LINKS - 1 downto 0) := (others => (others => '0')); begin @@ -178,6 +188,12 @@ begin rd_en_cache <= '0'; end if; end if; + -- Check for non-empty FIFOs at reset + if route_reset = '1' then + if empty_route = '0' then + non_empty_fifo_count(N_LINKS*j + i) <= std_logic_vector(unsigned(non_empty_fifo_count(N_LINKS*j + i)) + 1); + end if; + end if; end if; end process pTransferToRoutingFIFO; @@ -381,269 +397,6 @@ begin status_bits(7) <= output_overflow_array(7); -- link_aggregator_output_7_overflow; status_bits(8) <= cache_overflow_array(0)(0); -- link_aggregator_cache_0_0_overflow; status_bits(9) <= route_overflow_array(0)(0); -- link_aggregator_route_0_0_overflow; + non_empty_counts <= non_empty_fifo_count; end compressed; - - - ---======================================================================================================================================================-- - - - -architecture uncompressed of LinkAggregator is - - constant cFIFOWidth : integer := 64; - - - -- FIFO IP Cores - - COMPONENT link_agg_single_link_fifo - PORT ( - --- Input Ports --- - clk : IN STD_LOGIC; - srst : IN STD_LOGIC; - din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); - wr_en : IN STD_LOGIC; - rd_en : IN STD_LOGIC; - --- Output Ports --- - dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); - full : OUT STD_LOGIC; - empty : OUT STD_LOGIC; - almost_empty : OUT STD_LOGIC; - valid : OUT STD_LOGIC; - data_count : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); - wr_rst_busy : OUT STD_LOGIC; - rd_rst_busy : OUT STD_LOGIC - ); - END COMPONENT; - COMPONENT link_agg_single_link_fifo_fwft - PORT ( - --- Input Ports --- - clk : IN STD_LOGIC; - srst : IN STD_LOGIC; - din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); - wr_en : IN STD_LOGIC; - rd_en : IN STD_LOGIC; - --- Output Ports --- - dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); - full : OUT STD_LOGIC; - empty : OUT STD_LOGIC; - almost_empty : OUT STD_LOGIC; - valid : OUT STD_LOGIC; - data_count : OUT STD_LOGIC_VECTOR(4 DOWNTO 0); - wr_rst_busy : OUT STD_LOGIC; - rd_rst_busy : OUT STD_LOGIC - ); - END COMPONENT; - COMPONENT link_agg_all_links_fifo - PORT ( - --- Input Ports --- - clk : IN STD_LOGIC; - srst : IN STD_LOGIC; - din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); - wr_en : IN STD_LOGIC; - rd_en : IN STD_LOGIC; - --- Output Ports --- - dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); - full : OUT STD_LOGIC; - empty : OUT STD_LOGIC; - almost_empty : OUT STD_LOGIC; - valid : OUT STD_LOGIC; - data_count : OUT STD_LOGIC_VECTOR(5 DOWNTO 0); - wr_rst_busy : OUT STD_LOGIC; - rd_rst_busy : OUT STD_LOGIC - ); - END COMPONENT; - - constant cBoxcarBx : integer := 8; - - type tLinkDataArray is array(N_LINKS - 1 downto 0) of std_logic_vector(cFIFOWidth - 1 downto 0); - type t2DDataArray is array(cBoxcarBx - 1 downto 0) of tLinkDataArray; - type tEnableArray is array(cBoxcarBx - 1 downto 0) of std_logic_vector(N_LINKS - 1 downto 0); - - signal data : t2DDataArray := (others => (others => (others => '0'))); - signal rd_en_route_array : tEnableArray := (others => (others => '0')); - signal valid_route_array : tEnableArray := (others => (others => '0')); - signal counter : integer := 0; - -begin - --==============================-- - genLinkCache : for i in N_LINKS - 1 downto 0 generate - --==============================-- - signal wr_en_array_cache : std_logic_vector(cBoxcarBx - 1 downto 0) := (others => '0'); - signal data_in : std_logic_vector(cFIFOWidth - 1 downto 0); - begin - - -- Send the data to the correct FIFO, using the Bx field of the stub - pRouteInputData : process(clk_p) - begin - if rising_edge(clk_p) then - wr_en_array_cache <= (others => '0'); - wr_en_array_cache(to_integer(unsigned(links_in(i).data(17 downto 15)))) <= links_in(i).valid; - data_in <= std_logic_vector(to_unsigned(i, 4)) & links_in(i).data(cFIFOWidth - 1 - 4 downto 0); - end if; - end process; - - - --==============================-- - genLinkBxCache : for j in cBoxcarBx - 1 downto 0 generate - --==============================-- - signal dout_cache : std_logic_vector(cFIFOWidth - 1 downto 0); - signal rd_en_cache, full_cache, empty_cache, valid_cache, almost_empty_cache : std_logic := '0'; - signal count_cache : std_logic_vector(3 downto 0); - - signal wr_en_route, rd_en_route, empty_route, full_route, valid_route, almost_empty_route : std_logic := '0'; - signal din_route, dout_route : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0'); - signal count_route : std_logic_vector(4 downto 0); - signal route_reset : std_logic := '0'; - - begin - - pTransferToRoutingFIFO : process(clk_p) - begin - if rising_edge(clk_p) then - -- If FIFO is not empty at start of packet, enable readout to routing FIFO - if packet_start = '1' then - if empty_cache = '0' then - rd_en_cache <= '1'; - end if; - end if; - if rd_en_cache = '1' then - -- Use almost empty flag to avoid underflow - if almost_empty_cache = '1' then - rd_en_cache <= '0'; - end if; - end if; - end if; - end process; - - -- Enable writing of routing FIFO using the validflag of the cache FIFO - wr_en_route <= valid_cache; - din_route <= dout_cache; - - SingleLinkCacheInstance : link_agg_single_link_fifo - PORT MAP ( - --- Input Ports --- - clk => clk_p, - srst => reset, - din => data_in, - wr_en => wr_en_array_cache(j), - rd_en => rd_en_cache, - --- Output Ports --- - dout => dout_cache, - full => full_cache, - empty => empty_cache, - valid => valid_cache, - almost_empty => almost_empty_cache, - data_count => count_cache - ); - SingleLinkRoutingFIFOInstance : link_agg_single_link_fifo_fwft - PORT MAP ( - --- Input Ports --- - clk => clk_p, - srst => route_reset, -- Reset FIFO for every packet - din => din_route, - wr_en => wr_en_route, - rd_en => rd_en_route_array(j)(i), - --- Output Ports --- - dout => data(j)(i), - full => full_route, - empty => empty_route, - valid => valid_route_array(j)(i), - data_count => count_route - ); - - route_reset <= reset or packet_start; - - end generate; - end generate; - - genAggregatedFIFOs : for i in 7 downto 0 generate - signal pointer : integer := 0; - signal din : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0'); - - signal wr_en, rd_en, full, empty, almost_empty, valid : std_logic := '0'; - signal dout : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0'); - signal data_count : std_logic_vector(5 downto 0); - signal all_links_reset : std_logic := '0'; - - begin - pIteratePointer : process(clk_p) - begin - if rising_edge(clk_p) then - -- Loop pointer over all the links - if pointer = N_LINKS - 1 then - pointer <= 0; - else - pointer <= pointer + 1; - end if; - -- Readout value of FIFO which is currently pointed to - rd_en_route_array(i) <= (others => '0'); - rd_en_route_array(i)(pointer) <= valid_route_array(i)(pointer); - din <= data(i)(pointer); - - -- If counter is at the end of a packet, then start to readout the contents of the aggregated FIFOs - if counter = 48 then - rd_en <= '1'; - end if; - if rd_en = '1' then - if almost_empty = '1' then - rd_en <= '0'; - end if; - end if; - - if valid = '1' then - links_out(i).valid <= '1'; - links_out(i).data <= dout; - links_out(i).strobe <= '1'; - else - links_out(i).valid <= '0'; - links_out(i).data <= (others => '0'); - links_out(i).strobe <= '1'; - end if; - wr_en <= valid_route_array(i)(pointer); - end if; - - end process; - - - AllLinksFIFOInstance : link_agg_all_links_fifo - PORT MAP ( - --- Input Ports --- - clk => clk_p, - srst => all_links_reset, -- Reset FIFO on every packet - din => din, - wr_en => wr_en, - rd_en => rd_en, - --- Output Ports --- - dout => dout, - full => full, - empty => empty, - almost_empty => almost_empty, - valid => valid, - data_count => data_count - ); - - all_links_reset <= packet_start or reset; - - end generate; - - pReadoutReset : process(clk_p) - begin - if rising_edge(clk_p) then - if packet_start = '1' then - counter <= 0; - else - counter <= counter + 1; - end if; - -- If counter is at the end of a packet, then start to readout the contents of the aggregated FIFOs - readout_reset <= '0'; - if counter = 64 then - counter <= counter; - elsif counter = 48 then - readout_reset <= '1'; - end if; - end if; - end process pReadoutReset; - -end uncompressed; diff --git a/top/firmware/hdl/LinkAggregatorIPBus.vhd b/top/firmware/hdl/LinkAggregatorIPBus.vhd new file mode 100644 index 0000000000000000000000000000000000000000..25bad0443646df2d35d9865bc63acb5d12653f76 --- /dev/null +++ b/top/firmware/hdl/LinkAggregatorIPBus.vhd @@ -0,0 +1,194 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.emp_data_types.all; + +use work.ipbus.all; +use work.ipbus_reg_types.all; + +use work.ipbus_decode_link_aggregator.all; + + +entity LinkAggregatorIPBus is + generic ( + N_LINKS : integer + ); + port ( + --- Input Ports --- + clk_p : in std_logic; + packet_start : in std_logic; + links_in : in ldata(N_LINKS - 1 downto 0); + --- Output Ports --- + links_out : out ldata(7 downto 0) := (others => LWORD_NULL); + uncompressed_stubs : out ldata(N_LINKS * 8 - 1 downto 0) := (others => LWORD_NULL); + readout_reset : out std_logic := '0'; + --- IPBus Ports --- + ipb_clk : in std_logic; + ipb_rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus + ); +end LinkAggregatorIPBus; + + +architecture Behavorial of LinkAggregatorIPBus is + + signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0); + signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0); + signal channel_sel : ipb_reg_v(0 downto 0); + signal ipb_chain : ipbdc_bus_array(8 downto 0); + + -- signal link_aggregator_status_registers : ipb_reg_v(4 - 1 downto 0) := (others => (others => '0')); + signal control_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0')); + signal mprocessor_monitoring_registers : ipb_reg_v(8*N_LINKS - 1 downto 0) := (others => (others => '0')); + + signal masked_links : ldata(N_LINKS - 1 downto 0) := (others => LWORD_NULL); + +begin + + --==============================-- + -- IPBus + --==============================-- + + --==============================-- + fabric: entity work.ipbus_fabric_sel + --==============================-- + generic map( + NSLV => N_SLAVES, + SEL_WIDTH => IPBUS_SEL_WIDTH + ) + port map( + ipb_in => ipb_in, + ipb_out => ipb_out, + sel => ipbus_sel_link_aggregator(ipb_in.ipb_addr), + ipb_to_slaves => ipb_to_slaves, + ipb_from_slaves => ipb_from_slaves + ); + + --==============================-- + channel_ctrl: entity work.ipbus_reg_v + --==============================-- + generic map( + N_REG => 1 + ) + port map( + clk => ipb_clk, + reset => ipb_rst, + ipbus_in => ipb_to_slaves(N_SLV_CHAN_SEL), + ipbus_out => ipb_from_slaves(N_SLV_CHAN_SEL), + q => channel_sel, + qmask => (0 => X"0000007f") + ); + + --==============================-- + ControlInstance: entity work.ipbus_ctrlreg_v + --==============================-- + generic map( + N_CTRL => 1, + N_STAT => 0 + ) + port map( + clk => ipb_clk, + reset => ipb_rst, + ipbus_in => ipb_to_slaves(N_SLV_CONTROL), + ipbus_out => ipb_from_slaves(N_SLV_CONTROL), + -- d => link_aggregator_status_registers, + q => control_registers + ); + + --==============================-- + channel_select: entity work.ipbus_dc_fabric_sel + --==============================-- + generic map( + SEL_WIDTH => 7 + ) + port map( + clk => ipb_clk, + rst => ipb_rst, + sel => channel_sel(0)(6 downto 0), + ipb_in => ipb_to_slaves(N_SLV_MONITORING), + ipb_out => ipb_from_slaves(N_SLV_MONITORING), + ipbdc_out => ipb_chain(0), + ipbdc_in => ipb_chain(8) + ); + + --==============================-- + pInputLinkMask: process(clk_p) + --==============================-- + begin + if rising_edge(clk_p) then + for i in 0 to N_LINKS - 1 loop + if control_registers(0)(i) = '1' then + masked_links(i) <= links_in(i); + else + masked_links(i) <= LWORD_NULL; + end if; + end loop; + end if; + end process; + + --==============================-- + gMonitoringRegisters : for i in 0 to 7 generate + --==============================-- + signal ipb_to_channel : ipb_wbus; + signal ipb_from_channel : ipb_rbus; + signal din : ipb_reg_v(6 - 1 downto 0) := (others => (others => '0')); + begin + --==============================-- + channel_node: entity work.ipbus_dc_node + --==============================-- + generic map( + I_SLV => i, + SEL_WIDTH => 7, + PIPELINE => false + ) + port map( + clk => ipb_clk, + rst => ipb_rst, + ipb_out => ipb_to_channel, + ipb_in => ipb_from_channel, + ipbdc_in => ipb_chain(i), + ipbdc_out => ipb_chain(i + 1) + ); + + --==============================-- + MProcessorMonitoringInstance: entity work.ipbus_ctrlreg_v + --==============================-- + generic map( + N_CTRL => 0, + N_STAT => 6 + ) + port map( + clk => ipb_clk, + reset => ipb_rst, + ipbus_in => ipb_to_channel, + ipbus_out => ipb_from_channel, + d => din + ); + + din(N_LINKS - 1 downto 0) <= mprocessor_monitoring_registers((i+1)*N_LINKS - 1 downto i*N_LINKS); + end generate gMonitoringRegisters; + + + --==============================-- + LinkAggregatorInstance: entity work.LinkAggregatorCore + --==============================-- + generic map ( + N_LINKS => N_LINKS + ) + port map ( + --- Input Ports --- + clk_p => clk_p, + reset => control_registers(0)(N_LINKS + 1 - 1), + packet_start => packet_start, + links_in => masked_links, + --- Output Ports --- + links_out => links_out, + readout_reset => readout_reset, + --- Debug Ports --- + -- status_bits => link_aggregator_status_registers(3)(15 downto 0), + non_empty_counts => mprocessor_monitoring_registers + ); + + +end Behavorial; diff --git a/top/firmware/hdl/LinkAggregatorUncompressed.vhd b/top/firmware/hdl/LinkAggregatorUncompressed.vhd new file mode 100644 index 0000000000000000000000000000000000000000..ded60c3a538209065add03e305128ff5afdbbbdf --- /dev/null +++ b/top/firmware/hdl/LinkAggregatorUncompressed.vhd @@ -0,0 +1,290 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.emp_data_types.all; + +use work.ipbus.all; +use work.ipbus_reg_types.all; + +entity LinkAggregator is + generic ( + N_LINKS : integer + ); + port ( + --- Input Ports --- + clk_p : in std_logic; + reset : in std_logic; + packet_start : in std_logic; + links_in : in ldata(N_LINKS - 1 downto 0); + --- Output Ports --- + links_out : out ldata(7 downto 0) := (others => LWORD_NULL); + uncompressed_stubs : out ldata(N_LINKS * 8 - 1 downto 0) := (others => LWORD_NULL); + readout_reset : out std_logic := '0'; + --- Debug Ports --- + status_bits : out std_logic_vector(15 downto 0); + --- IPBus Ports --- + clk : in std_logic; + rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus; + non_empty_counts : out ipb_reg_v(8*N_LINKS - 1 downto 0) + ); +end LinkAggregator; + +architecture uncompressed of LinkAggregator is + + constant cFIFOWidth : integer := 64; + + + -- FIFO IP Cores + + COMPONENT link_agg_single_link_fifo + PORT ( + --- Input Ports --- + clk : IN STD_LOGIC; + srst : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + --- Output Ports --- + dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); + full : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + almost_empty : OUT STD_LOGIC; + valid : OUT STD_LOGIC; + data_count : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); + wr_rst_busy : OUT STD_LOGIC; + rd_rst_busy : OUT STD_LOGIC + ); + END COMPONENT; + COMPONENT link_agg_single_link_fifo_fwft + PORT ( + --- Input Ports --- + clk : IN STD_LOGIC; + srst : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + --- Output Ports --- + dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); + full : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + almost_empty : OUT STD_LOGIC; + valid : OUT STD_LOGIC; + data_count : OUT STD_LOGIC_VECTOR(4 DOWNTO 0); + wr_rst_busy : OUT STD_LOGIC; + rd_rst_busy : OUT STD_LOGIC + ); + END COMPONENT; + COMPONENT link_agg_all_links_fifo + PORT ( + --- Input Ports --- + clk : IN STD_LOGIC; + srst : IN STD_LOGIC; + din : IN STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); + wr_en : IN STD_LOGIC; + rd_en : IN STD_LOGIC; + --- Output Ports --- + dout : OUT STD_LOGIC_VECTOR(cFIFOWidth - 1 DOWNTO 0); + full : OUT STD_LOGIC; + empty : OUT STD_LOGIC; + almost_empty : OUT STD_LOGIC; + valid : OUT STD_LOGIC; + data_count : OUT STD_LOGIC_VECTOR(5 DOWNTO 0); + wr_rst_busy : OUT STD_LOGIC; + rd_rst_busy : OUT STD_LOGIC + ); + END COMPONENT; + + constant cBoxcarBx : integer := 8; + + type tLinkDataArray is array(N_LINKS - 1 downto 0) of std_logic_vector(cFIFOWidth - 1 downto 0); + type t2DDataArray is array(cBoxcarBx - 1 downto 0) of tLinkDataArray; + type tEnableArray is array(cBoxcarBx - 1 downto 0) of std_logic_vector(N_LINKS - 1 downto 0); + + signal data : t2DDataArray := (others => (others => (others => '0'))); + signal rd_en_route_array : tEnableArray := (others => (others => '0')); + signal valid_route_array : tEnableArray := (others => (others => '0')); + signal counter : integer := 0; + +begin + --==============================-- + genLinkCache : for i in N_LINKS - 1 downto 0 generate + --==============================-- + signal wr_en_array_cache : std_logic_vector(cBoxcarBx - 1 downto 0) := (others => '0'); + signal data_in : std_logic_vector(cFIFOWidth - 1 downto 0); + begin + + -- Send the data to the correct FIFO, using the Bx field of the stub + pRouteInputData : process(clk_p) + begin + if rising_edge(clk_p) then + wr_en_array_cache <= (others => '0'); + wr_en_array_cache(to_integer(unsigned(links_in(i).data(17 downto 15)))) <= links_in(i).valid; + data_in <= std_logic_vector(to_unsigned(i, 4)) & links_in(i).data(cFIFOWidth - 1 - 4 downto 0); + end if; + end process; + + + --==============================-- + genLinkBxCache : for j in cBoxcarBx - 1 downto 0 generate + --==============================-- + signal dout_cache : std_logic_vector(cFIFOWidth - 1 downto 0); + signal rd_en_cache, full_cache, empty_cache, valid_cache, almost_empty_cache : std_logic := '0'; + signal count_cache : std_logic_vector(3 downto 0); + + signal wr_en_route, rd_en_route, empty_route, full_route, valid_route, almost_empty_route : std_logic := '0'; + signal din_route, dout_route : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0'); + signal count_route : std_logic_vector(4 downto 0); + signal route_reset : std_logic := '0'; + + begin + + pTransferToRoutingFIFO : process(clk_p) + begin + if rising_edge(clk_p) then + -- If FIFO is not empty at start of packet, enable readout to routing FIFO + if packet_start = '1' then + if empty_cache = '0' then + rd_en_cache <= '1'; + end if; + end if; + if rd_en_cache = '1' then + -- Use almost empty flag to avoid underflow + if almost_empty_cache = '1' then + rd_en_cache <= '0'; + end if; + end if; + end if; + end process; + + -- Enable writing of routing FIFO using the validflag of the cache FIFO + wr_en_route <= valid_cache; + din_route <= dout_cache; + + SingleLinkCacheInstance : link_agg_single_link_fifo + PORT MAP ( + --- Input Ports --- + clk => clk_p, + srst => reset, + din => data_in, + wr_en => wr_en_array_cache(j), + rd_en => rd_en_cache, + --- Output Ports --- + dout => dout_cache, + full => full_cache, + empty => empty_cache, + valid => valid_cache, + almost_empty => almost_empty_cache, + data_count => count_cache + ); + SingleLinkRoutingFIFOInstance : link_agg_single_link_fifo_fwft + PORT MAP ( + --- Input Ports --- + clk => clk_p, + srst => route_reset, -- Reset FIFO for every packet + din => din_route, + wr_en => wr_en_route, + rd_en => rd_en_route_array(j)(i), + --- Output Ports --- + dout => data(j)(i), + full => full_route, + empty => empty_route, + valid => valid_route_array(j)(i), + data_count => count_route + ); + + route_reset <= reset or packet_start; + + end generate; + end generate; + + genAggregatedFIFOs : for i in 7 downto 0 generate + signal pointer : integer := 0; + signal din : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0'); + + signal wr_en, rd_en, full, empty, almost_empty, valid : std_logic := '0'; + signal dout : std_logic_vector(cFIFOWidth - 1 downto 0) := (others => '0'); + signal data_count : std_logic_vector(5 downto 0); + signal all_links_reset : std_logic := '0'; + + begin + pIteratePointer : process(clk_p) + begin + if rising_edge(clk_p) then + -- Loop pointer over all the links + if pointer = N_LINKS - 1 then + pointer <= 0; + else + pointer <= pointer + 1; + end if; + -- Readout value of FIFO which is currently pointed to + rd_en_route_array(i) <= (others => '0'); + rd_en_route_array(i)(pointer) <= valid_route_array(i)(pointer); + din <= data(i)(pointer); + + -- If counter is at the end of a packet, then start to readout the contents of the aggregated FIFOs + if counter = 48 then + rd_en <= '1'; + end if; + if rd_en = '1' then + if almost_empty = '1' then + rd_en <= '0'; + end if; + end if; + + if valid = '1' then + links_out(i).valid <= '1'; + links_out(i).data <= dout; + links_out(i).strobe <= '1'; + else + links_out(i).valid <= '0'; + links_out(i).data <= (others => '0'); + links_out(i).strobe <= '1'; + end if; + wr_en <= valid_route_array(i)(pointer); + end if; + + end process; + + + AllLinksFIFOInstance : link_agg_all_links_fifo + PORT MAP ( + --- Input Ports --- + clk => clk_p, + srst => all_links_reset, -- Reset FIFO on every packet + din => din, + wr_en => wr_en, + rd_en => rd_en, + --- Output Ports --- + dout => dout, + full => full, + empty => empty, + almost_empty => almost_empty, + valid => valid, + data_count => data_count + ); + + all_links_reset <= packet_start or reset; + + end generate; + + pReadoutReset : process(clk_p) + begin + if rising_edge(clk_p) then + if packet_start = '1' then + counter <= 0; + else + counter <= counter + 1; + end if; + -- If counter is at the end of a packet, then start to readout the contents of the aggregated FIFOs + readout_reset <= '0'; + if counter = 64 then + counter <= counter; + elsif counter = 48 then + readout_reset <= '1'; + end if; + end if; + end process pReadoutReset; + +end uncompressed; diff --git a/top/firmware/hdl/LinkCombiner.vhd b/top/firmware/hdl/LinkCombinerCore.vhd similarity index 99% rename from top/firmware/hdl/LinkCombiner.vhd rename to top/firmware/hdl/LinkCombinerCore.vhd index 0aea5348e383e50b16ebae8215fe3a93ececef92..fe4df5a4fd9b2800fca5d0eaecde8daf544afe8a 100644 --- a/top/firmware/hdl/LinkCombiner.vhd +++ b/top/firmware/hdl/LinkCombinerCore.vhd @@ -7,7 +7,7 @@ use work.gbt_module_constants.all; use work.dtc_link_maps.all; -entity LinkCombiner is +entity LinkCombinerCore is generic ( N_INPUT_LINKS : integer := 8; N_OUTPUT_LINKS : integer := 1 @@ -29,9 +29,9 @@ entity LinkCombiner is debug_super_id : out std_logic_vector(31 downto 0); debug_fifo : out std_logic_vector(31 downto 0) := (others => '0') ); -end LinkCombiner; +end LinkCombinerCore; -architecture Behavioral of LinkCombiner is +architecture Behavioral of LinkCombinerCore is constant cWordWidth : integer := 64; constant cOutputWordWidth : integer := 64; diff --git a/top/firmware/hdl/LinkCombinerIPBus.vhd b/top/firmware/hdl/LinkCombinerIPBus.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1ceb50e1d2f2b2876f663d2e44b10dfd3c3fd617 --- /dev/null +++ b/top/firmware/hdl/LinkCombinerIPBus.vhd @@ -0,0 +1,118 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.emp_data_types.all; + +use work.ipbus.all; +use work.ipbus_reg_types.all; + +use work.front_end_data_types.all; +use work.gbt_module_constants.all; +use work.dtc_link_maps.all; + + +entity LinkCombinerIPBus is + generic ( + N_INPUT_LINKS : integer := 8 + ); + port ( + --- Input Ports --- + clk_p : in std_logic; + reset : in std_logic; + 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'))); + lff : in std_logic; + --- Ouput Ports --- + links_out : out ldata(1 - 1 downto 0); + --- IPBus Ports --- + ipb_clk : in std_logic; + ipb_rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus + ); +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_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); + + signal control_registers : ipb_reg_v(2 - 1 downto 0) := (others => (others => '0')); + +begin + + --==============================-- + -- IPBus + --==============================-- + + --==============================-- + ControlInstance: entity work.ipbus_ctrlreg_v + --==============================-- + generic map( + N_CTRL => 2, + N_STAT => 0 + ) + port map( + clk => ipb_clk, + reset => ipb_rst, + ipbus_in => ipb_in, + ipbus_out => ipb_out, + -- d => link_aggregator_status_registers, + q => control_registers + ); + + --==============================-- + pInputLinkMask: process(clk_p) + --==============================-- + begin + if rising_edge(clk_p) then + for i in 0 to N_INPUT_LINKS - 1 loop + if control_registers(0)(i) = '1' then + masked_input(i) <= links_in(i); + else + masked_input(i) <= LWORD_NULL; + end if; + end loop; + end if; + end process pInputLinkMask; + + --==============================-- + pReadEnable: process(clk_p) + --==============================-- + 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; + end if; + end process pReadEnable; + + --==============================-- + LinkCombinerInstance : entity work.LinkCombinerCore + --==============================-- + generic map ( + N_INPUT_LINKS => 8 + ) + port map ( + --- Input Ports --- + clk_p => clk_p, + reset => reset, + output_reset => control_registers(0)(N_INPUT_LINKS + 1 - 1), + output_rd_en => 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 + --- Debug Ports --- + -- debug => link_combiner_debug, + -- debug_super_id => link_combiner_debug_super_id, + -- debug_fifo => link_aggregator_status_registers(2) + ); + +end Behavioral; diff --git a/top/firmware/hdl/MProcessor.vhd b/top/firmware/hdl/MProcessor.vhd new file mode 100644 index 0000000000000000000000000000000000000000..8f5bd62e33f16f47d2478f965e864a5047dc9c08 --- /dev/null +++ b/top/firmware/hdl/MProcessor.vhd @@ -0,0 +1,150 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.emp_data_types.all; + +use work.ipbus.all; +use work.ipbus_reg_types.all; + +use work.ipbus_decode_mprocessor.all; + +use work.dtc_link_maps.all; +use work.front_end_data_types.all; +use work.gbt_module_constants.all; +use work.mprocessor_constants.all; + + +entity MProcessor is + generic ( + N_LINKS : integer + ); + port ( + --- Input Ports --- + clk_p : in std_logic; + links_in : in ldata(N_LINKS - 1 downto 0); + header_in : in tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); + header_start_array : in tHeaderStartArray := (others => (others => '0')); + gbe_backpressure : in std_logic := '0'; + --- Output Ports --- + link_out : out lword := LWORD_NULL; + --- IPBus Ports --- + ipb_clk : in std_logic; + ipb_rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus + ); +end MProcessor; + + +architecture Behavorial of MProcessor is + + signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0); + signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0); + + signal packet_start : std_logic := '0'; + signal readout_reset : std_logic := '0'; + signal aggregated_stubs : ldata(7 downto 0) := (others => LWORD_NULL); + signal link_aggregator_input : ldata(5 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')); + +begin + + --==============================-- + -- IPBus fabric + --==============================-- + + + --==============================-- + fabric: entity work.ipbus_fabric_sel + --==============================-- + generic map( + NSLV => N_SLAVES, + SEL_WIDTH => IPBUS_SEL_WIDTH + ) + port map( + ipb_in => ipb_in, + ipb_out => ipb_out, + sel => ipbus_sel_mprocessor(ipb_in.ipb_addr), + ipb_to_slaves => ipb_to_slaves, + ipb_from_slaves => ipb_from_slaves + ); + + --==============================-- + MProcessorControlInstance: entity work.ipbus_ctrlreg_v + --==============================-- + generic map( + N_CTRL => 1, + N_STAT => 1 + ) + port map( + clk => ipb_clk, + reset => ipb_rst, + ipbus_in => ipb_to_slaves(N_SLV_CSR), + ipbus_out => ipb_from_slaves(N_SLV_CSR), + d => status_registers, + q => control_registers + ); + + --==============================-- + LinkAggregatorInstance: entity work.LinkAggregatorIPBus + --==============================-- + generic map ( + N_LINKS => 6 + ) + port map ( + --- Input Ports --- + clk_p => clk_p, + packet_start => packet_start, + links_in => link_aggregator_input, + --- Output Ports --- + links_out => aggregated_stubs, + readout_reset => readout_reset, + --- IPBus Ports --- + ipb_clk => ipb_clk, + ipb_rst => ipb_rst, + ipb_in => ipb_to_slaves(N_SLV_LINK_AGGREGATOR), + ipb_out => ipb_from_slaves(N_SLV_LINK_AGGREGATOR) + ); + + --==============================-- + LinkCombinerInstance : entity work.LinkCombinerIPBus + --==============================-- + generic map ( + N_INPUT_LINKS => 8 + ) + port map ( + --- Input Ports --- + clk_p => clk_p, + reset => readout_reset, + links_in => aggregated_stubs, + packet_start => packet_start, + header_in => header_in, + lff => gbe_backpressure, + --- Output Ports --- + links_out => eth_link_out, + --- IPBus Ports --- + ipb_clk => ipb_clk, + ipb_rst => ipb_rst, + ipb_in => ipb_to_slaves(N_SLV_LINK_COMBINER), + ipb_out => ipb_from_slaves(N_SLV_LINK_COMBINER) + ); + + -- --==============================-- + -- TrackReconstructorInstance: entity work.TrackReconstructor + -- --==============================-- + -- port map( + -- clk_p => clk_p, + -- reset => readout_reset, + -- stubs_in => aggregated_stubs(0) + -- ); + + 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); + +end Behavorial; diff --git a/top/firmware/hdl/emp_payload.vhd b/top/firmware/hdl/emp_payload.vhd index f3205a472714bb61a134e151946996ef63a9cd21..cafdf14d4d8f2b264ffacf67a9b8094f29ac164b 100644 --- a/top/firmware/hdl/emp_payload.vhd +++ b/top/firmware/hdl/emp_payload.vhd @@ -15,32 +15,33 @@ use work.ipbus_decode_emp_payload.all; use work.dtc_link_maps.all; use work.front_end_data_types.all; use work.gbt_module_constants.all; +use work.mprocessor_constants.all; entity emp_payload is port( --- Input Ports --- - clk_p : in std_logic; - clk40 : in std_logic := '0'; - clk_payload : in std_logic_vector(2 downto 0); - rst_payload : in std_logic_vector(2 downto 0); - rst_loc : in std_logic_vector(N_REGION - 1 downto 0); - clken_loc : in std_logic_vector(N_REGION - 1 downto 0); - ctrs : in ttc_stuff_array; - d : in ldata(4 * N_REGION - 1 downto 0); + clk_p : in std_logic; + clk40 : in std_logic := '0'; + clk_payload : in std_logic_vector(2 downto 0); + rst_payload : in std_logic_vector(2 downto 0); + rst_loc : in std_logic_vector(N_REGION - 1 downto 0); + clken_loc : in std_logic_vector(N_REGION - 1 downto 0); + ctrs : in ttc_stuff_array; + d : in ldata(4 * N_REGION - 1 downto 0); --- Output Ports --- - bc0 : out std_logic; - gpio : out std_logic_vector(29 downto 0); - gpio_en : out std_logic_vector(29 downto 0); - q : out ldata(4 * N_REGION - 1 downto 0); + bc0 : out std_logic; + gpio : out std_logic_vector(29 downto 0); + gpio_en : out std_logic_vector(29 downto 0); + q : out ldata(4 * N_REGION - 1 downto 0); --- IPBus Ports --- - clk : in std_logic; - rst : in std_logic; - ipb_in : in ipb_wbus; - ipb_out : out ipb_rbus; + clk : in std_logic; + rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus; -- KH - ldata_out : out lword; - lff : in std_logic + gbe_q : out ldata := (others => LWORD_NULL); + gbe_backpressure : in std_logic_vector(1 downto 0) ); end emp_payload; @@ -49,60 +50,59 @@ architecture rtl of emp_payload is -- IPBus fabric -signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0); -signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0); +signal ipb_to_slaves : ipb_wbus_array(N_SLAVES - 1 downto 0); +signal ipb_from_slaves : ipb_rbus_array(N_SLAVES - 1 downto 0); -signal channel_sel : ipb_reg_v(0 downto 0); -signal link_aggr_control : ipb_reg_v(0 downto 0); +signal channel_sel : ipb_reg_v(0 downto 0); +signal mproc_channel_sel : ipb_reg_v(0 downto 0); +signal link_aggr_control : ipb_reg_v(0 downto 0); -- FE data extraction and monitoring -signal ipb_chain : ipbdc_bus_array(cNumberOfFEModules downto 0); -signal stubs : ldata(cNumberOfFEModules - 1 downto 0); +signal ipb_chain : ipbdc_bus_array(cNumberOfFEModules downto 0); +signal stubs : ldata(cNumberOfFEModules - 1 downto 0); -signal linksout : ldata(cNumberOfFEModules - 1 downto 0); -signal linkor : lword := LWORD_NULL; +signal linksout : ldata(cNumberOfFEModules - 1 downto 0); +signal linkor : lword := LWORD_NULL; -- Histogrammer -constant N_CTRL_HIST : integer := 2; -constant N_STAT_HIST : integer := 2; - -constant bin_width : integer := 32; -constant input_width : integer := 9; - -signal status_registers : ipb_reg_v(N_STAT_HIST - 1 downto 0) := (others => (others => '0')); -signal control_registers : ipb_reg_v(N_CTRL_HIST - 1 downto 0) := (others => (others => '0')); -signal link_aggregator_status_registers : ipb_reg_v(4 - 1 downto 0) := (others => (others => '0')); -signal link_aggregator_control_registers : ipb_reg_v(4 - 1 downto 0) := (others => (others => '0')); - -signal trigger_window_lower : std_logic_vector(31 downto 0) := (others => '0'); -signal trigger_window_upper : std_logic_vector(3 downto 0) := (others => '0'); -signal trigger_window : std_logic_vector(36 - 1 downto 0) := X"0ffffffff"; -signal max_value0, max_value1 : std_logic_vector(bin_width - 1 downto 0) := (others => '0'); -signal histogram_reset : std_logic := '0'; -signal hist0_stub, hist1_stub : lword := LWORD_NULL; -signal histogram_sel : integer := 0; -signal histogram_enable : std_logic := '0'; -type tHeaderStartArray is array(cNumberOfFEModules - 1 downto 0) of std_logic_vector(1 downto 0); -signal header_start_array : tHeaderStartArray := (others => (others => '0')); -signal aggregated_stubs : ldata(7 downto 0) := (others => LWORD_NULL); -signal eth_link_out : ldata(0 downto 0) := (others => LWORD_NULL); -signal readout_reset : std_logic := '0'; - -signal header_array : tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); - -signal link_combiner_debug : lword := LWORD_NULL; -signal link_combiner_rd_en : std_logic_vector(0 downto 0) := "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 link_combiner_input : ldata(8 - 1 downto 0) := (others => LWORD_NULL); -signal packet_start : std_logic := '0'; +constant N_CTRL_HIST : integer := 2; +constant N_STAT_HIST : integer := 2; -begin +constant bin_width : integer := 32; +constant input_width : integer := 9; + +signal status_registers : ipb_reg_v(N_STAT_HIST - 1 downto 0) := (others => (others => '0')); +signal control_registers : ipb_reg_v(N_CTRL_HIST - 1 downto 0) := (others => (others => '0')); +signal mprocessor_status_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0')); +signal mprocessor_control_registers : ipb_reg_v(1 - 1 downto 0) := (others => (others => '0')); + +signal trigger_window_lower : std_logic_vector(31 downto 0) := (others => '0'); +signal trigger_window_upper : std_logic_vector(3 downto 0) := (others => '0'); +signal trigger_window : std_logic_vector(36 - 1 downto 0) := X"0ffffffff"; +signal max_value0, max_value1 : std_logic_vector(bin_width - 1 downto 0) := (others => '0'); +signal histogram_reset : std_logic := '0'; +signal hist0_stub, hist1_stub : lword := LWORD_NULL; +signal histogram_sel : integer := 0; +signal histogram_enable : std_logic := '0'; +signal header_start_array : tHeaderStartArray := (others => (others => '0')); +signal aggregated_stubs : ldata(7 downto 0) := (others => LWORD_NULL); +signal eth_link_out : ldata(0 downto 0) := (others => LWORD_NULL); +signal readout_reset : std_logic := '0'; + +signal header_array : tCICHeaderArray(cNumberOfFEModules * cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); + +signal link_combiner_debug_super_id : std_logic_vector(31 downto 0); +signal packet_start : std_logic := '0'; +-- MProcessor +constant cNumberOfMProcessors : integer := 1; +signal mprocessor_ipb_chain : ipbdc_bus_array(cNumberOfMProcessors downto 0); +begin + --==============================-- -- IPBus fabric --==============================-- @@ -125,7 +125,7 @@ port map( --==============================-- -channel_ctrl: entity work.ipbus_reg_v +fe_channel_ctrl: entity work.ipbus_reg_v --==============================-- generic map( N_REG => 1 @@ -139,6 +139,21 @@ port map( qmask => (0 => X"0000007f") ); +--==============================-- +mproc_channel_ctrl: entity work.ipbus_reg_v +--==============================-- +generic map( + N_REG => 1 +) +port map( + clk => clk, + reset => rst, + ipbus_in => ipb_to_slaves(N_SLV_MPROC_CTRL), + ipbus_out => ipb_from_slaves(N_SLV_MPROC_CTRL), + q => mproc_channel_sel, + qmask => (0 => X"0000007f") +); + --==============================-- channel_select: entity work.ipbus_dc_fabric_sel @@ -208,19 +223,14 @@ begin ipb_out => ipb_from_channel, --- Debug Ports --- debug_header_start => header_start_array(i), - debug_header_match => q(i+20).data(5 downto 4), - debug_aligner_state => q(i+20).data(13 downto 8) + debug_header_match => q(i+30).data(5 downto 4), + debug_aligner_state => q(i+30).data(13 downto 8) ); - - q(i+20).valid <= '1'; - q(i+20).strobe <= '1'; - q(i+20).data(1 downto 0) <= header_start_array(i); - q(i+20).data(63 downto 14) <= stubs(i).data(49 downto 0); - end generate; -linkor.data(63 downto 0) <= linksout(0).data(63 downto 0) or linksout(1).data(63 downto 0) or linksout(2).data(63 downto 0) or linksout(3).data(63 downto 0); +linkor.data(63 downto 0) <= linksout(0).data(63 downto 0) or linksout(1).data(63 downto 0) or linksout(2).data(63 downto 0) or linksout(3).data(63 downto 0); --or linksout(4).data(63 downto 0) or linksout(5).data(63 downto 0); + --==============================-- hack: for i in 0 to cNumberOfFEModules - 1 generate --==============================-- @@ -263,20 +273,6 @@ histogram_sel <= to_integer(unsigned(control_registers(1)(15 downto 5))) trigger_window <= trigger_window_upper & trigger_window_lower; ---==============================-- -pRouteStubsToOutput: process(clk_p) ---==============================-- -begin - if rising_edge(clk_p) then - for i in 0 to cNumberOfFEModules - 1 loop - q(cDTCOutputLinkMap(i)).valid <= stubs(i).valid; - q(cDTCOutputLinkMap(i)).data <= stubs(i).data; - q(cDTCOutputLinkMap(i)).strobe <= '1'; - end loop; - end if; -end process; - - --==============================-- pHistogram: process(clk_p) --==============================-- @@ -362,135 +358,71 @@ port map( --==============================-- --==============================-- -pInputLinkMask: process(clk_p) ---==============================-- -begin - if rising_edge(clk_p) then - for i in 0 to cNumberOfFEModules - 1 loop - if link_aggregator_control_registers(2)(i) = '1' then - masked_stubs(i) <= stubs(i); - else - masked_stubs(i) <= LWORD_NULL; - end if; - end loop; - end if; -end process; - ---==============================-- -pLinkCombinerInputLinkMask: process(clk_p) ---==============================-- -begin - if rising_edge(clk_p) then - for i in 0 to 8 - 1 loop - if link_aggregator_control_registers(2)(cNumberOfFEModules + i) = '1' then - link_combiner_input(i) <= aggregated_stubs(i); - else - link_combiner_input(i) <= LWORD_NULL; - end if; - end loop; - end if; -end process; - - ---==============================-- -LinkAggregatorInstance: entity work.LinkAggregator(compressed) ---==============================-- -generic map ( - N_LINKS => cNumberOfFEModules -) -port map ( - --- Input Ports --- - clk_p => clk_p, - reset => link_aggregator_control_registers(0)(0), - packet_start => packet_start, - links_in => masked_stubs, - --- Output Ports --- - links_out => aggregated_stubs, - readout_reset => readout_reset, - --- Debug Ports --- - status_bits => link_aggregator_status_registers(3)(15 downto 0) -); - -q(31 downto 24) <= aggregated_stubs; - -packet_start <= header_start_array(to_integer(unsigned(link_aggregator_control_registers(2)(cNumberOfFEModules + 8 + 1 downto cNumberOfFEModules + 8))))(0); - ---==============================-- -LinkAggregatorControlInstance: entity work.ipbus_ctrlreg_v +mprocessor_channel_select: entity work.ipbus_dc_fabric_sel --==============================-- generic map( - N_CTRL => 4, - N_STAT => 4 + SEL_WIDTH => 7 ) port map( - clk => clk, - reset => rst, - ipbus_in => ipb_to_slaves(N_SLV_LINK_AGGR), - ipbus_out => ipb_from_slaves(N_SLV_LINK_AGGR), - d => link_aggregator_status_registers, - q => link_aggregator_control_registers -); - ---==============================-- -LinkCombinerInstance : entity work.LinkCombiner ---==============================-- -generic map ( - N_INPUT_LINKS => 8, - N_OUTPUT_LINKS => 1 -) -port map ( - --- Input Ports --- - clk_p => clk_p, - reset => readout_reset, - output_reset => link_aggregator_control_registers(1)(0), - output_rd_en => link_combiner_rd_en, - links_in => link_combiner_input, - packet_start => packet_start, - header_in => header_array, - header_user_bits => link_aggregator_control_registers(3), - --- Output Ports --- - links_out => eth_link_out, - --- Debug Ports --- - debug => link_combiner_debug, - debug_super_id => link_combiner_debug_super_id, - debug_fifo => link_aggregator_status_registers(2) + clk => clk, + rst => rst, + sel => mproc_channel_sel(0)(6 downto 0), + ipb_in => ipb_to_slaves(N_SLV_MPROCESSOR), + ipb_out => ipb_from_slaves(N_SLV_MPROCESSOR), + ipbdc_out => mprocessor_ipb_chain(0), + ipbdc_in => mprocessor_ipb_chain(cNumberOfMProcessors) ); -q(32).valid <= eth_link_out(0).valid; -q(32).strobe <= '1'; -q(32).start <= '0'; -q(32).data <= eth_link_out(0).data; -q(33) <= link_combiner_debug; - -link_aggregator_status_registers(0) <= link_combiner_debug_super_id; -link_aggregator_status_registers(1)(0) <= lff; +genMProcessors : for i in 0 to cNumberOfMProcessors - 1 generate + signal ipb_to_channel : ipb_wbus; + signal ipb_from_channel : ipb_rbus; + constant cNumberofInputLinks : integer := 4; -pLinkCombinerReadEnable: process(clk_p) begin - if rising_edge(clk_p) then - for i in 0 downto 0 loop - link_combiner_rd_en(i) <= not lff and link_aggregator_control_registers(1)(1); - end loop; - end if; -end process pLinkCombinerReadEnable; - -ldata_out <= eth_link_out(0); --- --==============================-- --- TrackReconstructorInstance: entity work.TrackReconstructor --- --==============================-- --- port map( --- clk_p => clk_p, --- reset => readout_reset, --- stubs_in => aggregated_stubs(0) --- ); + --==============================-- + channel_node: entity work.ipbus_dc_node + --==============================-- + generic map( + I_SLV => i, + SEL_WIDTH => 7, + PIPELINE => false + ) + port map( + clk => clk, + rst => rst, + ipb_out => ipb_to_channel, + ipb_in => ipb_from_channel, + ipbdc_in => mprocessor_ipb_chain(i), + ipbdc_out => mprocessor_ipb_chain(i + 1) + ); + --==============================-- + MProcessorInstance: entity work.MProcessor + --==============================-- + generic map( + N_LINKS => cNumberofInputLinks + ) + port map( + --- Input Ports --- + clk_p => clk_p, + links_in => stubs(cNumberofInputLinks*i + (cNumberofInputLinks - 1) downto cNumberofInputLinks*i), + header_in => header_array, + header_start_array => header_start_array, + gbe_backpressure => gbe_backpressure(i), + --- Output Ports --- + link_out => gbe_q(i), + --- IPBus Ports --- + ipb_clk => clk, + ipb_rst => rst, + ipb_in => ipb_to_channel, + ipb_out => ipb_from_channel + ); +end generate genMProcessors; bc0 <= '0'; gpio <= (others => '0'); gpio_en <= (others => '0'); - - end rtl; diff --git a/top/firmware/hdl/emp_project_decl.vhd b/top/firmware/hdl/emp_project_decl.vhd index 6dbcdbab3e4ef3de4eca7f4df7bf5764de343ee6..fdc5575eec30b6c0d471caf07825f2de0b2bb1be 100644 --- a/top/firmware/hdl/emp_project_decl.vhd +++ b/top/firmware/hdl/emp_project_decl.vhd @@ -35,8 +35,8 @@ package emp_project_decl is -- 0 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 225 -- Right Column -- 1 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 226 2 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 227 - 3 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 228 --- 4 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 229 + 3 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 228 + 4 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 229 5 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 230 6 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 231 7 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 232 @@ -59,12 +59,14 @@ package emp_project_decl is -- for data framer (ic_simple, no_ec, n_ec_spare, ec_broadcast) constant REGION_DATA_FRAMER_CONF : region_data_framer_conf_array_t := ( 2 => ( 0=>(false, true, 0, false), 1=>(false, true, 0, false), 2=>(false, true, 0, false), 3=>(false, true, 0, false)), + 3 => ( 0=>(false, true, 0, false), 1=>(false, true, 0, false), 2=>(false, true, 0, false), 3=>(false, true, 0, false)), others => kDummyRegionDataFramer ); -- for lpgbt constant REGION_LPGBT_CONF : region_lpgbt_conf_array_t := ( 2 => (FEC5, DATARATE_5G12, PCS), + 3 => (FEC5, DATARATE_5G12, PCS), others => kDummyRegionLpgbt ); diff --git a/top/firmware/hdl/ipbus_decode_emp_payload.vhd b/top/firmware/hdl/ipbus_decode_emp_payload.vhd index fa879a32616a73b16afe62ff224cc3d40b8227e5..67da9d568ed2cbb86910acca8e505f877e48cb53 100644 --- a/top/firmware/hdl/ipbus_decode_emp_payload.vhd +++ b/top/firmware/hdl/ipbus_decode_emp_payload.vhd @@ -1,7 +1,10 @@ --- +-- Address decode logic for ipbus fabric +-- +-- This file has been AUTOGENERATED from the address table - do not hand edit +-- -- We assume the synthesis tool is clever enough to recognise exclusive conditions -- in the if statement. --- +-- -- Dave Newbold, February 2011 library IEEE; @@ -14,17 +17,18 @@ package ipbus_decode_emp_payload is subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0); function ipbus_sel_emp_payload(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t; --- START automatically generated VHDL (Mon Oct 11 10:15:52 2021) +-- START automatically generated VHDL (Thu Sep 1 14:33:48 2022) constant N_SLV_FE_CTRL: integer := 0; constant N_SLV_CSR: integer := 1; constant N_SLV_FE_CHAN: integer := 2; - constant N_SLV_LINK_AGGR: integer := 3; - constant N_SLV_MEM1: integer := 4; - constant N_SLV_MEM2: integer := 5; - constant N_SLAVES: integer := 6; + constant N_SLV_MPROC_CTRL: integer := 3; + constant N_SLV_MPROCESSOR: integer := 4; + constant N_SLV_MEM1: integer := 5; + constant N_SLV_MEM2: integer := 6; + constant N_SLAVES: integer := 7; -- END automatically generated VHDL - + end ipbus_decode_emp_payload; package body ipbus_decode_emp_payload is @@ -33,19 +37,21 @@ package body ipbus_decode_emp_payload is variable sel: ipbus_sel_t; begin --- START automatically generated VHDL (Mon Oct 11 10:15:52 2021) - if std_match(addr, "------------------00----00---0--") then - sel := ipbus_sel_t(to_unsigned(N_SLV_FE_CTRL, IPBUS_SEL_WIDTH)); -- fe_ctrl / base 0x00000000 / mask 0x000030c4 - elsif std_match(addr, "------------------00----00---1--") then - sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000004 / mask 0x000030c4 - elsif std_match(addr, "------------------00----01------") then - sel := ipbus_sel_t(to_unsigned(N_SLV_FE_CHAN, IPBUS_SEL_WIDTH)); -- fe_chan / base 0x00000040 / mask 0x000030c0 - elsif std_match(addr, "------------------00----10------") then - sel := ipbus_sel_t(to_unsigned(N_SLV_LINK_AGGR, IPBUS_SEL_WIDTH)); -- link_aggr / base 0x00000080 / mask 0x000030c0 - elsif std_match(addr, "------------------01------------") then - sel := ipbus_sel_t(to_unsigned(N_SLV_MEM1, IPBUS_SEL_WIDTH)); -- mem1 / base 0x00001000 / mask 0x00003000 - elsif std_match(addr, "------------------10------------") then - sel := ipbus_sel_t(to_unsigned(N_SLV_MEM2, IPBUS_SEL_WIDTH)); -- mem2 / base 0x00002000 / mask 0x00003000 +-- START automatically generated VHDL (Thu Sep 1 14:33:48 2022) + if std_match(addr, "------------------00--0000000000") then + sel := ipbus_sel_t(to_unsigned(N_SLV_FE_CTRL, IPBUS_SEL_WIDTH)); -- fe_ctrl / base 0x00000000 / mask 0x000033ff + elsif std_match(addr, "------------------00--00000001--") then + sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000004 / mask 0x000033fc + elsif std_match(addr, "------------------00--0001------") then + sel := ipbus_sel_t(to_unsigned(N_SLV_FE_CHAN, IPBUS_SEL_WIDTH)); -- fe_chan / base 0x00000040 / mask 0x000033c0 + elsif std_match(addr, "------------------00--0111111111") then + sel := ipbus_sel_t(to_unsigned(N_SLV_MPROC_CTRL, IPBUS_SEL_WIDTH)); -- mproc_ctrl / base 0x000001ff / mask 0x000033ff + elsif std_match(addr, "------------------00--100-------") then + sel := ipbus_sel_t(to_unsigned(N_SLV_MPROCESSOR, IPBUS_SEL_WIDTH)); -- mprocessor / base 0x00000200 / mask 0x00003380 + elsif std_match(addr, "------------------01--0---------") then + sel := ipbus_sel_t(to_unsigned(N_SLV_MEM1, IPBUS_SEL_WIDTH)); -- mem1 / base 0x00001000 / mask 0x00003200 + elsif std_match(addr, "------------------10--0---------") then + sel := ipbus_sel_t(to_unsigned(N_SLV_MEM2, IPBUS_SEL_WIDTH)); -- mem2 / base 0x00002000 / mask 0x00003200 -- END automatically generated VHDL else diff --git a/top/firmware/hdl/ipbus_decode_link_aggregator.vhd b/top/firmware/hdl/ipbus_decode_link_aggregator.vhd new file mode 100644 index 0000000000000000000000000000000000000000..f7f0f178ea0cd7089fdd2a2965ca4e618e03e1d5 --- /dev/null +++ b/top/firmware/hdl/ipbus_decode_link_aggregator.vhd @@ -0,0 +1,53 @@ +-- Address decode logic for ipbus fabric +-- +-- This file has been AUTOGENERATED from the address table - do not hand edit +-- +-- We assume the synthesis tool is clever enough to recognise exclusive conditions +-- in the if statement. +-- +-- Dave Newbold, February 2011 + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use ieee.numeric_std.all; + +package ipbus_decode_link_aggregator is + + constant IPBUS_SEL_WIDTH: positive := 2; + subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0); + function ipbus_sel_link_aggregator(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t; + +-- START automatically generated VHDL (Fri Aug 26 18:31:19 2022) + constant N_SLV_CHAN_SEL: integer := 0; + constant N_SLV_CONTROL: integer := 1; + constant N_SLV_MONITORING: integer := 2; + constant N_SLAVES: integer := 3; +-- END automatically generated VHDL + + +end ipbus_decode_link_aggregator; + +package body ipbus_decode_link_aggregator is + + function ipbus_sel_link_aggregator(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is + variable sel: ipbus_sel_t; + begin + +-- START automatically generated VHDL (Fri Aug 26 18:31:19 2022) + if std_match(addr, "----------------------------0--0") then + sel := ipbus_sel_t(to_unsigned(N_SLV_CHAN_SEL, IPBUS_SEL_WIDTH)); -- chan_sel / base 0x00000000 / mask 0x00000009 + elsif std_match(addr, "----------------------------0--1") then + sel := ipbus_sel_t(to_unsigned(N_SLV_CONTROL, IPBUS_SEL_WIDTH)); -- control / base 0x00000001 / mask 0x00000009 + elsif std_match(addr, "----------------------------1---") then + sel := ipbus_sel_t(to_unsigned(N_SLV_MONITORING, IPBUS_SEL_WIDTH)); -- monitoring / base 0x00000008 / mask 0x00000008 +-- END automatically generated VHDL + + else + sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH)); + end if; + + return sel; + + end function ipbus_sel_link_aggregator; + +end ipbus_decode_link_aggregator; diff --git a/top/firmware/hdl/ipbus_decode_mprocessor.vhd b/top/firmware/hdl/ipbus_decode_mprocessor.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1f97d1fac6f828b144c74d8d1cd4f4f5da6ba904 --- /dev/null +++ b/top/firmware/hdl/ipbus_decode_mprocessor.vhd @@ -0,0 +1,53 @@ +-- Address decode logic for ipbus fabric +-- +-- This file has been AUTOGENERATED from the address table - do not hand edit +-- +-- We assume the synthesis tool is clever enough to recognise exclusive conditions +-- in the if statement. +-- +-- Dave Newbold, February 2011 + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use ieee.numeric_std.all; + +package ipbus_decode_mprocessor is + + constant IPBUS_SEL_WIDTH: positive := 2; + subtype ipbus_sel_t is std_logic_vector(IPBUS_SEL_WIDTH - 1 downto 0); + function ipbus_sel_mprocessor(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t; + +-- START automatically generated VHDL (Fri Aug 26 18:31:27 2022) + constant N_SLV_LINK_AGGREGATOR: integer := 0; + constant N_SLV_LINK_COMBINER: integer := 1; + constant N_SLV_CSR: integer := 2; + constant N_SLAVES: integer := 3; +-- END automatically generated VHDL + + +end ipbus_decode_mprocessor; + +package body ipbus_decode_mprocessor is + + function ipbus_sel_mprocessor(addr : in std_logic_vector(31 downto 0)) return ipbus_sel_t is + variable sel: ipbus_sel_t; + begin + +-- START automatically generated VHDL (Fri Aug 26 18:31:27 2022) + if std_match(addr, "--------------------------0-----") then + sel := ipbus_sel_t(to_unsigned(N_SLV_LINK_AGGREGATOR, IPBUS_SEL_WIDTH)); -- link_aggregator / base 0x00000000 / mask 0x00000020 + elsif std_match(addr, "--------------------------1---0-") then + sel := ipbus_sel_t(to_unsigned(N_SLV_LINK_COMBINER, IPBUS_SEL_WIDTH)); -- link_combiner / base 0x00000020 / mask 0x00000022 + elsif std_match(addr, "--------------------------1---1-") then + sel := ipbus_sel_t(to_unsigned(N_SLV_CSR, IPBUS_SEL_WIDTH)); -- csr / base 0x00000022 / mask 0x00000022 +-- END automatically generated VHDL + + else + sel := ipbus_sel_t(to_unsigned(N_SLAVES, IPBUS_SEL_WIDTH)); + end if; + + return sel; + + end function ipbus_sel_mprocessor; + +end ipbus_decode_mprocessor; diff --git a/top/firmware/hdl/link_maps.vhd b/top/firmware/hdl/link_maps.vhd index aa5099fe77b2b8f5ac4cc9fccbfafc9980d18a52..d0ca6517cd88b2c93ed21c23763bf86053a0588d 100644 --- a/top/firmware/hdl/link_maps.vhd +++ b/top/firmware/hdl/link_maps.vhd @@ -10,5 +10,5 @@ package dtc_link_maps is constant cDTCInputLinkMap : tDTCInputLinkMap := (8, 9, 10, 11); type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := (12, 13, 14, 15); + constant cDTCOutputLinkMap : tDTCOutputLinkMap := (16, 17, 18, 19); end package dtc_link_maps; diff --git a/top/firmware/hdl/mprocessor_constants.vhd b/top/firmware/hdl/mprocessor_constants.vhd new file mode 100644 index 0000000000000000000000000000000000000000..90f2f75fb2499e65ab77d2c5c22bf05e87624425 --- /dev/null +++ b/top/firmware/hdl/mprocessor_constants.vhd @@ -0,0 +1,11 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; + +use work.dtc_link_maps.all; + +package mprocessor_constants is + + type tHeaderStartArray is array(cNumberOfFEModules - 1 downto 0) of std_logic_vector(1 downto 0); + +end package mprocessor_constants; \ No newline at end of file