diff --git a/dependencies.yml b/dependencies.yml index ef253d7730975e2d593f390d9369d84a5370b2f7..e19a1e46aa410920d2a72831d664c95d2d6c41d4 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -65,5 +65,5 @@ sources: url: https://gitlab.cern.ch/cms-tracker-phase2-data-processing/BE_firmware/10gb-ethernet.git daqpath-toolkit: - branch: master + branch: dev url: https://gitlab.cern.ch/dmonk/daqpath-toolkit.git diff --git a/replacements/dtc/dtc-be/common/firmware/hdl/L1DataAggregator.vhd b/replacements/dtc/dtc-be/common/firmware/hdl/L1DataAggregator.vhd new file mode 100644 index 0000000000000000000000000000000000000000..a0c607f94f63a730e35416463b3cab07cd929388 --- /dev/null +++ b/replacements/dtc/dtc-be/common/firmware/hdl/L1DataAggregator.vhd @@ -0,0 +1,261 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + --- + use work.ipbus.all; + use work.ipbus_reg_types.all; + use work.ipbus_decode_dtc_data_aggregator.all; + --- + use work.emp_data_types.all; + use work.emp_daqpath_types_package.all; + use work.emp_daqpath_user_package.all; + --- + use work.dtc_link_maps.all; + use work.dtc_constants.all; + use work.dtc_data_types.all; + + +entity L1DataAggregator is + generic ( + INPUT_LINKS : integer := cNumberOfFEModules + ); + port ( + --- Input Ports --- + clk_p : in std_logic; + daq_in : in tDaqDataLinkArray(INPUT_LINKS - 1 downto 0); + empty : in tDaqFlagLinkArray(INPUT_LINKS - 1 downto 0); + backpressure : in std_logic; + --- Output Ports --- + read : out tDaqFlagLinkArray(INPUT_LINKS - 1 downto 0); + data_out : out lword; + --- IPBus Ports --- + clk : in std_logic; + rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus + ); +end entity L1DataAggregator; + + +architecture rtl of L1DataAggregator 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); + + + -- Daqpath interface + + constant cNUM_CHANNELS : integer := INPUT_LINKS * cNumberOfCICs; + + signal daqpath_data_in : emp_daqpath_data_in_array(cNUM_CHANNELS - 1 downto 0); + signal daqpath_empty : emp_daqpath_flags_array(cNUM_CHANNELS - 1 downto 0); + signal daqpath_read_en : emp_daqpath_flags_array(cNUM_CHANNELS - 1 downto 0); + signal daqpath_en : std_logic; + signal daqpath_rst : std_logic; + signal daqpath_ext_creg : ipb_reg_v(3 downto 0) := (others => (others => '0')); + signal daqpath_ext_sreg : ipb_reg_v(3 downto 0) := (others => (others => '0')); + + + -- Daqpath core + + signal daqpath_data_out : emp_daqpath_data_out; + signal daqpath_slink_out : emp_daqpath_slink_out; + + + -- Output IPBus FIFO interface + + constant cNUM_LINKS : integer := 1; + signal output_data_fifo_wdata : data_fifo_data_array(0 to cNUM_LINKS - 1); + signal output_data_fifo_we : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_data_fifo_empty : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_data_fifo_full : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_idnw_fifo_wdata : ipbus_data_array(0 to cNUM_LINKS - 1); + signal output_idnw_fifo_we : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_idnw_fifo_empty : std_logic_vector(0 to cNUM_LINKS - 1); + signal output_idnw_fifo_full : std_logic_vector(0 to cNUM_LINKS - 1); + +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_dtc_data_aggregator(ipb_in.ipb_addr), + ipb_to_slaves => ipb_to_slaves, + ipb_from_slaves => ipb_from_slaves + ); + + --==============================-- + daq_control : entity work.ipbus_syncreg_v + --==============================-- + generic map ( + N_CTRL => 4, + N_STAT => 4 + ) + port map ( + clk => clk, + rst => rst, + ipb_in => ipb_to_slaves(N_SLV_DAQPATH_EXT_CTRL), + ipb_out => ipb_from_slaves(N_SLV_DAQPATH_EXT_CTRL), + slv_clk => clk_p, + d => daqpath_ext_sreg, + q => daqpath_ext_creg + ); + + + -- Status register 1-3 presents input FIFO status + -- Status register 0 presents output FIFO status + -- if output FIFOs not empty -> read them out through IPBus + + --==============================-- + status_registers_i : for i in 0 to cNUM_CHANNELS - 1 generate + --==============================-- + + daqpath_ext_sreg(1)(i) <= daqpath_empty(i).data_word; + daqpath_ext_sreg(2)(i) <= daqpath_empty(i).event_id; + daqpath_ext_sreg(3)(i) <= daqpath_empty(i).n_words; + + end generate status_registers_i; + + --==============================-- + status_registers_o : for i in 0 to cNUM_LINKS - 1 generate + --==============================-- + + daqpath_ext_sreg(0)(i * 4) <= output_data_fifo_empty(i); + daqpath_ext_sreg(0)(i * 4 + 1) <= output_idnw_fifo_empty(i); + daqpath_ext_sreg(0)(i * 4 + 2) <= output_data_fifo_full(i); + daqpath_ext_sreg(0)(i * 4 + 3) <= output_idnw_fifo_full(i); + + end generate status_registers_o; + + daqpath_ext_sreg(0)(31 downto 4 * cNUM_LINKS) <= (others => '0'); + + + -- Enable/reset signals for daqpath + + -- if daqpath_en=1 -> enabled + daqpath_en <= daqpath_ext_creg(0)(0); + + -- if daqpath_rst=1 -> all blocks internal to daqpath in reset + daqpath_rst <= daqpath_ext_creg(0)(4); + + + --==============================-- + -- DAQPATH + --==============================-- + + --==============================-- + map_links : for i in 0 to INPUT_LINKS - 1 generate + --==============================-- + + --==============================-- + map_channels : for j in 0 to cNumberOfCICs - 1 generate + --==============================-- + + daqpath_data_in(i * cNumberOfCICs + j).data_word <= daq_in(i)(j).data_word; + daqpath_data_in(i * cNumberOfCICs + j).event_id <= daq_in(i)(j).event_id; + daqpath_data_in(i * cNumberOfCICs + j).n_words <= daq_in(i)(j).n_words; + + daqpath_empty(i * cNumberOfCICs + j).data_word <= empty(i)(j).data_word; + daqpath_empty(i * cNumberOfCICs + j).event_id <= empty(i)(j).event_id; + daqpath_empty(i * cNumberOfCICs + j).n_words <= empty(i)(j).n_words; + + read(i)(j).data_word <= daqpath_read_en(i * cNumberOfCICs + j).data_word; + read(i)(j).event_id <= daqpath_read_en(i * cNumberOfCICs + j).event_id; + read(i)(j).n_words <= daqpath_read_en(i * cNumberOfCICs + j).n_words; + + end generate map_channels; + + end generate map_links; + + -- Daqpath core instance + -- Version 1.1 with : - input data flexibility (1,2,4,8 bytes) + -- - header insertion programmable through ipbus (hdr_en) in daqpath_regs + -- - Data formatter to have 64-bits words @clk_p at the output side + -- - channel mask + -- slink output stream also provided - used in the MProcessor by the Ethernet interface + + --==============================-- + DaqpathCore : entity work.emp_daqpath_module + --==============================-- + generic map ( + NUM_CHANNELS => cNUM_CHANNELS, + N_CHAN_PER_GROUP => N_CHAN_PER_GROUP + ) + port map ( + ipb_clk => clk, + ipb_rst => rst, + ipb_in => ipb_to_slaves(N_SLV_DAQPATH_CSR), + ipb_out => ipb_from_slaves(N_SLV_DAQPATH_CSR), + clk => clk_p, + rst => daqpath_rst, + en => daqpath_en, + pause => backpressure, + empty => daqpath_empty, + daqpath_data_in => daqpath_data_in, + read_en => daqpath_read_en, + daqpath_slink_out => daqpath_slink_out, + daqpath_data_out => daqpath_data_out + ); + + + -- daqpath stream exposed 'as is' + + data_out.data <= daqpath_slink_out.data; + data_out.valid <= daqpath_slink_out.valid; + data_out.start <= daqpath_slink_out.start; + data_out.strobe <= daqpath_slink_out.last; + + + --==============================-- + -- IPBus Output FIFO + --==============================-- + + --==============================-- + map_output : for i in 0 to cNUM_LINKS - 1 generate + --==============================-- + + output_data_fifo_wdata(i) <= daqpath_data_out.data_out; + output_data_fifo_we(i) <= daqpath_data_out.data_out_we; + output_idnw_fifo_wdata(i) <= daqpath_data_out.idnw_data; + output_idnw_fifo_we(i) <= daqpath_data_out.idnw_data_we; + + end generate map_output; + + --==============================-- + OutputFifo : entity work.emp_daqpath_ipbus_output_FIFOs_array + --==============================-- + generic map ( + NUM_CHANNELS => cNUM_LINKS + ) + port map ( + dp_clk => clk_p, + ipb_clk => clk, + rst => daqpath_rst, + en => daqpath_en, + ipb_in => ipb_to_slaves(N_SLV_DAQPATH_OUT), + ipb_out => ipb_from_slaves(N_SLV_DAQPATH_OUT), + data_fifo_wdata => output_data_fifo_wdata, + data_fifo_we => output_data_fifo_we, + data_fifo_empty => output_data_fifo_empty, + data_fifo_full => output_data_fifo_full, + idnw_fifo_wdata => output_idnw_fifo_wdata, + idnw_fifo_we => output_idnw_fifo_we, + idnw_fifo_empty => output_idnw_fifo_empty, + idnw_fifo_full => output_idnw_fifo_full + ); + +end architecture rtl; diff --git a/replacements/dtc/dtc-be/common/firmware/hdl/emp_daqpath_user_package.vhd b/replacements/dtc/dtc-be/common/firmware/hdl/emp_daqpath_user_package.vhd new file mode 100644 index 0000000000000000000000000000000000000000..e444d7f7db4e972f09a92f0358260dbf68ab1746 --- /dev/null +++ b/replacements/dtc/dtc-be/common/firmware/hdl/emp_daqpath_user_package.vhd @@ -0,0 +1,18 @@ +library ieee; + use ieee.std_logic_1164.all; + use ieee.numeric_std.all; + + +package emp_daqpath_user_package is + + -- DAQPATH settings + + --constant N_CHAN : integer := 8; -- total number of channnels (commented out cause channels number is calculated in payload with number fo FE modules/CICs constants) + constant N_CHAN_PER_GROUP : integer := 8; -- number of channels per pipeline group (number of group is then = ceil(N_CHAN/N_CHAN_PER_GROUP)) + constant DW_BYTES : integer := 4; -- 32 bit words for DTC + + constant emp_daqpath_ctrl_FIFOs_width : integer := 16; -- Width of the record/event-id input FIFOs words + + +end package emp_daqpath_user_package; + diff --git a/top/SerenityM/addr_table/emp_payload.xml b/top/SerenityM/addr_table/emp_payload.xml new file mode 100644 index 0000000000000000000000000000000000000000..711814852db7c1a3a33674eafc5e5aaa83efd27b --- /dev/null +++ b/top/SerenityM/addr_table/emp_payload.xml @@ -0,0 +1,25 @@ +<node description="Payload ipbus registers and RAM" fwinfo="endpoint"> + + <node id="fe" address="0x00" description="FE channel select" fwinfo="endpoint;width=1"> + <node id="chan_sel" address="0x00" mask="0x7f"/> + <node id="num_links" address="0x01"/> + </node> + + <node id="fe_chan" address="0x200" module="file://dtc_link_interface.xml" fwinfo="endpoint;width=9"/> + + <node id="tcds_fast_cmd" address="0x600" module="file://dtc_tcds_fastcmd.xml"/> + + <node id="link_monitor" address="0x10000" module="file://LinkMonitorInterface.xml"/> + + <node id="mprocessor" address="0x40000" description="MProcessor control and status" module="file://mprocessor.xml" fwinfo="endpoint;width=13"/> + <node id="mproc_ctrl" address="0x4fff0" description="MProcessor channel control" fwinfo="endpoint;width=1"> + <node id="control" address="0x0"> + <node id="chan_sel" mask="0x7f"/> + <node id="srst" mask="0x80"/> + <node id="sync_fastreset" mask="0x100"/> + </node> + <node id="header_user_bits" address="0x1"/> + </node> + + <node id="be_daq" address="0x40000000" module="file://dtc_data_aggregator.xml" fwinfo="endpoint;width=30"/> +</node> diff --git a/top/SerenityM/firmware/cfg/top.dep b/top/SerenityM/firmware/cfg/top.dep new file mode 100644 index 0000000000000000000000000000000000000000..7c37ee871c0c4ba17f6f80ad03af59362bef47e4 --- /dev/null +++ b/top/SerenityM/firmware/cfg/top.dep @@ -0,0 +1,31 @@ +include -c histogram:top histogram.dep +include -c dtc:dtc-fe common.dep +include -c dtc:dtc-fe framers.dep +include -c dtc:dtc-be/common daqpath.dep +include -c dtc:dtc-be/common common.dep +include -c dtc-stub-processing:common tools.dep + +src -c emp-fwk:components/payload ../ucf/emp_simple_payload.tcl +src -c ipbus-firmware:components/ipbus_slaves ipbus_dpram.vhd +src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_v.vhd +src -c ipbus-firmware:components/ipbus_slaves ipbus_ctrlreg_v.vhd +src -c ipbus-firmware:components/ipbus_slaves ipbus_reg_types.vhd +src -c ipbus-firmware:components/ipbus_core ipbus_dc_node.vhd +src -c ipbus-firmware:components/ipbus_core ipbus_dc_fabric_sel.vhd +include -c emp-fwk:boards/serenity/dc_vu13p dc_vu13p_so2.dep +include -c emp-fwk:components/links/fe_mgt/interface interface.dep +include -c emp-fwk:components/links/fe_mgt/lpgbt/interface interface_lpgbt.dep + +? toolset.lower() == "vivado" ? setup -c emp-fwk:components/payload emp_simple_payload_msg_suppressions.tcl + +include -c 10gb-ethernet:eth10g emp_eth10g.dep +include -c dtc-monitoring:common module.dep +include -c common module.dep + +src emp_project_decl.vhd +src emp_payload.vhd +src link_maps.vhd + +src ipbus_decode_emp_payload.vhd + +addrtab -t emp_payload.xml diff --git a/top/SerenityM/firmware/hdl/emp_payload.vhd b/top/SerenityM/firmware/hdl/emp_payload.vhd new file mode 100644 index 0000000000000000000000000000000000000000..1e712484d8fd9db88243bf70e6c4cffea85e7944 --- /dev/null +++ b/top/SerenityM/firmware/hdl/emp_payload.vhd @@ -0,0 +1,499 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +--- +use work.ipbus.all; +use work.ipbus_reg_types.all; +use work.ipbus_decode_emp_payload.all; +--- +use work.emp_data_types.all; +use work.emp_project_decl.all; +use work.emp_device_decl.all; +use work.emp_ttc_decl.all; +use work.emp_slink_types.all; +--- +use work.dtc_link_maps.all; +use work.front_end_data_types.all; +use work.module_constants.all; +use work.mprocessor_constants.all; +use work.dtc_constants.all; +use work.dtc_data_types.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); + backpressure : in std_logic_vector(SLINK_MAX_QUADS-1 downto 0); + ttc_cmd : in ttc_cmd_t; + --- 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); + slink_q : out slink_input_data_quad_array(SLINK_MAX_QUADS-1 downto 0); + --- IPBus Ports --- + clk : in std_logic; + rst : in std_logic; + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus; + -- KH + gbe_q : out ldata := (others => LWORD_NULL); + gbe_backpressure : in std_logic_vector(3 downto 0) + ); +end entity emp_payload; + + +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 fe_control_registers : ipb_reg_v(0 downto 0); + signal fe_status_registers : ipb_reg_v(0 downto 0); + signal mproc_control_registers : ipb_reg_v(1 downto 0); + signal mproc_status_registers : 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 header_array : tCICHeaderArray(cNumberOfFEModules*cNumberOfCICs - 1 downto 0) := (others => ('0', (others => '0'), (others => '0'), (others => '0'))); + signal header_start_array, header_start_array_buffered : std_logic_vector(cNumberOfFEModules*cNumberOfCICs - 1 downto 0) := (others => '0'); + + signal eth_link_out : ldata(3 downto 0) := (others => LWORD_NULL); + + + + -- MProcessor + signal mprocessor_ipb_chain : ipbdc_bus_array(cNumberOfMProcessors downto 0); + signal srst : std_logic := '0'; + signal ttc_resync_reset, ttc_resync_reset_prev : std_logic := '0'; + signal ttc_bc0, ttc_oc0, ttc_resync : std_logic := '0'; + + signal orbit_counter : unsigned(31 downto 0) := to_unsigned(0 , 32); + signal bunch_counter : unsigned(11 downto 0) := to_unsigned(3564, 12); + signal readout_reset : std_logic_vector(cNumberOfMProcessors - 1 downto 0) := (others => '0'); + signal payload_headers : tPayloadHeaderArray := (others => (others => '0')); + + + -- Daqpath + + signal daq_read : tDaqFlagLinkArray(cNumberOfFEModules - 1 downto 0); + signal daq_data : tDaqDataLinkArray(cNumberOfFEModules - 1 downto 0); + signal daq_empty : tDaqFlagLinkArray(cNumberOfFEModules - 1 downto 0); + signal daq_data_buffered : tDaqDataLinkArray(cNumberOfFEModules - 1 downto 0); + signal daq_empty_buffered : tDaqFlagLinkArray(cNumberOfFEModules - 1 downto 0); + + + -- TCDS & Fast commands + + signal global_fcmd : tFastCommand; + signal tcds_fcmd : tFastCommand; + + +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_emp_payload(ipb_in.ipb_addr), + ipb_to_slaves => ipb_to_slaves, + ipb_from_slaves => ipb_from_slaves + ); + + --==============================-- + fe_channel_ctrl : entity work.ipbus_ctrlreg_v + --==============================-- + generic map( + N_CTRL => 1, + N_STAT => 1 + ) + port map ( + clk => clk, + reset => rst, + ipbus_in => ipb_to_slaves(N_SLV_FE), + ipbus_out => ipb_from_slaves(N_SLV_FE), + d => fe_status_registers, + q => fe_control_registers + ); + + fe_status_registers(0) <= std_logic_vector(to_unsigned(cNumberOfFEModules, 32)); + + --==============================-- + channel_select : entity work.ipbus_dc_fabric_sel + --==============================-- + generic map ( + SEL_WIDTH => 7 + ) + port map ( + clk => clk, + rst => rst, + sel => fe_control_registers(0)(6 downto 0), + ipb_in => ipb_to_slaves(N_SLV_FE_CHAN), + ipb_out => ipb_from_slaves(N_SLV_FE_CHAN), + ipbdc_out => ipb_chain(0), + ipbdc_in => ipb_chain(cNumberOfFEModules) + ); + + --==============================-- + mproc_ctrl: entity work.ipbus_ctrlreg_v + --==============================-- + generic map( + N_CTRL => 2 + ) + 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_control_registers + ); + + + --==============================-- + -- FE data extraction and monitoring + --==============================-- + + --==============================-- + genLinkInterface: for i in 0 to cNumberOfFEModules - 1 generate + --==============================-- + + signal ipb_to_channel : ipb_wbus; + signal ipb_from_channel : ipb_rbus; + + begin + + --==============================-- + 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 => ipb_chain(i), + ipbdc_out => ipb_chain(i + 1) + ); + + --==============================-- + LinkInterfaceInstance : entity work.LinkInterface + --==============================-- + generic map ( + module_type => cDTCInputLinkMap(i).module_type, + bandwidth => cDTCInputLinkMap(i).bandwidth, + cic_type => cDTCInputLinkMap(i).cic_type + ) + port map ( + --- Input Ports --- + clk_p => clk_p, + clk40 => clk40, + link_in => d(cDTCInputLinkMap(i).index), + daq_read => daq_read(i), + global_fcmd => global_fcmd, + --- Output Ports --- + link_out => q(cDTCInputLinkMap(i).index), + stub_out => stubs(i), + header_out => header_array(cNumberOfCICs * i + cNumberOfCICs - 1 downto cNumberOfCICs * i), + daq_out => daq_data(i), + daq_empty => daq_empty(i), + --- IPBus Ports --- + clk => clk, + rst => rst, + ipb_in => ipb_to_channel, + ipb_out => ipb_from_channel, + --- Debug Ports --- + debug_header_start => header_start_array(cNumberOfCICs*(i + 1) - 1 downto cNumberOfCICs*i) + ); + end generate genLinkInterface; + + + --==============================-- + -- Global TCDS + --==============================-- + + --==============================-- + GlobalFastCommand: entity work.GlobalFastCommand + --==============================-- + port map ( + --- Input Ports --- + clk_p => clk_p, + clk40 => clk40, + ext_fcmd => tcds_fcmd, + --- Output Ports --- + global_fcmd => global_fcmd, + --- IPBus Ports --- + clk => clk, + rst => rst, + ipb_in => ipb_to_slaves(N_SLV_TCDS_FAST_CMD), + ipb_out => ipb_from_slaves(N_SLV_TCDS_FAST_CMD) + ); + + tcds_fcmd.fast_reset <= ttc_resync; + tcds_fcmd.l1a_trig <= '0'; + tcds_fcmd.cal_pulse <= '0'; + tcds_fcmd.counter_reset <= ttc_bc0; + + + + + + --==============================-- + -- L1 Data Aggregator + --==============================-- + + pBufferL1Data : process(clk_p) + begin + if rising_edge(clk_p) then + daq_data_buffered <= daq_data; + daq_empty_buffered <= daq_empty; + end if; + end process pBufferL1Data; + + --==============================-- + L1DataAggregator : entity work.L1DataAggregator + --==============================-- + port map ( + --- Input Ports --- + clk_p => clk_p, + daq_in => daq_data_buffered, + empty => daq_empty_buffered, + backpressure => gbe_backpressure(3), + --- Output Ports --- + read => daq_read, + data_out => gbe_q(3), + --- IPBus Ports --- + clk => clk, + rst => rst, + ipb_in => ipb_to_slaves(N_SLV_BE_DAQ), + ipb_out => ipb_from_slaves(N_SLV_BE_DAQ) + ); + + --==============================-- + pRouteStubsToOutput : process (clk_p) is + --==============================-- + begin + if rising_edge(clk_p) then + for i in 0 to cNumberOfOutputLinks - 1 loop + q(cDTCOutputLinkMap(i)).valid <= d(cDTCInputLinkMap(i).index).valid; + q(cDTCOutputLinkMap(i)).data <= d(cDTCInputLinkMap(i).index).data; + q(cDTCOutputLinkMap(i)).strobe <= '1'; + end loop; + + header_start_array_buffered <= header_start_array; + end if; + end process pRouteStubsToOutput; + + + + --==============================-- + LinkMonitorInterfaceInstance : entity work.LinkMonitorInterface + --==============================-- + generic map ( + N_LINKS => cNumberOfFEModules + ) + port map ( + --- Input Ports --- + clk_p => clk_p, + stubs => stubs(cNumberOfFEModules - 1 downto 0), + headers => header_array(2*cNumberOfFEModules - 1 downto 0), + header_start => header_start_array(2*cNumberOfFEModules - 1 downto 0), + --- IPBus Ports --- + clk => clk, + rst => rst, + ipb_in => ipb_to_slaves(N_SLV_LINK_MONITOR), + ipb_out => ipb_from_slaves(N_SLV_LINK_MONITOR) + ); + + + --==============================-- + -- Link Aggregation and Combination + --==============================-- + + --==============================-- + mprocessor_channel_select: entity work.ipbus_dc_fabric_sel + --==============================-- + generic map( + SEL_WIDTH => 7 + ) + port map( + clk => clk, + rst => rst, + sel => mproc_control_registers(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) + ); + + + --==============================- + genMProcessors : for i in 0 to cNumberOfMProcessors - 1 generate + --==============================- + + signal ipb_to_channel : ipb_wbus; + signal ipb_from_channel : ipb_rbus; + constant cNumberofInputLinks : integer := 3; + + begin + + --==============================-- + 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, + INDEX => i + ) + port map( + --- Input Ports --- + clk_p => clk_p, + links_in => stubs(cNumberofInputLinks*i + (cNumberofInputLinks - 1) downto cNumberofInputLinks*i), + header_start_array => convertSLVtoHeaderStartArray(header_start_array_buffered), + payload_header => payload_headers(i), + gbe_backpressure => gbe_backpressure(i), + srst => srst, + --- Output Ports --- + link_out => eth_link_out(i), + --- IPBus Ports --- + ipb_clk => clk, + ipb_rst => rst, + ipb_in => ipb_to_channel, + ipb_out => ipb_from_channel, + --- Debug Ports --- + debug_readout_reset => readout_reset(i) + ); + end generate genMProcessors; + + --==============================-- + PayloadHeadeGeneratorInstance : entity work.PayloadHeaderGenerator + --==============================-- + port map ( + --- Input Ports --- + clk_p => clk_p, + reset => srst, + readout_reset => readout_reset(0), + header_start => header_start_array_buffered(0), + module_header_in => header_array, + user_bits => mproc_control_registers(1), + --- Ouput Ports --- + header_out => payload_headers + ); + + + + gbe_q(cNumberOfMProcessors-1 downto 0) <= eth_link_out(cNumberOfMProcessors-1 downto 0); + q(25) <= eth_link_out(0); + q(26) <= eth_link_out(1); + + + --==============================-- + pTTC: process(clk40) + --==============================-- + begin + if rising_edge(clk40) then + + ttc_bc0 <= '0'; + ttc_oc0 <= '0'; + ttc_resync <= '0'; + + if ttc_cmd = TTC_BCMD_BC0 then + orbit_counter <= orbit_counter + 1; + bunch_counter <= (others => '0'); + ttc_bc0 <= '1'; + + if ttc_resync_reset = '1' and ttc_resync_reset_prev = '0' then + + ttc_resync <= '1'; + + end if; + + ttc_resync_reset_prev <= ttc_resync_reset; + + + elsif ttc_cmd = TTC_BCMD_OC0 then + + orbit_counter <= (others => '0'); + bunch_counter <= to_unsigned(3564, bunch_counter'length); + ttc_oc0 <= '1'; + + elsif bunch_counter < 3564 then + + bunch_counter <= bunch_counter + 1; + + end if; + + end if; + end process; + + ttc_resync_reset <= mproc_control_registers(0)(8); + srst <= mproc_control_registers(0)(7) or ttc_oc0; + + q(24).valid <= '1'; + q(24).data <= "0000" & std_logic_vector(bunch_counter) & "0000000000000000" & std_logic_vector(orbit_counter); + q(24).start <= '1'; + q(24).strobe <= '1'; + + + + + bc0 <= '0'; + gpio <= (others => '0'); + gpio_en <= (others => '0'); + + + --==============================-- + slink_q_gen : for q in SLINK_MAX_QUADS-1 downto 0 generate + --==============================-- + begin + slink_q(q) <= SLINK_INPUT_DATA_ARRAY_NULL; + end generate slink_q_gen; + + + +end architecture rtl; diff --git a/top/SerenityM/firmware/hdl/emp_project_decl.vhd b/top/SerenityM/firmware/hdl/emp_project_decl.vhd new file mode 100644 index 0000000000000000000000000000000000000000..5e6996a1d8b83ee693f476b271704434be97c09f --- /dev/null +++ b/top/SerenityM/firmware/hdl/emp_project_decl.vhd @@ -0,0 +1,90 @@ +-- emp_project_decl +-- +-- Defines constants for the whole device + +library ieee; +use ieee.std_logic_1164.all; + +library lpgbt_lib; +use lpgbt_lib.lpgbtfpga_package.all; + +use work.emp_framework_decl.all; +use work.emp_device_decl.all; +use work.emp_device_types.all; +use work.emp_lpgbt_decl.all; +use work.emp_data_framer_decl.all; +use work.emp_slink_types.all; +use work.emp_eth10g_types.all; + +------------------------------------------------------------------------------- +package emp_project_decl is + + constant PAYLOAD_REV : std_logic_vector(31 downto 0) := X"d451d001"; + + -- Latency buffer size + constant LB_ADDR_WIDTH : integer := 10; + + -- Clock setup + constant CLOCK_COMMON_RATIO : integer := 32; + constant CLOCK_RATIO : integer := 8; + constant CLOCK_AUX_DIV : clock_divisor_array_t := (16, 8, 4); -- Dividers of CLOCK_COMMON_RATIO * 40 MHz + + -- Only used by nullalgo + constant PAYLOAD_LATENCY : integer := 5; + + -- mgt -> buf -> fmt -> (algo) -> (fmt) -> buf -> mgt -> clk -> altclk + constant REGION_CONF : region_conf_array_t := ( + -- 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 => (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 + 8 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 233 + 9 => (no_mgt, buf, no_fmt, buf, no_mgt), --Bank 234 +-- -- Cross-chip +-- KH used for gbe + --10 => (gty25, buf, no_fmt, buf, gty25), + --11 => (gty25, buf, no_fmt, buf, gty25), + --12 => (gty25, buf, no_fmt, buf, gty25), +-- KH used for gbe +-- 13 => (gty25, buf, no_fmt, buf, gty25), --Bank 131 +-- 14 => (gty25, buf, no_fmt, buf, gty25), --Bank 130 +-- 15 => (gty25, buf, no_fmt, buf, gty25), --Bank 129 +-- 16 => (gty25, buf, no_fmt, buf, gty25), --Bank 128 +-- 17 => (gty25, buf, no_fmt, buf, gty25), --Bank 127 + others => kDummyRegion + ); + + -- for data framer (ic_simple, no_ec, n_ec_spare, ec_broadcast) + constant REGION_DATA_FRAMER_CONF : region_data_framer_conf_array_t := ( + -- 0 => ( 0=>(false, true, 0, false, lpgbtv1), 1=>(false, true, 0, false, lpgbtv1), 2=>(false, true, 0, false, lpgbtv1), 3=>(false, true, 0, false, lpgbtv1)), + 1 => ( 0=>(false, true, 0, false, lpgbtv1), 1=>(false, true, 0, false, lpgbtv1), 2=>(false, true, 0, false, lpgbtv1), 3=>(false, true, 0, false, lpgbtv1)), + -- 2 => ( 0=>(false, true, 0, false, lpgbtv1), 1=>(false, true, 0, false, lpgbtv1), 2=>(false, true, 0, false, lpgbtv1), 3=>(false, true, 0, false, lpgbtv1)), + others => kDummyRegionDataFramer + ); + + -- for lpgbt + constant REGION_LPGBT_CONF : region_lpgbt_conf_array_t := ( + -- 0 => (FEC5, DATARATE_5G12, PCS), + 1 => (FEC5, DATARATE_5G12, PCS), + -- 2 => (FEC5, DATARATE_5G12, PCS), + others => kDummyRegionLpgbt + ); + + -- Specify the slink quad using the corresponding region conf ID + -- Specify slink channels to enable using the channel mask + constant SLINK_CONF : slink_conf_array_t := ( + others => kNoSlink + ); + + constant ETH10G_CONF : eth10g_conf_array_t := ( + 0 => (10, "1111", (x"aabbccddef51", x"aabbccddef52", x"aabbccddef53", x"aabbccddef54")) + ); + + + +end emp_project_decl; +------------------------------------------------------------------------------- diff --git a/top/SerenityM/firmware/hdl/link_maps.vhd b/top/SerenityM/firmware/hdl/link_maps.vhd new file mode 100644 index 0000000000000000000000000000000000000000..df24373fa8df66d7c468c813ccb2c7f87ea4afc7 --- /dev/null +++ b/top/SerenityM/firmware/hdl/link_maps.vhd @@ -0,0 +1,26 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.ALL; +use IEEE.NUMERIC_STD.ALL; +use work.dtc_link_maps_func.all; + +package dtc_link_maps is + + constant cNumberOfFEModules : integer := 4; + constant cNumberOfOutputLinks : integer := 4; + constant cNumberOfMProcessors : integer := 1; + + type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; + constant cDTCInputLinkMap : tDTCInputLinkMap := ( + 0 => (32, "PS", 5, "CIC2"), + 1 => (33, "PS", 5, "CIC2"), + 2 => (34, "PS", 5, "CIC2"), + 3 => (35, "PS", 5, "CIC2") + + ); + + type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + 12, 13, 14, 15 + ); + +end package dtc_link_maps; diff --git a/top/charm/firmware/hdl/emp_payload.vhd b/top/charm/firmware/hdl/emp_payload.vhd index ac9e640368bf462e5bf4e620077f121bd5b4e894..1e712484d8fd9db88243bf70e6c4cffea85e7944 100644 --- a/top/charm/firmware/hdl/emp_payload.vhd +++ b/top/charm/firmware/hdl/emp_payload.vhd @@ -284,16 +284,18 @@ begin --==============================-- port map ( --- Input Ports --- - clk_p => clk_p, - daq_in => daq_data_buffered, - empty => daq_empty_buffered, + clk_p => clk_p, + daq_in => daq_data_buffered, + empty => daq_empty_buffered, + backpressure => gbe_backpressure(3), --- Output Ports --- - read => daq_read, + read => daq_read, + data_out => gbe_q(3), --- IPBus Ports --- - clk => clk, - rst => rst, - ipb_in => ipb_to_slaves(N_SLV_BE_DAQ), - ipb_out => ipb_from_slaves(N_SLV_BE_DAQ) + clk => clk, + rst => rst, + ipb_in => ipb_to_slaves(N_SLV_BE_DAQ), + ipb_out => ipb_from_slaves(N_SLV_BE_DAQ) ); --==============================--