Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 71 additions & 5 deletions INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ QECIPHY provides a simple AXI4-Stream interface that abstracts away all physical

### Hardware Requirements

- Xilinx FPGA with GTX, GTH, or GTY transceivers, or Altera FPGA with E-Tile transceivers
- Xilinx FPGA with GTX, GTH, or GTY transceivers, or Altera FPGA with E-Tile or F-Tile transceivers
- Appropriate reference clock source
- Differential signal routing between FPGAs

Expand Down Expand Up @@ -57,6 +57,8 @@ Check if your hardware platform matches one of the existing profiles in `config.
- **zcu216**: Zynq UltraScale+ with GTY transceivers
- **zcu106**: Zynq UltraScale with GTH transceivers
- **kasliSoC**: 7-series with GTX transceivers
- **de10**: Agilex 7 with E-Tile transceiver
- **agilex7**: Agilex 7 I-Series Development Kit with F-Tile transceiver

If your platform is not listed, create a new profile in `config.json`. Examples for both vendors:

Expand Down Expand Up @@ -114,6 +116,7 @@ If your platform is not listed, create a new profile in `config.json`. Examples
"example_designs/<your-platform>/src.f"
],
"constraints": [
"example_designs/<your-platform>/syn/project_settings.tcl",
"example_designs/<your-platform>/syn/clock_constraints.sdc",
"example_designs/<your-platform>/syn/pin_assignments.tcl"
]
Expand All @@ -127,7 +130,7 @@ If your platform is not listed, create a new profile in `config.json`. Examples
- `device.part`: Your FPGA part number
- `device.family`: Device family (Altera only)
- `board`: Xilinx board file (optional)
- `variant`: Transceiver type (GTX/GTH/GTY/E-Tile)
- `variant`: Transceiver type (`GTX`/`GTH`/`GTY`/`ETILE`/`FTILE`)
- `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") (Xilinx only)
Expand All @@ -139,7 +142,7 @@ If your platform is not listed, create a new profile in `config.json`. Examples

**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:
- Altera `ETILE` and `FTILE` profiles may differ by design:
- `device.family` is required (for example `"Agilex 7"`).
- `fclk_freq` should be omitted
- `transceiver.gt_loc` should be omitted
Expand Down Expand Up @@ -187,6 +190,7 @@ For quick platform validation, create a standalone example design:
│ └── qeciphy_syn_wrapper.sv # Top-level wrapper module
├── src.f # Source file list
└── syn/
├── project_settings.tcl # Quartus project/device settings
├── clock_constraints.sdc # SDC timing constraints
└── pin_assignments.tcl # Quartus pin assignment script
└── signal_tap.stp # Quartus signal tap assignments
Expand All @@ -196,6 +200,7 @@ For quick platform validation, create a standalone example design:
- **`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`** (Xilinx): XDC file with pin assignments, clock definitions, and I/O standards for your platform
- **`syn/project_settings.tcl`** (Altera): Tcl script sourced by Quartus with board-level project settings
- **`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

Expand All @@ -216,6 +221,7 @@ For quick platform validation, create a standalone example design:
For Altera, list `.sdc` and `.tcl` constraint files instead of `.xdc`:
```json
"constraints": [
"example_designs/<your-platform>/syn/project_settings.tcl",
"example_designs/<your-platform>/syn/clock_constraints.sdc",
"example_designs/<your-platform>/syn/pin_assignments.tcl"
]
Expand Down Expand Up @@ -287,7 +293,7 @@ You must add the following timing constraints to your project for proper operati

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.
**Note:** The E-Tile and F-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

Expand Down Expand Up @@ -461,6 +467,66 @@ set_false_path -from [get_keepers -no_duplicates {i_QECIPHY|i_qeciphy_resetcontr
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]}]
```

### F-Tile Transceiver Constraints

These constraints are in SDC format for Quartus Prime. They assume the QECIPHY instance is named `i_QECIPHY`. The clock creation paths are identical to E-Tile; only the false path `get_keepers` expressions differ due to the F-Tile's internal reset controller hierarchy.

```tcl
# Reference clock and AXI clock (replace period and port names for your board)
create_clock -name RCLK -period <refclk_period> [get_ports {<refclk_port>}]
create_clock -name ACLK -period <axi_clk_period> [get_ports {<axi_clk_port>}]

# 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 F-Tile reset/ready signals crossing clock domains
set_false_path -from [get_keepers -no_duplicates {synth_qeciphy_auto_tiles|*__reset_controller|x_f_tile_soft_reset_ctlr_sip_v1|x_ftile_reset|rst_ctrl|rx_lane_current_state_r[13]}] -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 {synth_qeciphy_auto_tiles|*__reset_controller|x_f_tile_soft_reset_ctlr_sip_v1|x_ftile_reset|rst_ctrl|tx_lane_current_state_r[13]}] -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 {synth_qeciphy_auto_tiles|*__reset_controller|x_f_tile_soft_reset_ctlr_sip_v1|x_ftile_reset|rst_ctrl|rx_lane_current_state_r[13]}] -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 {synth_qeciphy_auto_tiles|*__reset_controller|x_f_tile_soft_reset_ctlr_sip_v1|x_ftile_reset|rst_ctrl|tx_lane_current_state_r[13]}] -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]}]
```

> **Note:** The exact keeper paths for F-Tile false paths depend on Quartus's auto-tile placement. Replace `*__reset_controller` with the specific tile instance name reported by the Quartus Timing Analyzer for your device. Refer to `example_designs/agilex7/syn/clock_constraints.sdc` for a board-specific example.

## Data Path Integration Examples

### Reset Synchronization
Expand Down Expand Up @@ -598,4 +664,4 @@ QECIPHY uses standard AXI4-Stream protocol with 64-bit data width:
For additional support, please refer to:
- [README.md](README.md) - Project overview and quick start
- [docs/architecture.md](docs/architecture.md) - Detailed architecture description
- [GitHub Issues](https://github.com/riverlane/qeciphy/issues) - Report issues or ask questions
- [GitHub Issues](https://github.com/riverlane/qeciphy/issues) - Report issues or ask questions
20 changes: 19 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -384,8 +384,26 @@ quartus_generate_ip:
"--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)/ \; ; \
elif [ "$(VARIANT)" = "FTILE" ]; 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_ftile.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)/refclk.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."; \
echo "ERROR: Unsupported variant $(VARIANT) for Quartus IP generation. Must be ETILE or FTILE."; \
exit 1; \
fi

Expand Down
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 Xilinx FPGAs (GTX, GTH, GTY transceivers) and Altera FPGAs (E-Tile transceiver)
- **Universal Compatibility**: Supports Xilinx FPGAs (GTX, GTH, GTY transceivers) and Altera FPGAs (E-Tile and F-Tile transceivers)
- **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
Expand All @@ -39,7 +39,7 @@ QECIPHY is a physical layer implementation according to the [QECi (Quantum Error

**To use QECIPHY:**
- Vivado 2024.1+: tested with 2024.1 (Xilinx targets)
- Quartus Prime Pro 25.3.1: tested with 25.3.1 (Altera E-Tile targets)
- Quartus Prime Pro 25.3.1: tested with 25.3.1 (Altera E-Tile and F-Tile targets)
- Python 3.8+: for build scripts
- Make: for build automation

Expand All @@ -66,18 +66,20 @@ 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
# make render-design OPT_PROFILE=agilex7 # F-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
# Note: Simulation with Altera FPGAs is currently unsupported

# Run synthesis
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)
# make synth OPT_PROFILE=agilex7 # F-Tile (uses Quartus Prime Pro)
```

> *And you're done! For detailed integration instructions, please refer to the [Integration Guide](INTEGRATION.md).*
Expand Down Expand Up @@ -187,6 +189,8 @@ make sim OPT_PROFILE=<profile> OPT_TOOL=vcs

# Run VCS simulation (GUI mode)
make sim OPT_PROFILE=<profile> OPT_TOOL=vcs OPT_MODE=gui

#Note: Altera simulation is currently unsupported
```

> *If you are interested to learn more about multi-platform simulation support, please refer to the [Multi-Platform Simulation Guide](docs/multi_platform_simulation.md).*
Expand Down
31 changes: 31 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
"example_designs/de10/src.f"
],
"constraints": [
"example_designs/de10/syn/project_settings.tcl",
"example_designs/de10/syn/pin_assignments.tcl",
"example_designs/de10/syn/clock_constraints.sdc",
"example_designs/de10/syn/signal_tap.stp"
Expand All @@ -114,6 +115,36 @@
"example_designs/vendors/altera/25.3.1/ip/sys_clk_200_pll.tcl"
]
}
},
"agilex7": {
"device": {
"part": "AGIB027R29A1E1VB",
"vendor": "altera",
"family": "Agilex 7"
},
"variant": "FTILE",
"rclk_freq": "156.25",
"transceiver": {
"line_rate_gbps": "10.3125"
},
"synth": {
"top": "qeciphy_syn_wrapper",
"filelists": [
"example_designs/agilex7/src.f"
],
"constraints": [
"example_designs/agilex7/syn/project_settings.tcl",
"example_designs/agilex7/syn/pin_assignments.tcl",
"example_designs/agilex7/syn/clock_constraints.sdc",
"example_designs/agilex7/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"
]
}
}
}
}
2 changes: 2 additions & 0 deletions example_designs/agilex7/src.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-F src_altera.f
example_designs/agilex7/src/qeciphy_syn_wrapper.sv
Loading
Loading