diff --git a/.github/workflows/formal-regressions.yml b/.github/workflows/formal-regressions.yml index 55779bd..bfcb819 100644 --- a/.github/workflows/formal-regressions.yml +++ b/.github/workflows/formal-regressions.yml @@ -6,7 +6,7 @@ on: jobs: formal-verification: name: Run Formal Regressions - runs-on: sanity-builder + runs-on: engineering-eda environment: ci steps: diff --git a/.github/workflows/regressions.yml b/.github/workflows/regressions.yml index 3c86481..72b37fe 100644 --- a/.github/workflows/regressions.yml +++ b/.github/workflows/regressions.yml @@ -8,7 +8,7 @@ on: jobs: # Detect which files have changed to determine which jobs to run changes: - runs-on: sanity-builder + runs-on: engineering-eda environment: ci outputs: lint: ${{ steps.changes.outputs.lint }} @@ -26,7 +26,7 @@ jobs: lint: - 'lint_stubs/**' - 'src/**' - - 'src.f' + - 'src_common.f' - 'lint.f' - 'lib/**' - 'lint_waivers.vlt' @@ -44,7 +44,7 @@ jobs: - 'tb/**' - 'vendors/**' - 'sim.f' - - 'src.f' + - 'src_common.f' - 'Makefile' - 'scripts/**' - 'config.json' @@ -53,7 +53,7 @@ jobs: - 'lib/**' - 'example_designs/**' - 'vendors/**' - - 'src.f' + - 'src_common.f' - 'Makefile' - 'scripts/**' - 'config.json' @@ -61,7 +61,7 @@ jobs: - 'src/**' - 'lib/**' - 'vendors/**' - - 'src.f' + - 'src_common.f' - 'uvm/**' - 'Makefile' - 'scripts/**' @@ -73,7 +73,7 @@ jobs: static-checks: needs: changes if: needs.changes.outputs.lint == 'true' || needs.changes.outputs.format == 'true' - runs-on: sanity-builder + runs-on: engineering-eda steps: - name: Checkout repo uses: actions/checkout@v4 @@ -92,7 +92,7 @@ jobs: always() && needs.changes.outputs.simulation == 'true' && (needs.static-checks.result == 'success' || needs.static-checks.result == 'skipped') - runs-on: sanity-builder + runs-on: engineering-eda steps: - name: Checkout repo uses: actions/checkout@v4 @@ -106,7 +106,7 @@ jobs: always() && needs.changes.outputs.simulation == 'true' && (needs.static-checks.result == 'success' || needs.static-checks.result == 'skipped') - runs-on: sanity-builder + runs-on: engineering-eda steps: - name: Checkout repo uses: actions/checkout@v4 @@ -119,7 +119,7 @@ jobs: always() && needs.changes.outputs.uvm == 'true' && (needs.static-checks.result == 'success' || needs.static-checks.result == 'skipped') - runs-on: sanity-builder + runs-on: engineering-eda steps: - name: Checkout repo uses: actions/checkout@v4 @@ -133,7 +133,7 @@ jobs: always() && needs.changes.outputs.synthesis == 'true' && (needs.static-checks.result == 'success' || needs.static-checks.result == 'skipped') - runs-on: sanity-builder + runs-on: engineering-eda steps: - name: Checkout repo uses: actions/checkout@v4 diff --git a/.github/workflows/uvm_regressions.yml b/.github/workflows/uvm_regressions.yml index 22e3c0e..e6e3523 100644 --- a/.github/workflows/uvm_regressions.yml +++ b/.github/workflows/uvm_regressions.yml @@ -5,7 +5,7 @@ on: jobs: uvm-regression: - runs-on: sanity-builder + runs-on: engineering-eda environment: ci steps: - name: Checkout repo diff --git a/.gitignore b/.gitignore index dafbd32..4d04a57 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,10 @@ .Xil/ scripts/__pycache__/ run/ -xci/ +generated_ip/ tb/generated_sim_files/ tb/compiled_simlib/ -xci.f +generated_ip.f generated_sim.f src/qeciphy_build_cfg_pkg.sv tb/qeciphy_sim_cfg_pkg.sv diff --git a/INTEGRATION.md b/INTEGRATION.md index dcec4e0..006e541 100644 --- a/INTEGRATION.md +++ b/INTEGRATION.md @@ -26,13 +26,14 @@ QECIPHY provides a simple AXI4-Stream interface that abstracts away all physical ### Hardware Requirements -- Xilinx FPGA with GTX, GTH, or GTY transceivers +- Xilinx FPGA with GTX, GTH, or GTY transceivers, or Altera FPGA with E-Tile transceivers - Appropriate reference clock source - Differential signal routing between FPGAs ### Software Requirements -- Vivado 2024.1 or later +- Vivado 2024.1 or later (Xilinx profiles) +- Quartus Prime Pro 25.3.1 (Altera profiles) - Python 3.8+ (for build scripts) - Make (for build automation) @@ -57,8 +58,9 @@ Check if your hardware platform matches one of the existing profiles in `config. - **zcu106**: Zynq UltraScale with GTH transceivers - **kasliSoC**: 7-series with GTX transceivers -If your platform is not listed, create a new profile in `config.json`: +If your platform is not listed, create a new profile in `config.json`. Examples for both vendors: +**Xilinx (GTY example):** ```json { "profiles": { @@ -91,17 +93,56 @@ If your platform is not listed, create a new profile in `config.json`: } ``` +**Altera (E-Tile example):** +```json +{ + "profiles": { + "your-platform": { + "device": { + "part": "AGFB014R24B2E2V", + "vendor": "altera", + "family": "Agilex 7" + }, + "variant": "ETILE", + "rclk_freq": "156.25", + "transceiver": { + "line_rate_gbps": "10.3125" + }, + "synth": { + "top": "qeciphy_syn_wrapper", + "filelists": [ + "example_designs//src.f" + ], + "constraints": [ + "example_designs//syn/clock_constraints.sdc", + "example_designs//syn/pin_assignments.tcl" + ] + } + } + } +} +``` + **Profile Parameters:** - `device.part`: Your FPGA part number +- `device.family`: Device family (Altera only) - `board`: Xilinx board file (optional) -- `variant`: Transceiver type (GTX/GTH/GTY) -- `fclk_freq`: Transceiver DRP clock frequency in MHz +- `variant`: Transceiver type (GTX/GTH/GTY/E-Tile) +- `fclk_freq`: Transceiver DRP clock frequency in MHz (Xilinx only) - `rclk_freq`: Transceiver reference clock frequency in MHz -- `transceiver.gt_loc`: Transceiver location (e.g., "X0Y8") -- `transceiver.rx_rclk_src`: RX reference clock source (e.g., "X0Y8 clk1+2" means using refclock 1 from the GT quad located 2 quads above X0Y8) -- `transceiver.tx_rclk_src`: TX reference clock source (same format as RX) +- `transceiver.gt_loc`: Transceiver location (e.g., "X0Y8") (Xilinx only) +- `transceiver.rx_rclk_src`: RX reference clock source (e.g., "X0Y8 clk1+2" means using refclock 1 from the GT quad located 2 quads above X0Y8) (Xilinx only) +- `transceiver.tx_rclk_src`: TX reference clock source (same format as RX) (Xilinx only) - `transceiver.line_rate_gbps`: Transceiver line rate in Gbps (e.g., "10.3125") - `synth`: Synthesis configuration (optional, for standalone testing) +- `pre_setup_hooks` Lists IP (`.tcl`) scripts run at synthesis time to generate board-level IPs (VIO probes, ILAs, etc.). Leave empty if no such IPs are needed. + +**Vendor-Specific Notes (Important):** +- Xilinx profiles (`GTX`/`GTH`/`GTY`) require `fclk_freq`, `transceiver.gt_loc`, and Xilinx-oriented `rx_rclk_src`/`tx_rclk_src` values. +- Altera `ETILE` profiles (for example `de10`) may differ by design: + - `device.family` is required (for example `"Agilex 7"`). + - `fclk_freq` should be omitted + - `transceiver.gt_loc` should be omitted **Important:** Refer to your FPGA documentation for correct GT site assignments and available reference clock sources for your specific device and board. @@ -112,7 +153,7 @@ If your platform is not listed, create a new profile in `config.json`: make render-design OPT_PROFILE= ``` -This generates transceiver IP cores configured for your hardware platform. +This generates transceiver IP cores and package files configured for your hardware platform. ### Step 4: (Optional) Create Standalone Test Design @@ -129,20 +170,34 @@ For quick platform validation, create a standalone example design: - Top-level module that instantiates QECIPHY - XDC constraint file with pin assignments and timing - **Example Designs Folder Structure:** + **Example Designs Folder Structure (Xilinx):** ``` example_designs// ├── src/ │ └── qeciphy_syn_wrapper.sv # Top-level wrapper module ├── src.f # Source file list └── syn/ - └── constraints.xdc # Platform-specific constraints + └── constraints.xdc # XDC timing and pin constraints + ``` + + **Example Designs Folder Structure (Altera):** + ``` + example_designs// + ├── src/ + │ └── qeciphy_syn_wrapper.sv # Top-level wrapper module + ├── src.f # Source file list + └── syn/ + ├── clock_constraints.sdc # SDC timing constraints + └── pin_assignments.tcl # Quartus pin assignment script + └── signal_tap.stp # Quartus signal tap assignments ``` **Required Files:** - **`src/qeciphy_syn_wrapper.sv`**: SystemVerilog top-level that instantiates QECIPHY with your platform's clock and pin connections - **`src.f`**: File list containing the path to your top-level module - - **`syn/constraints.xdc`**: XDC file with pin assignments, clock definitions, and I/O standards for your platform + - **`syn/constraints.xdc`** (Xilinx): XDC file with pin assignments, clock definitions, and I/O standards for your platform + - **`syn/clock_constraints.sdc`** (Altera): SDC file with clock definitions, clock groups, multicycle paths, and false paths + - **`syn/pin_assignments.tcl`** (Altera): Tcl script sourced by Quartus for pin and I/O standard assignments 3. **Update Config for Synthesis**: Add synthesis settings to your profile in `config.json`: @@ -158,20 +213,33 @@ For quick platform validation, create a standalone example design: } ``` + For Altera, list `.sdc` and `.tcl` constraint files instead of `.xdc`: + ```json + "constraints": [ + "example_designs//syn/clock_constraints.sdc", + "example_designs//syn/pin_assignments.tcl" + ] + ``` + 4. **Run Synthesis**: ```bash make synth OPT_PROFILE= ``` - This creates a synthesis project with bitstream and debug files at: + For Xilinx profiles, this creates a bitstream and debug file at: - `run/synth_qeciphy/synth_qeciphy.runs/impl_1/qeciphy_syn_wrapper.bit` - `run/synth_qeciphy/synth_qeciphy.runs/impl_1/qeciphy_syn_wrapper.ltx` + For Altera profiles, the SOF programming file is at: + - `run//output_files/.sof` + + where `` is controlled by `OPT_QUARTUS_PROJECT` (default: `qeciphy_integration`). + ### Step 5: Integrate into Your Actual Design #### Add QECIPHY Files to Your Project -Add all files listed in `src.f` and `xci.f` in your project. +For Xilinx, add all files listed in `src_xilinx.f` and `generated_ip.f` to your project. For Altera, add all files listed in `src_altera.f` and `generated_ip.f`. #### Instantiate QECIPHY Module @@ -209,16 +277,18 @@ QECIPHY i_QECIPHY ( ### Step 6: Apply Timing Constraints and Run Synthesis -1. **Add Timing Constraints**: Copy the appropriate timing constraints from the [Timing Constraints](#timing-constraints) section below and add them to your project's XDC constraint file. +1. **Add Timing Constraints**: Copy the appropriate timing constraints from the [Timing Constraints](#timing-constraints) section below and add them to your project's constraint file (`.xdc` for Xilinx, `.sdc` for Altera). 2. **Run Synthesis**: With QECIPHY integrated into your design and timing constraints applied, run synthesis with your complete design. ## Timing Constraints -You must add the following timing constraints to your project for proper operation. +You must add the following timing constraints to your project for proper operation. Xilinx profiles use XDC format (Vivado); Altera profiles use SDC format (Quartus). We recommend instantiating the IP with the name `i_QECIPHY` or `u_QECIPHY`. The following constraints can then be applied based on the type of transceiver being used. These constraints handle the clock relationships within the QECIPHY. +**Note:** The E-Tile SDC constraints use `get_keepers` path expressions containing `i_QECIPHY` — the `i_QECIPHY` instantiation name is required for these expressions to resolve. + ### GTY Transceiver Constraints ```tcl @@ -333,6 +403,64 @@ set_multicycle_path 1 -hold -start -from [get_clocks tx_clk_2x] -to [get_clocks set_property LOC {location} [get_cells -hierarchical -filter {lib_cell =~ GTXE2_CHANNEL && NAME =~ *QECIPHY*}] ``` +### E-Tile Transceiver Constraints + +These constraints are in SDC format for Quartus Prime. They assume the QECIPHY instance is named `i_QECIPHY` — this naming is required for the false path `get_keepers` expressions to resolve correctly. + +```tcl +# Reference clock and free-running/AXI clock (replace period and port names for your board) +create_clock -name RCLK -period [get_ports {}] +create_clock -name ACLK -period [get_ports {}] + +# QECIPHY internal clocks from Altera clock divider network +# Periods depend on the configured line rate: +# 2x clock period (ns) = 40 / line_rate_gbps (e.g. 3.878 ns at 10.3125 Gbps) +# 1x clock period (ns) = 80 / line_rate_gbps (e.g. 7.756 ns at 10.3125 Gbps) +create_clock -name tx_clk_2x_o -period <2x_period> \ + [get_pins i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tile_tx_clk_network|intelclkctrl_0|clkdiv_inst|clock_div1] +create_clock -name rx_clk_2x_o -period <2x_period> \ + [get_pins i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tile_rx_clk_network|intelclkctrl_0|clkdiv_inst|clock_div1] +create_clock -name tx_clk_o -period <1x_period> \ + [get_pins i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tile_tx_clk_network|intelclkctrl_0|clkdiv_inst|clock_div2] +create_clock -name rx_clk_o -period <1x_period> \ + [get_pins i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tile_rx_clk_network|intelclkctrl_0|clkdiv_inst|clock_div2] + +# Collect clock groups +set rx_clk_2x [get_clocks -include_generated_clocks rx_clk_2x_o] +set rx_clk_1x [get_clocks -include_generated_clocks rx_clk_o] +set tx_clk_2x [get_clocks -include_generated_clocks tx_clk_2x_o] +set tx_clk_1x [get_clocks -include_generated_clocks tx_clk_o] + +set rx_grp [add_to_collection $rx_clk_2x $rx_clk_1x] +set tx_grp [add_to_collection $tx_clk_2x $tx_clk_1x] + +# Set asynchronous clock groups +# Optionally include additional board clocks +set_clock_groups -asynchronous \ + -group [get_clocks RCLK] \ + -group [get_clocks -include_generated_clocks ACLK] \ + -group $rx_grp \ + -group $tx_grp + +# Multicycle paths for 1x/2x clock pair timing +set_multicycle_path -setup -end -from $rx_clk_2x -to $rx_clk_1x 2 +set_multicycle_path -hold -end -from $rx_clk_2x -to $rx_clk_1x 1 +set_multicycle_path -setup -start -from $rx_clk_1x -to $rx_clk_2x 2 +set_multicycle_path -hold -start -from $rx_clk_1x -to $rx_clk_2x 1 +set_multicycle_path -setup -end -from $tx_clk_2x -to $tx_clk_1x 2 +set_multicycle_path -hold -end -from $tx_clk_2x -to $tx_clk_1x 1 +set_multicycle_path -setup -start -from $tx_clk_1x -to $tx_clk_2x 2 +set_multicycle_path -hold -start -from $tx_clk_1x -to $tx_clk_2x 1 + +# False paths for E-Tile reset/ready signals crossing clock domains +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|gen_etile.transceiver_inst|xcvrnphy_fme_0|g_pma_rsfec_reset.g_auto_reset.reset_ip_auto_etile_inst|reset_control_inst|g_rx.g_rx[0].g_rx.counter_rx_ready|r_reset}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|i_rx_ready_sync|sync_stage_sf[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|gen_etile.transceiver_inst|xcvrnphy_fme_0|g_pma_rsfec_reset.g_auto_reset.reset_ip_auto_etile_inst|reset_control_inst|g_tx.g_tx[0].g_tx.counter_tx_ready|r_reset}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|i_tx_ready_sync|sync_stage_sf[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|gen_etile.transceiver_inst|xcvrnphy_fme_0|g_pma_rsfec_reset.g_auto_reset.reset_ip_auto_etile_inst|reset_control_inst|g_rx.g_rx[0].g_rx.counter_rx_ready|r_reset}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|i_rx_ready_2x_sync|sync_stage_sf[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|gen_etile.transceiver_inst|xcvrnphy_fme_0|g_pma_rsfec_reset.g_auto_reset.reset_ip_auto_etile_inst|reset_control_inst|g_tx.g_tx[0].g_tx.counter_tx_ready|r_reset}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|i_tx_ready_2x_sync|sync_stage_sf[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_resetcontroller|i_cdc_gt_rst_n_o|sync_stage_sf[1]}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tx_reset_sync_ff[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_resetcontroller|i_cdc_gt_rst_n_o|sync_stage_sf[1]}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|rx_reset_sync_ff[0]}] +``` + ## Data Path Integration Examples ### Reset Synchronization diff --git a/Makefile b/Makefile index 6361127..69eef50 100644 --- a/Makefile +++ b/Makefile @@ -7,11 +7,12 @@ OPT_MODE?=batch OPT_PROFILE?= OPT_SIM_FILES ?= false -OPT_TOOL?= +OPT_TOOL?=xsim OPT_TOP?= OPT_TEST?= OPT_ARGS?=0 OPT_SEED?=0 +OPT_QUARTUS_PROJECT ?= qeciphy_integration # ------------------------------------------------------------- # Utils @@ -31,9 +32,10 @@ CFG ?= config.json # Collect fields from config (require OPT_PROFILE) SYN_TOP := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).synth.top) SYN_FILELIST := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).synth.filelists) -XDC := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).synth.constraints) +CONSTRAINTS := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).synth.constraints) PART := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).device.part) VENDOR := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).device.vendor) +FAMILY := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).device.family 2>/dev/null || echo "") BOARD := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).board 2>/dev/null || true) VARIANT := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).variant) HOOKS := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROFILE).synth.pre_setup_hooks) @@ -51,21 +53,29 @@ LINE_RATE_GBPS := $(shell $(PY) scripts/read_cfg.py $(CFG) profiles.$(OPT_PROF # Static file lists SIM_FILELIST := sim.f LINT_FILELIST := lint.f -SRC_FILELIST := src.f -XCI_FILELIST := xci.f +SRC_FILELIST := src_common.f +GENIP_FILELIST := generated_ip.f UVM_FILELIST := uvm.f SVA_FILELIST := sva.f +# Vendor-specific source file lists (optional, included if they exist) +SRC_XILINX_FILELIST := src_xilinx.f +SRC_ALTERA_FILELIST := src_altera.f +VENDOR_SRC_FILELIST := $(shell \ + if [ "$(VENDOR)" = "xilinx" ] && [ -f $(SRC_XILINX_FILELIST) ]; then echo $(SRC_XILINX_FILELIST); \ + elif [ "$(VENDOR)" = "altera" ] && [ -f $(SRC_ALTERA_FILELIST) ]; then echo $(SRC_ALTERA_FILELIST); \ + fi) + # Extracted file lists -LINT_FILES := $(shell $(PY) scripts/extract_sources.py $(SRC_FILELIST) $(LINT_FILELIST)) -SRC_FILES := $(shell $(PY) scripts/extract_sources.py $(SRC_FILELIST)) -SIM_FILES := $(shell $(PY) scripts/extract_sources.py $(SIM_FILELIST) $(SVA_FILELIST)) +LINT_FILES := $(shell $(PY) scripts/extract_sources.py $(SRC_XILINX_FILELIST) $(SRC_ALTERA_FILELIST) $(LINT_FILELIST)) +SRC_FILES := $(shell $(PY) scripts/extract_sources.py $(VENDOR_SRC_FILELIST)) +SIM_FILES := $(shell $(PY) scripts/extract_sources.py $(SIM_FILELIST) $(VENDOR_SRC_FILELIST) $(SVA_FILELIST)) SYN_FILES := $(shell $(PY) scripts/extract_sources.py $(SYN_FILELIST)) -VCF_FILES := $(shell $(PY) scripts/extract_sources.py $(SRC_FILELIST) $(SVA_FILELIST)) -XCI_FILES := $(shell if [ -f $(XCI_FILELIST) ]; then $(PY) scripts/extract_sources.py $(XCI_FILELIST); fi) +VCF_FILES := $(shell $(PY) scripts/extract_sources.py $(VENDOR_SRC_FILELIST) $(SVA_FILELIST)) +GENIP_FILES := $(shell if [ -f $(GENIP_FILELIST) ]; then $(PY) scripts/extract_sources.py $(GENIP_FILELIST); fi) # Tool paths and directories -XCI_DIR := xci +GENIP_DIR := generated_ip RUN_DIR := run GEN_XCI_TCL_gth := vendors/xilinx/qeciphy_gth_transceiver.tcl GEN_XCI_TCL_gtx := vendors/xilinx/qeciphy_gtx_transceiver.tcl @@ -75,6 +85,11 @@ XSIM_TCL := scripts/vivado_sim.tcl VIVADO_SYNTH_TCL := scripts/vivado_synth.tcl VIVADO_SIM_EXPORT_TCL := scripts/vivado_sim_export.tcl FORMAL_TCL := scripts/vcf_default.tcl +QUARTUS_PROJ_TCL := scripts/quartus_proj.tcl +QUARTUS_IP_GEN_PROJ_TCL := scripts/quartus_ip_gen_proj.tcl +ALTERA_IP_GEN_PROJECT := altera_ip_gen +ALTERA_VENDOR_IP_DIR := vendors/altera/25.3.1/ip +ALTERA_EXAMPLE_IP_DIR := example_designs/vendors/altera/25.3.1/ip # ------------------------------------------------------------- # Targets @@ -92,7 +107,7 @@ help: @echo " - Run lint checks on the design using Verilator" @echo "" @echo " synth" - @echo " - Run design synthesis and implementation using Vivado" + @echo " - Run design synthesis: Vivado (xilinx profiles) or Quartus (altera profiles)" @echo " - Required variables: OPT_PROFILE" @echo " - Optional variables: OPT_MODE=(gui|batch) [default: batch]" @echo "" @@ -116,12 +131,11 @@ help: @echo " - Optional variables: OPT_ARGS=(string) [additional simulator arguments]" @echo "" @echo " render-design" - @echo " - Generate Xilinx IP core files (.xci) for the target profile" - @echo " - Generate build configuration package (src/qeciphy_build_cfg_pkg.sv)" - @echo " - Generate simulation configuration package (tb/qeciphy_sim_cfg_pkg.sv)" + @echo " - Xilinx profiles: generate IP core files (.xci) via Vivado" + @echo " - Altera profiles: generate IP core files (.ip) via Quartus (altera_ip_gen project)" + @echo " - All profiles: generate build/sim config packages" @echo " - Required variables: OPT_PROFILE" - @echo " - Optional variables: OPT_SIM_FILES=(true|false) [default: false]" - @echo " When OPT_SIM_FILES=true, also exports simulation files for vendor specific modules to tb/generated_sim_files/" + @echo " - Optional variables: OPT_SIM_FILES=(true|false) [default: false] (xilinx only)" @echo "" @echo " format" @echo " - Format SystemVerilog source code using Verible" @@ -138,9 +152,11 @@ help: @echo " make distclean" @echo " make render-design OPT_PROFILE=zcu216" @echo " make render-design OPT_PROFILE=zcu216 OPT_SIM_FILES=true" + @echo " make render-design OPT_PROFILE=de10" @echo " make synth OPT_PROFILE=zcu216" @echo " make sim OPT_PROFILE=zcu216 OPT_TOOL=vcs" @echo " make sim OPT_PROFILE=zcu216 OPT_MODE=gui OPT_TOOL=vcs" + @echo " make synth OPT_PROFILE=de10" @echo " make lint" @echo " make format" @echo " make uvm-sim OPT_TEST=qeciphy_txrx_test OPT_PROFILE=zcu216" @@ -225,6 +241,12 @@ check_verible: exit 1; \ fi +check_quartus_sh: + @if ! command -v quartus_sh >/dev/null 2>&1; then \ + echo "ERROR: quartus_sh not found in PATH. Please ensure Quartus Prime is installed and available."; \ + exit 1; \ + fi + # ------------------------------------------------------------- # Main targets # ------------------------------------------------------------- @@ -239,12 +261,21 @@ lint: render-design: @$(MAKE) check_profile @echo "INFO: Rendering design for profile $(OPT_PROFILE)" - @$(MAKE) vivado_generate_xci + @if [ "$(VENDOR)" = "xilinx" ]; then \ + $(MAKE) vivado_generate_xci; \ + $(MAKE) generate-sim-cfg-pkg; \ + elif [ "$(VENDOR)" = "altera" ]; then \ + $(MAKE) quartus_generate_ip; \ + else \ + echo "ERROR: Unsupported vendor '$(VENDOR)' for profile $(OPT_PROFILE)"; exit 1; \ + fi @$(MAKE) generate-build-cfg-pkg - @$(MAKE) generate-sim-cfg-pkg sim: @$(MAKE) check_profile + @if [ "$(VENDOR)" = "altera" ]; then \ + echo "ERROR: Simulation is not supported for Altera vendor"; exit 1; \ + fi @$(MAKE) check_simulator @echo "INFO: Running simulation for profile $(OPT_PROFILE) using $(OPT_TOOL)" @if [ "$(OPT_TOOL)" = "vcs" ]; then \ @@ -258,10 +289,16 @@ formal: @echo "INFO: Running formal verification for $(OPT_TOP)" $(MAKE) vcf_formal -synth: +synth: @$(MAKE) check_profile @echo "INFO: Running synthesis for profile $(OPT_PROFILE)" - @$(MAKE) vivado_synth + @if [ "$(VENDOR)" = "xilinx" ]; then \ + $(MAKE) vivado_synth; \ + elif [ "$(VENDOR)" = "altera" ]; then \ + $(MAKE) quartus_synth; \ + else \ + echo "ERROR: Unsupported vendor '$(VENDOR)' for profile $(OPT_PROFILE)"; exit 1; \ + fi clean: @echo "INFO: Cleaning build artifacts" @@ -271,7 +308,7 @@ clean: distclean: clean @echo "INFO: Performing distclean" - @rm -rf tb/compiled_simlib/ tb/generated_sim_files/ generated_sim.f xci/ xci.f + @rm -rf tb/compiled_simlib/ tb/generated_sim_files/ generated_sim.f generated_ip/ generated_ip.f @rm -rf src/qeciphy_build_cfg_pkg.sv tb/qeciphy_sim_cfg_pkg.sv @@ -294,29 +331,29 @@ verible_format: vivado_generate_xci: @$(MAKE) check_vivado - @mkdir -p $(XCI_DIR) + @mkdir -p $(GENIP_DIR) @mkdir -p $(RUN_DIR) @if [ "$(VARIANT)" = "GTH" ]; then \ vivado -mode batch -source $(GEN_XCI_TCL_gth) -tclargs $(PART) $(RUN_DIR) "$(GT_LOC)" "$(FCLK_FREQ)" "$(RCLK_FREQ)" "$(RX_RCLK_SRC)" "$(TX_RCLK_SRC)" "$(LINE_RATE_GBPS)"; \ - find $(RUN_DIR) -name "*.xci" -exec cp {} $(XCI_DIR)/ \; ; \ - echo "INFO: Copied .xci files from $(RUN_DIR) to $(XCI_DIR)"; \ + find $(RUN_DIR) -name "*.xci" -exec cp {} $(GENIP_DIR)/ \; ; \ + echo "INFO: Copied .xci files from $(RUN_DIR) to $(GENIP_DIR)"; \ elif [ "$(VARIANT)" = "GTX" ]; then \ vivado -mode batch -source $(GEN_XCI_TCL_gtx) -tclargs $(PART) $(RUN_DIR) "$(GT_LOC)" "$(FCLK_FREQ)" "$(RCLK_FREQ)" "$(RX_RCLK_SRC)" "$(TX_RCLK_SRC)" "$(LINE_RATE_GBPS)"; \ - find $(RUN_DIR) -name "*.xci" -exec cp {} $(XCI_DIR)/ \; ; \ + find $(RUN_DIR) -name "*.xci" -exec cp {} $(GENIP_DIR)/ \; ; \ vivado -mode batch -source $(GEN_XCI_TCL_gtx_mmcm) -tclargs $(PART) $(RUN_DIR) "$(LINE_RATE_GBPS)"; \ - find $(RUN_DIR) -name "*.xci" -exec cp {} $(XCI_DIR)/ \; ; \ - echo "INFO: Copied .xci files from $(RUN_DIR) to $(XCI_DIR)"; \ + find $(RUN_DIR) -name "*.xci" -exec cp {} $(GENIP_DIR)/ \; ; \ + echo "INFO: Copied .xci files from $(RUN_DIR) to $(GENIP_DIR)"; \ elif [ "$(VARIANT)" = "GTY" ]; then \ vivado -mode batch -source $(GEN_XCI_TCL_gty) -tclargs $(PART) $(RUN_DIR) "$(GT_LOC)" "$(FCLK_FREQ)" "$(RCLK_FREQ)" "$(RX_RCLK_SRC)" "$(TX_RCLK_SRC)" "$(LINE_RATE_GBPS)"; \ - find $(RUN_DIR) -name "*.xci" -exec cp {} $(XCI_DIR)/ \; ; \ - echo "INFO: Copied .xci files from $(RUN_DIR) to $(XCI_DIR)"; \ + find $(RUN_DIR) -name "*.xci" -exec cp {} $(GENIP_DIR)/ \; ; \ + echo "INFO: Copied .xci files from $(RUN_DIR) to $(GENIP_DIR)"; \ else \ echo "ERROR: Unsupported variant $(VARIANT). Must be one of GTH, GTX, GTY."; \ exit 1; \ fi @echo "INFO: Generating XCI filelist" - @find $(XCI_DIR) -name "*.xci" | sort > xci.f - @echo "INFO: Created xci.f with $$(wc -l < xci.f) XCI files" + @find $(GENIP_DIR) -name "*.xci" | sort > generated_ip.f + @echo "INFO: Created generated_ip.f with $$(wc -l < generated_ip.f) XCI files" ifeq ($(OPT_SIM_FILES),true) @echo "INFO: Generating IP simulation files" @$(PY) scripts/generate_sim_files.py --part $(PART) --simulator vcs @@ -324,6 +361,40 @@ endif @echo "INFO: Cleaning up temporary project files in $(RUN_DIR)" @rm -rf $(RUN_DIR) +quartus_generate_ip: + @$(MAKE) check_quartus_sh + @mkdir -p $(GENIP_DIR) + @mkdir -p $(RUN_DIR)/$(ALTERA_IP_GEN_PROJECT)/ip + @quartus_sh --script $(CURRENT_DIR)/$(QUARTUS_IP_GEN_PROJ_TCL) -tclargs \ + "$(CURRENT_DIR)/$(RUN_DIR)/$(ALTERA_IP_GEN_PROJECT)" \ + "$(ALTERA_IP_GEN_PROJECT)" \ + "$(FAMILY)" \ + "$(PART)" + @if [ "$(VARIANT)" = "ETILE" ]; then \ + LINE_RATE_MBPS=$$(echo "$(LINE_RATE_GBPS) * 1000" | bc -l); \ + [ -n "$$LINE_RATE_MBPS" ] || { echo "ERROR: LINE_RATE_GBPS is not set for profile $(OPT_PROFILE)"; exit 1; }; \ + (cd $(RUN_DIR)/$(ALTERA_IP_GEN_PROJECT)/ip && \ + qsys-script \ + --script=$(CURRENT_DIR)/$(ALTERA_VENDOR_IP_DIR)/qeciphy_etile.tcl \ + --quartus-project=$(CURRENT_DIR)/$(RUN_DIR)/$(ALTERA_IP_GEN_PROJECT)/$(ALTERA_IP_GEN_PROJECT).qpf \ + "--cmd=set argv [list {$(PART)} {$(FAMILY)} $$LINE_RATE_MBPS $(RCLK_FREQ)]" && \ + qsys-script \ + --script=$(CURRENT_DIR)/$(ALTERA_VENDOR_IP_DIR)/qeciphy_altera_clk_mmcm.tcl \ + --quartus-project=$(CURRENT_DIR)/$(RUN_DIR)/$(ALTERA_IP_GEN_PROJECT)/$(ALTERA_IP_GEN_PROJECT).qpf \ + "--cmd=set argv [list {$(PART)} {$(FAMILY)} $$LINE_RATE_MBPS $(RCLK_FREQ)]") ; \ + echo "INFO: Copying .ip files from $(RUN_DIR)/$(ALTERA_IP_GEN_PROJECT)/ip to $(GENIP_DIR)"; \ + find $(RUN_DIR)/$(ALTERA_IP_GEN_PROJECT)/ip -name "*.ip" -exec cp {} $(GENIP_DIR)/ \; ; \ + else \ + echo "ERROR: Unsupported variant $(VARIANT) for Quartus IP generation. Must be ETILE."; \ + exit 1; \ + fi + + @echo "INFO: Generating IP filelist" + @find $(GENIP_DIR) -name "*.ip" | sort > $(GENIP_FILELIST) + @echo "INFO: Created $(GENIP_FILELIST) with $$(wc -l < $(GENIP_FILELIST)) IP files" + @echo "INFO: Cleaning up temporary project $(ALTERA_IP_GEN_PROJECT)" + @rm -rf $(RUN_DIR)/$(ALTERA_IP_GEN_PROJECT) + generate-build-cfg-pkg: @echo "INFO: Generating build configuration package" @echo "// SPDX-License-Identifier: BSD-2-Clause" > src/qeciphy_build_cfg_pkg.sv @@ -364,7 +435,7 @@ generate-sim-cfg-pkg: vivado_sim: @$(MAKE) check_vivado @mkdir -p $(RUN_DIR) - @vivado -mode $(OPT_MODE) -source $(XSIM_TCL) -tclargs qeciphy_tb $(PART) $(VARIANT) $(SRC_FILES) -- $(SIM_FILES) -- $(XCI_FILES) + @vivado -mode $(OPT_MODE) -source $(XSIM_TCL) -tclargs qeciphy_tb $(PART) $(VARIANT) $(SRC_FILES) -- $(SIM_FILES) -- $(GENIP_FILES) vcs_sim: @$(MAKE) check_vcs @@ -454,4 +525,11 @@ endif vivado_synth: @$(MAKE) check_vivado @mkdir -p $(RUN_DIR) - @vivado -mode $(OPT_MODE) -source $(VIVADO_SYNTH_TCL) -tclargs $(SYN_TOP) $(XDC) $(PART) "$(BOARD)" '$(HOOKS)' $(SYN_FILES) -- $(XCI_FILES) \ No newline at end of file + @vivado -mode $(OPT_MODE) -source $(VIVADO_SYNTH_TCL) -tclargs $(SYN_TOP) $(CONSTRAINTS) $(PART) "$(BOARD)" '$(HOOKS)' $(SYN_FILES) -- $(GENIP_FILES) + +quartus_synth: + @$(MAKE) check_quartus_sh + @mkdir -p $(RUN_DIR) + @quartus_sh --script $(QUARTUS_PROJ_TCL) -tclargs \ + "$(SYN_TOP)" "$(CONSTRAINTS)" "$(PART)" "$(FAMILY)" "$(VARIANT)" \ + '$(HOOKS)' $(SRC_FILES) $(SYN_FILES) -- $(GENIP_FILES) diff --git a/README.md b/README.md index 564cfa8..dac2661 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ QECIPHY is a physical layer implementation according to the [QECi (Quantum Error ## Key Features - **Simple Interface**: AXI4-Stream interface hides all physical layer complexity -- **Universal Compatibility**: Supports any Xilinx FPGA with GTX, GTH, or GTY transceivers +- **Universal Compatibility**: Supports Xilinx FPGAs (GTX, GTH, GTY transceivers) and Altera FPGAs (E-Tile transceiver) - **Latency**: ~150-200ns latency at 12.5 Gbps line rate - **Programmable Line Rate**: Configurable transceiver line rates for different bandwidth requirements - **Programmable Clock Sources**: Configurable reference clock sources for flexibility @@ -38,7 +38,8 @@ QECIPHY is a physical layer implementation according to the [QECi (Quantum Error ### Prerequisites **To use QECIPHY:** -- Vivado 2024.1+: tested with 2024.1 +- Vivado 2024.1+: tested with 2024.1 (Xilinx targets) +- Quartus Prime Pro 25.3.1: tested with 25.3.1 (Altera E-Tile targets) - Python 3.8+: for build scripts - Make: for build automation @@ -52,7 +53,7 @@ QECIPHY is a physical layer implementation according to the [QECi (Quantum Error ### Three-Step Setup -We provide three example profiles for different transceiver types: +We provide example profiles for different transceiver types: ```bash # Clone the repository @@ -61,19 +62,22 @@ cd qeciphy # Render design for your platform. # This generates the required vendor specific IP cores and build/simulation configs. -make render-design OPT_PROFILE=zcu216 # GTY transceivers -# make render-design OPT_PROFILE=zcu106 # GTH transceivers -# make render-design OPT_PROFILE=kasliSoC # GTX transceivers +make render-design OPT_PROFILE=zcu216 # GTY transceivers +# make render-design OPT_PROFILE=zcu106 # GTH transceivers +# make render-design OPT_PROFILE=kasliSoC # GTX transceivers +# make render-design OPT_PROFILE=de10 # E-Tile transceiver # Run your first simulation make sim OPT_PROFILE=zcu216 # GTY transceivers # make sim OPT_PROFILE=zcu106 # GTH transceivers # make sim OPT_PROFILE=kasliSoC # GTX transceivers +# make sim OPT_PROFILE=de10 # E-Tile # Run synthesis -make synth OPT_PROFILE=zcu216 # GTY transceivers -# make synth OPT_PROFILE=zcu106 # GTH transceivers -# make synth OPT_PROFILE=kasliSoC # GTX transceivers +make synth OPT_PROFILE=zcu216 # GTY transceivers (uses Vivado) +# make synth OPT_PROFILE=zcu106 # GTH transceivers (uses Vivado) +# make synth OPT_PROFILE=kasliSoC # GTX transceivers (uses Vivado) +# make synth OPT_PROFILE=de10 # E-Tile (uses Quartus Prime Pro) ``` > *And you're done! For detailed integration instructions, please refer to the [Integration Guide](INTEGRATION.md).* @@ -127,7 +131,7 @@ qeciphy/ ├── docs/ # Documentation files ├── config.json # Build configuration (profiles, settings) ├── Makefile # Build automation -├── src.f, sim.f, lint.f, uvm.f, sva.f # File lists for different flows +├── src_common.f, src_xilinx.f, src_altera.f, sim.f, lint.f, uvm.f, sva.f # File lists for different flows ├── lint_waivers.vlt # Verilator lint waivers ├── CODE_OF_CONDUCT.md # Code of conduct ├── CONTRIBUTING.md # Development guidelines @@ -189,10 +193,10 @@ make sim OPT_PROFILE= OPT_TOOL=vcs OPT_MODE=gui ### Synthesis ```bash -# Run synthesis using Vivado (batch mode) +# Run synthesis using Vivado for Xilinx profiles and Quartus Prime Pro for Altera profiles(batch mode) make synth OPT_PROFILE= -# Run synthesis using Vivado (GUI mode) +# Run synthesis (GUI mode) — Vivado only make synth OPT_PROFILE= OPT_MODE=gui ``` @@ -226,13 +230,13 @@ make formal OPT_TOP= OPT_MODE=gui ## Performance -| Metric | GTX (7-series) | GTH (UltraScale) | GTY (UltraScale+) | -|--------|----------------|----------------------|----------------------| -| **Latency** | ~220ns | ~190ns |~195ns | +| Metric | GTX (7-series) | GTH (UltraScale) | GTY (UltraScale+) | +|--------|---|---|---| +| **Latency** | ~220ns | ~190ns | ~195ns | | **LUT** | 1372 | 1230 | 1230 | -| **FF** | 1229 | 1156 | 1156 | +| **FF** | 1229 | 1156 | 1156 | -*Measured at 12.5 Gbps line rate. Performance varies by platform and configuration.* +*Measured at 12.5 Gbps line rate (Xilinx). Performance varies by platform and configuration.* ## Contributing diff --git a/config.json b/config.json index 82b2768..a9c3b82 100644 --- a/config.json +++ b/config.json @@ -85,6 +85,35 @@ "example_designs/vendors/xilinx/qeciphy_vio.tcl" ] } - } + }, + "de10": { + "device": { + "part": "AGFB014R24B2E2V", + "vendor": "altera", + "family": "Agilex 7" + }, + "variant": "ETILE", + "rclk_freq": "156.25", + "transceiver": { + "line_rate_gbps": "10.3125" + }, + "synth": { + "top": "qeciphy_syn_wrapper", + "filelists": [ + "example_designs/de10/src.f" + ], + "constraints": [ + "example_designs/de10/syn/pin_assignments.tcl", + "example_designs/de10/syn/clock_constraints.sdc", + "example_designs/de10/syn/signal_tap.stp" + ], + "pre_setup_hooks": [ + "example_designs/vendors/altera/25.3.1/ip/qeciphy_vio.tcl", + "example_designs/vendors/altera/25.3.1/ip/reset_release.tcl", + "example_designs/vendors/altera/25.3.1/ip/sys_clk_100.tcl", + "example_designs/vendors/altera/25.3.1/ip/sys_clk_200_pll.tcl" + ] + } + } } } diff --git a/docs/architecture.md b/docs/architecture.md index a1adcaf..7cf8d17 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -83,17 +83,21 @@ The protocol operates with deterministic timing: - `FCLK`: Free-running fabric clock for internal logic **Generated Clocks:** -- `tx_clk`: TX clock (Generated by GT from RCLK for 64-bit data) -- `tx_clk_2x`: 2x TX clock (synchronized to TX clock for 32-bit data) -- `rx_clk`: RX clock (Generated by GT through CDR for 64-bit data) -- `rx_clk_2x`: 2x RX clock (synchronized to RX clock for 32-bit data) +- `tx_clk`: TX clock (64-bit data rate) +- `tx_clk_2x`: 2× TX clock (32-bit data rate, phase-aligned with `tx_clk`) +- `rx_clk`: RX clock (64-bit data rate, recovered from incoming data stream) +- `rx_clk_2x`: 2× RX clock (32-bit data rate, phase-aligned with `rx_clk`) + +**Clock Generation (Vendor-Specific):** +- **Xilinx**: `tx_clk`/`tx_clk_2x` and `rx_clk`/`rx_clk_2x` are produced by BUFG primitives inside the GT wrapper from the GT PLL and CDR outputs. `FCLK` is also used as the GT DRP (dynamic reconfiguration) clock. +- **Altera**: The tile outputs raw 2× clocks (`tx_clkout2`, `rx_clkout2`) running at `line_rate / data_width`. These feed `qeciphy_altera_clk_mmcm` (an Altera clock divider), which produces `tx_clk_2x` (pass-through) and `tx_clk` (÷2), and equivalently for the RX path. `FCLK` is not used for DRP on Altera; it is used only for reset synchronization. **Clock Relationships:** - ACLK, RCLK, and FCLK can be asynchronous to each other -- TX clocks are derived from RCLK -- RX clocks are recovered from incoming data stream -- TX and RX clocks operate at the same frequency but are independent -- 2x clocks run at double the rate and are phase-aligned with their respective base clocks +- TX clocks are derived from RCLK (via GT PLL on Xilinx, via tile TX PLL on Altera) +- RX clocks are recovered from the incoming data stream (via GT CDR on Xilinx, via tile RX CDR on Altera) +- TX and RX clocks operate at the same nominal frequency but are independent +- 2× clocks run at double the rate and are phase-aligned with their respective base clocks ## Implementation @@ -156,8 +160,11 @@ User AXI4-S -> TX FIFO -> TX Channel Encoder -> SERDES TX TX Channel Encoder: TX Boundary Gen -> TX Controller -> TX Packet Gen -SERDES TX: +SERDES TX (Xilinx): TX 64b to 32b Serializer -> GT Primitive + +SERDES TX (Altera): +TX 64b to 32b Serializer -> 8b10b Encoder (x4) -> E-Tile / F-Tile IP ``` **Flow Control:** @@ -191,9 +198,12 @@ The TX 64b to 32b serializer (`qeciphy_tx_64b_to_32b.sv`) uses a toggle counter ``` SERDES RX -> RX Channel Decoder -> RX FIFO -> User AXI4-S -SERDES RX: +SERDES RX (Xilinx): GT Primitive -> RX Byte Aligner -> RX Word Aligner (32b to 64b) +SERDES RX (Altera): +E-Tile / F-Tile IP -> Soft Word Aligner (40b) -> 8b10b Decoder (x4) -> Soft Comma Detect -> RX Word Aligner (32b to 64b) + RX Channel Decoder: RX Boundary Gen -> RX Monitor -> User Data ``` @@ -204,10 +214,12 @@ RX Boundary Gen -> RX Monitor -> User Data #### 5.1 RX Byte Aligner -The byte alignment process leverages the GT transceiver's native comma detection and alignment capabilities combined with pattern monitoring through the `qeciphy_rx_comma_detect.sv` module. The GT transceiver automatically handles comma realignment while the comma detect module verifies alignment success through pattern detection across a 6-state FSM: +Byte alignment differs between Xilinx and Altera because Xilinx GT primitives provide native comma detection, while Altera tiles do not. + +**Xilinx:** The byte alignment process leverages the GT transceiver's native comma detection and alignment capabilities combined with pattern monitoring through the `qeciphy_rx_comma_detect.sv` module. The GT transceiver automatically handles comma realignment while the comma detect module verifies alignment success through pattern detection across a 6-state FSM: 1. **IDLE**: Initial state, transitions to CHECK -2. **CHECK**: Monitor for Frame Alignment Word patterns (`0xBC` byte comma) +2. **CHECK**: Monitor for Frame Alignment Word patterns (`0xBC` byte comma) 3. **REVIEW**: Verify pattern consistency across multiple frame cycles 4. **DONE**: Alignment successful and stable (sticky state) 5. **FAIL**: Pattern verification failed, retry alignment process @@ -215,6 +227,55 @@ The byte alignment process leverages the GT transceiver's native comma detection The module monitors the expected protocol pattern (FAW, CRC, and data word positions) over configurable review cycles to ensure stable byte alignment before declaring success. + +**Xilinx Data Path:** +``` +GT Primitive + | + | (32-bit data with comma alignment) + v +qeciphy_rx_comma_detect + | + | (32-bit data with verified frame alignment) + v +qeciphy_rx_32b_to_64b + | + | (64-bit word-aligned data) + v +qeciphy_rx_channeldecoder +``` + +**Altera:** E-Tile and F-Tile transceivers output a raw 40-bit 8b10b-encoded stream with no hardware comma alignment. Comma alignment is performed entirely in fabric logic by two additional RTL modules that replicate the GT transceiver's native comma detection and alignment capabilities combined with the pattern monitoring through the `qeciphy_rx_comma_detect.sv` module: + +1. **Word Aligner** (`qeciphy_word_align`): Barrel-shifts the raw 40-bit encoded stream across all possible bit positions, searching for valid K28.5 comma patterns in the encoded domain. It tries up to `RXSLIDE_COUNT_MAX` positions and requires `RX_ALIGN_MATCH_MAX` consecutive matches before declaring alignment. A failed search triggers `align_fail_o`, which resets the RX datapath for a retry. + +2. **8b10b Decoder** (`eth_8b10b_dec_x4_a`): Decodes the aligned 40-bit encoded stream to 32-bit parallel data, identical in width to the Xilinx GT output. The output is then fed into the `qeciphy_rx_comma_detect.sv` module + +**Altera Data Path:** +``` +E-Tile / F-Tile IP + | + | (Raw 40-bit 8b10b-encoded stream) + v +qeciphy_word_align + | + | (40-bit data with comma alignment) + v +eth_8b10b_dec_x4_a (8b10b Decoder x4) + | + | (32-bit data with comma alignment) + v +qeciphy_rx_comma_detect.sv + | + | (32-bit data with verified frame alignment) + v +qeciphy_rx_32b_to_64b + | + | (64-bit word-aligned data) + v +qeciphy_rx_channeldecoder +``` + #### 5.2 RX Word Aligner The word aligner (`qeciphy_rx_32b_to_64b.sv`) creates two possible 64-bit combinations in `rx_clk_2x` domain: diff --git a/example_designs/de10/src.f b/example_designs/de10/src.f new file mode 100644 index 0000000..f16145e --- /dev/null +++ b/example_designs/de10/src.f @@ -0,0 +1,2 @@ +-F src_altera.f +example_designs/de10/src/qeciphy_syn_wrapper.sv diff --git a/example_designs/de10/src/qeciphy_syn_wrapper.sv b/example_designs/de10/src/qeciphy_syn_wrapper.sv new file mode 100644 index 0000000..6b2a084 --- /dev/null +++ b/example_designs/de10/src/qeciphy_syn_wrapper.sv @@ -0,0 +1,187 @@ +// SPDX-License-Identifier: BSD-2-Clause +// Copyright (c) 2024-2026 Riverlane Ltd. +// Original authors: Aniket Datta, Gargi Sunil, Evan Sun + +module qeciphy_syn_wrapper ( + input logic gt_refclk_in_p, + input logic clk_100_p, + + input logic gt_rx_p, + input logic gt_rx_n, + output logic gt_tx_p, + output logic gt_tx_n, + + inout logic i2c_qsfpdd0_scl, + inout logic i2c_qsfpdd0_sda, + output logic [3:0] fpga_led + + +); + + //Optional QSFPDD0-related signals are available on the board but are not used in this design + // output logic qsfpdd0_modsel_L, + // output logic qsfpdd0_Initmode, + // input logic qsfpdd0_modprs_L, + // input logic qsfpdd0_int_L, + + logic sys_clk_100; + logic sys_clk_200; + logic init_done_n; + + //Reset logic + logic [ 4:0] rst_counter; + logic [ 4:0] rst_counter_nxt; + logic rst_n; + logic rst_n_async; + logic [ 1:0] rst_n_sf; + // QECIPHY Signal declarations + logic RCLK; + logic FCLK; + logic ACLK; + logic ARSTn; + logic [63:0] TX_TDATA; + logic [63:0] TX_TDATA_nxt; + logic TX_TVALID; + logic TX_TREADY; + logic [63:0] RX_TDATA; + logic RX_TVALID; + logic RX_TREADY; + logic [ 3:0] STATUS; + logic [ 3:0] ECODE; + logic [63:0] RX_TDATA_ref; + logic [63:0] RX_TDATA_ref_nxt; + logic RXDATA_error; + logic RXDATA_error_nxt; + + + //Blinky heartbeat + localparam logic [26:0] BLINKY_COUNTER_MAX = 27'd99_999_999; + logic [ 3:0] led; + logic [26:0] blinky_counter; + logic blinky_led; + + // Debug signals for VIO + logic vio_source; + + + + assign ACLK = sys_clk_200; + assign FCLK = sys_clk_200; + + sys_clk_100 clk100_inst ( + .inclk (clk_100_p), // input, width = 1, inclk.clk + .outclk(sys_clk_100) // output, width = 1, outclk.clk + ); + + sys_clk_200_pll clk200_inst ( + .refclk (sys_clk_100), // input, width = 1, refclk.clk + .locked (), // output, width = 1, locked.export + .rst (1'b0), // input, width = 1, reset.reset + .axis_clk(sys_clk_200) // output, width = 1, outclk0.clk + ); + qeciphy_vio i_vio ( + .source (vio_source), // output, width = 1, sources.source + .source_clk(ACLK) // input, width = 1, source_clk.clk + ); + + + reset_release reset_release_inst (.ninit_done(init_done_n)); + // Generate 16 cycle reset that de-asserts synchronously + assign ARSTn = rst_counter[4]; + assign rst_counter_nxt = ARSTn ? rst_counter : rst_counter + 5'h1; + assign rst_n = rst_n_sf[1]; + assign rst_n_async = vio_source || init_done_n; // Asynchronous reset from VIO or POR + + always_ff @(posedge ACLK or negedge rst_n) begin + if (!rst_n) rst_counter <= 5'h0; + else rst_counter <= rst_counter_nxt; + end + + always_ff @(posedge ACLK or negedge rst_n_async) begin + if (!rst_n_async) rst_n_sf <= 2'h0; + else rst_n_sf <= {rst_n_sf[0], 1'b1}; + end + + + assign fpga_led = led; // Connect debug LEDs with extra bit + // For debugging + assign led[0] = (STATUS == 4'b0100) ? 1'b1 : 1'b0; + assign led[1] = (ECODE == 4'b0000) ? 1'b1 : 1'b0; + assign led[2] = ~RXDATA_error; + assign led[3] = blinky_led; // Heartbeat LED + + // 0.5-second blinky on led[3] (ACLK = 200 MHz) + always_ff @(posedge ACLK or negedge ARSTn) begin + if (!ARSTn) begin + blinky_counter <= '0; + blinky_led <= 1'b0; + end else begin + if (blinky_counter == BLINKY_COUNTER_MAX) begin + blinky_counter <= '0; + blinky_led <= ~blinky_led; + end else begin + blinky_counter <= blinky_counter + 1'b1; + end + end + end + + + // By the spec + assign RX_TREADY = 1'b1; + // Drive the transmitter QECI-PHY TX data pins + always_ff @(posedge FCLK or negedge ARSTn) begin + if (!ARSTn) TX_TVALID <= 1'b0; + else TX_TVALID <= 1'b1; + end + + assign TX_TDATA_nxt = TX_TREADY ? TX_TDATA + 64'h1 : TX_TDATA; + + always_ff @(posedge FCLK or negedge ARSTn) begin + if (!ARSTn) TX_TDATA <= 'h0; + else TX_TDATA <= TX_TDATA_nxt; + end + + // Verify receiver data + assign RX_TDATA_ref_nxt = RX_TVALID ? RX_TDATA_ref + 64'h1 : RX_TDATA_ref; + + always_ff @(posedge FCLK or negedge ARSTn) begin + if (!ARSTn) RX_TDATA_ref <= 'h0; + else RX_TDATA_ref <= RX_TDATA_ref_nxt; + end + + assign RXDATA_error_nxt = RX_TVALID ? (RX_TDATA_ref != RX_TDATA) : RXDATA_error; + + always_ff @(posedge FCLK or negedge ARSTn) begin + if (!ARSTn) RXDATA_error <= 'h0; + else RXDATA_error <= RXDATA_error_nxt; + end + + + assign RCLK = gt_refclk_in_p; + QECIPHY i_QECIPHY ( + .RCLK (RCLK), + .FCLK (FCLK), + .ACLK (ACLK), + .ARSTn (ARSTn), + .TX_TDATA (TX_TDATA), + .TX_TVALID(TX_TVALID), + .TX_TREADY(TX_TREADY), + .RX_TDATA (RX_TDATA), + .RX_TVALID(RX_TVALID), + .RX_TREADY(RX_TREADY), + .STATUS (STATUS), + .ECODE (ECODE), + .GT_RX_P (gt_rx_p), + .GT_RX_N (gt_rx_n), + .GT_TX_P (gt_tx_p), + .GT_TX_N (gt_tx_n) + ); + + // CURRENTLY UNUSED SIGNAL ASSIGNMENTS + // I2C data lines default to High-Z (tri-state) for proper I2C operation + assign i2c_qsfpdd0_sda = 1'bz; + assign i2c_qsfpdd0_scl = 1'bz; + + + +endmodule diff --git a/example_designs/de10/syn/clock_constraints.sdc b/example_designs/de10/syn/clock_constraints.sdc new file mode 100644 index 0000000..5cf26ea --- /dev/null +++ b/example_designs/de10/syn/clock_constraints.sdc @@ -0,0 +1,73 @@ +#SPDX-License-Identifier: BSD-2-Clause +#Copyright (c) 2026 Riverlane Ltd. + +# False paths for async reset and async reset release to RX and TX clock domains +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|gen_etile.transceiver_inst|xcvrnphy_fme_0|g_pma_rsfec_reset.g_auto_reset.reset_ip_auto_etile_inst|reset_control_inst|g_rx.g_rx[0].g_rx.counter_rx_ready|r_reset}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|i_rx_ready_sync|sync_stage_sf[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|gen_etile.transceiver_inst|xcvrnphy_fme_0|g_pma_rsfec_reset.g_auto_reset.reset_ip_auto_etile_inst|reset_control_inst|g_tx.g_tx[0].g_tx.counter_tx_ready|r_reset}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|i_tx_ready_sync|sync_stage_sf[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|gen_etile.transceiver_inst|xcvrnphy_fme_0|g_pma_rsfec_reset.g_auto_reset.reset_ip_auto_etile_inst|reset_control_inst|g_rx.g_rx[0].g_rx.counter_rx_ready|r_reset}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|i_rx_ready_2x_sync|sync_stage_sf[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|gen_etile.transceiver_inst|xcvrnphy_fme_0|g_pma_rsfec_reset.g_auto_reset.reset_ip_auto_etile_inst|reset_control_inst|g_tx.g_tx[0].g_tx.counter_tx_ready|r_reset}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|i_tx_ready_2x_sync|sync_stage_sf[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_resetcontroller|i_cdc_gt_rst_n_o|sync_stage_sf[1]}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tx_reset_sync_ff[0]}] +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_resetcontroller|i_cdc_gt_rst_n_o|sync_stage_sf[1]}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|rx_reset_sync_ff[0]}] + +set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|gen_etile.transceiver_inst|xcvrnphy_fme_0|g_pma_rsfec_reset.g_auto_reset.reset_ip_auto_etile_inst|reset_control_inst|g_tx.g_tx[0].g_tx.counter_tx_ready|r_reset}] -to [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|i_tx_ready_2x_sync|sync_stage_sf[0]}] + +# Reference clock constraint - 6.4ns period (156.25 MHz) +create_clock -name {clk_100_p} -period 10.000 [get_ports {clk_100_p}] +create_clock -name gt_refclk -period 6.4 [get_ports {gt_refclk_in_p}] +create_clock -name tx_clk_2x_o [get_pins i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tile_tx_clk_network|intelclkctrl_0|clkdiv_inst|clock_div1] -period 3.878 +create_clock -name rx_clk_2x_o [get_pins i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tile_rx_clk_network|intelclkctrl_0|clkdiv_inst|clock_div1] -period 3.878 +create_clock -name tx_clk_o [get_pins i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tile_tx_clk_network|intelclkctrl_0|clkdiv_inst|clock_div2] -period 7.756 +create_clock -name rx_clk_o [get_pins i_QECIPHY|i_qeciphy_serdes|i_qeciphy_gt_wrapper|gen_altera.i_qeciphy_gt_altera|tile_rx_clk_network|intelclkctrl_0|clkdiv_inst|clock_div2] -period 7.756 + +#Generated directly from Quartus Timing Analyzer with settings: Input clock frequency: 100 MHz, Output clock frequency: 200 MHz +create_generated_clock -name {clk200_inst} -source {clk_100_p} -divide_by 7 -multiply_by 14 -duty_cycle 50.00 { clk200_inst|iopll_0|tennm_pll|outclk[1] } + +# Capture clocks into variables (collections) +set sys_clk [get_clocks -include_generated_clocks clk200_inst] +set rx_clk_2x [get_clocks -include_generated_clocks rx_clk_2x_o] +set rx_clk_1x [get_clocks -include_generated_clocks rx_clk_o] +set tx_clk_2x [get_clocks -include_generated_clocks tx_clk_2x_o] +set tx_clk_1x [get_clocks -include_generated_clocks tx_clk_o] + + +set rx_grp [add_to_collection $rx_clk_2x $rx_clk_1x] +set tx_grp [add_to_collection $tx_clk_2x $tx_clk_1x] + + +create_clock -name {altera_reserved_tck} -period 41.667 [get_ports { altera_reserved_tck }] +set_input_delay -clock altera_reserved_tck 6 [get_ports altera_reserved_tdi] +set_input_delay -clock altera_reserved_tck 6 [get_ports altera_reserved_tms] +set_output_delay -clock altera_reserved_tck -clock_fall -max 6 [get_ports altera_reserved_tdo] + + +# # Clock groups for asynchronous relationship +set_clock_groups -asynchronous \ + -group [get_clocks gt_refclk] \ + -group $sys_clk \ + -group $rx_grp \ + -group $tx_grp \ + -group [get_clocks clk_100_p] \ + -group [get_clocks {altera_reserved_tck}] + + +# Multicycle path constraints for synchronous clocks +# Define 2-cycle setup and 1-cycle hold timing between related clock pairs +# RX pair +set_multicycle_path -setup -end -from $rx_clk_2x -to $rx_clk_1x 2 +set_multicycle_path -hold -end -from $rx_clk_2x -to $rx_clk_1x 1 +set_multicycle_path -setup -start -from $rx_clk_1x -to $rx_clk_2x 2 +set_multicycle_path -hold -start -from $rx_clk_1x -to $rx_clk_2x 1 + +# TX pair +set_multicycle_path -setup -end -from $tx_clk_2x -to $tx_clk_1x 2 +set_multicycle_path -hold -end -from $tx_clk_2x -to $tx_clk_1x 1 +set_multicycle_path -setup -start -from $tx_clk_1x -to $tx_clk_2x 2 +set_multicycle_path -hold -start -from $tx_clk_1x -to $tx_clk_2x 1 + +set_false_path -to [get_ports {fpga_led[*]}] +set_false_path -to [get_ports {i2c_qsfpdd0_scl}] +set_false_path -to [get_ports {i2c_qsfpdd0_sda}] +#set_false_path -to [get_ports {qsfpdd0_fpga_led[*]}] +#set_false_path -to [get_ports {qsfpdd1_fpga_led[*]}] +#set_false_path -to [get_ports {qsfpdd_12v_port_en}] +#set_false_path -from [get_ports {qsfpdd_1v2_port_int_n}] diff --git a/example_designs/de10/syn/pin_assignments.tcl b/example_designs/de10/syn/pin_assignments.tcl new file mode 100644 index 0000000..3905835 --- /dev/null +++ b/example_designs/de10/syn/pin_assignments.tcl @@ -0,0 +1,81 @@ +# SPDX-License-Identifier: BSD-2-Clause +# Copyright (c) 2024-2026 Riverlane Ltd. +# Original authors: Evan Sun + +#CLOCKS + +set_location_assignment PIN_AJ12 -to gt_refclk_in_p +set_location_assignment PIN_CU50 -to clk_100_p + +set_instance_assignment -name IO_STANDARD "TRUE DIFFERENTIAL SIGNALING" -to clk_100_p -entity qeciphy_syn_wrapper +set_instance_assignment -name INPUT_TERMINATION DIFFERENTIAL -to clk_100_p -entity qeciphy_syn_wrapper + +#Transceivers + +set_location_assignment PIN_BF1 -to gt_tx_p +set_location_assignment PIN_BE2 -to gt_tx_n +set_location_assignment PIN_BF7 -to gt_rx_p +set_location_assignment PIN_BE8 -to gt_rx_n + +set_instance_assignment -name IO_STANDARD LVPECL -to gt_refclk_in_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "refclk_divider_enable_termination=enable_term" -to gt_refclk_in_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "refclk_divider_enable_3p3v=enable_3p3v_tol" -to gt_refclk_in_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "refclk_divider_input_freq=156250000" -to gt_refclk_in_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "refclk_divider_powerdown_mode=false" -to gt_refclk_in_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "refclk_divider_enable_hysteresis=disable_hyst" -to gt_refclk_in_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "refclk_divider_use_as_BTI_clock=TRUE" -to gt_refclk_in_p -entity qeciphy_syn_wrapper + + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to gt_tx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name IO_STANDARD "HIGH SPEED DIFFERENTIAL I/O" -to gt_tx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "txeq_main_tap=35" -to gt_tx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "txeq_pre_tap_1=5" -to gt_tx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "txeq_pre_tap_2=0" -to gt_tx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "txeq_post_tap_1=0" -to gt_tx_p -entity qeciphy_syn_wrapper + +set_instance_assignment -name IO_STANDARD "HIGH SPEED DIFFERENTIAL I/O" -to gt_tx_n -entity qeciphy_syn_wrapper + + +set_instance_assignment -name XCVR_VCCR_VCCT_VOLTAGE 1_1V -to gt_rx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name IO_STANDARD "HIGH SPEED DIFFERENTIAL I/O" -to gt_rx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "rx_ac_couple_enable=ENABLE" -to gt_rx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "rx_onchip_termination=RXONCHIP_TERMINATION_R_2" -to gt_rx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name HSSI_PARAMETER "rx_term_mode_select=RXTERM_MODE_SELECT_GROUNDED" -to gt_rx_p -entity qeciphy_syn_wrapper +set_instance_assignment -name IO_STANDARD "HIGH SPEED DIFFERENTIAL I/O" -to gt_rx_n -entity qeciphy_syn_wrapper + +#Other IO + +set_location_assignment PIN_CR54 -to fpga_led[0] +set_location_assignment PIN_DB57 -to fpga_led[1] +set_location_assignment PIN_CY57 -to fpga_led[2] +set_location_assignment PIN_CU52 -to fpga_led[3] + +set_location_assignment PIN_H21 -to i2c_qsfpdd0_scl +set_location_assignment PIN_H23 -to i2c_qsfpdd0_sda + +set_instance_assignment -name IO_STANDARD "1.2 V" -to fpga_led[0] -entity qeciphy_syn_wrapper +set_instance_assignment -name IO_STANDARD "1.2 V" -to fpga_led[1] -entity qeciphy_syn_wrapper +set_instance_assignment -name IO_STANDARD "1.2 V" -to fpga_led[2] -entity qeciphy_syn_wrapper +set_instance_assignment -name IO_STANDARD "1.2 V" -to fpga_led[3] -entity qeciphy_syn_wrapper + +set_instance_assignment -name RESERVE_PIN AS_BIDIRECTIONAL -to i2c_qsfpdd0_sda +set_instance_assignment -name RESERVE_PIN AS_BIDIRECTIONAL -to i2c_qsfpdd0_scl +set_instance_assignment -name IO_STANDARD "1.2 V" -to i2c_qsfpdd0_scl -entity qeciphy_syn_wrapper +set_instance_assignment -name IO_STANDARD "1.2 V" -to i2c_qsfpdd0_sda -entity qeciphy_syn_wrapper +set_instance_assignment -name SLEW_RATE 1 -to i2c_qsfpdd0_sda -entity qeciphy_syn_wrapper +set_instance_assignment -name SLEW_RATE 1 -to i2c_qsfpdd0_scl -entity qeciphy_syn_wrapper + + +#Optional QSFPDD control signals - not required for basic operation, but may be needed for some use cases +#set_location_assignment PIN_DA20 -to qsfpdd0_reset_L +#set_location_assignment PIN_CT29 -to qsfpdd0_modprs_L +#set_location_assignment PIN_DB21 -to qsfpdd0_Initmode +#set_location_assignment PIN_DB19 -to qsfpdd0_modsel_L +# set_instance_assignment -name IO_STANDARD "1.2-V" -to qsfpdd0_modsel_L -entity qeciphy_syn_wrapper +# set_instance_assignment -name IO_STANDARD "1.2-V" -to qsfpdd0_reset_L -entity qeciphy_syn_wrapper +# set_instance_assignment -name IO_STANDARD "1.2-V" -to qsfpdd0_Initmode -entity qeciphy_syn_wrapper +# set_instance_assignment -name IO_STANDARD "1.2-V" -to qsfpdd0_modprs_L -entity qeciphy_syn_wrapper +# set_instance_assignment -name IO_STANDARD "1.2-V" -to qsfpdd0_int_L -entity qeciphy_syn_wrapper +# set_instance_assignment -name SLEW_RATE 1 -to qsfpdd0_modsel_L -entity qeciphy_syn_wrapper +# set_instance_assignment -name SLEW_RATE 1 -to qsfpdd0_reset_L -entity qeciphy_syn_wrapper +# set_instance_assignment -name SLEW_RATE 1 -to qsfpdd0_Initmode -entity qeciphy_syn_wrapper \ No newline at end of file diff --git a/example_designs/de10/syn/signal_tap.stp b/example_designs/de10/syn/signal_tap.stp new file mode 100644 index 0000000..75a4e3b --- /dev/null +++ b/example_designs/de10/syn/signal_tap.stp @@ -0,0 +1,549 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 11111111111111111111111111111111111111111111111111111111111111111111111111 + 11111111111111111111111111111111111111111111111111111111111111111111111111 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/example_designs/kasliSoC/src.f b/example_designs/kasliSoC/src.f index 7d693b5..5485da7 100644 --- a/example_designs/kasliSoC/src.f +++ b/example_designs/kasliSoC/src.f @@ -1,2 +1,2 @@ --F src.f -example_designs/kasliSoC/src/qeciphy_syn_wrapper.sv \ No newline at end of file +-F src_xilinx.f +example_designs/kasliSoC/src/qeciphy_syn_wrapper.sv diff --git a/example_designs/vendors/altera/25.3.1/ip/qeciphy_vio.tcl b/example_designs/vendors/altera/25.3.1/ip/qeciphy_vio.tcl new file mode 100644 index 0000000..f7d256d --- /dev/null +++ b/example_designs/vendors/altera/25.3.1/ip/qeciphy_vio.tcl @@ -0,0 +1,69 @@ +package require -exact qsys 25.3.1 + +# create the system "qeciphy_vio" +# --- Parameters: overridden by $argv when called from quartus_ip.tcl --- +set device "AGFB014R24B2E2V" +set device_family "Agilex 7" + +if {[llength $argv] >= 1} { set device [lindex $argv 0] } +if {[llength $argv] >= 2} { set device_family [lindex $argv 1] } + +proc do_create_qeciphy_vio {} { + global device device_family + #create the system + create_system qeciphy_vio + set_project_property BOARD {default} + set_project_property DEVICE $device + set_project_property DEVICE_FAMILY $device_family + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance in_system_sources_probes_0 altera_in_system_sources_probes 19.2.1 + set_instance_parameter_value in_system_sources_probes_0 {create_source_clock} {1} + set_instance_parameter_value in_system_sources_probes_0 {create_source_clock_enable} {0} + set_instance_parameter_value in_system_sources_probes_0 {gui_use_auto_index} {1} + set_instance_parameter_value in_system_sources_probes_0 {instance_id} {NONE} + set_instance_parameter_value in_system_sources_probes_0 {probe_width} {0} + set_instance_parameter_value in_system_sources_probes_0 {sld_instance_index} {0} + set_instance_parameter_value in_system_sources_probes_0 {source_initial_value} {1} + set_instance_parameter_value in_system_sources_probes_0 {source_width} {1} + set_instance_property in_system_sources_probes_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property sources EXPORT_OF in_system_sources_probes_0.sources + set_interface_property source_clk EXPORT_OF in_system_sources_probes_0.source_clk + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {qeciphy_vio.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {qeciphy_vio} + + # save the system + sync_sysinfo_parameters + save_system qeciphy_vio +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_qeciphy_vio + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/example_designs/vendors/altera/25.3.1/ip/reset_release.tcl b/example_designs/vendors/altera/25.3.1/ip/reset_release.tcl new file mode 100644 index 0000000..a7c3356 --- /dev/null +++ b/example_designs/vendors/altera/25.3.1/ip/reset_release.tcl @@ -0,0 +1,61 @@ +package require -exact qsys 25.3.1 + +# create the system "reset_release" +# --- Parameters: overridden by $argv when called from quartus_ip.tcl --- +set device "AGIB027R31B1E1V" +set device_family "Agilex 7" + +if {[llength $argv] >= 1} { set device [lindex $argv 0] } +if {[llength $argv] >= 2} { set device_family [lindex $argv 1] } + +proc do_create_reset_release {} { + global device device_family + #create the system + create_system reset_release + set_project_property BOARD {default} + set_project_property DEVICE $device + set_project_property DEVICE_FAMILY $device_family + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance s10_user_rst_clkgate_0 altera_s10_user_rst_clkgate 19.4.9 + set_instance_parameter_value s10_user_rst_clkgate_0 {outputType} {Reset Interface} + set_instance_property s10_user_rst_clkgate_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property ninit_done EXPORT_OF s10_user_rst_clkgate_0.ninit_done + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {reset_release.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {reset_release} + + # save the system + sync_sysinfo_parameters + save_system reset_release +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_reset_release + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/example_designs/vendors/altera/25.3.1/ip/sys_clk_100.tcl b/example_designs/vendors/altera/25.3.1/ip/sys_clk_100.tcl new file mode 100644 index 0000000..e6611f1 --- /dev/null +++ b/example_designs/vendors/altera/25.3.1/ip/sys_clk_100.tcl @@ -0,0 +1,68 @@ +package require -exact qsys 25.3.1 + +# create the system "sys_clk_100" +# --- Parameters: overridden by $argv when called from quartus_ip.tcl --- +set device "AGFB014R24B2E2V" +set device_family "Agilex 7" + +if {[llength $argv] >= 1} { set device [lindex $argv 0] } +if {[llength $argv] >= 2} { set device_family [lindex $argv 1] } + +proc do_create_sys_clk_100 {} { + global device device_family + #create the system + create_system sys_clk_100 + set_project_property BOARD {default} + set_project_property DEVICE $device + set_project_property DEVICE_FAMILY $device_family + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance intelclkctrl_0 intelclkctrl 2.0.1 + set_instance_parameter_value intelclkctrl_0 {CLOCK_DIVIDER} {0} + set_instance_parameter_value intelclkctrl_0 {CLOCK_DIVIDER_OUTPUTS} {1} + set_instance_parameter_value intelclkctrl_0 {ENABLE} {0} + set_instance_parameter_value intelclkctrl_0 {ENABLE_REGISTER_TYPE} {1} + set_instance_parameter_value intelclkctrl_0 {ENABLE_TYPE} {2} + set_instance_parameter_value intelclkctrl_0 {GLITCH_FREE_SWITCHOVER} {1} + set_instance_parameter_value intelclkctrl_0 {NUM_CLOCKS} {1} + set_instance_property intelclkctrl_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property inclk EXPORT_OF intelclkctrl_0.inclk + set_interface_property outclk EXPORT_OF intelclkctrl_0.outclk + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {sys_clk_100.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {sys_clk_100} + + # save the system + sync_sysinfo_parameters + save_system sys_clk_100 +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_sys_clk_100 + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/example_designs/vendors/altera/25.3.1/ip/sys_clk_200_pll.tcl b/example_designs/vendors/altera/25.3.1/ip/sys_clk_200_pll.tcl new file mode 100644 index 0000000..3522da7 --- /dev/null +++ b/example_designs/vendors/altera/25.3.1/ip/sys_clk_200_pll.tcl @@ -0,0 +1,321 @@ +package require -exact qsys 25.3.1 + +# create the system "sys_clk_200_pll" +# --- Parameters: overridden by $argv when called from quartus_ip.tcl --- +set device "AGFB014R24B2E2V" +set device_family "Agilex 7" + +if {[llength $argv] >= 1} { set device [lindex $argv 0] } +if {[llength $argv] >= 2} { set device_family [lindex $argv 1] } + +proc do_create_sys_clk_200_pll {} { + global device device_family + #create the system + create_system sys_clk_200_pll + set_project_property BOARD {default} + set_project_property DEVICE $device + set_project_property DEVICE_FAMILY $device_family + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance iopll_0 altera_iopll 21.0.0 + set_instance_parameter_value iopll_0 {gui_active_clk} {0} + set_instance_parameter_value iopll_0 {gui_c_cnt_in_src0} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_c_cnt_in_src1} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_c_cnt_in_src2} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_c_cnt_in_src3} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_c_cnt_in_src4} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_c_cnt_in_src5} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_c_cnt_in_src6} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_c_cnt_in_src7} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_c_cnt_in_src8} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_cal_code_hex_file} {iossm.hex} + set_instance_parameter_value iopll_0 {gui_cal_converge} {0} + set_instance_parameter_value iopll_0 {gui_cal_error} {cal_clean} + set_instance_parameter_value iopll_0 {gui_cascade_counter0} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter1} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter10} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter11} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter12} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter13} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter14} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter15} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter16} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter17} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter2} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter3} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter4} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter5} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter6} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter7} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter8} {0} + set_instance_parameter_value iopll_0 {gui_cascade_counter9} {0} + set_instance_parameter_value iopll_0 {gui_cascade_outclk_index} {0} + set_instance_parameter_value iopll_0 {gui_clk_bad} {0} + set_instance_parameter_value iopll_0 {gui_clock_name_global} {0} + set_instance_parameter_value iopll_0 {gui_clock_name_instantiation} {1} + set_instance_parameter_value iopll_0 {gui_clock_name_string0} {axis_clk} + set_instance_parameter_value iopll_0 {gui_clock_name_string1} {outclk1} + set_instance_parameter_value iopll_0 {gui_clock_name_string10} {outclk10} + set_instance_parameter_value iopll_0 {gui_clock_name_string11} {outclk11} + set_instance_parameter_value iopll_0 {gui_clock_name_string12} {outclk12} + set_instance_parameter_value iopll_0 {gui_clock_name_string13} {outclk13} + set_instance_parameter_value iopll_0 {gui_clock_name_string14} {outclk14} + set_instance_parameter_value iopll_0 {gui_clock_name_string15} {outclk15} + set_instance_parameter_value iopll_0 {gui_clock_name_string16} {outclk16} + set_instance_parameter_value iopll_0 {gui_clock_name_string17} {outclk17} + set_instance_parameter_value iopll_0 {gui_clock_name_string2} {outclk2} + set_instance_parameter_value iopll_0 {gui_clock_name_string3} {outclk3} + set_instance_parameter_value iopll_0 {gui_clock_name_string4} {outclk4} + set_instance_parameter_value iopll_0 {gui_clock_name_string5} {outclk5} + set_instance_parameter_value iopll_0 {gui_clock_name_string6} {outclk6} + set_instance_parameter_value iopll_0 {gui_clock_name_string7} {outclk7} + set_instance_parameter_value iopll_0 {gui_clock_name_string8} {outclk8} + set_instance_parameter_value iopll_0 {gui_clock_name_string9} {outclk9} + set_instance_parameter_value iopll_0 {gui_clock_to_compensate} {0} + set_instance_parameter_value iopll_0 {gui_debug_mode} {0} + set_instance_parameter_value iopll_0 {gui_divide_factor_c0} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c1} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c10} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c11} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c12} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c13} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c14} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c15} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c16} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c17} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c2} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c3} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c4} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c5} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c6} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c7} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c8} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_c9} {6} + set_instance_parameter_value iopll_0 {gui_divide_factor_n} {1} + set_instance_parameter_value iopll_0 {gui_dps_cntr} {C0} + set_instance_parameter_value iopll_0 {gui_dps_dir} {Positive} + set_instance_parameter_value iopll_0 {gui_dps_num} {1} + set_instance_parameter_value iopll_0 {gui_dsm_out_sel} {1st_order} + set_instance_parameter_value iopll_0 {gui_duty_cycle0} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle1} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle10} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle11} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle12} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle13} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle14} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle15} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle16} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle17} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle2} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle3} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle4} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle5} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle6} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle7} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle8} {50.0} + set_instance_parameter_value iopll_0 {gui_duty_cycle9} {50.0} + set_instance_parameter_value iopll_0 {gui_en_adv_params} {0} + set_instance_parameter_value iopll_0 {gui_en_dps_ports} {0} + set_instance_parameter_value iopll_0 {gui_en_extclkout_ports} {0} + set_instance_parameter_value iopll_0 {gui_en_hvio_reconf} {0} + set_instance_parameter_value iopll_0 {gui_en_iossm_reconf} {0} + set_instance_parameter_value iopll_0 {gui_en_lvds_ports} {Disabled} + set_instance_parameter_value iopll_0 {gui_en_periphery_ports} {0} + set_instance_parameter_value iopll_0 {gui_en_phout_ports} {0} + set_instance_parameter_value iopll_0 {gui_en_reconf} {0} + set_instance_parameter_value iopll_0 {gui_enable_cascade_in} {0} + set_instance_parameter_value iopll_0 {gui_enable_cascade_out} {0} + set_instance_parameter_value iopll_0 {gui_enable_mif_dps} {0} + set_instance_parameter_value iopll_0 {gui_enable_output_counter_cascading} {0} + set_instance_parameter_value iopll_0 {gui_enable_permit_cal} {0} + set_instance_parameter_value iopll_0 {gui_enable_upstream_out_clk} {0} + set_instance_parameter_value iopll_0 {gui_existing_mif_file_path} {~/pll.mif} + set_instance_parameter_value iopll_0 {gui_extclkout_0_source} {C0} + set_instance_parameter_value iopll_0 {gui_extclkout_1_source} {C0} + set_instance_parameter_value iopll_0 {gui_extclkout_source} {C0} + set_instance_parameter_value iopll_0 {gui_feedback_clock} {Global Clock} + set_instance_parameter_value iopll_0 {gui_fix_vco_frequency} {0} + set_instance_parameter_value iopll_0 {gui_fixed_vco_frequency} {600.0} + set_instance_parameter_value iopll_0 {gui_fixed_vco_frequency_ps} {1667.0} + set_instance_parameter_value iopll_0 {gui_frac_multiply_factor} {0.0} + set_instance_parameter_value iopll_0 {gui_fractional_cout} {24} + set_instance_parameter_value iopll_0 {gui_include_iossm} {0} + set_instance_parameter_value iopll_0 {gui_location_type} {I/O Bank} + set_instance_parameter_value iopll_0 {gui_lock_setting} {Low Lock Time} + set_instance_parameter_value iopll_0 {gui_mif_config_name} {unnamed} + set_instance_parameter_value iopll_0 {gui_mif_gen_options} {Generate New MIF File} + set_instance_parameter_value iopll_0 {gui_multiply_factor} {6} + set_instance_parameter_value iopll_0 {gui_multiply_fraction} {0} + set_instance_parameter_value iopll_0 {gui_new_mif_file_path} {~/pll.mif} + set_instance_parameter_value iopll_0 {gui_number_of_clocks} {1} + set_instance_parameter_value iopll_0 {gui_operation_mode} {direct} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency0} {200.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency1} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency10} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency11} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency12} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency13} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency14} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency15} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency16} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency17} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency2} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency3} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency4} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency5} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency6} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency7} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency8} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency9} {100.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps0} {5000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps1} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps10} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps11} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps12} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps13} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps14} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps15} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps16} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps17} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps2} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps3} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps4} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps5} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps6} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps7} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps8} {10000.0} + set_instance_parameter_value iopll_0 {gui_output_clock_frequency_ps9} {10000.0} + set_instance_parameter_value iopll_0 {gui_parameter_table_hex_file} {seq_params_sim.hex} + set_instance_parameter_value iopll_0 {gui_phase_shift0} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift1} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift10} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift11} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift12} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift13} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift14} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift15} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift16} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift17} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift2} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift3} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift4} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift5} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift6} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift7} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift8} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift9} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg0} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg1} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg10} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg11} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg12} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg13} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg14} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg15} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg16} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg17} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg2} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg3} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg4} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg5} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg6} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg7} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg8} {0.0} + set_instance_parameter_value iopll_0 {gui_phase_shift_deg9} {0.0} + set_instance_parameter_value iopll_0 {gui_phout_division} {1} + set_instance_parameter_value iopll_0 {gui_pll_auto_reset} {0} + set_instance_parameter_value iopll_0 {gui_pll_bandwidth_preset} {Low} + set_instance_parameter_value iopll_0 {gui_pll_cal_done} {0} + set_instance_parameter_value iopll_0 {gui_pll_cascading_mode} {adjpllin} + set_instance_parameter_value iopll_0 {gui_pll_freqcal_en} {1} + set_instance_parameter_value iopll_0 {gui_pll_freqcal_req_flag} {1} + set_instance_parameter_value iopll_0 {gui_pll_m_cnt_in_src} {c_m_cnt_in_src_ph_mux_clk} + set_instance_parameter_value iopll_0 {gui_pll_mode} {Integer-N PLL} + set_instance_parameter_value iopll_0 {gui_pll_tclk_mux_en} {0} + set_instance_parameter_value iopll_0 {gui_pll_tclk_sel} {pll_tclk_m_src} + set_instance_parameter_value iopll_0 {gui_pll_type} {S10_Physical} + set_instance_parameter_value iopll_0 {gui_pll_vco_freq_band_0} {pll_freq_clk0_band18} + set_instance_parameter_value iopll_0 {gui_pll_vco_freq_band_1} {pll_freq_clk1_band18} + set_instance_parameter_value iopll_0 {gui_prot_mode} {UNUSED} + set_instance_parameter_value iopll_0 {gui_ps_units0} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units1} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units10} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units11} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units12} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units13} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units14} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units15} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units16} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units17} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units2} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units3} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units4} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units5} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units6} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units7} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units8} {ps} + set_instance_parameter_value iopll_0 {gui_ps_units9} {ps} + set_instance_parameter_value iopll_0 {gui_refclk1_frequency} {100.0} + set_instance_parameter_value iopll_0 {gui_refclk_might_change} {0} + set_instance_parameter_value iopll_0 {gui_refclk_switch} {0} + set_instance_parameter_value iopll_0 {gui_reference_clock_frequency} {100.0} + set_instance_parameter_value iopll_0 {gui_reference_clock_frequency_ps} {10000.0} + set_instance_parameter_value iopll_0 {gui_simulation_type} {1} + set_instance_parameter_value iopll_0 {gui_skip_sdc_generation} {0} + set_instance_parameter_value iopll_0 {gui_switchover_delay} {0} + set_instance_parameter_value iopll_0 {gui_switchover_mode} {Automatic Switchover} + set_instance_parameter_value iopll_0 {gui_use_NDFB_modes} {0} + set_instance_parameter_value iopll_0 {gui_use_coreclk} {0} + set_instance_parameter_value iopll_0 {gui_use_fractional_division} {0} + set_instance_parameter_value iopll_0 {gui_use_locked} {1} + set_instance_parameter_value iopll_0 {gui_use_logical} {0} + set_instance_parameter_value iopll_0 {gui_use_slvs_refclk} {0} + set_instance_parameter_value iopll_0 {gui_use_slvs_refclk1} {0} + set_instance_parameter_value iopll_0 {gui_user_base_address} {0} + set_instance_parameter_value iopll_0 {gui_usr_device_speed_grade} {1} + set_instance_parameter_value iopll_0 {gui_vco_frequency} {600.0} + set_instance_parameter_value iopll_0 {hp_qsys_scripting_mode} {0} + set_instance_parameter_value iopll_0 {system_info_device_iobank_rev} {} + set_instance_property iopll_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property refclk EXPORT_OF iopll_0.refclk + set_interface_property locked EXPORT_OF iopll_0.locked + set_interface_property reset EXPORT_OF iopll_0.reset + set_interface_property outclk0 EXPORT_OF iopll_0.outclk0 + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {sys_clk_200_pll.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {sys_clk_200_pll} + + # save the system + sync_sysinfo_parameters + save_system sys_clk_200_pll +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_sys_clk_200_pll + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/example_designs/zcu106/src.f b/example_designs/zcu106/src.f index be7f28c..09b154d 100644 --- a/example_designs/zcu106/src.f +++ b/example_designs/zcu106/src.f @@ -1,2 +1,2 @@ --F src.f -example_designs/zcu106/src/qeciphy_syn_wrapper.sv \ No newline at end of file +-F src_xilinx.f +example_designs/zcu106/src/qeciphy_syn_wrapper.sv diff --git a/example_designs/zcu106/syn/constraints.xdc b/example_designs/zcu106/syn/constraints.xdc index e75a595..ce7e90c 100644 --- a/example_designs/zcu106/syn/constraints.xdc +++ b/example_designs/zcu106/syn/constraints.xdc @@ -5,9 +5,9 @@ create_clock -period 6.4 -name gt_refclk [get_ports gt_refclk_in_p] set_property PACKAGE_PIN U10 [get_ports gt_refclk_in_p] -create_generated_clock -name rx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_wrapper/gen_GTH_transceiver.i_BUFG_rx_clk/O}] +create_generated_clock -name rx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_xilinx/gen_GTH_transceiver.i_BUFG_rx_clk/O}] create_generated_clock -name gt_rx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_wrapper*channel_inst/gthe4_channel_gen.gen_gthe4_channel_inst[0].GTHE4_CHANNEL_PRIM_INST/RXOUTCLK}] -create_generated_clock -name tx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_wrapper/gen_GTH_transceiver.i_BUFG_tx_clk/O}] +create_generated_clock -name tx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_xilinx/gen_GTH_transceiver.i_BUFG_tx_clk/O}] create_generated_clock -name gt_tx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_wrapper*channel_inst/gthe4_channel_gen.gen_gthe4_channel_inst[0].GTHE4_CHANNEL_PRIM_INST/TXOUTCLK}] set_clock_groups -asynchronous -group [get_clocks gt_refclk] -group [get_clocks {rx_clk gt_rx_clk}] -group [get_clocks {tx_clk gt_tx_clk}] diff --git a/example_designs/zcu216/src.f b/example_designs/zcu216/src.f index 4334364..2361689 100644 --- a/example_designs/zcu216/src.f +++ b/example_designs/zcu216/src.f @@ -1,2 +1,2 @@ --F src.f -example_designs/zcu216/src/qeciphy_syn_wrapper.sv \ No newline at end of file +-F src_xilinx.f +example_designs/zcu216/src/qeciphy_syn_wrapper.sv diff --git a/example_designs/zcu216/syn/constraints.xdc b/example_designs/zcu216/syn/constraints.xdc index b73417c..f037753 100644 --- a/example_designs/zcu216/syn/constraints.xdc +++ b/example_designs/zcu216/syn/constraints.xdc @@ -5,9 +5,9 @@ create_clock -period 6.4 -name gt_refclk [get_ports gt_refclk_in_p] set_property PACKAGE_PIN H34 [get_ports gt_refclk_in_p] -create_generated_clock -name rx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_wrapper/gen_GTY_transceiver.i_BUFG_rx_clk/O}] +create_generated_clock -name rx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_xilinx/gen_GTY_transceiver.i_BUFG_rx_clk/O}] create_generated_clock -name gt_rx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_wrapper*channel_inst/gtye4_channel_gen.gen_gtye4_channel_inst[0].GTYE4_CHANNEL_PRIM_INST/RXOUTCLK}] -create_generated_clock -name tx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_wrapper/gen_GTY_transceiver.i_BUFG_tx_clk/O}] +create_generated_clock -name tx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_xilinx/gen_GTY_transceiver.i_BUFG_tx_clk/O}] create_generated_clock -name gt_tx_clk [get_pins -hierarchical -filter {NAME =~ *QECIPHY*i_qeciphy_gt_wrapper*channel_inst/gtye4_channel_gen.gen_gtye4_channel_inst[0].GTYE4_CHANNEL_PRIM_INST/TXOUTCLK}] set_clock_groups -asynchronous -group [get_clocks gt_refclk] -group [get_clocks {rx_clk gt_rx_clk}] -group [get_clocks {tx_clk gt_tx_clk}] diff --git a/lint.f b/lint.f index 2e74e4e..9f07ced 100644 --- a/lint.f +++ b/lint.f @@ -1,6 +1,10 @@ -lint_stubs/BUFG_GT.sv -lint_stubs/GTXE2_COMMON.sv -lint_stubs/qeciphy_clk_mmcm.sv -lint_stubs/qeciphy_gty_transceiver.sv -lint_stubs/qeciphy_gtx_transceiver.sv -lint_stubs/qeciphy_gth_transceiver.sv \ No newline at end of file +lint_stubs/xilinx/BUFG_GT.sv +lint_stubs/xilinx/GTXE2_COMMON.sv +lint_stubs/xilinx/qeciphy_clk_mmcm.sv +lint_stubs/xilinx/qeciphy_gty_transceiver.sv +lint_stubs/xilinx/qeciphy_gtx_transceiver.sv +lint_stubs/xilinx/qeciphy_gth_transceiver.sv +lint_stubs/altera/qeciphy_etile.sv +lint_stubs/altera/qeciphy_ftile.sv +lint_stubs/altera/qeciphy_altera_clk_mmcm.sv +lint_stubs/altera/tennm_lcell_comb.sv diff --git a/lint_stubs/altera/qeciphy_altera_clk_mmcm.sv b/lint_stubs/altera/qeciphy_altera_clk_mmcm.sv new file mode 100644 index 0000000..b2d4e35 --- /dev/null +++ b/lint_stubs/altera/qeciphy_altera_clk_mmcm.sv @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: BSD-2-Clause +// ----------------------------------------------------------------------------- +// File : qeciphy_altera_clk_mmcm.sv +// Description : Lint stub for Altera clock divider module. +// Declares the module interface for tooling convenience only. +// No functional implementation is provided. +// +// Copyright (c) 2025 Riverlane Ltd. +// This file is not affiliated with or endorsed by Altera Corporation. +// The module names and ports are reproduced solely for build compatibility. +// ----------------------------------------------------------------------------- + +module qeciphy_altera_clk_mmcm ( + input logic inclk, + output logic clock_div1x, + output logic clock_div2x +); + + assign clock_div1x = '0; + assign clock_div2x = '0; + +endmodule diff --git a/lint_stubs/altera/qeciphy_etile.sv b/lint_stubs/altera/qeciphy_etile.sv new file mode 100644 index 0000000..e11e4eb --- /dev/null +++ b/lint_stubs/altera/qeciphy_etile.sv @@ -0,0 +1,48 @@ +// SPDX-License-Identifier: BSD-2-Clause +// ----------------------------------------------------------------------------- +// File : qeciphy_etile.sv +// Description : Lint stub for Altera Agilex E-Tile transceiver module. +// Declares the module interface for tooling convenience only. +// No functional implementation is provided. +// +// Copyright (c) 2025 Riverlane Ltd. +// This file is not affiliated with or endorsed by Altera Corporation. +// The module names and ports are reproduced solely for build compatibility. +// ----------------------------------------------------------------------------- + +module qeciphy_etile ( + input logic reset, + input logic pll_refclk0, + input logic tx_coreclkin, + input logic rx_coreclkin, + output logic tx_ready, + output logic rx_ready, + output logic tx_pma_ready, + output logic rx_pma_ready, + output logic tx_clkout, + output logic tx_clkout2, + output logic rx_clkout, + output logic rx_clkout2, + output logic tx_serial_data, + output logic tx_serial_data_n, + input logic rx_serial_data, + input logic rx_serial_data_n, + output logic rx_is_lockedtodata, + input logic [79:0] tx_parallel_data, + output logic [79:0] rx_parallel_data +); + + assign tx_ready = '0; + assign rx_ready = '0; + assign tx_pma_ready = '0; + assign rx_pma_ready = '0; + assign tx_clkout = '0; + assign tx_clkout2 = '0; + assign rx_clkout = '0; + assign rx_clkout2 = '0; + assign tx_serial_data = '0; + assign tx_serial_data_n = '0; + assign rx_is_lockedtodata = '0; + assign rx_parallel_data = '0; + +endmodule diff --git a/lint_stubs/altera/qeciphy_ftile.sv b/lint_stubs/altera/qeciphy_ftile.sv new file mode 100644 index 0000000..1e93233 --- /dev/null +++ b/lint_stubs/altera/qeciphy_ftile.sv @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: BSD-2-Clause +// ----------------------------------------------------------------------------- +// File : qeciphy_ftile.sv +// Description : Lint stub for Altera Agilex F-Tile transceiver module. +// Declares the module interface for tooling convenience only. +// No functional implementation is provided. +// +// Copyright (c) 2025 Riverlane Ltd. +// This file is not affiliated with or endorsed by Altera Corporation. +// The module names and ports are reproduced solely for build compatibility. +// ----------------------------------------------------------------------------- + +module qeciphy_ftile ( + input logic rx_cdr_refclk_link, + input logic tx_pll_refclk_link, + input logic tx_reset, + input logic rx_reset, + output logic tx_reset_ack, + output logic rx_reset_ack, + output logic tx_ready, + output logic rx_ready, + input logic tx_coreclkin, + input logic rx_coreclkin, + output logic tx_clkout, + output logic tx_clkout2, + output logic rx_clkout, + output logic rx_clkout2, + output logic tx_serial_data, + output logic tx_serial_data_n, + input logic rx_serial_data, + input logic rx_serial_data_n, + output logic tx_pll_locked, + output logic rx_is_lockedtodata, + output logic rx_is_lockedtoref, + output logic tx_fifo_full, + output logic tx_fifo_empty, + output logic tx_pmaif_fifo_empty, + output logic tx_pmaif_fifo_pempty, + output logic tx_pmaif_fifo_pfull, + input logic [79:0] tx_parallel_data, + output logic [79:0] rx_parallel_data +); + + assign tx_reset_ack = '0; + assign rx_reset_ack = '0; + assign tx_ready = '0; + assign rx_ready = '0; + assign tx_clkout = '0; + assign tx_clkout2 = '0; + assign rx_clkout = '0; + assign rx_clkout2 = '0; + assign tx_serial_data = '0; + assign tx_serial_data_n = '0; + assign tx_pll_locked = '0; + assign rx_is_lockedtodata = '0; + assign rx_is_lockedtoref = '0; + assign tx_fifo_full = '0; + assign tx_fifo_empty = '0; + assign tx_pmaif_fifo_empty = '0; + assign tx_pmaif_fifo_pempty = '0; + assign tx_pmaif_fifo_pfull = '0; + assign rx_parallel_data = '0; + +endmodule diff --git a/lint_stubs/altera/tennm_lcell_comb.sv b/lint_stubs/altera/tennm_lcell_comb.sv new file mode 100644 index 0000000..ff061b6 --- /dev/null +++ b/lint_stubs/altera/tennm_lcell_comb.sv @@ -0,0 +1,39 @@ +// SPDX-License-Identifier: BSD-2-Clause +// ----------------------------------------------------------------------------- +// File : tennm_lcell_comb.sv +// Description : Lint stub for Altera Agilex (Tennm) LUT primitive. +// Declares the module interface for tooling convenience only. +// No functional implementation is provided. +// +// Copyright (c) 2025 Riverlane Ltd. +// This file is not affiliated with or endorsed by Altera Corporation. +// The module names and ports are reproduced solely for build compatibility. +// ----------------------------------------------------------------------------- + +module tennm_lcell_comb #( + parameter [63:0] lut_mask = 64'h0, + parameter extended_lut = "off", + parameter shared_arith = "off" +) ( + input logic dataa, + input logic datab, + input logic datac, + input logic datad, + input logic datae, + input logic dataf, + input logic datag, + input logic datah, + input logic cin, + input logic sharein, + output logic sumout, + output logic cout, + output logic shareout, + output logic combout +); + + assign combout = '0; + assign sumout = '0; + assign cout = '0; + assign shareout = '0; + +endmodule diff --git a/lint_stubs/BUFG_GT.sv b/lint_stubs/xilinx/BUFG_GT.sv similarity index 100% rename from lint_stubs/BUFG_GT.sv rename to lint_stubs/xilinx/BUFG_GT.sv diff --git a/lint_stubs/GTXE2_COMMON.sv b/lint_stubs/xilinx/GTXE2_COMMON.sv similarity index 100% rename from lint_stubs/GTXE2_COMMON.sv rename to lint_stubs/xilinx/GTXE2_COMMON.sv diff --git a/lint_stubs/qeciphy_clk_mmcm.sv b/lint_stubs/xilinx/qeciphy_clk_mmcm.sv similarity index 100% rename from lint_stubs/qeciphy_clk_mmcm.sv rename to lint_stubs/xilinx/qeciphy_clk_mmcm.sv diff --git a/lint_stubs/qeciphy_gth_transceiver.sv b/lint_stubs/xilinx/qeciphy_gth_transceiver.sv similarity index 100% rename from lint_stubs/qeciphy_gth_transceiver.sv rename to lint_stubs/xilinx/qeciphy_gth_transceiver.sv diff --git a/lint_stubs/qeciphy_gtx_transceiver.sv b/lint_stubs/xilinx/qeciphy_gtx_transceiver.sv similarity index 100% rename from lint_stubs/qeciphy_gtx_transceiver.sv rename to lint_stubs/xilinx/qeciphy_gtx_transceiver.sv diff --git a/lint_stubs/qeciphy_gty_transceiver.sv b/lint_stubs/xilinx/qeciphy_gty_transceiver.sv similarity index 100% rename from lint_stubs/qeciphy_gty_transceiver.sv rename to lint_stubs/xilinx/qeciphy_gty_transceiver.sv diff --git a/lint_waivers.vlt b/lint_waivers.vlt index df3b6fe..abd08d5 100644 --- a/lint_waivers.vlt +++ b/lint_waivers.vlt @@ -10,9 +10,9 @@ lint_off -rule UNUSEDSIGNAL -file "*qeciphy_serdes.sv" -match "Signal is not lint_off -rule UNUSEDSIGNAL -file "*qeciphy_rx_monitor.sv" -match "Bits of signal are not used: 'faw'[62:0]" // Diagnostic signals kept in place although not used -lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_wrapper.sv" -match "Signal is not used: 'rxbyteisaligned'" -lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_wrapper.sv" -match "Signal is not used: 'rxcommadet'" -lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_wrapper.sv" -match "Signal is not used: 'cdr_stable'" +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_xilinx.sv" -match "Signal is not used: 'rxbyteisaligned'" +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_xilinx.sv" -match "Signal is not used: 'rxcommadet'" +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_xilinx.sv" -match "Signal is not used: 'cdr_stable'" // Currently unused as crc45_valid and crcvw_valid coincides, only one of them is used lint_off -rule UNUSEDSIGNAL -file "*qeciphy_crc_compute.sv" -match "Signal is not used: 'crc45_valid'" @@ -29,45 +29,90 @@ lint_off -rule PINCONNECTEMPTY -file "*QECIPHY.sv" -match "Cell pin connected by lint_off -rule PINCONNECTEMPTY -file "*QECIPHY.sv" -match "Cell pin connected by name with empty reference: 'wwcount'" // GTY / GTH transceivers -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'qpll0lock_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'qpll0outclk_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'qpll0outrefclk_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'rxctrl0_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'rxctrl1_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'rxctrl2_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'rxctrl3_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'qpll0lock_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'qpll0outclk_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'qpll0outrefclk_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'rxctrl0_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'rxctrl1_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'rxctrl2_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'rxctrl3_out'" // GTX transceiver -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_drpdo_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_drprdy_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_dmonitorout_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_eyescandataerror_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxdisperr_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxnotintable_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxmonitorout_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxoutclkfabric_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxcharisk_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_txoutclkfabric_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_txoutclkpcs_out'" -lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_wrapper.sv" -match "Cell pin connected by name with empty reference: 'gt0_txresetdone_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_drpdo_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_drprdy_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_dmonitorout_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_eyescandataerror_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxdisperr_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxnotintable_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxmonitorout_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxoutclkfabric_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_rxcharisk_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_txoutclkfabric_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_txoutclkpcs_out'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_xilinx.sv" -match "Cell pin connected by name with empty reference: 'gt0_txresetdone_out'" lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gtx_common.sv" -match "Cell pin connected by name with empty reference: *" -// Ignore linting errors for lint stub files - -lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/BUFG_GT.sv" - -lint_off -rule UNUSEDPARAM -file "*lint_stubs/GTXE2_COMMON.sv" -lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/GTXE2_COMMON.sv" +// Altera GT wrapper - 8b10b decoder unconnected outputs +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'dout_k'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'dout_kerr'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'dout_rderr'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'dout_rdreg'" + +// Altera GT wrapper - comma detect unused output +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'rx_datapath_resetn_o'" + +// E-Tile transceiver unconnected outputs +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'tx_pma_ready'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'rx_pma_ready'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'tx_clkout'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'rx_clkout'" + +// F-Tile transceiver unconnected outputs +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'tx_fifo_full'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'tx_fifo_empty'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'tx_pmaif_fifo_empty'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'tx_pmaif_fifo_pempty'" +lint_off -rule PINCONNECTEMPTY -file "*qeciphy_gt_altera.sv" -match "Cell pin connected by name with empty reference: 'tx_pmaif_fifo_pfull'" + +// Altera GT wrapper - signals used only in FTILE generate path (not visible to lint in ETILE-only flow) +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_altera.sv" -match "Signal is not used: 'tx_reset_ack'" +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_altera.sv" -match "Signal is not driven, nor used: 'tx_pll_locked'" +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_altera.sv" -match "Signal is not used: 'rx_reset_ack'" +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_altera.sv" -match "Signal is not used: 'rx_freqlocked'" +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_altera.sv" -match "Signal is not driven, nor used: 'rx_is_locked_to_ref'" + +// Altera GT wrapper - tile parallel data struct reserved fields are intentionally unused +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_gt_altera.sv" -match "Bits of signal are not used: 'rx_parallel_data'*" + +// Word aligner - full width registered for pipeline but only lower WORD_SIZE bits checked for comma +lint_off -rule UNUSEDSIGNAL -file "*qeciphy_word_align.sv" -match "Bits of signal are not used: 'rx_data_q'*" -lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/qeciphy_clk_mmcm.sv" +// Ignore linting errors for lint stub files -lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/qeciphy_gtx_transceiver.sv" +//Xilinx Lint Stubs +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/xilinx/BUFG_GT.sv" +lint_off -rule UNUSEDPARAM -file "*lint_stubs/xilinx/GTXE2_COMMON.sv" +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/xilinx/GTXE2_COMMON.sv" +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/xilinx/qeciphy_gtx_transceiver.sv" +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/xilinx/qeciphy_gth_transceiver.sv" +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/xilinx/qeciphy_gty_transceiver.sv" +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/xilinx/qeciphy_clk_mmcm.sv" -lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/qeciphy_gth_transceiver.sv" -lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/qeciphy_gty_transceiver.sv" +//Altera Lint Stubs +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/altera/qeciphy_etile.sv" +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/altera/qeciphy_ftile.sv" +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/altera/qeciphy_altera_clk_mmcm.sv" +lint_off -rule UNUSEDPARAM -file "*lint_stubs/altera/tennm_lcell_comb.sv" +lint_off -rule UNUSEDSIGNAL -file "*lint_stubs/altera/tennm_lcell_comb.sv" // Ignore linting package files lint_off -file "*qeciphy_*pkg.sv" + +// Ignore linting Altera-provided 8b10b files +lint_off -file "*eth_8b10b_dec_a.v" +lint_off -file "*eth_8b10b_dec_x4_a.v" +lint_off -file "*eth_8b10b_enc_a.v" +lint_off -file "*eth_8b10b_enc_x4_a.v" diff --git a/scripts/extract_sources.py b/scripts/extract_sources.py index d513b35..1e75e6f 100644 --- a/scripts/extract_sources.py +++ b/scripts/extract_sources.py @@ -26,7 +26,7 @@ def process_f_file(filepath, root, visited): sub_sources, sub_incdirs = process_f_file(subfile_path, root, visited) sources.extend(sub_sources) incdirs.extend(sub_incdirs) - elif line.endswith(".sv") or line.endswith(".v") or line.endswith(".xci"): + elif line.endswith(".sv") or line.endswith(".v") or line.endswith(".xci") or line.endswith(".ip"): sources.append(line) except Exception as e: sys.stderr.write(f"Error reading file {filepath}: {e}\n") diff --git a/scripts/generate_sim_files.py b/scripts/generate_sim_files.py index ec3048d..1e835cf 100644 --- a/scripts/generate_sim_files.py +++ b/scripts/generate_sim_files.py @@ -25,7 +25,7 @@ GENERATED_SIM_FILES_DIR = "tb/generated_sim_files" IP_SIM_EXPORT_DIR = "run/ip_sim_export" GENERATED_SIM_F = "generated_sim.f" -XCI_DIR = "xci" +XCI_DIR = "generated_ip" # HDL file extensions in priority order (longest first to avoid partial matches) HDL_EXTENSIONS = ("vhdl", "vhd", "sv", "v") diff --git a/scripts/quartus_ip_gen_proj.tcl b/scripts/quartus_ip_gen_proj.tcl new file mode 100644 index 0000000..1a9000e --- /dev/null +++ b/scripts/quartus_ip_gen_proj.tcl @@ -0,0 +1,38 @@ +# SPDX-License-Identifier: BSD-2-Clause +# Copyright (c) 2026 Riverlane Ltd. +# +# Creates a minimal Quartus project for IP generation. +# +# Called from Makefile quartus_generate_ip target via: +# quartus_sh --script scripts/quartus_ip_gen_proj.tcl -tclargs \ +# +# +# argv[0] = proj_dir absolute path where the project should be created +# argv[1] = proj_name e.g. altera_ip_gen +# argv[2] = family e.g. Agilex 7 +# argv[3] = device e.g. AGFB014R24B2E2V + +package require ::quartus::project + +if {[llength $argv] > 0 && [string match "*tcl*" [lindex $argv 0]]} { + set argv [lrange $argv 1 end] +} + +if {[llength $argv] < 4} { + puts "ERROR: quartus_ip_gen_proj.tcl requires 4 arguments: proj_dir proj_name family device" + exit 1 +} + +set proj_dir [lindex $argv 0] +set proj_name [lindex $argv 1] +set family [lindex $argv 2] +set device [lindex $argv 3] + +file mkdir [file join $proj_dir "ip"] +cd $proj_dir +project_new -revision $proj_name $proj_name +set_global_assignment -name FAMILY "$family" +set_global_assignment -name DEVICE "$device" +export_assignments +project_close +puts "INFO: Created project '$proj_name' in $proj_dir" diff --git a/scripts/quartus_proj.tcl b/scripts/quartus_proj.tcl new file mode 100644 index 0000000..c89cc53 --- /dev/null +++ b/scripts/quartus_proj.tcl @@ -0,0 +1,280 @@ +# SPDX-License-Identifier: BSD-2-Clause +# Copyright (c) 2026 Riverlane Ltd. +# +# quartus_proj.tcl — Dynamic Quartus project creation and compilation. +# +# Called from Makefile quartus_synth target via: +# quartus_sh --script scripts/quartus_proj.tcl -tclargs \ +# \ +# -- +# +# argv[0] = top_level_entity e.g. qeciphy_syn_wrapper +# argv[1] = constraints space-separated list of .sdc/.tcl paths +# argv[2] = device e.g. AGFB014R24B2E2V +# argv[3] = device_family e.g. Agilex 7 +# argv[4] = variant ETILE or FTILE +# argv[5] = hooks space-separated list of Platform Designer script paths +# argv[6+] = syn_files SRC_FILES and SYN_FILES (before --) +# -- = separator +# argv[N+] = ip_files GENIP_FILES (after --) + +package require ::quartus::project + +# --------------------------------------------------------------------------- +# Parse arguments +# --------------------------------------------------------------------------- +# quartus_sh --script puts the script path as argv[0]; strip it. +if {[llength $argv] > 0 && [string match "*tcl*" [lindex $argv 0]]} { + set argv [lrange $argv 1 end] +} + +if {[llength $argv] < 6} { + puts "ERROR: quartus_proj.tcl requires at least 6 arguments." + puts " top_level constraints device device_family variant hooks [syn_files...] -- [ip_files...]" + exit 1 +} + +set proj_name "synth_qeciphy" + +set top_entity [lindex $argv 0] +set constraints [lindex $argv 1] +set proj_device [lindex $argv 2] +set device_family [lindex $argv 3] +set variant [lindex $argv 4] +set hooks_raw [lindex $argv 5] + +set hooks [split $hooks_raw] + +# Parse file arguments separated by "--" +set separator_index -1 +for {set i 0} {$i < [llength $argv]} {incr i} { + if {[lindex $argv $i] eq "--"} { + set separator_index $i + break + } +} + +if {$separator_index == -1} { + set syn_files [lrange $argv 6 end] + set ip_files {} +} else { + set syn_files [lrange $argv 6 [expr {$separator_index - 1}]] + set ip_files [lrange $argv [expr {$separator_index + 1}] end] +} + +# --------------------------------------------------------------------------- +# File type classification +# --------------------------------------------------------------------------- +proc get_file_assignment {filepath} { + set ext [string tolower [file extension $filepath]] + switch -- $ext { + ".sv" { return "SYSTEMVERILOG_FILE" } + ".v" { return "VERILOG_FILE" } + ".vhd" - ".vhdl" { return "VHDL_FILE" } + ".sdc" - ".tcl" { return "SDC_FILE" } + ".ip" { return "IP_FILE" } + ".qip" { return "QIP_FILE" } + default { return "" } + } +} + +# --------------------------------------------------------------------------- +# Create project directory structure +# --------------------------------------------------------------------------- +set start_dir [pwd] + +set target_dir [file normalize [file join $start_dir "run"]] +if {![file isdirectory $target_dir]} { + file mkdir $target_dir + puts "INFO: Created run directory: $target_dir" +} + +set proj_dir [file join $target_dir $proj_name] +if {![file isdirectory $proj_dir]} { + file mkdir $proj_dir + puts "INFO: Created project directory: $proj_dir" +} + +# Create ip/ subdirectory so IP_FILE refs resolve after quartus_ip.tcl runs +file mkdir [file join $proj_dir "ip"] + +cd $proj_dir +puts "INFO: Working in project directory: [pwd]" + +# --------------------------------------------------------------------------- +# Open or create project +# --------------------------------------------------------------------------- +set need_to_close_project 0 +set make_assignments 1 + +if {[is_project_open]} { + if {[string compare $quartus(project) $proj_name] != 0} { + puts "WARNING: A different project is open. Skipping assignments." + set make_assignments 0 + } +} else { + if {[project_exists $proj_name]} { + project_open -revision $proj_name $proj_name + } else { + project_new -revision $proj_name $proj_name + } + set need_to_close_project 1 +} +cd ../../ +if {$make_assignments} { + + # Static project settings + + set_global_assignment -name ORIGINAL_QUARTUS_VERSION 25.3.1 + set_global_assignment -name LAST_QUARTUS_VERSION "25.3.1 Pro Edition" + set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files + set_global_assignment -name FAMILY $device_family + set_global_assignment -name DEVICE $proj_device + set_global_assignment -name DEVICE_INITIALIZATION_CLOCK OSC_CLK_1_125MHZ + set_global_assignment -name TOP_LEVEL_ENTITY $top_entity + set_global_assignment -name VERILOG_INPUT_VERSION SYSTEMVERILOG_2012 + set_global_assignment -name VHDL_INPUT_VERSION VHDL_2019 + set_global_assignment -name FLOW_DISABLE_ASSEMBLER OFF + set_global_assignment -name PROJECT_IP_REGENERATION_POLICY ALWAYS_REGENERATE_IP + set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR 1 + set_global_assignment -name BOARD default + set_global_assignment -name GENERATE_PROGRAMMING_FILES ON + + # Source and synthesis files — classified by extension + foreach f $syn_files { + set assignment [get_file_assignment $f] + if {$assignment ne ""} { + set_global_assignment -name $assignment ../../$f + } else { + puts "WARNING: Unrecognised file extension, skipping: $f" + } + } + + # Pre-generated IP files (from render-design / generated_ip/) + foreach f $ip_files { + if {$f ne ""} { + set_global_assignment -name IP_FILE ../../$f + } + } + + # Constraint files — .sdc files are added as SDC_FILE references; + # .tcl files contain Quartus assignment commands and are sourced directly. + foreach cfile $constraints { + if {$cfile eq ""} { continue } + set ext [string tolower [file extension $cfile]] + if {$ext eq ".tcl"} { + puts "INFO: Sourcing constraint script: $cfile" + source $cfile + } elseif {$ext eq ".stp"} { + set_global_assignment -name USE_SIGNALTAP_FILE ../../$cfile + set_global_assignment -name SIGNALTAP_FILE ../../$cfile + } else { + set_global_assignment -name SDC_FILE ../../$cfile + } + } + + # Auto-tiles support logic (if present from previous run) + set spd_file "support_logic/${proj_name}_auto_tiles.spd" + set qip_file "support_logic/${proj_name}_auto_tiles.qip" + if {[file exists $spd_file]} { + set_global_assignment -name SPD_FILE $spd_file -tag quartus_tlg + } + if {[file exists $qip_file]} { + set_global_assignment -name QIP_FILE $qip_file \ + -comment "Order-dependent: must appear after all other QIP_FILE and IP_FILE settings" \ + -tag quartus_tlg + } + set_global_assignment -name VID_OPERATION_MODE "PMBUS MASTER" + set_global_assignment -name USE_PWRMGT_SCL SDM_IO0 + set_global_assignment -name USE_PWRMGT_SDA SDM_IO12 + set_global_assignment -name USE_CONF_DONE SDM_IO16 + set_global_assignment -name ACTIVE_SERIAL_CLOCK AS_FREQ_100MHZ + set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "AVST X16" + set_global_assignment -name EDA_SIMULATION_TOOL "Questa Intel FPGA (Verilog)" + set_global_assignment -name PWRMGT_BUS_SPEED_MODE "400 KHZ" + set_global_assignment -name PWRMGT_SLAVE_DEVICE_TYPE OTHER + set_global_assignment -name PWRMGT_SLAVE_DEVICE0_ADDRESS 4F + set_global_assignment -name PWRMGT_PAGE_COMMAND_ENABLE ON + set_global_assignment -name NUMBER_OF_SLAVE_DEVICE 1 + set_global_assignment -name PWRMGT_VOLTAGE_OUTPUT_FORMAT "LINEAR FORMAT" + set_global_assignment -name PWRMGT_LINEAR_FORMAT_N "-12" + set_global_assignment -name ENABLE_SIGNALTAP ON + set_global_assignment -name POWER_APPLY_THERMAL_MARGIN ADDITIONAL + set_global_assignment -name PRESERVE_UNUSED_XCVR_CHANNEL ON + + # set_instance_assignment -name PARTITION_COLOUR 4294964852 -to qeciphy_dual_sim_top -entity qeciphy_syn_wrapper + # set_instance_assignment -name PARTITION_COLOUR 4294949993 -to auto_fab_0 -entity qeciphy_syn_wrapper + # set_instance_assignment -name IO_STANDARD "HIGH SPEED DIFFERENTIAL I/O" -to gt_tx_p_1 -entity qeciphy_syn_wrapper + # set_instance_assignment -name IO_STANDARD "HIGH SPEED DIFFERENTIAL I/O" -to gt_rx_p_1 -entity qeciphy_syn_wrapper + # set_instance_assignment -name IO_STANDARD "HIGH SPEED DIFFERENTIAL I/O" -to gt_tx_n_1 -entity qeciphy_syn_wrapper + # set_instance_assignment -name IO_STANDARD "HIGH SPEED DIFFERENTIAL I/O" -to gt_rx_n_1 -entity qeciphy_syn_wrapper + + export_assignments + puts "INFO: Project assignments written for '$proj_name'." +} + +# Close before running qsys-script hooks to avoid file-locking conflicts. +if {$need_to_close_project} { + project_close +} + +# --------------------------------------------------------------------------- +# Run pre-setup hooks via qsys-script +# --------------------------------------------------------------------------- +set ip_dir [file join $proj_dir "ip"] +set qpf_path [file normalize [file join $proj_dir "${proj_name}.qpf"]] +set param_cmd "set argv \[list {$proj_device} {$device_family}\]" +set generated_ips {} + +foreach hook_script $hooks { + if {$hook_script eq ""} { continue } + set abs_script [file normalize [file join $start_dir $hook_script]] + if {![file exists $abs_script]} { + puts "WARNING: Hook script not found: $abs_script" + continue + } + puts "INFO: Running hook: [file tail $abs_script]" + set save_dir [pwd] + cd $ip_dir + if {[catch { + exec qsys-script \ + --script=$abs_script \ + --quartus-project=$qpf_path \ + "--cmd=$param_cmd" \ + >@stdout 2>@stdout + } result]} { + puts "ERROR: qsys-script failed for [file tail $abs_script]: $result" + cd $save_dir + exit 1 + } + cd $save_dir + lappend generated_ips "[file rootname [file tail $abs_script]].ip" +} + +# --------------------------------------------------------------------------- +# Re-open project: add IP_FILE assignments, then compile +# --------------------------------------------------------------------------- +cd $proj_dir +project_open -revision $proj_name $proj_name + +foreach ip_name $generated_ips { + set_global_assignment -name IP_FILE "ip/$ip_name" + puts "INFO: Added IP_FILE: ip/$ip_name" +} +if {[llength $generated_ips] > 0} { + export_assignments + puts "INFO: Updated project with [llength $generated_ips] IP_FILE assignment(s)." +} + +package require ::quartus::flow +puts "INFO: Starting compilation..." +if {[catch { execute_flow -compile } result]} { + puts "ERROR: Compilation failed: $result" + project_close + cd $start_dir + exit 1 +} + +project_close +cd $start_dir +puts "INFO: quartus_proj.tcl complete. Project: $proj_name" diff --git a/src/QECIPHY.sv b/src/QECIPHY.sv index b031ca8..2ec2386 100644 --- a/src/QECIPHY.sv +++ b/src/QECIPHY.sv @@ -142,6 +142,9 @@ module QECIPHY ( logic rx_enable_aclk; logic rx_enable_rclk; + logic tx_active_tclk; + logic tx_active_aclk; + // ========================================================================= // Link State Machine Controller // ========================================================================= @@ -182,7 +185,7 @@ module QECIPHY ( // ========================================================================= // TX Interface Control Logic - assign TX_TREADY = ~tx_fifo_full && tx_data_enable_aclk; // Ready when FIFO space available and data enabled + assign TX_TREADY = ~tx_fifo_full && tx_active_aclk; // Ready when FIFO space available and data enabled assign tx_fifo_ren = ~tx_fifo_empty && tx_ch_enc_tready; // Read when data available and encoder ready assign tx_fifo_wen = TX_TVALID && TX_TREADY; // Write when user provides valid data and ready @@ -220,7 +223,8 @@ module QECIPHY ( .m_axis_tdata_isfaw_o(gt_tx_tdata_isfaw), // Encoded data is FAW indicator to qeciphy_serdes .link_enable_i (tx_link_enable_tclk), // Link enable from qeciphy_controller .data_enable_i (tx_data_enable_tclk), // User data enable from qeciphy_controller - .rx_rdy_i (rx_rdy_tclk) // RX ready status from qeciphy_rx_channeldecoder + .rx_rdy_i (rx_rdy_tclk), // RX ready status from qeciphy_rx_channeldecoder + .tx_active_o (tx_active_tclk) // TX active status output to qeciphy_controller ); // ========================================================================= @@ -274,7 +278,7 @@ module QECIPHY ( // ========================================================================= qeciphy_serdes #( - .GT_TYPE(qeciphy_build_cfg_pkg::QECIPHY_GT_TYPE) // GT primitive type selection + .GT_TYPE(qeciphy_build_cfg_pkg::QECIPHY_GT_TYPE) // GT primitive type: "GTX","GTH","GTY" (Xilinx) or "ETILE" (Altera) ) i_qeciphy_serdes ( // GT Reference and Control .gt_ref_clk_i (RCLK), // GT reference clock @@ -323,6 +327,7 @@ module QECIPHY ( .tx_clk_i (tx_clk), // TX clock .tx_rst_n_i (tx_rst_n), // TX reset (ARSTn synchronized to TX clock) .gt_tx_rst_done_tclk_i(gt_tx_rst_done_tclk), + .tx_active_tclk_i (tx_active_tclk), .rx_rdy_tclk_o (rx_rdy_tclk), .tx_link_enable_tclk_o(tx_link_enable_tclk), .tx_data_enable_tclk_o(tx_data_enable_tclk), @@ -341,6 +346,7 @@ module QECIPHY ( .gt_rx_rst_done_aclk_o (gt_rx_reset_done_aclk), .gt_tx_rst_done_aclk_o (gt_tx_reset_done_aclk), .gt_power_good_aclk_o (gt_power_good_aclk), + .tx_active_aclk_o (tx_active_aclk), .rx_fault_fatal_aclk_o (rx_fault_fatal_aclk), .rx_rdy_aclk_o (rx_rdy_aclk), .remote_rx_rdy_aclk_o (remote_rx_rdy_aclk), diff --git a/src/qeciphy_cdc.sv b/src/qeciphy_cdc.sv index 9ca0b84..37ef241 100644 --- a/src/qeciphy_cdc.sv +++ b/src/qeciphy_cdc.sv @@ -40,6 +40,7 @@ module qeciphy_cdc ( input logic tx_clk_i, // TX clock input logic tx_rst_n_i, // TX domain active-low reset input logic gt_tx_rst_done_tclk_i, // GT TX reset completion + input logic tx_active_tclk_i, // TX active status output logic rx_rdy_tclk_o, // RX ready status output logic tx_link_enable_tclk_o, // TX link enable control output logic tx_data_enable_tclk_o, // TX data enable control @@ -62,6 +63,7 @@ module qeciphy_cdc ( output logic gt_rx_rst_done_aclk_o, // GT RX reset done status output logic gt_tx_rst_done_aclk_o, // GT TX reset done status output logic gt_power_good_aclk_o, // GT power good status + output logic tx_active_aclk_o, // TX active status output logic rx_fault_fatal_aclk_o, // RX fault status output logic rx_rdy_aclk_o, // RX ready status output logic remote_rx_rdy_aclk_o, // Remote RX ready status @@ -165,4 +167,11 @@ module qeciphy_cdc ( .dst_out(rx_datapath_aligned_aclk_o) ); + riv_synchronizer_2ff i_cdc_tx_active_aclk ( + .src_in(tx_active_tclk_i), + .dst_clk(axis_clk_i), + .dst_rst_n(axis_rst_n_i), + .dst_out(tx_active_aclk_o) + ); + endmodule diff --git a/src/qeciphy_gt_altera.sv b/src/qeciphy_gt_altera.sv new file mode 100644 index 0000000..8a13495 --- /dev/null +++ b/src/qeciphy_gt_altera.sv @@ -0,0 +1,416 @@ +// SPDX-License-Identifier: BSD-2-Clause +// Copyright (c) 2024-2026 Riverlane Ltd. +// Original authors: Evan Sun + +//------------------------------------------------------------------------------ +// QECIPHY Altera GT Wrapper +//------------------------------------------------------------------------------ +// Wraps Altera Agilex F-Tile or E-Tile transceiver IP with soft PCS (8b10b +// encode/decode + word alignment) and soft comma detection to present the same +// interface as qeciphy_gt_xilinx to qeciphy_gt_wrapper. +// +// Tile selection is controlled by GT_TYPE parameter: +// "FTILE" - Altera Agilex 7 F-Tile (qeciphy_ftile) +// "ETILE" - Altera Agilex E-Tile (qeciphy_etile) +// +// Data flow (both tiles): +// TX: tx_tdata_i (32b) + tx_tdata_charisk_i → [8b10b enc x4] → [Tile IP] +// RX: [Tile IP] → [word align] → [8b10b dec x4] → [rx_comma_detect] → rx_tdata_o +// +// Clock mapping: +// tx_clkout2 (2x raw) → qeciphy_altera_clk_mmcm → tx_clk_2x_o (2x), tx_clk_o (1x) +// rx_clkout2 (2x raw) → qeciphy_altera_clk_mmcm → rx_clk_2x_o (2x), rx_clk_o (1x) +//------------------------------------------------------------------------------ +// Note: FTILE support is currently included for completeness but UNTESTED. + +module qeciphy_gt_altera #( + parameter string GT_TYPE = "ETILE" // Valid values: "ETILE", "FTILE" +) ( + input logic gt_ref_clk_i, + + // GT differential signals + input logic gt_rx_p_i, + input logic gt_rx_n_i, + output logic gt_tx_p_o, + output logic gt_tx_n_o, + + input logic f_clk_i, + input logic gt_rst_n_i, + output logic gt_power_good_o, + + output logic tx_clk_o, + output logic tx_clk_2x_o, + input logic [31:0] tx_tdata_i, + input logic [ 3:0] tx_tdata_charisk_i, + output logic gt_tx_rst_done_o, + + output logic rx_clk_o, + output logic rx_clk_2x_o, + output logic [31:0] rx_tdata_o, + output logic gt_rx_rst_done_o, + output logic rx_byte_aligned_o +); + + // ------------------------------------------------------------- + // Local parameters + // ------------------------------------------------------------- + + // 8b10b codec parameters + localparam DATA_WIDTH = 40; // Encoded data width (4 symbols × 10 bits) + localparam WORD_SIZE = 10; // 8b10b symbol size + + // Word alignment parameters + localparam TX_PATTERN_LENGTH = 128; // Cycles to wait for comma pattern + localparam RXSLIDE_COUNT_MAX = 80; // Max bit positions to try + localparam RX_ALIGN_MATCH_MAX = 8; // Required consecutive matches + + // Comma detection parameters + localparam MAX_REVIEWS = 128; // Reviews before declaring aligned + localparam MAX_RETRIES = 32; // Retries before failure + + // ------------------------------------------------------------- + // Signal declarations + // ------------------------------------------------------------- + + // Tile parallel data struct for 80-bit interface + // Format for F-Tile/E-Tile 80-bit parallel interface: + // [79] = fifo_wr_en (write enable for elastic FIFO) + // [78:60] = reserved + // [59:40] = data_hi (upper 20 bits of 40-bit encoded stream) + // [39] = reserved + // [38] = data_valid + // [37:20] = reserved + // [19:0] = data_lo (lower 20 bits of 40-bit encoded stream) + typedef struct packed { + logic fifo_wr_en; // [79] + logic [18:0] reserved_hi; // [78:60] + logic [19:0] data_hi; // [59:40] + logic reserved_mid; // [39] + logic data_valid; // [38] + logic [17:0] reserved_lo; // [37:20] + logic [19:0] data_lo; // [19:0] + } tile_parallel_data_t; + + // TX path signals + logic tx_clkout2; // 2x raw clock from FTile TX PLL + logic tx_reset_sync; // Reset synchronized to TX 2x clock + logic rx_reset_sync; // Reset synchronized to RX 2x clock + logic tx_reset_sync_n; // Reset synchronized to TX 2x clock + logic rx_reset_sync_n; // Reset synchronized to RX 2x clock + logic tx_reset_ack; + logic tx_ready; + logic tx_pll_locked; + logic [39:0] tx_encoded; + tile_parallel_data_t tx_parallel_data; + + // TX ready synchronizer to tx_clk_2x_o domain + logic tx_ready_2x_sync; + + // TX ready synchronizer to f_clk_i domain + logic tx_ready_sync; + + // RX path signals + logic rx_clkout2; // 2x raw clock from FTile RX CDR + logic rx_reset_ack; + logic rx_ready; + logic rx_freqlocked; + logic rx_is_locked_to_ref; + tile_parallel_data_t rx_parallel_data; + + // E-Tile-specific signals (unused in FTILE path) + logic [39:0] rx_unaligned; + logic [39:0] word_aligner_data_out; + + // Datapath reset signals + logic tx_reset_datapath; + logic rx_reset_datapath; + + // RX ready synchronizer to rx_clk_2x_o domain + logic rx_ready_2x_sync; + + // RX ready synchronizer to f_clk_i domain + logic rx_ready_sync; + + // Comma detection signals + logic rx_byte_aligned; + logic word_align_done; + logic word_align_fail; + +`ifdef TILE_SIM_MODEL + // Sim-only cross-connect signals accessed hierarchically by the testbench. + // sim_tile_tx_parallel_data: exposes this instance's TX to the peer's RX. + // sim_tile_rx_parallel_data: receives the peer's TX (driven by testbench). + logic [79:0] sim_tile_tx_parallel_data; + logic [79:0] sim_tile_rx_parallel_data; +`endif + + + // F-Tile does not have a power-good signal; tie high. + assign gt_power_good_o = 1'b1; + + + // ------------------------------------------------------------- + // Output assignments + // ------------------------------------------------------------- + + assign rx_byte_aligned_o = rx_byte_aligned; + assign gt_tx_rst_done_o = tx_ready_sync; + assign gt_rx_rst_done_o = rx_ready_sync; + + // ------------------------------------------------------------- + // TX/RX reset synchronization using proper reset synchronizers + // ------------------------------------------------------------- + // Use riv_synchronizer_2ff with ASYNC reset to safely cross + // the asynchronous reset into the TX/RX clock domains. + + assign tx_reset_sync = ~tx_reset_sync_n; + assign rx_reset_sync = ~rx_reset_sync_n; + + riv_synchronizer_2ff #( + .RESET_TYPE("ASYNC") + ) i_tx_reset_sync ( + .src_in (1'b1), + .dst_clk (tx_clk_2x_o), + .dst_rst_n(gt_rst_n_i), + .dst_out (tx_reset_sync_n) + ); + + riv_synchronizer_2ff #( + .RESET_TYPE("ASYNC") + ) i_rx_reset_sync ( + .src_in (1'b1), + .dst_clk (rx_clk_2x_o), + .dst_rst_n(gt_rst_n_i), + .dst_out (rx_reset_sync_n) + ); + + + // ------------------------------------------------------------- + // TX / RX ready synchronization to 2x clock domains + // ------------------------------------------------------------- + + riv_synchronizer_2ff #( + .RESET_TYPE("ASYNC") + ) i_tx_ready_2x_sync ( + .src_in (tx_ready), + .dst_clk (tx_clk_2x_o), + .dst_rst_n(gt_rst_n_i), + .dst_out (tx_ready_2x_sync) + ); + + riv_synchronizer_2ff #( + .RESET_TYPE("ASYNC") + ) i_rx_ready_2x_sync ( + .src_in (rx_ready), + .dst_clk (rx_clk_2x_o), + .dst_rst_n(gt_rst_n_i), + .dst_out (rx_ready_2x_sync) + ); + + // ------------------------------------------------------------- + // TX / RX ready synchronization to f_clk_i domain + // ------------------------------------------------------------- + + riv_synchronizer_2ff #( + .RESET_TYPE("ASYNC") + ) i_tx_ready_sync ( + .src_in (tx_ready), + .dst_clk (f_clk_i), + .dst_rst_n(gt_rst_n_i), + .dst_out (tx_ready_sync) + ); + + riv_synchronizer_2ff #( + .RESET_TYPE("ASYNC") + ) i_rx_ready_sync ( + .src_in (rx_ready), + .dst_clk (f_clk_i), + .dst_rst_n(gt_rst_n_i), + .dst_out (rx_ready_sync) + ); + + // ------------------------------------------------------------- + // RX ready synchronization to rx_clk_2x_o domain + // ------------------------------------------------------------- + // RX datapath reset: hold in reset until FTile RX is ready, or when + // comma detect or word aligner requests a datapath reset (alignment retry). + + assign tx_reset_datapath = tx_reset_sync || !tx_ready_2x_sync; + assign rx_reset_datapath = rx_reset_sync || !rx_ready_2x_sync || word_align_fail; + + + + // ------------------------------------------------------------- + // TX data path: 8b10b encoding (x4, 32-bit wide) + // ------------------------------------------------------------- + // Format TX parallel data for F-Tile 80-bit interface: + // [79] = fifo_wr_en (write enable) + // [78:60] = reserved + // [59:40] = tx_encoded[39:20] (upper 20 bits of 40-bit encoded stream) + // [39] = reserved + // [38] = data_valid + // [37:20] = reserved + // [19:0] = tx_encoded[19:0] (lower 20 bits of 40-bit encoded stream) + + eth_8b10b_enc_x4_a u_8b10b_encoder_4x ( + .clk (tx_clk_2x_o), + .sclr (tx_reset_datapath), + .din_k (tx_tdata_charisk_i), + .din_dat (tx_tdata_i), + .dout_dat(tx_encoded) + ); + + assign tx_parallel_data.fifo_wr_en = 1'b1; + assign tx_parallel_data.reserved_hi = 19'b0; + assign tx_parallel_data.data_hi = tx_encoded[39:20]; + assign tx_parallel_data.reserved_mid = 1'b0; + assign tx_parallel_data.data_valid = 1'b1; + assign tx_parallel_data.reserved_lo = 18'b0; + assign tx_parallel_data.data_lo = tx_encoded[19:0]; + + // ------------------------------------------------------------- + // RX data path: word alignment then 8b10b decoding (x4) + // ------------------------------------------------------------- + + // Extract 40-bit encoded data from Tile 80-bit parallel interface for aligner + assign rx_unaligned = {rx_parallel_data.data_hi, rx_parallel_data.data_lo}; + + // Word aligner: barrel-shifts raw 40-bit stream and automatically + // detects K28.5 comma patterns in the encoded output to align. + qeciphy_word_align #( + .DATA_WIDTH (DATA_WIDTH), + .WORD_SIZE (WORD_SIZE), + .TX_PATTERN_LENGTH (TX_PATTERN_LENGTH), + .RXSLIDE_COUNT_MAX (RXSLIDE_COUNT_MAX), + .RX_ALIGN_MATCH_MAX(RX_ALIGN_MATCH_MAX) + ) u_word_aligner ( + .clk_i (rx_clk_2x_o), + .rst_n_i (~rx_reset_datapath), + .rx_datain_i (rx_unaligned), + .rx_dataout_o(word_aligner_data_out), + .align_done_o(word_align_done), + .align_fail_o(word_align_fail) + ); + + eth_8b10b_dec_x4_a u_8b10b_decoder_4x ( + .clk (rx_clk_2x_o), + .sclr (rx_reset_datapath), + .din_dat (word_aligner_data_out), + .dout_dat (rx_tdata_o), + .dout_k (), + .dout_kerr (), + .dout_rderr(), + .dout_rdreg() + ); + + // ------------------------------------------------------------- + // Soft comma detection (replaces Xilinx GT hardware comma assist) + // ------------------------------------------------------------- + // comma_realign_i is tied to 0: the word aligner handles byte-level + // realignment internally; the comma detect monitors the data stream + // and asserts rx_byte_aligned once a stable QECIPHY comma pattern + // is observed. + + qeciphy_rx_comma_detect #( + .TX_PATTERN_LENGTH(TX_PATTERN_LENGTH), + .MAX_REVIEWS (MAX_REVIEWS), + .MAX_RETRIES (MAX_RETRIES) + ) i_qeciphy_rx_comma_detect ( + .clk_i (rx_clk_2x_o), + .rst_n_i (~rx_reset_datapath && word_align_done), + .comma_realign_i (1'b0), + .tdata_i (rx_tdata_o), + .align_done_o (rx_byte_aligned), + .rx_datapath_resetn_o() + ); + + // ------------------------------------------------------------- + // Clock generation via Altera PLL dividers + // ------------------------------------------------------------- + // FTile and ETile output line_rate/data_width (nominally 10.3125 Gbps / 40 bits = 257.8125 MHz) clocks on tx_clkout2 / rx_clkout2. + // qeciphy_altera_clk_mmcm divides to provide both InClk and divide-by-2 InClk outputs for the 32-bit and 64-bit datapaths, respectively. + + qeciphy_altera_clk_mmcm tile_tx_clk_network ( + .inclk (tx_clkout2), // Nominally 257.8125 MHz input from Tile TX PLL + .clock_div1x(tx_clk_2x_o), // Inclk output (nominally 257.8125 MHz for 32-bit path) + .clock_div2x(tx_clk_o) // Inclk/2 output (nominally 128.90625 MHz for 64-bit path) + ); + + qeciphy_altera_clk_mmcm tile_rx_clk_network ( + .inclk (rx_clkout2), // Nominally 257.8125 MHz input from Tile RX CDR + .clock_div1x(rx_clk_2x_o), // Inclk output (nominally 257.8125 MHz for 32-bit path) + .clock_div2x(rx_clk_o) // Inclk/2 output (nominally 128.90625 MHz for 64-bit path) + ); + + // ------------------------------------------------------------- + // Transceiver instantiation: E-Tile or F-Tile + // ------------------------------------------------------------- + + generate + if (GT_TYPE == "ETILE") begin : gen_etile + + assign tx_reset_ack = '0; + assign rx_reset_ack = '0; + qeciphy_etile transceiver_inst ( + .reset (~gt_rst_n_i), + .pll_refclk0 (gt_ref_clk_i), + .tx_coreclkin (tx_clk_2x_o), + .rx_coreclkin (rx_clk_2x_o), + .tx_ready (tx_ready), + .rx_ready (rx_ready), + .tx_pma_ready (), + .rx_pma_ready (), + .tx_clkout (), + .tx_clkout2 (tx_clkout2), + .rx_clkout (), + .rx_clkout2 (rx_clkout2), + .tx_serial_data (gt_tx_p_o), + .tx_serial_data_n (gt_tx_n_o), + .rx_serial_data (gt_rx_p_i), + .rx_serial_data_n (gt_rx_n_i), + .rx_is_lockedtodata(rx_freqlocked), + .tx_parallel_data (tx_parallel_data), + .rx_parallel_data (rx_parallel_data) + ); + + end else if (GT_TYPE == "FTILE") begin : gen_ftile + qeciphy_ftile transceiver_inst ( + .rx_cdr_refclk_link (gt_ref_clk_i), // RX CDR reference clock + .tx_pll_refclk_link (gt_ref_clk_i), // TX PLL reference clock + .tx_reset (~gt_rst_n_i), // TX reset (active-high) + .rx_reset (~gt_rst_n_i), // RX reset (active-high) + .tx_reset_ack (tx_reset_ack), + .rx_reset_ack (rx_reset_ack), + .tx_ready (tx_ready), // TX datapath ready + .rx_ready (rx_ready), // RX datapath ready + .tx_coreclkin (tx_clk_2x_o), // TX core clock input (2x) + .rx_coreclkin (rx_clk_2x_o), // RX core clock input (2x) + .tx_clkout (), + .tx_clkout2 (tx_clkout2), // TX 2x raw clock output + .rx_clkout (), + .rx_clkout2 (rx_clkout2), // RX 2x raw clock output + .tx_serial_data (gt_tx_p_o), // TX serial positive + .tx_serial_data_n (gt_tx_n_o), // TX serial negative + .rx_serial_data (gt_rx_p_i), // RX serial positive + .rx_serial_data_n (gt_rx_n_i), // RX serial negative + .tx_pll_locked (tx_pll_locked), + .rx_is_lockedtodata (rx_freqlocked), + .rx_is_lockedtoref (rx_is_locked_to_ref), + .tx_fifo_full (), + .tx_fifo_empty (), + .tx_pmaif_fifo_empty (), + .tx_pmaif_fifo_pempty(), + .tx_pmaif_fifo_pfull (), + .tx_parallel_data (tx_parallel_data), // 80-bit TX data to FTile + .rx_parallel_data (rx_parallel_data) // 80-bit RX data from FTile + ); + end else begin : gen_invalid + initial begin + $error("Invalid GT_TYPE parameter value: %s. Valid values are 'ETILE' or 'FTILE'.", GT_TYPE); + $finish; + end + + end + endgenerate + +endmodule // qeciphy_gt_altera diff --git a/src/qeciphy_gt_wrapper.sv b/src/qeciphy_gt_wrapper.sv index 35e540e..b688cd4 100644 --- a/src/qeciphy_gt_wrapper.sv +++ b/src/qeciphy_gt_wrapper.sv @@ -3,7 +3,7 @@ // Original authors: Dogancan Davutoglu, Aniket Datta module qeciphy_gt_wrapper #( - parameter string GT_TYPE = "GTY" // Valid values: "GTX", "GTY", "GTH" + parameter string GT_TYPE = "GTY" // Valid values: "GTX", "GTY", "GTH", "ETILE", or "FTILE" ) ( input logic gt_ref_clk_i, @@ -31,474 +31,61 @@ module qeciphy_gt_wrapper #( ); // ------------------------------------------------------------- - // Common signal declaration - // ------------------------------------------------------------- - - logic rxoutclk; - logic txoutclk; - - logic rxpcommaalignen; - logic rxmcommaalignen; - logic rxbyteisaligned; - logic rxbyterealign; - logic rxcommadet; - logic rx_comma_align_en; - - logic rx_byte_aligned; - logic rx_datapath_resetn; - - logic gt_tx_rst_done; - logic gt_tx_rst_done_reg; - logic gt_rx_rst_done; - logic gt_rx_rst_done_reg; - - // Assign outputs - assign rx_byte_aligned_o = rx_byte_aligned; - assign gt_tx_rst_done_o = gt_tx_rst_done_reg; - assign gt_rx_rst_done_o = gt_rx_rst_done_reg; - - // Capture gt_tx_rst_done in its own clock domain to cleanup any potential glitches - always_ff @(posedge tx_clk_2x_o or negedge gt_rst_n_i) begin - if (!gt_rst_n_i) begin - gt_tx_rst_done_reg <= '0; - end else begin - gt_tx_rst_done_reg <= gt_tx_rst_done; - end - end - - // Capture gt_rx_rst_done in its own clock domain to cleanup any potential glitches - always_ff @(posedge rx_clk_2x_o or negedge gt_rst_n_i) begin - if (!gt_rst_n_i) begin - gt_rx_rst_done_reg <= '0; - end else begin - gt_rx_rst_done_reg <= gt_rx_rst_done; - end - end - - // Comma align enable signals - assign rxpcommaalignen = rx_comma_align_en; - assign rxmcommaalignen = rx_comma_align_en; - - // Comma align enable logic - always_ff @(posedge rx_clk_2x_o or negedge gt_rst_n_i) begin - if (!gt_rst_n_i) begin - rx_comma_align_en <= 1'b0; - end else if (rx_byte_aligned) begin - rx_comma_align_en <= 1'b0; - end else if (gt_rx_rst_done_reg) begin - rx_comma_align_en <= 1'b1; - end else begin - rx_comma_align_en <= 1'b0; - end - end - - // Monitor rx_tdata to ensure comma alignment is done - // Otherwise, reset the rx datapath and try again - qeciphy_rx_comma_detect #( - .TX_PATTERN_LENGTH(128), - .MAX_REVIEWS(128), - .MAX_RETRIES(32) - ) i_qeciphy_rx_comma_detect ( - .clk_i(rx_clk_2x_o), - .rst_n_i(gt_rx_rst_done_reg), - .comma_realign_i(rxbyterealign), - .tdata_i(rx_tdata_o), - .align_done_o(rx_byte_aligned), - .rx_datapath_resetn_o(rx_datapath_resetn) - ); - - // ------------------------------------------------------------- - // GTY transceiver instantiation + // Vendor-specific GT wrapper selection // ------------------------------------------------------------- generate - if (GT_TYPE == "GTY") begin : gen_GTY_transceiver - // ------------------------------------------------------------- - // Transceiver specific declaration - // ------------------------------------------------------------- - logic txpmaresetdone; - logic rxpmaresetdone; - logic userclk_tx_reset; - logic userclk_rx_reset; - logic rxcommadeten; - - // Comma detect enable logic - always_ff @(posedge rx_clk_2x_o or negedge gt_rst_n_i) begin - if (!gt_rst_n_i) begin - rxcommadeten <= 1'b0; - end else if (gt_rx_rst_done_reg) begin - rxcommadeten <= 1'b1; - end else begin - rxcommadeten <= 1'b0; - end - end - - assign userclk_tx_reset = ~txpmaresetdone; - assign userclk_rx_reset = ~rxpmaresetdone; - - //debug - logic cdr_stable; - - qeciphy_gty_transceiver transceiver ( - .gtwiz_userclk_tx_active_in (~userclk_tx_reset), - .gtwiz_userclk_rx_active_in (~userclk_rx_reset), - .gtwiz_reset_clk_freerun_in (f_clk_i), - .gtwiz_reset_all_in (~gt_rst_n_i), - .gtwiz_reset_tx_pll_and_datapath_in(~gt_rst_n_i), - .gtwiz_reset_tx_datapath_in (~gt_rst_n_i), - .gtwiz_reset_rx_pll_and_datapath_in(~gt_rst_n_i), - .gtwiz_reset_rx_datapath_in (~rx_datapath_resetn), - .gtwiz_reset_rx_cdr_stable_out (cdr_stable), - .gtwiz_reset_tx_done_out (gt_tx_rst_done), - .gtwiz_reset_rx_done_out (gt_rx_rst_done), - .gtwiz_userdata_tx_in (tx_tdata_i), - .gtwiz_userdata_rx_out (rx_tdata_o), - .gtrefclk00_in (gt_ref_clk_i), - .qpll0lock_out (), - .qpll0outclk_out (), - .qpll0outrefclk_out (), - .gtyrxn_in (gt_rx_n_i), - .gtyrxp_in (gt_rx_p_i), - .gtytxn_out (gt_tx_n_o), - .gtytxp_out (gt_tx_p_o), - .rx8b10ben_in (1'b1), - .rxusrclk_in (rx_clk_2x_o), - .rxusrclk2_in (rx_clk_2x_o), - .tx8b10ben_in (1'b1), - .txctrl0_in (16'd0), - .txctrl1_in (16'd0), - .txctrl2_in ({4'h0, tx_tdata_charisk_i}), - .txusrclk_in (tx_clk_2x_o), - .txusrclk2_in (tx_clk_2x_o), - .gtpowergood_out (gt_power_good_o), - .rxctrl0_out (), - .rxctrl1_out (), - .rxctrl2_out (), - .rxctrl3_out (), - .rxoutclk_out (rxoutclk), - .rxpmaresetdone_out (rxpmaresetdone), - .txoutclk_out (txoutclk), - .txpmaresetdone_out (txpmaresetdone), - .rxcommadeten_in (rxcommadeten), - .rxpcommaalignen_in (rxpcommaalignen), - .rxmcommaalignen_in (rxmcommaalignen), - .rxbyteisaligned_out (rxbyteisaligned), - .rxbyterealign_out (rxbyterealign), - .rxcommadet_out (rxcommadet) - ); - - // ------------------------------------------------------------- - // Clock buffers - // ------------------------------------------------------------- - - // The rx_clk_2x_o is used both as rxusrclk_in and rxusrclk2_in. - // This should be okay as they are both expected to be of the same frequency for a 32 bit datapath. - // Please refer: https://docs.amd.com/v/u/en-US/ug578-ultrascale-gty-transceivers : Table 4-51 - BUFG_GT i_BUFG_gt_rx_clk ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (userclk_rx_reset), - .CLRMASK(1'b0), - .DIV (3'b000), - .I (rxoutclk), - .O (rx_clk_2x_o) - ); - - // The rx_clk_o is used by the Channel Decoder of the QEC-Phy when converting 32 bit data into 64 bits. - // rx_clk_o = rx_clk_2x_o/2 and they should be phase aligned. - BUFG_GT i_BUFG_rx_clk ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (userclk_rx_reset), - .CLRMASK(1'b0), - .DIV (3'b001), - .I (rxoutclk), - .O (rx_clk_o) - ); - - // The tx_clk_2x_o is used both as txusrclk_in and txusrclk2_in. - // This should be okay as they are both expected to be of the same frequency for a 32 bit datapath. - // Please refer: https://docs.amd.com/v/u/en-US/ug578-ultrascale-gty-transceivers : Table 3-3 - BUFG_GT i_BUFG_gt_tx_clk ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (userclk_tx_reset), - .CLRMASK(1'b0), - .DIV (3'b000), - .I (txoutclk), - .O (tx_clk_2x_o) - ); - - // The tx_clk_o is used by the Channel Encoder of the QEC-Phy when converting 64 bit data into 32 bits. - // tx_clk_o = tx_clk_2x_o/2 and they should be phase aligned. - BUFG_GT i_BUFG_tx_clk ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (userclk_tx_reset), - .CLRMASK(1'b0), - .DIV (3'b001), - .I (txoutclk), - .O (tx_clk_o) + if (GT_TYPE == "FTILE" || GT_TYPE == "ETILE") begin : gen_altera + qeciphy_gt_altera #( + .GT_TYPE(GT_TYPE) + ) i_qeciphy_gt_altera ( + .gt_ref_clk_i (gt_ref_clk_i), + .gt_rx_p_i (gt_rx_p_i), + .gt_rx_n_i (gt_rx_n_i), + .gt_tx_p_o (gt_tx_p_o), + .gt_tx_n_o (gt_tx_n_o), + .f_clk_i (f_clk_i), + .gt_rst_n_i (gt_rst_n_i), + .gt_power_good_o (gt_power_good_o), + .tx_clk_o (tx_clk_o), + .tx_clk_2x_o (tx_clk_2x_o), + .tx_tdata_i (tx_tdata_i), + .tx_tdata_charisk_i(tx_tdata_charisk_i), + .gt_tx_rst_done_o (gt_tx_rst_done_o), + .rx_clk_o (rx_clk_o), + .rx_clk_2x_o (rx_clk_2x_o), + .rx_tdata_o (rx_tdata_o), + .gt_rx_rst_done_o (gt_rx_rst_done_o), + .rx_byte_aligned_o (rx_byte_aligned_o) ); - - end else if (GT_TYPE == "GTH") begin : gen_GTH_transceiver - - // ------------------------------------------------------------- - // Transceiver specific declaration - // ------------------------------------------------------------- - logic txpmaresetdone; - logic rxpmaresetdone; - logic userclk_tx_reset; - logic userclk_rx_reset; - logic rxcommadeten; - - // Comma detect enable logic - always_ff @(posedge rx_clk_2x_o or negedge gt_rst_n_i) begin - if (!gt_rst_n_i) begin - rxcommadeten <= 1'b0; - end else if (gt_rx_rst_done_reg) begin - rxcommadeten <= 1'b1; - end else begin - rxcommadeten <= 1'b0; - end - end - - assign userclk_tx_reset = ~txpmaresetdone; - assign userclk_rx_reset = ~rxpmaresetdone; - - //debug - logic cdr_stable; - - qeciphy_gth_transceiver transceiver ( - .gtwiz_userclk_tx_active_in (~userclk_tx_reset), - .gtwiz_userclk_rx_active_in (~userclk_rx_reset), - .gtwiz_reset_clk_freerun_in (f_clk_i), - .gtwiz_reset_all_in (~gt_rst_n_i), - .gtwiz_reset_tx_pll_and_datapath_in(~gt_rst_n_i), - .gtwiz_reset_tx_datapath_in (~gt_rst_n_i), - .gtwiz_reset_rx_pll_and_datapath_in(~gt_rst_n_i), - .gtwiz_reset_rx_datapath_in (~rx_datapath_resetn), - .gtwiz_reset_rx_cdr_stable_out (cdr_stable), - .gtwiz_reset_tx_done_out (gt_tx_rst_done), - .gtwiz_reset_rx_done_out (gt_rx_rst_done), - .gtwiz_userdata_tx_in (tx_tdata_i), - .gtwiz_userdata_rx_out (rx_tdata_o), - .gtrefclk00_in (gt_ref_clk_i), - .qpll0lock_out (), - .qpll0outclk_out (), - .qpll0outrefclk_out (), - .gthrxn_in (gt_rx_n_i), - .gthrxp_in (gt_rx_p_i), - .gthtxn_out (gt_tx_n_o), - .gthtxp_out (gt_tx_p_o), - .rx8b10ben_in (1'b1), - .rxusrclk_in (rx_clk_2x_o), - .rxusrclk2_in (rx_clk_2x_o), - .tx8b10ben_in (1'b1), - .txctrl0_in (16'd0), - .txctrl1_in (16'd0), - .txctrl2_in ({4'h0, tx_tdata_charisk_i}), - .txusrclk_in (tx_clk_2x_o), - .txusrclk2_in (tx_clk_2x_o), - .gtpowergood_out (gt_power_good_o), - .rxctrl0_out (), - .rxctrl1_out (), - .rxctrl2_out (), - .rxctrl3_out (), - .rxoutclk_out (rxoutclk), - .rxpmaresetdone_out (rxpmaresetdone), - .txoutclk_out (txoutclk), - .txpmaresetdone_out (txpmaresetdone), - .rxcommadeten_in (rxcommadeten), - .rxpcommaalignen_in (rxpcommaalignen), - .rxmcommaalignen_in (rxmcommaalignen), - .rxbyteisaligned_out (rxbyteisaligned), - .rxbyterealign_out (rxbyterealign), - .rxcommadet_out (rxcommadet) - ); - - // ------------------------------------------------------------- - // Clock buffers - // ------------------------------------------------------------- - - // The rx_clk_2x_o is used both as rxusrclk_in and rxusrclk2_in. - // This should be okay as they are both expected to be of the same frequency for a 32 bit datapath. - // Please refer: https://docs.amd.com/v/u/en-US/ug578-ultrascale-gty-transceivers : Table 4-51 - BUFG_GT i_BUFG_gt_rx_clk ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (userclk_rx_reset), - .CLRMASK(1'b0), - .DIV (3'b000), - .I (rxoutclk), - .O (rx_clk_2x_o) - ); - - // The rx_clk_o is used by the Channel Decoder of the QEC-Phy when converting 32 bit data into 64 bits. - // rx_clk_o = rx_clk_2x_o/2 and they should be phase aligned. - BUFG_GT i_BUFG_rx_clk ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (userclk_rx_reset), - .CLRMASK(1'b0), - .DIV (3'b001), - .I (rxoutclk), - .O (rx_clk_o) - ); - - // The tx_clk_2x_o is used both as txusrclk_in and txusrclk2_in. - // This should be okay as they are both expected to be of the same frequency for a 32 bit datapath. - // Please refer: https://docs.amd.com/v/u/en-US/ug578-ultrascale-gty-transceivers : Table 3-3 - BUFG_GT i_BUFG_gt_tx_clk ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (userclk_tx_reset), - .CLRMASK(1'b0), - .DIV (3'b000), - .I (txoutclk), - .O (tx_clk_2x_o) - ); - - // The tx_clk_o is used by the Channel Encoder of the QEC-Phy when converting 64 bit data into 32 bits. - // tx_clk_o = tx_clk_2x_o/2 and they should be phase aligned. - BUFG_GT i_BUFG_tx_clk ( - .CE (1'b1), - .CEMASK (1'b0), - .CLR (userclk_tx_reset), - .CLRMASK(1'b0), - .DIV (3'b001), - .I (txoutclk), - .O (tx_clk_o) - ); - - end else if (GT_TYPE == "GTX") begin : gen_GTX_transceiver - // ------------------------------------------------------------- - // Transceiver specific declaration - // ------------------------------------------------------------- - logic qplllock_out; - logic qpllrefclklost_out; - logic qpllreset_in; - logic qplloutclk_out; - logic qplloutrefclk_out; - logic txoutclk_stopped; - logic txoutclk_stopped_d1; - logic rxoutclk_stopped; - logic rxoutclk_stopped_d1; - logic txoutclk_stopped_fall; - logic rxoutclk_stopped_fall; - logic tx_mmcm_reset; - logic rx_mmcm_reset; - logic rxpmaresetdone; - - qeciphy_gtx_transceiver transceiver ( - .sysclk_in (f_clk_i), - .soft_reset_tx_in (1'b0), - .soft_reset_rx_in (~rx_datapath_resetn), - .dont_reset_on_data_error_in(1'b1), - .gt0_tx_fsm_reset_done_out (gt_tx_rst_done), - .gt0_rx_fsm_reset_done_out (gt_rx_rst_done), - .gt0_data_valid_in (rxpmaresetdone), - .gt0_drpaddr_in (9'h00), - .gt0_drpclk_in (f_clk_i), - .gt0_drpdi_in (16'h0000), - .gt0_drpdo_out (), - .gt0_drpen_in (1'b0), - .gt0_drprdy_out (), - .gt0_drpwe_in (1'b0), - .gt0_dmonitorout_out (), - .gt0_loopback_in (3'b000), - .gt0_eyescanreset_in (1'b0), - .gt0_rxuserrdy_in (1'b1), - .gt0_eyescandataerror_out (), - .gt0_eyescantrigger_in (1'b0), - .gt0_rxusrclk_in (rx_clk_2x_o), - .gt0_rxusrclk2_in (rx_clk_2x_o), - .gt0_rxdata_out (rx_tdata_o), - .gt0_rxdisperr_out (), - .gt0_rxnotintable_out (), - .gt0_gtxrxp_in (gt_rx_p_i), - .gt0_gtxrxn_in (gt_rx_n_i), - .gt0_rxdfelpmreset_in (1'b0), - .gt0_rxmonitorout_out (), - .gt0_rxmonitorsel_in (2'b00), - .gt0_rxoutclk_out (rxoutclk), - .gt0_rxoutclkfabric_out (), - .gt0_gtrxreset_in (~gt_rst_n_i), - .gt0_rxpmareset_in (~gt_rst_n_i), - .gt0_rxcharisk_out (), - .gt0_rxresetdone_out (rxpmaresetdone), - .gt0_gttxreset_in (~gt_rst_n_i), - .gt0_txuserrdy_in (1'b1), - .gt0_txusrclk_in (tx_clk_2x_o), - .gt0_txusrclk2_in (tx_clk_2x_o), - .gt0_txdata_in (tx_tdata_i), - .gt0_gtxtxn_out (gt_tx_n_o), - .gt0_gtxtxp_out (gt_tx_p_o), - .gt0_txoutclk_out (txoutclk), - .gt0_txoutclkfabric_out (), - .gt0_txoutclkpcs_out (), - .gt0_txcharisk_in (tx_tdata_charisk_i), - .gt0_txpmareset_in (~gt_rst_n_i), - .gt0_txresetdone_out (), - .gt0_qplllock_in (qplllock_out), - .gt0_qpllrefclklost_in (qpllrefclklost_out), - .gt0_qpllreset_out (qpllreset_in), - .gt0_qplloutclk_in (qplloutclk_out), - .gt0_qplloutrefclk_in (qplloutrefclk_out), - .gt0_rxpcommaalignen_in (rxpcommaalignen), - .gt0_rxmcommaalignen_in (rxmcommaalignen), - .gt0_rxbyteisaligned_out (rxbyteisaligned), - .gt0_rxbyterealign_out (rxbyterealign), - .gt0_rxcommadet_out (rxcommadet) + end else if (GT_TYPE == "GTY" || GT_TYPE == "GTH" || GT_TYPE == "GTX") begin : gen_xilinx + qeciphy_gt_xilinx #( + .GT_TYPE(GT_TYPE) + ) i_qeciphy_gt_xilinx ( + .gt_ref_clk_i (gt_ref_clk_i), + .gt_rx_p_i (gt_rx_p_i), + .gt_rx_n_i (gt_rx_n_i), + .gt_tx_p_o (gt_tx_p_o), + .gt_tx_n_o (gt_tx_n_o), + .f_clk_i (f_clk_i), + .gt_rst_n_i (gt_rst_n_i), + .gt_power_good_o (gt_power_good_o), + .tx_clk_o (tx_clk_o), + .tx_clk_2x_o (tx_clk_2x_o), + .tx_tdata_i (tx_tdata_i), + .tx_tdata_charisk_i(tx_tdata_charisk_i), + .gt_tx_rst_done_o (gt_tx_rst_done_o), + .rx_clk_o (rx_clk_o), + .rx_clk_2x_o (rx_clk_2x_o), + .rx_tdata_o (rx_tdata_o), + .gt_rx_rst_done_o (gt_rx_rst_done_o), + .rx_byte_aligned_o (rx_byte_aligned_o) ); - - // GTX transceiver does not have gt_power_good - assign gt_power_good_o = 1'b1; - - // MMCMs must be reset after clk input gets interrupted - // Async reset generation for TX MMCM - assign txoutclk_stopped_fall = txoutclk_stopped & ~txoutclk_stopped_d1; - always_ff @(posedge f_clk_i) begin - txoutclk_stopped_d1 <= txoutclk_stopped; - if (txoutclk_stopped_fall) tx_mmcm_reset <= 1'b1; - else tx_mmcm_reset <= 1'b0; - end - - // Async reset generation for RX MMCM - assign rxoutclk_stopped_fall = rxoutclk_stopped & ~rxoutclk_stopped_d1; - always_ff @(posedge f_clk_i) begin - rxoutclk_stopped_d1 <= rxoutclk_stopped; - if (rxoutclk_stopped_fall) rx_mmcm_reset <= 1'b1; - else rx_mmcm_reset <= 1'b0; + end else begin : gen_unsupported + // synthesis translate_off + initial begin + $warning("qeciphy_gt_wrapper: unsupported GT_TYPE = \"%s\". Valid values: GTX, GTY, GTH, ETILE, FTILE.", GT_TYPE); end - - qeciphy_gtx_common i_gtx_common ( - .qpllrefclksel_in (3'b010), - .gtrefclk0_in (1'b0), - .gtrefclk1_in (gt_ref_clk_i), - .qplllock_out (qplllock_out), - .qplllockdetclk_in (f_clk_i), - .qplloutclk_out (qplloutclk_out), - .qplloutrefclk_out (qplloutrefclk_out), - .qpllrefclklost_out(qpllrefclklost_out), - .qpllreset_in (qpllreset_in) - ); - - qeciphy_clk_mmcm i_tx_clks ( - .clk_in (txoutclk), - .reset (tx_mmcm_reset), - .clk_out (tx_clk_o), - .clk_out_2x (tx_clk_2x_o), - .input_clk_stopped(txoutclk_stopped) - ); - - qeciphy_clk_mmcm i_rx_clks ( - .clk_in (rxoutclk), - .reset (rx_mmcm_reset), - .clk_out (rx_clk_o), - .clk_out_2x (rx_clk_2x_o), - .input_clk_stopped(rxoutclk_stopped) - ); - + // synthesis translate_on end endgenerate diff --git a/src/qeciphy_gt_xilinx.sv b/src/qeciphy_gt_xilinx.sv new file mode 100644 index 0000000..dac999b --- /dev/null +++ b/src/qeciphy_gt_xilinx.sv @@ -0,0 +1,505 @@ +// SPDX-License-Identifier: BSD-2-Clause +// Copyright (c) 2024-2026 Riverlane Ltd. +// Original authors: Dogancan Davutoglu, Aniket Datta + +module qeciphy_gt_xilinx #( + parameter string GT_TYPE = "GTY" // Valid values: "GTX", "GTY", "GTH" +) ( + input logic gt_ref_clk_i, + + // GT differential signals + input logic gt_rx_p_i, + input logic gt_rx_n_i, + output logic gt_tx_p_o, + output logic gt_tx_n_o, + + input logic f_clk_i, + input logic gt_rst_n_i, + output logic gt_power_good_o, + + output logic tx_clk_o, + output logic tx_clk_2x_o, + input logic [31:0] tx_tdata_i, + input logic [ 3:0] tx_tdata_charisk_i, + output logic gt_tx_rst_done_o, + + output logic rx_clk_o, + output logic rx_clk_2x_o, + output logic [31:0] rx_tdata_o, + output logic gt_rx_rst_done_o, + output logic rx_byte_aligned_o +); + + // ------------------------------------------------------------- + // Common signal declaration + // ------------------------------------------------------------- + + logic rxoutclk; + logic txoutclk; + + logic rxpcommaalignen; + logic rxmcommaalignen; + logic rxbyteisaligned; + logic rxbyterealign; + logic rxcommadet; + logic rx_comma_align_en; + + logic rx_byte_aligned; + logic rx_datapath_resetn; + + logic gt_tx_rst_done; + logic gt_tx_rst_done_reg; + logic gt_rx_rst_done; + logic gt_rx_rst_done_reg; + + // Assign outputs + assign rx_byte_aligned_o = rx_byte_aligned; + assign gt_tx_rst_done_o = gt_tx_rst_done_reg; + assign gt_rx_rst_done_o = gt_rx_rst_done_reg; + + // Capture gt_tx_rst_done in its own clock domain to cleanup any potential glitches + always_ff @(posedge tx_clk_2x_o or negedge gt_rst_n_i) begin + if (!gt_rst_n_i) begin + gt_tx_rst_done_reg <= '0; + end else begin + gt_tx_rst_done_reg <= gt_tx_rst_done; + end + end + + // Capture gt_rx_rst_done in its own clock domain to cleanup any potential glitches + always_ff @(posedge rx_clk_2x_o or negedge gt_rst_n_i) begin + if (!gt_rst_n_i) begin + gt_rx_rst_done_reg <= '0; + end else begin + gt_rx_rst_done_reg <= gt_rx_rst_done; + end + end + + // Comma align enable signals + assign rxpcommaalignen = rx_comma_align_en; + assign rxmcommaalignen = rx_comma_align_en; + + // Comma align enable logic + always_ff @(posedge rx_clk_2x_o or negedge gt_rst_n_i) begin + if (!gt_rst_n_i) begin + rx_comma_align_en <= 1'b0; + end else if (rx_byte_aligned) begin + rx_comma_align_en <= 1'b0; + end else if (gt_rx_rst_done_reg) begin + rx_comma_align_en <= 1'b1; + end else begin + rx_comma_align_en <= 1'b0; + end + end + + // Monitor rx_tdata to ensure comma alignment is done + // Otherwise, reset the rx datapath and try again + qeciphy_rx_comma_detect #( + .TX_PATTERN_LENGTH(128), + .MAX_REVIEWS(128), + .MAX_RETRIES(32) + ) i_qeciphy_rx_comma_detect ( + .clk_i(rx_clk_2x_o), + .rst_n_i(gt_rx_rst_done_reg), + .comma_realign_i(rxbyterealign), + .tdata_i(rx_tdata_o), + .align_done_o(rx_byte_aligned), + .rx_datapath_resetn_o(rx_datapath_resetn) + ); + + // ------------------------------------------------------------- + // GTY transceiver instantiation + // ------------------------------------------------------------- + generate + if (GT_TYPE == "GTY") begin : gen_GTY_transceiver + // ------------------------------------------------------------- + // Transceiver specific declaration + // ------------------------------------------------------------- + logic txpmaresetdone; + logic rxpmaresetdone; + logic userclk_tx_reset; + logic userclk_rx_reset; + logic rxcommadeten; + + // Comma detect enable logic + always_ff @(posedge rx_clk_2x_o or negedge gt_rst_n_i) begin + if (!gt_rst_n_i) begin + rxcommadeten <= 1'b0; + end else if (gt_rx_rst_done_reg) begin + rxcommadeten <= 1'b1; + end else begin + rxcommadeten <= 1'b0; + end + end + + assign userclk_tx_reset = ~txpmaresetdone; + assign userclk_rx_reset = ~rxpmaresetdone; + + //debug + logic cdr_stable; + + qeciphy_gty_transceiver transceiver ( + .gtwiz_userclk_tx_active_in (~userclk_tx_reset), + .gtwiz_userclk_rx_active_in (~userclk_rx_reset), + .gtwiz_reset_clk_freerun_in (f_clk_i), + .gtwiz_reset_all_in (~gt_rst_n_i), + .gtwiz_reset_tx_pll_and_datapath_in(~gt_rst_n_i), + .gtwiz_reset_tx_datapath_in (~gt_rst_n_i), + .gtwiz_reset_rx_pll_and_datapath_in(~gt_rst_n_i), + .gtwiz_reset_rx_datapath_in (~rx_datapath_resetn), + .gtwiz_reset_rx_cdr_stable_out (cdr_stable), + .gtwiz_reset_tx_done_out (gt_tx_rst_done), + .gtwiz_reset_rx_done_out (gt_rx_rst_done), + .gtwiz_userdata_tx_in (tx_tdata_i), + .gtwiz_userdata_rx_out (rx_tdata_o), + .gtrefclk00_in (gt_ref_clk_i), + .qpll0lock_out (), + .qpll0outclk_out (), + .qpll0outrefclk_out (), + .gtyrxn_in (gt_rx_n_i), + .gtyrxp_in (gt_rx_p_i), + .gtytxn_out (gt_tx_n_o), + .gtytxp_out (gt_tx_p_o), + .rx8b10ben_in (1'b1), + .rxusrclk_in (rx_clk_2x_o), + .rxusrclk2_in (rx_clk_2x_o), + .tx8b10ben_in (1'b1), + .txctrl0_in (16'd0), + .txctrl1_in (16'd0), + .txctrl2_in ({4'h0, tx_tdata_charisk_i}), + .txusrclk_in (tx_clk_2x_o), + .txusrclk2_in (tx_clk_2x_o), + .gtpowergood_out (gt_power_good_o), + .rxctrl0_out (), + .rxctrl1_out (), + .rxctrl2_out (), + .rxctrl3_out (), + .rxoutclk_out (rxoutclk), + .rxpmaresetdone_out (rxpmaresetdone), + .txoutclk_out (txoutclk), + .txpmaresetdone_out (txpmaresetdone), + .rxcommadeten_in (rxcommadeten), + .rxpcommaalignen_in (rxpcommaalignen), + .rxmcommaalignen_in (rxmcommaalignen), + .rxbyteisaligned_out (rxbyteisaligned), + .rxbyterealign_out (rxbyterealign), + .rxcommadet_out (rxcommadet) + ); + + // ------------------------------------------------------------- + // Clock buffers + // ------------------------------------------------------------- + + // The rx_clk_2x_o is used both as rxusrclk_in and rxusrclk2_in. + // This should be okay as they are both expected to be of the same frequency for a 32 bit datapath. + // Please refer: https://docs.amd.com/v/u/en-US/ug578-ultrascale-gty-transceivers : Table 4-51 + BUFG_GT i_BUFG_gt_rx_clk ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (userclk_rx_reset), + .CLRMASK(1'b0), + .DIV (3'b000), + .I (rxoutclk), + .O (rx_clk_2x_o) + ); + + // The rx_clk_o is used by the Channel Decoder of the QEC-Phy when converting 32 bit data into 64 bits. + // rx_clk_o = rx_clk_2x_o/2 and they should be phase aligned. + BUFG_GT i_BUFG_rx_clk ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (userclk_rx_reset), + .CLRMASK(1'b0), + .DIV (3'b001), + .I (rxoutclk), + .O (rx_clk_o) + ); + + // The tx_clk_2x_o is used both as txusrclk_in and txusrclk2_in. + // This should be okay as they are both expected to be of the same frequency for a 32 bit datapath. + // Please refer: https://docs.amd.com/v/u/en-US/ug578-ultrascale-gty-transceivers : Table 3-3 + BUFG_GT i_BUFG_gt_tx_clk ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (userclk_tx_reset), + .CLRMASK(1'b0), + .DIV (3'b000), + .I (txoutclk), + .O (tx_clk_2x_o) + ); + + // The tx_clk_o is used by the Channel Encoder of the QEC-Phy when converting 64 bit data into 32 bits. + // tx_clk_o = tx_clk_2x_o/2 and they should be phase aligned. + BUFG_GT i_BUFG_tx_clk ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (userclk_tx_reset), + .CLRMASK(1'b0), + .DIV (3'b001), + .I (txoutclk), + .O (tx_clk_o) + ); + + end else if (GT_TYPE == "GTH") begin : gen_GTH_transceiver + + // ------------------------------------------------------------- + // Transceiver specific declaration + // ------------------------------------------------------------- + logic txpmaresetdone; + logic rxpmaresetdone; + logic userclk_tx_reset; + logic userclk_rx_reset; + logic rxcommadeten; + + // Comma detect enable logic + always_ff @(posedge rx_clk_2x_o or negedge gt_rst_n_i) begin + if (!gt_rst_n_i) begin + rxcommadeten <= 1'b0; + end else if (gt_rx_rst_done_reg) begin + rxcommadeten <= 1'b1; + end else begin + rxcommadeten <= 1'b0; + end + end + + assign userclk_tx_reset = ~txpmaresetdone; + assign userclk_rx_reset = ~rxpmaresetdone; + + //debug + logic cdr_stable; + + qeciphy_gth_transceiver transceiver ( + .gtwiz_userclk_tx_active_in (~userclk_tx_reset), + .gtwiz_userclk_rx_active_in (~userclk_rx_reset), + .gtwiz_reset_clk_freerun_in (f_clk_i), + .gtwiz_reset_all_in (~gt_rst_n_i), + .gtwiz_reset_tx_pll_and_datapath_in(~gt_rst_n_i), + .gtwiz_reset_tx_datapath_in (~gt_rst_n_i), + .gtwiz_reset_rx_pll_and_datapath_in(~gt_rst_n_i), + .gtwiz_reset_rx_datapath_in (~rx_datapath_resetn), + .gtwiz_reset_rx_cdr_stable_out (cdr_stable), + .gtwiz_reset_tx_done_out (gt_tx_rst_done), + .gtwiz_reset_rx_done_out (gt_rx_rst_done), + .gtwiz_userdata_tx_in (tx_tdata_i), + .gtwiz_userdata_rx_out (rx_tdata_o), + .gtrefclk00_in (gt_ref_clk_i), + .qpll0lock_out (), + .qpll0outclk_out (), + .qpll0outrefclk_out (), + .gthrxn_in (gt_rx_n_i), + .gthrxp_in (gt_rx_p_i), + .gthtxn_out (gt_tx_n_o), + .gthtxp_out (gt_tx_p_o), + .rx8b10ben_in (1'b1), + .rxusrclk_in (rx_clk_2x_o), + .rxusrclk2_in (rx_clk_2x_o), + .tx8b10ben_in (1'b1), + .txctrl0_in (16'd0), + .txctrl1_in (16'd0), + .txctrl2_in ({4'h0, tx_tdata_charisk_i}), + .txusrclk_in (tx_clk_2x_o), + .txusrclk2_in (tx_clk_2x_o), + .gtpowergood_out (gt_power_good_o), + .rxctrl0_out (), + .rxctrl1_out (), + .rxctrl2_out (), + .rxctrl3_out (), + .rxoutclk_out (rxoutclk), + .rxpmaresetdone_out (rxpmaresetdone), + .txoutclk_out (txoutclk), + .txpmaresetdone_out (txpmaresetdone), + .rxcommadeten_in (rxcommadeten), + .rxpcommaalignen_in (rxpcommaalignen), + .rxmcommaalignen_in (rxmcommaalignen), + .rxbyteisaligned_out (rxbyteisaligned), + .rxbyterealign_out (rxbyterealign), + .rxcommadet_out (rxcommadet) + ); + + // ------------------------------------------------------------- + // Clock buffers + // ------------------------------------------------------------- + + // The rx_clk_2x_o is used both as rxusrclk_in and rxusrclk2_in. + // This should be okay as they are both expected to be of the same frequency for a 32 bit datapath. + // Please refer: https://docs.amd.com/v/u/en-US/ug578-ultrascale-gty-transceivers : Table 4-51 + BUFG_GT i_BUFG_gt_rx_clk ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (userclk_rx_reset), + .CLRMASK(1'b0), + .DIV (3'b000), + .I (rxoutclk), + .O (rx_clk_2x_o) + ); + + // The rx_clk_o is used by the Channel Decoder of the QEC-Phy when converting 32 bit data into 64 bits. + // rx_clk_o = rx_clk_2x_o/2 and they should be phase aligned. + BUFG_GT i_BUFG_rx_clk ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (userclk_rx_reset), + .CLRMASK(1'b0), + .DIV (3'b001), + .I (rxoutclk), + .O (rx_clk_o) + ); + + // The tx_clk_2x_o is used both as txusrclk_in and txusrclk2_in. + // This should be okay as they are both expected to be of the same frequency for a 32 bit datapath. + // Please refer: https://docs.amd.com/v/u/en-US/ug578-ultrascale-gty-transceivers : Table 3-3 + BUFG_GT i_BUFG_gt_tx_clk ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (userclk_tx_reset), + .CLRMASK(1'b0), + .DIV (3'b000), + .I (txoutclk), + .O (tx_clk_2x_o) + ); + + // The tx_clk_o is used by the Channel Encoder of the QEC-Phy when converting 64 bit data into 32 bits. + // tx_clk_o = tx_clk_2x_o/2 and they should be phase aligned. + BUFG_GT i_BUFG_tx_clk ( + .CE (1'b1), + .CEMASK (1'b0), + .CLR (userclk_tx_reset), + .CLRMASK(1'b0), + .DIV (3'b001), + .I (txoutclk), + .O (tx_clk_o) + ); + + end else if (GT_TYPE == "GTX") begin : gen_GTX_transceiver + // ------------------------------------------------------------- + // Transceiver specific declaration + // ------------------------------------------------------------- + logic qplllock_out; + logic qpllrefclklost_out; + logic qpllreset_in; + logic qplloutclk_out; + logic qplloutrefclk_out; + logic txoutclk_stopped; + logic txoutclk_stopped_d1; + logic rxoutclk_stopped; + logic rxoutclk_stopped_d1; + logic txoutclk_stopped_fall; + logic rxoutclk_stopped_fall; + logic tx_mmcm_reset; + logic rx_mmcm_reset; + logic rxpmaresetdone; + + qeciphy_gtx_transceiver transceiver ( + .sysclk_in (f_clk_i), + .soft_reset_tx_in (1'b0), + .soft_reset_rx_in (~rx_datapath_resetn), + .dont_reset_on_data_error_in(1'b1), + .gt0_tx_fsm_reset_done_out (gt_tx_rst_done), + .gt0_rx_fsm_reset_done_out (gt_rx_rst_done), + .gt0_data_valid_in (rxpmaresetdone), + .gt0_drpaddr_in (9'h00), + .gt0_drpclk_in (f_clk_i), + .gt0_drpdi_in (16'h0000), + .gt0_drpdo_out (), + .gt0_drpen_in (1'b0), + .gt0_drprdy_out (), + .gt0_drpwe_in (1'b0), + .gt0_dmonitorout_out (), + .gt0_loopback_in (3'b000), + .gt0_eyescanreset_in (1'b0), + .gt0_rxuserrdy_in (1'b1), + .gt0_eyescandataerror_out (), + .gt0_eyescantrigger_in (1'b0), + .gt0_rxusrclk_in (rx_clk_2x_o), + .gt0_rxusrclk2_in (rx_clk_2x_o), + .gt0_rxdata_out (rx_tdata_o), + .gt0_rxdisperr_out (), + .gt0_rxnotintable_out (), + .gt0_gtxrxp_in (gt_rx_p_i), + .gt0_gtxrxn_in (gt_rx_n_i), + .gt0_rxdfelpmreset_in (1'b0), + .gt0_rxmonitorout_out (), + .gt0_rxmonitorsel_in (2'b00), + .gt0_rxoutclk_out (rxoutclk), + .gt0_rxoutclkfabric_out (), + .gt0_gtrxreset_in (~gt_rst_n_i), + .gt0_rxpmareset_in (~gt_rst_n_i), + .gt0_rxcharisk_out (), + .gt0_rxresetdone_out (rxpmaresetdone), + .gt0_gttxreset_in (~gt_rst_n_i), + .gt0_txuserrdy_in (1'b1), + .gt0_txusrclk_in (tx_clk_2x_o), + .gt0_txusrclk2_in (tx_clk_2x_o), + .gt0_txdata_in (tx_tdata_i), + .gt0_gtxtxn_out (gt_tx_n_o), + .gt0_gtxtxp_out (gt_tx_p_o), + .gt0_txoutclk_out (txoutclk), + .gt0_txoutclkfabric_out (), + .gt0_txoutclkpcs_out (), + .gt0_txcharisk_in (tx_tdata_charisk_i), + .gt0_txpmareset_in (~gt_rst_n_i), + .gt0_txresetdone_out (), + .gt0_qplllock_in (qplllock_out), + .gt0_qpllrefclklost_in (qpllrefclklost_out), + .gt0_qpllreset_out (qpllreset_in), + .gt0_qplloutclk_in (qplloutclk_out), + .gt0_qplloutrefclk_in (qplloutrefclk_out), + .gt0_rxpcommaalignen_in (rxpcommaalignen), + .gt0_rxmcommaalignen_in (rxmcommaalignen), + .gt0_rxbyteisaligned_out (rxbyteisaligned), + .gt0_rxbyterealign_out (rxbyterealign), + .gt0_rxcommadet_out (rxcommadet) + ); + + // GTX transceiver does not have gt_power_good + assign gt_power_good_o = 1'b1; + + // MMCMs must be reset after clk input gets interrupted + // Async reset generation for TX MMCM + assign txoutclk_stopped_fall = txoutclk_stopped & ~txoutclk_stopped_d1; + always_ff @(posedge f_clk_i) begin + txoutclk_stopped_d1 <= txoutclk_stopped; + if (txoutclk_stopped_fall) tx_mmcm_reset <= 1'b1; + else tx_mmcm_reset <= 1'b0; + end + + // Async reset generation for RX MMCM + assign rxoutclk_stopped_fall = rxoutclk_stopped & ~rxoutclk_stopped_d1; + always_ff @(posedge f_clk_i) begin + rxoutclk_stopped_d1 <= rxoutclk_stopped; + if (rxoutclk_stopped_fall) rx_mmcm_reset <= 1'b1; + else rx_mmcm_reset <= 1'b0; + end + + qeciphy_gtx_common i_gtx_common ( + .qpllrefclksel_in (3'b010), + .gtrefclk0_in (1'b0), + .gtrefclk1_in (gt_ref_clk_i), + .qplllock_out (qplllock_out), + .qplllockdetclk_in (f_clk_i), + .qplloutclk_out (qplloutclk_out), + .qplloutrefclk_out (qplloutrefclk_out), + .qpllrefclklost_out(qpllrefclklost_out), + .qpllreset_in (qpllreset_in) + ); + + qeciphy_clk_mmcm i_tx_clks ( + .clk_in (txoutclk), + .reset (tx_mmcm_reset), + .clk_out (tx_clk_o), + .clk_out_2x (tx_clk_2x_o), + .input_clk_stopped(txoutclk_stopped) + ); + + qeciphy_clk_mmcm i_rx_clks ( + .clk_in (rxoutclk), + .reset (rx_mmcm_reset), + .clk_out (rx_clk_o), + .clk_out_2x (rx_clk_2x_o), + .input_clk_stopped(rxoutclk_stopped) + ); + + end + endgenerate + +endmodule // qeciphy_gt_xilinx diff --git a/src/qeciphy_serdes.sv b/src/qeciphy_serdes.sv index 4417d2e..9cbd3fa 100644 --- a/src/qeciphy_serdes.sv +++ b/src/qeciphy_serdes.sv @@ -22,7 +22,7 @@ //------------------------------------------------------------------------------ module qeciphy_serdes #( - parameter string GT_TYPE = "GTY" // GT primitive type: "GTX", "GTY", or "GTH" + parameter string GT_TYPE = "GTY" // GT primitive type: "GTX", "GTY", "GTH", or "ETILE" ) ( input logic gt_ref_clk_i, // GT reference clock input input logic f_clk_i, // Free-running fabric clock diff --git a/src/qeciphy_tx_channelencoder.sv b/src/qeciphy_tx_channelencoder.sv index 4cf64ba..956e5ef 100644 --- a/src/qeciphy_tx_channelencoder.sv +++ b/src/qeciphy_tx_channelencoder.sv @@ -28,7 +28,8 @@ module qeciphy_tx_channelencoder ( output logic m_axis_tdata_isfaw_o, // Output indicates if m_axis_tdata is FAW input logic link_enable_i, // Link enable control input logic data_enable_i, // Data transmission enable - input logic rx_rdy_i // Receiver ready status for FAW packets + input logic rx_rdy_i, // Receiver ready status for FAW packets + output logic tx_active_o // TX active status output ); logic faw_boundary; // FAW boundary timing signal from qeciphy_tx_boundary_gen @@ -36,7 +37,6 @@ module qeciphy_tx_channelencoder ( logic crc_boundary; // CRC boundary timing signal from qeciphy_tx_boundary_gen logic tx_off; // TX off state from qeciphy_tx_controller logic tx_idle; // TX idle state from qeciphy_tx_controller - logic tx_active; // TX active state from qeciphy_tx_controller //-------------------------------------------------------------------------- // TX Controller Instance @@ -49,7 +49,7 @@ module qeciphy_tx_channelencoder ( .data_enable_i (data_enable_i), // External data enable input .tx_off_o (tx_off), // TX off state output .tx_idle_o (tx_idle), // TX idle state output - .tx_active_o (tx_active) // TX active state output + .tx_active_o (tx_active_o) // TX active state output ); //-------------------------------------------------------------------------- @@ -78,7 +78,7 @@ module qeciphy_tx_channelencoder ( .m_axis_tdata_isfaw_o(m_axis_tdata_isfaw_o), // Output indicates if m_axis_tdata is FAW .tx_off_i (tx_off), // TX off state from qeciphy_tx_controller .tx_idle_i (tx_idle), // TX idle state from qeciphy_tx_controller - .tx_active_i (tx_active), // TX active state from qeciphy_tx_controller + .tx_active_i (tx_active_o), // TX active state from qeciphy_tx_controller .rx_rdy_i (rx_rdy_i) // Receiver ready status for FAW packets ); diff --git a/src/qeciphy_word_align.sv b/src/qeciphy_word_align.sv new file mode 100644 index 0000000..a1725a1 --- /dev/null +++ b/src/qeciphy_word_align.sv @@ -0,0 +1,291 @@ +// SPDX-License-Identifier: BSD-2-Clause +// Copyright (c) 2024-2026 Riverlane Ltd. +// Original authors: Evan Sun, Kauser Johar +// +// Word aligner with automatic comma-based alignment. +// +// +// DATA_WIDTH must equal 4 * WORD_SIZE (e.g. 40 = 4 * 10). + +module qeciphy_word_align #( + parameter DATA_WIDTH = 40, + parameter WORD_SIZE = 10, + parameter TX_PATTERN_LENGTH = 128, + parameter RXSLIDE_COUNT_MAX = 80, + parameter RX_ALIGN_MATCH_MAX = 8, + parameter [WORD_SIZE-1:0] COMMA_POS = 10'b0101111100, + parameter [WORD_SIZE-1:0] COMMA_NEG = 10'b1010000011 +) ( + input logic clk_i, + input logic rst_n_i, + input logic [DATA_WIDTH - 1 : 0] rx_datain_i, + output logic [DATA_WIDTH - 1 : 0] rx_dataout_o, + output logic align_done_o, + output logic align_fail_o +); + + // ---------------------------------------------------------------- + // Barrel-shifter parameters + // ---------------------------------------------------------------- + localparam BUFFER_SIZE = 4 * DATA_WIDTH; + + // synthesis translate_off + initial begin + if (DATA_WIDTH != 4 * WORD_SIZE) begin + $display("Not tested for parameters where DATA_WIDTH != 4 * WORD_SIZE"); + $stop(); + end + end + // synthesis translate_on + + // ---------------------------------------------------------------- + // Alignment FSM parameters + // ---------------------------------------------------------------- + localparam RXSLIDE_COUNT_WIDTH = $clog2(RXSLIDE_COUNT_MAX); + localparam PATTERN_COUNT_WIDTH = $clog2(TX_PATTERN_LENGTH); + localparam POSITION_WIDTH = $clog2(DATA_WIDTH); + + typedef enum logic [2:0] { + IDLE = 3'h0, + SLIDE = 3'h1, + CHECK = 3'h2, + REVIEW = 3'h3, + DONE = 3'h4, + FAIL = 3'h5 + } fsm_t; + + // ---------------------------------------------------------------- + // Signal declarations + // ---------------------------------------------------------------- + + // Barrel shifter + logic [ POSITION_WIDTH - 1 : 0] position; + logic [ BUFFER_SIZE - 1 : 0] buffer; + + // Internal slide (driven by FSM) + logic do_slide; + + // FSM + fsm_t fsm; + fsm_t fsm_nxt; + logic fsm_idle; + logic fsm_slide; + logic fsm_check; + logic fsm_review; + logic fsm_done; + logic fsm_fail; + + // Registered FSM transition conditions (reduces combinational fan-in) + logic check_to_review_q; // Comma detected in CHECK + logic check_to_slide_q; // Pattern timeout, retry slide + logic check_to_fail_q; // Pattern timeout, no more slides + logic review_to_done_q; // Enough matches in REVIEW + logic review_to_fail_q; // Boundary check failed in REVIEW + + // Comma detection on encoded output + logic [ DATA_WIDTH-1:0] rx_data_q; + logic rx_datan_comma_m_nxt; + logic rx_datan_comma_m; + + // Counters + logic [RXSLIDE_COUNT_WIDTH-1:0] rx_slide_count; + logic [RXSLIDE_COUNT_WIDTH-1:0] rx_slide_count_nxt; + logic rx_slide_count_max; + + logic [PATTERN_COUNT_WIDTH-1:0] rx_pattern_count; + logic [PATTERN_COUNT_WIDTH-1:0] rx_pattern_count_nxt; + logic rx_pattern_count_max; + + logic [ 3:0] rx_align_matched_count; + logic [ 3:0] rx_align_matched_count_nxt; + logic rx_align_matched_count_max; + + logic [PATTERN_COUNT_WIDTH-1:0] rx_align_timeout_count; + logic [PATTERN_COUNT_WIDTH-1:0] rx_align_timeout_count_nxt; + logic rx_align_boundary_check; + logic rx_align_boundary_check_fail; + logic rx_align_matched; + + // Registered counter control signals (reduces combinational fan-in) + logic slide_count_clear_q; // Clear slide counter + logic slide_count_inc_q; // Increment slide counter + logic pattern_count_clear_q; // Clear pattern counter + logic pattern_count_inc_q; // Increment pattern counter + + // ================================================================ + // Barrel shifter + // ================================================================ + + always_ff @(posedge clk_i) begin + if (!rst_n_i) begin + position <= '0; + rx_dataout_o <= '0; + buffer <= '0; + end else begin + buffer <= {rx_datain_i, buffer[BUFFER_SIZE-1 : DATA_WIDTH]}; + rx_dataout_o <= buffer[BUFFER_SIZE-1-DATA_WIDTH-position-:DATA_WIDTH]; + + if (do_slide) begin + position <= (position == POSITION_WIDTH'(DATA_WIDTH - 1)) ? '0 : position + POSITION_WIDTH'(1); + end + end + end + + // ================================================================ + // Comma detection in encoded domain + // ================================================================ + // Search for K28.5 (positive or negative disparity) at the LSB-most WORD_SIZE + // boundary in the barrel-shifter output. + + always_ff @(posedge clk_i) begin + if (!rst_n_i) rx_data_q <= '0; + else rx_data_q <= rx_dataout_o; + end + + always_comb begin + rx_datan_comma_m_nxt = 1'b0; + if (rx_data_q[WORD_SIZE-1:0] == COMMA_POS || rx_data_q[WORD_SIZE-1:0] == COMMA_NEG) rx_datan_comma_m_nxt = 1'b1; + end + + always_ff @(posedge clk_i) begin + if (!rst_n_i) rx_datan_comma_m <= 1'b0; + else rx_datan_comma_m <= rx_datan_comma_m_nxt; + end + + // ================================================================ + // Alignment FSM + // ================================================================ + + // Register FSM transition conditions to reduce combinational fan-in + always_ff @(posedge clk_i) begin + if (!rst_n_i) begin + check_to_review_q <= 1'b0; + check_to_slide_q <= 1'b0; + check_to_fail_q <= 1'b0; + review_to_done_q <= 1'b0; + review_to_fail_q <= 1'b0; + end else begin + // CHECK state transition conditions + check_to_review_q <= rx_datan_comma_m; + check_to_slide_q <= rx_pattern_count_max & ~rx_slide_count_max; + check_to_fail_q <= rx_pattern_count_max & rx_slide_count_max; + // REVIEW state transition conditions + review_to_done_q <= rx_align_matched_count_max; + review_to_fail_q <= rx_align_boundary_check_fail; + end + end + + always_ff @(posedge clk_i) begin + if (!rst_n_i) fsm <= IDLE; + else fsm <= fsm_nxt; + end + + always_comb begin + case (fsm) + IDLE: fsm_nxt = SLIDE; + SLIDE: fsm_nxt = CHECK; + CHECK: fsm_nxt = check_to_review_q ? REVIEW : + check_to_fail_q ? FAIL : + check_to_slide_q ? SLIDE : + CHECK; + REVIEW: fsm_nxt = review_to_done_q ? DONE : + review_to_fail_q ? FAIL : + REVIEW; + DONE: fsm_nxt = DONE; + FAIL: fsm_nxt = IDLE; + default: fsm_nxt = IDLE; + endcase + end + + assign fsm_idle = (fsm == IDLE); + assign fsm_slide = (fsm == SLIDE); + assign fsm_check = (fsm == CHECK); + assign fsm_review = (fsm == REVIEW); + assign fsm_done = (fsm == DONE); + assign fsm_fail = (fsm == FAIL); + + // Internal slide: assert for one cycle in SLIDE state + assign do_slide = fsm_slide; + + // ================================================================ + // Counters + // ================================================================ + + assign rx_slide_count_max = (rx_slide_count == RXSLIDE_COUNT_WIDTH'(RXSLIDE_COUNT_MAX - 1)); + assign rx_pattern_count_max = (rx_pattern_count == PATTERN_COUNT_WIDTH'(TX_PATTERN_LENGTH - 1)); + + // Register counter control signals to reduce combinational fan-in + always_ff @(posedge clk_i) begin + if (!rst_n_i) begin + slide_count_clear_q <= 1'b1; + slide_count_inc_q <= 1'b0; + pattern_count_clear_q <= 1'b1; + pattern_count_inc_q <= 1'b0; + end else begin + // Slide counter controls: clear on idle, comma match, or max both counters; inc on pattern max + slide_count_clear_q <= fsm_idle | (fsm_check & rx_datan_comma_m) | (fsm_check & rx_pattern_count_max & rx_slide_count_max); + slide_count_inc_q <= fsm_check & rx_pattern_count_max & ~rx_slide_count_max; + // Pattern counter controls: clear on idle, comma match, or pattern max; inc while checking + pattern_count_clear_q <= fsm_idle | (fsm_check & rx_datan_comma_m) | (fsm_check & rx_pattern_count_max); + pattern_count_inc_q <= fsm_check & ~rx_pattern_count_max & ~rx_datan_comma_m; + end + end + + // Slide counter: how many bit positions we have tried + always_ff @(posedge clk_i) begin + if (!rst_n_i) rx_slide_count <= '0; + else rx_slide_count <= rx_slide_count_nxt; + end + + assign rx_slide_count_nxt = slide_count_clear_q ? RXSLIDE_COUNT_WIDTH'(0) : slide_count_inc_q ? rx_slide_count + RXSLIDE_COUNT_WIDTH'(1) : rx_slide_count; + + // Pattern counter: cycles since last slide (wait for data to propagate) + always_ff @(posedge clk_i) begin + if (!rst_n_i) rx_pattern_count <= '0; + else rx_pattern_count <= rx_pattern_count_nxt; + end + + assign rx_pattern_count_nxt = pattern_count_clear_q ? PATTERN_COUNT_WIDTH'(0) : pattern_count_inc_q ? rx_pattern_count + PATTERN_COUNT_WIDTH'(1) : rx_pattern_count; + + // ================================================================ + // Alignment verification (REVIEW state) + // ================================================================ + + assign rx_align_matched = fsm_review & rx_datan_comma_m & rx_align_boundary_check; + + always_ff @(posedge clk_i) begin + if (!rst_n_i) rx_align_matched_count <= '0; + else rx_align_matched_count <= rx_align_matched_count_nxt; + end + + assign rx_align_matched_count_nxt = fsm_review ? (rx_align_matched ? rx_align_matched_count + 4'(1) : rx_align_matched_count) : 4'(0); + assign rx_align_matched_count_max = (rx_align_matched_count == 4'(RX_ALIGN_MATCH_MAX)); + + // Timeout counter for periodic boundary checks during REVIEW + always_ff @(posedge clk_i) begin + if (!rst_n_i) rx_align_timeout_count <= '0; + else rx_align_timeout_count <= rx_align_timeout_count_nxt; + end + + //Starts at 1 due to a 1 cycle pipeline delay between the comma match and the fsm transitioning to REVIEW + assign rx_align_timeout_count_nxt = !fsm_review ? PATTERN_COUNT_WIDTH'(1) : + (rx_align_timeout_count == PATTERN_COUNT_WIDTH'(TX_PATTERN_LENGTH - 1)) ? PATTERN_COUNT_WIDTH'(0) : + rx_align_timeout_count + PATTERN_COUNT_WIDTH'(1); + assign rx_align_boundary_check = (rx_align_timeout_count == PATTERN_COUNT_WIDTH'(TX_PATTERN_LENGTH - 1)); + assign rx_align_boundary_check_fail = rx_align_boundary_check ^ rx_datan_comma_m; + + // ================================================================ + // Output assignments + // ================================================================ + + always_ff @(posedge clk_i) begin + if (!rst_n_i) begin + align_done_o <= 1'b0; + align_fail_o <= 1'b0; + end else begin + align_done_o <= fsm_done; + align_fail_o <= fsm_fail; + end + end + +endmodule // qeciphy_word_align diff --git a/src_altera.f b/src_altera.f new file mode 100644 index 0000000..91aa10d --- /dev/null +++ b/src_altera.f @@ -0,0 +1,8 @@ +# Altera-specific source files +-F src_common.f +src/qeciphy_gt_altera.sv +src/qeciphy_word_align.sv +vendors/altera/25.3.1/src/eth_8b10b_enc_a.v +vendors/altera/25.3.1/src/eth_8b10b_dec_a.v +vendors/altera/25.3.1/src/eth_8b10b_enc_x4_a.v +vendors/altera/25.3.1/src/eth_8b10b_dec_x4_a.v \ No newline at end of file diff --git a/src.f b/src_common.f similarity index 96% rename from src.f rename to src_common.f index bba060d..c2ceae8 100644 --- a/src.f +++ b/src_common.f @@ -2,7 +2,6 @@ -F lib/riv_synchronizer_2ff/src.f -F lib/riv_counter/src.f src/qeciphy_pkg.sv -src/qeciphy_gtx_common.sv src/qeciphy_crc_compute.sv src/qeciphy_crc_check.sv src/qeciphy_rx_monitor.sv diff --git a/src_xilinx.f b/src_xilinx.f new file mode 100644 index 0000000..143fa2d --- /dev/null +++ b/src_xilinx.f @@ -0,0 +1,4 @@ +# Xilinx-specific source files +-F src_common.f +src/qeciphy_gt_xilinx.sv +src/qeciphy_gtx_common.sv diff --git a/vendors/altera/25.3.1/ip/qeciphy_altera_clk_mmcm.tcl b/vendors/altera/25.3.1/ip/qeciphy_altera_clk_mmcm.tcl new file mode 100644 index 0000000..bc44a68 --- /dev/null +++ b/vendors/altera/25.3.1/ip/qeciphy_altera_clk_mmcm.tcl @@ -0,0 +1,69 @@ +package require -exact qsys 25.3.1 + +# create the system "qeciphy_altera_clk_mmcm" +# --- Parameters: overridden by $argv when called from quartus_ip.tcl --- +set device "AGIB027R31B1E1V" +set device_family "Agilex 7" + +if {[llength $argv] >= 1} { set device [lindex $argv 0] } +if {[llength $argv] >= 2} { set device_family [lindex $argv 1] } + +proc do_create_qeciphy_altera_clk_mmcm {} { + global device device_family + # create the system + create_system qeciphy_altera_clk_mmcm + set_project_property BOARD {default} + set_project_property DEVICE $device + set_project_property DEVICE_FAMILY $device_family + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance intelclkctrl_0 intelclkctrl 2.0.1 + set_instance_parameter_value intelclkctrl_0 {CLOCK_DIVIDER} {1} + set_instance_parameter_value intelclkctrl_0 {CLOCK_DIVIDER_OUTPUTS} {2} + set_instance_parameter_value intelclkctrl_0 {ENABLE} {0} + set_instance_parameter_value intelclkctrl_0 {ENABLE_REGISTER_TYPE} {1} + set_instance_parameter_value intelclkctrl_0 {ENABLE_TYPE} {2} + set_instance_parameter_value intelclkctrl_0 {GLITCH_FREE_SWITCHOVER} {1} + set_instance_parameter_value intelclkctrl_0 {NUM_CLOCKS} {1} + set_instance_property intelclkctrl_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property inclk EXPORT_OF intelclkctrl_0.inclk + set_interface_property clock_div1x EXPORT_OF intelclkctrl_0.clock_div1x + set_interface_property clock_div2x EXPORT_OF intelclkctrl_0.clock_div2x + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {qeciphy_altera_clk_mmcm.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {qeciphy_altera_clk_mmcm} + + # save the system + sync_sysinfo_parameters + save_system qeciphy_altera_clk_mmcm +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_qeciphy_altera_clk_mmcm + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/vendors/altera/25.3.1/ip/qeciphy_etile.tcl b/vendors/altera/25.3.1/ip/qeciphy_etile.tcl new file mode 100644 index 0000000..336badd --- /dev/null +++ b/vendors/altera/25.3.1/ip/qeciphy_etile.tcl @@ -0,0 +1,530 @@ +package require -exact qsys 25.3.1 + +# --- Parameters: overridden by $argv when called from quartus_ip.tcl --- +set device "AGFB014R24B2E2V" +set device_family "Agilex 7" +set line_rate_mbps 10312.5 +set rclk_freq_mhz 156.25 + +if {[llength $argv] >= 1} { set device [lindex $argv 0] } +if {[llength $argv] >= 2} { set device_family [lindex $argv 1] } +if {[llength $argv] >= 3} { set line_rate_mbps [lindex $argv 2] } +if {[llength $argv] >= 4} { set rclk_freq_mhz [lindex $argv 3] } + +# create the system "qeciphy_etile" +proc do_create_qeciphy_etile {} { + global device device_family line_rate_mbps rclk_freq_mhz + # create the system + create_system qeciphy_etile + set_project_property BOARD {default} + set_project_property DEVICE $device + set_project_property DEVICE_FAMILY $device_family + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance xcvrnphy_fme_0 xcvrnphy_fme 4.1.2 + set_instance_parameter_value xcvrnphy_fme_0 {DR_NRZ_PAM4} {0} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_multi_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_cnt} {1} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_data0} {} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_data1} {} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_data2} {} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_data3} {} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_data4} {} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_data5} {} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_data6} {} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_data7} {} + set_instance_parameter_value xcvrnphy_fme_0 {adpt_recipe_select} {0} + set_instance_parameter_value xcvrnphy_fme_0 {aggregate_rsfec_enable_checkbox} {0} + set_instance_parameter_value xcvrnphy_fme_0 {cal_recipe_sel} {NRZ_28Gbps_VSR} + set_instance_parameter_value xcvrnphy_fme_0 {channels} {1} + set_instance_parameter_value xcvrnphy_fme_0 {cr3_advanced_aib_settings_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_gs1_val_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_gs1_val_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_gs2_val_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_gs2_val_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_hf_max_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_hf_max_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_hf_min_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_hf_min_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_hf_val_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_hf_val_ada_a} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_hf_val_ada_b} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_hf_val_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_lf_max_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_lf_max_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_lf_min_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_lf_min_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_lf_val_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_lf_val_ada_a} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_lf_val_ada_b} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {ctle_lf_val_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {design_environment} {NATIVE} + set_instance_parameter_value xcvrnphy_fme_0 {design_example_filename} {top} + set_instance_parameter_value xcvrnphy_fme_0 {deskew_pma_only_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {dr_25g_cpri_nphy} {0} + set_instance_parameter_value xcvrnphy_fme_0 {duplex_mode} {duplex} + set_instance_parameter_value xcvrnphy_fme_0 {elane_am_encoding40g_0} {9467463} + set_instance_parameter_value xcvrnphy_fme_0 {elane_am_encoding40g_1} {15779046} + set_instance_parameter_value xcvrnphy_fme_0 {elane_am_encoding40g_2} {12936603} + set_instance_parameter_value xcvrnphy_fme_0 {elane_am_encoding40g_3} {10647869} + set_instance_parameter_value xcvrnphy_fme_0 {elane_check_random_idles} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_disable_link_fault_rf} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_ehip_dist_clk_sel} {0} + set_instance_parameter_value xcvrnphy_fme_0 {elane_ehip_mode} {ehip_disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_ehip_rate} {rate_100gx4} + set_instance_parameter_value xcvrnphy_fme_0 {elane_enable_rx_stats_snapshot} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_enable_tx_stats_snapshot} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_enforce_max_frame_size} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_fec_dist_clk_sel} {0} + set_instance_parameter_value xcvrnphy_fme_0 {elane_flow_control} {none} + set_instance_parameter_value xcvrnphy_fme_0 {elane_flow_control_holdoff_mode} {per_queue} + set_instance_parameter_value xcvrnphy_fme_0 {elane_force_deskew_done} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_force_hip_ready} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_force_link_fault_rf} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_forward_rx_pause_requests} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_func_mode} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_hi_ber_monitor} {enable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_holdoff_quanta} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_ipg_removed_per_am_period} {20} + set_instance_parameter_value xcvrnphy_fme_0 {elane_is_usr_avmm} {false} + set_instance_parameter_value xcvrnphy_fme_0 {elane_keep_rx_crc} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_link_fault_mode} {lf_off} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pause_quanta} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_holdoff_quanta_0} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_holdoff_quanta_1} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_holdoff_quanta_2} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_holdoff_quanta_3} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_holdoff_quanta_4} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_holdoff_quanta_5} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_holdoff_quanta_6} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_holdoff_quanta_7} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_pause_quanta_0} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_pause_quanta_1} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_pause_quanta_2} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_pause_quanta_3} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_pause_quanta_4} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_pause_quanta_5} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_pause_quanta_6} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_pfc_pause_quanta_7} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_powerdown_mode} {powerup} + set_instance_parameter_value xcvrnphy_fme_0 {elane_ptp_timestamp_format} {v2} + set_instance_parameter_value xcvrnphy_fme_0 {elane_ptp_tx_timestamp_method} {ptp_1step} + set_instance_parameter_value xcvrnphy_fme_0 {elane_remove_pads} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_reset_rx_stats_parity_error} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_reset_tx_stats_parity_error} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_aib_dp_latency} {0} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_clock_period} {162689} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_length_checking} {enable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_max_frame_size} {1518} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_pause_daddr} {1652522221569} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_pcs_max_skew} {47} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_preamble_passthrough} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_ptp_dp_latency} {0} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_ptp_extra_latency} {0} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rx_vlan_detection} {enable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_rxcrc_covers_preamble} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_sim_mode} {enable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_source_address_insertion} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_strict_preamble_checking} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_strict_sfd_checking} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_aib_dp_latency} {0} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_clock_period} {162689} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_ipg_size} {ipg_12} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_mac_data_flow} {enable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_max_frame_size} {1518} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_pause_daddr} {1652522221569} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_pause_saddr} {247393538562781} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_pld_fifo_almost_full_level} {16} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_preamble_passthrough} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_ptp_asym_latency} {0} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_ptp_dp_latency} {0} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_ptp_extra_latency} {0} + set_instance_parameter_value xcvrnphy_fme_0 {elane_tx_vlan_detection} {enable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_txcrc_covers_preamble} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {elane_txmac_saddr} {73588229205} + set_instance_parameter_value xcvrnphy_fme_0 {elane_uniform_holdoff_quanta} {65535} + set_instance_parameter_value xcvrnphy_fme_0 {elane_use_factory_settings} {true} + set_instance_parameter_value xcvrnphy_fme_0 {enable_advanced_options} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_custom_backplane_mode_checkbox} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_debug_options} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_direct_reset_control} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_ehip_options} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_ind_channel} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_ind_txrx} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_infuture_options} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_inprogress_options} {1} + set_instance_parameter_value xcvrnphy_fme_0 {enable_interlaken_options} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_latency_measurement_feature} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_low_rate_pam4} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_manual_reset} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_pma_reset} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_latency_measurement} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_pll_refclk} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_pma_initialized} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_clkout2} {1} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_clkout2_hioint} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_clkout_hioint} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_enh_pmaif_fifo_overflow} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_fifo_empty} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_fifo_full} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_fifo_pempty} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_fifo_pfull} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_fifo_rd_en} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_is_lockedtodata} {1} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_pcs_fifo_empty} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_pcs_fifo_full} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_pma_clkslip} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_pma_elecidle} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_pma_en} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_pmaif_bitslip} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_rx_pmaif_fifo_underflow} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_clkin2} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_clkout2} {1} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_clkout2_hioint} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_clkout_hioint} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_dll_lock} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_enh_pmaif_fifo_almost_empty} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_enh_pmaif_fifo_almost_full} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_enh_pmaif_fifo_overflow} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_enh_pmaif_fifo_underflow} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_fifo_empty} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_fifo_full} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_fifo_pempty} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_fifo_pfull} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_pcs_fifo_empty} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_pcs_fifo_full} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_pma_en} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_port_tx_pmaif_bitslip} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_ptp_measurement_feature} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_ptp_measurement_port} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_rsfec_fc_cpri_options_checkbox} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_rsfec_support_mode_options_checkbox} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_seq} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_simple_interface} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_spico_reset} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_split_interface} {0} + set_instance_parameter_value xcvrnphy_fme_0 {enable_workaround_rules} {0} + set_instance_parameter_value xcvrnphy_fme_0 {internal_derived_parameter_select} {l_is_loopback_mode_enabled} + set_instance_parameter_value xcvrnphy_fme_0 {l_enable_reset_controller} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_adapt_rx_rx_10g_krfec_rx_diag_data_status_polling_bypass} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_adapt_rx_rx_pld_8g_wa_boundary_polling_bypass} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_adapt_rx_rx_pld_pma_pcie_sw_done_polling_bypass} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_adapt_rx_rx_pld_pma_reser_in_polling_bypass} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_adapt_rx_rx_pld_pma_testbus_polling_bypass} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_adapt_rx_rx_pld_test_data_polling_bypass} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_adapt_tx_dv_gating} {disable} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_clocking_mode} {fec_dir_adp_clk_0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_am_5bad_dis0} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_am_5bad_dis1} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_am_5bad_dis2} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_am_5bad_dis3} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_blk_chk_dis0} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_blk_chk_dis1} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_blk_chk_dis2} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_blk_chk_dis3} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_enter_align_entry_field} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_exit_align_entry_field} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_fec_3bad_dis0} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_fec_3bad_dis1} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_fec_3bad_dis2} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_fec_3bad_dis3} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_sf_dis0} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_sf_dis1} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_sf_dis2} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_sf_dis3} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_swaps0} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_swaps1} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_swaps2} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_swaps3} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_test} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_trans_byp0_string} {Enabled} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_trans_byp1_string} {Enabled} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_trans_byp2_string} {Enabled} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_eng_trans_byp3_string} {Enabled} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_fibre_channel0_string} {Basic Mode} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_fibre_channel1_string} {Basic Mode} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_fibre_channel2_string} {Basic Mode} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_fibre_channel3_string} {Basic Mode} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_indic_byp0} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_indic_byp1} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_indic_byp2} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_core_indic_byp3} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_deskew_channels_clear} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_fec_tx2rx_loopback0} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_fec_tx2rx_loopback1} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_fec_tx2rx_loopback2} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_fec_tx2rx_loopback3} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_first_lane_sel} {first_lane0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_force_deskew_done} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_force_fec_ready} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_source_lane_ena0} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_source_lane_ena1} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_source_lane_ena2} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_source_lane_ena3} {0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_tx_data_source_sel0} {fec_tx_lane_off0} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_tx_data_source_sel1} {fec_tx_lane_off1} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_tx_data_source_sel2} {fec_tx_lane_off2} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfec_tx_data_source_sel3} {fec_tx_lane_off3} + set_instance_parameter_value xcvrnphy_fme_0 {l_hssi_rsfecrx_mux_rx_data_source} {fec_rx_data} + set_instance_parameter_value xcvrnphy_fme_0 {loopback_tx_clk_sel} {internal_clk} + set_instance_parameter_value xcvrnphy_fme_0 {message_level} {error} + set_instance_parameter_value xcvrnphy_fme_0 {parallel_lpbk_mode} {disabled} + set_instance_parameter_value xcvrnphy_fme_0 {pcs_manual_rx_fifo_rd_clk_sel_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pcs_rx_fifo_rd_clk_sel} {tx_pma_clk} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_debug_ports_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_manual_transfer_clk_mode_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_osc_clk_divider} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_rx_clkout2_sel} {half-rate} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_rx_clkout_sel} {half-rate} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_rx_coreclkin_clock_network} {dedicated} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_rx_double_width_transfer_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_rx_fast_pipeln_reg_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_rx_fifo_mode} {phase_comp} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_rx_fifo_pempty_thld} {2} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_rx_fifo_pfull_thld} {10} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_rx_manual_mode_transfer_clk_hz} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_clkout2_sel} {half-rate} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_clkout_sel} {half-rate} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_coreclkin2_clock_network} {dedicated} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_coreclkin2_external_clk_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_coreclkin_clock_network} {dedicated} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_double_width_transfer_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_fast_pipeln_reg_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_fifo_mode} {phase_comp} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_fifo_pempty_thld} {2} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_fifo_pfull_thld} {10} + set_instance_parameter_value xcvrnphy_fme_0 {pldif_tx_manual_mode_transfer_clk_hz} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pll_outclk_freq_mhz} {400} + set_instance_parameter_value xcvrnphy_fme_0 {pll_refclk_cnt} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pll_refclk_freq_mhz} {250.000000} + set_instance_parameter_value xcvrnphy_fme_0 {pll_select} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_an_constraints_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_disable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_example_qsf_strings} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_ical_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_ical_poweron_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pma_plls} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pma_rx_clkdiv66_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pma_rx_clkfullrate_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pma_rx_clkhalfrate_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_rx_data_rate} $line_rate_mbps + set_instance_parameter_value xcvrnphy_fme_0 {pma_rx_dedicated_refclk_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_rx_dedicated_refclk_select} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_rx_modulation} {NRZ} + set_instance_parameter_value xcvrnphy_fme_0 {pma_rx_pll_post_divider} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pma_rx_pll_refclk_freq_mhz} {156.250000} + set_instance_parameter_value xcvrnphy_fme_0 {pma_seq_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_bonding_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_clkdiv66_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_data_rate} $line_rate_mbps + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_atten_tap} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_main_tap} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_post1_tap} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_post_tap} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_powerup_disable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_pre1_tap} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_pre2_tap} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_pre3_tap} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_pre_tap} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_slew_rate} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_eq_vod} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_modulation} {NRZ} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_pll_post_divider} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_pll_refclk_freq_mhz} {156.250000} + set_instance_parameter_value xcvrnphy_fme_0 {pma_tx_pll_select} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_bit_interleaving_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_fifo_aempty_thld} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_fifo_afull_thld} {20} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_fifo_empty_thld} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_fifo_full_thld} {31} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_fifo_rd_empty_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_fifo_wr_clk_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_fifo_wr_full_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_gb_bit_reversal_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_gb_bitslip_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_gb_mode} {rx_gb_64_64} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_gb_sh_bit_mode} {bit1-bit0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_gb_sh_bit_reversal_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_gb_width_adapt_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_gb_word_order} {lower} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_soft_reset_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_rx_width} {20} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_bit_interleaving_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_fifo_aempty_thld} {7} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_fifo_afull_thld} {20} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_fifo_empty_thld} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_fifo_full_thld} {31} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_fifo_mode} {phase_comp} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_fifo_rd_empty_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_fifo_wr_full_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_gb_bit_reversal_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_gb_bitslip_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_gb_mode} {tx_gb_64_64} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_gb_sh_bit_mode} {bit1-bit0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_gb_sh_bit_reversal_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_gb_width_adapt_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_gb_word_order} {lower} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_soft_reset_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_to_rx_parallel_loopback_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {pmaif_tx_width} {20} + set_instance_parameter_value xcvrnphy_fme_0 {protocol_mode} {pma_direct} + set_instance_parameter_value xcvrnphy_fme_0 {ptp_data_channels} {4} + set_instance_parameter_value xcvrnphy_fme_0 {ptp_ethernet_data_rsfec_enabled} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_debug} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_enable_avmm_busy_port} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_file_prefix} {altera_xcvr_rcfg_10} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_files_as_common_package} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_h_file_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_iface_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_jtag_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_mif_file_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_multi_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_cnt} {2} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_data0} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_data1} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_data2} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_data3} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_data4} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_data5} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_data6} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_data7} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_profile_select} {1} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_reduced_files_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_sdc_derived_profile_data0} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_sdc_derived_profile_data1} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_sdc_derived_profile_data2} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_sdc_derived_profile_data3} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_sdc_derived_profile_data4} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_sdc_derived_profile_data5} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_sdc_derived_profile_data6} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_sdc_derived_profile_data7} {} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_separate_avmm_busy} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_shared} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_sv_file_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcfg_txt_file_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rcp_load_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {reduced_reset_sim_time} {0} + set_instance_parameter_value xcvrnphy_fme_0 {reduced_sim_time} {1} + set_instance_parameter_value xcvrnphy_fme_0 {reset_separation_ns} {200} + set_instance_parameter_value xcvrnphy_fme_0 {rf_a_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_a_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b0_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b0_ada_a} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b0_ada_b} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b0_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b0t_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b0t_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b1_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b1_ada_a} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b1_ada_b} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_b1_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p0_val_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p0_val_ada_a} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p0_val_ada_b} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p0_val_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p1_max_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p1_max_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p1_min_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p1_min_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p1_val_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p1_val_ada_a} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p1_val_ada_b} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p1_val_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p2_max_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p2_max_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p2_min_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p2_min_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p2_val_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p2_val_ada_a} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p2_val_ada_b} {adaptable} + set_instance_parameter_value xcvrnphy_fme_0 {rf_p2_val_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_reserved0_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_reserved0_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_reserved1_a} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rf_reserved1_b} {999} + set_instance_parameter_value xcvrnphy_fme_0 {rsfec_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rx_bit_counter_rollover} {0} + set_instance_parameter_value xcvrnphy_fme_0 {rx_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {rx_nd_maib_op_mode} {rx_dll_enable} + set_instance_parameter_value xcvrnphy_fme_0 {set_capability_reg_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {set_csr_soft_logic_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {set_embedded_debug_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {set_op_mode_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {set_rcfg_emb_strm_enable} {0} + set_instance_parameter_value xcvrnphy_fme_0 {set_user_identifier} {0} + set_instance_parameter_value xcvrnphy_fme_0 {space_ns} {100} + set_instance_parameter_value xcvrnphy_fme_0 {support_mode} {user_mode} + set_instance_parameter_value xcvrnphy_fme_0 {support_mode_hssi_adpt} {user_mode} + set_instance_parameter_value xcvrnphy_fme_0 {support_mode_pld_adpt} {user_mode} + set_instance_parameter_value xcvrnphy_fme_0 {support_mode_rsfec} {advanced_user_mode} + set_instance_parameter_value xcvrnphy_fme_0 {suppress_design_example_messages} {0} + set_instance_parameter_value xcvrnphy_fme_0 {t_rx_reset} {100} + set_instance_parameter_value xcvrnphy_fme_0 {t_tx_reset} {100} + set_instance_parameter_value xcvrnphy_fme_0 {tx_enable} {1} + set_instance_parameter_value xcvrnphy_fme_0 {tx_nd_maib_op_mode} {tx_dcc_enable} + set_instance_parameter_value xcvrnphy_fme_0 {user_bti_channel_clock_select} {0} + set_instance_parameter_value xcvrnphy_fme_0 {user_bti_channel_ref_clock_freq_mhz} {100} + set_instance_parameter_value xcvrnphy_fme_0 {user_enable_serialliteiv} {0} + set_instance_parameter_value xcvrnphy_fme_0 {user_preserve_unused_xcvr_channels} {0} + set_instance_parameter_value xcvrnphy_fme_0 {user_set_int_seq_serd_en} {seq_en_all} + set_instance_parameter_value xcvrnphy_fme_0 {user_set_serdes_en_seq} {en_serdes_seq} + set_instance_parameter_value xcvrnphy_fme_0 {validation_rule_select} {} + set_instance_property xcvrnphy_fme_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property reset EXPORT_OF xcvrnphy_fme_0.reset + set_interface_property tx_ready EXPORT_OF xcvrnphy_fme_0.tx_ready + set_interface_property rx_ready EXPORT_OF xcvrnphy_fme_0.rx_ready + set_interface_property tx_pma_ready EXPORT_OF xcvrnphy_fme_0.tx_pma_ready + set_interface_property rx_pma_ready EXPORT_OF xcvrnphy_fme_0.rx_pma_ready + set_interface_property tx_serial_data EXPORT_OF xcvrnphy_fme_0.tx_serial_data + set_interface_property tx_serial_data_n EXPORT_OF xcvrnphy_fme_0.tx_serial_data_n + set_interface_property rx_serial_data EXPORT_OF xcvrnphy_fme_0.rx_serial_data + set_interface_property rx_serial_data_n EXPORT_OF xcvrnphy_fme_0.rx_serial_data_n + set_interface_property pll_refclk0 EXPORT_OF xcvrnphy_fme_0.pll_refclk0 + set_interface_property rx_is_lockedtodata EXPORT_OF xcvrnphy_fme_0.rx_is_lockedtodata + set_interface_property tx_parallel_data EXPORT_OF xcvrnphy_fme_0.tx_parallel_data + set_interface_property rx_parallel_data EXPORT_OF xcvrnphy_fme_0.rx_parallel_data + set_interface_property tx_coreclkin EXPORT_OF xcvrnphy_fme_0.tx_coreclkin + set_interface_property rx_coreclkin EXPORT_OF xcvrnphy_fme_0.rx_coreclkin + set_interface_property tx_clkout EXPORT_OF xcvrnphy_fme_0.tx_clkout + set_interface_property tx_clkout2 EXPORT_OF xcvrnphy_fme_0.tx_clkout2 + set_interface_property rx_clkout EXPORT_OF xcvrnphy_fme_0.rx_clkout + set_interface_property rx_clkout2 EXPORT_OF xcvrnphy_fme_0.rx_clkout2 + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {qeciphy_etile.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {qeciphy_etile} + + # save the system + sync_sysinfo_parameters + save_system qeciphy_etile +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_qeciphy_etile + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/vendors/altera/25.3.1/ip/qeciphy_ftile.tcl b/vendors/altera/25.3.1/ip/qeciphy_ftile.tcl new file mode 100644 index 0000000..03b3408 --- /dev/null +++ b/vendors/altera/25.3.1/ip/qeciphy_ftile.tcl @@ -0,0 +1,293 @@ +package require -exact qsys 25.3.1 + +# --- Parameters: overridden by $argv when called from quartus_ip.tcl --- +set device "AGIB027R31B1E1V" +set device_family "Agilex 7" +set line_rate_mbps 12500 +set rclk_freq_mhz 156.25 + +if {[llength $argv] >= 1} { set device [lindex $argv 0] } +if {[llength $argv] >= 2} { set device_family [lindex $argv 1] } +if {[llength $argv] >= 3} { set line_rate_mbps [lindex $argv 2] } +if {[llength $argv] >= 4} { set rclk_freq_mhz [lindex $argv 3] } + +# create the system "qeciphy_ftile" +proc do_create_qeciphy_ftile {} { + global device device_family line_rate_mbps rclk_freq_mhz + # create the system + create_system qeciphy_ftile + set_project_property BOARD {default} + set_project_property DEVICE $device + set_project_property DEVICE_FAMILY $device_family + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance directphy_f_0 directphy_f 4.10.5 + set_instance_parameter_value directphy_f_0 {CLOCK_SELECTION} {0} + set_instance_parameter_value directphy_f_0 {CLOCK_SELECTION_Board} {3} + set_instance_parameter_value directphy_f_0 {ENABLE_ANLT} {0} + set_instance_parameter_value directphy_f_0 {MODE_1000_BASE_KX} {0} + set_instance_parameter_value directphy_f_0 {avmm1_aib_enable} {0} + set_instance_parameter_value directphy_f_0 {avmm1_jtag_enable} {0} + set_instance_parameter_value directphy_f_0 {avmm1_readdv_enable} {0} + set_instance_parameter_value directphy_f_0 {avmm1_soft_csr_enable} {0} + set_instance_parameter_value directphy_f_0 {avmm1_split} {0} + set_instance_parameter_value directphy_f_0 {avmm2_enable} {0} + set_instance_parameter_value directphy_f_0 {avmm2_jtag_enable} {0} + set_instance_parameter_value directphy_f_0 {avmm2_readdv_enable} {0} + set_instance_parameter_value directphy_f_0 {avmm2_split} {0} + set_instance_parameter_value directphy_f_0 {bk_alt_pam4_grey_code} {0} + set_instance_parameter_value directphy_f_0 {bk_cfg_kvcc_vreg_offset_en_val} {CFG_KVCC_VREG_OFFSET_EN_VAL_DISABLE} + set_instance_parameter_value directphy_f_0 {bk_dl_enable} {DETLAT_DIS} + set_instance_parameter_value directphy_f_0 {bk_en_rxdat_profile} {RXDAT_PROF_EN} + set_instance_parameter_value directphy_f_0 {bk_ext_ac_cap} {EXTERNAL_AC_CAP_ENABLE} + set_instance_parameter_value directphy_f_0 {bk_loopback_mode} {SERIAL_EXT_LOOPBACK} + set_instance_parameter_value directphy_f_0 {bk_pll_pcs3334_ratio} {DIV_33_BY_2} + set_instance_parameter_value directphy_f_0 {bk_pll_rx_pcs3334_ratio} {RX_DIV_33_BY_2} + set_instance_parameter_value directphy_f_0 {bk_refclk_source_lane_pll} {PLL_156_MHZ} + set_instance_parameter_value directphy_f_0 {bk_rx_invert_p_and_n} {RX_INVERT_PN_DIS} + set_instance_parameter_value directphy_f_0 {bk_rx_lat_bit_for_async} {0} + set_instance_parameter_value directphy_f_0 {bk_rx_pmadir_frame_len} {5280} + set_instance_parameter_value directphy_f_0 {bk_rx_precode_en} {0} + set_instance_parameter_value directphy_f_0 {bk_rx_termination} {RXTERM_OFFSET_P0} + set_instance_parameter_value directphy_f_0 {bk_rx_user_clk1_en} {0} + set_instance_parameter_value directphy_f_0 {bk_rx_user_clk1_sel} {0} + set_instance_parameter_value directphy_f_0 {bk_rx_user_clk2_en} {0} + set_instance_parameter_value directphy_f_0 {bk_rx_user_clk2_sel} {0} + set_instance_parameter_value directphy_f_0 {bk_rxdat_1cnt_thld_high} {550000} + set_instance_parameter_value directphy_f_0 {bk_rxdat_1cnt_thld_low} {450000} + set_instance_parameter_value directphy_f_0 {bk_sup_mode} {USER_MODE} + set_instance_parameter_value directphy_f_0 {bk_tx_invert_p_and_n} {TX_INVERT_PN_DIS} + set_instance_parameter_value directphy_f_0 {bk_tx_precode_en} {0} + set_instance_parameter_value directphy_f_0 {bk_tx_predivider_en} {0} + set_instance_parameter_value directphy_f_0 {bk_tx_termination} {TXTERM_OFFSET_P0} + set_instance_parameter_value directphy_f_0 {bk_tx_user_clk1_en} {0} + set_instance_parameter_value directphy_f_0 {bk_tx_user_clk1_sel} {0} + set_instance_parameter_value directphy_f_0 {bk_tx_user_clk2_en} {0} + set_instance_parameter_value directphy_f_0 {bk_tx_user_clk2_sel} {0} + set_instance_parameter_value directphy_f_0 {bk_txeq_main_tap} {41.5} + set_instance_parameter_value directphy_f_0 {bk_txeq_post_tap_1} {0.0} + set_instance_parameter_value directphy_f_0 {bk_txeq_post_tap_2} {0.0} + set_instance_parameter_value directphy_f_0 {bk_txeq_post_tap_3} {0.0} + set_instance_parameter_value directphy_f_0 {bk_txeq_post_tap_4} {0.0} + set_instance_parameter_value directphy_f_0 {bk_txeq_pre_tap_1} {0.0} + set_instance_parameter_value directphy_f_0 {bk_txeq_pre_tap_2} {0.0} + set_instance_parameter_value directphy_f_0 {bk_txeq_pre_tap_3} {0.0} + set_instance_parameter_value directphy_f_0 {bk_txout_tristate_en} {TXOUT_TRISTATE_DIS} + set_instance_parameter_value directphy_f_0 {clocking_mode} {xcvr} + set_instance_parameter_value directphy_f_0 {design_environment} {NATIVE} + set_instance_parameter_value directphy_f_0 {dp_mode} {0} + set_instance_parameter_value directphy_f_0 {duplex_mode} {duplex} + set_instance_parameter_value directphy_f_0 {dv_cwbin_timeout} {0} + set_instance_parameter_value directphy_f_0 {ed_ack} {0} + set_instance_parameter_value directphy_f_0 {ed_board} {None} + set_instance_parameter_value directphy_f_0 {ed_hdl_sel} {Verilog} + set_instance_parameter_value directphy_f_0 {ed_sel} {None} + set_instance_parameter_value directphy_f_0 {enable_N_width_ready_signal} {0} + set_instance_parameter_value directphy_f_0 {enable_advanced_options} {0} + set_instance_parameter_value directphy_f_0 {enable_cwbin_gui} {0} + set_instance_parameter_value directphy_f_0 {enable_fgt_rx_cdr_fast_freeze_sel} {0} + set_instance_parameter_value directphy_f_0 {enable_fgt_rx_cdr_set_locktoref} {0} + set_instance_parameter_value directphy_f_0 {enable_port_Rx_pstate_lx} {0} + set_instance_parameter_value directphy_f_0 {enable_port_Rx_term_hiz_en_lx_a} {0} + set_instance_parameter_value directphy_f_0 {enable_port_Tx_pstate_lx} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_rx_cdr_divclk_link0} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_rx_cdr_divclk_link1} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_rx_cdr_freeze} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_rx_set_locktodata} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_rx_set_locktoref} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_rx_signal_detect} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_rx_signal_detect_lfps} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_rx_status} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_tx_beacon} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_tx_status} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_txdetectrx_ack} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_txdetectrx_req} {0} + set_instance_parameter_value directphy_f_0 {enable_port_fgt_txdetectrx_stat} {0} + set_instance_parameter_value directphy_f_0 {enable_port_latency_measurement} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_clkout2} {1} + set_instance_parameter_value directphy_f_0 {enable_port_rx_clkout2_hioint} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_clkout_hioint} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_fifo_empty} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_fifo_full} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_fifo_pempty} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_fifo_pfull} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_fifo_rd_en} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_pcs_fifo_empty} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_pcs_fifo_full} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_pmaif_fifo_empty} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_pmaif_fifo_pempty} {0} + set_instance_parameter_value directphy_f_0 {enable_port_rx_pmaif_fifo_pfull} {0} + set_instance_parameter_value directphy_f_0 {enable_port_tx_cadence_slow_clk_locked} {0} + set_instance_parameter_value directphy_f_0 {enable_port_tx_clkout2} {1} + set_instance_parameter_value directphy_f_0 {enable_port_tx_clkout2_hioint} {0} + set_instance_parameter_value directphy_f_0 {enable_port_tx_clkout_hioint} {0} + set_instance_parameter_value directphy_f_0 {enable_port_tx_dll_lock} {0} + set_instance_parameter_value directphy_f_0 {enable_port_tx_fifo_empty} {1} + set_instance_parameter_value directphy_f_0 {enable_port_tx_fifo_full} {1} + set_instance_parameter_value directphy_f_0 {enable_port_tx_fifo_pempty} {0} + set_instance_parameter_value directphy_f_0 {enable_port_tx_fifo_pfull} {0} + set_instance_parameter_value directphy_f_0 {enable_port_tx_pcs_fifo_empty} {0} + set_instance_parameter_value directphy_f_0 {enable_port_tx_pcs_fifo_full} {0} + set_instance_parameter_value directphy_f_0 {enable_port_tx_pmaif_fifo_empty} {1} + set_instance_parameter_value directphy_f_0 {enable_port_tx_pmaif_fifo_pempty} {1} + set_instance_parameter_value directphy_f_0 {enable_port_tx_pmaif_fifo_pfull} {1} + set_instance_parameter_value directphy_f_0 {enable_simple_interface} {0} + set_instance_parameter_value directphy_f_0 {enable_split_interface} {0} + set_instance_parameter_value directphy_f_0 {enable_tx_ssc_interface} {0} + set_instance_parameter_value directphy_f_0 {enable_user_fec_lock} {0} + set_instance_parameter_value directphy_f_0 {fec_802p3ck} {0} + set_instance_parameter_value directphy_f_0 {fec_en} {0} + set_instance_parameter_value directphy_f_0 {fec_lpbk_en} {0} + set_instance_parameter_value directphy_f_0 {fgt_core_pll_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_protocol_mode} {DISABLED} + set_instance_parameter_value directphy_f_0 {fgt_rx_cdr_divclk_link0_sel} {0} + set_instance_parameter_value directphy_f_0 {fgt_rx_cdr_divclk_link1_sel} {0} + set_instance_parameter_value directphy_f_0 {fgt_rx_cdr_lock_mode} {auto} + set_instance_parameter_value directphy_f_0 {fgt_rx_cdr_rxuserclk_div} {100} + set_instance_parameter_value directphy_f_0 {fgt_rx_cdr_rxuserclk_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_rx_pll_bw_sel} {LOW} + set_instance_parameter_value directphy_f_0 {fgt_rx_pll_l_cnt} {1} + set_instance_parameter_value directphy_f_0 {fgt_rx_pll_m_cnt} {1} + set_instance_parameter_value directphy_f_0 {fgt_rx_pll_manual_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_rx_pll_n_cnt} {1} + set_instance_parameter_value directphy_f_0 {fgt_rx_pll_refclk_freq_mhz} $rclk_freq_mhz + set_instance_parameter_value directphy_f_0 {fgt_rx_sata_squelch_det_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_rx_serdes_adapt_mode} {auto} + set_instance_parameter_value directphy_f_0 {fgt_rx_serdes_gray_coding_enable} {1} + set_instance_parameter_value directphy_f_0 {fgt_rx_serdes_prbs_mon_mode} {disable} + set_instance_parameter_value directphy_f_0 {fgt_rx_serdes_pre_coding_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_serdes_lpbk_mode} {LOOPBACK_MODE_DISABLED} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_bw_sel} {LOW} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_cascade_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_frac_mode_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_k_cnt} {0} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_l_cnt} {1} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_m_cnt} {165} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_manual_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_n_cnt} {4} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_refclk_freq_itxt} $rclk_freq_mhz + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_refclk_freq_mhz} $rclk_freq_mhz + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_txuserclk1_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_txuserclk2_enable} {0} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_txuserclk_div} {100} + set_instance_parameter_value directphy_f_0 {fgt_tx_pll_type} {FAST} + set_instance_parameter_value directphy_f_0 {fgt_tx_serdes_disable} {0} + set_instance_parameter_value directphy_f_0 {fgt_tx_serdes_gray_coding_enable} {1} + set_instance_parameter_value directphy_f_0 {fgt_tx_serdes_prbs_gen_mode} {disable} + set_instance_parameter_value directphy_f_0 {fgt_tx_serdes_pre_coding_enable} {0} + set_instance_parameter_value directphy_f_0 {l_av1_enable} {0} + set_instance_parameter_value directphy_f_0 {l_fec_mode} {IEEE 802.3 RS(528,514) (CL 91,KR)} + set_instance_parameter_value directphy_f_0 {message_level} {error} + set_instance_parameter_value directphy_f_0 {num_sys_cop} {1} + set_instance_parameter_value directphy_f_0 {num_xcvr_per_sys} {1} + set_instance_parameter_value directphy_f_0 {pldif_rx_clkout2_div} {2} + set_instance_parameter_value directphy_f_0 {pldif_rx_clkout2_sel} {RX_WORD_CLK} + set_instance_parameter_value directphy_f_0 {pldif_rx_clkout_sel} {RX_WORD_CLK} + set_instance_parameter_value directphy_f_0 {pldif_rx_coreclkin_clock_network} {dedicated} + set_instance_parameter_value directphy_f_0 {pldif_rx_double_width_transfer_enable} {1} + set_instance_parameter_value directphy_f_0 {pldif_rx_fast_pipeln_reg_enable} {0} + set_instance_parameter_value directphy_f_0 {pldif_rx_fifo_mode} {phase_comp} + set_instance_parameter_value directphy_f_0 {pldif_rx_fifo_pempty_thld} {2} + set_instance_parameter_value directphy_f_0 {pldif_rx_fifo_pfull_thld} {10} + set_instance_parameter_value directphy_f_0 {pldif_tile_tx_fifo_mode} {phase_comp} + set_instance_parameter_value directphy_f_0 {pldif_tx_clkout2_div} {2} + set_instance_parameter_value directphy_f_0 {pldif_tx_clkout2_sel} {TX_WORD_CLK} + set_instance_parameter_value directphy_f_0 {pldif_tx_clkout_sel} {TX_WORD_CLK} + set_instance_parameter_value directphy_f_0 {pldif_tx_coreclkin2_clock_network} {dedicated} + set_instance_parameter_value directphy_f_0 {pldif_tx_coreclkin_clock_network} {dedicated} + set_instance_parameter_value directphy_f_0 {pldif_tx_double_width_transfer_enable} {1} + set_instance_parameter_value directphy_f_0 {pldif_tx_fast_pipeln_reg_enable} {0} + set_instance_parameter_value directphy_f_0 {pldif_tx_fifo_mode} {phase_comp} + set_instance_parameter_value directphy_f_0 {pldif_tx_fifo_pempty_thld} {2} + set_instance_parameter_value directphy_f_0 {pldif_tx_fifo_pfull_thld} {10} + set_instance_parameter_value directphy_f_0 {pma_data_rate} $line_rate_mbps + set_instance_parameter_value directphy_f_0 {pma_modulation} {NRZ} + set_instance_parameter_value directphy_f_0 {pma_width} {20} + set_instance_parameter_value directphy_f_0 {pmaif_lpbk_enable} {0} + set_instance_parameter_value directphy_f_0 {pmaif_rx_fifo_mode_s} {register} + set_instance_parameter_value directphy_f_0 {pmaif_tx_fifo_mode_s} {phase_comp} + set_instance_parameter_value directphy_f_0 {protocol_hard_pcie_lowloss} {DISABLE} + set_instance_parameter_value directphy_f_0 {refclk_cwbin_gui} {100.0} + set_instance_parameter_value directphy_f_0 {rx_ac_couple_enable} {ENABLE} + set_instance_parameter_value directphy_f_0 {rx_deskew_en} {0} + set_instance_parameter_value directphy_f_0 {rx_onchip_termination} {RX_ONCHIP_TERMINATION_R_2} + set_instance_parameter_value directphy_f_0 {rxeq_dfe_data_tap_1} {0} + set_instance_parameter_value directphy_f_0 {rxeq_hf_boost} {0} + set_instance_parameter_value directphy_f_0 {rxeq_vga_gain} {0} + set_instance_parameter_value directphy_f_0 {src_bypass} {0} + set_instance_parameter_value directphy_f_0 {suppress_design_example_messages} {0} + set_instance_parameter_value directphy_f_0 {syspll_outclk_freq_mhz} {830.08} + set_instance_parameter_value directphy_f_0 {tx_custom_cadence_enable} {0} + set_instance_parameter_value directphy_f_0 {ux_txeq_main_tap} {50} + set_instance_parameter_value directphy_f_0 {ux_txeq_post_tap_1} {0} + set_instance_parameter_value directphy_f_0 {ux_txeq_pre_tap_1} {5} + set_instance_parameter_value directphy_f_0 {ux_txeq_pre_tap_2} {0} + set_instance_parameter_value directphy_f_0 {vsr_mode} {VSR_MODE_DISABLE} + set_instance_parameter_value directphy_f_0 {xcvr_type} {FGT} + set_instance_property directphy_f_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property rx_cdr_refclk_link EXPORT_OF directphy_f_0.rx_cdr_refclk_link + set_interface_property tx_pll_refclk_link EXPORT_OF directphy_f_0.tx_pll_refclk_link + set_interface_property tx_reset EXPORT_OF directphy_f_0.tx_reset + set_interface_property rx_reset EXPORT_OF directphy_f_0.rx_reset + set_interface_property tx_reset_ack EXPORT_OF directphy_f_0.tx_reset_ack + set_interface_property rx_reset_ack EXPORT_OF directphy_f_0.rx_reset_ack + set_interface_property tx_ready EXPORT_OF directphy_f_0.tx_ready + set_interface_property rx_ready EXPORT_OF directphy_f_0.rx_ready + set_interface_property tx_coreclkin EXPORT_OF directphy_f_0.tx_coreclkin + set_interface_property rx_coreclkin EXPORT_OF directphy_f_0.rx_coreclkin + set_interface_property tx_clkout EXPORT_OF directphy_f_0.tx_clkout + set_interface_property tx_clkout2 EXPORT_OF directphy_f_0.tx_clkout2 + set_interface_property rx_clkout EXPORT_OF directphy_f_0.rx_clkout + set_interface_property rx_clkout2 EXPORT_OF directphy_f_0.rx_clkout2 + set_interface_property tx_serial_data EXPORT_OF directphy_f_0.tx_serial_data + set_interface_property tx_serial_data_n EXPORT_OF directphy_f_0.tx_serial_data_n + set_interface_property rx_serial_data EXPORT_OF directphy_f_0.rx_serial_data + set_interface_property rx_serial_data_n EXPORT_OF directphy_f_0.rx_serial_data_n + set_interface_property tx_pll_locked EXPORT_OF directphy_f_0.tx_pll_locked + set_interface_property rx_is_lockedtodata EXPORT_OF directphy_f_0.rx_is_lockedtodata + set_interface_property rx_is_lockedtoref EXPORT_OF directphy_f_0.rx_is_lockedtoref + set_interface_property tx_fifo_full EXPORT_OF directphy_f_0.tx_fifo_full + set_interface_property tx_fifo_empty EXPORT_OF directphy_f_0.tx_fifo_empty + set_interface_property tx_pmaif_fifo_empty EXPORT_OF directphy_f_0.tx_pmaif_fifo_empty + set_interface_property tx_pmaif_fifo_pempty EXPORT_OF directphy_f_0.tx_pmaif_fifo_pempty + set_interface_property tx_pmaif_fifo_pfull EXPORT_OF directphy_f_0.tx_pmaif_fifo_pfull + set_interface_property tx_parallel_data EXPORT_OF directphy_f_0.tx_parallel_data + set_interface_property rx_parallel_data EXPORT_OF directphy_f_0.rx_parallel_data + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {qeciphy_ftile.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {qeciphy_ftile} + + # save the system + sync_sysinfo_parameters + save_system qeciphy_ftile +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_qeciphy_ftile + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/vendors/altera/25.3.1/ip/refclk.tcl b/vendors/altera/25.3.1/ip/refclk.tcl new file mode 100644 index 0000000..68dee80 --- /dev/null +++ b/vendors/altera/25.3.1/ip/refclk.tcl @@ -0,0 +1,162 @@ +package require -exact qsys 25.3.1 + +# --- Parameters: overridden by $argv when called from quartus_ip.tcl --- +set device "AGIB027R31B1E1V" +set device_family "Agilex 7" +set rclk_freq_mhz 156.25 + +if {[llength $argv] >= 1} { set device [lindex $argv 0] } +if {[llength $argv] >= 2} { set device_family [lindex $argv 1] } +if {[llength $argv] >= 4} { set rclk_freq_mhz [lindex $argv 3] } + +# create the system "refclk" +proc do_create_refclk {} { + global device device_family rclk_freq_mhz + # create the system + create_system refclk + set_project_property BOARD {default} + set_project_property DEVICE $device + set_project_property DEVICE_FAMILY $device_family + set_project_property HIDE_FROM_IP_CATALOG {true} + set_use_testbench_naming_pattern 0 {} + + # add HDL parameters + + # add the components + add_instance systemclk_f_0 systemclk_f 4.0.3 + set_instance_parameter_value systemclk_f_0 {bk_cfg_kvcc_vreg_offset_en_val} {CFG_KVCC_VREG_OFFSET_EN_VAL_DISABLE} + set_instance_parameter_value systemclk_f_0 {bk_ext_ac_cap} {EXTERNAL_AC_CAP_ENABLE} + set_instance_parameter_value systemclk_f_0 {bk_rx_invert_p_and_n} {RX_INVERT_PN_DIS} + set_instance_parameter_value systemclk_f_0 {bk_rx_termination} {RXTERM_OFFSET_P0} + set_instance_parameter_value systemclk_f_0 {bk_tx_invert_p_and_n} {TX_INVERT_PN_DIS} + set_instance_parameter_value systemclk_f_0 {bk_tx_termination} {TXTERM_OFFSET_P0} + set_instance_parameter_value systemclk_f_0 {bk_txeq_main_tap} {41.5} + set_instance_parameter_value systemclk_f_0 {bk_txeq_post_tap_1} {0.0} + set_instance_parameter_value systemclk_f_0 {bk_txeq_post_tap_2} {0.0} + set_instance_parameter_value systemclk_f_0 {bk_txeq_post_tap_3} {0.0} + set_instance_parameter_value systemclk_f_0 {bk_txeq_post_tap_4} {0.0} + set_instance_parameter_value systemclk_f_0 {bk_txeq_pre_tap_1} {0.0} + set_instance_parameter_value systemclk_f_0 {bk_txeq_pre_tap_2} {0.0} + set_instance_parameter_value systemclk_f_0 {bk_txeq_pre_tap_3} {0.0} + set_instance_parameter_value systemclk_f_0 {bk_txout_tristate_en} {TXOUT_TRISTATE_DIS} + set_instance_parameter_value systemclk_f_0 {cmnpll_dummy} {0} + set_instance_parameter_value systemclk_f_0 {cmnpll_enable_0} {0} + set_instance_parameter_value systemclk_f_0 {cmnpll_enable_1} {0} + set_instance_parameter_value systemclk_f_0 {cmnpll_refclk_src_0} {FHT RefClk #0} + set_instance_parameter_value systemclk_f_0 {cmnpll_refclk_src_1} {FHT RefClk #0} + set_instance_parameter_value systemclk_f_0 {cmnpll_xtensa_src} {Auto} + set_instance_parameter_value systemclk_f_0 {protocol_hard_pcie_lowloss} {DISABLE} + set_instance_parameter_value systemclk_f_0 {refclk_cdrclk_output_enable_0} {0} + set_instance_parameter_value systemclk_f_0 {refclk_cdrclk_output_enable_1} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_0} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_1} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_2} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_3} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_4} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_5} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_6} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_7} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_8} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_always_active_9} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_0} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_1} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_2} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_3} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_4} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_5} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_6} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_7} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_8} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_coreclk_enable_9} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_0} $rclk_freq_mhz + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_1} {NotSpecified} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_2} {NotSpecified} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_3} {NotSpecified} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_4} $rclk_freq_mhz + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_5} {NotSpecified} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_6} {NotSpecified} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_7} {NotSpecified} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_8} {NotSpecified} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_9} {NotSpecified} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_0} $rclk_freq_mhz + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_1} {100} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_2} {100} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_3} {100} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_4} $rclk_freq_mhz + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_5} {100} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_6} {100} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_7} {100} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_8} {100} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_freq_mhz_txt_9} {100} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_0} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_1} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_2} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_3} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_4} {1} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_5} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_6} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_7} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_8} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fgt_output_enable_9} {0} + set_instance_parameter_value systemclk_f_0 {refclk_fht_freq_mhz_txt_0} {} + set_instance_parameter_value systemclk_f_0 {refclk_fht_freq_mhz_txt_1} {} + set_instance_parameter_value systemclk_f_0 {rx_ac_couple_enable} {ENABLE} + set_instance_parameter_value systemclk_f_0 {rx_onchip_termination} {RX_ONCHIP_TERMINATION_R_2} + set_instance_parameter_value systemclk_f_0 {rxeq_dfe_data_tap_1} {0} + set_instance_parameter_value systemclk_f_0 {rxeq_hf_boost} {0} + set_instance_parameter_value systemclk_f_0 {rxeq_vga_gain} {0} + set_instance_parameter_value systemclk_f_0 {syspll_flux_src} {Auto} + set_instance_parameter_value systemclk_f_0 {syspll_freq_mhz_0} $rclk_freq_mhz + set_instance_parameter_value systemclk_f_0 {syspll_freq_mhz_1} {805.6640625} + set_instance_parameter_value systemclk_f_0 {syspll_freq_mhz_2} {805.6640625} + set_instance_parameter_value systemclk_f_0 {syspll_mod_0} {User Configuration} + set_instance_parameter_value systemclk_f_0 {syspll_mod_1} {Disabled} + set_instance_parameter_value systemclk_f_0 {syspll_mod_2} {Disabled} + set_instance_parameter_value systemclk_f_0 {syspll_refclk_src_0} {RefClk #4} + set_instance_parameter_value systemclk_f_0 {syspll_refclk_src_1} {RefClk #0} + set_instance_parameter_value systemclk_f_0 {syspll_refclk_src_2} {RefClk #0} + set_instance_parameter_value systemclk_f_0 {ux_txeq_main_tap} {35} + set_instance_parameter_value systemclk_f_0 {ux_txeq_post_tap_1} {0} + set_instance_parameter_value systemclk_f_0 {ux_txeq_pre_tap_1} {5} + set_instance_parameter_value systemclk_f_0 {ux_txeq_pre_tap_2} {0} + set_instance_parameter_value systemclk_f_0 {vsr_mode} {VSR_MODE_DISABLE} + set_instance_property systemclk_f_0 AUTO_EXPORT true + + # add wirelevel expressions + + # preserve ports for debug + + # add the exports + set_interface_property out_systempll_synthlock_0 EXPORT_OF systemclk_f_0.out_systempll_synthlock_0 + set_interface_property out_systempll_clk_0 EXPORT_OF systemclk_f_0.out_systempll_clk_0 + set_interface_property out_refclk_fgt_4 EXPORT_OF systemclk_f_0.out_refclk_fgt_4 + set_interface_property refclk_fgt EXPORT_OF systemclk_f_0.refclk_fgt + set_interface_property disable_refclk_monitor_4 EXPORT_OF systemclk_f_0.disable_refclk_monitor_4 + + # set values for exposed HDL parameters + + # set the the module properties + set_module_property BONUS_DATA { + + + + + +} + set_module_property FILE {refclk.ip} + set_module_property GENERATION_ID {0x00000000} + set_module_property NAME {refclk} + + # save the system + sync_sysinfo_parameters + save_system refclk +} + +proc do_set_exported_interface_sysinfo_parameters {} { +} + +# create all the systems, from bottom up +do_create_refclk + +# set system info parameters on exported interface, from bottom up +do_set_exported_interface_sysinfo_parameters diff --git a/vendors/altera/25.3.1/src/eth_8b10b_dec_a.v b/vendors/altera/25.3.1/src/eth_8b10b_dec_a.v new file mode 100644 index 0000000..467cc46 --- /dev/null +++ b/vendors/altera/25.3.1/src/eth_8b10b_dec_a.v @@ -0,0 +1,302 @@ +// Copyright 2024 Intel Corporation. +// +// This reference design file is subject licensed to you by the terms and +// conditions of the applicable License Terms and Conditions for Hardware +// Reference Designs and/or Design Examples (either as signed by you or +// found at https://www.altera.com/common/legal/leg-license_agreement.html ). +// +// As stated in the license, you agree to only use this reference design +// solely in conjunction with Intel FPGAs or Intel CPLDs. +// +// THE REFERENCE DESIGN IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED +// WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, +// NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not +// warrant or assume responsibility for the accuracy or completeness of any +// information, links or other items within the Reference Design and any +// accompanying materials. +// +// In the event that you do not agree with such terms and conditions, do not +// use the reference design file. +///////////////////////////////////////////////////////////////////////////// + +// Generated by one of Gregg's toys on Mon Jan 15 15:54:16 2024 + +//`timescale 1ps / 1ps + +module eth_8b10b_dec_a ( + input clk, + input sclr, + input din_ena, + input [9:0] din_dat, + input din_rd, + output [7:0] dout_dat, + output dout_k, + output dout_val, + output dout_kerr, + output dout_rderr, + output dout_rdcomb, + output dout_rdreg +); + + + // The decoder reverses the encoding process. Decoding does not depend on the running disparity which + // simplifies the process somewhat. + // + + reg dout_val_r = 1'b0; + reg [7:0] dout_dat_r = 8'h0; + reg dout_k_r = 1'b0; + reg dout_kerr_r = 1'b0; + reg dout_rderr_r = 1'b0; + reg dout_rdreg_r = 1'b0; + + wire a = din_dat[0]; + wire b = din_dat[1]; + wire c = din_dat[2]; + wire d = din_dat[3]; + wire e = din_dat[4]; + wire i = din_dat[5]; + wire f = din_dat[6]; + wire g = din_dat[7]; + wire h = din_dat[8]; + wire j = din_dat[9]; + + + //classification + wire P04 = (!a & !b & !c & !d); + wire P13 = (!a & !b & !c & d) | (!a & !b & c & !d) | (!a & b & !c & !d) | (a & !b & !c & !d); + wire P22 = (!a & !b & c & d) | (!a & b & c & !d) | (a & b & !c & !d) | (a & !b & c & !d) | (a & !b & !c & d) | (!a & b & !c & d); + wire P31 = (a & b & c & !d) | (a & b & !c & d) | (a & !b & c & d) | (!a & b & c & d); + wire P40 = (a & b & c & d); + + + //////////////////////////////////////////////// + // data outputs + //////////////////////////////////////////////// + + wire A = (P22 & !b & !c & !(e ^ i)) ? !a : (P31 & i) ? !a : (P13 & d & e & i) ? !a : (P22 & !a & !c & !(e ^ i)) ? !a : (P13 & !e) ? !a : (a & b & e & i) ? !a : (!c & !d & !e & !i) ? !a : a; + wire B = (P22 & b & c & !(e ^ i)) ? !b : (P31 & i) ? !b : (P13 & d & e & i) ? !b : (P22 & a & c & !(e ^ i)) ? !b : (P13 & !e) ? !b : (a & b & e & i) ? !b : (!c & !d & !e & !i) ? !b : b; + wire C = (P22 & b & c & !(e ^ i)) ? !c : (P31 & i) ? !c : (P13 & d & e & i) ? !c : (P22 & !a & !c & !(e ^ i)) ? !c : (P13 & !e) ? !c : (!a & !b & !e & !i) ? !c : (!c & !d & !e & !i) ? !c : c; + wire D = (P22 & !b & !c & !(e ^ i)) ? !d : (P31 & i) ? !d : (P13 & d & e & i) ? !d : (P22 & a & c & !(e ^ i)) ? !d : (P13 & !e) ? !d : (a & b & e & i) ? !d : (!c & !d & !e & !i) ? !d : d; + wire E = (P22 & !b & !c & !(e ^ i)) ? !e : (P13 & !i) ? !e : (P13 & d & e & i) ? !e : (P22 & !a & !c & !(e ^ i)) ? !e : (P13 & !e) ? !e : (!a & !b & !e & !i) ? !e : (!c & !d & !e & !i) ? !e : e; + + + wire F = (f & h & j) ? !f : (!c & !d & !e & !i & (h ^ j)) ? !f : (!f & !g & h & j) ? !f : (f & g & j) ? !f : (!f & !g & !h) ? !f : (g & h & j) ? !f : f; + wire G = (!f & !h & !j) ? !g : (!c & !d & !e & !i & (h ^ j)) ? !g : (!f & !g & h & j) ? !g : (f & g & j) ? !g : (!f & !g & !h) ? !g : (!g & !h & !j) ? !g : g; + wire H = (f & h & j) ? !h : (!c & !d & !e & !i & (h ^ j)) ? !h : (!f & !g & h & j) ? !h : (f & g & j) ? !h : (!f & !g & !h) ? !h : (!g & !h & !j) ? !h : h; + + + wire K = (c & d & e & i) | (!c & !d & !e & !i) | (P13 & !e & i & g & h & j) | (P31 & e & !i & !g & !h & !j); + + + //////////////////////////////////////////////// + //running disparity - generate and err check + //////////////////////////////////////////////// + wire rd1n = (P04) ? 1'b1 : (P13 & !(e & i)) ? 1'b1 : (P22 & !e & !i) ? 1'b1 : (P13 & d & e & i) ? 1'b1 : 1'b0 /* synthesis keep */; + wire rd1p = (P40) ? 1'b1 : (P31 & !(!e & !i)) ? 1'b1 : (P22 & e & i) ? 1'b1 : (P31 & !d & !e & !i) ? 1'b1 : 1'b0 /* synthesis keep */; + wire rd1e = (P13 & !d & e & i) ? 1'b1 : (P22 & (e ^ i)) ? 1'b1 : (P31 & d & !e & !i) ? 1'b1 : 1'b0 /* synthesis keep */; + + wire rd1_err = (!din_rd & rd1n) | (din_rd & rd1p); + + ///////////////////////////// + // factored rd1 generation + ///////////////////////////// + wire [63:0] rd1_when_din_rd_0_mask = 64'hffe8e880e8808000; + wire rd1_when_din_rd_0 = rd1_when_din_rd_0_mask[din_dat[5:0]] /* synthesis keep */; + wire [63:0] rd1_when_din_rd_1_mask = 64'hfffefee8fee8e800; + wire rd1_when_din_rd_1 = rd1_when_din_rd_1_mask[din_dat[5:0]] /* synthesis keep */; + wire rd1 = din_rd ? rd1_when_din_rd_1 : rd1_when_din_rd_0; + + wire rd2n = (!f & !g & !h) ? 1'b1 : (!f & !g & !j) ? 1'b1 : (!f & !h & !j) ? 1'b1 : (!g & !h & !j) ? 1'b1 : (!f & !g & h & j) ? 1'b1 : 1'b0 /* synthesis keep */; + wire rd2p = (f & g & h) ? 1'b1 : (f & g & j) ? 1'b1 : (f & h & j) ? 1'b1 : (g & h & j) ? 1'b1 : (f & g & !h & !j) ? 1'b1 : 1'b0 /* synthesis keep */; + + //wire rd2e = ((f ^ g) & (h ^ j)) ? 1'b1 : + // 0; + + wire rd2_err = (!rd1 & rd2n) | (rd1 & rd2p); + + + // these two conditions appear in rd2p and rd2n with the + // opposite associated rdcomb output. + wire dout_rdcomb_special = (!f & !g & h & j) | (f & g & !h & !j) /* synthesis keep */; + + assign dout_rdcomb = (rd2p) ? !dout_rdcomb_special : (rd2n) ? dout_rdcomb_special : rd1; + + //////////////////////////////////////////////// + // K error check - this is by far the most + // complex expression in the decoder. + // It appears to require depth 3. Please let + // me know if you identify a depth 2 mapping. + //////////////////////////////////////////////// + wire k_err; + ///////////////////////////////////// + // use the upper and lower portions only + // to identify definite errors + ///////////////////////////////////// + wire [63:0] kerr_mask_ai = 64'h6881800180018117; + wire [63:0] kerr_mask_ej = 64'hf20000018000004f; + wire kerr_out_ai = kerr_mask_ai[din_dat[5:0]] /* synthesis keep */; + wire kerr_out_ej = kerr_mask_ej[din_dat[9:4]] /* synthesis keep */; + wire rd2_err_lc = rd2_err /* synthesis keep */; + + wire kerr6, kerr7, kerr8, kerr9, kerr_remainder; + tennm_lcell_comb #( + .lut_mask(64'h0C0000300C000030), + .extended_lut("off"), + .shared_arith("off") + ) wlc0 ( + .dataa(1'b1), + .datab(!din_dat[7]), + .datac(!din_dat[6]), + .datad(!din_dat[8]), + .datae(!din_dat[9]), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(kerr6) + ); + + tennm_lcell_comb #( + .lut_mask(64'h0002403000024030), + .extended_lut("off"), + .shared_arith("off") + ) wlc1 ( + .dataa(!din_dat[3]), + .datab(!din_dat[7]), + .datac(!din_dat[6]), + .datad(!din_dat[8]), + .datae(!din_dat[9]), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(kerr7) + ); + + tennm_lcell_comb #( + .lut_mask(64'h6868960868689608), + .extended_lut("off"), + .shared_arith("off") + ) wlc2 ( + .dataa(!din_dat[0]), + .datab(!din_dat[1]), + .datac(!din_dat[2]), + .datad(!din_dat[4]), + .datae(!din_dat[3]), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(kerr8) + ); + + tennm_lcell_comb #( + .lut_mask(64'h1001161E1001161E), + .extended_lut("off"), + .shared_arith("off") + ) wlc3 ( + .dataa(!din_dat[0]), + .datab(!din_dat[1]), + .datac(!din_dat[2]), + .datad(!din_dat[4]), + .datae(!din_dat[3]), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(kerr9) + ); + + tennm_lcell_comb #( + .lut_mask(64'h2331223029110325), + .extended_lut("off"), + .shared_arith("off") + ) wlc4 ( + .dataa(!din_dat[5]), + .datab(!kerr6), + .datac(!kerr7), + .datad(!din_dat[4]), + .datae(!kerr8), + .dataf(!kerr9), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(kerr_remainder) + ); + + + assign k_err = kerr_out_ai | kerr_out_ej | rd2_err_lc & !rd1e | kerr_remainder; + + //////////////////////////////////////////////// + // output registers + //////////////////////////////////////////////// + always @(posedge clk) begin + dout_val_r <= 1'b0; + if (din_ena) begin + dout_k_r <= K; + dout_val_r <= din_ena; + dout_dat_r <= {H, G, F, E, D, C, B, A}; + dout_rdreg_r <= dout_rdcomb; + dout_rderr_r <= (rd1_err | rd2_err); + dout_kerr_r <= k_err; + end + if (sclr) begin + dout_val_r <= 1'b0; + dout_k_r <= 1'b0; + dout_dat_r <= 8'b0; + dout_rdreg_r <= 1'b0; + dout_rderr_r <= 1'b0; + dout_kerr_r <= 1'b0; + end + end + + assign dout_val = dout_val_r; + assign dout_k = dout_k_r; + assign dout_dat = dout_dat_r; + assign dout_rdreg = dout_rdreg_r; + assign dout_rderr = dout_rderr_r; + assign dout_kerr = dout_kerr_r; + + +endmodule diff --git a/vendors/altera/25.3.1/src/eth_8b10b_dec_x4_a.v b/vendors/altera/25.3.1/src/eth_8b10b_dec_x4_a.v new file mode 100644 index 0000000..8033798 --- /dev/null +++ b/vendors/altera/25.3.1/src/eth_8b10b_dec_x4_a.v @@ -0,0 +1,61 @@ +// Copyright 2024 Intel Corporation. +// +// This reference design file is subject licensed to you by the terms and +// conditions of the applicable License Terms and Conditions for Hardware +// Reference Designs and/or Design Examples (either as signed by you or +// found at https://www.altera.com/common/legal/leg-license_agreement.html ). +// +// As stated in the license, you agree to only use this reference design +// solely in conjunction with Intel FPGAs or Intel CPLDs. +// +// THE REFERENCE DESIGN IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED +// WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, +// NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not +// warrant or assume responsibility for the accuracy or completeness of any +// information, links or other items within the Reference Design and any +// accompanying materials. +// +// In the event that you do not agree with such terms and conditions, do not +// use the reference design file. +///////////////////////////////////////////////////////////////////////////// + +// Generated by one of Gregg's toys on Mon Jan 15 15:54:16 2024 + +//`timescale 1ps / 1ps + +module eth_8b10b_dec_x4_a ( + input clk, + input sclr, + input [39:0] din_dat, + output [31:0] dout_dat, + output [3:0] dout_k, + output [3:0] dout_kerr, + output [3:0] dout_rderr, + output [3:0] dout_rdreg +); + + localparam WORDS = 4; + wire [WORDS-1:0] dout_rdcomb; + + genvar i; + generate + for (i = 0; i < WORDS; i = i + 1) begin : lp + eth_8b10b_dec_a dc0 ( + .clk (clk), + .sclr (sclr), + .din_ena (1'b1), // Data (or code) input enable + .din_dat (din_dat[(i+1)*10-1:i*10]), // 8b data in + .din_rd ((i == 0) ? dout_rdreg[WORDS-1] : dout_rdcomb[i-1]), // running disparity input + .dout_val (), + .dout_kerr (dout_kerr[i]), + .dout_dat (dout_dat[(i+1)*8-1:i*8]), // data out + .dout_k (dout_k[i]), + .dout_rderr (dout_rderr[i]), + .dout_rdcomb(dout_rdcomb[i]), // running disparity output (comb) + .dout_rdreg (dout_rdreg[i]) // running disparity output (reg) + ); + end + endgenerate + + +endmodule diff --git a/vendors/altera/25.3.1/src/eth_8b10b_enc_a.v b/vendors/altera/25.3.1/src/eth_8b10b_enc_a.v new file mode 100644 index 0000000..5fd85c2 --- /dev/null +++ b/vendors/altera/25.3.1/src/eth_8b10b_enc_a.v @@ -0,0 +1,646 @@ +// Copyright 2024 Intel Corporation. +// +// This reference design file is subject licensed to you by the terms and +// conditions of the applicable License Terms and Conditions for Hardware +// Reference Designs and/or Design Examples (either as signed by you or +// found at https://www.altera.com/common/legal/leg-license_agreement.html ). +// +// As stated in the license, you agree to only use this reference design +// solely in conjunction with Intel FPGAs or Intel CPLDs. +// +// THE REFERENCE DESIGN IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED +// WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, +// NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not +// warrant or assume responsibility for the accuracy or completeness of any +// information, links or other items within the Reference Design and any +// accompanying materials. +// +// In the event that you do not agree with such terms and conditions, do not +// use the reference design file. +///////////////////////////////////////////////////////////////////////////// + +// Generated by one of Gregg's toys on Mon Jan 15 15:54:16 2024 + +//`timescale 1ps / 1ps + +module eth_8b10b_enc_a ( + input clk, + input sclr, + input din_k, + input din_ena, + input [7:0] din_dat, + input din_rd, + output dout_val, + output [9:0] dout_dat, + output dout_rdcomb, + output dout_rdreg +); + + + // baeckler - 04-10-2006 + // reworked a little for new chips 03-01-2013 + + // an 8b10b encoder, based on files from Martin R and IBM paper + + // DESCRIPTION + // + // 8B10B coding is designed to maintain an equal number of ones and zeros on the coded stream, and to + // limit run length to five bits. Additionally, it has a mechanism for sending control characters and some + // error detection capability. The 8B10B encoder is composed of a 5B/6B coder and a 3B/4B coder + // operating in a loosely coupled fashion as illustrated in the figure below. + // + // The running disparity, or rd, signals balance ones and zeros over time. If an encoded result contains a + // surplus of either bit, the rd signal directs downstream coders to restore the balance. The 5-bit run- + // length is enforced by construction. The K signal is used to transmit control characters. Only some of the + // 8-bit inputs represent legal control characters. K28.5 is the standard link synchronization or idle + // character, although K28.7 and K28.1 are also suitable. The following table shows the legal K control + // characters. + // + // Table : legal K characters + // K28.0 8'b000_11100 + // K28.1 8'b001_11100 + // K28.2 8'b010_11100 + // K28.3 8'b011_11100 + // K28.4 8'b100_11100 + // K28.5 8'b101_11100 (comma) + // K28.6 8'b110_11100 + // K28.7 8'b111_11100 + // K23.7 8'b111_10111 + // K27.7 8'b111_11011 + // K29.7 8'b111_11101 + // K30.7 8'b111_11110 + // + // din_k, // Data in is a special code, not all are legal. + // din_ena, // Data (or code) input enable + // din_dat, // 8b data in + // din_rd, // running disparity input + // dout_val, // data out is valid + // dout_dat, // data out + // dout_rdcomb, // running disparity output (comb) + // dout_rdreg // running disparity output (reg) + + + reg dout_val_r = 1'b0; + reg [9:0] dout_dat_r = 10'b0; + + wire A = din_dat[0]; + wire B = din_dat[1]; + wire C = din_dat[2]; + wire D = din_dat[3]; + wire E = din_dat[4]; + wire F = din_dat[5]; + wire G = din_dat[6]; + wire H = din_dat[7]; + wire K = din_k; + + reg rd1_part /* synthesis keep */; + reg rd1; + + reg dout_rdcomb_r; + reg dout_rdreg_r = 1'b0; + reg SorK; + reg a, b, c, d, e, f, g, h, i, j; + + wire rdout_x, rdout_y; + + tennm_lcell_comb #( + .lut_mask(64'h157E7EE800000000), + .extended_lut("off"), + .shared_arith("off") + ) wlc0 ( + .dataa(!B), + .datab(!D), + .datac(!E), + .datad(!A), + .datae(!C), + .dataf(!K), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(rdout_x) + ); + + tennm_lcell_comb #( + .lut_mask(64'h3CC99663699CC336), + .extended_lut("off"), + .shared_arith("off") + ) wlc1 ( + .dataa(!H), + .datab(!din_rd), + .datac(!F), + .datad(!G), + .datae(!rdout_x), + .dataf(!rdout_x), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(rdout_y) + ); + + + always @(*) begin + dout_rdcomb_r = rdout_y; + + case ({ + din_rd, din_dat[4:0], din_k + }) + 7'h00: {i, e, d, c, b, a} = 6'h39; + 7'h01: {i, e, d, c, b, a} = 6'h39; + 7'h02: {i, e, d, c, b, a} = 6'h2e; + 7'h03: {i, e, d, c, b, a} = 6'h2e; + 7'h04: {i, e, d, c, b, a} = 6'h2d; + 7'h05: {i, e, d, c, b, a} = 6'h2d; + 7'h06: {i, e, d, c, b, a} = 6'h23; + 7'h07: {i, e, d, c, b, a} = 6'h23; + 7'h08: {i, e, d, c, b, a} = 6'h2b; + 7'h09: {i, e, d, c, b, a} = 6'h2b; + 7'h0a: {i, e, d, c, b, a} = 6'h25; + 7'h0b: {i, e, d, c, b, a} = 6'h25; + 7'h0c: {i, e, d, c, b, a} = 6'h26; + 7'h0d: {i, e, d, c, b, a} = 6'h26; + 7'h0e: {i, e, d, c, b, a} = 6'h07; + 7'h0f: {i, e, d, c, b, a} = 6'h07; + 7'h10: {i, e, d, c, b, a} = 6'h27; + 7'h11: {i, e, d, c, b, a} = 6'h27; + 7'h12: {i, e, d, c, b, a} = 6'h29; + 7'h13: {i, e, d, c, b, a} = 6'h29; + 7'h14: {i, e, d, c, b, a} = 6'h2a; + 7'h15: {i, e, d, c, b, a} = 6'h2a; + 7'h16: {i, e, d, c, b, a} = 6'h0b; + 7'h17: {i, e, d, c, b, a} = 6'h0b; + 7'h18: {i, e, d, c, b, a} = 6'h2c; + 7'h19: {i, e, d, c, b, a} = 6'h2c; + 7'h1a: {i, e, d, c, b, a} = 6'h0d; + 7'h1b: {i, e, d, c, b, a} = 6'h0d; + 7'h1c: {i, e, d, c, b, a} = 6'h0e; + 7'h1d: {i, e, d, c, b, a} = 6'h0e; + 7'h1e: {i, e, d, c, b, a} = 6'h3a; + 7'h1f: {i, e, d, c, b, a} = 6'h3a; + 7'h20: {i, e, d, c, b, a} = 6'h36; + 7'h21: {i, e, d, c, b, a} = 6'h36; + 7'h22: {i, e, d, c, b, a} = 6'h31; + 7'h23: {i, e, d, c, b, a} = 6'h31; + 7'h24: {i, e, d, c, b, a} = 6'h32; + 7'h25: {i, e, d, c, b, a} = 6'h32; + 7'h26: {i, e, d, c, b, a} = 6'h13; + 7'h27: {i, e, d, c, b, a} = 6'h33; + 7'h28: {i, e, d, c, b, a} = 6'h34; + 7'h29: {i, e, d, c, b, a} = 6'h34; + 7'h2a: {i, e, d, c, b, a} = 6'h15; + 7'h2b: {i, e, d, c, b, a} = 6'h35; + 7'h2c: {i, e, d, c, b, a} = 6'h16; + 7'h2d: {i, e, d, c, b, a} = 6'h36; + 7'h2e: {i, e, d, c, b, a} = 6'h17; + 7'h2f: {i, e, d, c, b, a} = 6'h17; + 7'h30: {i, e, d, c, b, a} = 6'h33; + 7'h31: {i, e, d, c, b, a} = 6'h33; + 7'h32: {i, e, d, c, b, a} = 6'h19; + 7'h33: {i, e, d, c, b, a} = 6'h39; + 7'h34: {i, e, d, c, b, a} = 6'h1a; + 7'h35: {i, e, d, c, b, a} = 6'h3a; + 7'h36: {i, e, d, c, b, a} = 6'h1b; + 7'h37: {i, e, d, c, b, a} = 6'h1b; + 7'h38: {i, e, d, c, b, a} = 6'h1c; + 7'h39: {i, e, d, c, b, a} = 6'h3c; + 7'h3a: {i, e, d, c, b, a} = 6'h1d; + 7'h3b: {i, e, d, c, b, a} = 6'h1d; + 7'h3c: {i, e, d, c, b, a} = 6'h1e; + 7'h3d: {i, e, d, c, b, a} = 6'h1e; + 7'h3e: {i, e, d, c, b, a} = 6'h35; + 7'h3f: {i, e, d, c, b, a} = 6'h35; + 7'h40: {i, e, d, c, b, a} = 6'h06; + 7'h41: {i, e, d, c, b, a} = 6'h39; + 7'h42: {i, e, d, c, b, a} = 6'h11; + 7'h43: {i, e, d, c, b, a} = 6'h2e; + 7'h44: {i, e, d, c, b, a} = 6'h12; + 7'h45: {i, e, d, c, b, a} = 6'h2d; + 7'h46: {i, e, d, c, b, a} = 6'h23; + 7'h47: {i, e, d, c, b, a} = 6'h1c; + 7'h48: {i, e, d, c, b, a} = 6'h14; + 7'h49: {i, e, d, c, b, a} = 6'h2b; + 7'h4a: {i, e, d, c, b, a} = 6'h25; + 7'h4b: {i, e, d, c, b, a} = 6'h1a; + 7'h4c: {i, e, d, c, b, a} = 6'h26; + 7'h4d: {i, e, d, c, b, a} = 6'h19; + 7'h4e: {i, e, d, c, b, a} = 6'h38; + 7'h4f: {i, e, d, c, b, a} = 6'h38; + 7'h50: {i, e, d, c, b, a} = 6'h18; + 7'h51: {i, e, d, c, b, a} = 6'h27; + 7'h52: {i, e, d, c, b, a} = 6'h29; + 7'h53: {i, e, d, c, b, a} = 6'h16; + 7'h54: {i, e, d, c, b, a} = 6'h2a; + 7'h55: {i, e, d, c, b, a} = 6'h15; + 7'h56: {i, e, d, c, b, a} = 6'h0b; + 7'h57: {i, e, d, c, b, a} = 6'h34; + 7'h58: {i, e, d, c, b, a} = 6'h2c; + 7'h59: {i, e, d, c, b, a} = 6'h13; + 7'h5a: {i, e, d, c, b, a} = 6'h0d; + 7'h5b: {i, e, d, c, b, a} = 6'h32; + 7'h5c: {i, e, d, c, b, a} = 6'h0e; + 7'h5d: {i, e, d, c, b, a} = 6'h31; + 7'h5e: {i, e, d, c, b, a} = 6'h05; + 7'h5f: {i, e, d, c, b, a} = 6'h3a; + 7'h60: {i, e, d, c, b, a} = 6'h09; + 7'h61: {i, e, d, c, b, a} = 6'h09; + 7'h62: {i, e, d, c, b, a} = 6'h31; + 7'h63: {i, e, d, c, b, a} = 6'h0e; + 7'h64: {i, e, d, c, b, a} = 6'h32; + 7'h65: {i, e, d, c, b, a} = 6'h0d; + 7'h66: {i, e, d, c, b, a} = 6'h13; + 7'h67: {i, e, d, c, b, a} = 6'h0c; + 7'h68: {i, e, d, c, b, a} = 6'h34; + 7'h69: {i, e, d, c, b, a} = 6'h0b; + 7'h6a: {i, e, d, c, b, a} = 6'h15; + 7'h6b: {i, e, d, c, b, a} = 6'h0a; + 7'h6c: {i, e, d, c, b, a} = 6'h16; + 7'h6d: {i, e, d, c, b, a} = 6'h09; + 7'h6e: {i, e, d, c, b, a} = 6'h28; + 7'h6f: {i, e, d, c, b, a} = 6'h28; + 7'h70: {i, e, d, c, b, a} = 6'h0c; + 7'h71: {i, e, d, c, b, a} = 6'h33; + 7'h72: {i, e, d, c, b, a} = 6'h19; + 7'h73: {i, e, d, c, b, a} = 6'h06; + 7'h74: {i, e, d, c, b, a} = 6'h1a; + 7'h75: {i, e, d, c, b, a} = 6'h05; + 7'h76: {i, e, d, c, b, a} = 6'h24; + 7'h77: {i, e, d, c, b, a} = 6'h24; + 7'h78: {i, e, d, c, b, a} = 6'h1c; + 7'h79: {i, e, d, c, b, a} = 6'h03; + 7'h7a: {i, e, d, c, b, a} = 6'h22; + 7'h7b: {i, e, d, c, b, a} = 6'h22; + 7'h7c: {i, e, d, c, b, a} = 6'h21; + 7'h7d: {i, e, d, c, b, a} = 6'h21; + 7'h7e: {i, e, d, c, b, a} = 6'h0a; + 7'h7f: {i, e, d, c, b, a} = 6'h0a; + endcase + + case (din_dat[4:0]) + 5'h00: rd1_part = 1'b1; + 5'h01: rd1_part = 1'b1; + 5'h02: rd1_part = 1'b1; + 5'h03: rd1_part = 1'b0; + 5'h04: rd1_part = 1'b1; + 5'h05: rd1_part = 1'b0; + 5'h06: rd1_part = 1'b0; + 5'h07: rd1_part = 1'b0; + 5'h08: rd1_part = 1'b1; + 5'h09: rd1_part = 1'b0; + 5'h0a: rd1_part = 1'b0; + 5'h0b: rd1_part = 1'b0; + 5'h0c: rd1_part = 1'b0; + 5'h0d: rd1_part = 1'b0; + 5'h0e: rd1_part = 1'b0; + 5'h0f: rd1_part = 1'b1; + 5'h10: rd1_part = 1'b1; + 5'h11: rd1_part = 1'b0; + 5'h12: rd1_part = 1'b0; + 5'h13: rd1_part = 1'b0; + 5'h14: rd1_part = 1'b0; + 5'h15: rd1_part = 1'b0; + 5'h16: rd1_part = 1'b0; + 5'h17: rd1_part = 1'b1; + 5'h18: rd1_part = 1'b1; + 5'h19: rd1_part = 1'b0; + 5'h1a: rd1_part = 1'b0; + 5'h1b: rd1_part = 1'b1; + 5'h1c: rd1_part = 1'b0; + 5'h1d: rd1_part = 1'b1; + 5'h1e: rd1_part = 1'b1; + 5'h1f: rd1_part = 1'b1; + endcase + end + + wire disp4 = (!F & !G); + wire disp5 = (F & G); + wire disp6 = ((F ^ G) & K); + wire invert_fj = !(((rd1_part | K) ^ din_rd) ? disp5 : (disp4 | disp6)); + + always @(*) begin + g = (!(!F & !H) & !G) ^ invert_fj; + h = (!H) ^ invert_fj; + end + + wire f0, f1, f2, f3, f4; + + tennm_lcell_comb #( + .lut_mask(64'h0224244002242440), + .extended_lut("off"), + .shared_arith("off") + ) wlc2 ( + .dataa(!din_dat[3]), + .datab(!din_dat[4]), + .datac(!din_dat[1]), + .datad(!din_dat[2]), + .datae(!din_dat[0]), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(f0) + ); + + tennm_lcell_comb #( + .lut_mask(64'h0F03AA590F03AA59), + .extended_lut("off"), + .shared_arith("off") + ) wlc3 ( + .dataa(!din_rd), + .datab(!din_dat[7]), + .datac(!din_dat[6]), + .datad(!din_dat[5]), + .datae(!din_k), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(f1) + ); + + tennm_lcell_comb #( + .lut_mask(64'h00F355A600F355A6), + .extended_lut("off"), + .shared_arith("off") + ) wlc4 ( + .dataa(!din_rd), + .datab(!din_dat[7]), + .datac(!din_dat[6]), + .datad(!din_dat[5]), + .datae(!din_k), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(f2) + ); + + tennm_lcell_comb #( + .lut_mask(64'h7800FF597800FF59), + .extended_lut("off"), + .shared_arith("off") + ) wlc5 ( + .dataa(!f4), + .datab(!f0), + .datac(!din_rd), + .datad(!f1), + .datae(!f2), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(f3) + ); + + tennm_lcell_comb #( + .lut_mask(64'h055E5EE8055E5EE8), + .extended_lut("off"), + .shared_arith("off") + ) wlc6 ( + .dataa(!din_dat[3]), + .datab(!din_dat[4]), + .datac(!din_dat[1]), + .datad(!din_dat[2]), + .datae(!din_dat[0]), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(f4) + ); + + + always @(*) begin + f = f3; + end + + wire j0, j1, j2, j3, j4, j5; + + tennm_lcell_comb #( + .lut_mask(64'h117676E8117676E8), + .extended_lut("off"), + .shared_arith("off") + ) wlc7 ( + .dataa(!din_dat[1]), + .datab(!din_dat[3]), + .datac(!din_dat[4]), + .datad(!din_dat[2]), + .datae(!din_dat[0]), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(j0) + ); + + tennm_lcell_comb #( + .lut_mask(64'h0418182004181820), + .extended_lut("off"), + .shared_arith("off") + ) wlc8 ( + .dataa(!din_dat[1]), + .datab(!din_dat[3]), + .datac(!din_dat[4]), + .datad(!din_dat[2]), + .datae(!din_dat[0]), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(j1) + ); + + tennm_lcell_comb #( + .lut_mask(64'h5339A6665339A666), + .extended_lut("off"), + .shared_arith("off") + ) wlc9 ( + .dataa(!din_rd), + .datab(!din_dat[7]), + .datac(!din_dat[5]), + .datad(!din_dat[6]), + .datae(!din_k), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(j2) + ); + + tennm_lcell_comb #( + .lut_mask(64'hF00F0000F00F0000), + .extended_lut("off"), + .shared_arith("off") + ) wlc10 ( + .dataa(1'b1), + .datab(1'b1), + .datac(!din_dat[5]), + .datad(!din_dat[6]), + .datae(!din_k), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(j3) + ); + + tennm_lcell_comb #( + .lut_mask(64'h0003000000030000), + .extended_lut("off"), + .shared_arith("off") + ) wlc11 ( + .dataa(1'b1), + .datab(!din_dat[7]), + .datac(!din_dat[5]), + .datad(!din_dat[6]), + .datae(!din_k), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(j4) + ); + + tennm_lcell_comb #( + .lut_mask(64'hF07870A6F07870A6), + .extended_lut("off"), + .shared_arith("off") + ) wlc12 ( + .dataa(!j0), + .datab(!j1), + .datac(!j2), + .datad(!j3), + .datae(!j4), + .dataf(1'b1), + .datag(1'b1), + .datah(1'b1), + .cin(1'b0), + // synthesis translate_off + .sharein(1'b0), + // synthesis translate_on + .sumout(), + .cout(), + // synthesis translate_off + .shareout(), + // synthesis translate_on + .combout(j5) + ); + + + always @(*) j = j5; + + + always @(posedge clk) begin + dout_val_r <= 0; + if (din_ena | din_k) begin + dout_rdreg_r <= dout_rdcomb; + dout_val_r <= din_ena | din_k; + dout_dat_r <= {j, h, g, f, i, e, d, c, b, a}; + end + if (sclr) begin + dout_val_r <= 1'b0; + dout_rdreg_r <= 1'b0; + dout_dat_r <= 10'b0; + end + end + assign dout_val = dout_val_r; + assign dout_dat = dout_dat_r; + assign dout_rdreg = dout_rdreg_r; + assign dout_rdcomb = dout_rdcomb_r; + + +endmodule diff --git a/vendors/altera/25.3.1/src/eth_8b10b_enc_x4_a.v b/vendors/altera/25.3.1/src/eth_8b10b_enc_x4_a.v new file mode 100644 index 0000000..7b2c130 --- /dev/null +++ b/vendors/altera/25.3.1/src/eth_8b10b_enc_x4_a.v @@ -0,0 +1,58 @@ +// Copyright 2024 Intel Corporation. +// +// This reference design file is subject licensed to you by the terms and +// conditions of the applicable License Terms and Conditions for Hardware +// Reference Designs and/or Design Examples (either as signed by you or +// found at https://www.altera.com/common/legal/leg-license_agreement.html ). +// +// As stated in the license, you agree to only use this reference design +// solely in conjunction with Intel FPGAs or Intel CPLDs. +// +// THE REFERENCE DESIGN IS PROVIDED "AS IS" WITHOUT ANY EXPRESS OR IMPLIED +// WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY, +// NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not +// warrant or assume responsibility for the accuracy or completeness of any +// information, links or other items within the Reference Design and any +// accompanying materials. +// +// In the event that you do not agree with such terms and conditions, do not +// use the reference design file. +///////////////////////////////////////////////////////////////////////////// + +// Generated by one of Gregg's toys on Mon Jan 15 15:54:16 2024 + +//`timescale 1ps / 1ps + +module eth_8b10b_enc_x4_a ( + input clk, + input sclr, + input [3:0] din_k, + input [31:0] din_dat, + output [39:0] dout_dat +); + + localparam WORDS = 4; + wire [WORDS-1:0] dout_rdcomb; + wire [WORDS-1:0] dout_rdreg; + wire [WORDS-1:0] dout_val; // not used, since din_ena not used in cascaded version + + genvar i; + generate + for (i = 0; i < WORDS; i = i + 1) begin : lp + eth_8b10b_enc_a en0 ( + .clk (clk), + .sclr (sclr), + .din_k (din_k[i]), // Data in is a special code, not all are legal. + .din_ena (1'b1), // Data (or code) input enable + .din_dat (din_dat[(i+1)*8-1:i*8]), // 8b data in + .din_rd ((i == 0) ? dout_rdreg[WORDS-1] : dout_rdcomb[i-1]), // running disparity input + .dout_val (dout_val[i]), // data out is valid + .dout_dat (dout_dat[(i+1)*10-1:i*10]), // data out + .dout_rdcomb(dout_rdcomb[i]), // running disparity output (comb) + .dout_rdreg (dout_rdreg[i]) // running disparity output (reg) + ); + end + endgenerate + + +endmodule