diff --git a/.gitignore b/.gitignore index 1bb46147d7feb65673794f3a0c412fb42fdff549..1c77988a33ea10ae53e852b37efbc5b8338cdb5a 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -*.code-workspace \ No newline at end of file +*.code-workspace +**/ipbus_decode* \ No newline at end of file diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8fe1eba72dc0d40bd1487ec04e8051687700043a..076d88b59f137d756eba8b378e4406af50c9e15a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -3,12 +3,12 @@ include: file: "/ci/templates/vivado-jobs.yml" variables: - VIVADO_VER: "2022.2" + VIVADO_VER: "2023.2" PROJECT_DEPFILE: top.dep - PROJECT_ALGORITHM: top + PROJECT_ALGORITHM: top/charm PROJECT_NAME: mprocessor EMPHUB_TAG: $CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA - IPBB_VER: "dev-2021j-v1.2" + IPBB_VER: "dev-2023a-v1.3" .vivado-job-build: diff --git a/common/firmware/hdl/LinkCombinerCore.vhd b/common/firmware/hdl/LinkCombinerCore.vhd index 54a09f1ec60364be15b0bcdc15783de00d89c54c..5770215a5f77e1218f812ccbd46bb9df3e6f70df 100644 --- a/common/firmware/hdl/LinkCombinerCore.vhd +++ b/common/firmware/hdl/LinkCombinerCore.vhd @@ -3,7 +3,7 @@ use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; use work.emp_data_types.all; use work.front_end_data_types.all; -use work.gbt_module_constants.all; +use work.module_constants.all; use work.dtc_link_maps.all; use work.dtc_data_types.all; use work.dtc_constants.all; diff --git a/common/firmware/hdl/LinkCombinerIPBus.vhd b/common/firmware/hdl/LinkCombinerIPBus.vhd index 18a08325379e68a329f95f0f85b175af2318052c..4270a665761cea862179ce7abde47dfd9da80518 100644 --- a/common/firmware/hdl/LinkCombinerIPBus.vhd +++ b/common/firmware/hdl/LinkCombinerIPBus.vhd @@ -7,7 +7,7 @@ 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.module_constants.all; use work.dtc_link_maps.all; use work.dtc_data_types.all; use work.dtc_constants.all; diff --git a/common/firmware/hdl/MProcessor.vhd b/common/firmware/hdl/MProcessor.vhd index 27f7176539dd8bfff702ee0dea536fafdc2f0dd0..c6b2ec042a243d8235e7458bd70f41335648d59d 100644 --- a/common/firmware/hdl/MProcessor.vhd +++ b/common/firmware/hdl/MProcessor.vhd @@ -10,7 +10,7 @@ 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.module_constants.all; use work.mprocessor_constants.all; use work.dtc_data_types.all; use work.dtc_constants.all; diff --git a/dependencies.yml b/dependencies.yml index 0cbe131cbe6e15a919fa141564d1e7e6163a8e5b..1585d8bb24ae2a4bffcf5e6f13db2f0be0091923 100644 --- a/dependencies.yml +++ b/dependencies.yml @@ -1,7 +1,7 @@ --- sources: emp-fwk: - branch: feature/lpgbtv1_merge_rebase + branch: v0.9.0-alpha2 url: https://gitlab.cern.ch/p2-xware/firmware/emp-fwk.git ttc_legacy: @@ -17,7 +17,7 @@ sources: url: https://gitlab.cern.ch/gbt-fpga/lpgbt-fpga.git ipbus: - tag: v1.9 + tag: v1.10 url: https://github.com/ipbus/ipbus-firmware histogram: @@ -45,7 +45,7 @@ sources: url: https://gitlab.cern.ch/gbtsc-fpga-support/gbt-sc.git dtc: - branch: master + branch: 25-master-branch-uses-old-emp-branch url: https://gitlab.cern.ch/cms-tracker-phase2-data-processing/BE_firmware/dtc.git dtc-stub-processing: @@ -63,3 +63,8 @@ sources: 10gb-ethernet: branch: master url: https://gitlab.cern.ch/cms-tracker-phase2-data-processing/BE_firmware/10gb-ethernet.git + + daqpath-toolkit: + branch: master + url: https://gitlab.cern.ch/dmonk/daqpath-toolkit.git + 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 2ac77db506624757e959ec1c66b214630cca78cd..bb48838f1a700742281480df98d233187f537e41 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 @@ -64,6 +64,8 @@ entity top is -- Transceiver ref-clocks refclkp : in std_logic_vector(N_REFCLK - 1 downto 0); refclkn : in std_logic_vector(N_REFCLK - 1 downto 0); + -- Site ID pins + site_id : in std_logic_vector(1 downto 0); -- Heartbeat LED heartbeat_led : out std_logic ); @@ -126,11 +128,11 @@ begin -- Infrastructure -pcie_rst_invert : if emp_slim_top_decl.PCIE_RST_ACTIVE_LEVEL = '1' generate -pcie_sys_rst_n <= not pcie_sys_rst; -else generate -- pcie_rst_invert -pcie_sys_rst_n <= pcie_sys_rst; -end generate pcie_rst_invert; + pcie_rst_invert : if emp_slim_top_decl.PCIE_RST_ACTIVE_LEVEL = '1' generate + pcie_sys_rst_n <= not pcie_sys_rst; + else generate -- pcie_rst_invert + pcie_sys_rst_n <= pcie_sys_rst; + end generate pcie_rst_invert; infra : entity work.emp_infra_pcie port map( @@ -182,7 +184,8 @@ end generate pcie_rst_invert; clk => ipb_clk, rst => ipb_rst, ipb_in => ipb_w_array(N_SLV_INFO), - ipb_out => ipb_r_array(N_SLV_INFO) + ipb_out => ipb_r_array(N_SLV_INFO), + site_id => "000000" & site_id ); ctrl : entity work.emp_ctrl @@ -271,7 +274,7 @@ end generate pcie_rst_invert; rst => ipb_rst, ipb_in => ipb_w_array(N_SLV_PAYLOAD), ipb_out => ipb_r_array(N_SLV_PAYLOAD), - clk40 => clk40, + clk40 => clk40, clk_payload => clks_aux, rst_payload => rsts_aux, clk_p => clk_p, @@ -289,31 +292,30 @@ end generate pcie_rst_invert; -- 10g gbe_q => gbe_ldata, gbe_backpressure => gbe_backpressure + ); - ); - - slink_check : if slink_quads_enabled(SLINK_CONF) > 0 generate - slink : entity work.emp_slink_interface - generic map ( - throughput => SLINK_THROUGHPUT, - technology => SLINK_XCVR_TYPE, - ref_clock_freq => SLINK_REFCLK_FREQ, - ref_clock_index => IO_REGION_SPEC(SLINK_CONF(0).region).io_async_refclk + slink_check : if slink_quads_enabled(SLINK_CONF) > 0 generate + slink : entity work.emp_slink_interface + generic map ( + throughput => SLINK_THROUGHPUT, + technology => SLINK_XCVR_TYPE, + ref_clock_freq => SLINK_REFCLK_FREQ, + ref_clock_index => IO_REGION_SPEC(SLINK_CONF(0).region).io_async_refclk ) - port map ( - ipb_clk => ipb_clk, - ipb_rst => ipb_rst, - ipb_in => ipb_w_array(N_SLV_SLINK), - ipb_out => ipb_r_array(N_SLV_SLINK), + port map ( + ipb_clk => ipb_clk, + ipb_rst => ipb_rst, + ipb_in => ipb_w_array(N_SLV_SLINK), + ipb_out => ipb_r_array(N_SLV_SLINK), - clk_40 => clk40ish, - clk_p => clk_p, + clk_40 => clk40ish, + clk_p => clk_p, - slink_d => slink_payload_data, - backpressure => slink_backpressure, + slink_d => slink_payload_data, + backpressure => slink_backpressure, - refclkp => refclkp, - refclkn => refclkn + refclkp => refclkp, + refclkn => refclkn ); end generate; diff --git a/replacements/emp-fwk/components/top/firmware/ucf/clock_constraints_common.tcl b/replacements/emp-fwk/components/top/firmware/ucf/clock_constraints_common.tcl new file mode 100644 index 0000000000000000000000000000000000000000..4faaa1bb5976d64cfa98a255410f24242849eb9f --- /dev/null +++ b/replacements/emp-fwk/components/top/firmware/ucf/clock_constraints_common.tcl @@ -0,0 +1,70 @@ + +# 40MHz & payload I/O clocks derived from board-local source (for tests without external clock source) +create_generated_clock -name clk_40_pseudo_i [get_pins ttc/bufgce_clk_40_rx/O] +create_generated_clock -name clk_40_pseudo -source [get_pins ttc/clocks/mmcm/CLKIN2] [get_pins ttc/clocks/mmcm/CLKOUT1] +create_generated_clock -name clk_payload_pseudo -source [get_pins ttc/clocks/mmcm/CLKIN2] [get_pins ttc/clocks/mmcm/CLKOUT3] + +# Names of the LHC-synchronised derived clocks that are used by payload and infra (outside of TTC block) +lappend lMainPayloadClocks clk_40_pseudo clk_payload_pseudo + + +if {[llength [get_pins -quiet ttc/gen_master_legacy.osc_clock/mmcm/CLKOUT1]] != 0} { + create_generated_clock -name clk_40_extern_i0 [get_pins ttc/gen_master_legacy.osc_clock/gen_mmcm/mmcm/CLKOUT1] +} + +if {[llength [get_pins -quiet ttc/gen_master_tcds2.tcds2/tcds2_interface/bufgce_clk_40_rx/O]] != 0} { + create_generated_clock -name clk_40_extern_i1 [get_pins ttc/gen_master_tcds2.tcds2/tcds2_interface/bufgce_clk_40_rx/O] +} + +foreach i [list 0 1] { + if {[llength [get_clocks -quiet clk_40_extern_i$i]] != 0 } { + create_generated_clock -name clk_40_extern$i -master_clock [get_clocks clk_40_extern_i$i] [get_pins ttc/clocks/mmcm/CLKOUT1] + # Payload I/O clock derived from external oscillator + create_generated_clock -name clk_payload_extern$i -master_clock [get_clocks clk_40_extern_i$i] [get_pins ttc/clocks/mmcm/CLKOUT3] + + lappend lMainPayloadClocks clk_40_extern_i$i clk_40_extern$i clk_payload_extern$i + } +} + + +# Clock groups: Asynchronous +puts "lMainPayloadClocks = $lMainPayloadClocks" +set_clock_groups -asynch -group [get_clocks axi_clk] -group [get_clocks -include_generated_clocks ipbus_clk] +set_clock_groups -asynch -group [get_clocks -include_generated_clocks ipbus_clk] -group $lMainPayloadClocks + +# Clock groups: Logically exclusive +# The 40MHz, 160MHz and payload clocks used across the chip are generated by an MMCM with two clock sources: +# * an externally-provided LHC clock (typically from TCDS), which itself could come from one of two interfaces (clk_40_externN); and +# * an internally-generated 'pseudo-LHC' clock (clk_40_pseudo) +# Must set the copies of the clocks generated from those sources as logically exclusive +foreach lMasterA [list clk_40_pseudo_i clk_40_pseudo_i clk_40_extern_i0] lMasterB [list clk_40_extern_i0 clk_40_extern_i1 clk_40_extern_i1] { + if {[llength [get_clocks -quiet [list $lMasterA $lMasterB]]] == 2} { + puts "Declaring clocks derived from $lMasterA and $lMasterB as logically exclusive" + set_clock_groups -logically_exclusive -group [get_clocks -filter "MASTER_CLOCK == $lMasterA || NAME == $lMasterA"] -group [get_clocks -filter "MASTER_CLOCK == $lMasterB || NAME == $lMasterB"] + } +} + + +# Inform Vivado that skew between 40MHz and payload clocks should be minimised +set_property CLOCK_DELAY_GROUP lhc_sync_clkgroup [get_nets -of_objects [get_pins ttc/clocks/bufg_40/O]] [get_nets -of_objects [get_pins ttc/clocks/bufg_p/O]] + + +# SLink: Give SLink clocks nicer names, and declare them as async to LHC clocks, main data I/O clocks and IPbus clock +if { [llength [get_cells slink_check.slink]] > 0 } { + create_generated_clock -name slink_fed_clk [get_pins slink_check.slink/clocks/bufg_fed/O] + create_generated_clock -name slink_fmt_clk [get_pins slink_check.slink/clocks/mmcm/CLKOUT1] + + set_clock_groups -asynch -group [get_clocks -include_generated_clocks ipbus_clk] -group [get_clocks -include_generated_clocks {slink_fmt_clk slink_fed_clk}] + set_clock_groups -asynch -group [get_clocks -include_generated_clocks $lMainPayloadClocks] -group [get_clocks -include_generated_clocks {slink_fmt_clk slink_fed_clk}] + + # Remove clock constraints on the paths to the slink clock frequency measurement block + set_false_path -to [get_pins slink_check.slink/ctr/t_in_reg/D] +} + + +# Print clock report for the record (in case build fails, or need to debug clock-related issues) +report_clocks + + +# Remove timing constraints for heartbeat LED output port +set_false_path -to [get_ports -regexp "(.+_led|led_.+)"] diff --git a/replacements/emp-fwk/components/top/firmware/ucf/clock_constraints_tcds2.tcl b/replacements/emp-fwk/components/top/firmware/ucf/clock_constraints_tcds2.tcl deleted file mode 100644 index 606c6caf8b35ccc2b6da32e9c7fc317d2310a392..0000000000000000000000000000000000000000 --- a/replacements/emp-fwk/components/top/firmware/ucf/clock_constraints_tcds2.tcl +++ /dev/null @@ -1,12 +0,0 @@ - -# Define 125MHz clock, and declare as async to other clocks -#Â Note: In some designs 125MHz clock is top-level port (e.g. Serenity DC), -# otherwise its a derived clock from the infra block (e.g. Apollo) -if {[llength [get_ports -quiet clk125]] != 0} { - create_clock -period 8.000 -name sys_clk125 [get_ports clk125] -} -set_clock_groups -asynch -group [get_clocks -include_generated_clocks sys_clk125] - -# Paths from TCDS core to EMP TTC logic: Only perform timing analysis when clk40 in EMP logic comes from TCDS core -# Commented out as it throws error in Vivado 2022 -# set_false_path -through [get_nets {ttc/*tcds2_interface_stat[channel0_ttc2]*}] -to [get_clocks {clk_40_extern0 clk_40_pseudo}] diff --git a/replacements/emp-fwk/components/top/firmware/ucf/clock_declarations_pcie.tcl b/replacements/emp-fwk/components/top/firmware/ucf/clock_declarations_pcie.tcl new file mode 100644 index 0000000000000000000000000000000000000000..22736af01d5101834d1c36f7350be36b01814909 --- /dev/null +++ b/replacements/emp-fwk/components/top/firmware/ucf/clock_declarations_pcie.tcl @@ -0,0 +1,24 @@ +# From Vivado 2020.2.2 (or from IP core 4.1 revision 10) there appears to be a bug which causes Vivado +# to think that the AXI clock frequency is half of what it actually is (i.e. 62.5MHz rather than 125MHz) +# if it's configured to use a CPLL rather than QPLL. Solution: Tell Vivado what the frequency really is. +# When using the create_clock command you to fix this, you lose the relationship with any parent clocks, # so to avoid fallout from that, we actually fix the frequency of the TXOUTCLK (which should be 500MHz) +# See https://gitlab.cern.ch/p2-xware/firmware/emp-fwk/-/issues/31 +# This bug was apparently fixed in Vivado 2023.2 +if {([get_property CORE_REVISION [get_ips xdma_0]] >= 10) && ([get_property CORE_REVISION [get_ips xdma_0]] < 26) && ([get_property CONFIG.plltype [get_ips xdma_0]] == "CPLL")} { + create_clock -period 2.000 -name xdma_txoutclk [get_pins -hierarchical -filter {NAME =~infra/dma/xdma/*/*_CHANNEL_PRIM_INST/TXOUTCLK}] +} + +# 100 Mhz PCIe system clock +create_clock -period 10.000 -name pcie_sys_clk [get_ports pcie_sys_clk_p] + +# IPbus clock +create_generated_clock -name ipbus_clk -source [get_pins infra/clocks/mmcm/CLKIN1] [get_pins infra/clocks/mmcm/CLKOUT1] + +set lAxiClockSource [get_pins -quiet -hierarchical -filter {NAME =~infra/dma/xdma/*/phy_clk_i/bufg_gt_userclk/O}] +if {[llength $lAxiClockSource] == 0} { + set lAxiClockSource [get_pins -hierarchical -filter {NAME =~infra/dma/xdma/*/phy_clk_i/bufg_gt_coreclk/O}] +} +create_generated_clock -name axi_clk $lAxiClockSource + +# Approx 40MHz clock derived from AXI clock (for tests without external clock source) +#create_generated_clock -name clk_40_pseudo_i [get_pins infra/clocks/mmcm/CLKOUT2] diff --git a/replacements/emp-fwk/components/ttc/firmware/hdl/emp_ttc.vhd b/replacements/emp-fwk/components/ttc/firmware/hdl/emp_ttc.vhd new file mode 100644 index 0000000000000000000000000000000000000000..f40112bbff7ebf380ac551f23cb7ca9dc422afa7 --- /dev/null +++ b/replacements/emp-fwk/components/ttc/firmware/hdl/emp_ttc.vhd @@ -0,0 +1,764 @@ +-- ttc +-- +-- TTC decoder, counters, LHC clock distribution, etc +-- +-- Dave Newbold, June 2013 + +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use ieee.numeric_std.all; + +library unisim; +use unisim.VComponents.all; + +use work.ipbus.all; +use work.ipbus_reg_types.all; +use work.ipbus_decode_emp_ttc.all; +use work.emp_ttc_decl.all; +use work.emp_ttc_utils; + +use work.emp_device_decl; +use work.emp_project_decl.all; + +use work.tcds2_interface_pkg; +use work.tcds2_streams_pkg; +use work.tcds2_link_pkg; + + +------------------------------------------------------------------------------- +entity emp_ttc is + generic ( + ENABLE_LEGACY_TTC : boolean; + ENABLE_TCDS2 : boolean; + EXT_CLK_FREQ : real; + ENABLE_TCDS_RELAY : boolean := false + ); + port ( + -- ipbus clock & rst + clk_ipb : in std_logic; + rst_ipb : in std_logic; + -- IPBus + ipb_in : in ipb_wbus; + ipb_out : out ipb_rbus; + -- 125MHz clock + clk125 : in std_logic; + -- internal pseudo-40MHz clock + clk40ish_in : in std_logic; + -- clock outputs + clk40 : out std_logic; + -- clock domain reset outputs + rst40 : out std_logic; + clk_p : out std_logic; + rst_p : out std_logic; + clks_aux : out std_logic_vector(2 downto 0); + rsts_aux : out std_logic_vector(2 downto 0); + -- Legacy TTC interface + ttc_clk_p : in std_logic; + ttc_clk_n : in std_logic; + ttc_rx_p : in std_logic; + ttc_rx_n : in std_logic; + -- TCDS2 interface + tcds_clk_p : in std_logic; + tcds_clk_n : in std_logic; + tcds_rx_p : in std_logic; + tcds_rx_n : in std_logic; + tcds_tx_p : out std_logic; + tcds_tx_n : out std_logic; + -- KH for FPGA#1<->FPGA#2 TCDS + tcds_secondary_clk_p : in std_logic := '0'; + tcds_secondary_clk_n : in std_logic := '0'; + tcds_secondary_rx_p : in std_logic := '0'; + tcds_secondary_rx_n : in std_logic := '0'; + tcds_secondary_tx_p : out std_logic := '0'; + tcds_secondary_tx_n : out std_logic := '0'; + -- TTC b command output + ttc_cmd : out ttc_cmd_t; + ttc_cmd_dist : out ttc_cmd_t; + -- L1A output + ttc_l1a : out std_logic; + -- L1A qualifier output + ttc_l1a_dist : out std_logic; + dist_lock : in std_logic; + bunch_ctr : out bctr_t; + evt_ctr : in eoctr_t; + orb_ctr : out eoctr_t; + oc_flag : out std_logic; + ec_flag : out std_logic; + -- clock monitoring inputs from MGTs + monclk : in std_logic_vector(3 downto 0); + clk125_o : out std_logic + ); + +end emp_ttc; +------------------------------------------------------------------------------- + +------------------------------------------------------------------------------- +architecture rtl of emp_ttc is + + signal clk40_ext, clk40_ext_legacy, clk40_ext_tcds2 : std_logic; + signal tcds_refclk_b, tcds_refclk_div : std_logic; + signal tcds_secondary_clk, tcds_secondary_clk_b, tcds_secondary_clk_i, tcds_secondary_clk_div : std_logic; + signal clk40_i, rst40_i, clk160s, clk40_div, rsti, rsti_40, clk40_a, rst40_a, clk_p_i, rst_p_i : std_logic; + signal lock, stop : std_logic; + signal clks_aux_i, rsts_aux_i : std_logic_vector(2 downto 0); + signal l1a_ext_legacy, l1a_ext_tcds2 : std_logic; + signal l1a, l1a_ttc, l1a_del, l1a_ext, l1a_pend, cmd_bx, cmd_pend, l1a_issue, cmd_issue : std_logic; + signal cmd, cmd_ttc, cmd_del, cmd_ext_tcds2, cmd_ext_legacy : ttc_cmd_t; + signal psok, bc0_fr, ctr_clr : std_logic; + signal bunch_ctr_i : bctr_t; + signal req_bx : unsigned(bctr_t'range); + signal orb_ctr_i : eoctr_t; + signal clk40_mmcm_sel : std_logic; + + signal stat_mux : ipb_reg_v(0 downto 0); + signal ctrl_mux : ipb_reg_v(0 downto 0); + signal ctrl_ttc2_delay : ipb_reg_v(0 downto 0); + + signal stat_common : ipb_reg_v(5 downto 0); + signal ctrl_common : ipb_reg_v(0 downto 0); + signal stb_common : std_logic_vector(0 downto 0); + + signal bc0_lock : std_logic; + signal ipbw : ipb_wbus_array(N_SLAVES - 1 downto 0); + signal ipbr : ipb_rbus_array(N_SLAVES - 1 downto 0); + + signal clk_40_to_mmcm : std_logic; + signal ttc2_frame_secondary : tcds2_link_pkg.tcds2_frame_t; + signal tts2_frame_secondary : tcds2_link_pkg.tcds2_frame_t; + signal tcds_secondary_clk40_recv : std_logic_vector(0 downto 0); + signal secondary_clk40_ext_tcds2 : std_logic; + signal tcds_secondary_orbit_pulse : std_logic; + + signal channel0_ttc2_dly, channel1_ttc2_dly : tcds2_streams_pkg.tcds2_ttc2; + signal ttc2_delay : std_logic_vector(6 downto 0); -- 7b + type ttc2_array_t is array (50 downto 1) of tcds2_streams_pkg.tcds2_ttc2; + signal channel0_ttc2_array, channel1_ttc2_array : ttc2_array_t; + +begin + +-- ipbus address decode + + 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_ttc(ipb_in.ipb_addr), + ipb_to_slaves => ipbw, + ipb_from_slaves => ipbr + ); + + + -- KH : a stand-alone register for delaying ttc2 on the + -- primary fpga. Maybe the official interface will + -- handle the sync of bc0 etc across the two fpgas. For + -- now the important thing is to have a register where the + -- rst is tied to zero so resetting ipb doesn't interfere + reg_fpga1 : entity work.ipbus_ctrlreg_v + generic map ( + N_CTRL => 1, + N_STAT => 1 + ) + port map ( + clk => clk_ipb, + + -- JRF returned this to rst_ipb, having said that Kristian specifically + -- set this to '0' so we should be prepared to revert this change if + -- it causes issues with TCDS2 on FPFGA2 + reset => rst_ipb, --'0', + + ipbus_in => ipbw(N_SLV_TTC2_DELAY), + ipbus_out => ipbr(N_SLV_TTC2_DELAY), + d => open, + q => ctrl_ttc2_delay, + + stb => open + ); + +-- TTC control registers + + reg_clk40 : entity work.ipbus_ctrlreg_v + generic map ( + N_CTRL => 1, + N_STAT => 1 + ) + port map ( + clk => clk_ipb, + reset => rst_ipb, + ipbus_in => ipbw(N_SLV_MUX), + ipbus_out => ipbr(N_SLV_MUX), + d => stat_mux, + q => ctrl_mux, + stb => open + ); + + stat_mux(0)(0) <= lock; + stat_mux(0)(1) <= stop; + + reg_common : entity work.ipbus_syncreg_v + generic map( + N_CTRL => 1, + N_STAT => 6 + ) + port map( + clk => clk_ipb, + rst => rst_ipb, + ipb_in => ipbw(N_SLV_MASTER_COMMON), + ipb_out => ipbr(N_SLV_MASTER_COMMON), + slv_clk => clk40_a, + d => stat_common, + q => ctrl_common, + stb => stb_common + ); + + stat_mux(0)(2) <= '1' when ENABLE_LEGACY_TTC else '0'; + stat_mux(0)(3) <= '1' when ENABLE_TCDS2 else '0'; + stat_mux(0)(4) <= '1' when ENABLE_TCDS_RELAY else '0'; + + + -- Mux for external clocks + gen_ext_mux : if ENABLE_TCDS2 and ENABLE_LEGACY_TTC generate + + signal sel_pipeline : std_logic_vector(3 downto 0); + + begin + + process (clk_ipb) + begin + if rising_edge(clk_ipb) then + sel_pipeline(0) <= ctrl_mux(0)(2); + sel_pipeline(1) <= sel_pipeline(0); + sel_pipeline(2) <= sel_pipeline(1); + sel_pipeline(3) <= sel_pipeline(2); + end if; + end process; + + clk40mux : BUFGMUX + port map ( + S => sel_pipeline(3), + I0 => clk40_ext_legacy, + I1 => clk40_ext_tcds2, + O => clk40_ext + ); + + elsif ENABLE_TCDS2 generate -- gen_ext_mux + + clk40_ext <= clk40_ext_tcds2; + + else generate -- gen_ext_mux + + clk40_ext <= clk40_ext_legacy; + + end generate gen_ext_mux; + + +-- MMCM for clock multiplication / phase adjustment + + rsti <= rst_ipb or ctrl_common(0)(0); + clk40_mmcm_sel <= ctrl_mux(0)(1) or ctrl_mux(0)(2); + + bufgce_clk_40_rx : bufgce_div + generic map ( + BUFGCE_DIVIDE => 8 + ) + port map ( + i => tcds_refclk_b, + o => clk_40_to_mmcm, + ce => '1', + clr => '0' + ); + + clocks : entity work.emp_ttc_clocks + port map( + clk_40 => clk40_ext, + clk_40pseudo => clk_40_to_mmcm, + clko_40 => clk40_i, + clko_p => clk_p_i, + clko_aux => clks_aux_i, + rsto_40 => rst40_i, + rsto_p => rst_p_i, + rsto_aux => rsts_aux_i, + clko_160s => clk160s, + stopped => stop, + locked => lock, + rst_mmcm => ctrl_mux(0)(0), + rsti => rsti_40, + clksel => clk40_mmcm_sel, + psval => ctrl_common(0)(23 downto 12), + psok => psok, + psen => ctrl_common(0)(24) + ); + + clk40_a <= clk40_i; -- Needed to make sure delta delays line up in simulation! + rst40_a <= rst40_i; + clk40 <= clk40_i; + rst40 <= rst40_i; + clk_p <= clk_p_i; + rst_p <= rst_p_i; + clks_aux <= clks_aux_i; + rsts_aux <= rsts_aux_i; + + +-- TTC protocol decoder + gen_master_tcds2 : if ENABLE_TCDS2 generate + + signal clk125_i, clk125_b : std_logic; + signal tcds_refclk : std_logic; + signal tcds_refclk_i : std_logic; + signal tcds_orbit_pulse : std_logic; + + signal channel0_ttc2, channel1_ttc2 : tcds2_streams_pkg.tcds2_ttc2; + signal tcds2_interface_ctrl : tcds2_interface_pkg.tcds2_interface_ctrl_t; + signal tcds2_interface_stat : tcds2_interface_pkg.tcds2_interface_stat_t; + + attribute dont_touch : string; + attribute dont_touch of tcds2_interface_stat : signal is "true"; + + signal channel0_tts2, channel1_tts2 : tcds2_streams_pkg.tcds2_tts2; + signal secondary_channel0_tts2, secondary_channel1_tts2 : tcds2_streams_pkg.tcds2_tts2; + signal secondary_channel0_ttc2, secondary_channel1_ttc2 : tcds2_streams_pkg.tcds2_ttc2; + signal tcds2_secondary_interface_ctrl : tcds2_interface_pkg.tcds2_interface_ctrl_t; + signal tcds2_secondary_interface_stat : tcds2_interface_pkg.tcds2_interface_stat_t; + + begin + + clk125_o <= clk125_b; + --KH + ttc2_delay <= ctrl_ttc2_delay(0)(6 downto 0); + + ibufds_gt : IBUFDS_GTE4 + port map ( + i => tcds_clk_p, + ib => tcds_clk_n, + o => tcds_refclk, + odiv2 => tcds_refclk_i, + ceb => '0' + ); + + --KH : refclk for fgpa#1/2 tcds + gen_secondary_bufds : if ENABLE_TCDS_RELAY generate + begin + ibufds_gt_2 : IBUFDS_GTE4 + port map ( + i => tcds_secondary_clk_p, + ib => tcds_secondary_clk_n, + o => tcds_secondary_clk, -- to the xcvr + odiv2 => tcds_secondary_clk_i, -- for logic monitoring + ceb => '0' + ); + end generate; + + + ibuf_osc : IBUF + port map ( + O => clk125_i, + I => clk125 + ); + + bufg_osc : BUFG + port map ( + I => clk125_i, + O => clk125_b + ); + + bufg_ref : BUFG_GT + port map ( + i => tcds_refclk_i, + o => tcds_refclk_b, + ce => '1', + clr => '0', + div => "000", + cemask => '1', + clrmask => '0' + ); + + gen_secondary_bufgt : if ENABLE_TCDS_RELAY generate + begin + bufg_ref2 : BUFG_GT + port map ( + i => tcds_secondary_clk_i, + o => tcds_secondary_clk_b, + ce => '1', + clr => '0', + div => "000", + cemask => '1', + clrmask => '0' + ); + end generate; + + + tcds2 : entity work.tcds2_interface_with_mgt + generic map ( + G_MGT_TYPE => emp_ttc_utils.get_tcds2_mgt_type(emp_device_decl.TCDS2_MGT_TYPE), + G_LINK_SPEED => emp_ttc_utils.get_tcds2_link_speed(emp_device_decl.TCDS2_SPEED), + G_INCLUDE_PRBS_LINK_TEST => true + ) + port map ( + ctrl_i => tcds2_interface_ctrl, + stat_o => tcds2_interface_stat, + + clk_sys_125mhz => clk125_b, + + mgt_tx_p_o => tcds_tx_p, + mgt_tx_n_o => tcds_tx_n, + mgt_rx_p_i => tcds_rx_n, + mgt_rx_n_i => tcds_rx_p, + + clk_320_mgt_ref_i => tcds_refclk, + + clk_40_o => clk40_ext_tcds2, + + orbit_o => tcds_orbit_pulse, + + channel0_ttc2_o => channel0_ttc2, + channel0_tts2_i(0) => tcds2_streams_pkg.C_TCDS2_TTS2_VALUE_IGNORED, + channel1_ttc2_o => channel1_ttc2, + channel1_tts2_i(0) => tcds2_streams_pkg.C_TCDS2_TTS2_VALUE_IGNORED + ); + + + gen_relay : if ENABLE_TCDS_RELAY generate + begin + + -- have the streams, make a frame ... + ttc2_frame_builder : entity work.ttc2_frame_builder + generic map ( + G_LINK_SPEED => emp_ttc_utils.get_tcds2_link_speed(emp_device_decl.TCDS2_SPEED) + ) + port map ( + stream0_i => channel0_ttc2, + stream1_i => channel1_ttc2, + + ic_i => tcds2_streams_pkg.C_TCDS2_IC_NULL, + ec_i => tcds2_streams_pkg.C_TCDS2_EC_NULL, + lm_i => tcds2_streams_pkg.C_TCDS2_LM_NULL, + + frame_o => ttc2_frame_secondary + ); + + + -- get the streams from the TTS2 frame + tts2_frame_splitter : entity work.tts2_frame_splitter + generic map ( + G_LINK_SPEED => emp_ttc_utils.get_tcds2_link_speed(emp_device_decl.TCDS2_SPEED) + ) + port map ( + frame_i => tts2_frame_secondary, + + stream0_o => channel0_tts2, + stream1_o => channel1_tts2, + + ic_o => open, + ec_o => open, + lm_o => open + ); + + tcds2_relay : entity work.tcds2_relay + port map ( + clk_ipb => clk_ipb, + rst_ipb => rst_ipb, + ipb_in => ipbw(N_SLV_TCDS2_RELAY), + ipb_out => ipbr(N_SLV_TCDS2_RELAY), + ------------ + clk_gp_125mhz => clk125_b, + clk_40_tx => clk40_a, + clk_40_rx => tcds_secondary_clk40_recv, + mgt_refclk_relay => tcds_secondary_clk, + ------------ + tcds2_relay_tx_p => tcds_secondary_tx_p, + tcds2_relay_tx_n => tcds_secondary_tx_n, + tcds2_relay_rx_p => tcds_secondary_rx_p, + tcds2_relay_rx_n => tcds_secondary_rx_n, + ------------ + ttc2_frame_relay => ttc2_frame_secondary, + ------------ + tts2_frame_relay => tts2_frame_secondary + ); + + end generate; -- ENABLE_TCDS_RELAY + + + -- Delay TTC outputs if running on the first Apollo FPGA, default is no delay + tcds_delay : process(clk40_a) + begin + if rising_edge(clk40_a) then + channel0_ttc2_array <= channel0_ttc2_array(channel0_ttc2_array'high - 1 downto channel0_ttc2_array'low) & channel0_ttc2; + channel1_ttc2_array <= channel1_ttc2_array(channel1_ttc2_array'high - 1 downto channel1_ttc2_array'low) & channel1_ttc2; + end if; + end process; + + with ttc2_delay select channel0_ttc2_dly <= + channel0_ttc2 when b"0000000", + channel0_ttc2_array(to_integer(unsigned(ttc2_delay))) when others; + with ttc2_delay select channel1_ttc2_dly <= + channel1_ttc2 when b"0000000", + channel1_ttc2_array(to_integer(unsigned(ttc2_delay))) when others; + --KH + + process (clk40_a) + begin + if rising_edge(clk40_a) then + -- Only consider a BC0 signal to be received if I see it on both of those channels in the same BX + -- Reason: Improve robustness against bitflips in TTC path for Serenity + -- TODO: Set this behvaviour using SW-settable register in v0.7.0, rather than hardcoding + --KH use the delay if (channel0_ttc2.sync_flags_and_commands(0) = '1') and (channel1_ttc2.sync_flags_and_commands(0) = '1') then + if (channel0_ttc2_dly.sync_flags_and_commands(0) = '1') and (channel1_ttc2_dly.sync_flags_and_commands(0) = '1') then + cmd_ext_tcds2 <= TTC_BCMD_BC0; + else + cmd_ext_tcds2 <= TTC_BCMD_NULL; + end if; + + rsti_40 <= rsti; + end if; + end process; + + l1a_ext_tcds2 <= '0'; + + csr : entity work.ipbus_tcds2_interface_accessor + port map ( + clk_ipb => clk_ipb, + rst_ipb => rst_ipb, + ipb_in => ipbw(N_SLV_MASTER_TCDS2), + ipb_out => ipbr(N_SLV_MASTER_TCDS2), + + ctrl_o => tcds2_interface_ctrl, + stat_i => tcds2_interface_stat + ); + + + else generate -- gen_master_tcds2 + + tcds_tx_p <= '0'; + tcds_tx_n <= '0'; + + tcds_refclk_b <= '0'; + tcds_secondary_clk_b <= '0'; + clk40_ext_tcds2 <= '0'; + cmd_ext_tcds2 <= TTC_BCMD_NULL; + l1a_ext_tcds2 <= '0'; + + ipbr(N_SLV_MASTER_TCDS2).ipb_ack <= '0'; + ipbr(N_SLV_MASTER_TCDS2).ipb_err <= ipbw(N_SLV_MASTER_TCDS2).ipb_strobe; + ipbr(N_SLV_MASTER_TCDS2).ipb_rdata <= (others => '0'); + + end generate gen_master_tcds2; + + + gen_master_legacy : if ENABLE_LEGACY_TTC generate + + signal err_rst : std_logic; + signal sinerr_ctr, dblerr_ctr : std_logic_vector(15 downto 0); + signal stat_legacy : ipb_reg_v(0 downto 0); + signal ctrl_legacy : ipb_reg_v(0 downto 0); + signal stb_legacy : std_logic_vector(0 downto 0); + + begin + + osc_clock : entity work.emp_oscclk + generic map ( + OSC_FREQ => EXT_CLK_FREQ + ) + port map ( + clk_p => ttc_clk_p, + clk_n => ttc_clk_n, + clk40 => clk40_ext_legacy + ); + + reg : entity work.ipbus_syncreg_v + generic map( + N_CTRL => 1, + N_STAT => 1 + ) + port map( + clk => clk_ipb, + rst => rst_ipb, + ipb_in => ipbw(N_SLV_MASTER_LEGACY), + ipb_out => ipbr(N_SLV_MASTER_LEGACY), + slv_clk => clk40_a, + d => stat_legacy, + q => ctrl_legacy, + stb => stb_legacy + ); + + interface : entity work.emp_ttc_legacy + port map( + clk => clk40_a, + rst => rst40_a, + sclk => clk160s, + sclk_locked => lock, + ttc_in_p => ttc_rx_p, + ttc_in_n => ttc_rx_n, + l1a => l1a_ext_legacy, + cmd => cmd_ext_legacy, + sinerr_ctr => sinerr_ctr, + dblerr_ctr => dblerr_ctr, + err_rst => err_rst + ); + + err_rst <= ctrl_legacy(0)(0) and stb_legacy(0); + stat_legacy(0) <= dblerr_ctr & sinerr_ctr; + + + else generate -- gen_master_legacy + + clk40_ext_legacy <= '0'; + cmd_ext_legacy <= TTC_BCMD_NULL; + l1a_ext_legacy <= '0'; + + ipbr(N_SLV_MASTER_LEGACY).ipb_ack <= '0'; + ipbr(N_SLV_MASTER_LEGACY).ipb_err <= ipbw(N_SLV_MASTER_LEGACY).ipb_strobe; + ipbr(N_SLV_MASTER_LEGACY).ipb_rdata <= (others => '0'); + + end generate gen_master_legacy; + + + -- FIXME: Select between each of two external sources and internal + with ctrl_mux(0)(4 downto 3) select cmd_ttc <= + cmd_ext_legacy when "01", + cmd_ext_tcds2 when "10", + TTC_BCMD_NULL when others; + + with ctrl_mux(0)(4 downto 3) select l1a_ttc <= + l1a_ext_legacy when "01", + l1a_ext_tcds2 when "10", + '0' when others; + + -- L1A generation + l1a <= l1a_ttc or l1a_pend; + l1a_issue <= l1a and not l1a_ttc; + + -- TTC command generation + req_bx <= to_unsigned(LHC_BUNCH_COUNT, req_bx'length) - to_unsigned(TTC_DEL, req_bx'length) - 1; + cmd_bx <= '1' when std_logic_vector(req_bx) = bunch_ctr_i else '0'; + + process(cmd_ttc, bc0_fr, cmd_pend, cmd_bx) + begin + cmd_issue <= '0'; + if cmd_ttc /= TTC_BCMD_NULL then + cmd <= cmd_ttc; + elsif bc0_fr = '1' then + cmd <= TTC_BCMD_BC0; + elsif cmd_pend = '1' then + cmd <= ctrl_common(0)(11 downto 4); + cmd_issue <= '1'; + else + cmd <= TTC_BCMD_NULL; + end if; + end process; + + process(clk40_a) + begin + if rising_edge(clk40_a) then + cmd_pend <= (cmd_pend or (ctrl_common(0)(3) and stb_common(0))) and not (rst40_a or cmd_issue); + l1a_pend <= l1a_pend and not (rst40_a or l1a_issue); + ttc_cmd_dist <= cmd; + end if; + end process; + + ttc_l1a_dist <= l1a; + +-- Counters + + ctr_clr <= ctrl_common(0)(2) and stb_common(0); + + ttcctr : entity work.ttc_ctrs + port map( + clk => clk40_a, + rst => rst40_a, + ttc_cmd => cmd, + l1a => l1a, + clr => '0', + en_int_bc0 => ctrl_common(0)(1), + bc0_lock => bc0_lock, + bc0_fr => bc0_fr, + ttc_cmd_out => cmd_del, + l1a_out => l1a_del, + bunch_ctr => bunch_ctr_i, + orb_ctr => orb_ctr_i, + bc0_on_time_count => stat_common(3), + bc0_invalid_count => stat_common(4), + bc0_missing_count => stat_common(5) + ); + + ttc_cmd <= cmd_del; + ttc_l1a <= l1a_del; + bunch_ctr <= bunch_ctr_i; + orb_ctr <= orb_ctr_i; + oc_flag <= '1' when orb_ctr_i(13 downto 0) = (13 downto 0 => '0') and bc0_lock = '1' else '0'; + ec_flag <= '1' when evt_ctr(16 downto 0) = (16 downto 0 => '0') else '0'; + +-- Status reg + stat_common(0)(3 downto 0) <= (l1a_pend or cmd_pend) & psok & dist_lock & bc0_lock; + stat_common(0)(15 downto 4) <= bunch_ctr_i; + stat_common(0)(27 downto 16) <= std_logic_vector(to_unsigned(LHC_BUNCH_COUNT, 12)); + stat_common(1) <= evt_ctr; + stat_common(2) <= orb_ctr_i; + +-- clk40 frequency monitoring + + div : entity work.freq_ctr_div + generic map( + N_CLK => 3 --KH 2 + ) + port map( + clk(0) => clk40_a, + clk(1) => tcds_refclk_b, + clk(2) => tcds_secondary_clk_b, + + clkdiv(0) => clk40_div, + clkdiv(1) => tcds_refclk_div, + clkdiv(2) => tcds_secondary_clk_div + ); + +-- Clock frequency monitor + + ctr : entity work.ipbus_freq_ctr + generic map( + N_CLK => 7 --KH 6 + ) + port map( + clk => clk_ipb, + rst => rst_ipb, + ipb_in => ipbw(N_SLV_FREQ), + ipb_out => ipbr(N_SLV_FREQ), + clkdiv(0) => clk40_div, + clkdiv(1) => tcds_refclk_div, + clkdiv(5 downto 2) => monclk, + clkdiv(6) => tcds_secondary_clk_div + ); + +-- TTC history buffer + + hist : entity work.ttc_history_new + port map( + clk => clk_ipb, + rst => rst_ipb, + ipb_in => ipbw(N_SLV_HIST), + ipb_out => ipbr(N_SLV_HIST), + ttc_clk => clk40_a, + ttc_rst => rst40_a, + ttc_l1a => l1a_del, + ttc_cmd => cmd_del, + ttc_bx => bunch_ctr_i, + ttc_orb => orb_ctr_i, + ttc_evt => evt_ctr + ); + +-- Command counters + + cmdctrs : entity work.ttc_cmd_ctrs + port map( + clk => clk_ipb, + rst => rst_ipb, + ipb_in => ipbw(N_SLV_CMD_CTRS), + ipb_out => ipbr(N_SLV_CMD_CTRS), + ttc_clk => clk40_a, + clr => ctr_clr, + ttc_cmd => cmd_del + ); + +end rtl; +------------------------------------------------------------------------------- diff --git a/top/addr_table/emp_payload.xml b/top/charm/addr_table/emp_payload.xml similarity index 87% rename from top/addr_table/emp_payload.xml rename to top/charm/addr_table/emp_payload.xml index f37df61257a4f900107b812560a831791898e26a..6565fe20613346e07da6f821af442fd0cb72fd54 100644 --- a/top/addr_table/emp_payload.xml +++ b/top/charm/addr_table/emp_payload.xml @@ -1,7 +1,8 @@ <node description="Payload ipbus registers and RAM" fwinfo="endpoint"> - <node id="fe" address="0x0000" description="FE channel select" fwinfo="endpoint;width=0"> - <node id="chan_sel" mask="0x7f"/> + <node id="fe" address="0x0000" 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"/> diff --git a/top/firmware/cfg/top.dep b/top/charm/firmware/cfg/top.dep similarity index 87% rename from top/firmware/cfg/top.dep rename to top/charm/firmware/cfg/top.dep index 2b37dc34fb52519cea4a6724b0c16a47e881702b..fa18f1e2134c88f7ab42329e53cfe65796958dfa 100644 --- a/top/firmware/cfg/top.dep +++ b/top/charm/firmware/cfg/top.dep @@ -1,6 +1,6 @@ include -c histogram:top histogram.dep -include -c dtc:dtc-fe/2S/5G-FEC12 module.dep -include -c dtc:dtc-fe/2S/5G-FEC12 framer.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 @@ -12,7 +12,7 @@ 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_ku15p dc_ku15p_sm1_v1.dep +include -c emp-fwk:boards/serenity/dc_ku15p dc_ku15p_sm1_v2.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 diff --git a/top/firmware/hdl/emp_payload.vhd b/top/charm/firmware/hdl/emp_payload.vhd similarity index 92% rename from top/firmware/hdl/emp_payload.vhd rename to top/charm/firmware/hdl/emp_payload.vhd index 2455f84bd25b63f082daf137b51e2bcdaee1156d..1ff76fb2aeb5777f60d1b1acb922dd7b42074b65 100644 --- a/top/firmware/hdl/emp_payload.vhd +++ b/top/charm/firmware/hdl/emp_payload.vhd @@ -14,7 +14,7 @@ use work.emp_slink_types.all; --- use work.dtc_link_maps.all; use work.front_end_data_types.all; -use work.gbt_module_constants.all; +use work.module_constants.all; use work.mprocessor_constants.all; use work.dtc_constants.all; use work.dtc_data_types.all; @@ -59,7 +59,9 @@ architecture rtl of emp_payload 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 fe_control_registers : ipb_reg_v(0 downto 0); + signal fe_status_registers : 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); @@ -122,20 +124,23 @@ begin ); --==============================-- - fe_channel_ctrl: entity work.ipbus_reg_v + channel_ctrl : entity work.ipbus_ctrlreg_v --==============================-- generic map ( - N_REG => 1 + 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), - q => channel_sel, - qmask => (0 => X"0000007f") + 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 --==============================-- @@ -145,7 +150,7 @@ begin port map ( clk => clk, rst => rst, - sel => channel_sel(0)(6 downto 0), + 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), @@ -205,17 +210,19 @@ begin LinkInterfaceInstance : entity work.LinkInterface --==============================-- generic map ( - module_type => "2S" + 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)), + link_in => d(cDTCInputLinkMap(i).index), daq_read => daq_read(i), global_fcmd => global_fcmd, --- Output Ports --- - link_out => q(cDTCInputLinkMap(i)), + 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), @@ -288,8 +295,8 @@ begin begin if rising_edge(clk_p) then for i in 0 to cNumberOfOutputLinks - 1 loop - q(cDTCOutputLinkMap(i)).valid <= d(cDTCInputLinkMap(i)).valid; - q(cDTCOutputLinkMap(i)).data <= d(cDTCInputLinkMap(i)).data; + 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; end if; @@ -301,14 +308,14 @@ begin LinkMonitorInterfaceInstance : entity work.LinkMonitorInterface --==============================-- generic map ( - N_LINKS => 12 + N_LINKS => 3 ) port map ( --- Input Ports --- clk_p => clk_p, - stubs => stubs(3 downto 0), - headers => header_array(7 downto 0), - header_start => header_start_array(7 downto 0), + stubs => stubs(2 downto 0), + headers => header_array(5 downto 0), + header_start => header_start_array(5 downto 0), --- IPBus Ports --- clk => clk, rst => rst, @@ -345,7 +352,7 @@ begin signal ipb_to_channel : ipb_wbus; signal ipb_from_channel : ipb_rbus; - constant cNumberofInputLinks : integer := 4; + constant cNumberofInputLinks : integer := 3; begin @@ -436,10 +443,10 @@ begin ttc_resync_reset <= mproc_channel_sel(0)(8); srst <= mproc_channel_sel(0)(7) or ttc_oc0; - q(20).valid <= '1'; - q(20).data <= "0000" & std_logic_vector(bunch_counter) & "0000000000000000" & std_logic_vector(orbit_counter); - q(20).start <= '1'; - q(20).strobe <= '1'; + 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'; diff --git a/top/firmware/hdl/emp_project_decl.vhd b/top/charm/firmware/hdl/emp_project_decl.vhd similarity index 76% rename from top/firmware/hdl/emp_project_decl.vhd rename to top/charm/firmware/hdl/emp_project_decl.vhd index c4e9c7c16c0407b76b60156fe5e9fa722d6c91da..561f318b1c79e563f1f9e0f66fdaf583ba9afc21 100644 --- a/top/firmware/hdl/emp_project_decl.vhd +++ b/top/charm/firmware/hdl/emp_project_decl.vhd @@ -34,10 +34,10 @@ package emp_project_decl is -- 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 => (lpgbt, buf, no_fmt, buf, lpgbt), --Bank 228 + -- 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 @@ -60,15 +60,17 @@ 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, lpgbtv0), 1=>(false, true, 0, false, lpgbtv0), 2=>(false, true, 0, false, lpgbtv1), 3=>(false, true, 0, false, lpgbtv0)), - 3 => ( 0=>(false, true, 0, false, lpgbtv0), 1=>(false, true, 0, false, lpgbtv0), 2=>(false, true, 0, false, lpgbtv0), 3=>(false, true, 0, false, lpgbtv0)), + -- 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 := ( - 2 => (FEC5, DATARATE_5G12, PCS), - 3 => (FEC5, DATARATE_5G12, PCS), + -- 0 => (FEC5, DATARATE_5G12, PCS), + 1 => (FEC5, DATARATE_5G12, PCS), + -- 2 => (FEC5, DATARATE_5G12, PCS), others => kDummyRegionLpgbt ); diff --git a/top/charm/firmware/hdl/link_maps.vhd b/top/charm/firmware/hdl/link_maps.vhd new file mode 100644 index 0000000000000000000000000000000000000000..75269aa6132d16e3e4ca58adec6e1f5192d97a0e --- /dev/null +++ b/top/charm/firmware/hdl/link_maps.vhd @@ -0,0 +1,23 @@ +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 := 3; + constant cNumberOfOutputLinks : integer := 3; + + type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of tDTCInputLinkConfig; + constant cDTCInputLinkMap : tDTCInputLinkMap := ( + 0 => (4 , "2S", 5, "CIC2"), + 1 => (5 , "2S", 5, "CIC2"), + 2 => (6 , "2S", 5, "CIC2") + ); + + type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; + constant cDTCOutputLinkMap : tDTCOutputLinkMap := ( + 12, 13, 14 + ); + +end package dtc_link_maps; \ No newline at end of file diff --git a/top/firmware/hdl/link_maps.vhd b/top/firmware/hdl/link_maps.vhd deleted file mode 100644 index d0ca6517cd88b2c93ed21c23763bf86053a0588d..0000000000000000000000000000000000000000 --- a/top/firmware/hdl/link_maps.vhd +++ /dev/null @@ -1,14 +0,0 @@ -library IEEE; -use IEEE.STD_LOGIC_1164.ALL; -use IEEE.NUMERIC_STD.ALL; - -package dtc_link_maps is - constant cNumberOfFEModules : integer := 4; - constant cNumberOfOutputLinks : integer := 4; - - type tDTCInputLinkMap is array(0 to cNumberOfFEModules - 1) of integer; - constant cDTCInputLinkMap : tDTCInputLinkMap := (8, 9, 10, 11); - - type tDTCOutputLinkMap is array(0 to cNumberOfOutputLinks - 1) of integer; - constant cDTCOutputLinkMap : tDTCOutputLinkMap := (16, 17, 18, 19); -end package dtc_link_maps;