Skip to content
Snippets Groups Projects
Commit 49977b38 authored by Thomas Owen James's avatar Thomas Owen James :speech_balloon:
Browse files

kcu1500 relevant files and changes for the multiboard project

parent cad2fb6b
Branches
Tags
1 merge request!59Multiboard kcu1500only
Pipeline #5271400 passed
Showing
with 876 additions and 47 deletions
......@@ -4,61 +4,105 @@ include:
variables:
BUILD_DIR: "build/"
VIVADO_PATH: /opt/Xilinx/Vivado/2022.2
BUILD_IMAGE_TAG: master-859016dc__ipbb2022a
BUILD_IMAGE_TAG: 2022-05-11__ipbb2022c
MP7FW_TAG: v3.2.2
scout-ugmt-quick-check:
scout-kcu1500-ugmt-quick-check:
extends: .quick-check
variables:
SETUP_SCRIPT: makeScoutUgmtProject.sh
SETUP_SCRIPT: kcu1500/makeScoutUgmtProject.sh
BOARD: kcu1500
INPUT_SYSTEM: ugmt
scout-ugmt-synth:
scout-kcu1500-ugmt-synth:
extends: .synth
variables:
BOARD: kcu1500
INPUT_SYSTEM: ugmt
needs:
- job: scout-ugmt-quick-check
- job: scout-kcu1500-ugmt-quick-check
scout-ugmt-impl:
scout-kcu1500-ugmt-impl:
extends: .impl
variables:
BOARD: kcu1500
INPUT_SYSTEM: ugmt
needs:
- job: scout-ugmt-synth
- job: scout-kcu1500-ugmt-synth
scout-ugmt-publish:
scout-kcu1500-ugmt-publish:
extends: .publish
variables:
BOARD: kcu1500
INPUT_SYSTEM: ugmt
needs:
- job: scout-ugmt-impl
- job: scout-kcu1500-ugmt-impl
scout-demux-quick-check:
scout-kcu1500-demux-quick-check:
extends: .quick-check
variables:
SETUP_SCRIPT: makeScoutDemuxProject.sh
SETUP_SCRIPT: kcu1500/makeScoutDemuxProject.sh
BOARD: kcu1500
INPUT_SYSTEM: demux
scout-demux-synth:
scout-kcu1500-demux-synth:
extends: .synth
variables:
BOARD: kcu1500
INPUT_SYSTEM: demux
needs:
- job: scout-demux-quick-check
- job: scout-kcu1500-demux-quick-check
scout-demux-impl:
scout-kcu1500-demux-impl:
extends: .impl
variables:
BOARD: kcu1500
INPUT_SYSTEM: demux
needs:
- job: scout-demux-synth
- job: scout-kcu1500-demux-synth
scout-demux-publish:
scout-kcu1500-demux-publish:
extends: .publish
variables:
BOARD: kcu1500
INPUT_SYSTEM: demux
needs:
- job: scout-demux-impl
- job: scout-kcu1500-demux-impl
scout-kcu1500-bril-quick-check:
extends: .quick-check
variables:
SETUP_SCRIPT: kcu1500/makeScoutBrilProject.sh
BOARD: kcu1500
INPUT_SYSTEM: bril
scout-kcu1500-bril-synth:
extends: .synth
variables:
BOARD: kcu1500
INPUT_SYSTEM: bril
needs:
- job: scout-kcu1500-bril-quick-check
scout-kcu1500-bril-impl:
extends: .impl
variables:
BOARD: kcu1500
INPUT_SYSTEM: bril
needs:
- job: scout-kcu1500-bril-synth
scout-kcu1500-bril-publish:
extends: .publish
variables:
BOARD: kcu1500
INPUT_SYSTEM: bril
needs:
- job: scout-kcu1500-bril-impl
stages:
- check
......
# 40 MHz scouting preprocessor
This board receives trigger data via 4-8 optical links @ 10 Gb/s and provides their data to an attached CPU-based compute system.
This board receives trigger data via optical links @ 10 Gb/s and provides their data to a CPU-based compute system.
## Project structure
The project structure is inspired by the the emp-framework (https://gitlab.cern.ch/p2-xware/firmware/emp-fwk). There are 4 main subdirectories:
* **`projects`**: Structured as projects/$board/$algo. It contains the top-level `.dep` and VHDL files defining entities and parameter values that are unique to a particular project.
* **`boards`**: It contains board-specific source code and constraints (one subdirectory per board). The supported boards employed up to now are:
* `kcu1500`
* `sb852`
* `vcu128`
* **`components`**: It contains the source code of the components instantiated in the projects.
* **`scripts`**: It contains the python/bash/tcl scripts to:
* Build the projects
* Perform operations on the board like loading the bitfile or reset
* Generate the vhdl address table for SCONE
The board-independent scripts are placed in the subsubdirectory `common`, while board specific scripts are placed in `scripts/$BOARD/`
<center>
<img src="./project-structure.png" alt="Drawing" style="width: 400px"/>
</center>
Each individual board/component folder can have the following structure:
| Subdirectory | Contents |
|----------------|----------------------------------------------------------------------------------|
| `addrtab` | Address table `json` files to generate the scouting registers package for SCONE |
| `firmware/hdl` | Firmware source code (e.g. Verilog/VHDL) |
| `firmware/cfg` | `.dep` files and `.tcl` scripts that should be run when creating vivado projects |
| `firmware/ucf` | Constraints files |
## Requirements
The `ipbb` build environment requires Python 2.7, pip, and virtualenv to run. For the firmware build itself Xilinx Vivado (at least 2018.3) and for the simulation Mentor Modelsim 10.6a are used.
`ipbb` version 1.0a0+2022.dev3 is recommended. It must be in the path to excecute the make project and build scripts.
The `ipbb` build environment requires Python 3, pip, and virtualenv to run. For the firmware build itself Xilinx Vivado at least 2019.2.
## Build instructions
First remember to set your BUILD_DIR of choice.
* First remember to set your `BUILD_DIR` of choice.
From the scouting-preprocessor directory level the project can be set up with:
* From the scouting-preprocessor directory level the project can be set up with:
```bash
scripts/generate_addr_table.py scouting-board/firmware/addrtab/address_table.json scouting-board/firmware/hdl/common/decoder_constants_kcu1500.vhd [Demux|uGMT]
scripts/makeScout[Demux|Ugmt]Project.sh
scripts/$BOARD/makeScout[Demux|Ugmt|Bril]Project.sh
```
for the UGMT and Calo demux versions of the code.
for the UGMT, Calo demux, and Bril versions of the code.
The script will also generate the VHDL address table from the board specific json address table by calling `scripts/common/generate_decoder.py`
A bitfile can be generated in the following way:
* A bitfile can be generated in the following way:
```bash
scripts/buildFirmware.sh
......@@ -29,6 +68,15 @@ It can then be found in the folder `build/scouting/proj/scouting_build/package`.
*Note:* If the build scripts find the file `buildToolSetup.sh` in the base directory they will source it. It can be used to set the environment variables required for Vivado and Modelsim. A template (`buildToolSetup_template.sh`) is provided.
## To use simulation testbench
* For KCU1500 simply set `SIM = true` inside your `top_decl.vhd` file and run with the standard `kcu1500_top.vhd` as the simulation top level.
* For SB852 set `SIM = true` inside `top_decl.vhd` and comment in/out a few top level signals that can be found by searching SIMULATION in `sb852_user_top.vhd`. This includes the process runtb. You should now be ready to simulate.
* For VCU128 the simulation is currently in a seperate top file
## Versioning
The scouting boards follow semantic versioning for which the 24 LSBs of the algorithm rev field are used. These are segmented into three eight bit fields, indicating major, minor, patch level.
......@@ -37,4 +85,6 @@ The eight MSBs indicate the scouting board type where the following codes are cu
* `0x0` ... Prototype board until late 2021
* `0x1` ... uGMT inputs
* `0x2` ... Layer-2 Demux inputs
* `0x5` ... uGMT inputs, bril histogramming enabled
* `0x3` ... uGMT inputs, bril histogramming enabled
* `0x4` ... uGT inputs
* `0x5` ... BMTF (twinmux data) inputs
{
"kcu1500_ugmt": {
"driver": "/dev/wz-xdma0_user",
"registers": {
"link_enable": {
"width": 8,
"address": "0x8",
"offset": 0,
"metric": "gauge",
"writable": true,
"exposable": true
},
"reset_board": {
"width": 1,
"address": "0xc",
"offset": 0,
"metric": "gauge",
"writable": true,
"exposable": false
},
"orbits_per_packet": {
"width": 16,
"address": "0x10",
"offset": 0,
"metric": "gauge",
"writable": true,
"exposable": true
},
"rst_i2c": {
"width": 1,
"address": "0x20",
"offset": 0,
"metric": "gauge",
"writable": true,
"exposable": false
},
"str_rd": {
"width": 1,
"address": "0x20",
"offset": 1,
"metric": "gauge",
"writable": true,
"exposable": false
},
"str_wr": {
"width": 1,
"address": "0x20",
"offset": 2,
"metric": "gauge",
"writable": true,
"exposable": false
},
"do_zs": {
"width": 1,
"address": "0x20",
"offset": 3,
"metric": "gauge",
"writable": true,
"exposable": true
},
"enable_autorealign": {
"width": 1,
"address": "0x20",
"offset": 4,
"metric": "gauge",
"writable": true,
"exposable": true
},
"cdr_stable_info": {
"width": 1,
"address": "0x40",
"offset": 0,
"metric": "gauge",
"writable": false,
"exposable": true
},
"rx_byte_is_aligned_info": {
"width": 8,
"address": "0x40",
"offset": 1,
"metric": "gauge",
"writable": false,
"exposable": true
},
"gt_power_good_info": {
"width": 8,
"address": "0x40",
"offset": 9,
"metric": "gauge",
"writable": false,
"exposable": false
},
"gt_tx_reset_done_info": {
"width": 1,
"address": "0x40",
"offset": 17,
"metric": "gauge",
"writable": false,
"exposable": false
},
"gt_rx_reset_done_info": {
"width": 1,
"address": "0x40",
"offset": 18,
"metric": "gauge",
"writable": false,
"exposable": false
},
"tx_pma_reset_done_info": {
"width": 1,
"address": "0x40",
"offset": 19,
"metric": "gauge",
"writable": false,
"exposable": true
},
"rx_pma_reset_done_info": {
"width": 1,
"address": "0x40",
"offset": 20,
"metric": "gauge",
"writable": false,
"exposable": true
},
"gt_reset_tx_pll_datapath_info": {
"width": 1,
"address": "0x40",
"offset": 21,
"metric": "gauge",
"writable": false,
"exposable": false
},
"gt_reset_tx_datapath_info": {
"width": 1,
"address": "0x40",
"offset": 22,
"metric": "gauge",
"writable": false,
"exposable": false
},
"gt_reset_rx_datapath_info": {
"width": 1,
"address": "0x40",
"offset": 23,
"metric": "gauge",
"writable": false,
"exposable": false
},
"init_done_info": {
"width": 1,
"address": "0x40",
"offset": 24,
"metric": "gauge",
"writable": false,
"exposable": false
},
"frequency_input_hertz": {
"width": 32,
"address": "0x44",
"offset": 0,
"metric": "gauge",
"writable": false,
"exposable": true
},
"filler_orbits_seen_orbits": {
"width": 32,
"address": "0x48",
"offset": 0,
"metric": "counter",
"writable": false,
"exposable": true
},
"filler_orbits_dropped_orbits": {
"width": 32,
"address": "0x4c",
"offset": 0,
"metric": "counter",
"writable": false,
"exposable": true
},
"axi_backpressure_seen_info": {
"width": 1,
"address": "0x50",
"offset": 0,
"metric": "gauge",
"writable": false,
"exposable": true
},
"orbit_exceeds_size_info": {
"width": 1,
"address": "0x50",
"offset": 1,
"metric": "gauge",
"writable": false,
"exposable": true
},
"waiting_for_orbit_end_info": {
"width": 1,
"address": "0x50",
"offset": 2,
"metric": "gauge",
"writable": false,
"exposable": false
},
"i2c_value_read_info": {
"width": 8,
"address": "0x50",
"offset": 3,
"metric": "gauge",
"writable": false,
"exposable": true
},
"autorealigns_total": {
"width": 32,
"address": "0x54",
"offset": 0,
"metric": "counter",
"writable": false,
"exposable": true
},
"orbit_length_bxs": {
"width": 32,
"address": "0x58",
"offset": 0,
"metric": "gauge",
"writable": false,
"exposable": true
},
"algo_version": {
"width": 24,
"address": "0x5c",
"offset": 0,
"metric": "gauge",
"writable": false,
"exposable": true
},
"fw_type": {
"width": 8,
"address": "0x5c",
"offset": 24,
"metric": "gauge",
"writable": false,
"exposable": true
},
"rst_link": {
"width": 1,
"address": "0x64",
"offset": 0,
"metric": "gauge",
"writable": false,
"exposable": true
},
"rst_aligner": {
"width": 1,
"address": "0x64",
"offset": 1,
"metric": "gauge",
"writable": false,
"exposable": true
},
"init_retry_ctr": {
"width": 1,
"address": "0x64",
"offset": 2,
"metric": "gauge",
"writable": false,
"exposable": true
}
}
}
}
set_property -name "target_language" -value "VHDL" -objects [current_project]
set_property -name "steps.place_design.tcl.pre" -value "[file normalize "../../src/scouting-preprocessor/scouting-board/firmware/cfg/pre-place.tcl"]" -objects [get_runs impl_1]
set_property -name "steps.place_design.tcl.pre" -value "[file normalize "../../src/scouting-preprocessor/boards/kcu1500/firmware/cfg/pre-place.tcl"]" -objects [get_runs impl_1]
set_property STEPS.OPT_DESIGN.ARGS.DIRECTIVE ExploreWithRemap [get_runs impl_1]
set_property STEPS.PLACE_DESIGN.ARGS.DIRECTIVE ExtraNetDelay_high [get_runs impl_1]
set_property STEPS.PHYS_OPT_DESIGN.IS_ENABLED true [get_runs impl_1]
......
@top_entity = "top"
@device_name = "xcku115"
@device_package = "-flvb2104"
@device_speed = "-2-e"
@board_part = "xilinx.com:kcu1500:part0:1.2"
@dsa_board_id = "kcu1500"
setup settings_kcu1500.tcl
src --cd ../ucf constraints.tcl
src -c boards/kcu1500 xilinx_pcie_xdma_ref_board.xdc
src --vhdl2008 -c components/top kcu1500_top.vhd
src --vhdl2008 -c components scouting_algo.vhd
src --vhdl2008 -c components/data_reduction filled_bx_trailer_generator.vhd
src --vhdl2008 -c components/axi_register_bank_interface axi_register_interface_wrapper.vhd
src -c components/axi_register_bank_interface axi_register_interface.sv
src --vhdl2008 -c components/infra reset.vhd
src --vhdl2008 -c components/infra inputs.vhd
src --vhdl2008 -c components/infra comma_gap_cleaner.vhd
src --vhdl2008 -c components/infra bx_aware_aligner.vhd
src --vhdl2008 -c components/infra cross_to_slr1_delay_line.vhd
src --vhdl2008 -c components/debug/cdc debug_signals_axiClkToI2cClk.vhd
src --vhdl2008 -c components/debug/cdc debug_signals_axiClkToLinkClk.vhd
src --vhdl2008 -c components/debug/cdc debug_signals_linkClkToAxiClk.vhd
src --vhdl2008 -c components/debug/cdc debug_signals_freeClkToAxiClk.vhd
src --vhdl2008 -c components/infra fifo_filler.vhd
src --vhdl2008 -c components/infra synchroniser.vhd
src --vhdl2008 -c components/infra cdc_single.vhd
src --vhdl2008 -c components/infra cdc_array.vhd
src --vhdl2008 -c components/infra auto_realign_controller.vhd
src --vhdl2008 -c components/infra freq_meas.vhd
src --vhdl2008 -c components/infra bx_counter.vhd
src --vhdl2008 -c components/infra check_crc.vhd
src -c mp7:components/mp7_links crc/outputlogic/outputlogic_32b_crc.vhd
# Links
src -c components/infra/mgts gtwizard_ultrascale_0_example_top.xdc
src -c components/infra/mgts gtwizard_ultrascale_0_example_bit_sync.v
src -c components/infra/mgts gtwizard_ultrascale_0_example_init.v
src -c components/infra/mgts gtwizard_ultrascale_0_example_reset_sync.v
src -c components/infra/mgts gtwizard_ultrascale_0_example_top.v
src -c components/infra/mgts gtwizard_ultrascale_0_example_wrapper.v
src -c components/infra/mgts gtwizard_ultrascale_0_example_gtwiz_userclk_*
src -c components/infra/mgts gtwizard_ultrascale_0.xci
# I2C
src --vhdl2008 -c components/i2c i2c_driver.vhd
src --vhdl2008 -c components/i2c i2c_master.vhd
# DMA
src -c components/dma/xdma xilinx_dma_pcie_ep.sv
src -c components/dma/xdma xdma_app.v
src -c components/dma/xdma xdma_0_tandem.xdc
src -c components/dma/xdma xdma_0.xci
src -c components/dma/blk_mem_gen blk_mem_gen_0.xci
# FIFO
src -c components/fifo/axi_fifo_256x32k axi_fifo_256x32k_generator.xci
src -c components/fifo/axi_packet_fifo_256x32k axi_packet_fifo_256x32k_generator.xci
src -c components/fifo/axi_distfifo_256x16 axi_distfifo_256x16.xci
src -c components/fifo/axi_packet_fifo_2kx4k axi_packet_fifo_2kx4k_generator.xci
src -c components/aligner_fifo aligner_fifo.xci
src -c components/fifo/header_fifo header_fifo.xci
# ILA
src -c components/debug/ila ila_0.xci
# IBERT
src -c components/debug/ibert gtwizard_ultrascale_0_in_system_ibert_0.xci
src --vhdl2008 -c components datatypes.vhd
src --vhdl2008 -c boards/kcu1500 decoder_constants_kcu1500.vhd
# Only used in Simulation
src --vhdl2008 -c components test_file_io.vhd
......@@ -9,21 +9,21 @@ set_property HD.TANDEM 1 [get_cells dbg_hub/inst/BSCANID.u_xsdbm_id/SWITCH_N_EXT
add_cells_to_pblock [get_pblocks -of_object [get_sites CONFIG_SITE_X0Y0]] [get_cells dbg_hub/inst/BSCANID.u_xsdbm_id/SWITCH_N_EXT_BSCAN.bscan_inst/SERIES7_BSCAN.bscan_inst]
# For replicated logic:
set_property HD.TANDEM 1 [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_4_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_4_LOPT_REMAP}]
set_property HD.TANDEM 1 [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_3_LOPT_REMAP_1}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_3_LOPT_REMAP_1}]
set_property HD.TANDEM 1 [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_3_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_3_LOPT_REMAP}]
set_property HD.TANDEM 1 [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_2_LOPT_REMAP_1}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_2_LOPT_REMAP_1}]
set_property HD.TANDEM 1 [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_2_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_2_LOPT_REMAP}]
set_property HD.TANDEM 1 [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_1_LOPT_REMAP_1}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_1_LOPT_REMAP_1}]
set_property HD.TANDEM 1 [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_1_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_1_LOPT_REMAP}]
set_property HD.TANDEM 1 [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_0_LOPT_REMAP_1}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_0_LOPT_REMAP_1}]
set_property HD.TANDEM 1 [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_0_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_0_LOPT_REMAP}]
set_property HD.TANDEM 1 [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_4_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_4_LOPT_REMAP}]
set_property HD.TANDEM 1 [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_3_LOPT_REMAP_1}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_3_LOPT_REMAP_1}]
set_property HD.TANDEM 1 [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_3_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_3_LOPT_REMAP}]
set_property HD.TANDEM 1 [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_2_LOPT_REMAP_1}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_2_LOPT_REMAP_1}]
set_property HD.TANDEM 1 [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_2_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_2_LOPT_REMAP}]
set_property HD.TANDEM 1 [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_1_LOPT_REMAP_1}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_1_LOPT_REMAP_1}]
set_property HD.TANDEM 1 [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_1_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_1_LOPT_REMAP}]
set_property HD.TANDEM 1 [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_0_LOPT_REMAP_1}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_0_LOPT_REMAP_1}]
set_property HD.TANDEM 1 [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_0_LOPT_REMAP}]
set_property HD.TANDEM_IP_PBLOCK Stage1_Config_IO [get_cells {dma_gen.dma_engine_i/xdma_0_i/inst/pcie3_ip_i/U0/i_0_LOPT_REMAP}]
set_property top top [get_filesets sim_1]
set_property top_lib xil_defaultlib [get_filesets sim_1]
set_property USER_SLR_ASSIGNMENT SLR1 [get_cells -hierarchical -filter {NAME =~ *fifo_filler*}]
set_property USER_SLR_ASSIGNMENT SLR1 [get_cells -hierarchical -filter {NAME =~ *fifo_filler* || NAME=~ *bril_histogram_top_async*}]
set_property USER_SLR_ASSIGNMENT SLR0 [get_cells -hierarchical -filter {NAME =~ *dma_engine* || NAME=~ *algo*}]
# ILA constraints
##
......
......@@ -14,7 +14,7 @@ workflow:
- source ${VIVADO_PATH}/settings64.sh
script:
- ./scripts/${SETUP_SCRIPT}
- cd $BUILD_DIR
- cd ${BUILD_DIR}
- pushd scouting/proj/scouting_build/
- ipbb vivado project # Build the project
- ipbb vivado check-syntax
......@@ -22,7 +22,9 @@ workflow:
name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME////-}"
paths:
- $BUILD_DIR
- scouting-board/firmware/hdl/common/decoder_constants_kcu1500.vhd
- boards/${BOARD}/firmware/hdl/decoder_constants_${BOARD}.vhd
except:
- tags
tags:
- vivado
- docker
......@@ -40,7 +42,8 @@ workflow:
artifacts:
name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME////-}"
paths:
- $BUILD_DIR
- ${BUILD_DIR}
- boards/${BOARD}/firmware/hdl/decoder_constants_${BOARD}.vhd
tags:
- vivado
- docker
......@@ -51,19 +54,19 @@ workflow:
before_script:
- source ${VIVADO_PATH}/settings64.sh
script:
- cd $BUILD_DIR
- cd ${BUILD_DIR}
- cd scouting/proj/scouting_build/
- ipbb vivado --loglevel warn impl -j4
- ipbb vivado --loglevel warn bitfile debug-probes
- echo "Done with bitfile generation."
- cp ../../../../scouting-board/firmware/addrtab/address_table_${INPUT_SYSTEM}.json products/address_table.json
- cp ../../../../boards/${BOARD}/addrtab/address_table_${INPUT_SYSTEM}.json products/address_table.json
- cp ../../../../scripts/load_kcu1500_bitfile.sh products/.
- cp ../../../../scripts/vivado_load_bitfile.tcl products/.
- cp ../../../../scripts/kcu1500/vivado_load_bitfile.tcl products/.
- mv products ../../../../.
artifacts:
name: "${CI_JOB_NAME}_${CI_COMMIT_REF_NAME////-}"
paths:
- $BUILD_DIR/scouting/proj/scouting_build
- ${BUILD_DIR}/scouting/proj/scouting_build
- products
when: always
expire_in: 8 year
......
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.NUMERIC_STD_UNSIGNED.ALL;
use work.datatypes.all;
use work.top_decl.all;
library unisim;
use unisim.vcomponents.all;
entity scout_bril is
generic (
NSTREAMS : integer
);
port (
clk : in std_logic;
rst : in std_logic;
d : in adata(NSTREAMS-1 downto 0);
d_ctrl : in acontrol;
q : out adata(NSTREAMS-1 downto 0);
q_ctrl : out acontrol;
new_nibble_d : out std_logic;
mu_count_out : out std_logic_vector(5 downto 0);
bx_id_out : out std_logic_vector(12 downto 0);
d_valid_bril_o : out std_logic;
bril_fifo_data_valid_o :out std_logic;
trigger_bril_readout_i : in std_logic
);
end scout_bril;
architecture Behavioral of scout_bril is
-- For Bril
signal lhc_fill : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal cms_run : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal lumi_section : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal lumi_nibble : std_logic_vector(31 downto 0) := "00000000000000000000000000000000";
signal d_valid_bril : std_logic :='0';
signal orbit_id, orbit_id_buf : std_logic_vector(31 downto 0); -- called iteration id in bril code
signal orbit_id_prev : std_logic_vector(31 downto 0); -- called iteration id in bril code
signal bx_id : std_logic_vector(12 downto 0); -- called bin_id in bril code
signal bx_id_prev : std_logic_vector(12 downto 0); -- called bin_id in bril code
signal mu_count : std_logic_vector(5 downto 0); -- called increment in bril
-- one clock buffer versions
signal orbit_id_d : std_logic_vector(31 downto 0); -- called iteration id in bril code
signal bx_id_d : std_logic_vector(12 downto 0); -- called bin_id in bril code
signal mu_count_d : std_logic_vector(5 downto 0); -- called increment in bril code
signal trigger_bril_readout, trigger_bril_readout_d, trigger_bril_readout_sim, rising_bril_trigger : std_logic := '0';
signal new_nibble : std_logic := '0';
signal d_valid_bril_d : std_logic := '0';
--bril histo outputs
signal bril_fifo_data : std_logic_vector(31 downto 0);
signal bril_fifo_data_valid : std_logic;
signal bril_init_done : std_logic;
signal bril_fifo_rd_en : std_logic := '0';
signal bril_fifo_empty : std_logic;
signal bril_words_cnt : std_logic_vector(31 downto 0);
signal bril_header : adata(8 downto 0);
signal q_bril_calc : adata(4*N_REGION -1 downto 0);
signal q_ctrl_bril_calc : acontrol;
signal q_int : adata(NSTREAMS-1 downto 0);
signal q_ctrl_int : acontrol;
begin
trigger_bril_readout <= trigger_bril_readout_i or trigger_bril_readout_sim;
rising_bril_trigger_detect : process (clk,trigger_bril_readout)
begin
if rising_edge(clk) then
if (trigger_bril_readout = '1') then
trigger_bril_readout_d <= '0';
else
-- delay input by 1 clock
trigger_bril_readout_d <= trigger_bril_readout;
-- detect rising edge
rising_bril_trigger <= trigger_bril_readout and (not trigger_bril_readout_d);
end if;
end if;
end process;
scout_bril_calc : entity work.scout_bril_calc
generic map (
NSTREAMS => 4* N_REGION)
port map (
clk => clk,
rst => rst,
d => d,
d_ctrl => d_ctrl,
q => q_bril_calc,
q_ctrl => q_ctrl_bril_calc,
mu_count_o => mu_count,
bx_id_o => bx_id,
orbit_id_o => orbit_id,
q_valid_o => d_valid_bril
);
mu_count_out <= mu_count_d;
orbit_id_buf <= orbit_id;
bx_id_out <= bx_id_d;
d_valid_bril_o <= d_valid_bril;
bril_fifo_data_valid_o <= bril_fifo_data_valid;
--for sim
gen_new_nibble: if SIM = true generate
new_nibble <= '1' after 500 us;
else generate
new_nibble <= '1' when d_valid_bril = '1' and orbit_id(13 downto 0) = 0 and orbit_id_prev(13 downto 0) > 0 and rst /= '1' else '0';
end generate;
luminibblecheck: process(clk) is
variable lumi_orbit : integer range 0 to 16383;
begin
if rising_edge(clk) then
-- variable assign
lumi_orbit := to_integer(unsigned(orbit_id(13 downto 0)));
--
if rst = '1' then
orbit_id_prev <= (others => '0');
bx_id_prev <= (others => '0');
mu_count_d <= (others => '0');
orbit_id_d <= (others => '0');
bx_id_d <= (others => '0');
d_valid_bril_d <= '0';
else
if d_valid_bril = '1' then
bx_id_prev <= bx_id;
orbit_id_prev <= orbit_id;
orbit_id_d <= std_logic_vector(to_unsigned(lumi_orbit, orbit_id'length));
bx_id_d <= bx_id;
mu_count_d <= mu_count;
d_valid_bril_d <= '1';
else
orbit_id_d <= (others => '0');
bx_id_d <= (others => '0');
mu_count_d <= (others => '0');
d_valid_bril_d <= '0';
end if;
end if;
end if;
end process luminibblecheck;
new_nibble_d <= new_nibble OR rising_bril_trigger;
bril_histogram_top_async_inst: entity work.bril_histogram_top_async
generic map (
-- identification of the histogram
HISTOGRAM_TYPE => 0,
HISTOGRAM_ID => 0,
-- extenral new histogram
USE_EXTERNAL_NEW_HISTOGRAM => true,
-- histogram parameters
NUMBER_OF_BINS => 3564, --3564 bx per orbit
COUNTER_WIDTH => 16, --per BX per lumi nibble count
INCREMENT_WIDTH => 6, --per BX
-- memory
ORBIT_BX_COUNTER_WIDTH => 16,
-- accumulation parameters
NUMBER_OF_UNITS => 1,
UNIT_INCREMENT_WIDTH => 6,
NUMBER_OF_UNITS_PER_ACCUMULATION_STAGE => 4,
UNIT_ERROR_COUNTER_WIDTH => 3,
CHECK_ERRORS => false,
STORE_ERRORS => false
)
port map(
-- core signals
async_reset_i => rst,
clk_i => clk,
-- tcds data
lhc_fill_i => x"00000000",
cms_run_i => x"00000000",
lumi_section_i => x"00000000",
lumi_nibble_i => x"00000000",
-- new histogram
new_histogram_ext_i => new_nibble_d,
-- counter signals
valid_i => d_valid_bril_d,
iteration_id_i(12 downto 0) => orbit_id_d(12 downto 0),
iteration_id_i(15 downto 13) => (others => '0'),
iteration_counter_i => orbit_id_buf(15 downto 0),
bin_id_i(12 downto 0) => bx_id_d,
bin_id_i(15 downto 13) => (others => '0'),
increment_i => mu_count_d,
error_i => (others => '0'),
mask_i => (others => '0'),
-- fifo interface
fifo_rd_clk_i => clk,
fifo_rd_en_i => bril_fifo_rd_en,
fifo_empty_o => bril_fifo_empty,
fifo_words_cnt_o => bril_words_cnt,
fifo_data_o => bril_fifo_data,
fifo_data_valid_o => bril_fifo_data_valid,
-- module is ready
init_done_o => bril_init_done
);
-- formats the bril histogram output such that it can be sent out over the DMA one word each frame, with a counter for the Nth word in the histogram
brilpack: process(clk) is
variable histoword_counter : integer range 0 to 4000;
begin
if rising_edge(clk) then
if rst = '1' then
-- reset handling
bril_fifo_rd_en <= '0';
histoword_counter := 0;
bril_fifo_rd_en <= '0';
for i in bril_header'range loop
bril_header(i) <= x"00000000";
end loop;
else
--logic
if bril_fifo_data_valid = '0' then
histoword_counter := 0;
end if;
if bril_init_done = '1' and bril_fifo_data_valid = '1' and bril_fifo_empty = '0' then
if bril_fifo_rd_en = '0' then -- i.e first clock of being ready to read data
bril_fifo_rd_en <= '1';
q_int(0) <= x"00000000";
for i in 4*N_REGION -1 downto 1 loop
q_int(i) <= (others => '0');
end loop;
else
bril_fifo_rd_en <= '0';
end if;
else
bril_fifo_rd_en <= '0';
end if;
if bril_fifo_rd_en = '1' then --i.e not the first clock of being ready to read data
for i in 4*N_REGION -1 downto 2 loop
q_int(i) <= (others => '0');
end loop;
q_int(0) <= bril_fifo_data;
q_int(1) <= std_logic_vector(to_unsigned(histoword_counter, 32));
q_ctrl_int <= (valid => '1', strobe => '1', bx_start => '0', last => '0', header => '0', bx_counter => 1);
histoword_counter := histoword_counter + 1;
else
for i in 4*N_REGION -1 downto 0 loop
q_int(i) <= (others => '0');
q_ctrl_int <= (valid => '0', strobe => '0', bx_start => '0', last => '0', header => '0', bx_counter => 1);
end loop;
end if;
end if;
end if;
end process brilpack;
q <= q_int;
q_ctrl <= q_ctrl_int;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use work.datatypes.all;
entity scout_bril_calc is
generic (
NSTREAMS : integer
);
port (
clk : in std_logic;
rst : in std_logic;
d : in adata(NSTREAMS-1 downto 0);
d_ctrl : in acontrol;
q : out adata(NSTREAMS-1 downto 0);
q_ctrl : out acontrol;
mu_count_o : out std_logic_vector(5 downto 0);
bx_id_o : out std_logic_vector(12 downto 0);
orbit_id_o : out std_logic_vector(31 downto 0);
q_valid_o : out std_logic
);
end scout_bril_calc;
architecture Behavioral of scout_bril_calc is
signal d1, d2, d3, d4, d5, d6 : adata(NSTREAMS-1 downto 0);
signal d_ctrl1, d_ctrl2, d_ctrl3, d_ctrl4, d_ctrl5, d_ctrl6 : acontrol;
begin
count_mu : process(clk, rst) is
variable mu_counter : integer range 0 to 255;
variable q_valid : boolean;
begin
if rst = '1' then
d1 <= (others => AWORD_NULL); d_ctrl1 <=('0', '0', '0', '0', '0', 1);
d2 <= (others => AWORD_NULL); d_ctrl2 <=('0', '0', '0', '0', '0', 1);
d3 <= (others => AWORD_NULL); d_ctrl3 <=('0', '0', '0', '0', '0', 1);
d4 <= (others => AWORD_NULL); d_ctrl4 <=('0', '0', '0', '0', '0', 1);
d5 <= (others => AWORD_NULL); d_ctrl5 <=('0', '0', '0', '0', '0', 1);
d6 <= (others => AWORD_NULL); d_ctrl6 <=('0', '0', '0', '0', '0', 1);
mu_counter := 0;
q_valid := false;
else
if clk'event and clk = '1' then
d1 <= d; d_ctrl1 <= d_ctrl;
d2 <= d1; d_ctrl2 <= d_ctrl1;
d3 <= d2; d_ctrl3 <= d_ctrl2;
d4 <= d3; d_ctrl4 <= d_ctrl3;
d5 <= d4; d_ctrl5 <= d_ctrl4;
d6 <= d5; d_ctrl6 <= d_ctrl5;
q <= d5; q_ctrl <= d_ctrl5;
q_valid := false;
if d_ctrl5.valid ='1' and d_ctrl5.strobe='1' and d_ctrl5.bx_start = '1' then
mu_counter := 0;
bx_id_o <= std_logic_vector(to_unsigned(d_ctrl4.bx_counter, bx_id_o'length));
orbit_id_o <= d5(0)(31 downto 0);
for i in d'range loop
if d3(i)(18 downto 10) /= "000000000" then -- pt is in bits 18 downto 10
mu_counter := mu_counter + 1;
end if;
if d1(i)(18 downto 10) /= "000000000" then -- d3 has 1st word of 1st muon, d1 has 1st word of 2nd muon
mu_counter := mu_counter + 1;
end if;
end loop;
q_valid := true;
end if;
mu_count_o <= std_logic_vector(to_unsigned(mu_counter, mu_count_o'length));
q_valid_o <= '1' when q_valid else '0';
end if;
end if;
end process count_mu;
end Behavioral;
......@@ -26,11 +26,10 @@ architecture Behavioral of filled_bx_trailer_generator is
begin
filled_bxs(filled_bxs'high downto 3565) <= (others => '0'); -- Fill remaining space in last frame with zeros.
gen_trailer : process (clk, rst) is
variable bx_counter : integer range 1 to 3564; -- 3564 BXs per orbit
begin
filled_bxs(filled_bxs'high downto 3565) <= (others => '0'); -- Fill remaining space in last frame with zeros.
if rst = '1' then
filled_bxs(3564 downto 1) <= (others => '0'); -- Zero filled_bx field at reset.
elsif rising_edge(clk) then
......
......@@ -39,11 +39,22 @@ begin
d_ctrl;
suppress_calib_sequence : process (clk, rst) is
variable warning_test_enable_received : boolean;
variable calib_sequence_in_this_orbit : boolean;
begin
if rising_edge(clk) then
-- We don't want to start suppressing immediately when we recieve the BGo in the header, so we store receipt.
if d_ctrl.header = '1' then
if d(0)(BGO_WARNING_TEST_ENABLE) = '1' then -- TODO: This should probably be per channel?
warning_test_enable_received := True;
else
warning_test_enable_received := False;
end if;
end if;
-- Once we enter the new orbit we check if we received WarningTestEnable previously. If so we suppress in this orbit.
if d_ctrl.bx_counter = 1 then
if warning_test_enable_received then
calib_sequence_in_this_orbit := True;
else
calib_sequence_in_this_orbit := False;
......@@ -57,9 +68,6 @@ begin
q_suppressed_ctrl.bx_start <= d_ctrl.bx_start;
q_suppressed_ctrl.header <= d_ctrl.header;
q_suppressed_ctrl.bx_counter <= d_ctrl.bx_counter;
if d_ctrl.bx_counter = ORBIT_LENGTH then -- The calibration sequence ends with the ultimate BX of the orbit.
calib_sequence_in_this_orbit := False;
end if;
else
q_suppressed_ctrl <= d_ctrl;
end if;
......@@ -67,3 +75,4 @@ begin
end if;
end process;
end Behavioral;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment