Skip to content
Open
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
3 changes: 2 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
OPT_MODE?=batch
OPT_PROFILE?=
OPT_SIM_FILES ?= false
OPT_TOOL?=
OPT_TOOL?=xsim

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to define a default target here?

OPT_TOP?=
OPT_TEST?=
OPT_ARGS?=0
Expand Down Expand Up @@ -188,6 +188,7 @@ get_gt_type = $(shell \
if [ "$(OPT_PROFILE)" = "kasliSoC" ]; then echo "GTX"; \
elif [ "$(OPT_PROFILE)" = "zcu106" ]; then echo "GTH"; \
elif [ "$(OPT_PROFILE)" = "zcu216" ]; then echo "GTY"; \
elif [ "$(OPT_PROFILE)" = "zcu111" ]; then echo "GTY"; \
else echo "GTY"; fi)

# -------------------------------------------------------------
Expand Down
29 changes: 29 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,35 @@
]
}
},
"zcu111": {
"device": {
"part": "xczu28dr-ffvg1517-2-e",
"vendor": "xilinx"
},
"board": "xilinx.com:zcu111:part0:1.4",
"variant": "GTY",
"fclk_freq": "156.25",
"rclk_freq": "156.25",
"transceiver": {
"gt_loc": "X0Y8",
"rx_rclk_src": "X0Y8 clk1+1",
"tx_rclk_src": "X0Y8 clk1+1",
"line_rate_gbps": "10.3125"
},
"synth": {
"top": "qeciphy_syn_wrapper",
"filelists": [
"example_designs/zcu111/src.f"
],
"constraints": [
"example_designs/zcu111/syn/constraints.xdc"
],
"pre_setup_hooks": [
"example_designs/vendors/xilinx/qeciphy_rx_ila.tcl",
"example_designs/vendors/xilinx/qeciphy_vio.tcl"
]
}
},
"kasliSoC": {
"device": {
"part": "xc7z030ffg676-3",
Expand Down
2 changes: 2 additions & 0 deletions example_designs/zcu111/src.f
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-F src.f
example_designs/zcu111/src/qeciphy_syn_wrapper.sv
156 changes: 156 additions & 0 deletions example_designs/zcu111/src/qeciphy_syn_wrapper.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
// SPDX-License-Identifier: BSD-2-Clause
// Copyright (c) 2025 Riverlane Ltd.
// Original authors: Aniket Datta, Gargi Sunil

module qeciphy_syn_wrapper (
input logic gt_refclk_in_p,
input logic gt_refclk_in_n,
input logic gt_rx_p,
input logic gt_rx_n,
output logic gt_tx_p,
output logic gt_tx_n,
output logic [3:0] SFP_tx_enable,
output logic [2:0] led
);

// 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 [ 4:0] rst_counter;
logic [ 4:0] rst_counter_nxt;
logic rst_n_async;
logic [ 1:0] rst_n_sf;
logic rst_n;
logic clk_freerun;
logic [ 3:0] sfp_enable;
logic [63:0] RX_TDATA_ref;
logic [63:0] RX_TDATA_ref_nxt;
logic RXDATA_error;
logic RXDATA_error_nxt;

assign SFP_tx_enable = sfp_enable;

// Refer: https://docs.amd.com/r/en-US/ug974-vivado-ultrascale-libraries/IBUFDS_GTE4
IBUFDS_GTE4 #(
.REFCLK_EN_TX_PATH(1'b0),
.REFCLK_HROW_CK_SEL(2'b00),
.REFCLK_ICNTL_RX(2'b00)
) i_buff_gtrefclk (
.O (RCLK),
.ODIV2(clk_freerun),
.CEB (1'b0),
.I (gt_refclk_in_p),
.IB (gt_refclk_in_n)
);

BUFG_GT i_buff_fclk (
.O (FCLK),
.CE (1'b1),
.CEMASK (1'b1),
.CLR (1'b0),
.CLRMASK(1'b1),
.DIV (3'b000),
.I (clk_freerun)
);

qeciphy_rx_ila i_rx_ila (
.clk (ACLK),
.probe0(RX_TDATA),
.probe1(RX_TVALID),
.probe2(STATUS),
.probe3(ECODE),
.probe4(sfp_enable),
.probe5(RXDATA_error)
);

qeciphy_vio i_vio (
.clk (ACLK),
.probe_out0(rst_n_async),
.probe_out1(sfp_enable)
);

// 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];

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) begin
if (!rst_n_async) rst_n_sf <= 2'h0;
else rst_n_sf <= {rst_n_sf[0], 1'b1};
end

// Connect free-running clock to AXI clock for simplicity
assign ACLK = FCLK;

// By the spec
assign RX_TREADY = 1'b1;

// 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;

// 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

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)
);

endmodule
46 changes: 46 additions & 0 deletions example_designs/zcu111/syn/constraints.xdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# SPDX-License-Identifier: BSD-2-Clause
# Copyright (c) 2025 Riverlane Ltd.
# Original authors: Dogancan Davutoglu, Aniket Datta, Gargi Sunil

create_clock -period 6.400 -name gt_refclk [get_ports gt_refclk_in_p]
set_property PACKAGE_PIN W33 [get_ports gt_refclk_in_p]

# -------------------------------------------------------------------------
# QECIPHY instance 0 clocks
# -------------------------------------------------------------------------
create_generated_clock -name rx_clk [get_pins -hierarchical -filter {NAME =~ *i_QECIPHY/i_qeciphy_serdes/i_qeciphy_gt_wrapper/gen_GTY_transceiver.i_BUFG_rx_clk/O}]
create_generated_clock -name gt_rx_clk [get_pins -hierarchical -filter {NAME =~ *i_QECIPHY/i_qeciphy_serdes/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 =~ *i_QECIPHY/i_qeciphy_serdes/i_qeciphy_gt_wrapper/gen_GTY_transceiver.i_BUFG_tx_clk/O}]
create_generated_clock -name gt_tx_clk [get_pins -hierarchical -filter {NAME =~ *i_QECIPHY/i_qeciphy_serdes/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}]
set_property CLOCK_DELAY_GROUP rx_clk_dly_grp [get_nets -hierarchical -filter {NAME =~ *i_QECIPHY/i_qeciphy_serdes/i_qeciphy_gt_wrapper/rx_clk_o || NAME =~ *i_QECIPHY/i_qeciphy_serdes/i_qeciphy_gt_wrapper/rx_clk_2x_o}]
set_property CLOCK_DELAY_GROUP tx_clk_dly_grp [get_nets -hierarchical -filter {NAME =~ *i_QECIPHY/i_qeciphy_serdes/i_qeciphy_gt_wrapper/tx_clk_o || NAME =~ *i_QECIPHY/i_qeciphy_serdes/i_qeciphy_gt_wrapper/tx_clk_2x_o}]

#Define multicycle path between sync clocks
set_multicycle_path -setup -end -from [get_clocks rx_clk] -to [get_clocks gt_rx_clk] 2
set_multicycle_path -hold -end -from [get_clocks rx_clk] -to [get_clocks gt_rx_clk] 1
set_multicycle_path -setup -start -from [get_clocks gt_rx_clk] -to [get_clocks rx_clk] 2
set_multicycle_path -hold -start -from [get_clocks gt_rx_clk] -to [get_clocks rx_clk] 1
set_multicycle_path -setup -end -from [get_clocks tx_clk] -to [get_clocks gt_tx_clk] 2
set_multicycle_path -hold -end -from [get_clocks tx_clk] -to [get_clocks gt_tx_clk] 1
set_multicycle_path -setup -start -from [get_clocks gt_tx_clk] -to [get_clocks tx_clk] 2
set_multicycle_path -hold -start -from [get_clocks gt_tx_clk] -to [get_clocks tx_clk] 1

set_property IOSTANDARD LVCMOS18 [get_ports {led[0]}]
set_property IOSTANDARD LVCMOS18 [get_ports {led[1]}]
set_property IOSTANDARD LVCMOS18 [get_ports {led[2]}]

set_property PACKAGE_PIN AR13 [get_ports {led[0]}]
set_property PACKAGE_PIN AP13 [get_ports {led[1]}]
set_property PACKAGE_PIN AR16 [get_ports {led[2]}]

set_property IOSTANDARD LVCMOS12 [get_ports {SFP_tx_enable[0]}]
set_property IOSTANDARD LVCMOS12 [get_ports {SFP_tx_enable[1]}]
set_property IOSTANDARD LVCMOS12 [get_ports {SFP_tx_enable[2]}]
set_property IOSTANDARD LVCMOS12 [get_ports {SFP_tx_enable[3]}]

set_property PACKAGE_PIN G12 [get_ports {SFP_tx_enable[0]}]
set_property PACKAGE_PIN G10 [get_ports {SFP_tx_enable[1]}]
set_property PACKAGE_PIN K12 [get_ports {SFP_tx_enable[2]}]
set_property PACKAGE_PIN J7 [get_ports {SFP_tx_enable[3]}]
Loading