Compare commits

..

54 Commits

Author SHA1 Message Date
Alex Forencich
8567f91ef6 cndm: Add support for Silicom fb2CG@KU15P
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-25 00:52:42 -08:00
Alex Forencich
2659fec26b cndm: Add support for ZCU106
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 18:33:41 -08:00
Alex Forencich
6827f619f7 cndm: Clean up unused MMCM outputs
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 17:51:57 -08:00
Alex Forencich
39638ab4d3 eth/example: Clean up unused MMCM outputs
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 17:51:40 -08:00
Alex Forencich
146fc78a2f eth/example: XDC cleanup
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 17:50:10 -08:00
Alex Forencich
3fc54f0384 cndm: Add missing testbench connections
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 17:49:26 -08:00
Alex Forencich
37393ca112 cndm_proto: Add missing testbench connections
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 17:49:10 -08:00
Alex Forencich
6f43d2b454 eth/example: Clean up hardware server commands
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 17:48:32 -08:00
Alex Forencich
34408521cc cndm: Add support for VCU108
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 15:23:32 -08:00
Alex Forencich
5545602a26 pcie: Fix width cast
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 14:26:42 -08:00
Alex Forencich
8b925954ef pyrite: Add support for flashing via PCIe VSEC
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 12:33:55 -08:00
Alex Forencich
5d3aff95cc pcie: Add VSEC AXIL register access extended capability implementation for UltraScale
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 12:20:02 -08:00
Alex Forencich
7bb3f18fa3 pcie: Add VSEC APB register access extended capability implementation for UltraScale
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 12:19:54 -08:00
Alex Forencich
842d39faca pyrite: Fix compiler warning
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 12:02:55 -08:00
Alex Forencich
d627de2c15 pyrite: Ensure APB IF is included
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-24 11:47:59 -08:00
Alex Forencich
0519318ea0 cndm: Alveo testbench cleanup
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-23 20:55:51 -08:00
Alex Forencich
b1d66f36fb cndm: AS02MC04 testbench cleanup
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-23 20:55:36 -08:00
Alex Forencich
e33bac67d7 cndm: Add support for Alpha Data ADM-PCIE-9V3
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-23 20:53:30 -08:00
Alex Forencich
781b7902a6 cndm: Add support for Alveo U280
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-23 14:47:18 -08:00
Alex Forencich
a404a2c0ba cndm: Add support for Alveo U50
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-23 14:13:26 -08:00
Alex Forencich
d09efd9a5a cndm: Add support for RK-XCKU5P-F
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-23 00:51:13 -08:00
Alex Forencich
329b9a99be cndm: Add support for Alveo X3/X3522
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-23 00:47:08 -08:00
Alex Forencich
0ccd136c15 cndm: Add support for Alveo U45N/SN1000
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-23 00:45:49 -08:00
Alex Forencich
5b7b0bc35e cndm: Add support for Alveo AU55N/AU55C
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-23 00:45:03 -08:00
Alex Forencich
7f55a956f4 cndm: Add support for Alveo AU250
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-22 18:32:10 -08:00
Alex Forencich
d1aa3013c6 cndm: Add support for Alveo AU200/VCU1525
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-22 16:49:55 -08:00
Alex Forencich
09665325bc eth: Update readme
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-22 15:13:04 -08:00
Alex Forencich
4b3319ff0c eth: Add Ethernet example design for XEM8320 board
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-22 13:58:24 -08:00
Alex Forencich
9ace50f723 eth: Support artixuplus in MAC wrappers
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-22 13:14:59 -08:00
Alex Forencich
d8719efbee cndm: Fix device IDs
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-21 15:57:34 -08:00
Alex Forencich
ca5f9b045d dma: Add workaround for verilator linter bug
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-21 14:03:37 -08:00
Alex Forencich
69c2a1e896 pyrite: Cast widths
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-21 13:56:13 -08:00
Alex Forencich
427aabe5d7 eth: RK-XCKU5P-F XDC cleanup
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-21 02:49:01 -08:00
Alex Forencich
be80d4e964 pcie: Tie off AXIL user signals in PCIe AXI lite master module
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-21 02:48:18 -08:00
Alex Forencich
1e6f5531d1 eth: Fix typo
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 22:15:01 -08:00
Alex Forencich
c37b4cbbfa pyrite: Cast widths
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 22:14:20 -08:00
Alex Forencich
9b55a08465 pcie: Cast widths in VPD implementation
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 22:14:01 -08:00
Alex Forencich
63c9544c3f cndm: Clean up parameters, add flashing support via pyrite
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 22:05:50 -08:00
Alex Forencich
b68be72e70 cndm: Fix readme
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 21:34:06 -08:00
Alex Forencich
5a439c7e8e pyrite: Add flash access modules for UltraScale PCIe VPD
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 21:33:09 -08:00
Alex Forencich
2387aa793e eth: Add Ethernet example design for RK-XCKU5P-F board
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 21:31:46 -08:00
Alex Forencich
add1c7aec2 eth: Fix path
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 21:10:04 -08:00
Alex Forencich
8fe55a6aae eth: Minor example design cleanup
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 13:54:48 -08:00
Alex Forencich
2b2450da54 cndm: Fix path
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-20 12:41:10 -08:00
Alex Forencich
589a80f582 pyrite: Initial commit of pyrite flashing utility
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-19 21:46:09 -08:00
Alex Forencich
8f40d3a426 cndm_proto: Fix PCIe class code
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-18 13:21:35 -08:00
Alex Forencich
43de83de89 cndm: Fix PCIe class code
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-18 13:21:24 -08:00
Alex Forencich
8b13e7a1ea ptp: Ensure reads are consistent
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-16 20:37:37 -08:00
Alex Forencich
45d7b1d77c ptp: Fix signal name
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-16 17:47:29 -08:00
Alex Forencich
dc70c7247a ptp: Fix parameter name
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-16 16:54:56 -08:00
Alex Forencich
9630afce1d pcie: Add VPD capability implementation for UltraScale+
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-16 13:37:35 -08:00
Alex Forencich
d6744bc99b cndm_proto: Clean up ports
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-16 12:34:37 -08:00
Alex Forencich
ab01a1ba42 cndm: Clean up ports
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-16 12:34:28 -08:00
Alex Forencich
5951547d11 apb: Add APB to AXI lite adapter module and testbench
Signed-off-by: Alex Forencich <alex@alexforencich.com>
2026-02-15 12:49:30 -08:00
236 changed files with 44986 additions and 350 deletions

View File

@@ -77,6 +77,7 @@ The Taxi transport library contains many smaller components that can be composed
* APB
* SV interface for APB
* APB to AXI lite adapter
* Interconnect
* Width converter
* Single-port RAM
@@ -219,12 +220,14 @@ Example designs are provided for several different FPGA boards, showcasing many
* Cisco Nexus K3P-S/ExaNIC X25 (Xilinx Kintex UltraScale+ XCKU3P)
* Cisco Nexus K3P-Q/ExaNIC X100 (Xilinx Kintex UltraScale+ XCKU3P)
* Alibaba AS02MC04 (Xilinx Kintex UltraScale+ XCKU3P)
* RK-XCKU5P-F (Xilinx Kintex UltraScale+ XCKU5P)
* Digilent Arty A7 (Xilinx Artix 7 XC7A35T)
* Digilent NetFPGA SUME (Xilinx Virtex 7 XC7V690T)
* HiTech Global HTG-940 (Xilinx Virtex UltraScale+ XCVU9P/XCVU13P)
* HiTech Global HTG-9200 (Xilinx Virtex UltraScale+ XCVU9P/XCVU13P)
* HiTech Global HTG-ZRF8-R2 (Xilinx Zynq UltraScale+ RFSoC XCZU28DR/XCZU48DR)
* HiTech Global HTG-ZRF8-EM (Xilinx Zynq UltraScale+ RFSoC XCZU28DR/XCZU48DR)
* Opal Kelley XEM8320 (Xilinx Artix UltraScale+ XCAU25P)
* Silicom fb2CG@KU15P (Xilinx Kintex UltraScale+ XCKU15P)
* Xilinx Alveo U45N/SN1000 (Xilinx Virtex UltraScale+ XCU26)
* Xilinx Alveo U50 (Xilinx Virtex UltraScale+ XCU50)

View File

@@ -0,0 +1,601 @@
// SPDX-License-Identifier: CERN-OHL-S-2.0
/*
Copyright (c) 2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* APB to AXI4 lite adapter
*/
module taxi_apb_axil_adapter
(
input wire logic clk,
input wire logic rst,
/*
* APB slave interface
*/
taxi_apb_if.slv s_apb,
/*
* AXI4-Lite master interface
*/
taxi_axil_if.wr_mst m_axil_wr,
taxi_axil_if.rd_mst m_axil_rd
);
// extract parameters
localparam APB_DATA_W = s_apb.DATA_W;
localparam APB_ADDR_W = s_apb.ADDR_W;
localparam APB_STRB_W = s_apb.STRB_W;
localparam logic PAUSER_EN = (m_axil_wr.AWUSER_EN || m_axil_wr.ARUSER_EN) && s_apb.PAUSER_EN;
localparam PAUSER_W = s_apb.PAUSER_W;
localparam logic PWUSER_EN = m_axil_wr.WUSER_EN && s_apb.PWUSER_EN;
localparam PWUSER_W = s_apb.PWUSER_W;
localparam logic PRUSER_EN = m_axil_rd.RUSER_EN && s_apb.PRUSER_EN;
localparam PRUSER_W = s_apb.PRUSER_W;
localparam logic PBUSER_EN = m_axil_wr.BUSER_EN && s_apb.PBUSER_EN;
localparam PBUSER_W = s_apb.PBUSER_W;
localparam AXIL_DATA_W = m_axil_rd.DATA_W;
localparam AXIL_ADDR_W = m_axil_rd.ADDR_W;
localparam AXIL_STRB_W = m_axil_rd.STRB_W;
localparam logic AWUSER_EN = m_axil_wr.AWUSER_EN && s_apb.PAUSER_EN;
localparam AWUSER_W = m_axil_wr.AWUSER_W;
localparam logic WUSER_EN = m_axil_wr.WUSER_EN && s_apb.PWUSER_EN;
localparam WUSER_W = m_axil_wr.WUSER_W;
localparam logic BUSER_EN = m_axil_wr.BUSER_EN && s_apb.PBUSER_EN;
localparam BUSER_W = m_axil_wr.BUSER_W;
localparam logic ARUSER_EN = m_axil_rd.ARUSER_EN && s_apb.PAUSER_EN;
localparam ARUSER_W = m_axil_rd.ARUSER_W;
localparam logic RUSER_EN = m_axil_rd.RUSER_EN && s_apb.PRUSER_EN;
localparam RUSER_W = m_axil_rd.RUSER_W;
localparam AUSER_W = ARUSER_W > AWUSER_W ? ARUSER_W : AWUSER_W;
localparam APB_ADDR_BIT_OFFSET = $clog2(APB_STRB_W);
localparam AXIL_ADDR_BIT_OFFSET = $clog2(AXIL_STRB_W);
localparam APB_BYTE_LANES = APB_STRB_W;
localparam AXIL_BYTE_LANES = AXIL_STRB_W;
localparam APB_BYTE_W = APB_DATA_W/APB_BYTE_LANES;
localparam AXIL_BYTE_W = AXIL_DATA_W/AXIL_BYTE_LANES;
localparam APB_ADDR_MASK = {APB_ADDR_W{1'b1}} << APB_ADDR_BIT_OFFSET;
localparam AXIL_ADDR_MASK = {AXIL_ADDR_W{1'b1}} << AXIL_ADDR_BIT_OFFSET;
// check configuration
if (APB_BYTE_W * APB_STRB_W != APB_DATA_W)
$fatal(0, "Error: APB interface data width not evenly divisible (instance %m)");
if (AXIL_BYTE_W * AXIL_STRB_W != AXIL_DATA_W)
$fatal(0, "Error: AXI lite interface data width not evenly divisible (instance %m)");
if (APB_BYTE_W != AXIL_BYTE_W)
$fatal(0, "Error: byte size mismatch (instance %m)");
if (2**$clog2(APB_BYTE_LANES) != APB_BYTE_LANES)
$fatal(0, "Error: APB interface byte lane count must be even power of two (instance %m)");
if (2**$clog2(AXIL_BYTE_LANES) != AXIL_BYTE_LANES)
$fatal(0, "Error: AXI lite interface byte lane count must be even power of two (instance %m)");
if (m_axil_wr.DATA_W != m_axil_rd.DATA_W)
$fatal(0, "Error: AXI interface configuration mismatch (instance %m)");
if (AXIL_BYTE_LANES == APB_BYTE_LANES) begin : bypass
// same width; translate
localparam [0:0]
STATE_IDLE = 1'd0,
STATE_DATA = 1'd1;
logic [0:0] state_reg = STATE_IDLE, state_next;
logic s_apb_pready_reg = 1'b0, s_apb_pready_next;
logic [APB_DATA_W-1:0] s_apb_prdata_reg = '0, s_apb_prdata_next;
logic s_apb_pslverr_reg = 1'b0, s_apb_pslverr_next;
logic [PRUSER_W-1:0] s_apb_pruser_reg = '0, s_apb_pruser_next;
logic [PBUSER_W-1:0] s_apb_pbuser_reg = '0, s_apb_pbuser_next;
logic [AXIL_ADDR_W-1:0] m_axil_addr_reg = '0, m_axil_addr_next;
logic [2:0] m_axil_prot_reg = 3'd0, m_axil_prot_next;
logic [AUSER_W-1:0] m_axil_auser_reg = '0, m_axil_auser_next;
logic m_axil_awvalid_reg = 1'b0, m_axil_awvalid_next;
logic [AXIL_DATA_W-1:0] m_axil_wdata_reg = '0, m_axil_wdata_next;
logic [AXIL_STRB_W-1:0] m_axil_wstrb_reg = '0, m_axil_wstrb_next;
logic [WUSER_W-1:0] m_axil_wuser_reg = '0, m_axil_wuser_next;
logic m_axil_wvalid_reg = 1'b0, m_axil_wvalid_next;
logic m_axil_bready_reg = 1'b0, m_axil_bready_next;
logic m_axil_arvalid_reg = 1'b0, m_axil_arvalid_next;
logic m_axil_rready_reg = 1'b0, m_axil_rready_next;
assign s_apb.pready = s_apb_pready_reg;
assign s_apb.prdata = s_apb_prdata_reg;
assign s_apb.pslverr = s_apb_pslverr_reg;
assign s_apb.pruser = PRUSER_EN ? s_apb_pruser_reg : '0;
assign s_apb.pbuser = PBUSER_EN ? s_apb_pbuser_reg : '0;
assign m_axil_wr.awaddr = m_axil_addr_reg;
assign m_axil_wr.awprot = m_axil_prot_reg;
assign m_axil_wr.awuser = AWUSER_EN ? m_axil_auser_reg : '0;
assign m_axil_wr.awvalid = m_axil_awvalid_reg;
assign m_axil_wr.wdata = m_axil_wdata_reg;
assign m_axil_wr.wstrb = m_axil_wstrb_reg;
assign m_axil_wr.wuser = WUSER_EN ? m_axil_wuser_reg : '0;
assign m_axil_wr.wvalid = m_axil_wvalid_reg;
assign m_axil_wr.bready = m_axil_bready_reg;
assign m_axil_rd.araddr = m_axil_addr_reg;
assign m_axil_rd.arprot = m_axil_prot_reg;
assign m_axil_rd.aruser = ARUSER_EN ? m_axil_auser_reg : '0;
assign m_axil_rd.arvalid = m_axil_arvalid_reg;
assign m_axil_rd.rready = m_axil_rready_reg;
always_comb begin
state_next = STATE_IDLE;
s_apb_pready_next = 1'b0;
s_apb_prdata_next = s_apb_prdata_reg;
s_apb_pslverr_next = s_apb_pslverr_reg;
s_apb_pruser_next = s_apb_pruser_reg;
s_apb_pbuser_next = s_apb_pbuser_reg;
m_axil_addr_next = m_axil_addr_reg;
m_axil_prot_next = m_axil_prot_reg;
m_axil_auser_next = m_axil_auser_reg;
m_axil_awvalid_next = m_axil_awvalid_reg && !m_axil_wr.awready;
m_axil_wdata_next = m_axil_wdata_reg;
m_axil_wstrb_next = m_axil_wstrb_reg;
m_axil_wuser_next = m_axil_wuser_reg;
m_axil_wvalid_next = m_axil_wvalid_reg && !m_axil_wr.wready;
m_axil_bready_next = 1'b0;
m_axil_arvalid_next = m_axil_arvalid_reg && !m_axil_rd.arready;
m_axil_rready_next = 1'b0;
case (state_reg)
STATE_IDLE: begin
m_axil_addr_next = s_apb.paddr;
m_axil_prot_next = s_apb.pprot;
m_axil_wdata_next = s_apb.pwdata;
m_axil_wstrb_next = s_apb.pstrb;
m_axil_auser_next = s_apb.pauser;
m_axil_wuser_next = s_apb.pwuser;
if (s_apb.psel && s_apb.penable && !s_apb.pready) begin
if (s_apb.pwrite) begin
m_axil_awvalid_next = 1'b1;
m_axil_wvalid_next = 1'b1;
m_axil_bready_next = 1'b1;
end else begin
m_axil_arvalid_next = 1'b1;
m_axil_rready_next = 1'b1;
end
state_next = STATE_DATA;
end else begin
state_next = STATE_IDLE;
end
end
STATE_DATA: begin
if (s_apb.pwrite) begin
m_axil_bready_next = 1'b1;
end else begin
m_axil_rready_next = 1'b1;
end
s_apb_pready_next = 1'b0;
s_apb_prdata_next = m_axil_rd.rdata;
s_apb_pslverr_next = s_apb.pwrite ? m_axil_wr.bresp[1] : m_axil_rd.rresp[1];
s_apb_pruser_next = m_axil_rd.ruser;
s_apb_pbuser_next = m_axil_wr.buser;
if (s_apb.pwrite ? (m_axil_wr.bready && m_axil_wr.bvalid) : (m_axil_rd.rready && m_axil_rd.rvalid)) begin
m_axil_bready_next = 1'b0;
m_axil_rready_next = 1'b0;
s_apb_pready_next = 1'b1;
state_next = STATE_IDLE;
end else begin
state_next = STATE_DATA;
end
end
endcase
end
always_ff @(posedge clk) begin
state_reg <= state_next;
s_apb_pready_reg <= s_apb_pready_next;
s_apb_prdata_reg <= s_apb_prdata_next;
s_apb_pslverr_reg <= s_apb_pslverr_next;
s_apb_pruser_reg <= s_apb_pruser_next;
s_apb_pbuser_reg <= s_apb_pbuser_next;
m_axil_addr_reg <= m_axil_addr_next;
m_axil_prot_reg <= m_axil_prot_next;
m_axil_auser_reg <= m_axil_auser_next;
m_axil_awvalid_reg <= m_axil_awvalid_next;
m_axil_wdata_reg <= m_axil_wdata_next;
m_axil_wstrb_reg <= m_axil_wstrb_next;
m_axil_wuser_reg <= m_axil_wuser_next;
m_axil_wvalid_reg <= m_axil_wvalid_next;
m_axil_bready_reg <= m_axil_bready_next;
m_axil_arvalid_reg <= m_axil_arvalid_next;
m_axil_rready_reg <= m_axil_rready_next;
if (rst) begin
state_reg <= STATE_IDLE;
s_apb_pready_reg <= 1'b0;
m_axil_awvalid_reg <= 1'b0;
m_axil_wvalid_reg <= 1'b0;
m_axil_bready_reg <= 1'b0;
m_axil_arvalid_reg <= 1'b0;
m_axil_rready_reg <= 1'b0;
end
end
end else if (AXIL_BYTE_LANES > APB_BYTE_LANES) begin : upsize
// output is wider; upsize
localparam [0:0]
STATE_IDLE = 1'd0,
STATE_DATA = 1'd1;
logic [0:0] state_reg = STATE_IDLE, state_next;
logic s_apb_pready_reg = 1'b0, s_apb_pready_next;
logic [APB_DATA_W-1:0] s_apb_prdata_reg = '0, s_apb_prdata_next;
logic s_apb_pslverr_reg = 1'b0, s_apb_pslverr_next;
logic [PRUSER_W-1:0] s_apb_pruser_reg = '0, s_apb_pruser_next;
logic [PBUSER_W-1:0] s_apb_pbuser_reg = '0, s_apb_pbuser_next;
logic [AXIL_ADDR_W-1:0] m_axil_addr_reg = '0, m_axil_addr_next;
logic [2:0] m_axil_prot_reg = 3'd0, m_axil_prot_next;
logic [AUSER_W-1:0] m_axil_auser_reg = '0, m_axil_auser_next;
logic m_axil_awvalid_reg = 1'b0, m_axil_awvalid_next;
logic [AXIL_DATA_W-1:0] m_axil_wdata_reg = '0, m_axil_wdata_next;
logic [AXIL_STRB_W-1:0] m_axil_wstrb_reg = '0, m_axil_wstrb_next;
logic [WUSER_W-1:0] m_axil_wuser_reg = '0, m_axil_wuser_next;
logic m_axil_wvalid_reg = 1'b0, m_axil_wvalid_next;
logic m_axil_bready_reg = 1'b0, m_axil_bready_next;
logic m_axil_arvalid_reg = 1'b0, m_axil_arvalid_next;
logic m_axil_rready_reg = 1'b0, m_axil_rready_next;
assign s_apb.pready = s_apb_pready_reg;
assign s_apb.prdata = s_apb_prdata_reg;
assign s_apb.pslverr = s_apb_pslverr_reg;
assign s_apb.pruser = PRUSER_EN ? s_apb_pruser_reg : '0;
assign s_apb.pbuser = PBUSER_EN ? s_apb_pbuser_reg : '0;
assign m_axil_wr.awaddr = m_axil_addr_reg;
assign m_axil_wr.awprot = m_axil_prot_reg;
assign m_axil_wr.awuser = AWUSER_EN ? m_axil_auser_reg : '0;
assign m_axil_wr.awvalid = m_axil_awvalid_reg;
assign m_axil_wr.wdata = m_axil_wdata_reg;
assign m_axil_wr.wstrb = m_axil_wstrb_reg;
assign m_axil_wr.wuser = WUSER_EN ? m_axil_wuser_reg : '0;
assign m_axil_wr.wvalid = m_axil_wvalid_reg;
assign m_axil_wr.bready = m_axil_bready_reg;
assign m_axil_rd.araddr = m_axil_addr_reg;
assign m_axil_rd.arprot = m_axil_prot_reg;
assign m_axil_rd.aruser = ARUSER_EN ? m_axil_auser_reg : '0;
assign m_axil_rd.arvalid = m_axil_arvalid_reg;
assign m_axil_rd.rready = m_axil_rready_reg;
always_comb begin
state_next = STATE_IDLE;
s_apb_pready_next = 1'b0;
s_apb_prdata_next = s_apb_prdata_reg;
s_apb_pslverr_next = s_apb_pslverr_reg;
s_apb_pruser_next = s_apb_pruser_reg;
s_apb_pbuser_next = s_apb_pbuser_reg;
m_axil_addr_next = m_axil_addr_reg;
m_axil_prot_next = m_axil_prot_reg;
m_axil_auser_next = m_axil_auser_reg;
m_axil_awvalid_next = m_axil_awvalid_reg && !m_axil_wr.awready;
m_axil_wdata_next = m_axil_wdata_reg;
m_axil_wstrb_next = m_axil_wstrb_reg;
m_axil_wuser_next = m_axil_wuser_reg;
m_axil_wvalid_next = m_axil_wvalid_reg && !m_axil_wr.wready;
m_axil_bready_next = 1'b0;
m_axil_arvalid_next = m_axil_arvalid_reg && !m_axil_rd.arready;
m_axil_rready_next = 1'b0;
case (state_reg)
STATE_IDLE: begin
m_axil_addr_next = s_apb.paddr;
m_axil_prot_next = s_apb.pprot;
m_axil_wdata_next = {(AXIL_BYTE_LANES/APB_BYTE_LANES){s_apb.pwdata}};
m_axil_wstrb_next = '0;
m_axil_wstrb_next[s_apb.paddr[AXIL_ADDR_BIT_OFFSET - 1:APB_ADDR_BIT_OFFSET] * APB_STRB_W +: APB_STRB_W] = s_apb.pstrb;
m_axil_auser_next = s_apb.pauser;
m_axil_wuser_next = s_apb.pwuser;
if (s_apb.psel && s_apb.penable && !s_apb.pready) begin
if (s_apb.pwrite) begin
m_axil_awvalid_next = 1'b1;
m_axil_wvalid_next = 1'b1;
m_axil_bready_next = 1'b1;
end else begin
m_axil_arvalid_next = 1'b1;
m_axil_rready_next = 1'b1;
end
state_next = STATE_DATA;
end else begin
state_next = STATE_IDLE;
end
end
STATE_DATA: begin
if (s_apb.pwrite) begin
m_axil_bready_next = 1'b1;
end else begin
m_axil_rready_next = 1'b1;
end
s_apb_pready_next = 1'b0;
s_apb_prdata_next = m_axil_rd.rdata[m_axil_addr_reg[AXIL_ADDR_BIT_OFFSET - 1:APB_ADDR_BIT_OFFSET] * APB_DATA_W +: APB_DATA_W];
s_apb_pslverr_next = s_apb.pwrite ? m_axil_wr.bresp[1] : m_axil_rd.rresp[1];
s_apb_pruser_next = m_axil_rd.ruser;
s_apb_pbuser_next = m_axil_wr.buser;
if (s_apb.pwrite ? (m_axil_wr.bready && m_axil_wr.bvalid) : (m_axil_rd.rready && m_axil_rd.rvalid)) begin
m_axil_bready_next = 1'b0;
m_axil_rready_next = 1'b0;
s_apb_pready_next = 1'b1;
state_next = STATE_IDLE;
end else begin
state_next = STATE_DATA;
end
end
endcase
end
always_ff @(posedge clk) begin
state_reg <= state_next;
s_apb_pready_reg <= s_apb_pready_next;
s_apb_prdata_reg <= s_apb_prdata_next;
s_apb_pslverr_reg <= s_apb_pslverr_next;
s_apb_pruser_reg <= s_apb_pruser_next;
s_apb_pbuser_reg <= s_apb_pbuser_next;
m_axil_addr_reg <= m_axil_addr_next;
m_axil_prot_reg <= m_axil_prot_next;
m_axil_auser_reg <= m_axil_auser_next;
m_axil_awvalid_reg <= m_axil_awvalid_next;
m_axil_wdata_reg <= m_axil_wdata_next;
m_axil_wstrb_reg <= m_axil_wstrb_next;
m_axil_wuser_reg <= m_axil_wuser_next;
m_axil_wvalid_reg <= m_axil_wvalid_next;
m_axil_bready_reg <= m_axil_bready_next;
m_axil_arvalid_reg <= m_axil_arvalid_next;
m_axil_rready_reg <= m_axil_rready_next;
if (rst) begin
state_reg <= STATE_IDLE;
s_apb_pready_reg <= 1'b0;
m_axil_awvalid_reg <= 1'b0;
m_axil_wvalid_reg <= 1'b0;
m_axil_bready_reg <= 1'b0;
m_axil_arvalid_reg <= 1'b0;
m_axil_rready_reg <= 1'b0;
end
end
end else begin : downsize
// output is narrower; downsize
// output bus is wider
localparam DATA_W = APB_DATA_W;
localparam STRB_W = APB_STRB_W;
// required number of segments in wider bus
localparam SEG_COUNT = APB_BYTE_LANES / AXIL_BYTE_LANES;
localparam SEG_COUNT_W = $clog2(SEG_COUNT);
// data width and keep width per segment
localparam SEG_DATA_W = DATA_W / SEG_COUNT;
localparam SEG_STRB_W = STRB_W / SEG_COUNT;
localparam [0:0]
STATE_IDLE = 1'd0,
STATE_DATA = 1'd1;
logic [0:0] state_reg = STATE_IDLE, state_next;
logic [DATA_W-1:0] data_reg = '0, data_next;
logic [STRB_W-1:0] strb_reg = '0, strb_next;
logic [SEG_COUNT_W-1:0] current_seg_reg = '0, current_seg_next;
logic s_apb_pready_reg = 1'b0, s_apb_pready_next;
logic [APB_DATA_W-1:0] s_apb_prdata_reg = '0, s_apb_prdata_next;
logic s_apb_pslverr_reg = 1'b0, s_apb_pslverr_next;
logic [PRUSER_W-1:0] s_apb_pruser_reg = '0, s_apb_pruser_next;
logic [PBUSER_W-1:0] s_apb_pbuser_reg = '0, s_apb_pbuser_next;
logic [AXIL_ADDR_W-1:0] m_axil_addr_reg = '0, m_axil_addr_next;
logic [2:0] m_axil_prot_reg = 3'd0, m_axil_prot_next;
logic [AUSER_W-1:0] m_axil_auser_reg = '0, m_axil_auser_next;
logic m_axil_awvalid_reg = 1'b0, m_axil_awvalid_next;
logic [AXIL_DATA_W-1:0] m_axil_wdata_reg = '0, m_axil_wdata_next;
logic [AXIL_STRB_W-1:0] m_axil_wstrb_reg = '0, m_axil_wstrb_next;
logic [WUSER_W-1:0] m_axil_wuser_reg = '0, m_axil_wuser_next;
logic m_axil_wvalid_reg = 1'b0, m_axil_wvalid_next;
logic m_axil_bready_reg = 1'b0, m_axil_bready_next;
logic m_axil_arvalid_reg = 1'b0, m_axil_arvalid_next;
logic m_axil_rready_reg = 1'b0, m_axil_rready_next;
assign s_apb.pready = s_apb_pready_reg;
assign s_apb.prdata = s_apb_prdata_reg;
assign s_apb.pslverr = s_apb_pslverr_reg;
assign s_apb.pruser = PRUSER_EN ? s_apb_pruser_reg : '0;
assign s_apb.pbuser = PBUSER_EN ? s_apb_pbuser_reg : '0;
assign m_axil_wr.awaddr = m_axil_addr_reg;
assign m_axil_wr.awprot = m_axil_prot_reg;
assign m_axil_wr.awuser = AWUSER_EN ? m_axil_auser_reg : '0;
assign m_axil_wr.awvalid = m_axil_awvalid_reg;
assign m_axil_wr.wdata = m_axil_wdata_reg;
assign m_axil_wr.wstrb = m_axil_wstrb_reg;
assign m_axil_wr.wuser = WUSER_EN ? m_axil_wuser_reg : '0;
assign m_axil_wr.wvalid = m_axil_wvalid_reg;
assign m_axil_wr.bready = m_axil_bready_reg;
assign m_axil_rd.araddr = m_axil_addr_reg;
assign m_axil_rd.arprot = m_axil_prot_reg;
assign m_axil_rd.aruser = ARUSER_EN ? m_axil_auser_reg : '0;
assign m_axil_rd.arvalid = m_axil_arvalid_reg;
assign m_axil_rd.rready = m_axil_rready_reg;
always_comb begin
state_next = STATE_IDLE;
data_next = data_reg;
strb_next = strb_reg;
current_seg_next = current_seg_reg;
s_apb_pready_next = 1'b0;
s_apb_prdata_next = s_apb_prdata_reg;
s_apb_pslverr_next = s_apb_pslverr_reg;
s_apb_pruser_next = s_apb_pruser_reg;
s_apb_pbuser_next = s_apb_pbuser_reg;
m_axil_addr_next = m_axil_addr_reg;
m_axil_prot_next = m_axil_prot_reg;
m_axil_auser_next = m_axil_auser_reg;
m_axil_awvalid_next = m_axil_awvalid_reg && !m_axil_wr.awready;
m_axil_wdata_next = m_axil_wdata_reg;
m_axil_wstrb_next = m_axil_wstrb_reg;
m_axil_wuser_next = m_axil_wuser_reg;
m_axil_wvalid_next = m_axil_wvalid_reg && !m_axil_wr.wready;
m_axil_bready_next = 1'b0;
m_axil_arvalid_next = m_axil_arvalid_reg && !m_axil_rd.arready;
m_axil_rready_next = 1'b0;
case (state_reg)
STATE_IDLE: begin
current_seg_next = s_apb.paddr[AXIL_ADDR_BIT_OFFSET +: SEG_COUNT_W];
m_axil_addr_next = s_apb.paddr;
m_axil_prot_next = s_apb.pprot;
data_next = s_apb.pwdata;
strb_next = s_apb.pstrb;
m_axil_wdata_next = data_next[current_seg_next*SEG_DATA_W +: SEG_DATA_W];
m_axil_wstrb_next = strb_next[current_seg_next*SEG_STRB_W +: SEG_STRB_W];
m_axil_auser_next = s_apb.pauser;
m_axil_wuser_next = s_apb.pwuser;
s_apb_pslverr_next = 1'b0;
if (s_apb.psel && s_apb.penable && !s_apb.pready) begin
if (s_apb.pwrite) begin
m_axil_awvalid_next = 1'b1;
m_axil_wvalid_next = 1'b1;
m_axil_bready_next = 1'b1;
end else begin
m_axil_arvalid_next = 1'b1;
m_axil_rready_next = 1'b1;
end
state_next = STATE_DATA;
end else begin
state_next = STATE_IDLE;
end
end
STATE_DATA: begin
if (s_apb.pwrite) begin
m_axil_bready_next = 1'b1;
end else begin
m_axil_rready_next = 1'b1;
end
s_apb_pready_next = 1'b0;
s_apb_prdata_next[current_seg_reg*SEG_DATA_W +: SEG_DATA_W] = m_axil_rd.rdata;
if (s_apb.pwrite ? m_axil_wr.bresp[1] : m_axil_rd.rresp[1]) begin
s_apb_pslverr_next = 1'b1;
end
s_apb_pruser_next = m_axil_rd.ruser;
s_apb_pbuser_next = m_axil_wr.buser;
if (s_apb.pwrite ? (m_axil_wr.bready && m_axil_wr.bvalid) : (m_axil_rd.rready && m_axil_rd.rvalid)) begin
m_axil_bready_next = 1'b0;
m_axil_rready_next = 1'b0;
current_seg_next = current_seg_reg + 1;
m_axil_addr_next = (m_axil_addr_reg & AXIL_ADDR_MASK) + SEG_STRB_W;
m_axil_wdata_next = data_next[current_seg_next*SEG_DATA_W +: SEG_DATA_W];
m_axil_wstrb_next = strb_next[current_seg_next*SEG_STRB_W +: SEG_STRB_W];
if (current_seg_reg == SEG_COUNT_W'(SEG_COUNT-1)) begin
s_apb_pready_next = 1'b1;
state_next = STATE_IDLE;
end else begin
if (s_apb.pwrite) begin
m_axil_awvalid_next = 1'b1;
m_axil_wvalid_next = 1'b1;
m_axil_bready_next = 1'b1;
end else begin
m_axil_arvalid_next = 1'b1;
m_axil_rready_next = 1'b1;
end
state_next = STATE_DATA;
end
end else begin
state_next = STATE_DATA;
end
end
endcase
end
always_ff @(posedge clk) begin
state_reg <= state_next;
data_reg <= data_next;
strb_reg <= strb_next;
current_seg_reg <= current_seg_next;
s_apb_pready_reg <= s_apb_pready_next;
s_apb_prdata_reg <= s_apb_prdata_next;
s_apb_pslverr_reg <= s_apb_pslverr_next;
s_apb_pruser_reg <= s_apb_pruser_next;
s_apb_pbuser_reg <= s_apb_pbuser_next;
m_axil_addr_reg <= m_axil_addr_next;
m_axil_prot_reg <= m_axil_prot_next;
m_axil_auser_reg <= m_axil_auser_next;
m_axil_awvalid_reg <= m_axil_awvalid_next;
m_axil_wdata_reg <= m_axil_wdata_next;
m_axil_wstrb_reg <= m_axil_wstrb_next;
m_axil_wuser_reg <= m_axil_wuser_next;
m_axil_wvalid_reg <= m_axil_wvalid_next;
m_axil_bready_reg <= m_axil_bready_next;
m_axil_arvalid_reg <= m_axil_arvalid_next;
m_axil_rready_reg <= m_axil_rready_next;
if (rst) begin
state_reg <= STATE_IDLE;
s_apb_pready_reg <= 1'b0;
m_axil_awvalid_reg <= 1'b0;
m_axil_wvalid_reg <= 1'b0;
m_axil_bready_reg <= 1'b0;
m_axil_arvalid_reg <= 1'b0;
m_axil_rready_reg <= 1'b0;
end
end
end
endmodule
`resetall

View File

@@ -0,0 +1,64 @@
# SPDX-License-Identifier: CERN-OHL-S-2.0
#
# Copyright (c) 2020-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
TOPLEVEL_LANG = verilog
SIM ?= verilator
WAVES ?= 0
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
RTL_DIR = ../../rtl
LIB_DIR = ../../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
DUT = taxi_apb_axil_adapter
COCOTB_TEST_MODULES = test_$(DUT)
COCOTB_TOPLEVEL = test_$(DUT)
MODULE = $(COCOTB_TEST_MODULES)
TOPLEVEL = $(COCOTB_TOPLEVEL)
VERILOG_SOURCES += $(COCOTB_TOPLEVEL).sv
VERILOG_SOURCES += $(RTL_DIR)/$(DUT).sv
VERILOG_SOURCES += $(RTL_DIR)/taxi_apb_if.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/axi/rtl/taxi_axil_if.sv
# handle file list files
process_f_file = $(call process_f_files,$(addprefix $(dir $1),$(shell cat $1)))
process_f_files = $(foreach f,$1,$(if $(filter %.f,$f),$(call process_f_file,$f),$f))
uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $(lastword $1)),$(notdir $f)),$f,))) $(lastword $1))
VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
# module parameters
export PARAM_ADDR_W := 32
export PARAM_APB_DATA_W := 32
export PARAM_APB_STRB_W := $(shell expr $(PARAM_APB_DATA_W) / 8 )
export PARAM_AXIL_DATA_W := 32
export PARAM_AXIL_STRB_W := $(shell expr $(PARAM_AXIL_DATA_W) / 8 )
export PARAM_PAUSER_EN := 0
export PARAM_PAUSER_W := 1
export PARAM_PWUSER_EN := 0
export PARAM_PWUSER_W := 1
export PARAM_PBUSER_EN := 0
export PARAM_PBUSER_W := 1
export PARAM_PRUSER_EN := 0
export PARAM_PRUSER_W := 1
ifeq ($(SIM), icarus)
PLUSARGS += -fst
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-P $(COCOTB_TOPLEVEL).$(subst PARAM_,,$(v))=$($(v)))
else ifeq ($(SIM), verilator)
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-G$(subst PARAM_,,$(v))=$($(v)))
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
VERILATOR_TRACE = 1
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim

View File

@@ -0,0 +1,242 @@
#!/usr/bin/env python
# SPDX-License-Identifier: CERN-OHL-S-2.0
"""
Copyright (c) 2020-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
"""
import itertools
import logging
import os
import random
import cocotb_test.simulator
import pytest
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, Timer
from cocotb.regression import TestFactory
from cocotbext.axi import ApbBus, ApbMaster, AxiLiteBus, AxiLiteRam
class TB(object):
def __init__(self, dut):
self.dut = dut
self.log = logging.getLogger("cocotb.tb")
self.log.setLevel(logging.DEBUG)
cocotb.start_soon(Clock(dut.clk, 10, units="ns").start())
self.apb_master = ApbMaster(ApbBus.from_entity(dut.s_apb), dut.clk, dut.rst)
self.axil_ram = AxiLiteRam(AxiLiteBus.from_entity(dut.m_axil), dut.clk, dut.rst, size=2**16)
def set_idle_generator(self, generator=None):
if generator:
self.apb_master.set_pause_generator(generator())
self.axil_ram.write_if.b_channel.set_pause_generator(generator())
self.axil_ram.read_if.r_channel.set_pause_generator(generator())
def set_backpressure_generator(self, generator=None):
if generator:
self.axil_ram.write_if.aw_channel.set_pause_generator(generator())
self.axil_ram.write_if.w_channel.set_pause_generator(generator())
self.axil_ram.read_if.ar_channel.set_pause_generator(generator())
async def cycle_reset(self):
self.dut.rst.setimmediatevalue(0)
await RisingEdge(self.dut.clk)
await RisingEdge(self.dut.clk)
self.dut.rst.value = 1
await RisingEdge(self.dut.clk)
await RisingEdge(self.dut.clk)
self.dut.rst.value = 0
await RisingEdge(self.dut.clk)
await RisingEdge(self.dut.clk)
async def run_test_write(dut, data_in=None, idle_inserter=None, backpressure_inserter=None):
tb = TB(dut)
byte_lanes = tb.apb_master.byte_lanes
await tb.cycle_reset()
tb.set_idle_generator(idle_inserter)
tb.set_backpressure_generator(backpressure_inserter)
for length in range(1, byte_lanes*2):
for offset in range(byte_lanes):
tb.log.info("length %d, offset %d", length, offset)
addr = offset+0x1000
test_data = bytearray([x % 256 for x in range(length)])
tb.axil_ram.write(addr-128, b'\xaa'*(length+256))
await tb.apb_master.write(addr, test_data)
tb.log.debug("%s", tb.axil_ram.hexdump_str((addr & ~0xf)-16, (((addr & 0xf)+length-1) & ~0xf)+48))
assert tb.axil_ram.read(addr, length) == test_data
assert tb.axil_ram.read(addr-1, 1) == b'\xaa'
assert tb.axil_ram.read(addr+length, 1) == b'\xaa'
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
async def run_test_read(dut, data_in=None, idle_inserter=None, backpressure_inserter=None):
tb = TB(dut)
byte_lanes = tb.apb_master.byte_lanes
await tb.cycle_reset()
tb.set_idle_generator(idle_inserter)
tb.set_backpressure_generator(backpressure_inserter)
for length in range(1, byte_lanes*2):
for offset in range(byte_lanes):
tb.log.info("length %d, offset %d", length, offset)
addr = offset+0x1000
test_data = bytearray([x % 256 for x in range(length)])
tb.axil_ram.write(addr, test_data)
data = await tb.apb_master.read(addr, length)
assert data.data == test_data
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
async def run_stress_test(dut, idle_inserter=None, backpressure_inserter=None):
tb = TB(dut)
await tb.cycle_reset()
tb.set_idle_generator(idle_inserter)
tb.set_backpressure_generator(backpressure_inserter)
async def worker(master, offset, aperture, count=16):
for k in range(count):
length = random.randint(1, min(32, aperture))
addr = offset+random.randint(0, aperture-length)
test_data = bytearray([x % 256 for x in range(length)])
await Timer(random.randint(1, 100), 'ns')
await master.write(addr, test_data)
await Timer(random.randint(1, 100), 'ns')
data = await master.read(addr, length)
assert data.data == test_data
workers = []
for k in range(16):
workers.append(cocotb.start_soon(worker(tb.apb_master, k*0x1000, 0x1000, count=16)))
while workers:
await workers.pop(0).join()
await RisingEdge(dut.clk)
await RisingEdge(dut.clk)
def cycle_pause():
return itertools.cycle([1, 1, 1, 0])
if getattr(cocotb, 'top', None) is not None:
for test in [run_test_write, run_test_read]:
factory = TestFactory(test)
factory.add_option("idle_inserter", [None, cycle_pause])
factory.add_option("backpressure_inserter", [None, cycle_pause])
factory.generate_tests()
factory = TestFactory(run_stress_test)
factory.generate_tests()
# cocotb-test
tests_dir = os.path.abspath(os.path.dirname(__file__))
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
lib_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'lib'))
taxi_src_dir = os.path.abspath(os.path.join(lib_dir, 'taxi', 'src'))
def process_f_files(files):
lst = {}
for f in files:
if f[-2:].lower() == '.f':
with open(f, 'r') as fp:
l = fp.read().split()
for f in process_f_files([os.path.join(os.path.dirname(f), x) for x in l]):
lst[os.path.basename(f)] = f
else:
lst[os.path.basename(f)] = f
return list(lst.values())
@pytest.mark.parametrize("axil_data_w", [8, 16, 32])
@pytest.mark.parametrize("apb_data_w", [8, 16, 32])
def test_taxi_apb_axil_adapter(request, apb_data_w, axil_data_w):
dut = "taxi_apb_axil_adapter"
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = module
verilog_sources = [
os.path.join(tests_dir, f"{toplevel}.sv"),
os.path.join(rtl_dir, f"{dut}.sv"),
os.path.join(rtl_dir, "taxi_apb_if.sv"),
os.path.join(taxi_src_dir, "axi", "rtl", "taxi_axil_if.sv"),
]
verilog_sources = process_f_files(verilog_sources)
parameters = {}
parameters['ADDR_W'] = 32
parameters['APB_DATA_W'] = apb_data_w
parameters['APB_STRB_W'] = parameters['APB_DATA_W'] // 8
parameters['AXIL_DATA_W'] = axil_data_w
parameters['AXIL_STRB_W'] = parameters['AXIL_DATA_W'] // 8
parameters["PAUSER_EN"] = 0
parameters["PAUSER_W"] = 1
parameters["PWUSER_EN"] = 0
parameters["PWUSER_W"] = 1
parameters["PRUSER_EN"] = 0
parameters["PRUSER_W"] = 1
parameters["PBUSER_EN"] = 0
parameters["PBUSER_W"] = 1
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
simulator="verilator",
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
)

View File

@@ -0,0 +1,90 @@
// SPDX-License-Identifier: CERN-OHL-S-2.0
/*
Copyright (c) 2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* APB to AXI4 lite adapter testbench
*/
module test_taxi_apb_axil_adapter #
(
/* verilator lint_off WIDTHTRUNC */
parameter ADDR_W = 32,
parameter APB_DATA_W = 32,
parameter APB_STRB_W = (APB_DATA_W/8),
parameter AXIL_DATA_W = 32,
parameter AXIL_STRB_W = (AXIL_DATA_W/8),
parameter logic PAUSER_EN = 1'b0,
parameter PAUSER_W = 1,
parameter logic PWUSER_EN = 1'b0,
parameter PWUSER_W = 1,
parameter logic PRUSER_EN = 1'b0,
parameter PRUSER_W = 1,
parameter logic PBUSER_EN = 1'b0,
parameter PBUSER_W = 1
/* verilator lint_on WIDTHTRUNC */
)
();
logic clk;
logic rst;
taxi_apb_if #(
.DATA_W(APB_DATA_W),
.ADDR_W(ADDR_W),
.STRB_W(APB_STRB_W),
.PAUSER_EN(PAUSER_EN),
.PAUSER_W(PAUSER_W),
.PWUSER_EN(PWUSER_EN),
.PWUSER_W(PWUSER_W),
.PRUSER_EN(PRUSER_EN),
.PRUSER_W(PRUSER_W),
.PBUSER_EN(PBUSER_EN),
.PBUSER_W(PBUSER_W)
) s_apb();
taxi_axil_if #(
.DATA_W(AXIL_DATA_W),
.ADDR_W(ADDR_W),
.STRB_W(AXIL_STRB_W),
.AWUSER_EN(PAUSER_EN),
.AWUSER_W(PAUSER_W),
.WUSER_EN(PWUSER_EN),
.WUSER_W(PWUSER_W),
.BUSER_EN(PBUSER_EN),
.BUSER_W(PBUSER_W),
.ARUSER_EN(PAUSER_EN),
.ARUSER_W(PAUSER_W),
.RUSER_EN(PRUSER_EN),
.RUSER_W(PRUSER_W)
) m_axil();
taxi_apb_axil_adapter
uut (
.clk(clk),
.rst(rst),
/*
* APB slave interface
*/
.s_apb(s_apb),
/*
* AXI4-Lite master interface
*/
.m_axil_wr(m_axil),
.m_axil_rd(m_axil)
);
endmodule
`resetall

View File

@@ -0,0 +1,32 @@
# Corundum for ADM-PCIE-9V3
## Introduction
This design targets the Alpha Data ADM-PCIE-9V3 FPGA board.
* QSFP28
* 10GBASE-R or 25GBASE-R MACs via GTY transceivers
## Board details
* FPGA: xcvu3p-ffvc1517-2-i
* PCIe: gen 3 x16 (~128 Gbps)
* Reference oscillator: 161.1328125 MHz from Si5338
* 25GBASE-R PHY: Soft PCS with GTY transceivers
## Licensing
* Toolchain
* Vivado Enterprise (requires license)
* IP
* No licensed vendor IP or 3rd party IP
## How to build
Run `make` in the appropriate `fpga*` subdirectory to build the bitstream. Ensure that the Xilinx Vivado toolchain components are in PATH.
On the host system, run `make` in `modules/cndm` to build the driver. Ensure that the headers for the running kernel are installed, otherwise the driver cannot be compiled.
## How to test
Run `make program` to program the board with Vivado. Then, reboot the machine to re-enumerate the PCIe bus. Finally, load the driver on the host system with `insmod cndm.ko`. Check `dmesg` for output from driver initialization. Run `cndm_ddcmd.sh =p` to enable all debug messages.

View File

@@ -0,0 +1,153 @@
# SPDX-License-Identifier: MIT
###################################################################
#
# Xilinx Vivado FPGA Makefile
#
# Copyright (c) 2016-2025 Alex Forencich
#
###################################################################
#
# Parameters:
# FPGA_TOP - Top module name
# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale)
# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e)
# SYN_FILES - list of source files
# INC_FILES - list of include files
# XDC_FILES - list of timing constraint files
# XCI_FILES - list of IP XCI files
# IP_TCL_FILES - list of IP TCL files (sourced during project creation)
# CONFIG_TCL_FILES - list of config TCL files (sourced before each build)
#
# Note: both SYN_FILES and INC_FILES support file list files. File list
# files are files with a .f extension that contain a list of additional
# files to include, one path relative to the .f file location per line.
# The .f files are processed recursively, and then the complete file list
# is de-duplicated, with later files in the list taking precedence.
#
# Example:
#
# FPGA_TOP = fpga
# FPGA_FAMILY = VirtexUltrascale
# FPGA_DEVICE = xcvu095-ffva2104-2-e
# SYN_FILES = rtl/fpga.v
# XDC_FILES = fpga.xdc
# XCI_FILES = ip/pcspma.xci
# include ../common/vivado.mk
#
###################################################################
# phony targets
.PHONY: fpga vivado tmpclean clean distclean
# prevent make from deleting intermediate files and reports
.PRECIOUS: %.xpr %.bit %.bin %.ltx %.xsa %.mcs %.prm
.SECONDARY:
CONFIG ?= config.mk
-include $(CONFIG)
FPGA_TOP ?= fpga
PROJECT ?= $(FPGA_TOP)
XDC_FILES ?= $(PROJECT).xdc
# handle file list files
process_f_file = $(call process_f_files,$(addprefix $(dir $1),$(shell cat $1)))
process_f_files = $(foreach f,$1,$(if $(filter %.f,$f),$(call process_f_file,$f),$f))
uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $(lastword $1)),$(notdir $f)),$f,))) $(lastword $1))
SYN_FILES := $(call uniq_base,$(call process_f_files,$(SYN_FILES)))
INC_FILES := $(call uniq_base,$(call process_f_files,$(INC_FILES)))
###################################################################
# Main Targets
#
# all: build everything (fpga)
# fpga: build FPGA config
# vivado: open project in Vivado
# tmpclean: remove intermediate files
# clean: remove output files and project files
# distclean: remove archived output files
###################################################################
all: fpga
fpga: $(PROJECT).bit
vivado: $(PROJECT).xpr
vivado $(PROJECT).xpr
tmpclean::
-rm -rf *.log *.jou *.cache *.gen *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v
-rm -rf create_project.tcl update_config.tcl run_synth.tcl run_impl.tcl generate_bit.tcl
clean:: tmpclean
-rm -rf *.bit *.bin *.ltx *.xsa program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl
-rm -rf *_utilization.rpt *_utilization_hierarchical.rpt
distclean:: clean
-rm -rf rev
###################################################################
# Target implementations
###################################################################
# Vivado project file
# create fresh project if Makefile or IP files have changed
create_project.tcl: Makefile $(XCI_FILES) $(IP_TCL_FILES)
rm -rf defines.v
touch defines.v
for x in $(DEFS); do echo '`define' $$x >> defines.v; done
echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@
echo "add_files -fileset sources_1 defines.v $(SYN_FILES)" >> $@
echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@
echo "add_files -fileset constrs_1 $(XDC_FILES)" >> $@
for x in $(XCI_FILES); do echo "import_ip $$x" >> $@; done
for x in $(IP_TCL_FILES); do echo "source $$x" >> $@; done
for x in $(CONFIG_TCL_FILES); do echo "source $$x" >> $@; done
# source config TCL scripts if any source file has changed
update_config.tcl: $(CONFIG_TCL_FILES) $(SYN_FILES) $(INC_FILES) $(XDC_FILES)
echo "open_project -quiet $(PROJECT).xpr" > $@
for x in $(CONFIG_TCL_FILES); do echo "source $$x" >> $@; done
$(PROJECT).xpr: create_project.tcl update_config.tcl
vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x)
# synthesis run
$(PROJECT).runs/synth_1/$(PROJECT).dcp: create_project.tcl update_config.tcl $(SYN_FILES) $(INC_FILES) $(XDC_FILES) | $(PROJECT).xpr
echo "open_project $(PROJECT).xpr" > run_synth.tcl
echo "reset_run synth_1" >> run_synth.tcl
echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl
echo "wait_on_run synth_1" >> run_synth.tcl
vivado -nojournal -nolog -mode batch -source run_synth.tcl
# implementation run
$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp
echo "open_project $(PROJECT).xpr" > run_impl.tcl
echo "reset_run impl_1" >> run_impl.tcl
echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl
echo "wait_on_run impl_1" >> run_impl.tcl
echo "open_run impl_1" >> run_impl.tcl
echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl
echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl
vivado -nojournal -nolog -mode batch -source run_impl.tcl
# output files (including potentially bit, bin, ltx, and xsa)
$(PROJECT).bit $(PROJECT).bin $(PROJECT).ltx $(PROJECT).xsa: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp
echo "open_project $(PROJECT).xpr" > generate_bit.tcl
echo "open_run impl_1" >> generate_bit.tcl
echo "write_bitstream -force -bin_file $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl
echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl
echo "write_hw_platform -fixed -force -include_bit $(PROJECT).xsa" >> generate_bit.tcl
vivado -nojournal -nolog -mode batch -source generate_bit.tcl
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit .
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bin .
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi
mkdir -p rev
COUNT=100; \
while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bin rev/$(PROJECT)_rev$$COUNT.bin; \
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi; \
if [ -e $(PROJECT).xsa ]; then cp -pv $(PROJECT).xsa rev/$(PROJECT)_rev$$COUNT.xsa; fi

View File

@@ -0,0 +1,490 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2014-2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# XDC constraints for the ADM-PCIE-9V3
# part: xcvu3p-ffvc1517-2-i
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN {DIV-1} [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 8 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN {Pullnone} [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
# 300 MHz system clock
set_property -dict {LOC AP26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_p]
set_property -dict {LOC AP27 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports clk_300mhz_n]
create_clock -period 3.333 -name clk_300mhz [get_ports clk_300mhz_p]
# LEDs
set_property -dict {LOC AT27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[0]}]
set_property -dict {LOC AU27 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_g[1]}]
set_property -dict {LOC AU23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {user_led_r}]
set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[0]}]
set_property -dict {LOC AJ23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {front_led[1]}]
set_false_path -to [get_ports {user_led_g[*] user_led_r front_led[*]}]
set_output_delay 0 [get_ports {user_led_g[*] user_led_r front_led[*]}]
# Switches
set_property -dict {LOC AV27 IOSTANDARD LVCMOS18} [get_ports {user_sw[0]}]
set_property -dict {LOC AW27 IOSTANDARD LVCMOS18} [get_ports {user_sw[1]}]
set_false_path -from [get_ports {user_sw[*]}]
set_input_delay 0 [get_ports {user_sw[*]}]
# GPIO
#set_property -dict {LOC G30 IOSTANDARD LVCMOS18} [get_ports gpio_p[0]]
#set_property -dict {LOC F30 IOSTANDARD LVCMOS18} [get_ports gpio_n[0]]
#set_property -dict {LOC J31 IOSTANDARD LVCMOS18} [get_ports gpio_p[1]]
#set_property -dict {LOC H31 IOSTANDARD LVCMOS18} [get_ports gpio_n[1]]
# QSFP28 Interfaces
set_property -dict {LOC G38 } [get_ports {qsfp_0_rx_p[0]}] ;# MGTYRXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC G39 } [get_ports {qsfp_0_rx_n[0]}] ;# MGTYRXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC F35 } [get_ports {qsfp_0_tx_p[0]}] ;# MGTYTXP0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC F36 } [get_ports {qsfp_0_tx_n[0]}] ;# MGTYTXN0_128 GTYE4_CHANNEL_X0Y16 / GTYE4_COMMON_X0Y4
set_property -dict {LOC E38 } [get_ports {qsfp_0_rx_p[1]}] ;# MGTYRXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC E39 } [get_ports {qsfp_0_rx_n[1]}] ;# MGTYRXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC D35 } [get_ports {qsfp_0_tx_p[1]}] ;# MGTYTXP1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC D36 } [get_ports {qsfp_0_tx_n[1]}] ;# MGTYTXN1_128 GTYE4_CHANNEL_X0Y17 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C38 } [get_ports {qsfp_0_rx_p[2]}] ;# MGTYRXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C39 } [get_ports {qsfp_0_rx_n[2]}] ;# MGTYRXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C33 } [get_ports {qsfp_0_tx_p[2]}] ;# MGTYTXP2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC C34 } [get_ports {qsfp_0_tx_n[2]}] ;# MGTYTXN2_128 GTYE4_CHANNEL_X0Y18 / GTYE4_COMMON_X0Y4
set_property -dict {LOC B36 } [get_ports {qsfp_0_rx_p[3]}] ;# MGTYRXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC B37 } [get_ports {qsfp_0_rx_n[3]}] ;# MGTYRXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC A33 } [get_ports {qsfp_0_tx_p[3]}] ;# MGTYTXP3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC A34 } [get_ports {qsfp_0_tx_n[3]}] ;# MGTYTXN3_128 GTYE4_CHANNEL_X0Y19 / GTYE4_COMMON_X0Y4
set_property -dict {LOC N33 } [get_ports qsfp_0_mgt_refclk_p] ;# MGTREFCLK0P_128 from ?
set_property -dict {LOC N34 } [get_ports qsfp_0_mgt_refclk_n] ;# MGTREFCLK0N_128 from ?
set_property -dict {LOC F29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_0_modprs_l]
set_property -dict {LOC D31 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_0_sel_l]
# 161.1328125 MHz MGT reference clock
create_clock -period 6.206 -name qsfp_0_mgt_refclk [get_ports qsfp_0_mgt_refclk_p]
set_property -dict {LOC R38 } [get_ports {qsfp_1_rx_p[0]}] ;# MGTYRXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC R39 } [get_ports {qsfp_1_rx_n[0]}] ;# MGTYRXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC P35 } [get_ports {qsfp_1_tx_p[0]}] ;# MGTYTXP0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC P36 } [get_ports {qsfp_1_tx_n[0]}] ;# MGTYTXN0_127 GTYE4_CHANNEL_X0Y12 / GTYE4_COMMON_X0Y3
set_property -dict {LOC N38 } [get_ports {qsfp_1_rx_p[1]}] ;# MGTYRXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC N39 } [get_ports {qsfp_1_rx_n[1]}] ;# MGTYRXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC M35 } [get_ports {qsfp_1_tx_p[1]}] ;# MGTYTXP1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC M36 } [get_ports {qsfp_1_tx_n[1]}] ;# MGTYTXN1_127 GTYE4_CHANNEL_X0Y13 / GTYE4_COMMON_X0Y3
set_property -dict {LOC L38 } [get_ports {qsfp_1_rx_p[2]}] ;# MGTYRXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC L39 } [get_ports {qsfp_1_rx_n[2]}] ;# MGTYRXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC K35 } [get_ports {qsfp_1_tx_p[2]}] ;# MGTYTXP2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC K36 } [get_ports {qsfp_1_tx_n[2]}] ;# MGTYTXN2_127 GTYE4_CHANNEL_X0Y14 / GTYE4_COMMON_X0Y3
set_property -dict {LOC J38 } [get_ports {qsfp_1_rx_p[3]}] ;# MGTYRXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC J39 } [get_ports {qsfp_1_rx_n[3]}] ;# MGTYRXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC H35 } [get_ports {qsfp_1_tx_p[3]}] ;# MGTYTXP3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
set_property -dict {LOC H36 } [get_ports {qsfp_1_tx_n[3]}] ;# MGTYTXN3_127 GTYE4_CHANNEL_X0Y15 / GTYE4_COMMON_X0Y3
#set_property -dict {LOC U33 } [get_ports qsfp_1_mgt_refclk_p] ;# MGTREFCLK0P_127 from ?
#set_property -dict {LOC U34 } [get_ports qsfp_1_mgt_refclk_n] ;# MGTREFCLK0N_127 from ?
set_property -dict {LOC F33 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_1_modprs_l]
set_property -dict {LOC D30 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_1_sel_l]
# 161.1328125 MHz MGT reference clock
#create_clock -period 6.206 -name qsfp_1_mgt_refclk [get_ports qsfp_1_mgt_refclk_p]
set_property -dict {LOC B29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports qsfp_reset_l]
set_property -dict {LOC C29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports qsfp_int_l]
#set_property -dict {LOC A28 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_scl]
#set_property -dict {LOC A29 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports qsfp_i2c_sda]
set_false_path -to [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
set_output_delay 0 [get_ports {qsfp_0_sel_l qsfp_1_sel_l qsfp_reset_l}]
set_false_path -from [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
set_input_delay 0 [get_ports {qsfp_0_modprs_l qsfp_1_modprs_l qsfp_int_l}]
#set_false_path -to [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_output_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_false_path -from [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
#set_input_delay 0 [get_ports {qsfp_i2c_sda qsfp_i2c_scl}]
# I2C interface
#set_property -dict {LOC AT25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_scl]
#set_property -dict {LOC AT26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_i2c_sda]
#set_property -dict {LOC AP23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12 PULLUP true} [get_ports eeprom_wp]
#set_false_path -to [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#set_output_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl eeprom_wp}]
#set_false_path -from [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
#set_input_delay 0 [get_ports {eeprom_i2c_sda eeprom_i2c_scl}]
# PCIe Interface
set_property -dict {LOC J2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC J1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC H5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC H4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC L2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC L1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC K5 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC K4 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC N2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC N1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC M5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC M4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC R2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC R1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC P5 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC P4 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC U2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC U1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC T5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC T4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC W2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC W1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC V5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC V4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AA2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AA1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AC2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AC1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AE2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AE1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AK5 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AK4 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AM5 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AM4 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AP5 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AP4 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AW7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AW6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AA7 } [get_ports pcie_refclk_1_p] ;# MGTREFCLK0P_226
set_property -dict {LOC AA6 } [get_ports pcie_refclk_1_n] ;# MGTREFCLK0N_226
#set_property -dict {LOC AJ7 } [get_ports pcie_refclk_2_p] ;# MGTREFCLK0P_224
#set_property -dict {LOC AJ6 } [get_ports pcie_refclk_2_n] ;# MGTREFCLK0N_224
set_property -dict {LOC AJ31 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n]
#set_property -dict {LOC AH29 IOSTANDARD LVCMOS18 PULLUP true} [get_ports pcie_reset_n]
# 100 MHz MGT reference clock
create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports pcie_refclk_1_p]
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports pcie_refclk_2_p]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]
# DDR4 C0
# 5x K4A8G085WB-RC
#set_property -dict {LOC F9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[0]}]
#set_property -dict {LOC G9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[1]}]
#set_property -dict {LOC G11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[2]}]
#set_property -dict {LOC D11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[3]}]
#set_property -dict {LOC E12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[4]}]
#set_property -dict {LOC G10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[5]}]
#set_property -dict {LOC F10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[6]}]
#set_property -dict {LOC J9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[7]}]
#set_property -dict {LOC J8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[8]}]
#set_property -dict {LOC F12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[9]}]
#set_property -dict {LOC D9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[10]}]
#set_property -dict {LOC H11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[11]}]
#set_property -dict {LOC E8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[12]}]
#set_property -dict {LOC J11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[13]}]
#set_property -dict {LOC C9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[14]}]
#set_property -dict {LOC B11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[15]}]
#set_property -dict {LOC K12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[16]}]
#set_property -dict {LOC H9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[17]}]
#set_property -dict {LOC F8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_ba[0]}]
#set_property -dict {LOC H8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_ba[1]}]
#set_property -dict {LOC D10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_bg[0]}]
#set_property -dict {LOC E11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_bg[1]}]
#set_property -dict {LOC B10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_c[0]}]
#set_property -dict {LOC C11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_c[1]}]
#set_property -dict {LOC A9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_c[2]}]
#set_property -dict {LOC H12 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c0_ck_t}]
#set_property -dict {LOC G12 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c0_ck_c}]
#set_property -dict {LOC B9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cke}]
#set_property -dict {LOC E10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cs_n}]
#set_property -dict {LOC C12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_act_n}]
#set_property -dict {LOC A10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_odt}]
#set_property -dict {LOC G7 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_par}]
#set_property -dict {LOC F7 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c0_reset_n}]
#set_property -dict {LOC H7 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c0_alert_n}]
#set_property -dict {LOC J10 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c0_ten}]
#set_property -dict {LOC L10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[0]}]
#set_property -dict {LOC L9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[1]}]
#set_property -dict {LOC N9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[2]}]
#set_property -dict {LOC M9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[3]}]
#set_property -dict {LOC M10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[4]}]
#set_property -dict {LOC K11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[5]}]
#set_property -dict {LOC M11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[6]}]
#set_property -dict {LOC K10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[7]}]
#set_property -dict {LOC L17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[8]}]
#set_property -dict {LOC M16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[9]}]
#set_property -dict {LOC M15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[10]}]
#set_property -dict {LOC M17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[11]}]
#set_property -dict {LOC M14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[12]}]
#set_property -dict {LOC N18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[13]}]
#set_property -dict {LOC N16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[14]}]
#set_property -dict {LOC N17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[15]}]
#set_property -dict {LOC F15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[16]}]
#set_property -dict {LOC E16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[17]}]
#set_property -dict {LOC F14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[18]}]
#set_property -dict {LOC E17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[19]}]
#set_property -dict {LOC G16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[20]}]
#set_property -dict {LOC F17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[21]}]
#set_property -dict {LOC E15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[22]}]
#set_property -dict {LOC G17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[23]}]
#set_property -dict {LOC A17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[24]}]
#set_property -dict {LOC C16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[25]}]
#set_property -dict {LOC B16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[26]}]
#set_property -dict {LOC A14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[27]}]
#set_property -dict {LOC B17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[28]}]
#set_property -dict {LOC B14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[29]}]
#set_property -dict {LOC D16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[30]}]
#set_property -dict {LOC D15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[31]}]
#set_property -dict {LOC F18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[32]}]
#set_property -dict {LOC F20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[33]}]
#set_property -dict {LOC F19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[34]}]
#set_property -dict {LOC D21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[35]}]
#set_property -dict {LOC E18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[36]}]
#set_property -dict {LOC G19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[37]}]
#set_property -dict {LOC E21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[38]}]
#set_property -dict {LOC G20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[39]}]
#set_property -dict {LOC D18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[40]}]
#set_property -dict {LOC B22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[41]}]
#set_property -dict {LOC A19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[42]}]
#set_property -dict {LOC A18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[43]}]
#set_property -dict {LOC C19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[44]}]
#set_property -dict {LOC B19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[45]}]
#set_property -dict {LOC A22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[46]}]
#set_property -dict {LOC C18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[47]}]
#set_property -dict {LOC G22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[48]}]
#set_property -dict {LOC J20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[49]}]
#set_property -dict {LOC H19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[50]}]
#set_property -dict {LOC J19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[51]}]
#set_property -dict {LOC H18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[52]}]
#set_property -dict {LOC J18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[53]}]
#set_property -dict {LOC G21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[54]}]
#set_property -dict {LOC K18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[55]}]
#set_property -dict {LOC L20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[56]}]
#set_property -dict {LOC L18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[57]}]
#set_property -dict {LOC N19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[58]}]
#set_property -dict {LOC M21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[59]}]
#set_property -dict {LOC M19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[60]}]
#set_property -dict {LOC M22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[61]}]
#set_property -dict {LOC L19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[62]}]
#set_property -dict {LOC M20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[63]}]
#set_property -dict {LOC H16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[64]}]
#set_property -dict {LOC K15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[65]}]
#set_property -dict {LOC J16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[66]}]
#set_property -dict {LOC J14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[67]}]
#set_property -dict {LOC K13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[68]}]
#set_property -dict {LOC L13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[69]}]
#set_property -dict {LOC H14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[70]}]
#set_property -dict {LOC J15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[71]}]
#set_property -dict {LOC M12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[0]}]
#set_property -dict {LOC L12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[0]}]
#set_property -dict {LOC L15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[1]}]
#set_property -dict {LOC L14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[1]}]
#set_property -dict {LOC F13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[2]}]
#set_property -dict {LOC E13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[2]}]
#set_property -dict {LOC B15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[3]}]
#set_property -dict {LOC A15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[3]}]
#set_property -dict {LOC F22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[4]}]
#set_property -dict {LOC E22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[4]}]
#set_property -dict {LOC C21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[5]}]
#set_property -dict {LOC B21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[5]}]
#set_property -dict {LOC K21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[6]}]
#set_property -dict {LOC K20 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[6]}]
#set_property -dict {LOC L22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[7]}]
#set_property -dict {LOC K22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[7]}]
#set_property -dict {LOC K17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[8]}]
#set_property -dict {LOC K16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[8]}]
#set_property -dict {LOC N12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[0]}]
#set_property -dict {LOC P14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[1]}]
#set_property -dict {LOC G15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[2]}]
#set_property -dict {LOC D14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[3]}]
#set_property -dict {LOC E20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[4]}]
#set_property -dict {LOC B20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[5]}]
#set_property -dict {LOC H22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[6]}]
#set_property -dict {LOC N22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[7]}]
#set_property -dict {LOC J13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dm_dbi_n[8]}]
# DDR4 C1
# 5x K4A8G085WB-RC
#set_property -dict {LOC AN9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[0]}]
#set_property -dict {LOC AM9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[1]}]
#set_property -dict {LOC AP11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[2]}]
#set_property -dict {LOC AU9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[3]}]
#set_property -dict {LOC AT10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[4]}]
#set_property -dict {LOC AL12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[5]}]
#set_property -dict {LOC AM12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[6]}]
#set_property -dict {LOC AM10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[7]}]
#set_property -dict {LOC AL11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[8]}]
#set_property -dict {LOC AP7 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[9]}]
#set_property -dict {LOC AR8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[10]}]
#set_property -dict {LOC AL10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[11]}]
#set_property -dict {LOC AP8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[12]}]
#set_property -dict {LOC AK11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[13]}]
#set_property -dict {LOC AP9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[14]}]
#set_property -dict {LOC AV10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[15]}]
#set_property -dict {LOC AT11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[16]}]
#set_property -dict {LOC AL8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[17]}]
#set_property -dict {LOC AN11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_ba[0]}]
#set_property -dict {LOC AR9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_ba[1]}]
#set_property -dict {LOC AP12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_bg[0]}]
#set_property -dict {LOC AN10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_bg[1]}]
#set_property -dict {LOC AW13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_c[0]}]
#set_property -dict {LOC AU10 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_c[1]}]
#set_property -dict {LOC AW11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_c[2]}]
#set_property -dict {LOC AM7 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c1_ck_t}]
#set_property -dict {LOC AN7 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c1_ck_c}]
#set_property -dict {LOC AU12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cke}]
#set_property -dict {LOC AT12 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cs_n}]
#set_property -dict {LOC AV9 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_act_n}]
#set_property -dict {LOC AR11 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_odt}]
#set_property -dict {LOC AM8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_par}]
#set_property -dict {LOC AN12 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c1_reset_n}]
#set_property -dict {LOC AR10 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c1_alert_n}]
#set_property -dict {LOC AV11 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c1_ten}]
#set_property -dict {LOC AK9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[0]}]
#set_property -dict {LOC AK10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[1]}]
#set_property -dict {LOC AH10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[2]}]
#set_property -dict {LOC AJ11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[3]}]
#set_property -dict {LOC AJ9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[4]}]
#set_property -dict {LOC AH12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[5]}]
#set_property -dict {LOC AG10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[6]}]
#set_property -dict {LOC AJ12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[7]}]
#set_property -dict {LOC AM15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[8]}]
#set_property -dict {LOC AN14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[9]}]
#set_property -dict {LOC AL13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[10]}]
#set_property -dict {LOC AM14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[11]}]
#set_property -dict {LOC AL15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[12]}]
#set_property -dict {LOC AM17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[13]}]
#set_property -dict {LOC AL17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[14]}]
#set_property -dict {LOC AM13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[15]}]
#set_property -dict {LOC AR15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[16]}]
#set_property -dict {LOC AP14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[17]}]
#set_property -dict {LOC AT15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[18]}]
#set_property -dict {LOC AR14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[19]}]
#set_property -dict {LOC AP17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[20]}]
#set_property -dict {LOC AN16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[21]}]
#set_property -dict {LOC AN17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[22]}]
#set_property -dict {LOC AN15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[23]}]
#set_property -dict {LOC AU15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[24]}]
#set_property -dict {LOC AT17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[25]}]
#set_property -dict {LOC AV15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[26]}]
#set_property -dict {LOC AT16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[27]}]
#set_property -dict {LOC AV14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[28]}]
#set_property -dict {LOC AW17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[29]}]
#set_property -dict {LOC AW14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[30]}]
#set_property -dict {LOC AW18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[31]}]
#set_property -dict {LOC AP19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[32]}]
#set_property -dict {LOC AT20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[33]}]
#set_property -dict {LOC AN21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[34]}]
#set_property -dict {LOC AR19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[35]}]
#set_property -dict {LOC AN20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[36]}]
#set_property -dict {LOC AR18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[37]}]
#set_property -dict {LOC AR20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[38]}]
#set_property -dict {LOC AP18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[39]}]
#set_property -dict {LOC AW19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[40]}]
#set_property -dict {LOC AU22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[41]}]
#set_property -dict {LOC AV19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[42]}]
#set_property -dict {LOC AW22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[43]}]
#set_property -dict {LOC AU18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[44]}]
#set_property -dict {LOC AT22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[45]}]
#set_property -dict {LOC AW21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[46]}]
#set_property -dict {LOC AU19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[47]}]
#set_property -dict {LOC AH19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[48]}]
#set_property -dict {LOC AJ22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[49]}]
#set_property -dict {LOC AF21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[50]}]
#set_property -dict {LOC AH22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[51]}]
#set_property -dict {LOC AF20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[52]}]
#set_property -dict {LOC AJ19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[53]}]
#set_property -dict {LOC AH21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[54]}]
#set_property -dict {LOC AJ21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[55]}]
#set_property -dict {LOC AM19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[56]}]
#set_property -dict {LOC AK20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[57]}]
#set_property -dict {LOC AM22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[58]}]
#set_property -dict {LOC AL22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[59]}]
#set_property -dict {LOC AM20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[60]}]
#set_property -dict {LOC AK19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[61]}]
#set_property -dict {LOC AN19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[62]}]
#set_property -dict {LOC AL20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[63]}]
#set_property -dict {LOC AF15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[64]}]
#set_property -dict {LOC AJ17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[65]}]
#set_property -dict {LOC AH17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[66]}]
#set_property -dict {LOC AJ14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[67]}]
#set_property -dict {LOC AG15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[68]}]
#set_property -dict {LOC AJ13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[69]}]
#set_property -dict {LOC AG17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[70]}]
#set_property -dict {LOC AJ16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[71]}]
#set_property -dict {LOC AG9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[0]}]
#set_property -dict {LOC AH9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[0]}]
#set_property -dict {LOC AK16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[1]}]
#set_property -dict {LOC AL16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[1]}]
#set_property -dict {LOC AR13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[2]}]
#set_property -dict {LOC AT13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[2]}]
#set_property -dict {LOC AU17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[3]}]
#set_property -dict {LOC AV17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[3]}]
#set_property -dict {LOC AN22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[4]}]
#set_property -dict {LOC AP22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[4]}]
#set_property -dict {LOC AV22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[5]}]
#set_property -dict {LOC AV21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[5]}]
#set_property -dict {LOC AG20 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[6]}]
#set_property -dict {LOC AH20 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[6]}]
#set_property -dict {LOC AK21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[7]}]
#set_property -dict {LOC AL21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[7]}]
#set_property -dict {LOC AH16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[8]}]
#set_property -dict {LOC AH15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[8]}]
#set_property -dict {LOC AG12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[0]}]
#set_property -dict {LOC AK15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[1]}]
#set_property -dict {LOC AP16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[2]}]
#set_property -dict {LOC AV16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[3]}]
#set_property -dict {LOC AP21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[4]}]
#set_property -dict {LOC AU20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[5]}]
#set_property -dict {LOC AG19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[6]}]
#set_property -dict {LOC AL18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[7]}]
#set_property -dict {LOC AG14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dm_dbi_n[8]}]
# QSPI flash
set_property -dict {LOC AF30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[0]}]
set_property -dict {LOC AG30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[1]}]
set_property -dict {LOC AF28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[2]}]
set_property -dict {LOC AG28 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_dq[3]}]
set_property -dict {LOC AV30 IOSTANDARD LVCMOS18 DRIVE 12} [get_ports {qspi_1_cs}]
set_false_path -to [get_ports {qspi_1_dq[*] qspi_1_cs}]
set_output_delay 0 [get_ports {qspi_1_dq[*] qspi_1_cs}]
set_false_path -from [get_ports {qspi_1_dq}]
set_input_delay 0 [get_ports {qspi_1_dq}]

View File

@@ -0,0 +1,94 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcvu3p-ffvc1517-2-i
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 64 -interface SPIx8 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu256-spi-x1_x2_x4_x8}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B39093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x4144]
set board_device_id [expr 0x9003]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,94 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcvu3p-ffvc1517-2-i
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 64 -interface SPIx8 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in _primary.mcs _secondary.mcs _primary.prm _secondary.prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT)_primary.mcs $(PROJECT)_secondary.mcs $(PROJECT)_primary.prm $(PROJECT)_secondary.prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu256-spi-x1_x2_x4_x8}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)_primary.mcs\" \"$(PROJECT)_secondary.mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)_primary.prm\" \"$(PROJECT)_secondary.prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B39093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x4144]
set board_device_id [expr 0x9003]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,30 @@
create_ip -name pcie4_uscale_plus -vendor xilinx.com -library ip -module_name pcie4_uscale_plus_0
set_property -dict [list \
CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \
CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X16} \
CONFIG.AXISTEN_IF_EXT_512_CQ_STRADDLE {false} \
CONFIG.AXISTEN_IF_EXT_512_RQ_STRADDLE {false} \
CONFIG.AXISTEN_IF_EXT_512_RC_4TLP_STRADDLE {false} \
CONFIG.axisten_if_enable_client_tag {true} \
CONFIG.axisten_if_width {512_bit} \
CONFIG.extended_tag_field {true} \
CONFIG.pf0_dev_cap_max_payload {1024_bytes} \
CONFIG.axisten_freq {250} \
CONFIG.PF0_Use_Class_Code_Lookup_Assistant {false} \
CONFIG.PF0_CLASS_CODE {020000} \
CONFIG.PF0_DEVICE_ID {C001} \
CONFIG.PF0_SUBSYSTEM_ID {9003} \
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {4144} \
CONFIG.pf0_bar0_64bit {true} \
CONFIG.pf0_bar0_prefetchable {true} \
CONFIG.pf0_bar0_scale {Megabytes} \
CONFIG.pf0_bar0_size {16} \
CONFIG.pf0_msi_enabled {true} \
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
CONFIG.en_msi_per_vec_masking {true} \
CONFIG.legacy_ext_pcie_cfg_space_enabled {true} \
CONFIG.vendor_id {1234} \
CONFIG.mode_selection {Advanced} \
] [get_ips pcie4_uscale_plus_0]

View File

@@ -0,0 +1 @@
../../../../../../

View File

@@ -0,0 +1,904 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2014-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga #
(
// simulation (set to avoid vendor primitives)
parameter logic SIM = 1'b0,
// vendor ("GENERIC", "XILINX", "ALTERA")
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// FW ID
parameter FPGA_ID = 32'h4B39093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h4144_9003,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
)
(
/*
* Clock: 300MHz LVDS
*/
input wire logic clk_300mhz_p,
input wire logic clk_300mhz_n,
/*
* GPIO
*/
output wire logic [1:0] user_led_g,
output wire logic user_led_r,
output wire logic [1:0] front_led,
input wire logic [1:0] user_sw,
/*
* Ethernet: QSFP28
*/
output wire logic qsfp_0_tx_p[4],
output wire logic qsfp_0_tx_n[4],
input wire logic qsfp_0_rx_p[4],
input wire logic qsfp_0_rx_n[4],
input wire logic qsfp_0_mgt_refclk_p,
input wire logic qsfp_0_mgt_refclk_n,
input wire logic qsfp_0_modprs_l,
output wire logic qsfp_0_sel_l,
output wire logic qsfp_1_tx_p[4],
output wire logic qsfp_1_tx_n[4],
input wire logic qsfp_1_rx_p[4],
input wire logic qsfp_1_rx_n[4],
// input wire logic qsfp_1_mgt_refclk_p,
// input wire logic qsfp_1_mgt_refclk_n,
input wire logic qsfp_1_modprs_l,
output wire logic qsfp_1_sel_l,
output wire logic qsfp_reset_l,
input wire logic qsfp_int_l,
/*
* PCIe
*/
input wire logic [15:0] pcie_rx_p,
input wire logic [15:0] pcie_rx_n,
output wire logic [15:0] pcie_tx_p,
output wire logic [15:0] pcie_tx_n,
input wire logic pcie_refclk_1_p,
input wire logic pcie_refclk_1_n,
input wire logic pcie_reset_n,
/*
* QSPI
*/
inout wire logic [3:0] qspi_1_dq,
output wire logic qspi_1_cs
);
// Clock and reset
wire pcie_user_clk;
wire pcie_user_rst;
wire clk_300mhz_ibufg;
// Internal 125 MHz clock
wire clk_125mhz_mmcm_out;
wire clk_125mhz_int;
wire rst_125mhz_int;
wire mmcm_rst = 1'b0;
wire mmcm_locked;
wire mmcm_clkfb;
IBUFGDS #(
.DIFF_TERM("FALSE"),
.IBUF_LOW_PWR("FALSE")
)
clk_300mhz_ibufg_inst (
.O (clk_300mhz_ibufg),
.I (clk_300mhz_p),
.IB (clk_300mhz_n)
);
// MMCM instance
MMCME4_BASE #(
// 300 MHz input
.CLKIN1_PERIOD(3.333),
.REF_JITTER1(0.010),
// 300 MHz input / 3 = 100 MHz PFD (range 10 MHz to 500 MHz)
.DIVCLK_DIVIDE(3),
// 100 MHz PFD * 12.5 = 1250 MHz VCO (range 800 MHz to 1600 MHz)
.CLKFBOUT_MULT_F(12.5),
.CLKFBOUT_PHASE(0),
// 1250 MHz / 10 = 125 MHz, 0 degrees
.CLKOUT0_DIVIDE_F(10),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0),
// Not used
.CLKOUT1_DIVIDE(1),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT1_PHASE(0),
// Not used
.CLKOUT2_DIVIDE(1),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT2_PHASE(0),
// Not used
.CLKOUT3_DIVIDE(1),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT3_PHASE(0),
// Not used
.CLKOUT4_DIVIDE(1),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT4_PHASE(0),
.CLKOUT4_CASCADE("FALSE"),
// Not used
.CLKOUT5_DIVIDE(1),
.CLKOUT5_DUTY_CYCLE(0.5),
.CLKOUT5_PHASE(0),
// Not used
.CLKOUT6_DIVIDE(1),
.CLKOUT6_DUTY_CYCLE(0.5),
.CLKOUT6_PHASE(0),
// optimized bandwidth
.BANDWIDTH("OPTIMIZED"),
// don't wait for lock during startup
.STARTUP_WAIT("FALSE")
)
clk_mmcm_inst (
// 300 MHz input
.CLKIN1(clk_300mhz_ibufg),
// direct clkfb feeback
.CLKFBIN(mmcm_clkfb),
.CLKFBOUT(mmcm_clkfb),
.CLKFBOUTB(),
// 125 MHz, 0 degrees
.CLKOUT0(clk_125mhz_mmcm_out),
.CLKOUT0B(),
// Not used
.CLKOUT1(),
.CLKOUT1B(),
// Not used
.CLKOUT2(),
.CLKOUT2B(),
// Not used
.CLKOUT3(),
.CLKOUT3B(),
// Not used
.CLKOUT4(),
// Not used
.CLKOUT5(),
// Not used
.CLKOUT6(),
// reset input
.RST(mmcm_rst),
// don't power down
.PWRDWN(1'b0),
// locked output
.LOCKED(mmcm_locked)
);
BUFG
clk_125mhz_bufg_inst (
.I(clk_125mhz_mmcm_out),
.O(clk_125mhz_int)
);
taxi_sync_reset #(
.N(4)
)
sync_reset_125mhz_inst (
.clk(clk_125mhz_int),
.rst(~mmcm_locked),
.out(rst_125mhz_int)
);
// GPIO
wire [1:0] user_sw_int;
taxi_debounce_switch #(
.WIDTH(2),
.N(4),
.RATE(125000)
)
debounce_switch_inst (
.clk(clk_125mhz_int),
.rst(rst_125mhz_int),
.in({user_sw}),
.out({user_sw_int})
);
// Flash
wire qspi_clk_int;
wire [3:0] qspi_0_dq_int;
wire [3:0] qspi_0_dq_i_int;
wire [3:0] qspi_0_dq_o_int;
wire [3:0] qspi_0_dq_oe_int;
wire qspi_0_cs_int;
wire [3:0] qspi_1_dq_i_int;
wire [3:0] qspi_1_dq_o_int;
wire [3:0] qspi_1_dq_oe_int;
wire qspi_1_cs_int;
logic qspi_clk_reg;
logic [3:0] qspi_0_dq_o_reg;
logic [3:0] qspi_0_dq_oe_reg;
logic qspi_0_cs_reg;
logic [3:0] qspi_1_dq_o_reg;
logic [3:0] qspi_1_dq_oe_reg;
logic qspi_1_cs_reg;
always_ff @(posedge pcie_user_clk) begin
qspi_clk_reg <= qspi_clk_int;
qspi_0_dq_o_reg <= qspi_0_dq_o_int;
qspi_0_dq_oe_reg <= qspi_0_dq_oe_int;
qspi_0_cs_reg <= qspi_0_cs_int;
qspi_1_dq_o_reg <= qspi_1_dq_o_int;
qspi_1_dq_oe_reg <= qspi_1_dq_oe_int;
qspi_1_cs_reg <= qspi_1_cs_int;
end
assign qspi_1_dq[0] = qspi_1_dq_oe_reg[0] ? qspi_1_dq_o_reg[0] : 1'bz;
assign qspi_1_dq[1] = qspi_1_dq_oe_reg[1] ? qspi_1_dq_o_reg[1] : 1'bz;
assign qspi_1_dq[2] = qspi_1_dq_oe_reg[2] ? qspi_1_dq_o_reg[2] : 1'bz;
assign qspi_1_dq[3] = qspi_1_dq_oe_reg[3] ? qspi_1_dq_o_reg[3] : 1'bz;
assign qspi_1_cs = qspi_1_cs_reg;
taxi_sync_signal #(
.WIDTH(8),
.N(2)
)
flash_sync_signal_inst (
.clk(pcie_user_clk),
.in({qspi_1_dq, qspi_0_dq_int}),
.out({qspi_1_dq_i_int, qspi_0_dq_i_int})
);
STARTUPE3
startupe3_inst (
.CFGCLK(),
.CFGMCLK(),
.DI(qspi_0_dq_int),
.DO(qspi_0_dq_o_reg),
.DTS(~qspi_0_dq_oe_reg),
.EOS(),
.FCSBO(qspi_0_cs_reg),
.FCSBTS(1'b0),
.GSR(1'b0),
.GTS(1'b0),
.KEYCLEARB(1'b1),
.PACK(1'b0),
.PREQ(),
.USRCCLKO(qspi_clk_reg),
.USRCCLKTS(1'b0),
.USRDONEO(1'b0),
.USRDONETS(1'b1)
);
// FPGA boot
wire fpga_boot;
wire fpga_boot_sync;
taxi_sync_signal #(
.WIDTH(1),
.N(2)
)
fpga_boot_sync_inst (
.clk(clk_125mhz_int),
.in({fpga_boot}),
.out({fpga_boot_sync})
);
wire icap_avail;
logic [2:0] icap_state_reg = 0;
logic icap_csib_reg = 1'b1;
logic icap_rdwrb_reg = 1'b0;
logic [31:0] icap_di_reg = 32'hffffffff;
wire [31:0] icap_di_rev;
assign icap_di_rev[ 7] = icap_di_reg[ 0];
assign icap_di_rev[ 6] = icap_di_reg[ 1];
assign icap_di_rev[ 5] = icap_di_reg[ 2];
assign icap_di_rev[ 4] = icap_di_reg[ 3];
assign icap_di_rev[ 3] = icap_di_reg[ 4];
assign icap_di_rev[ 2] = icap_di_reg[ 5];
assign icap_di_rev[ 1] = icap_di_reg[ 6];
assign icap_di_rev[ 0] = icap_di_reg[ 7];
assign icap_di_rev[15] = icap_di_reg[ 8];
assign icap_di_rev[14] = icap_di_reg[ 9];
assign icap_di_rev[13] = icap_di_reg[10];
assign icap_di_rev[12] = icap_di_reg[11];
assign icap_di_rev[11] = icap_di_reg[12];
assign icap_di_rev[10] = icap_di_reg[13];
assign icap_di_rev[ 9] = icap_di_reg[14];
assign icap_di_rev[ 8] = icap_di_reg[15];
assign icap_di_rev[23] = icap_di_reg[16];
assign icap_di_rev[22] = icap_di_reg[17];
assign icap_di_rev[21] = icap_di_reg[18];
assign icap_di_rev[20] = icap_di_reg[19];
assign icap_di_rev[19] = icap_di_reg[20];
assign icap_di_rev[18] = icap_di_reg[21];
assign icap_di_rev[17] = icap_di_reg[22];
assign icap_di_rev[16] = icap_di_reg[23];
assign icap_di_rev[31] = icap_di_reg[24];
assign icap_di_rev[30] = icap_di_reg[25];
assign icap_di_rev[29] = icap_di_reg[26];
assign icap_di_rev[28] = icap_di_reg[27];
assign icap_di_rev[27] = icap_di_reg[28];
assign icap_di_rev[26] = icap_di_reg[29];
assign icap_di_rev[25] = icap_di_reg[30];
assign icap_di_rev[24] = icap_di_reg[31];
always_ff @(posedge clk_125mhz_int) begin
case (icap_state_reg)
0: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b1;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
if (fpga_boot_sync && icap_avail) begin
icap_state_reg <= 1;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
end
end
1: begin
icap_state_reg <= 2;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hAA995566; // sync word
end
2: begin
icap_state_reg <= 3;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
3: begin
icap_state_reg <= 4;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h30008001; // write 1 word to CMD
end
4: begin
icap_state_reg <= 5;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h0000000F; // IPROG
end
5: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
endcase
end
ICAPE3
icape3_inst (
.AVAIL(icap_avail),
.CLK(clk_125mhz_int),
.CSIB(icap_csib_reg),
.I(icap_di_rev),
.O(),
.PRDONE(),
.PRERROR(),
.RDWRB(icap_rdwrb_reg)
);
// PCIe
localparam AXIS_PCIE_DATA_W = 512;
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
localparam AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161;
localparam AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137;
localparam AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183;
localparam AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81;
localparam RC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 256;
localparam RQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
localparam RQ_SEQ_NUM_EN = 1;
localparam PCIE_TAG_CNT = AXIS_PCIE_RQ_USER_W == 60 ? 64 : 256;
localparam BAR0_APERTURE = 24;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CQ_USER_W)
) axis_pcie_cq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CC_USER_W)
) axis_pcie_cc();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RQ_USER_W)
) axis_pcie_rq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RC_USER_W)
) axis_pcie_rc();
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0;
wire pcie_rq_seq_num_vld0;
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1;
wire pcie_rq_seq_num_vld1;
wire [2:0] cfg_max_payload;
wire [2:0] cfg_max_read_req;
wire [3:0] cfg_rcb_status;
wire [9:0] cfg_mgmt_addr;
wire [7:0] cfg_mgmt_function_number;
wire cfg_mgmt_write;
wire [31:0] cfg_mgmt_write_data;
wire [3:0] cfg_mgmt_byte_enable;
wire cfg_mgmt_read;
wire [31:0] cfg_mgmt_read_data;
wire cfg_mgmt_read_write_done;
wire [7:0] cfg_fc_ph;
wire [11:0] cfg_fc_pd;
wire [7:0] cfg_fc_nph;
wire [11:0] cfg_fc_npd;
wire [7:0] cfg_fc_cplh;
wire [11:0] cfg_fc_cpld;
wire [2:0] cfg_fc_sel;
wire cfg_ext_read_received;
wire cfg_ext_write_received;
wire [9:0] cfg_ext_register_number;
wire [7:0] cfg_ext_function_number;
wire [31:0] cfg_ext_write_data;
wire [3:0] cfg_ext_write_byte_enable;
wire [31:0] cfg_ext_read_data;
wire cfg_ext_read_data_valid;
// wire [3:0] cfg_interrupt_msix_enable;
// wire [3:0] cfg_interrupt_msix_mask;
// wire [251:0] cfg_interrupt_msix_vf_enable;
// wire [251:0] cfg_interrupt_msix_vf_mask;
// wire [63:0] cfg_interrupt_msix_address;
// wire [31:0] cfg_interrupt_msix_data;
// wire cfg_interrupt_msix_int;
// wire [1:0] cfg_interrupt_msix_vec_pending;
// wire cfg_interrupt_msix_vec_pending_status;
// wire cfg_interrupt_msix_sent;
// wire cfg_interrupt_msix_fail;
// wire [7:0] cfg_interrupt_msi_function_number;
wire [3:0] cfg_interrupt_msi_enable;
wire [11:0] cfg_interrupt_msi_mmenable;
wire cfg_interrupt_msi_mask_update;
wire [31:0] cfg_interrupt_msi_data;
wire [1:0] cfg_interrupt_msi_select;
wire [31:0] cfg_interrupt_msi_int;
wire [31:0] cfg_interrupt_msi_pending_status;
wire cfg_interrupt_msi_pending_status_data_enable;
wire [1:0] cfg_interrupt_msi_pending_status_function_num;
wire cfg_interrupt_msi_sent;
wire cfg_interrupt_msi_fail;
wire [2:0] cfg_interrupt_msi_attr;
wire cfg_interrupt_msi_tph_present;
wire [1:0] cfg_interrupt_msi_tph_type;
wire [7:0] cfg_interrupt_msi_tph_st_tag;
wire [7:0] cfg_interrupt_msi_function_number;
wire stat_err_cor;
wire stat_err_uncor;
wire pcie_sys_clk;
wire pcie_sys_clk_gt;
IBUFDS_GTE4 #(
.REFCLK_HROW_CK_SEL(2'b00)
)
ibufds_gte4_pcie_refclk_inst (
.I (pcie_refclk_1_p),
.IB (pcie_refclk_1_n),
.CEB (1'b0),
.O (pcie_sys_clk_gt),
.ODIV2 (pcie_sys_clk)
);
pcie4_uscale_plus_0
pcie4_uscale_plus_inst (
.pci_exp_txn(pcie_tx_n),
.pci_exp_txp(pcie_tx_p),
.pci_exp_rxn(pcie_rx_n),
.pci_exp_rxp(pcie_rx_p),
.user_clk(pcie_user_clk),
.user_reset(pcie_user_rst),
.user_lnk_up(),
.s_axis_rq_tdata(axis_pcie_rq.tdata),
.s_axis_rq_tkeep(axis_pcie_rq.tkeep),
.s_axis_rq_tlast(axis_pcie_rq.tlast),
.s_axis_rq_tready(axis_pcie_rq.tready),
.s_axis_rq_tuser(axis_pcie_rq.tuser),
.s_axis_rq_tvalid(axis_pcie_rq.tvalid),
.m_axis_rc_tdata(axis_pcie_rc.tdata),
.m_axis_rc_tkeep(axis_pcie_rc.tkeep),
.m_axis_rc_tlast(axis_pcie_rc.tlast),
.m_axis_rc_tready(axis_pcie_rc.tready),
.m_axis_rc_tuser(axis_pcie_rc.tuser),
.m_axis_rc_tvalid(axis_pcie_rc.tvalid),
.m_axis_cq_tdata(axis_pcie_cq.tdata),
.m_axis_cq_tkeep(axis_pcie_cq.tkeep),
.m_axis_cq_tlast(axis_pcie_cq.tlast),
.m_axis_cq_tready(axis_pcie_cq.tready),
.m_axis_cq_tuser(axis_pcie_cq.tuser),
.m_axis_cq_tvalid(axis_pcie_cq.tvalid),
.s_axis_cc_tdata(axis_pcie_cc.tdata),
.s_axis_cc_tkeep(axis_pcie_cc.tkeep),
.s_axis_cc_tlast(axis_pcie_cc.tlast),
.s_axis_cc_tready(axis_pcie_cc.tready),
.s_axis_cc_tuser(axis_pcie_cc.tuser),
.s_axis_cc_tvalid(axis_pcie_cc.tvalid),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.pcie_rq_tag0(),
.pcie_rq_tag1(),
.pcie_rq_tag_av(),
.pcie_rq_tag_vld0(),
.pcie_rq_tag_vld1(),
.pcie_tfc_nph_av(),
.pcie_tfc_npd_av(),
.pcie_cq_np_req(1'b1),
.pcie_cq_np_req_count(),
.cfg_phy_link_down(),
.cfg_phy_link_status(),
.cfg_negotiated_width(),
.cfg_current_speed(),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_function_status(),
.cfg_function_power_state(),
.cfg_vf_status(),
.cfg_vf_power_state(),
.cfg_link_power_state(),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_mgmt_debug_access(1'b0),
.cfg_err_cor_out(),
.cfg_err_nonfatal_out(),
.cfg_err_fatal_out(),
.cfg_local_error_valid(),
.cfg_local_error_out(),
.cfg_ltssm_state(),
.cfg_rx_pm_state(),
.cfg_tx_pm_state(),
.cfg_rcb_status(cfg_rcb_status),
.cfg_obff_enable(),
.cfg_pl_status_change(),
.cfg_tph_requester_enable(),
.cfg_tph_st_mode(),
.cfg_vf_tph_requester_enable(),
.cfg_vf_tph_st_mode(),
.cfg_msg_received(),
.cfg_msg_received_data(),
.cfg_msg_received_type(),
.cfg_msg_transmit(1'b0),
.cfg_msg_transmit_type(3'd0),
.cfg_msg_transmit_data(32'd0),
.cfg_msg_transmit_done(),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_dsn(64'd0),
.cfg_bus_number(),
.cfg_power_state_change_ack(1'b1),
.cfg_power_state_change_interrupt(),
.cfg_err_cor_in(stat_err_cor),
.cfg_err_uncor_in(stat_err_uncor),
.cfg_flr_in_process(),
.cfg_flr_done(4'd0),
.cfg_vf_flr_in_process(),
.cfg_vf_flr_func_num(8'd0),
.cfg_vf_flr_done(8'd0),
.cfg_link_training_enable(1'b1),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_int(4'd0),
.cfg_interrupt_pending(4'd0),
.cfg_interrupt_sent(),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msi_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msi_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_pm_aspm_l1_entry_reject(1'b0),
.cfg_pm_aspm_tx_l0s_entry_disable(1'b0),
.cfg_hot_reset_out(),
.cfg_config_space_enable(1'b1),
.cfg_req_pm_transition_l23_ready(1'b0),
.cfg_hot_reset_in(1'b0),
.cfg_ds_port_number(8'd0),
.cfg_ds_bus_number(8'd0),
.cfg_ds_device_number(5'd0),
.sys_clk(pcie_sys_clk),
.sys_clk_gt(pcie_sys_clk_gt),
.sys_reset(pcie_reset_n),
.phy_rdy_out()
);
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
)
core_inst (
/*
* Clock: 125 MHz
* Synchronous reset
*/
.clk_125mhz(clk_125mhz_int),
.rst_125mhz(rst_125mhz_int),
/*
* GPIO
*/
.user_led_g(user_led_g),
.user_led_r(user_led_r),
.front_led(front_led),
.user_sw(user_sw_int),
/*
* Ethernet: QSFP28
*/
.qsfp_0_tx_p(qsfp_0_tx_p),
.qsfp_0_tx_n(qsfp_0_tx_n),
.qsfp_0_rx_p(qsfp_0_rx_p),
.qsfp_0_rx_n(qsfp_0_rx_n),
.qsfp_0_mgt_refclk_p(qsfp_0_mgt_refclk_p),
.qsfp_0_mgt_refclk_n(qsfp_0_mgt_refclk_n),
.qsfp_0_modprs_l(qsfp_0_modprs_l),
.qsfp_0_sel_l(qsfp_0_sel_l),
.qsfp_1_tx_p(qsfp_1_tx_p),
.qsfp_1_tx_n(qsfp_1_tx_n),
.qsfp_1_rx_p(qsfp_1_rx_p),
.qsfp_1_rx_n(qsfp_1_rx_n),
// .qsfp_1_mgt_refclk_p(qsfp_1_mgt_refclk_p),
// .qsfp_1_mgt_refclk_n(qsfp_1_mgt_refclk_n),
.qsfp_1_modprs_l(qsfp_1_modprs_l),
.qsfp_1_sel_l(qsfp_1_sel_l),
.qsfp_reset_l(qsfp_reset_l),
.qsfp_int_l(qsfp_int_l),
/*
* PCIe
*/
.pcie_clk(pcie_user_clk),
.pcie_rst(pcie_user_rst),
.s_axis_pcie_cq(axis_pcie_cq),
.m_axis_pcie_cc(axis_pcie_cc),
.m_axis_pcie_rq(axis_pcie_rq),
.s_axis_pcie_rc(axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msix_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msix_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk_int),
.qspi_0_dq_i(qspi_0_dq_i_int),
.qspi_0_dq_o(qspi_0_dq_o_int),
.qspi_0_dq_oe(qspi_0_dq_oe_int),
.qspi_0_cs(qspi_0_cs_int),
.qspi_1_dq_i(qspi_1_dq_i_int),
.qspi_1_dq_o(qspi_1_dq_o_int),
.qspi_1_dq_oe(qspi_1_dq_oe_int),
.qspi_1_cs(qspi_1_cs_int)
);
endmodule
`resetall

View File

@@ -0,0 +1,677 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2014-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA core logic
*/
module fpga_core #
(
// simulation (set to avoid vendor primitives)
parameter logic SIM = 1'b0,
// vendor ("GENERIC", "XILINX", "ALTERA")
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// FW ID
parameter FPGA_ID = 32'h4B39093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h4144_9003,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// PCIe interface configuration
parameter RQ_SEQ_NUM_W = 6,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
)
(
/*
* Clock: 125 MHz
* Synchronous reset
*/
input wire logic clk_125mhz,
input wire logic rst_125mhz,
/*
* GPIO
*/
output wire logic [1:0] user_led_g,
output wire logic user_led_r,
output wire logic [1:0] front_led,
input wire logic [1:0] user_sw,
/*
* Ethernet: QSFP28
*/
output wire logic qsfp_0_tx_p[4],
output wire logic qsfp_0_tx_n[4],
input wire logic qsfp_0_rx_p[4],
input wire logic qsfp_0_rx_n[4],
input wire logic qsfp_0_mgt_refclk_p,
input wire logic qsfp_0_mgt_refclk_n,
input wire logic qsfp_0_modprs_l,
output wire logic qsfp_0_sel_l,
output wire logic qsfp_1_tx_p[4],
output wire logic qsfp_1_tx_n[4],
input wire logic qsfp_1_rx_p[4],
input wire logic qsfp_1_rx_n[4],
// input wire logic qsfp_1_mgt_refclk_p,
// input wire logic qsfp_1_mgt_refclk_n,
input wire logic qsfp_1_modprs_l,
output wire logic qsfp_1_sel_l,
output wire logic qsfp_reset_l,
input wire logic qsfp_int_l,
/*
* PCIe
*/
input wire logic pcie_clk,
input wire logic pcie_rst,
taxi_axis_if.snk s_axis_pcie_cq,
taxi_axis_if.src m_axis_pcie_cc,
taxi_axis_if.src m_axis_pcie_rq,
taxi_axis_if.snk s_axis_pcie_rc,
input wire logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0,
input wire logic pcie_rq_seq_num_vld0,
input wire logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1,
input wire logic pcie_rq_seq_num_vld1,
input wire logic [2:0] cfg_max_payload,
input wire logic [2:0] cfg_max_read_req,
input wire logic [3:0] cfg_rcb_status,
output wire logic [9:0] cfg_mgmt_addr,
output wire logic [7:0] cfg_mgmt_function_number,
output wire logic cfg_mgmt_write,
output wire logic [31:0] cfg_mgmt_write_data,
output wire logic [3:0] cfg_mgmt_byte_enable,
output wire logic cfg_mgmt_read,
output wire logic [31:0] cfg_mgmt_read_data,
input wire logic cfg_mgmt_read_write_done,
input wire logic [7:0] cfg_fc_ph,
input wire logic [11:0] cfg_fc_pd,
input wire logic [7:0] cfg_fc_nph,
input wire logic [11:0] cfg_fc_npd,
input wire logic [7:0] cfg_fc_cplh,
input wire logic [11:0] cfg_fc_cpld,
output wire logic [2:0] cfg_fc_sel,
input wire logic cfg_ext_read_received,
input wire logic cfg_ext_write_received,
input wire logic [9:0] cfg_ext_register_number,
input wire logic [7:0] cfg_ext_function_number,
input wire logic [31:0] cfg_ext_write_data,
input wire logic [3:0] cfg_ext_write_byte_enable,
output wire logic [31:0] cfg_ext_read_data,
output wire logic cfg_ext_read_data_valid,
input wire logic [3:0] cfg_interrupt_msi_enable,
input wire logic [11:0] cfg_interrupt_msi_mmenable,
input wire logic cfg_interrupt_msi_mask_update,
input wire logic [31:0] cfg_interrupt_msi_data,
output wire logic [1:0] cfg_interrupt_msi_select,
output wire logic [31:0] cfg_interrupt_msi_int,
output wire logic [31:0] cfg_interrupt_msi_pending_status,
output wire logic cfg_interrupt_msi_pending_status_data_enable,
output wire logic [1:0] cfg_interrupt_msi_pending_status_function_num,
input wire logic cfg_interrupt_msi_sent,
input wire logic cfg_interrupt_msi_fail,
output wire logic [2:0] cfg_interrupt_msi_attr,
output wire logic cfg_interrupt_msi_tph_present,
output wire logic [1:0] cfg_interrupt_msi_tph_type,
output wire logic [7:0] cfg_interrupt_msi_tph_st_tag,
output wire logic [7:0] cfg_interrupt_msi_function_number,
/*
* QSPI flash
*/
output wire logic fpga_boot,
output wire logic qspi_clk,
input wire logic [3:0] qspi_0_dq_i,
output wire logic [3:0] qspi_0_dq_o,
output wire logic [3:0] qspi_0_dq_oe,
output wire logic qspi_0_cs,
input wire logic [3:0] qspi_1_dq_i,
output wire logic [3:0] qspi_1_dq_o,
output wire logic [3:0] qspi_1_dq_oe,
output wire logic qspi_1_cs
);
localparam logic PTP_TS_FMT_TOD = 1'b0;
localparam PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 48;
// flashing via PCIe VPD
pyrite_pcie_us_vpd_qspi #(
.VPD_CAP_ID(8'h03),
.VPD_CAP_OFFSET(8'hB0),
.VPD_CAP_NEXT(8'h00),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Flash
.FLASH_SEG_COUNT(2),
.FLASH_SEG_DEFAULT(1),
.FLASH_SEG_FALLBACK(0),
.FLASH_SEG0_SIZE(32'h00000000),
.FLASH_DATA_W(4),
.FLASH_DUAL_QSPI(1'b1)
)
pyrite_inst (
.clk(pcie_clk),
.rst(pcie_rst),
/*
* PCIe
*/
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk),
.qspi_0_dq_i(qspi_0_dq_i),
.qspi_0_dq_o(qspi_0_dq_o),
.qspi_0_dq_oe(qspi_0_dq_oe),
.qspi_0_cs(qspi_0_cs),
.qspi_1_dq_i(qspi_1_dq_i),
.qspi_1_dq_o(qspi_1_dq_o),
.qspi_1_dq_oe(qspi_1_dq_oe),
.qspi_1_cs(qspi_1_cs)
);
// QSFP28
assign qsfp_0_sel_l = 1'b1;
assign qsfp_1_sel_l = 1'b1;
assign qsfp_reset_l = 1'b1;
wire qsfp_tx_clk[8];
wire qsfp_tx_rst[8];
wire qsfp_rx_clk[8];
wire qsfp_rx_rst[8];
wire qsfp_rx_status[8];
wire [1:0] qsfp_gtpowergood;
wire qsfp_0_mgt_refclk;
wire qsfp_0_mgt_refclk_int;
wire qsfp_0_mgt_refclk_bufg;
wire qsfp_rst;
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) axis_qsfp_tx[8]();
taxi_axis_if #(.DATA_W(PTP_TS_W), .KEEP_W(1), .ID_W(8)) axis_qsfp_tx_cpl[8]();
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1+PTP_TS_W)) axis_qsfp_rx[8]();
taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(8)) axis_qsfp_stat[2]();
if (SIM) begin
assign qsfp_0_mgt_refclk = qsfp_0_mgt_refclk_p;
assign qsfp_0_mgt_refclk_int = qsfp_0_mgt_refclk_p;
assign qsfp_0_mgt_refclk_bufg = qsfp_0_mgt_refclk_int;
end else begin
IBUFDS_GTE4 ibufds_gte4_qsfp_0_mgt_refclk_inst (
.I (qsfp_0_mgt_refclk_p),
.IB (qsfp_0_mgt_refclk_n),
.CEB (1'b0),
.O (qsfp_0_mgt_refclk),
.ODIV2 (qsfp_0_mgt_refclk_int)
);
BUFG_GT bufg_gt_qsfp_0_mgt_refclk_inst (
.CE (&qsfp_gtpowergood),
.CEMASK (1'b1),
.CLR (1'b0),
.CLRMASK (1'b1),
.DIV (3'd0),
.I (qsfp_0_mgt_refclk_int),
.O (qsfp_0_mgt_refclk_bufg)
);
end
taxi_sync_reset #(
.N(4)
)
qsfp_sync_reset_inst (
.clk(qsfp_0_mgt_refclk_bufg),
.rst(rst_125mhz),
.out(qsfp_rst)
);
wire ptp_clk = qsfp_0_mgt_refclk_bufg;
wire ptp_rst = qsfp_rst;
wire ptp_sample_clk = clk_125mhz;
wire ptp_td_sd;
wire ptp_pps;
wire ptp_pps_str;
assign user_led_g[0] = ptp_pps_str;
assign user_led_g[1] = 1'b0;
assign user_led_r = 1'b0;
wire qsfp_tx_p[8];
wire qsfp_tx_n[8];
wire qsfp_rx_p[8];
wire qsfp_rx_n[8];
assign qsfp_0_tx_p = qsfp_tx_p[4*0 +: 4];
assign qsfp_0_tx_n = qsfp_tx_n[4*0 +: 4];
assign qsfp_1_tx_p = qsfp_tx_p[4*1 +: 4];
assign qsfp_1_tx_n = qsfp_tx_n[4*1 +: 4];
assign qsfp_rx_p[4*0 +: 4] = qsfp_0_rx_p;
assign qsfp_rx_n[4*0 +: 4] = qsfp_0_rx_n;
assign qsfp_rx_p[4*1 +: 4] = qsfp_1_rx_p;
assign qsfp_rx_n[4*1 +: 4] = qsfp_1_rx_n;
for (genvar n = 0; n < 2; n = n + 1) begin : gty_quad
localparam CNT = 4;
taxi_apb_if #(
.ADDR_W(18),
.DATA_W(16)
)
gt_apb_ctrl();
taxi_eth_mac_25g_us #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
.CNT(CNT),
// GT config
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
// GT type
.GT_TYPE("GTY"),
// PHY parameters
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.DATA_W(MAC_DATA_W),
.PADDING_EN(1'b1),
.DIC_EN(1'b1),
.MIN_FRAME_LEN(64),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(2),
.PRBS31_EN(1'b0),
.TX_SERDES_PIPELINE(1),
.RX_SERDES_PIPELINE(1),
.COUNT_125US(125000/6.4),
.STAT_EN(1'b0)
)
mac_inst (
.xcvr_ctrl_clk(clk_125mhz),
.xcvr_ctrl_rst(qsfp_rst),
/*
* Transceiver control
*/
.s_apb_ctrl(gt_apb_ctrl),
/*
* Common
*/
.xcvr_gtpowergood_out(qsfp_gtpowergood[n]),
.xcvr_gtrefclk00_in(qsfp_0_mgt_refclk),
.xcvr_qpll0pd_in(1'b0),
.xcvr_qpll0reset_in(1'b0),
.xcvr_qpll0pcierate_in(3'd0),
.xcvr_qpll0lock_out(),
.xcvr_qpll0clk_out(),
.xcvr_qpll0refclk_out(),
.xcvr_gtrefclk01_in(qsfp_0_mgt_refclk),
.xcvr_qpll1pd_in(1'b0),
.xcvr_qpll1reset_in(1'b0),
.xcvr_qpll1pcierate_in(3'd0),
.xcvr_qpll1lock_out(),
.xcvr_qpll1clk_out(),
.xcvr_qpll1refclk_out(),
/*
* Serial data
*/
.xcvr_txp(qsfp_tx_p[n*CNT +: CNT]),
.xcvr_txn(qsfp_tx_n[n*CNT +: CNT]),
.xcvr_rxp(qsfp_rx_p[n*CNT +: CNT]),
.xcvr_rxn(qsfp_rx_n[n*CNT +: CNT]),
/*
* MAC clocks
*/
.rx_clk(qsfp_rx_clk[n*CNT +: CNT]),
.rx_rst_in('{CNT{1'b0}}),
.rx_rst_out(qsfp_rx_rst[n*CNT +: CNT]),
.tx_clk(qsfp_tx_clk[n*CNT +: CNT]),
.tx_rst_in('{CNT{1'b0}}),
.tx_rst_out(qsfp_tx_rst[n*CNT +: CNT]),
/*
* Transmit interface (AXI stream)
*/
.s_axis_tx(axis_qsfp_tx[n*CNT +: CNT]),
.m_axis_tx_cpl(axis_qsfp_tx_cpl[n*CNT +: CNT]),
/*
* Receive interface (AXI stream)
*/
.m_axis_rx(axis_qsfp_rx[n*CNT +: CNT]),
/*
* PTP clock
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_sample_clk(ptp_sample_clk),
.ptp_td_sdi(ptp_td_sd),
.tx_ptp_ts_in('{CNT{'0}}),
.tx_ptp_ts_out(),
.tx_ptp_ts_step_out(),
.tx_ptp_locked(),
.rx_ptp_ts_in('{CNT{'0}}),
.rx_ptp_ts_out(),
.rx_ptp_ts_step_out(),
.rx_ptp_locked(),
/*
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
*/
.tx_lfc_req('{CNT{1'b0}}),
.tx_lfc_resend('{CNT{1'b0}}),
.rx_lfc_en('{CNT{1'b0}}),
.rx_lfc_req(),
.rx_lfc_ack('{CNT{1'b0}}),
/*
* Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)
*/
.tx_pfc_req('{CNT{'0}}),
.tx_pfc_resend('{CNT{1'b0}}),
.rx_pfc_en('{CNT{'0}}),
.rx_pfc_req(),
.rx_pfc_ack('{CNT{'0}}),
/*
* Pause interface
*/
.tx_lfc_pause_en('{CNT{1'b0}}),
.tx_pause_req('{CNT{1'b0}}),
.tx_pause_ack(),
/*
* Statistics
*/
.stat_clk(clk_125mhz),
.stat_rst(rst_125mhz),
.m_axis_stat(axis_qsfp_stat[n]),
/*
* Status
*/
.tx_start_packet(),
.stat_tx_byte(),
.stat_tx_pkt_len(),
.stat_tx_pkt_ucast(),
.stat_tx_pkt_mcast(),
.stat_tx_pkt_bcast(),
.stat_tx_pkt_vlan(),
.stat_tx_pkt_good(),
.stat_tx_pkt_bad(),
.stat_tx_err_oversize(),
.stat_tx_err_user(),
.stat_tx_err_underflow(),
.rx_start_packet(),
.rx_error_count(),
.rx_block_lock(),
.rx_high_ber(),
.rx_status(qsfp_rx_status[n*CNT +: CNT]),
.stat_rx_byte(),
.stat_rx_pkt_len(),
.stat_rx_pkt_fragment(),
.stat_rx_pkt_jabber(),
.stat_rx_pkt_ucast(),
.stat_rx_pkt_mcast(),
.stat_rx_pkt_bcast(),
.stat_rx_pkt_vlan(),
.stat_rx_pkt_good(),
.stat_rx_pkt_bad(),
.stat_rx_err_oversize(),
.stat_rx_err_bad_fcs(),
.stat_rx_err_bad_block(),
.stat_rx_err_framing(),
.stat_rx_err_preamble(),
.stat_rx_fifo_drop('{CNT{1'b0}}),
.stat_tx_mcf(),
.stat_rx_mcf(),
.stat_tx_lfc_pkt(),
.stat_tx_lfc_xon(),
.stat_tx_lfc_xoff(),
.stat_tx_lfc_paused(),
.stat_tx_pfc_pkt(),
.stat_tx_pfc_xon(),
.stat_tx_pfc_xoff(),
.stat_tx_pfc_paused(),
.stat_rx_lfc_pkt(),
.stat_rx_lfc_xon(),
.stat_rx_lfc_xoff(),
.stat_rx_lfc_paused(),
.stat_rx_pfc_pkt(),
.stat_rx_pfc_xon(),
.stat_rx_pfc_xoff(),
.stat_rx_pfc_paused(),
/*
* Configuration
*/
.cfg_tx_max_pkt_len('{CNT{16'd9218}}),
.cfg_tx_ifg('{CNT{8'd12}}),
.cfg_tx_enable('{CNT{1'b1}}),
.cfg_rx_max_pkt_len('{CNT{16'd9218}}),
.cfg_rx_enable('{CNT{1'b1}}),
.cfg_tx_prbs31_enable('{CNT{1'b0}}),
.cfg_rx_prbs31_enable('{CNT{1'b0}}),
.cfg_mcf_rx_eth_dst_mcast('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_mcf_rx_check_eth_dst_mcast('{CNT{1'b1}}),
.cfg_mcf_rx_eth_dst_ucast('{CNT{48'd0}}),
.cfg_mcf_rx_check_eth_dst_ucast('{CNT{1'b0}}),
.cfg_mcf_rx_eth_src('{CNT{48'd0}}),
.cfg_mcf_rx_check_eth_src('{CNT{1'b0}}),
.cfg_mcf_rx_eth_type('{CNT{16'h8808}}),
.cfg_mcf_rx_opcode_lfc('{CNT{16'h0001}}),
.cfg_mcf_rx_check_opcode_lfc('{CNT{1'b1}}),
.cfg_mcf_rx_opcode_pfc('{CNT{16'h0101}}),
.cfg_mcf_rx_check_opcode_pfc('{CNT{1'b1}}),
.cfg_mcf_rx_forward('{CNT{1'b0}}),
.cfg_mcf_rx_enable('{CNT{1'b0}}),
.cfg_tx_lfc_eth_dst('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_tx_lfc_eth_src('{CNT{48'h80_23_31_43_54_4C}}),
.cfg_tx_lfc_eth_type('{CNT{16'h8808}}),
.cfg_tx_lfc_opcode('{CNT{16'h0001}}),
.cfg_tx_lfc_en('{CNT{1'b0}}),
.cfg_tx_lfc_quanta('{CNT{16'hffff}}),
.cfg_tx_lfc_refresh('{CNT{16'h7fff}}),
.cfg_tx_pfc_eth_dst('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_tx_pfc_eth_src('{CNT{48'h80_23_31_43_54_4C}}),
.cfg_tx_pfc_eth_type('{CNT{16'h8808}}),
.cfg_tx_pfc_opcode('{CNT{16'h0101}}),
.cfg_tx_pfc_en('{CNT{1'b0}}),
.cfg_tx_pfc_quanta('{CNT{'{8{16'hffff}}}}),
.cfg_tx_pfc_refresh('{CNT{'{8{16'h7fff}}}}),
.cfg_rx_lfc_opcode('{CNT{16'h0001}}),
.cfg_rx_lfc_en('{CNT{1'b0}}),
.cfg_rx_pfc_opcode('{CNT{16'h0101}}),
.cfg_rx_pfc_en('{CNT{1'b0}})
);
end
cndm_micro_pcie_us #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration
.PORTS(8),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(1'b0),
.PTP_CLK_PER_NS_NUM(1024),
.PTP_CLK_PER_NS_DENOM(165),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W)
)
cndm_inst (
/*
* PCIe
*/
.pcie_clk(pcie_clk),
.pcie_rst(pcie_rst),
.s_axis_pcie_cq(s_axis_pcie_cq),
.m_axis_pcie_cc(m_axis_pcie_cc),
.m_axis_pcie_rq(m_axis_pcie_rq),
.s_axis_pcie_rc(s_axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* PTP
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_sample_clk(ptp_sample_clk),
.ptp_td_sdo(ptp_td_sd),
.ptp_pps(ptp_pps),
.ptp_pps_str(ptp_pps_str),
.ptp_sync_locked(),
.ptp_sync_ts_rel(),
.ptp_sync_ts_rel_step(),
.ptp_sync_ts_tod(),
.ptp_sync_ts_tod_step(),
.ptp_sync_pps(),
.ptp_sync_pps_str(),
/*
* Ethernet
*/
.mac_tx_clk(qsfp_tx_clk),
.mac_tx_rst(qsfp_tx_rst),
.mac_axis_tx(axis_qsfp_tx),
.mac_axis_tx_cpl(axis_qsfp_tx_cpl),
.mac_rx_clk(qsfp_rx_clk),
.mac_rx_rst(qsfp_rx_rst),
.mac_axis_rx(axis_qsfp_rx)
);
endmodule
`resetall

View File

@@ -0,0 +1,71 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2020-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
TOPLEVEL_LANG = verilog
SIM ?= verilator
WAVES ?= 0
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
RTL_DIR = ../../rtl
LIB_DIR = ../../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
DUT = fpga_core
COCOTB_TEST_MODULES = test_$(DUT)
COCOTB_TOPLEVEL = test_$(DUT)
MODULE = $(COCOTB_TEST_MODULES)
TOPLEVEL = $(COCOTB_TOPLEVEL)
VERILOG_SOURCES += $(COCOTB_TOPLEVEL).sv
VERILOG_SOURCES += $(RTL_DIR)/$(DUT).sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# handle file list files
process_f_file = $(call process_f_files,$(addprefix $(dir $1),$(shell cat $1)))
process_f_files = $(foreach f,$1,$(if $(filter %.f,$f),$(call process_f_file,$f),$f))
uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $(lastword $1)),$(notdir $f)),$f,))) $(lastword $1))
VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
# module parameters
export PARAM_SIM := "1'b1"
export PARAM_VENDOR := "\"XILINX\""
export PARAM_FAMILY := "\"virtexuplus\""
# PTP configuration
export PARAM_PTP_TS_EN := 1
# AXI lite interface configuration (control)
export PARAM_AXIL_CTRL_DATA_W := 32
export PARAM_AXIL_CTRL_ADDR_W := 24
# MAC configuration
export PARAM_CFG_LOW_LATENCY := 1
export PARAM_COMBINED_MAC_PCS := 1
export PARAM_MAC_DATA_W := "64"
ifeq ($(SIM), icarus)
PLUSARGS += -fst
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-P $(COCOTB_TOPLEVEL).$(subst PARAM_,,$(v))=$($(v)))
else ifeq ($(SIM), verilator)
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-G$(subst PARAM_,,$(v))=$($(v)))
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
VERILATOR_TRACE = 1
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim

View File

@@ -0,0 +1 @@
../../lib/taxi/src/eth/tb/baser.py

View File

@@ -0,0 +1 @@
../../lib/taxi/src/cndm/tb/cndm.py

View File

@@ -0,0 +1,522 @@
#!/usr/bin/env python
# SPDX-License-Identifier: MIT
"""
Copyright (c) 2020-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
"""
import logging
import os
import sys
import pytest
import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, FallingEdge, Timer
from cocotbext.axi import AxiStreamBus
from cocotbext.eth import XgmiiFrame
from cocotbext.pcie.core import RootComplex
from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice
try:
from baser import BaseRSerdesSource, BaseRSerdesSink
import cndm
except ImportError:
# attempt import from current directory
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
try:
from baser import BaseRSerdesSource, BaseRSerdesSink
import cndm
finally:
del sys.path[0]
class TB:
def __init__(self, dut):
self.dut = dut
self.log = logging.getLogger("cocotb.tb")
self.log.setLevel(logging.DEBUG)
# Clocks
cocotb.start_soon(Clock(dut.clk_125mhz, 8, units="ns").start())
# PCIe
self.rc = RootComplex()
self.rc.max_payload_size = 0x1 # 256 bytes
self.rc.max_read_request_size = 0x2 # 512 bytes
self.dev = UltraScalePlusPcieDevice(
# configuration options
pcie_generation=3,
pcie_link_width=16,
user_clk_frequency=250e6,
alignment="dword",
cq_straddle=False,
cc_straddle=False,
rq_straddle=False,
rc_straddle=False,
rc_4tlp_straddle=False,
pf_count=1,
max_payload_size=1024,
enable_client_tag=True,
enable_extended_tag=True,
enable_parity=False,
enable_rx_msg_interface=False,
enable_sriov=False,
enable_extended_configuration=False,
pf0_msi_enable=True,
pf0_msi_count=32,
pf1_msi_enable=False,
pf1_msi_count=1,
pf2_msi_enable=False,
pf2_msi_count=1,
pf3_msi_enable=False,
pf3_msi_count=1,
pf0_msix_enable=False,
pf0_msix_table_size=31,
pf0_msix_table_bir=4,
pf0_msix_table_offset=0x00000000,
pf0_msix_pba_bir=4,
pf0_msix_pba_offset=0x00008000,
pf1_msix_enable=False,
pf1_msix_table_size=0,
pf1_msix_table_bir=0,
pf1_msix_table_offset=0x00000000,
pf1_msix_pba_bir=0,
pf1_msix_pba_offset=0x00000000,
pf2_msix_enable=False,
pf2_msix_table_size=0,
pf2_msix_table_bir=0,
pf2_msix_table_offset=0x00000000,
pf2_msix_pba_bir=0,
pf2_msix_pba_offset=0x00000000,
pf3_msix_enable=False,
pf3_msix_table_size=0,
pf3_msix_table_bir=0,
pf3_msix_table_offset=0x00000000,
pf3_msix_pba_bir=0,
pf3_msix_pba_offset=0x00000000,
# signals
# Clock and Reset Interface
user_clk=dut.pcie_clk,
user_reset=dut.pcie_rst,
# user_lnk_up
# sys_clk
# sys_clk_gt
# sys_reset
# phy_rdy_out
# Requester reQuest Interface
rq_bus=AxiStreamBus.from_entity(dut.m_axis_pcie_rq),
pcie_rq_seq_num0=dut.pcie_rq_seq_num0,
pcie_rq_seq_num_vld0=dut.pcie_rq_seq_num_vld0,
pcie_rq_seq_num1=dut.pcie_rq_seq_num1,
pcie_rq_seq_num_vld1=dut.pcie_rq_seq_num_vld1,
# pcie_rq_tag0
# pcie_rq_tag1
# pcie_rq_tag_av
# pcie_rq_tag_vld0
# pcie_rq_tag_vld1
# Requester Completion Interface
rc_bus=AxiStreamBus.from_entity(dut.s_axis_pcie_rc),
# Completer reQuest Interface
cq_bus=AxiStreamBus.from_entity(dut.s_axis_pcie_cq),
# pcie_cq_np_req
# pcie_cq_np_req_count
# Completer Completion Interface
cc_bus=AxiStreamBus.from_entity(dut.m_axis_pcie_cc),
# Transmit Flow Control Interface
# pcie_tfc_nph_av=dut.pcie_tfc_nph_av,
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
# Configuration Management Interface
cfg_mgmt_addr=dut.cfg_mgmt_addr,
cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
cfg_mgmt_write=dut.cfg_mgmt_write,
cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
cfg_mgmt_read=dut.cfg_mgmt_read,
cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
# cfg_mgmt_debug_access
# Configuration Status Interface
# cfg_phy_link_down
# cfg_phy_link_status
# cfg_negotiated_width
# cfg_current_speed
cfg_max_payload=dut.cfg_max_payload,
cfg_max_read_req=dut.cfg_max_read_req,
# cfg_function_status
# cfg_vf_status
# cfg_function_power_state
# cfg_vf_power_state
# cfg_link_power_state
# cfg_err_cor_out
# cfg_err_nonfatal_out
# cfg_err_fatal_out
# cfg_local_error_out
# cfg_local_error_valid
# cfg_rx_pm_state
# cfg_tx_pm_state
# cfg_ltssm_state
cfg_rcb_status=dut.cfg_rcb_status,
# cfg_obff_enable
# cfg_pl_status_change
# cfg_tph_requester_enable
# cfg_tph_st_mode
# cfg_vf_tph_requester_enable
# cfg_vf_tph_st_mode
# Configuration Received Message Interface
# cfg_msg_received
# cfg_msg_received_data
# cfg_msg_received_type
# Configuration Transmit Message Interface
# cfg_msg_transmit
# cfg_msg_transmit_type
# cfg_msg_transmit_data
# cfg_msg_transmit_done
# Configuration Flow Control Interface
cfg_fc_ph=dut.cfg_fc_ph,
cfg_fc_pd=dut.cfg_fc_pd,
cfg_fc_nph=dut.cfg_fc_nph,
cfg_fc_npd=dut.cfg_fc_npd,
cfg_fc_cplh=dut.cfg_fc_cplh,
cfg_fc_cpld=dut.cfg_fc_cpld,
cfg_fc_sel=dut.cfg_fc_sel,
# Configuration Control Interface
# cfg_hot_reset_in
# cfg_hot_reset_out
# cfg_config_space_enable
# cfg_dsn
# cfg_bus_number
# cfg_ds_port_number
# cfg_ds_bus_number
# cfg_ds_device_number
# cfg_ds_function_number
# cfg_power_state_change_ack
# cfg_power_state_change_interrupt
# cfg_err_cor_in=dut.status_error_cor,
# cfg_err_uncor_in=dut.status_error_uncor,
# cfg_flr_in_process
# cfg_flr_done
# cfg_vf_flr_in_process
# cfg_vf_flr_func_num
# cfg_vf_flr_done
# cfg_pm_aspm_l1_entry_reject
# cfg_pm_aspm_tx_l0s_entry_disable
# cfg_req_pm_transition_l23_ready
# cfg_link_training_enable
# Configuration Interrupt Controller Interface
# cfg_interrupt_int
# cfg_interrupt_sent
# cfg_interrupt_pending
cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable,
cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable,
cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update,
cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data,
cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select,
cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int,
cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status,
cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable,
cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num,
cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent,
cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail,
# cfg_interrupt_msix_enable=dut.cfg_interrupt_msix_enable,
# cfg_interrupt_msix_mask=dut.cfg_interrupt_msix_mask,
# cfg_interrupt_msix_vf_enable=dut.cfg_interrupt_msix_vf_enable,
# cfg_interrupt_msix_vf_mask=dut.cfg_interrupt_msix_vf_mask,
# cfg_interrupt_msix_address=dut.cfg_interrupt_msix_address,
# cfg_interrupt_msix_data=dut.cfg_interrupt_msix_data,
# cfg_interrupt_msix_int=dut.cfg_interrupt_msix_int,
# cfg_interrupt_msix_vec_pending=dut.cfg_interrupt_msix_vec_pending,
# cfg_interrupt_msix_vec_pending_status=dut.cfg_interrupt_msix_vec_pending_status,
# cfg_interrupt_msix_sent=dut.cfg_interrupt_msix_sent,
# cfg_interrupt_msix_fail=dut.cfg_interrupt_msix_fail,
cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr,
cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present,
cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type,
cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag,
cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number,
# Configuration Extend Interface
# cfg_ext_read_received
# cfg_ext_write_received
# cfg_ext_register_number
# cfg_ext_function_number
# cfg_ext_write_data
# cfg_ext_write_byte_enable
# cfg_ext_read_data
# cfg_ext_read_data_valid
)
# self.dev.log.setLevel(logging.DEBUG)
self.rc.make_port().connect(self.dev)
self.dev.functions[0].configure_bar(0, 2**int(dut.uut.cndm_inst.axil_ctrl_bar.ADDR_W))
# Ethernet
cocotb.start_soon(Clock(dut.qsfp_0_mgt_refclk_p, 6.206, units="ns").start())
self.qsfp_sources = []
self.qsfp_sinks = []
for inst in dut.uut.gty_quad:
for ch in inst.mac_inst.ch:
gt_inst = ch.ch_inst.gt.gt_inst
if ch.ch_inst.DATA_W.value == 64:
if ch.ch_inst.CFG_LOW_LATENCY.value:
clk = 2.482
gbx_cfg = (66, [64, 65])
else:
clk = 2.56
gbx_cfg = None
else:
if ch.ch_inst.CFG_LOW_LATENCY.value:
clk = 3.102
gbx_cfg = (66, [64, 65])
else:
clk = 3.2
gbx_cfg = None
cocotb.start_soon(Clock(gt_inst.tx_clk, clk, units="ns").start())
cocotb.start_soon(Clock(gt_inst.rx_clk, clk, units="ns").start())
self.qsfp_sources.append(BaseRSerdesSource(
data=gt_inst.serdes_rx_data,
data_valid=gt_inst.serdes_rx_data_valid,
hdr=gt_inst.serdes_rx_hdr,
hdr_valid=gt_inst.serdes_rx_hdr_valid,
clock=gt_inst.rx_clk,
slip=gt_inst.serdes_rx_bitslip,
reverse=True,
gbx_cfg=gbx_cfg
))
self.qsfp_sinks.append(BaseRSerdesSink(
data=gt_inst.serdes_tx_data,
data_valid=gt_inst.serdes_tx_data_valid,
hdr=gt_inst.serdes_tx_hdr,
hdr_valid=gt_inst.serdes_tx_hdr_valid,
gbx_sync=gt_inst.serdes_tx_gbx_sync,
clock=gt_inst.tx_clk,
reverse=True,
gbx_cfg=gbx_cfg
))
dut.user_sw.setimmediatevalue(0)
dut.qsfp_0_modprs_l.setimmediatevalue(0)
dut.qsfp_1_modprs_l.setimmediatevalue(0)
dut.qsfp_int_l.setimmediatevalue(0)
self.loopback_enable = False
cocotb.start_soon(self._run_loopback())
async def init(self):
self.dut.rst_125mhz.setimmediatevalue(0)
await FallingEdge(self.dut.pcie_rst)
await Timer(100, 'ns')
for k in range(10):
await RisingEdge(self.dut.clk_125mhz)
self.dut.rst_125mhz.value = 1
for k in range(10):
await RisingEdge(self.dut.clk_125mhz)
self.dut.rst_125mhz.value = 0
for k in range(10):
await RisingEdge(self.dut.clk_125mhz)
await self.rc.enumerate()
async def _run_loopback(self):
while True:
await RisingEdge(self.dut.pcie_clk)
if self.loopback_enable:
for src, snk in zip(self.qsfp_sources, self.qsfp_sinks):
while not snk.empty():
await src.send(await snk.recv())
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("Init driver model")
driver = cndm.Driver()
await driver.init_pcie_dev(tb.rc.find_device(tb.dev.functions[0].pcie_id))
tb.log.info("Init complete")
tb.log.info("Wait for block lock")
for k in range(1200):
await RisingEdge(tb.dut.clk_125mhz)
for snk in tb.qsfp_sinks:
snk.clear()
tb.log.info("Send and receive single packet on each port")
for k in range(len(driver.ports)):
data = f"Corundum rocks on port {k}!".encode('ascii')
await driver.ports[k].start_xmit(data)
pkt = await tb.qsfp_sinks[k].recv()
tb.log.info("Got TX packet: %s", pkt)
assert pkt.get_payload() == data.ljust(60, b'\x00')
assert pkt.check_fcs()
await tb.qsfp_sources[k].send(pkt)
pkt = await driver.ports[k].recv()
tb.log.info("Got RX packet: %s", pkt)
assert bytes(pkt) == data.ljust(60, b'\x00')
tb.log.info("Multiple small packets")
count = 64
pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)]
tb.loopback_enable = True
for p in pkts:
await driver.ports[0].start_xmit(p)
for k in range(count):
pkt = await driver.ports[0].recv()
tb.log.info("Got RX packet: %s", pkt)
assert bytes(pkt) == pkts[k].ljust(60, b'\x00')
tb.loopback_enable = False
tb.log.info("Multiple large packets")
count = 64
pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)]
tb.loopback_enable = True
for p in pkts:
await driver.ports[0].start_xmit(p)
for k in range(count):
pkt = await driver.ports[0].recv()
tb.log.info("Got RX packet: %s", pkt)
assert bytes(pkt) == pkts[k].ljust(60, b'\x00')
tb.loopback_enable = False
await RisingEdge(dut.clk_125mhz)
await RisingEdge(dut.clk_125mhz)
# cocotb-test
tests_dir = os.path.abspath(os.path.dirname(__file__))
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
lib_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'lib'))
taxi_src_dir = os.path.abspath(os.path.join(lib_dir, 'taxi', 'src'))
def process_f_files(files):
lst = {}
for f in files:
if f[-2:].lower() == '.f':
with open(f, 'r') as fp:
l = fp.read().split()
for f in process_f_files([os.path.join(os.path.dirname(f), x) for x in l]):
lst[os.path.basename(f)] = f
else:
lst[os.path.basename(f)] = f
return list(lst.values())
@pytest.mark.parametrize("mac_data_w", [32, 64])
def test_fpga_core(request, mac_data_w):
dut = "fpga_core"
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = module
verilog_sources = [
os.path.join(tests_dir, f"{toplevel}.sv"),
os.path.join(rtl_dir, f"{dut}.sv"),
os.path.join(taxi_src_dir, "cndm", "rtl", "cndm_micro_pcie_us.f"),
os.path.join(taxi_src_dir, "eth", "rtl", "us", "taxi_eth_mac_25g_us.f"),
os.path.join(taxi_src_dir, "axis", "rtl", "taxi_axis_async_fifo.f"),
os.path.join(taxi_src_dir, "sync", "rtl", "taxi_sync_reset.sv"),
os.path.join(taxi_src_dir, "sync", "rtl", "taxi_sync_signal.sv"),
os.path.join(taxi_src_dir, "io", "rtl", "taxi_debounce_switch.sv"),
os.path.join(taxi_src_dir, "pyrite", "rtl", "pyrite_pcie_us_vpd_qspi.f"),
]
verilog_sources = process_f_files(verilog_sources)
parameters = {}
parameters['SIM'] = "1'b1"
parameters['VENDOR'] = "\"XILINX\""
parameters['FAMILY'] = "\"virtexuplus\""
# PTP configuration
parameters['PTP_TS_EN'] = 1
# AXI lite interface configuration (control)
parameters['AXIL_CTRL_DATA_W'] = 32
parameters['AXIL_CTRL_ADDR_W'] = 24
# MAC configuration
parameters['CFG_LOW_LATENCY'] = 1
parameters['COMBINED_MAC_PCS'] = 1
parameters['MAC_DATA_W'] = mac_data_w
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
simulator="verilator",
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
)

View File

@@ -0,0 +1,328 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA core logic testbench
*/
module test_fpga_core #
(
/* verilator lint_off WIDTHTRUNC */
parameter logic SIM = 1'b0,
parameter string VENDOR = "XILINX",
parameter string FAMILY = "virtexuplus",
// FW ID
parameter FPGA_ID = 32'h4B39093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h4144_9003,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// PCIe interface configuration
parameter AXIS_PCIE_DATA_W = 512,
parameter AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161,
parameter AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137,
parameter AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183,
parameter AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
/* verilator lint_on WIDTHTRUNC */
)
();
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
logic clk_125mhz;
logic rst_125mhz;
logic [1:0] user_led_g;
logic user_led_r;
logic [1:0] front_led;
logic [1:0] user_sw;
logic qsfp_0_mgt_refclk_p;
logic qsfp_0_mgt_refclk_n;
logic qsfp_0_modprs_l;
logic qsfp_0_sel_l;
// logic qsfp_1_mgt_refclk_p;
// logic qsfp_1_mgt_refclk_n;
logic qsfp_1_modprs_l;
logic qsfp_1_sel_l;
logic qsfp_reset_l;
logic qsfp_int_l;
logic pcie_clk;
logic pcie_rst;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CQ_USER_W)
) s_axis_pcie_cq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CC_USER_W)
) m_axis_pcie_cc();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RQ_USER_W)
) m_axis_pcie_rq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RC_USER_W)
) s_axis_pcie_rc();
logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0;
logic pcie_rq_seq_num_vld0;
logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1;
logic pcie_rq_seq_num_vld1;
logic [2:0] cfg_max_payload;
logic [2:0] cfg_max_read_req;
logic [3:0] cfg_rcb_status;
logic [9:0] cfg_mgmt_addr;
logic [7:0] cfg_mgmt_function_number;
logic cfg_mgmt_write;
logic [31:0] cfg_mgmt_write_data;
logic [3:0] cfg_mgmt_byte_enable;
logic cfg_mgmt_read;
logic [31:0] cfg_mgmt_read_data;
logic cfg_mgmt_read_write_done;
logic [7:0] cfg_fc_ph;
logic [11:0] cfg_fc_pd;
logic [7:0] cfg_fc_nph;
logic [11:0] cfg_fc_npd;
logic [7:0] cfg_fc_cplh;
logic [11:0] cfg_fc_cpld;
logic [2:0] cfg_fc_sel;
logic cfg_ext_read_received;
logic cfg_ext_write_received;
logic [9:0] cfg_ext_register_number;
logic [7:0] cfg_ext_function_number;
logic [31:0] cfg_ext_write_data;
logic [3:0] cfg_ext_write_byte_enable;
logic [31:0] cfg_ext_read_data;
logic cfg_ext_read_data_valid;
logic [3:0] cfg_interrupt_msi_enable;
logic [11:0] cfg_interrupt_msi_mmenable;
logic cfg_interrupt_msi_mask_update;
logic [31:0] cfg_interrupt_msi_data;
logic [1:0] cfg_interrupt_msi_select;
logic [31:0] cfg_interrupt_msi_int;
logic [31:0] cfg_interrupt_msi_pending_status;
logic cfg_interrupt_msi_pending_status_data_enable;
logic [1:0] cfg_interrupt_msi_pending_status_function_num;
logic cfg_interrupt_msi_sent;
logic cfg_interrupt_msi_fail;
logic [2:0] cfg_interrupt_msi_attr;
logic cfg_interrupt_msi_tph_present;
logic [1:0] cfg_interrupt_msi_tph_type;
logic [7:0] cfg_interrupt_msi_tph_st_tag;
logic [7:0] cfg_interrupt_msi_function_number;
logic fpga_boot;
logic qspi_clk;
logic [3:0] qspi_0_dq_i;
logic [3:0] qspi_0_dq_o;
logic [3:0] qspi_0_dq_oe;
logic qspi_0_cs;
logic [3:0] qspi_1_dq_i;
logic [3:0] qspi_1_dq_o;
logic [3:0] qspi_1_dq_oe;
logic qspi_1_cs;
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
)
uut (
/*
* Clock: 125MHz
* Synchronous reset
*/
.clk_125mhz(clk_125mhz),
.rst_125mhz(rst_125mhz),
/*
* GPIO
*/
.user_led_g(user_led_g),
.user_led_r(user_led_r),
.front_led(front_led),
.user_sw(user_sw),
/*
* Ethernet: QSFP28
*/
.qsfp_0_tx_p(),
.qsfp_0_tx_n(),
.qsfp_0_rx_p('{4{1'b0}}),
.qsfp_0_rx_n('{4{1'b0}}),
.qsfp_0_mgt_refclk_p(qsfp_0_mgt_refclk_p),
.qsfp_0_mgt_refclk_n(qsfp_0_mgt_refclk_n),
.qsfp_0_modprs_l(qsfp_0_modprs_l),
.qsfp_0_sel_l(qsfp_0_sel_l),
.qsfp_1_tx_p(),
.qsfp_1_tx_n(),
.qsfp_1_rx_p('{4{1'b0}}),
.qsfp_1_rx_n('{4{1'b0}}),
// .qsfp_1_mgt_refclk_p(qsfp_1_mgt_refclk_p),
// .qsfp_1_mgt_refclk_n(qsfp_1_mgt_refclk_n),
.qsfp_1_modprs_l(qsfp_1_modprs_l),
.qsfp_1_sel_l(qsfp_1_sel_l),
.qsfp_reset_l(qsfp_reset_l),
.qsfp_int_l(qsfp_int_l),
/*
* PCIe
*/
.pcie_clk(pcie_clk),
.pcie_rst(pcie_rst),
.s_axis_pcie_cq(s_axis_pcie_cq),
.m_axis_pcie_cc(m_axis_pcie_cc),
.m_axis_pcie_rq(m_axis_pcie_rq),
.s_axis_pcie_rc(s_axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk),
.qspi_0_dq_i(qspi_0_dq_i),
.qspi_0_dq_o(qspi_0_dq_o),
.qspi_0_dq_oe(qspi_0_dq_oe),
.qspi_0_cs(qspi_0_cs),
.qspi_1_dq_i(qspi_1_dq_i),
.qspi_1_dq_o(qspi_1_dq_o),
.qspi_1_dq_oe(qspi_1_dq_oe),
.qspi_1_cs(qspi_1_cs)
);
endmodule
`resetall

View File

@@ -25,8 +25,8 @@ This design targets the Alibaba AS02MC04 FPGA board.
Run `make` in the appropriate `fpga*` subdirectory to build the bitstream. Ensure that the Xilinx Vivado toolchain components are in PATH.
On the host system, run `make` in `modules/cndm_proto` to build the driver. Ensure that the headers for the running kernel are installed, otherwise the driver cannot be compiled.
On the host system, run `make` in `modules/cndm` to build the driver. Ensure that the headers for the running kernel are installed, otherwise the driver cannot be compiled.
## How to test
Run `make program` to program the board with Vivado. Then, reboot the machine to re-enumerate the PCIe bus. Finally, load the driver on the host system with `insmod cndm_proto.ko`. Check `dmesg` for output from driver initialization. Run `cndm_proto_ddcmd.sh =p` to enable all debug messages.
Run `make program` to program the board with Vivado. Then, reboot the machine to re-enumerate the PCIe bus. Finally, load the driver on the host system with `insmod cndm.ko`. Check `dmesg` for output from driver initialization. Run `cndm_ddcmd.sh =p` to enable all debug messages.

View File

@@ -18,11 +18,12 @@ TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/corundum/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga.xdc

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
@@ -8,11 +8,120 @@
set params [dict create]
# 10G MAC configuration
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4A63093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x1ded]
set board_device_id [expr 0x0009]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {

View File

@@ -23,6 +23,7 @@ SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga.xdc

View File

@@ -1,6 +1,6 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
@@ -8,11 +8,120 @@
set params [dict create]
# 10G MAC configuration
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4A63093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x1ded]
set board_device_id [expr 0x0009]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {

View File

@@ -10,7 +10,8 @@ set_property -dict [list \
CONFIG.extended_tag_field {true} \
CONFIG.pf0_dev_cap_max_payload {1024_bytes} \
CONFIG.axisten_freq {250} \
CONFIG.PF0_CLASS_CODE {058000} \
CONFIG.PF0_Use_Class_Code_Lookup_Assistant {false} \
CONFIG.PF0_CLASS_CODE {020000} \
CONFIG.PF0_DEVICE_ID {C001} \
CONFIG.PF0_SUBSYSTEM_ID {0009} \
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {1ded} \
@@ -21,6 +22,7 @@ set_property -dict [list \
CONFIG.pf0_msi_enabled {true} \
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
CONFIG.en_msi_per_vec_masking {true} \
CONFIG.legacy_ext_pcie_cfg_space_enabled {true} \
CONFIG.vendor_id {1234} \
CONFIG.mode_selection {Advanced} \
CONFIG.en_gt_selection {true} \

View File

@@ -23,9 +23,25 @@ module fpga #
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "kintexuplus",
// FW ID
parameter FPGA_ID = 32'h4A63093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h1ded_0009,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// 10G/25G MAC configuration
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
@@ -74,6 +90,8 @@ module fpga #
);
// Clock and reset
wire pcie_user_clk;
wire pcie_user_rst;
wire clk_100mhz_ibufg;
@@ -189,6 +207,175 @@ sync_reset_125mhz_inst (
.out(rst_125mhz_int)
);
// Flash
wire qspi_clk_int;
wire [3:0] qspi_dq_int;
wire [3:0] qspi_dq_i_int;
wire [3:0] qspi_dq_o_int;
wire [3:0] qspi_dq_oe_int;
wire qspi_cs_int;
reg qspi_clk_reg;
reg [3:0] qspi_dq_o_reg;
reg [3:0] qspi_dq_oe_reg;
reg qspi_cs_reg;
always_ff @(posedge pcie_user_clk) begin
qspi_clk_reg <= qspi_clk_int;
qspi_dq_o_reg <= qspi_dq_o_int;
qspi_dq_oe_reg <= qspi_dq_oe_int;
qspi_cs_reg <= qspi_cs_int;
end
taxi_sync_signal #(
.WIDTH(8),
.N(2)
)
flash_sync_inst (
.clk(pcie_user_clk),
.in({qspi_dq_int}),
.out({qspi_dq_i_int})
);
STARTUPE3
startupe3_inst (
.CFGCLK(),
.CFGMCLK(),
.DI(qspi_dq_int),
.DO(qspi_dq_o_reg),
.DTS(~qspi_dq_oe_reg),
.EOS(),
.FCSBO(qspi_cs_reg),
.FCSBTS(1'b0),
.GSR(1'b0),
.GTS(1'b0),
.KEYCLEARB(1'b1),
.PACK(1'b0),
.PREQ(),
.USRCCLKO(qspi_clk_reg),
.USRCCLKTS(1'b0),
.USRDONEO(1'b0),
.USRDONETS(1'b1)
);
// FPGA boot
wire fpga_boot;
wire fpga_boot_sync;
taxi_sync_signal #(
.WIDTH(1),
.N(2)
)
fpga_boot_sync_inst (
.clk(clk_125mhz_int),
.in({fpga_boot}),
.out({fpga_boot_sync})
);
wire icap_avail;
logic [2:0] icap_state_reg = 0;
logic icap_csib_reg = 1'b1;
logic icap_rdwrb_reg = 1'b0;
logic [31:0] icap_di_reg = 32'hffffffff;
wire [31:0] icap_di_rev;
assign icap_di_rev[ 7] = icap_di_reg[ 0];
assign icap_di_rev[ 6] = icap_di_reg[ 1];
assign icap_di_rev[ 5] = icap_di_reg[ 2];
assign icap_di_rev[ 4] = icap_di_reg[ 3];
assign icap_di_rev[ 3] = icap_di_reg[ 4];
assign icap_di_rev[ 2] = icap_di_reg[ 5];
assign icap_di_rev[ 1] = icap_di_reg[ 6];
assign icap_di_rev[ 0] = icap_di_reg[ 7];
assign icap_di_rev[15] = icap_di_reg[ 8];
assign icap_di_rev[14] = icap_di_reg[ 9];
assign icap_di_rev[13] = icap_di_reg[10];
assign icap_di_rev[12] = icap_di_reg[11];
assign icap_di_rev[11] = icap_di_reg[12];
assign icap_di_rev[10] = icap_di_reg[13];
assign icap_di_rev[ 9] = icap_di_reg[14];
assign icap_di_rev[ 8] = icap_di_reg[15];
assign icap_di_rev[23] = icap_di_reg[16];
assign icap_di_rev[22] = icap_di_reg[17];
assign icap_di_rev[21] = icap_di_reg[18];
assign icap_di_rev[20] = icap_di_reg[19];
assign icap_di_rev[19] = icap_di_reg[20];
assign icap_di_rev[18] = icap_di_reg[21];
assign icap_di_rev[17] = icap_di_reg[22];
assign icap_di_rev[16] = icap_di_reg[23];
assign icap_di_rev[31] = icap_di_reg[24];
assign icap_di_rev[30] = icap_di_reg[25];
assign icap_di_rev[29] = icap_di_reg[26];
assign icap_di_rev[28] = icap_di_reg[27];
assign icap_di_rev[27] = icap_di_reg[28];
assign icap_di_rev[26] = icap_di_reg[29];
assign icap_di_rev[25] = icap_di_reg[30];
assign icap_di_rev[24] = icap_di_reg[31];
always_ff @(posedge clk_125mhz_int) begin
case (icap_state_reg)
0: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b1;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
if (fpga_boot_sync && icap_avail) begin
icap_state_reg <= 1;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
end
end
1: begin
icap_state_reg <= 2;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hAA995566; // sync word
end
2: begin
icap_state_reg <= 3;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
3: begin
icap_state_reg <= 4;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h30008001; // write 1 word to CMD
end
4: begin
icap_state_reg <= 5;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h0000000F; // IPROG
end
5: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
endcase
end
ICAPE3
icape3_inst (
.AVAIL(icap_avail),
.CLK(clk_125mhz_int),
.CSIB(icap_csib_reg),
.I(icap_di_rev),
.O(),
.PRDONE(),
.PRERROR(),
.RDWRB(icap_rdwrb_reg)
);
// PCIe
localparam AXIS_PCIE_DATA_W = 256;
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
@@ -201,12 +388,9 @@ localparam RC_STRADDLE = 1'b0; // AXIS_PCIE_DATA_W >= 256;
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
localparam RQ_SEQ_NUM_EN = 1;
localparam PCIE_TAG_CNT = 64;
localparam PCIE_TAG_CNT = AXIS_PCIE_RQ_USER_W == 60 ? 64 : 256;
localparam BAR0_APERTURE = 24;
logic pcie_user_clk;
logic pcie_user_rst;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
@@ -265,6 +449,15 @@ wire [7:0] cfg_fc_cplh;
wire [11:0] cfg_fc_cpld;
wire [2:0] cfg_fc_sel;
wire cfg_ext_read_received;
wire cfg_ext_write_received;
wire [9:0] cfg_ext_register_number;
wire [7:0] cfg_ext_function_number;
wire [31:0] cfg_ext_write_data;
wire [3:0] cfg_ext_write_byte_enable;
wire [31:0] cfg_ext_read_data;
wire cfg_ext_read_data_valid;
// wire [3:0] cfg_interrupt_msix_enable;
// wire [3:0] cfg_interrupt_msix_mask;
// wire [251:0] cfg_interrupt_msix_vf_enable;
@@ -437,6 +630,15 @@ pcie4_uscale_plus_inst (
.cfg_link_training_enable(1'b1),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_int(4'd0),
.cfg_interrupt_pending(4'd0),
.cfg_interrupt_sent(),
@@ -493,7 +695,28 @@ fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
@@ -565,6 +788,15 @@ core_inst (
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
@@ -593,7 +825,17 @@ core_inst (
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number)
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk_int),
.qspi_dq_i(qspi_dq_i_int),
.qspi_dq_o(qspi_dq_o_int),
.qspi_dq_oe(qspi_dq_oe_int),
.qspi_cs(qspi_cs_int)
);
endmodule

View File

@@ -23,10 +23,28 @@ module fpga_core #
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "kintexuplus",
parameter RQ_SEQ_NUM_W = 6,
// FW ID
parameter FPGA_ID = 32'h4A63093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h1ded_0009,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// 10G/25G MAC configuration
// PCIe interface configuration
parameter RQ_SEQ_NUM_W = 6,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
@@ -36,89 +54,163 @@ module fpga_core #
* Clock: 125MHz
* Synchronous reset
*/
input wire logic clk_125mhz,
input wire logic rst_125mhz,
input wire logic clk_125mhz,
input wire logic rst_125mhz,
/*
* GPIO
*/
output wire logic sfp_led[2],
output wire logic [3:0] led,
output wire logic led_r,
output wire logic led_g,
output wire logic led_hb,
output wire logic sfp_led[2],
output wire logic [3:0] led,
output wire logic led_r,
output wire logic led_g,
output wire logic led_hb,
/*
* Ethernet: SFP+
*/
input wire logic sfp_rx_p[2],
input wire logic sfp_rx_n[2],
output wire logic sfp_tx_p[2],
output wire logic sfp_tx_n[2],
input wire logic sfp_mgt_refclk_p,
input wire logic sfp_mgt_refclk_n,
output wire logic sfp_mgt_refclk_out,
input wire logic [1:0] sfp_npres,
input wire logic [1:0] sfp_tx_fault,
input wire logic [1:0] sfp_los,
input wire logic sfp_rx_p[2],
input wire logic sfp_rx_n[2],
output wire logic sfp_tx_p[2],
output wire logic sfp_tx_n[2],
input wire logic sfp_mgt_refclk_p,
input wire logic sfp_mgt_refclk_n,
output wire logic sfp_mgt_refclk_out,
input wire logic [1:0] sfp_npres,
input wire logic [1:0] sfp_tx_fault,
input wire logic [1:0] sfp_los,
/*
* PCIe
*/
input wire logic pcie_clk,
input wire logic pcie_rst,
taxi_axis_if.snk s_axis_pcie_cq,
taxi_axis_if.src m_axis_pcie_cc,
taxi_axis_if.src m_axis_pcie_rq,
taxi_axis_if.snk s_axis_pcie_rc,
input wire logic pcie_clk,
input wire logic pcie_rst,
taxi_axis_if.snk s_axis_pcie_cq,
taxi_axis_if.src m_axis_pcie_cc,
taxi_axis_if.src m_axis_pcie_rq,
taxi_axis_if.snk s_axis_pcie_rc,
input wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0,
input wire pcie_rq_seq_num_vld0,
input wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1,
input wire pcie_rq_seq_num_vld1,
input wire logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0,
input wire logic pcie_rq_seq_num_vld0,
input wire logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1,
input wire logic pcie_rq_seq_num_vld1,
input wire [2:0] cfg_max_payload,
input wire [2:0] cfg_max_read_req,
input wire [3:0] cfg_rcb_status,
input wire logic [2:0] cfg_max_payload,
input wire logic [2:0] cfg_max_read_req,
input wire logic [3:0] cfg_rcb_status,
output wire [9:0] cfg_mgmt_addr,
output wire [7:0] cfg_mgmt_function_number,
output wire cfg_mgmt_write,
output wire [31:0] cfg_mgmt_write_data,
output wire [3:0] cfg_mgmt_byte_enable,
output wire cfg_mgmt_read,
output wire [31:0] cfg_mgmt_read_data,
input wire cfg_mgmt_read_write_done,
output wire logic [9:0] cfg_mgmt_addr,
output wire logic [7:0] cfg_mgmt_function_number,
output wire logic cfg_mgmt_write,
output wire logic [31:0] cfg_mgmt_write_data,
output wire logic [3:0] cfg_mgmt_byte_enable,
output wire logic cfg_mgmt_read,
output wire logic [31:0] cfg_mgmt_read_data,
input wire logic cfg_mgmt_read_write_done,
input wire [7:0] cfg_fc_ph,
input wire [11:0] cfg_fc_pd,
input wire [7:0] cfg_fc_nph,
input wire [11:0] cfg_fc_npd,
input wire [7:0] cfg_fc_cplh,
input wire [11:0] cfg_fc_cpld,
output wire [2:0] cfg_fc_sel,
input wire logic [7:0] cfg_fc_ph,
input wire logic [11:0] cfg_fc_pd,
input wire logic [7:0] cfg_fc_nph,
input wire logic [11:0] cfg_fc_npd,
input wire logic [7:0] cfg_fc_cplh,
input wire logic [11:0] cfg_fc_cpld,
output wire logic [2:0] cfg_fc_sel,
input wire [3:0] cfg_interrupt_msi_enable,
input wire [11:0] cfg_interrupt_msi_mmenable,
input wire cfg_interrupt_msi_mask_update,
input wire [31:0] cfg_interrupt_msi_data,
output wire [1:0] cfg_interrupt_msi_select,
output wire [31:0] cfg_interrupt_msi_int,
output wire [31:0] cfg_interrupt_msi_pending_status,
output wire cfg_interrupt_msi_pending_status_data_enable,
output wire [1:0] cfg_interrupt_msi_pending_status_function_num,
input wire cfg_interrupt_msi_sent,
input wire cfg_interrupt_msi_fail,
output wire [2:0] cfg_interrupt_msi_attr,
output wire cfg_interrupt_msi_tph_present,
output wire [1:0] cfg_interrupt_msi_tph_type,
output wire [7:0] cfg_interrupt_msi_tph_st_tag,
output wire [7:0] cfg_interrupt_msi_function_number
input wire logic cfg_ext_read_received,
input wire logic cfg_ext_write_received,
input wire logic [9:0] cfg_ext_register_number,
input wire logic [7:0] cfg_ext_function_number,
input wire logic [31:0] cfg_ext_write_data,
input wire logic [3:0] cfg_ext_write_byte_enable,
output wire logic [31:0] cfg_ext_read_data,
output wire logic cfg_ext_read_data_valid,
input wire logic [3:0] cfg_interrupt_msi_enable,
input wire logic [11:0] cfg_interrupt_msi_mmenable,
input wire logic cfg_interrupt_msi_mask_update,
input wire logic [31:0] cfg_interrupt_msi_data,
output wire logic [1:0] cfg_interrupt_msi_select,
output wire logic [31:0] cfg_interrupt_msi_int,
output wire logic [31:0] cfg_interrupt_msi_pending_status,
output wire logic cfg_interrupt_msi_pending_status_data_enable,
output wire logic [1:0] cfg_interrupt_msi_pending_status_function_num,
input wire logic cfg_interrupt_msi_sent,
input wire logic cfg_interrupt_msi_fail,
output wire logic [2:0] cfg_interrupt_msi_attr,
output wire logic cfg_interrupt_msi_tph_present,
output wire logic [1:0] cfg_interrupt_msi_tph_type,
output wire logic [7:0] cfg_interrupt_msi_tph_st_tag,
output wire logic [7:0] cfg_interrupt_msi_function_number,
/*
* QSPI flash
*/
output wire logic fpga_boot,
output wire logic qspi_clk,
input wire logic [3:0] qspi_dq_i,
output wire logic [3:0] qspi_dq_o,
output wire logic [3:0] qspi_dq_oe,
output wire logic qspi_cs
);
localparam logic PTP_TS_FMT_TOD = 1'b0;
localparam PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 48;
// flashing via PCIe VPD
pyrite_pcie_us_vpd_qspi #(
.VPD_CAP_ID(8'h03),
.VPD_CAP_OFFSET(8'hB0),
.VPD_CAP_NEXT(8'h00),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Flash
.FLASH_SEG_COUNT(2),
.FLASH_SEG_DEFAULT(1),
.FLASH_SEG_FALLBACK(0),
.FLASH_SEG0_SIZE(32'h00000000),
.FLASH_DATA_W(4),
.FLASH_DUAL_QSPI(1'b0)
)
pyrite_inst (
.clk(pcie_clk),
.rst(pcie_rst),
/*
* PCIe
*/
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk),
.qspi_0_dq_i(qspi_dq_i),
.qspi_0_dq_o(qspi_dq_o),
.qspi_0_dq_oe(qspi_dq_oe),
.qspi_0_cs(qspi_cs),
.qspi_1_dq_i('0),
.qspi_1_dq_o(),
.qspi_1_dq_oe(),
.qspi_1_cs()
);
// SFP+
wire sfp_tx_clk[2];
wire sfp_tx_rst[2];
@@ -462,12 +554,32 @@ cndm_micro_pcie_us #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration
.PORTS(2),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(1'b0),
.PTP_CLK_PER_NS_NUM(32),
.PTP_CLK_PER_NS_DENOM(5),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
.BAR0_APERTURE(24)
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W)
)
cndm_inst (
/*

View File

@@ -29,6 +29,7 @@ VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# handle file list files
process_f_file = $(call process_f_files,$(addprefix $(dir $1),$(shell cat $1)))
@@ -40,9 +41,17 @@ VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
export PARAM_SIM := "1'b1"
export PARAM_VENDOR := "\"XILINX\""
export PARAM_FAMILY := "\"kintexuplus\""
export PARAM_PTP_TS_EN := "1'b1"
export PARAM_CFG_LOW_LATENCY := "1'b1"
export PARAM_COMBINED_MAC_PCS := "1'b1"
# PTP configuration
export PARAM_PTP_TS_EN := 1
# AXI lite interface configuration (control)
export PARAM_AXIL_CTRL_DATA_W := 32
export PARAM_AXIL_CTRL_ADDR_W := 24
# MAC configuration
export PARAM_CFG_LOW_LATENCY := 1
export PARAM_COMBINED_MAC_PCS := 1
export PARAM_MAC_DATA_W := "64"
ifeq ($(SIM), icarus)

View File

@@ -45,6 +45,9 @@ class TB:
self.log = logging.getLogger("cocotb.tb")
self.log.setLevel(logging.DEBUG)
# Clocks
cocotb.start_soon(Clock(dut.clk_125mhz, 8, units="ns").start())
# PCIe
self.rc = RootComplex()
@@ -157,8 +160,8 @@ class TB:
# cfg_phy_link_status
# cfg_negotiated_width
# cfg_current_speed
# cfg_max_payload=dut.cfg_max_payload,
# cfg_max_read_req=dut.cfg_max_read_req,
cfg_max_payload=dut.cfg_max_payload,
cfg_max_read_req=dut.cfg_max_read_req,
# cfg_function_status
# cfg_vf_status
# cfg_function_power_state
@@ -172,7 +175,7 @@ class TB:
# cfg_rx_pm_state
# cfg_tx_pm_state
# cfg_ltssm_state
# cfg_rcb_status=dut.cfg_rcb_status,
cfg_rcb_status=dut.cfg_rcb_status,
# cfg_obff_enable
# cfg_pl_status_change
# cfg_tph_requester_enable
@@ -274,7 +277,6 @@ class TB:
self.dev.functions[0].configure_bar(0, 2**int(dut.uut.cndm_inst.axil_ctrl_bar.ADDR_W))
# Ethernet
cocotb.start_soon(Clock(dut.clk_125mhz, 8, units="ns").start())
cocotb.start_soon(Clock(dut.sfp_mgt_refclk_p, 6.4, units="ns").start())
self.sfp_sources = []
@@ -477,6 +479,7 @@ def test_fpga_core(request, mac_data_w):
os.path.join(taxi_src_dir, "axis", "rtl", "taxi_axis_async_fifo.f"),
os.path.join(taxi_src_dir, "sync", "rtl", "taxi_sync_reset.sv"),
os.path.join(taxi_src_dir, "sync", "rtl", "taxi_sync_signal.sv"),
os.path.join(taxi_src_dir, "pyrite", "rtl", "pyrite_pcie_us_vpd_qspi.f"),
]
verilog_sources = process_f_files(verilog_sources)
@@ -486,9 +489,17 @@ def test_fpga_core(request, mac_data_w):
parameters['SIM'] = "1'b1"
parameters['VENDOR'] = "\"XILINX\""
parameters['FAMILY'] = "\"kintexuplus\""
parameters['PTP_TS_EN'] = "1'b1"
parameters['CFG_LOW_LATENCY'] = "1'b1"
parameters['COMBINED_MAC_PCS'] = "1'b1"
# PTP configuration
parameters['PTP_TS_EN'] = 1
# AXI lite interface configuration (control)
parameters['AXIL_CTRL_DATA_W'] = 32
parameters['AXIL_CTRL_ADDR_W'] = 24
# MAC configuration
parameters['CFG_LOW_LATENCY'] = 1
parameters['COMBINED_MAC_PCS'] = 1
parameters['MAC_DATA_W'] = mac_data_w
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}

View File

@@ -21,14 +21,32 @@ module test_fpga_core #
parameter logic SIM = 1'b0,
parameter string VENDOR = "XILINX",
parameter string FAMILY = "kintexuplus",
// FW ID
parameter FPGA_ID = 32'h4A63093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h1ded_0009,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// PCIe interface configuration
parameter AXIS_PCIE_DATA_W = 256,
parameter AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161,
parameter AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137,
parameter AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183,
parameter AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// 10G/25G MAC configuration
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
@@ -117,6 +135,15 @@ logic [7:0] cfg_fc_cplh;
logic [11:0] cfg_fc_cpld;
logic [2:0] cfg_fc_sel;
logic cfg_ext_read_received;
logic cfg_ext_write_received;
logic [9:0] cfg_ext_register_number;
logic [7:0] cfg_ext_function_number;
logic [31:0] cfg_ext_write_data;
logic [3:0] cfg_ext_write_byte_enable;
logic [31:0] cfg_ext_read_data;
logic cfg_ext_read_data_valid;
logic [3:0] cfg_interrupt_msi_enable;
logic [11:0] cfg_interrupt_msi_mmenable;
logic cfg_interrupt_msi_mask_update;
@@ -134,14 +161,39 @@ logic [1:0] cfg_interrupt_msi_tph_type;
logic [7:0] cfg_interrupt_msi_tph_st_tag;
logic [7:0] cfg_interrupt_msi_function_number;
logic fpga_boot;
logic qspi_clk;
logic [3:0] qspi_dq_i;
logic [3:0] qspi_dq_o;
logic [3:0] qspi_dq_oe;
logic qspi_cs;
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
// 10G/25G MAC configuration
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
@@ -199,6 +251,15 @@ uut (
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
@@ -219,16 +280,26 @@ uut (
/*
* Ethernet: SFP+
*/
.sfp_rx_p(),
.sfp_rx_n(),
.sfp_tx_p('{2{1'b0}}),
.sfp_tx_n('{2{1'b0}}),
.sfp_rx_p('{2{1'b0}}),
.sfp_rx_n('{2{1'b0}}),
.sfp_tx_p(),
.sfp_tx_n(),
.sfp_mgt_refclk_p(sfp_mgt_refclk_p),
.sfp_mgt_refclk_n(sfp_mgt_refclk_n),
.sfp_mgt_refclk_out(sfp_mgt_refclk_out),
.sfp_npres(sfp_npres),
.sfp_tx_fault(sfp_tx_fault),
.sfp_los(sfp_los)
.sfp_los(sfp_los),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk),
.qspi_dq_i(qspi_dq_i),
.qspi_dq_o(qspi_dq_o),
.qspi_dq_oe(qspi_dq_oe),
.qspi_cs(qspi_cs)
);
endmodule

View File

@@ -0,0 +1,84 @@
# Corundum for Alveo
## Introduction
This design targets the Xilinx Alveo series.
* USB UART
* XFCP (3 Mbaud)
* DSFP/QSFP28
* 10GBASE-R or 25GBASE-R MACs via GTY transceivers
## Board details
* AU45N/SN1000
* FPGA: xcu26-vsva1365-2LV-e
* USB UART: FTDI FT4232H (DMB-2)
* PCIe: gen 3 x16 (~128 Gbps) or dual bifurcated gen 4 x8 (~256 Gbps)
* Reference oscillator: 161.1328125 MHz from Si5394
* 25GBASE-R PHY: Soft PCS with GTY transceivers
* AU50
* FPGA: xcu50-fsvh2104-2-e
* USB UART: FTDI FT4232H (3 via DMB-1)
* PCIe: gen 3 x16 (~128 Gbps) or dual bifurcated gen 4 x8 (~256 Gbps)
* Reference oscillator: 161.1328125 MHz from Si5394
* 25GBASE-R PHY: Soft PCS with GTY transceivers
* AU55C
* FPGA: xcu55c-fsvh2892-2L-e
* USB UART: FTDI FT4232H (2 onboard, all 3 via DMB-1)
* PCIe: gen 3 x16 (~128 Gbps) or dual bifurcated gen 4 x8 (~256 Gbps)
* Reference oscillator: 161.1328125 MHz from Si5394
* 25GBASE-R PHY: Soft PCS with GTY transceivers
* AU55N/C1100
* FPGA: xcu55n-fsvh2892-2L-e
* USB UART: FTDI FT4232H (2 onboard, all 3 via DMB-1)
* PCIe: gen 3 x16 (~128 Gbps) or dual bifurcated gen 4 x8 (~256 Gbps)
* Reference oscillator: 161.1328125 MHz from Si5394
* 25GBASE-R PHY: Soft PCS with GTY transceivers
* AU200
* FPGA: xcu200-fsgd2104-2-e
* USB UART: FTDI FT4232H
* PCIe: gen 3 x16 (~128 Gbps)
* Reference oscillator: 156.25 MHz from Si570
* 25GBASE-R PHY: Soft PCS with GTY transceivers
* AU250
* FPGA: xcu250-fsgd2104-2-e
* USB UART: FTDI FT4232H
* PCIe: gen 3 x16 (~128 Gbps)
* Reference oscillator: 156.25 MHz from Si570
* 25GBASE-R PHY: Soft PCS with GTY transceivers
* AU280
* FPGA: xcu280-fsvh2892-2L-e
* USB UART: FTDI FT4232H
* PCIe: gen 3 x16 (~128 Gbps) or dual bifurcated gen 4 x8 (~256 Gbps)
* Reference oscillator: 156.25 MHz from Si570
* 25GBASE-R PHY: Soft PCS with GTY transceivers
* VCU1525
* FPGA: xcvu9p-fsgd2104-2L-e
* USB UART: FTDI FT4232H
* PCIe: gen 3 x16 (~128 Gbps)
* Reference oscillator: 156.25 MHz from Si570
* 25GBASE-R PHY: Soft PCS with GTY transceivers
* X3/X3522
* FPGA: xcux35-vsva1365-3-e
* USB UART: FTDI FT4232H (DMB-2)
* PCIe: gen 4 x8 (~128 Gbps)
* Reference oscillator: 161.1328125 MHz from Si5394
* 25GBASE-R PHY: Soft PCS with GTY transceivers
## Licensing
* Toolchain
* Vivado Standard (enterprise license not required)
* IP
* No licensed vendor IP or 3rd party IP
## How to build
Run `make` in the appropriate `fpga*` subdirectory to build the bitstream. Ensure that the Xilinx Vivado toolchain components are in PATH.
On the host system, run `make` in `modules/cndm` to build the driver. Ensure that the headers for the running kernel are installed, otherwise the driver cannot be compiled.
## How to test
Run `make program` to program the board with Vivado. Then, reboot the machine to re-enumerate the PCIe bus. Finally, load the driver on the host system with `insmod cndm.ko`. Check `dmesg` for output from driver initialization. Run `cndm_ddcmd.sh =p` to enable all debug messages.

View File

@@ -0,0 +1,153 @@
# SPDX-License-Identifier: MIT
###################################################################
#
# Xilinx Vivado FPGA Makefile
#
# Copyright (c) 2016-2025 Alex Forencich
#
###################################################################
#
# Parameters:
# FPGA_TOP - Top module name
# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale)
# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e)
# SYN_FILES - list of source files
# INC_FILES - list of include files
# XDC_FILES - list of timing constraint files
# XCI_FILES - list of IP XCI files
# IP_TCL_FILES - list of IP TCL files (sourced during project creation)
# CONFIG_TCL_FILES - list of config TCL files (sourced before each build)
#
# Note: both SYN_FILES and INC_FILES support file list files. File list
# files are files with a .f extension that contain a list of additional
# files to include, one path relative to the .f file location per line.
# The .f files are processed recursively, and then the complete file list
# is de-duplicated, with later files in the list taking precedence.
#
# Example:
#
# FPGA_TOP = fpga
# FPGA_FAMILY = VirtexUltrascale
# FPGA_DEVICE = xcvu095-ffva2104-2-e
# SYN_FILES = rtl/fpga.v
# XDC_FILES = fpga.xdc
# XCI_FILES = ip/pcspma.xci
# include ../common/vivado.mk
#
###################################################################
# phony targets
.PHONY: fpga vivado tmpclean clean distclean
# prevent make from deleting intermediate files and reports
.PRECIOUS: %.xpr %.bit %.bin %.ltx %.xsa %.mcs %.prm
.SECONDARY:
CONFIG ?= config.mk
-include $(CONFIG)
FPGA_TOP ?= fpga
PROJECT ?= $(FPGA_TOP)
XDC_FILES ?= $(PROJECT).xdc
# handle file list files
process_f_file = $(call process_f_files,$(addprefix $(dir $1),$(shell cat $1)))
process_f_files = $(foreach f,$1,$(if $(filter %.f,$f),$(call process_f_file,$f),$f))
uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $(lastword $1)),$(notdir $f)),$f,))) $(lastword $1))
SYN_FILES := $(call uniq_base,$(call process_f_files,$(SYN_FILES)))
INC_FILES := $(call uniq_base,$(call process_f_files,$(INC_FILES)))
###################################################################
# Main Targets
#
# all: build everything (fpga)
# fpga: build FPGA config
# vivado: open project in Vivado
# tmpclean: remove intermediate files
# clean: remove output files and project files
# distclean: remove archived output files
###################################################################
all: fpga
fpga: $(PROJECT).bit
vivado: $(PROJECT).xpr
vivado $(PROJECT).xpr
tmpclean::
-rm -rf *.log *.jou *.cache *.gen *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v
-rm -rf create_project.tcl update_config.tcl run_synth.tcl run_impl.tcl generate_bit.tcl
clean:: tmpclean
-rm -rf *.bit *.bin *.ltx *.xsa program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl
-rm -rf *_utilization.rpt *_utilization_hierarchical.rpt
distclean:: clean
-rm -rf rev
###################################################################
# Target implementations
###################################################################
# Vivado project file
# create fresh project if Makefile or IP files have changed
create_project.tcl: Makefile $(XCI_FILES) $(IP_TCL_FILES)
rm -rf defines.v
touch defines.v
for x in $(DEFS); do echo '`define' $$x >> defines.v; done
echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@
echo "add_files -fileset sources_1 defines.v $(SYN_FILES)" >> $@
echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@
echo "add_files -fileset constrs_1 $(XDC_FILES)" >> $@
for x in $(XCI_FILES); do echo "import_ip $$x" >> $@; done
for x in $(IP_TCL_FILES); do echo "source $$x" >> $@; done
for x in $(CONFIG_TCL_FILES); do echo "source $$x" >> $@; done
# source config TCL scripts if any source file has changed
update_config.tcl: $(CONFIG_TCL_FILES) $(SYN_FILES) $(INC_FILES) $(XDC_FILES)
echo "open_project -quiet $(PROJECT).xpr" > $@
for x in $(CONFIG_TCL_FILES); do echo "source $$x" >> $@; done
$(PROJECT).xpr: create_project.tcl update_config.tcl
vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x)
# synthesis run
$(PROJECT).runs/synth_1/$(PROJECT).dcp: create_project.tcl update_config.tcl $(SYN_FILES) $(INC_FILES) $(XDC_FILES) | $(PROJECT).xpr
echo "open_project $(PROJECT).xpr" > run_synth.tcl
echo "reset_run synth_1" >> run_synth.tcl
echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl
echo "wait_on_run synth_1" >> run_synth.tcl
vivado -nojournal -nolog -mode batch -source run_synth.tcl
# implementation run
$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp
echo "open_project $(PROJECT).xpr" > run_impl.tcl
echo "reset_run impl_1" >> run_impl.tcl
echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl
echo "wait_on_run impl_1" >> run_impl.tcl
echo "open_run impl_1" >> run_impl.tcl
echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl
echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl
vivado -nojournal -nolog -mode batch -source run_impl.tcl
# output files (including potentially bit, bin, ltx, and xsa)
$(PROJECT).bit $(PROJECT).bin $(PROJECT).ltx $(PROJECT).xsa: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp
echo "open_project $(PROJECT).xpr" > generate_bit.tcl
echo "open_run impl_1" >> generate_bit.tcl
echo "write_bitstream -force -bin_file $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl
echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl
echo "write_hw_platform -fixed -force -include_bit $(PROJECT).xsa" >> generate_bit.tcl
vivado -nojournal -nolog -mode batch -source generate_bit.tcl
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit .
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bin .
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi
mkdir -p rev
COUNT=100; \
while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bin rev/$(PROJECT)_rev$$COUNT.bin; \
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi; \
if [ -e $(PROJECT).xsa ]; then cp -pv $(PROJECT).xsa rev/$(PROJECT)_rev$$COUNT.xsa; fi

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu200-fsgd2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au200.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au200.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_156.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B37093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x90c8]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu200-fsgd2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au200.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au200.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_156.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B37093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x90c8]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu250-figd2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au200.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au200.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_156.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B57093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x90fa]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu250-figd2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au200.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au200.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_156.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B57093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x90fa]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu280-fsvh2892-2L-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au280.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au280.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_156.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B7D093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9118]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu280-fsvh2892-2L-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au280.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au280.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_156.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B7D093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9118]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu26-vsva1365-2LV-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au45n.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au45n.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4AD5093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x902d]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu26-vsva1365-2LV-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au45n.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au45n.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4AD5093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x902d]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu50-fsvh2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au50.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au50.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B77093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9032]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu50-fsvh2104-2-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au50.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au50.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B77093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9032]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu55c-fsvh2892-2L-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au55.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au55.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B7D093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9038]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu55c-fsvh2892-2L-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au55.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au55.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B7D093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9038]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu55n-fsvh2892-2L-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au55.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au55.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B77093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9037]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcu55n-fsvh2892-2L-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au55.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au55.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x01002000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B77093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9037]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,169 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcvu9p-fsgd2104-2L-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au200.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au200.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_156.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
$(PROJECT)_fallback.bit: $(PROJECT).bit
echo "open_project $*.xpr" > generate_fallback_bit.tcl
echo "open_run impl_1" >> generate_fallback_bit.tcl
echo "startgroup" >> generate_fallback_bit.tcl
echo "set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]" >> generate_fallback_bit.tcl
echo "set_property BITSTREAM.CONFIG.TIMER_CFG 0x03000000 [current_design]" >> generate_fallback_bit.tcl
echo "set_property BITSTREAM.CONFIG.NEXT_CONFIG_REBOOT ENABLE [current_design]" >> generate_fallback_bit.tcl
echo "set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 0x04000000 [current_design]" >> generate_fallback_bit.tcl
echo "endgroup" >> generate_fallback_bit.tcl
echo "write_bitstream -verbose -force $*_fallback.bit" >> generate_fallback_bit.tcl
echo "undo" >> generate_fallback_bit.tcl
echo "exit" >> generate_fallback_bit.tcl
vivado -nojournal -nolog -mode batch -source generate_fallback_bit.tcl
mkdir -p rev
EXT=bit; COUNT=100; \
while [ -e rev/$*_rev$$COUNT.$$EXT ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
cp $@ rev/$*_fallback_rev$$COUNT.$$EXT; \
echo "Output: rev/$*_fallback_rev$$COUNT.$$EXT";
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x04000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
$(PROJECT)_fallback.mcs $(PROJECT)_fallback.prm: $(PROJECT)_fallback.bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x00000000 $*_fallback.bit} -checksum -file $*_fallback.mcs" > generate_fallback_mcs.tcl
echo "exit" >> generate_fallback_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_fallback_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*_fallback$$x rev/$*_fallback_rev$$COUNT$$x; \
echo "Output: rev/$*_fallback_rev$$COUNT$$x"; done;
$(PROJECT)_full.mcs $(PROJECT)_full.prm: $(PROJECT)_fallback.bit $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x00000000 $*_fallback.bit up 0x04000000 $*.bit} -checksum -file $*_full.mcs" > generate_full_mcs.tcl
echo "exit" >> generate_full_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_full_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*_full$$x rev/$*_full_rev$$COUNT$$x; \
echo "Output: rev/$*_full_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl
flash%: $(PROJECT)%.mcs $(PROJECT)%.prm
echo "open_hw_manager" > flash$*.tcl
echo "connect_hw_server" >> flash$*.tcl
echo "open_hw_target" >> flash$*.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash$*.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash$*.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash$*.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash$*.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)$*.mcs\"] [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)$*.prm\"] [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash$*.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash$*.tcl
echo "program_hw_devices [current_hw_device]" >> flash$*.tcl
echo "refresh_hw_device [current_hw_device]" >> flash$*.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash$*.tcl
echo "boot_hw_device [current_hw_device]" >> flash$*.tcl
echo "exit" >> flash$*.tcl
vivado -nojournal -nolog -mode batch -source flash$*.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B31093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x95f5]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,169 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcvu9p-fsgd2104-2L-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_au200.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_au200.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4_uscale_plus_0.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_156.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
$(PROJECT)_fallback.bit: $(PROJECT).bit
echo "open_project $*.xpr" > generate_fallback_bit.tcl
echo "open_run impl_1" >> generate_fallback_bit.tcl
echo "startgroup" >> generate_fallback_bit.tcl
echo "set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]" >> generate_fallback_bit.tcl
echo "set_property BITSTREAM.CONFIG.TIMER_CFG 0x03000000 [current_design]" >> generate_fallback_bit.tcl
echo "set_property BITSTREAM.CONFIG.NEXT_CONFIG_REBOOT ENABLE [current_design]" >> generate_fallback_bit.tcl
echo "set_property BITSTREAM.CONFIG.NEXT_CONFIG_ADDR 0x04000000 [current_design]" >> generate_fallback_bit.tcl
echo "endgroup" >> generate_fallback_bit.tcl
echo "write_bitstream -verbose -force $*_fallback.bit" >> generate_fallback_bit.tcl
echo "undo" >> generate_fallback_bit.tcl
echo "exit" >> generate_fallback_bit.tcl
vivado -nojournal -nolog -mode batch -source generate_fallback_bit.tcl
mkdir -p rev
EXT=bit; COUNT=100; \
while [ -e rev/$*_rev$$COUNT.$$EXT ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
cp $@ rev/$*_fallback_rev$$COUNT.$$EXT; \
echo "Output: rev/$*_fallback_rev$$COUNT.$$EXT";
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x04000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
$(PROJECT)_fallback.mcs $(PROJECT)_fallback.prm: $(PROJECT)_fallback.bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x00000000 $*_fallback.bit} -checksum -file $*_fallback.mcs" > generate_fallback_mcs.tcl
echo "exit" >> generate_fallback_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_fallback_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*_fallback$$x rev/$*_fallback_rev$$COUNT$$x; \
echo "Output: rev/$*_fallback_rev$$COUNT$$x"; done;
$(PROJECT)_full.mcs $(PROJECT)_full.prm: $(PROJECT)_fallback.bit $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 128 -interface SPIx4 -loadbit {up 0x00000000 $*_fallback.bit up 0x04000000 $*.bit} -checksum -file $*_full.mcs" > generate_full_mcs.tcl
echo "exit" >> generate_full_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_full_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*_full$$x rev/$*_full_rev$$COUNT$$x; \
echo "Output: rev/$*_full_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl
flash%: $(PROJECT)%.mcs $(PROJECT)%.prm
echo "open_hw_manager" > flash$*.tcl
echo "connect_hw_server" >> flash$*.tcl
echo "open_hw_target" >> flash$*.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash$*.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash$*.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu01g-spi-x1_x2_x4}] 0]" >> flash$*.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash$*.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT)$*.mcs\"] [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT)$*.prm\"] [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash$*.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash$*.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash$*.tcl
echo "program_hw_devices [current_hw_device]" >> flash$*.tcl
echo "refresh_hw_device [current_hw_device]" >> flash$*.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash$*.tcl
echo "boot_hw_device [current_hw_device]" >> flash$*.tcl
echo "exit" >> flash$*.tcl
vivado -nojournal -nolog -mode batch -source flash$*.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4B31093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x95f5]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcux35-vsva1365-3-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_x3522.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_x3522.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0_x3522.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4AD5093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9dc2]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcux35-vsva1365-3-e
FPGA_TOP = fpga
FPGA_ARCH = virtexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga_x3522.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga_x3522.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = ../ip/pcie4c_uscale_plus_0_x3522.tcl
IP_TCL_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_161.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 256 -interface SPIx4 -loadbit {up 0x00000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw_manager" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu02g-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4AD5093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x10ee]
set board_device_id [expr 0x9dc2]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "32"
# PCIe IP core settings
set pcie [get_ips pcie4c_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,862 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# XDC constraints for Xilinx AU200/AU250/VCU1525
# AU200 part: xcu200-fsgd2104-2-e
# AU250 part: xcu250-figd2104-2-e
# VCU1525 part: xcvu9p-fsgd2104-2L-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 63.8 [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
set_operating_conditions -design_power_budget 160
# System clocks
# 300 MHz (DDR 0)
#set_property -dict {LOC AY37 IOSTANDARD LVDS} [get_ports clk_300mhz_0_p]
#set_property -dict {LOC AY38 IOSTANDARD LVDS} [get_ports clk_300mhz_0_n]
#create_clock -period 3.333 -name clk_300mhz_0 [get_ports clk_300mhz_0_p]
# 300 MHz (DDR 1)
#set_property -dict {LOC AW20 IOSTANDARD LVDS} [get_ports clk_300mhz_1_p]
#set_property -dict {LOC AW19 IOSTANDARD LVDS} [get_ports clk_300mhz_1_n]
#create_clock -period 3.333 -name clk_300mhz_1 [get_ports clk_300mhz_1_p]
# 300 MHz (DDR 2)
#set_property -dict {LOC F32 IOSTANDARD LVDS} [get_ports clk_300mhz_2_p]
#set_property -dict {LOC E32 IOSTANDARD LVDS} [get_ports clk_300mhz_2_n]
#create_clock -period 3.333 -name clk_300mhz_2 [get_ports clk_300mhz_2_p]
# 300 MHz (DDR 3)
#set_property -dict {LOC J16 IOSTANDARD LVDS} [get_ports clk_300mhz_3_p]
#set_property -dict {LOC H16 IOSTANDARD LVDS} [get_ports clk_300mhz_3_n]
#create_clock -period 3.333 -name clk_300mhz_3 [get_ports clk_300mhz_3_p]
# SI570 user clock
#set_property -dict {LOC AU19 IOSTANDARD LVDS} [get_ports clk_user_p]
#set_property -dict {LOC AV19 IOSTANDARD LVDS} [get_ports clk_user_n]
#create_clock -period 6.400 -name clk_user [get_ports clk_user_p]
# LEDs
set_property -dict {LOC BC21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[0]}]
set_property -dict {LOC BB21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[1]}]
set_property -dict {LOC BA20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {led[2]}]
set_false_path -to [get_ports {led[*]}]
set_output_delay 0 [get_ports {led[*]}]
# Reset button
set_property -dict {LOC AL20 IOSTANDARD LVCMOS12} [get_ports reset]
set_false_path -from [get_ports {reset}]
set_input_delay 0 [get_ports {reset}]
# DIP switches
set_property -dict {LOC AN22 IOSTANDARD LVCMOS12} [get_ports {sw[0]}]
set_property -dict {LOC AM19 IOSTANDARD LVCMOS12} [get_ports {sw[1]}]
set_property -dict {LOC AL19 IOSTANDARD LVCMOS12} [get_ports {sw[2]}]
set_property -dict {LOC AP20 IOSTANDARD LVCMOS12} [get_ports {sw[3]}]
set_false_path -from [get_ports {sw[*]}]
set_input_delay 0 [get_ports {sw[*]}]
# UART (U27 FT4232H channel CDBUS)
set_property -dict {LOC BB20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports uart_txd] ;# U27.39 CDBUS1 RXD
set_property -dict {LOC BF18 IOSTANDARD LVCMOS12} [get_ports uart_rxd] ;# U27.38 CDBUS0 TXD
set_false_path -to [get_ports {uart_txd}]
set_output_delay 0 [get_ports {uart_txd}]
set_false_path -from [get_ports {uart_rxd}]
set_input_delay 0 [get_ports {uart_rxd}]
# BMC
#set_property -dict {LOC AR20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
#set_property -dict {LOC AM20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
#set_property -dict {LOC AM21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[2]}]
#set_property -dict {LOC AN21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[3]}]
#set_property -dict {LOC BB19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
#set_property -dict {LOC BA19 IOSTANDARD LVCMOS12} [get_ports {msp_uart_rxd}]
#set_false_path -to [get_ports {msp_uart_txd}]
#set_output_delay 0 [get_ports {msp_uart_txd}]
#set_false_path -from [get_ports {msp_gpio[*] msp_uart_rxd}]
#set_input_delay 0 [get_ports {msp_gpio[*] msp_uart_rxd}]
# QSFP28 Interfaces
set_property -dict {LOC N4 } [get_ports {qsfp0_rx_p[0]}] ;# MGTYRXP0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
set_property -dict {LOC N3 } [get_ports {qsfp0_rx_n[0]}] ;# MGTYRXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
set_property -dict {LOC N9 } [get_ports {qsfp0_tx_p[0]}] ;# MGTYTXP0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
set_property -dict {LOC N8 } [get_ports {qsfp0_tx_n[0]}] ;# MGTYTXN0_231 GTYE4_CHANNEL_X1Y48 / GTYE4_COMMON_X1Y12
set_property -dict {LOC M2 } [get_ports {qsfp0_rx_p[1]}] ;# MGTYRXP1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
set_property -dict {LOC M1 } [get_ports {qsfp0_rx_n[1]}] ;# MGTYRXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
set_property -dict {LOC M7 } [get_ports {qsfp0_tx_p[1]}] ;# MGTYTXP1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
set_property -dict {LOC M6 } [get_ports {qsfp0_tx_n[1]}] ;# MGTYTXN1_231 GTYE4_CHANNEL_X1Y49 / GTYE4_COMMON_X1Y12
set_property -dict {LOC L4 } [get_ports {qsfp0_rx_p[2]}] ;# MGTYRXP2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
set_property -dict {LOC L3 } [get_ports {qsfp0_rx_n[2]}] ;# MGTYRXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
set_property -dict {LOC L9 } [get_ports {qsfp0_tx_p[2]}] ;# MGTYTXP2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
set_property -dict {LOC L8 } [get_ports {qsfp0_tx_n[2]}] ;# MGTYTXN2_231 GTYE4_CHANNEL_X1Y50 / GTYE4_COMMON_X1Y12
set_property -dict {LOC K2 } [get_ports {qsfp0_rx_p[3]}] ;# MGTYRXP3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
set_property -dict {LOC K1 } [get_ports {qsfp0_rx_n[3]}] ;# MGTYRXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
set_property -dict {LOC K7 } [get_ports {qsfp0_tx_p[3]}] ;# MGTYTXP3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
set_property -dict {LOC K6 } [get_ports {qsfp0_tx_n[3]}] ;# MGTYTXN3_231 GTYE4_CHANNEL_X1Y51 / GTYE4_COMMON_X1Y12
set_property -dict {LOC M11 } [get_ports {qsfp0_mgt_refclk_0_p}] ;# MGTREFCLK0P_231 from U14.4 via U43.13
set_property -dict {LOC M10 } [get_ports {qsfp0_mgt_refclk_0_n}] ;# MGTREFCLK0N_231 from U14.5 via U43.14
#set_property -dict {LOC K11 } [get_ports {qsfp0_mgt_refclk_1_p}] ;# MGTREFCLK1P_231 from U9.18
#set_property -dict {LOC K10 } [get_ports {qsfp0_mgt_refclk_1_n}] ;# MGTREFCLK1N_231 from U9.17
set_property -dict {LOC BE16 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_modsell}]
set_property -dict {LOC BE17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_resetl}]
set_property -dict {LOC BE20 IOSTANDARD LVCMOS12 PULLUP true} [get_ports {qsfp0_modprsl}]
set_property -dict {LOC BE21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports {qsfp0_intl}]
set_property -dict {LOC BD18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_lpmode}]
# set_property -dict {LOC AT22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_refclk_reset}]
# set_property -dict {LOC AT20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_fs[0]}]
# set_property -dict {LOC AU22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp0_fs[1]}]
# 156.25 MHz MGT reference clock (from SI570)
create_clock -period 6.400 -name qsfp0_mgt_refclk_0 [get_ports {qsfp0_mgt_refclk_0_p}]
# 156.25 MHz MGT reference clock (from SI5335, FS = 0b01)
#create_clock -period 6.400 -name qsfp0_mgt_refclk_1 [get_ports {qsfp0_mgt_refclk_1_p}]
# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10)
#create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports {qsfp0_mgt_refclk_1_p}]
set_false_path -to [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode}]
set_output_delay 0 [get_ports {qsfp0_modsell qsfp0_resetl qsfp0_lpmode}]
set_false_path -from [get_ports {qsfp0_modprsl qsfp0_intl}]
set_input_delay 0 [get_ports {qsfp0_modprsl qsfp0_intl}]
#set_false_path -to [get_ports {qsfp0_refclk_reset qsfp0_fs[*]}]
#set_output_delay 0 [get_ports {qsfp0_refclk_reset qsfp0_fs[*]}]
set_property -dict {LOC U4 } [get_ports {qsfp1_rx_p[0]}] ;# MGTYRXP0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC U3 } [get_ports {qsfp1_rx_n[0]}] ;# MGTYRXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC U9 } [get_ports {qsfp1_tx_p[0]}] ;# MGTYTXP0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC U8 } [get_ports {qsfp1_tx_n[0]}] ;# MGTYTXN0_230 GTYE4_CHANNEL_X1Y44 / GTYE4_COMMON_X1Y11
set_property -dict {LOC T2 } [get_ports {qsfp1_rx_p[1]}] ;# MGTYRXP1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC T1 } [get_ports {qsfp1_rx_n[1]}] ;# MGTYRXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC T7 } [get_ports {qsfp1_tx_p[1]}] ;# MGTYTXP1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC T6 } [get_ports {qsfp1_tx_n[1]}] ;# MGTYTXN1_230 GTYE4_CHANNEL_X1Y45 / GTYE4_COMMON_X1Y11
set_property -dict {LOC R4 } [get_ports {qsfp1_rx_p[2]}] ;# MGTYRXP2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC R3 } [get_ports {qsfp1_rx_n[2]}] ;# MGTYRXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC R9 } [get_ports {qsfp1_tx_p[2]}] ;# MGTYTXP2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC R8 } [get_ports {qsfp1_tx_n[2]}] ;# MGTYTXN2_230 GTYE4_CHANNEL_X1Y46 / GTYE4_COMMON_X1Y11
set_property -dict {LOC P2 } [get_ports {qsfp1_rx_p[3]}] ;# MGTYRXP3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC P1 } [get_ports {qsfp1_rx_n[3]}] ;# MGTYRXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC P7 } [get_ports {qsfp1_tx_p[3]}] ;# MGTYTXP3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC P6 } [get_ports {qsfp1_tx_n[3]}] ;# MGTYTXN3_230 GTYE4_CHANNEL_X1Y47 / GTYE4_COMMON_X1Y11
set_property -dict {LOC T11 } [get_ports {qsfp1_mgt_refclk_0_p}] ;# MGTREFCLK0P_230 from U14.4 via U43.15
set_property -dict {LOC T10 } [get_ports {qsfp1_mgt_refclk_0_n}] ;# MGTREFCLK0N_230 from U14.5 via U43.16
#set_property -dict {LOC P11 } [get_ports {qsfp1_mgt_refclk_1_p}] ;# MGTREFCLK1P_230 from U12.18
#set_property -dict {LOC P10 } [get_ports {qsfp1_mgt_refclk_1_n}] ;# MGTREFCLK1N_230 from U12.17
set_property -dict {LOC AY20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_modsell}]
set_property -dict {LOC BC18 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_resetl}]
set_property -dict {LOC BC19 IOSTANDARD LVCMOS12 PULLUP true} [get_ports {qsfp1_modprsl}]
set_property -dict {LOC AV21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports {qsfp1_intl}]
set_property -dict {LOC AV22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_lpmode}]
# set_property -dict {LOC AR21 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_refclk_reset}]
# set_property -dict {LOC AR22 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_fs[0]}]
# set_property -dict {LOC AU20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports {qsfp1_fs[1]}]
# 156.25 MHz MGT reference clock (from SI570)
create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports {qsfp1_mgt_refclk_0_p}]
# 156.25 MHz MGT reference clock (from SI5335, FS = 0b01)
#create_clock -period 6.400 -name qsfp1_mgt_refclk_1 [get_ports {qsfp1_mgt_refclk_1_p}]
# 161.1328125 MHz MGT reference clock (from SI5335, FS = 0b10)
#create_clock -period 6.206 -name qsfp1_mgt_refclk_1 [get_ports {qsfp1_mgt_refclk_1_p}]
set_false_path -to [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode}]
set_output_delay 0 [get_ports {qsfp1_modsell qsfp1_resetl qsfp1_lpmode}]
set_false_path -from [get_ports {qsfp1_modprsl qsfp1_intl}]
set_input_delay 0 [get_ports {qsfp1_modprsl qsfp1_intl}]
#set_false_path -to [get_ports {qsfp1_refclk_reset qsfp1_fs[*]}]
#set_output_delay 0 [get_ports {qsfp1_refclk_reset qsfp1_fs[*]}]
# I2C interface
#set_property -dict {LOC BF19 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_mux_reset]
set_property -dict {LOC BF20 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_scl]
set_property -dict {LOC BF17 IOSTANDARD LVCMOS12 SLEW SLOW DRIVE 8} [get_ports i2c_sda]
set_false_path -to [get_ports {i2c_sda i2c_scl}]
set_output_delay 0 [get_ports {i2c_sda i2c_scl}]
set_false_path -from [get_ports {i2c_sda i2c_scl}]
set_input_delay 0 [get_ports {i2c_sda i2c_scl}]
# PCIe Interface
set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y35 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AG4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AG3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AG9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AG8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y34 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AH2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AH1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AH7 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AH6 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y33 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AJ4 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AJ3 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AJ9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AJ8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y32 / GTYE4_COMMON_X1Y8
set_property -dict {LOC AK2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AK1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AK7 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AK6 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y31 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AL4 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AL3 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AL9 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AL8 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y30 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AM2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AM1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AM7 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AM6 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y29 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AN4 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AN3 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AN9 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AN8 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y28 / GTYE4_COMMON_X1Y7
set_property -dict {LOC AP2 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AP1 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AP7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AP6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y27 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AR4 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AR3 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AR9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AR8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y26 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AT2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AT1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AT7 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AT6 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y25 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AU4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AU3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AU9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AU8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y24 / GTYE4_COMMON_X1Y6
set_property -dict {LOC AV2 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AV1 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AV7 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AV6 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y23 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AW4 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AW3 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BB5 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BB4 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y22 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BD5 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BD4 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y21 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BF5 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
set_property -dict {LOC BF4 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y20 / GTYE4_COMMON_X1Y5
set_property -dict {LOC AM11 } [get_ports {pcie_refclk_p}] ;# MGTREFCLK0P_226
set_property -dict {LOC AM10 } [get_ports {pcie_refclk_n}] ;# MGTREFCLK0N_226
set_property -dict {LOC BD21 IOSTANDARD LVCMOS12 PULLUP true} [get_ports {pcie_reset_n}]
# 100 MHz MGT reference clock
create_clock -period 10 -name pcie_mgt_refclk [get_ports {pcie_refclk_p}]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]
# DDR4 C0
#set_property -dict {LOC AT36 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[0]}]
#set_property -dict {LOC AV36 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[1]}]
#set_property -dict {LOC AV37 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[2]}]
#set_property -dict {LOC AW35 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[3]}]
#set_property -dict {LOC AW36 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[4]}]
#set_property -dict {LOC AY36 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[5]}]
#set_property -dict {LOC AY35 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[6]}]
#set_property -dict {LOC BA40 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[7]}]
#set_property -dict {LOC BA37 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[8]}]
#set_property -dict {LOC BB37 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[9]}]
#set_property -dict {LOC AR35 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[10]}]
#set_property -dict {LOC BA39 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[11]}]
#set_property -dict {LOC BB40 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[12]}]
#set_property -dict {LOC AN36 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[13]}]
#set_property -dict {LOC AP35 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[14]}]
#set_property -dict {LOC AP36 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[15]}]
#set_property -dict {LOC AR36 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[16]}]
#set_property -dict {LOC AT35 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_ba[0]}]
#set_property -dict {LOC AT34 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_ba[1]}]
#set_property -dict {LOC BC37 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_bg[0]}]
#set_property -dict {LOC BC39 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_bg[1]}]
#set_property -dict {LOC AV38 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c0_ck_t[0]}]
#set_property -dict {LOC AW38 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c0_ck_c[0]}]
#set_property -dict {LOC AU34 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c0_ck_t[1]}]
#set_property -dict {LOC AU35 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c0_ck_c[1]}]
#set_property -dict {LOC BC38 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cke[0]}]
#set_property -dict {LOC BC40 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cke[1]}]
#set_property -dict {LOC AR33 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cs_n[0]}]
#set_property -dict {LOC AP33 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cs_n[1]}]
#set_property -dict {LOC AN33 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cs_n[2]}]
#set_property -dict {LOC AM34 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cs_n[3]}]
#set_property -dict {LOC BB39 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_act_n}]
#set_property -dict {LOC AP34 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_odt[0]}]
#set_property -dict {LOC AN34 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_odt[1]}]
#set_property -dict {LOC AU36 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_par}]
#set_property -dict {LOC AU31 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c0_reset_n}]
#set_property -dict {LOC AW28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[0]}]
#set_property -dict {LOC AW29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[1]}]
#set_property -dict {LOC BA28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[2]}]
#set_property -dict {LOC BA27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[3]}]
#set_property -dict {LOC BB29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[4]}]
#set_property -dict {LOC BA29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[5]}]
#set_property -dict {LOC BC27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[6]}]
#set_property -dict {LOC BB27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[7]}]
#set_property -dict {LOC BE28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[8]}]
#set_property -dict {LOC BF28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[9]}]
#set_property -dict {LOC BE30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[10]}]
#set_property -dict {LOC BD30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[11]}]
#set_property -dict {LOC BF27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[12]}]
#set_property -dict {LOC BE27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[13]}]
#set_property -dict {LOC BF30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[14]}]
#set_property -dict {LOC BF29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[15]}]
#set_property -dict {LOC BB31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[16]}]
#set_property -dict {LOC BB32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[17]}]
#set_property -dict {LOC AY32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[18]}]
#set_property -dict {LOC AY33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[19]}]
#set_property -dict {LOC BC32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[20]}]
#set_property -dict {LOC BC33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[21]}]
#set_property -dict {LOC BB34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[22]}]
#set_property -dict {LOC BC34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[23]}]
#set_property -dict {LOC AV31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[24]}]
#set_property -dict {LOC AV32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[25]}]
#set_property -dict {LOC AV34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[26]}]
#set_property -dict {LOC AW34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[27]}]
#set_property -dict {LOC AW31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[28]}]
#set_property -dict {LOC AY31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[29]}]
#set_property -dict {LOC BA35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[30]}]
#set_property -dict {LOC BA34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[31]}]
#set_property -dict {LOC AL30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[32]}]
#set_property -dict {LOC AM30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[33]}]
#set_property -dict {LOC AU32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[34]}]
#set_property -dict {LOC AT32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[35]}]
#set_property -dict {LOC AN31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[36]}]
#set_property -dict {LOC AN32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[37]}]
#set_property -dict {LOC AR32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[38]}]
#set_property -dict {LOC AR31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[39]}]
#set_property -dict {LOC AP29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[40]}]
#set_property -dict {LOC AP28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[41]}]
#set_property -dict {LOC AN27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[42]}]
#set_property -dict {LOC AM27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[43]}]
#set_property -dict {LOC AN29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[44]}]
#set_property -dict {LOC AM29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[45]}]
#set_property -dict {LOC AR27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[46]}]
#set_property -dict {LOC AR28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[47]}]
#set_property -dict {LOC AT28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[48]}]
#set_property -dict {LOC AV27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[49]}]
#set_property -dict {LOC AU27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[50]}]
#set_property -dict {LOC AT27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[51]}]
#set_property -dict {LOC AV29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[52]}]
#set_property -dict {LOC AY30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[53]}]
#set_property -dict {LOC AW30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[54]}]
#set_property -dict {LOC AV28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[55]}]
#set_property -dict {LOC BD34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[56]}]
#set_property -dict {LOC BD33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[57]}]
#set_property -dict {LOC BE33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[58]}]
#set_property -dict {LOC BD35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[59]}]
#set_property -dict {LOC BF32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[60]}]
#set_property -dict {LOC BF33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[61]}]
#set_property -dict {LOC BF34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[62]}]
#set_property -dict {LOC BF35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[63]}]
#set_property -dict {LOC BD40 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[64]}]
#set_property -dict {LOC BD39 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[65]}]
#set_property -dict {LOC BF43 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[66]}]
#set_property -dict {LOC BF42 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[67]}]
#set_property -dict {LOC BF37 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[68]}]
#set_property -dict {LOC BE37 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[69]}]
#set_property -dict {LOC BE40 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[70]}]
#set_property -dict {LOC BF41 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[71]}]
#set_property -dict {LOC BA30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[0]}]
#set_property -dict {LOC BB30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[0]}]
#set_property -dict {LOC BB26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[1]}]
#set_property -dict {LOC BC26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[1]}]
#set_property -dict {LOC BD28 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[2]}]
#set_property -dict {LOC BD29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[2]}]
#set_property -dict {LOC BD26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[3]}]
#set_property -dict {LOC BE26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[3]}]
#set_property -dict {LOC BB35 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[4]}]
#set_property -dict {LOC BB36 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[4]}]
#set_property -dict {LOC BC31 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[5]}]
#set_property -dict {LOC BD31 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[5]}]
#set_property -dict {LOC AV33 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[6]}]
#set_property -dict {LOC AW33 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[6]}]
#set_property -dict {LOC BA32 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[7]}]
#set_property -dict {LOC BA33 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[7]}]
#set_property -dict {LOC AM31 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[8]}]
#set_property -dict {LOC AM32 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[8]}]
#set_property -dict {LOC AP30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[9]}]
#set_property -dict {LOC AP31 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[9]}]
#set_property -dict {LOC AL28 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[10]}]
#set_property -dict {LOC AL29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[10]}]
#set_property -dict {LOC AR30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[11]}]
#set_property -dict {LOC AT30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[11]}]
#set_property -dict {LOC AU29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[12]}]
#set_property -dict {LOC AU30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[12]}]
#set_property -dict {LOC AY27 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[13]}]
#set_property -dict {LOC AY28 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[13]}]
#set_property -dict {LOC BE35 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[14]}]
#set_property -dict {LOC BE36 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[14]}]
#set_property -dict {LOC BE31 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[15]}]
#set_property -dict {LOC BE32 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[15]}]
#set_property -dict {LOC BE38 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[16]}]
#set_property -dict {LOC BF38 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[16]}]
#set_property -dict {LOC BF39 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[17]}]
#set_property -dict {LOC BF40 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[17]}]
# DDR4 C1
#set_property -dict {LOC AN24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[0]}]
#set_property -dict {LOC AT24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[1]}]
#set_property -dict {LOC AW24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[2]}]
#set_property -dict {LOC AN26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[3]}]
#set_property -dict {LOC AY22 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[4]}]
#set_property -dict {LOC AY23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[5]}]
#set_property -dict {LOC AV24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[6]}]
#set_property -dict {LOC BA22 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[7]}]
#set_property -dict {LOC AY25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[8]}]
#set_property -dict {LOC BA23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[9]}]
#set_property -dict {LOC AM26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[10]}]
#set_property -dict {LOC BA25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[11]}]
#set_property -dict {LOC BB22 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[12]}]
#set_property -dict {LOC AL24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[13]}]
#set_property -dict {LOC AL25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[14]}]
#set_property -dict {LOC AM25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[15]}]
#set_property -dict {LOC AN23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[16]}]
#set_property -dict {LOC AU24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_ba[0]}]
#set_property -dict {LOC AP26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_ba[1]}]
#set_property -dict {LOC BC22 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_bg[0]}]
#set_property -dict {LOC AW26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_bg[1]}]
#set_property -dict {LOC AT25 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c1_ck_t[0]}]
#set_property -dict {LOC AU25 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c1_ck_c[0]}]
#set_property -dict {LOC AU26 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c1_ck_t[1]}]
#set_property -dict {LOC AV26 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c1_ck_c[1]}]
#set_property -dict {LOC BB25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cke[0]}]
#set_property -dict {LOC BB24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cke[1]}]
#set_property -dict {LOC AV23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cs_n[0]}]
#set_property -dict {LOC AP25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cs_n[1]}]
#set_property -dict {LOC AR23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cs_n[2]}]
#set_property -dict {LOC AP23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cs_n[3]}]
#set_property -dict {LOC AW25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_act_n}]
#set_property -dict {LOC AW23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_odt[0]}]
#set_property -dict {LOC AP24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_odt[1]}]
#set_property -dict {LOC AT23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_par}]
#set_property -dict {LOC AR17 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c1_reset_n}]
#set_property -dict {LOC BD9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[0]}]
#set_property -dict {LOC BD7 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[1]}]
#set_property -dict {LOC BC7 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[2]}]
#set_property -dict {LOC BD8 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[3]}]
#set_property -dict {LOC BD10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[4]}]
#set_property -dict {LOC BE10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[5]}]
#set_property -dict {LOC BE7 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[6]}]
#set_property -dict {LOC BF7 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[7]}]
#set_property -dict {LOC AU13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[8]}]
#set_property -dict {LOC AV13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[9]}]
#set_property -dict {LOC AW13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[10]}]
#set_property -dict {LOC AW14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[11]}]
#set_property -dict {LOC AU14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[12]}]
#set_property -dict {LOC AY11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[13]}]
#set_property -dict {LOC AV14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[14]}]
#set_property -dict {LOC BA11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[15]}]
#set_property -dict {LOC BA12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[16]}]
#set_property -dict {LOC BB12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[17]}]
#set_property -dict {LOC BA13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[18]}]
#set_property -dict {LOC BA14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[19]}]
#set_property -dict {LOC BC9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[20]}]
#set_property -dict {LOC BB9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[21]}]
#set_property -dict {LOC BA7 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[22]}]
#set_property -dict {LOC BA8 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[23]}]
#set_property -dict {LOC AN13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[24]}]
#set_property -dict {LOC AR13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[25]}]
#set_property -dict {LOC AM13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[26]}]
#set_property -dict {LOC AP13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[27]}]
#set_property -dict {LOC AM14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[28]}]
#set_property -dict {LOC AR15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[29]}]
#set_property -dict {LOC AL14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[30]}]
#set_property -dict {LOC AT15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[31]}]
#set_property -dict {LOC BE13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[32]}]
#set_property -dict {LOC BD14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[33]}]
#set_property -dict {LOC BF12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[34]}]
#set_property -dict {LOC BD13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[35]}]
#set_property -dict {LOC BD15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[36]}]
#set_property -dict {LOC BD16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[37]}]
#set_property -dict {LOC BF14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[38]}]
#set_property -dict {LOC BF13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[39]}]
#set_property -dict {LOC AY17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[40]}]
#set_property -dict {LOC BA17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[41]}]
#set_property -dict {LOC AY18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[42]}]
#set_property -dict {LOC BA18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[43]}]
#set_property -dict {LOC BA15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[44]}]
#set_property -dict {LOC BB15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[45]}]
#set_property -dict {LOC BC11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[46]}]
#set_property -dict {LOC BD11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[47]}]
#set_property -dict {LOC AV16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[48]}]
#set_property -dict {LOC AV17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[49]}]
#set_property -dict {LOC AU16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[50]}]
#set_property -dict {LOC AU17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[51]}]
#set_property -dict {LOC BB17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[52]}]
#set_property -dict {LOC BB16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[53]}]
#set_property -dict {LOC AT18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[54]}]
#set_property -dict {LOC AT17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[55]}]
#set_property -dict {LOC AM15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[56]}]
#set_property -dict {LOC AL15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[57]}]
#set_property -dict {LOC AN17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[58]}]
#set_property -dict {LOC AN16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[59]}]
#set_property -dict {LOC AR18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[60]}]
#set_property -dict {LOC AP18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[61]}]
#set_property -dict {LOC AL17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[62]}]
#set_property -dict {LOC AL16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[63]}]
#set_property -dict {LOC BF25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[64]}]
#set_property -dict {LOC BF24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[65]}]
#set_property -dict {LOC BD25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[66]}]
#set_property -dict {LOC BE25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[67]}]
#set_property -dict {LOC BD23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[68]}]
#set_property -dict {LOC BC23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[69]}]
#set_property -dict {LOC BF23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[70]}]
#set_property -dict {LOC BE23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[71]}]
#set_property -dict {LOC BF10 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[0]}]
#set_property -dict {LOC BF9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[0]}]
#set_property -dict {LOC BE8 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[1]}]
#set_property -dict {LOC BF8 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[1]}]
#set_property -dict {LOC AW15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[2]}]
#set_property -dict {LOC AY15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[2]}]
#set_property -dict {LOC AY13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[3]}]
#set_property -dict {LOC AY12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[3]}]
#set_property -dict {LOC BB11 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[4]}]
#set_property -dict {LOC BB10 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[4]}]
#set_property -dict {LOC BA10 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[5]}]
#set_property -dict {LOC BA9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[5]}]
#set_property -dict {LOC AT14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[6]}]
#set_property -dict {LOC AT13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[6]}]
#set_property -dict {LOC AN14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[7]}]
#set_property -dict {LOC AP14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[7]}]
#set_property -dict {LOC BE12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[8]}]
#set_property -dict {LOC BE11 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[8]}]
#set_property -dict {LOC BE15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[9]}]
#set_property -dict {LOC BF15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[9]}]
#set_property -dict {LOC BC13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[10]}]
#set_property -dict {LOC BC12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[10]}]
#set_property -dict {LOC BB14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[11]}]
#set_property -dict {LOC BC14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[11]}]
#set_property -dict {LOC AV18 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[12]}]
#set_property -dict {LOC AW18 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[12]}]
#set_property -dict {LOC AW16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[13]}]
#set_property -dict {LOC AY16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[13]}]
#set_property -dict {LOC AP16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[14]}]
#set_property -dict {LOC AR16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[14]}]
#set_property -dict {LOC AM17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[15]}]
#set_property -dict {LOC AM16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[15]}]
#set_property -dict {LOC BC24 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[16]}]
#set_property -dict {LOC BD24 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[16]}]
#set_property -dict {LOC BE22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[17]}]
#set_property -dict {LOC BF22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[17]}]
# DDR4 C2
#set_property -dict {LOC L29 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[0]}]
#set_property -dict {LOC A33 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[1]}]
#set_property -dict {LOC C33 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[2]}]
#set_property -dict {LOC J29 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[3]}]
#set_property -dict {LOC H31 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[4]}]
#set_property -dict {LOC G31 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[5]}]
#set_property -dict {LOC C32 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[6]}]
#set_property -dict {LOC B32 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[7]}]
#set_property -dict {LOC A32 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[8]}]
#set_property -dict {LOC D31 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[9]}]
#set_property -dict {LOC A34 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[10]}]
#set_property -dict {LOC E31 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[11]}]
#set_property -dict {LOC M30 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[12]}]
#set_property -dict {LOC F33 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[13]}]
#set_property -dict {LOC A35 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[14]}]
#set_property -dict {LOC G32 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[15]}]
#set_property -dict {LOC K30 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_adr[16]}]
#set_property -dict {LOC D33 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_ba[0]}]
#set_property -dict {LOC B36 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_ba[1]}]
#set_property -dict {LOC C31 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_bg[0]}]
#set_property -dict {LOC J30 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_bg[1]}]
#set_property -dict {LOC C34 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c2_ck_t[0]}]
#set_property -dict {LOC B34 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c2_ck_c[0]}]
#set_property -dict {LOC D34 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c2_ck_t[1]}]
#set_property -dict {LOC D35 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c2_ck_c[1]}]
#set_property -dict {LOC G30 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_cke[0]}]
#set_property -dict {LOC E30 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_cke[1]}]
#set_property -dict {LOC B35 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_cs_n[0]}]
#set_property -dict {LOC J31 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_cs_n[1]}]
#set_property -dict {LOC L30 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_cs_n[2]}]
#set_property -dict {LOC K31 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_cs_n[3]}]
#set_property -dict {LOC B31 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_act_n}]
#set_property -dict {LOC E33 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_odt[0]}]
#set_property -dict {LOC F34 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_odt[1]}]
#set_property -dict {LOC M29 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c2_par}]
#set_property -dict {LOC D36 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c2_reset_n}]
#set_property -dict {LOC R25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[0]}]
#set_property -dict {LOC P25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[1]}]
#set_property -dict {LOC M25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[2]}]
#set_property -dict {LOC L25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[3]}]
#set_property -dict {LOC P26 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[4]}]
#set_property -dict {LOC R26 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[5]}]
#set_property -dict {LOC N27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[6]}]
#set_property -dict {LOC N28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[7]}]
#set_property -dict {LOC J28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[8]}]
#set_property -dict {LOC H29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[9]}]
#set_property -dict {LOC H28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[10]}]
#set_property -dict {LOC G29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[11]}]
#set_property -dict {LOC K25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[12]}]
#set_property -dict {LOC L27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[13]}]
#set_property -dict {LOC K26 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[14]}]
#set_property -dict {LOC K27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[15]}]
#set_property -dict {LOC F27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[16]}]
#set_property -dict {LOC E27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[17]}]
#set_property -dict {LOC E28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[18]}]
#set_property -dict {LOC D28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[19]}]
#set_property -dict {LOC G27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[20]}]
#set_property -dict {LOC G26 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[21]}]
#set_property -dict {LOC F28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[22]}]
#set_property -dict {LOC F29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[23]}]
#set_property -dict {LOC D26 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[24]}]
#set_property -dict {LOC C26 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[25]}]
#set_property -dict {LOC B27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[26]}]
#set_property -dict {LOC B26 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[27]}]
#set_property -dict {LOC A29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[28]}]
#set_property -dict {LOC A30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[29]}]
#set_property -dict {LOC C27 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[30]}]
#set_property -dict {LOC C28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[31]}]
#set_property -dict {LOC F35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[32]}]
#set_property -dict {LOC E38 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[33]}]
#set_property -dict {LOC D38 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[34]}]
#set_property -dict {LOC E35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[35]}]
#set_property -dict {LOC E36 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[36]}]
#set_property -dict {LOC E37 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[37]}]
#set_property -dict {LOC F38 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[38]}]
#set_property -dict {LOC G38 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[39]}]
#set_property -dict {LOC P30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[40]}]
#set_property -dict {LOC R30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[41]}]
#set_property -dict {LOC P29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[42]}]
#set_property -dict {LOC N29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[43]}]
#set_property -dict {LOC L32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[44]}]
#set_property -dict {LOC M32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[45]}]
#set_property -dict {LOC P31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[46]}]
#set_property -dict {LOC N32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[47]}]
#set_property -dict {LOC J35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[48]}]
#set_property -dict {LOC K35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[49]}]
#set_property -dict {LOC L33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[50]}]
#set_property -dict {LOC K33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[51]}]
#set_property -dict {LOC J34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[52]}]
#set_property -dict {LOC J33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[53]}]
#set_property -dict {LOC N34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[54]}]
#set_property -dict {LOC P34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[55]}]
#set_property -dict {LOC H36 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[56]}]
#set_property -dict {LOC G36 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[57]}]
#set_property -dict {LOC H37 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[58]}]
#set_property -dict {LOC J36 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[59]}]
#set_property -dict {LOC K37 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[60]}]
#set_property -dict {LOC K38 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[61]}]
#set_property -dict {LOC G35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[62]}]
#set_property -dict {LOC G34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[63]}]
#set_property -dict {LOC C36 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[64]}]
#set_property -dict {LOC B37 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[65]}]
#set_property -dict {LOC A37 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[66]}]
#set_property -dict {LOC A38 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[67]}]
#set_property -dict {LOC C39 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[68]}]
#set_property -dict {LOC D39 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[69]}]
#set_property -dict {LOC A40 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[70]}]
#set_property -dict {LOC B40 IOSTANDARD POD12_DCI } [get_ports {ddr4_c2_dq[71]}]
#set_property -dict {LOC N26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[0]}]
#set_property -dict {LOC M26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[0]}]
#set_property -dict {LOC R28 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[1]}]
#set_property -dict {LOC P28 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[1]}]
#set_property -dict {LOC J25 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[2]}]
#set_property -dict {LOC J26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[2]}]
#set_property -dict {LOC M27 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[3]}]
#set_property -dict {LOC L28 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[3]}]
#set_property -dict {LOC D29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[4]}]
#set_property -dict {LOC D30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[4]}]
#set_property -dict {LOC H26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[5]}]
#set_property -dict {LOC H27 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[5]}]
#set_property -dict {LOC A27 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[6]}]
#set_property -dict {LOC A28 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[6]}]
#set_property -dict {LOC C29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[7]}]
#set_property -dict {LOC B29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[7]}]
#set_property -dict {LOC E39 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[8]}]
#set_property -dict {LOC E40 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[8]}]
#set_property -dict {LOC G37 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[9]}]
#set_property -dict {LOC F37 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[9]}]
#set_property -dict {LOC N31 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[10]}]
#set_property -dict {LOC M31 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[10]}]
#set_property -dict {LOC T30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[11]}]
#set_property -dict {LOC R31 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[11]}]
#set_property -dict {LOC L35 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[12]}]
#set_property -dict {LOC L36 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[12]}]
#set_property -dict {LOC M34 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[13]}]
#set_property -dict {LOC L34 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[13]}]
#set_property -dict {LOC J38 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[14]}]
#set_property -dict {LOC H38 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[14]}]
#set_property -dict {LOC H33 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[15]}]
#set_property -dict {LOC H34 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[15]}]
#set_property -dict {LOC B39 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[16]}]
#set_property -dict {LOC A39 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[16]}]
#set_property -dict {LOC C37 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_t[17]}]
#set_property -dict {LOC C38 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c2_dqs_c[17]}]
# DDR4 C3
#set_property -dict {LOC K15 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[0]}]
#set_property -dict {LOC B15 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[1]}]
#set_property -dict {LOC F14 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[2]}]
#set_property -dict {LOC A15 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[3]}]
#set_property -dict {LOC C14 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[4]}]
#set_property -dict {LOC A14 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[5]}]
#set_property -dict {LOC B14 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[6]}]
#set_property -dict {LOC E13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[7]}]
#set_property -dict {LOC F13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[8]}]
#set_property -dict {LOC A13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[9]}]
#set_property -dict {LOC D14 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[10]}]
#set_property -dict {LOC C13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[11]}]
#set_property -dict {LOC B13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[12]}]
#set_property -dict {LOC K16 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[13]}]
#set_property -dict {LOC D15 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[14]}]
#set_property -dict {LOC E15 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[15]}]
#set_property -dict {LOC F15 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_adr[16]}]
#set_property -dict {LOC J15 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_ba[0]}]
#set_property -dict {LOC H14 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_ba[1]}]
#set_property -dict {LOC D13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_bg[0]}]
#set_property -dict {LOC J13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_bg[1]}]
#set_property -dict {LOC L14 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c3_ck_t[0]}]
#set_property -dict {LOC L13 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c3_ck_c[0]}]
#set_property -dict {LOC G14 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c3_ck_t[1]}]
#set_property -dict {LOC G13 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_c3_ck_c[1]}]
#set_property -dict {LOC K13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_cke[0]}]
#set_property -dict {LOC L15 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_cke[1]}]
#set_property -dict {LOC B16 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_cs_n[0]}]
#set_property -dict {LOC D16 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_cs_n[1]}]
#set_property -dict {LOC M14 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_cs_n[2]}]
#set_property -dict {LOC M13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_cs_n[3]}]
#set_property -dict {LOC H13 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_act_n}]
#set_property -dict {LOC C16 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_odt[0]}]
#set_property -dict {LOC E16 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_odt[1]}]
#set_property -dict {LOC J14 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c3_par}]
#set_property -dict {LOC D21 IOSTANDARD LVCMOS12 } [get_ports {ddr4_c3_reset_n}]
#set_property -dict {LOC P24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[0]}]
#set_property -dict {LOC N24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[1]}]
#set_property -dict {LOC T24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[2]}]
#set_property -dict {LOC R23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[3]}]
#set_property -dict {LOC N23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[4]}]
#set_property -dict {LOC P21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[5]}]
#set_property -dict {LOC P23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[6]}]
#set_property -dict {LOC R21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[7]}]
#set_property -dict {LOC J24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[8]}]
#set_property -dict {LOC J23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[9]}]
#set_property -dict {LOC H24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[10]}]
#set_property -dict {LOC G24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[11]}]
#set_property -dict {LOC L24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[12]}]
#set_property -dict {LOC L23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[13]}]
#set_property -dict {LOC K22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[14]}]
#set_property -dict {LOC K21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[15]}]
#set_property -dict {LOC G20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[16]}]
#set_property -dict {LOC H17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[17]}]
#set_property -dict {LOC F19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[18]}]
#set_property -dict {LOC G17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[19]}]
#set_property -dict {LOC J20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[20]}]
#set_property -dict {LOC L19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[21]}]
#set_property -dict {LOC L18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[22]}]
#set_property -dict {LOC J19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[23]}]
#set_property -dict {LOC M19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[24]}]
#set_property -dict {LOC M20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[25]}]
#set_property -dict {LOC R18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[26]}]
#set_property -dict {LOC R17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[27]}]
#set_property -dict {LOC R20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[28]}]
#set_property -dict {LOC T20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[29]}]
#set_property -dict {LOC N18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[30]}]
#set_property -dict {LOC N19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[31]}]
#set_property -dict {LOC A23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[32]}]
#set_property -dict {LOC A22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[33]}]
#set_property -dict {LOC B24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[34]}]
#set_property -dict {LOC B25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[35]}]
#set_property -dict {LOC B22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[36]}]
#set_property -dict {LOC C22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[37]}]
#set_property -dict {LOC C24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[38]}]
#set_property -dict {LOC C23 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[39]}]
#set_property -dict {LOC C19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[40]}]
#set_property -dict {LOC C18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[41]}]
#set_property -dict {LOC C21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[42]}]
#set_property -dict {LOC B21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[43]}]
#set_property -dict {LOC A18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[44]}]
#set_property -dict {LOC A17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[45]}]
#set_property -dict {LOC A20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[46]}]
#set_property -dict {LOC B20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[47]}]
#set_property -dict {LOC E17 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[48]}]
#set_property -dict {LOC F20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[49]}]
#set_property -dict {LOC E18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[50]}]
#set_property -dict {LOC E20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[51]}]
#set_property -dict {LOC D19 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[52]}]
#set_property -dict {LOC D20 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[53]}]
#set_property -dict {LOC H18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[54]}]
#set_property -dict {LOC J18 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[55]}]
#set_property -dict {LOC F22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[56]}]
#set_property -dict {LOC E22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[57]}]
#set_property -dict {LOC G22 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[58]}]
#set_property -dict {LOC G21 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[59]}]
#set_property -dict {LOC F24 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[60]}]
#set_property -dict {LOC E25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[61]}]
#set_property -dict {LOC F25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[62]}]
#set_property -dict {LOC G25 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[63]}]
#set_property -dict {LOC M16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[64]}]
#set_property -dict {LOC N16 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[65]}]
#set_property -dict {LOC N13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[66]}]
#set_property -dict {LOC N14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[67]}]
#set_property -dict {LOC T15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[68]}]
#set_property -dict {LOC R15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[69]}]
#set_property -dict {LOC P13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[70]}]
#set_property -dict {LOC P14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c3_dq[71]}]
#set_property -dict {LOC T22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[0]}]
#set_property -dict {LOC R22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[0]}]
#set_property -dict {LOC N22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[1]}]
#set_property -dict {LOC N21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[1]}]
#set_property -dict {LOC J21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[2]}]
#set_property -dict {LOC H21 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[2]}]
#set_property -dict {LOC M22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[3]}]
#set_property -dict {LOC L22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[3]}]
#set_property -dict {LOC L20 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[4]}]
#set_property -dict {LOC K20 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[4]}]
#set_property -dict {LOC K18 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[5]}]
#set_property -dict {LOC K17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[5]}]
#set_property -dict {LOC P19 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[6]}]
#set_property -dict {LOC P18 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[6]}]
#set_property -dict {LOC N17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[7]}]
#set_property -dict {LOC M17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[7]}]
#set_property -dict {LOC A25 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[8]}]
#set_property -dict {LOC A24 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[8]}]
#set_property -dict {LOC D24 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[9]}]
#set_property -dict {LOC D23 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[9]}]
#set_property -dict {LOC C17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[10]}]
#set_property -dict {LOC B17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[10]}]
#set_property -dict {LOC B19 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[11]}]
#set_property -dict {LOC A19 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[11]}]
#set_property -dict {LOC F18 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[12]}]
#set_property -dict {LOC F17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[12]}]
#set_property -dict {LOC H19 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[13]}]
#set_property -dict {LOC G19 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[13]}]
#set_property -dict {LOC F23 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[14]}]
#set_property -dict {LOC E23 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[14]}]
#set_property -dict {LOC H23 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[15]}]
#set_property -dict {LOC H22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[15]}]
#set_property -dict {LOC R16 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[16]}]
#set_property -dict {LOC P15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[16]}]
#set_property -dict {LOC T13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_t[17]}]
#set_property -dict {LOC R13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c3_dqs_c[17]}]

View File

@@ -0,0 +1,503 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# XDC constraints for the Xilinx Alveo U280 board
# part: xcu280-fsvh2892-2L-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 85.0 [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
set_operating_conditions -design_power_budget 160
# System clocks
# 100 MHz (DDR4)
#set_property -dict {LOC BJ43 IOSTANDARD LVDS} [get_ports clk_100mhz_0_p]
#set_property -dict {LOC BJ44 IOSTANDARD LVDS} [get_ports clk_100mhz_0_n]
#create_clock -period 10 -name clk_100mhz_0 [get_ports clk_100mhz_0_p]
# 100 MHz (DDR4)
#set_property -dict {LOC BH6 IOSTANDARD LVDS} [get_ports clk_100mhz_1_p]
#set_property -dict {LOC BJ6 IOSTANDARD LVDS} [get_ports clk_100mhz_1_n]
#create_clock -period 10 -name clk_100mhz_1 [get_ports clk_100mhz_1_p]
# 100 MHz
#set_property -dict {LOC G31 IOSTANDARD LVDS} [get_ports clk_100mhz_2_p]
#set_property -dict {LOC F31 IOSTANDARD LVDS} [get_ports clk_100mhz_2_n]
#create_clock -period 10 -name clk_100mhz_2 [get_ports clk_100mhz_2_p]
# SI570 user clock
#set_property -dict {LOC G30 IOSTANDARD LVDS} [get_ports clk_si570_p]
#set_property -dict {LOC F30 IOSTANDARD LVDS} [get_ports clk_si570_n]
#create_clock -period 6.4 -name clk_si570 [get_ports clk_si570_p]
# Reset button
set_property -dict {LOC L30 IOSTANDARD LVCMOS18} [get_ports reset]
set_false_path -from [get_ports {reset}]
set_input_delay 0 [get_ports {reset}]
# UART (U34 FT4232H channel CDBUS)
set_property -dict {LOC B33 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd}] ;# U34.39 CDBUS1 RXD
set_property -dict {LOC A28 IOSTANDARD LVCMOS18} [get_ports {uart_rxd}] ;# U34.38 CDBUS0 TXD
set_false_path -to [get_ports {uart_txd}]
set_output_delay 0 [get_ports {uart_txd}]
set_false_path -from [get_ports {uart_rxd}]
set_input_delay 0 [get_ports {uart_rxd}]
# HBM overtemp
set_property -dict {LOC D32 IOSTANDARD LVCMOS18} [get_ports hbm_cattrip]
set_false_path -to [get_ports {hbm_cattrip}]
set_output_delay 0 [get_ports {hbm_cattrip}]
# QSFP28 Interfaces
set_property -dict {LOC L53 } [get_ports {qsfp0_rx_p[0]}] ;# MGTYRXP0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L54 } [get_ports {qsfp0_rx_n[0]}] ;# MGTYRXN0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L48 } [get_ports {qsfp0_tx_p[0]}] ;# MGTYTXP0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L49 } [get_ports {qsfp0_tx_n[0]}] ;# MGTYTXN0_134 GTYE4_CHANNEL_X0Y40 / GTYE4_COMMON_X0Y10
set_property -dict {LOC K51 } [get_ports {qsfp0_rx_p[1]}] ;# MGTYRXP1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
set_property -dict {LOC K52 } [get_ports {qsfp0_rx_n[1]}] ;# MGTYRXN1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L44 } [get_ports {qsfp0_tx_p[1]}] ;# MGTYTXP1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
set_property -dict {LOC L45 } [get_ports {qsfp0_tx_n[1]}] ;# MGTYTXN1_134 GTYE4_CHANNEL_X0Y41 / GTYE4_COMMON_X0Y10
set_property -dict {LOC J53 } [get_ports {qsfp0_rx_p[2]}] ;# MGTYRXP2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
set_property -dict {LOC J54 } [get_ports {qsfp0_rx_n[2]}] ;# MGTYRXN2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
set_property -dict {LOC K46 } [get_ports {qsfp0_tx_p[2]}] ;# MGTYTXP2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
set_property -dict {LOC K47 } [get_ports {qsfp0_tx_n[2]}] ;# MGTYTXN2_134 GTYE4_CHANNEL_X0Y42 / GTYE4_COMMON_X0Y10
set_property -dict {LOC H51 } [get_ports {qsfp0_rx_p[3]}] ;# MGTYRXP3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
set_property -dict {LOC H52 } [get_ports {qsfp0_rx_n[3]}] ;# MGTYRXN3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
set_property -dict {LOC J48 } [get_ports {qsfp0_tx_p[3]}] ;# MGTYTXP3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
set_property -dict {LOC J49 } [get_ports {qsfp0_tx_n[3]}] ;# MGTYTXN3_134 GTYE4_CHANNEL_X0Y43 / GTYE4_COMMON_X0Y10
set_property -dict {LOC T42 } [get_ports {qsfp0_mgt_refclk_0_p}] ;# MGTREFCLK0P_134 from SI570
set_property -dict {LOC T43 } [get_ports {qsfp0_mgt_refclk_0_n}] ;# MGTREFCLK0N_134 from SI570
#set_property -dict {LOC R40 } [get_ports {qsfp0_mgt_refclk_1_p}] ;# MGTREFCLK1P_134 from SI546
#set_property -dict {LOC R41 } [get_ports {qsfp0_mgt_refclk_1_n}] ;# MGTREFCLK1N_134 from SI546
set_property -dict {LOC H32 IOSTANDARD LVCMOS18} [get_ports {qsfp0_refclk_oe_b}]
set_property -dict {LOC G32 IOSTANDARD LVCMOS18} [get_ports {qsfp0_refclk_fs}]
# 156.25 MHz MGT reference clock (from SI570)
create_clock -period 6.400 -name qsfp0_mgt_refclk_0 [get_ports {qsfp0_mgt_refclk_0_p}]
# 156.25 MHz MGT reference clock (from SI546, fs = 0)
#create_clock -period 6.400 -name qsfp0_mgt_refclk_1 [get_ports {qsfp0_mgt_refclk_1_p}]
# 161.1328125 MHz MGT reference clock (from SI546, fs = 1)
#create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports {qsfp0_mgt_refclk_1_p}]
set_false_path -to [get_ports {qsfp0_refclk_oe_b qsfp0_refclk_fs}]
set_output_delay 0 [get_ports {qsfp0_refclk_oe_b qsfp0_refclk_fs}]
set_property -dict {LOC G53 } [get_ports {qsfp1_rx_p[0]}] ;# MGTYRXP0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
set_property -dict {LOC G54 } [get_ports {qsfp1_rx_n[0]}] ;# MGTYRXN0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
set_property -dict {LOC G48 } [get_ports {qsfp1_tx_p[0]}] ;# MGTYTXP0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
set_property -dict {LOC G49 } [get_ports {qsfp1_tx_n[0]}] ;# MGTYTXN0_135 GTYE4_CHANNEL_X0Y44 / GTYE4_COMMON_X0Y11
set_property -dict {LOC F51 } [get_ports {qsfp1_rx_p[1]}] ;# MGTYRXP1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
set_property -dict {LOC F52 } [get_ports {qsfp1_rx_n[1]}] ;# MGTYRXN1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
set_property -dict {LOC E48 } [get_ports {qsfp1_tx_p[1]}] ;# MGTYTXP1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
set_property -dict {LOC E49 } [get_ports {qsfp1_tx_n[1]}] ;# MGTYTXN1_135 GTYE4_CHANNEL_X0Y45 / GTYE4_COMMON_X0Y11
set_property -dict {LOC E53 } [get_ports {qsfp1_rx_p[2]}] ;# MGTYRXP2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
set_property -dict {LOC E54 } [get_ports {qsfp1_rx_n[2]}] ;# MGTYRXN2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
set_property -dict {LOC C48 } [get_ports {qsfp1_tx_p[2]}] ;# MGTYTXP2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
set_property -dict {LOC C49 } [get_ports {qsfp1_tx_n[2]}] ;# MGTYTXN2_135 GTYE4_CHANNEL_X0Y46 / GTYE4_COMMON_X0Y11
set_property -dict {LOC D51 } [get_ports {qsfp1_rx_p[3]}] ;# MGTYRXP3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
set_property -dict {LOC D52 } [get_ports {qsfp1_rx_n[3]}] ;# MGTYRXN3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
set_property -dict {LOC A49 } [get_ports {qsfp1_tx_p[3]}] ;# MGTYTXP3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
set_property -dict {LOC A50 } [get_ports {qsfp1_tx_n[3]}] ;# MGTYTXN3_135 GTYE4_CHANNEL_X0Y47 / GTYE4_COMMON_X0Y11
set_property -dict {LOC P42 } [get_ports {qsfp1_mgt_refclk_0_p}] ;# MGTREFCLK0P_135 from SI570
set_property -dict {LOC P43 } [get_ports {qsfp1_mgt_refclk_0_n}] ;# MGTREFCLK0N_135 from SI570
#set_property -dict {LOC M42 } [get_ports {qsfp1_mgt_refclk_1_p}] ;# MGTREFCLK1P_135 from SI546
#set_property -dict {LOC M43 } [get_ports {qsfp1_mgt_refclk_1_n}] ;# MGTREFCLK1N_135 from SI546
set_property -dict {LOC H30 IOSTANDARD LVCMOS18} [get_ports {qsfp1_refclk_oe_b}]
set_property -dict {LOC G33 IOSTANDARD LVCMOS18} [get_ports {qsfp1_refclk_fs}]
# 156.25 MHz MGT reference clock (from SI570)
create_clock -period 6.400 -name qsfp1_mgt_refclk_0 [get_ports {qsfp1_mgt_refclk_0_p}]
# 156.25 MHz MGT reference clock (from SI546, fs = 0)
#create_clock -period 6.400 -name qsfp1_mgt_refclk_1 [get_ports {qsfp1_mgt_refclk_1_p}]
# 161.1328125 MHz MGT reference clock (from SI546, fs = 1)
#create_clock -period 6.206 -name qsfp1_mgt_refclk_1 [get_ports {qsfp1_mgt_refclk_1_p}]
set_false_path -to [get_ports {qsfp1_refclk_oe_b qsfp1_refclk_fs}]
set_output_delay 0 [get_ports {qsfp1_refclk_oe_b qsfp1_refclk_fs}]
# PCIe Interface
set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AL11} [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AL10} [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN6 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN5 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN11} [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN10} [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AP9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AP8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AP4 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AP3 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR11} [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR10} [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR7 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR6 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT9 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT8 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU11} [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU10} [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW6 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW5 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AV9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AV8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW11} [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW10} [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC BA6 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA5 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA11} [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA10} [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB9 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB8 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB4 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB3 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC11} [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC10} [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AL15} [get_ports {pcie_refclk_0_p}] ;# MGTREFCLK0P_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AL14} [get_ports {pcie_refclk_0_n}] ;# MGTREFCLK0N_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AK13} [get_ports {pcie_refclk_2_p}] ;# MGTREFCLK1P_227 (for async x8 bifurcated lanes 0-7)
#set_property -dict {LOC AK12} [get_ports {pcie_refclk_2_n}] ;# MGTREFCLK1N_227 (for async x8 bifurcated lanes 0-7)
set_property -dict {LOC AR15} [get_ports {pcie_refclk_1_p}] ;# MGTREFCLK0P_225 (for x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC AR14} [get_ports {pcie_refclk_1_n}] ;# MGTREFCLK0N_225 (for x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AP13} [get_ports {pcie_refclk_3_p}] ;# MGTREFCLK1P_225 (for async x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AP12} [get_ports {pcie_refclk_3_n}] ;# MGTREFCLK1N_225 (for async x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC BH26 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {pcie_reset_n}]
# 100 MHz MGT reference clock
#create_clock -period 10 -name pcie_mgt_refclk_0 [get_ports {pcie_refclk_0_p}]
create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports {pcie_refclk_1_p}]
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports {pcie_refclk_2_p}]
#create_clock -period 10 -name pcie_mgt_refclk_3 [get_ports {pcie_refclk_3_p}]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]
# DDR4 C0
#set_property -dict {LOC BF46 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[0]}]
#set_property -dict {LOC BG43 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[1]}]
#set_property -dict {LOC BK45 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[2]}]
#set_property -dict {LOC BF42 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[3]}]
#set_property -dict {LOC BL45 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[4]}]
#set_property -dict {LOC BF43 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[5]}]
#set_property -dict {LOC BG42 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[6]}]
#set_property -dict {LOC BL43 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[7]}]
#set_property -dict {LOC BK43 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[8]}]
#set_property -dict {LOC BM42 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[9]}]
#set_property -dict {LOC BG45 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[10]}]
#set_property -dict {LOC BD41 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[11]}]
#set_property -dict {LOC BL42 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[12]}]
#set_property -dict {LOC BE44 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[13]}]
#set_property -dict {LOC BE43 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[14]}]
#set_property -dict {LOC BL46 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[15]}]
#set_property -dict {LOC BH44 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_adr[16]}]
#set_property -dict {LOC BH45 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_ba[0]}]
#set_property -dict {LOC BM47 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_ba[1]}]
#set_property -dict {LOC BF41 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_bg[0]}]
#set_property -dict {LOC BE41 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_bg[1]}]
#set_property -dict {LOC BH46 IOSTANDARD DIFF_SSTL12_DCI } [get_ports {ddr4_c0_ck_t}]
#set_property -dict {LOC BJ46 IOSTANDARD DIFF_SSTL12_DCI } [get_ports {ddr4_c0_ck_c}]
#set_property -dict {LOC BH42 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cke}]
#set_property -dict {LOC BK46 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_cs_n}]
#set_property -dict {LOC BH41 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_act_n}]
#set_property -dict {LOC BG44 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_odt}]
#set_property -dict {LOC BF45 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c0_par}]
#set_property -dict {LOC BG33 IOSTANDARD LVCMOS12 DRIVE 8} [get_ports {ddr4_c0_reset_n}]
#set_property -dict {LOC BN32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[0]}]
#set_property -dict {LOC BP32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[1]}]
#set_property -dict {LOC BL30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[2]}]
#set_property -dict {LOC BM30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[3]}]
#set_property -dict {LOC BP29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[4]}]
#set_property -dict {LOC BP28 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[5]}]
#set_property -dict {LOC BP31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[6]}]
#set_property -dict {LOC BN31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[7]}]
#set_property -dict {LOC BJ31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[8]}]
#set_property -dict {LOC BH31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[9]}]
#set_property -dict {LOC BF32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[10]}]
#set_property -dict {LOC BF33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[11]}]
#set_property -dict {LOC BH29 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[12]}]
#set_property -dict {LOC BH30 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[13]}]
#set_property -dict {LOC BF31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[14]}]
#set_property -dict {LOC BG32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[15]}]
#set_property -dict {LOC BK31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[16]}]
#set_property -dict {LOC BL31 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[17]}]
#set_property -dict {LOC BK33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[18]}]
#set_property -dict {LOC BL33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[19]}]
#set_property -dict {LOC BL32 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[20]}]
#set_property -dict {LOC BM33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[21]}]
#set_property -dict {LOC BN34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[22]}]
#set_property -dict {LOC BP34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[23]}]
#set_property -dict {LOC BH34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[24]}]
#set_property -dict {LOC BH35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[25]}]
#set_property -dict {LOC BF35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[26]}]
#set_property -dict {LOC BF36 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[27]}]
#set_property -dict {LOC BJ33 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[28]}]
#set_property -dict {LOC BJ34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[29]}]
#set_property -dict {LOC BG34 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[30]}]
#set_property -dict {LOC BG35 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[31]}]
#set_property -dict {LOC BM52 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[32]}]
#set_property -dict {LOC BL53 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[33]}]
#set_property -dict {LOC BL52 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[34]}]
#set_property -dict {LOC BL51 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[35]}]
#set_property -dict {LOC BN50 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[36]}]
#set_property -dict {LOC BN51 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[37]}]
#set_property -dict {LOC BN49 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[38]}]
#set_property -dict {LOC BM48 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[39]}]
#set_property -dict {LOC BE50 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[40]}]
#set_property -dict {LOC BE49 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[41]}]
#set_property -dict {LOC BE51 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[42]}]
#set_property -dict {LOC BD51 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[43]}]
#set_property -dict {LOC BF52 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[44]}]
#set_property -dict {LOC BF51 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[45]}]
#set_property -dict {LOC BG50 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[46]}]
#set_property -dict {LOC BF50 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[47]}]
#set_property -dict {LOC BH50 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[48]}]
#set_property -dict {LOC BJ51 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[49]}]
#set_property -dict {LOC BH51 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[50]}]
#set_property -dict {LOC BH49 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[51]}]
#set_property -dict {LOC BK50 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[52]}]
#set_property -dict {LOC BK51 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[53]}]
#set_property -dict {LOC BJ49 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[54]}]
#set_property -dict {LOC BJ48 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[55]}]
#set_property -dict {LOC BN44 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[56]}]
#set_property -dict {LOC BN45 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[57]}]
#set_property -dict {LOC BM44 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[58]}]
#set_property -dict {LOC BM45 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[59]}]
#set_property -dict {LOC BP43 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[60]}]
#set_property -dict {LOC BP44 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[61]}]
#set_property -dict {LOC BN47 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[62]}]
#set_property -dict {LOC BP47 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[63]}]
#set_property -dict {LOC BG54 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[64]}]
#set_property -dict {LOC BG53 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[65]}]
#set_property -dict {LOC BE53 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[66]}]
#set_property -dict {LOC BE54 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[67]}]
#set_property -dict {LOC BH52 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[68]}]
#set_property -dict {LOC BG52 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[69]}]
#set_property -dict {LOC BK54 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[70]}]
#set_property -dict {LOC BK53 IOSTANDARD POD12_DCI } [get_ports {ddr4_c0_dq[71]}]
#set_property -dict {LOC BN29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[0]}]
#set_property -dict {LOC BN30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[0]}]
#set_property -dict {LOC BM28 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[1]}]
#set_property -dict {LOC BM29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[1]}]
#set_property -dict {LOC BJ29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[2]}]
#set_property -dict {LOC BK30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[2]}]
#set_property -dict {LOC BG29 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[3]}]
#set_property -dict {LOC BG30 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[3]}]
#set_property -dict {LOC BL35 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[4]}]
#set_property -dict {LOC BM35 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[4]}]
#set_property -dict {LOC BM34 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[5]}]
#set_property -dict {LOC BN35 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[5]}]
#set_property -dict {LOC BK34 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[6]}]
#set_property -dict {LOC BK35 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[6]}]
#set_property -dict {LOC BH32 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[7]}]
#set_property -dict {LOC BJ32 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[7]}]
#set_property -dict {LOC BM49 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[8]}]
#set_property -dict {LOC BM50 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[8]}]
#set_property -dict {LOC BP48 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[9]}]
#set_property -dict {LOC BP49 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[9]}]
#set_property -dict {LOC BF47 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[10]}]
#set_property -dict {LOC BF48 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[10]}]
#set_property -dict {LOC BG48 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[11]}]
#set_property -dict {LOC BG49 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[11]}]
#set_property -dict {LOC BH47 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[12]}]
#set_property -dict {LOC BJ47 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[12]}]
#set_property -dict {LOC BK48 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[13]}]
#set_property -dict {LOC BK49 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[13]}]
#set_property -dict {LOC BN46 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[14]}]
#set_property -dict {LOC BP46 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[14]}]
#set_property -dict {LOC BN42 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[15]}]
#set_property -dict {LOC BP42 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[15]}]
#set_property -dict {LOC BH54 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[16]}]
#set_property -dict {LOC BJ54 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[16]}]
#set_property -dict {LOC BJ52 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_t[17]}]
#set_property -dict {LOC BJ53 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c0_dqs_c[17]}]
# DDR4 C1
#set_property -dict {LOC BF7 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[0]}]
#set_property -dict {LOC BK1 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[1]}]
#set_property -dict {LOC BF6 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[2]}]
#set_property -dict {LOC BF5 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[3]}]
#set_property -dict {LOC BE3 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[4]}]
#set_property -dict {LOC BE6 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[5]}]
#set_property -dict {LOC BE5 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[6]}]
#set_property -dict {LOC BG7 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[7]}]
#set_property -dict {LOC BJ1 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[8]}]
#set_property -dict {LOC BG2 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[9]}]
#set_property -dict {LOC BJ8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[10]}]
#set_property -dict {LOC BE4 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[11]}]
#set_property -dict {LOC BL2 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[12]}]
#set_property -dict {LOC BK5 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[13]}]
#set_property -dict {LOC BK8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[14]}]
#set_property -dict {LOC BJ4 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[15]}]
#set_property -dict {LOC BF8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_adr[16]}]
#set_property -dict {LOC BG8 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_ba[0]}]
#set_property -dict {LOC BK4 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_ba[1]}]
#set_property -dict {LOC BF3 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_bg[0]}]
#set_property -dict {LOC BF2 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_bg[1]}]
#set_property -dict {LOC BJ3 IOSTANDARD DIFF_SSTL12_DCI } [get_ports {ddr4_c1_ck_t}]
#set_property -dict {LOC BJ2 IOSTANDARD DIFF_SSTL12_DCI } [get_ports {ddr4_c1_ck_c}]
#set_property -dict {LOC BE1 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cke}]
#set_property -dict {LOC BL3 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_cs_n}]
#set_property -dict {LOC BG3 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_act_n}]
#set_property -dict {LOC BH2 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_odt}]
#set_property -dict {LOC BH1 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_c1_par}]
#set_property -dict {LOC BH12 IOSTANDARD LVCMOS12 DRIVE 8} [get_ports {ddr4_c1_reset_n}]
#set_property -dict {LOC A11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[0]}]
#set_property -dict {LOC A10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[1]}]
#set_property -dict {LOC A9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[2]}]
#set_property -dict {LOC A8 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[3]}]
#set_property -dict {LOC B12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[4]}]
#set_property -dict {LOC B10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[5]}]
#set_property -dict {LOC C12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[6]}]
#set_property -dict {LOC B11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[7]}]
#set_property -dict {LOC E11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[8]}]
#set_property -dict {LOC D11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[9]}]
#set_property -dict {LOC E12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[10]}]
#set_property -dict {LOC F11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[11]}]
#set_property -dict {LOC F10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[12]}]
#set_property -dict {LOC E9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[13]}]
#set_property -dict {LOC F9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[14]}]
#set_property -dict {LOC G11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[15]}]
#set_property -dict {LOC H12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[16]}]
#set_property -dict {LOC G13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[17]}]
#set_property -dict {LOC H13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[18]}]
#set_property -dict {LOC H14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[19]}]
#set_property -dict {LOC J11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[20]}]
#set_property -dict {LOC J12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[21]}]
#set_property -dict {LOC J15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[22]}]
#set_property -dict {LOC J14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[23]}]
#set_property -dict {LOC A14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[24]}]
#set_property -dict {LOC C15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[25]}]
#set_property -dict {LOC A15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[26]}]
#set_property -dict {LOC B15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[27]}]
#set_property -dict {LOC F15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[28]}]
#set_property -dict {LOC E14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[29]}]
#set_property -dict {LOC F14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[30]}]
#set_property -dict {LOC F13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[31]}]
#set_property -dict {LOC BM3 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[32]}]
#set_property -dict {LOC BM4 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[33]}]
#set_property -dict {LOC BM5 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[34]}]
#set_property -dict {LOC BL6 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[35]}]
#set_property -dict {LOC BN4 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[36]}]
#set_property -dict {LOC BN5 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[37]}]
#set_property -dict {LOC BN6 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[38]}]
#set_property -dict {LOC BN7 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[39]}]
#set_property -dict {LOC BJ9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[40]}]
#set_property -dict {LOC BK9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[41]}]
#set_property -dict {LOC BK10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[42]}]
#set_property -dict {LOC BL10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[43]}]
#set_property -dict {LOC BM9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[44]}]
#set_property -dict {LOC BN9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[45]}]
#set_property -dict {LOC BN10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[46]}]
#set_property -dict {LOC BM10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[47]}]
#set_property -dict {LOC BM15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[48]}]
#set_property -dict {LOC BM14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[49]}]
#set_property -dict {LOC BL15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[50]}]
#set_property -dict {LOC BM13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[51]}]
#set_property -dict {LOC BN12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[52]}]
#set_property -dict {LOC BM12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[53]}]
#set_property -dict {LOC BP13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[54]}]
#set_property -dict {LOC BP14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[55]}]
#set_property -dict {LOC BJ13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[56]}]
#set_property -dict {LOC BJ12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[57]}]
#set_property -dict {LOC BH15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[58]}]
#set_property -dict {LOC BH14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[59]}]
#set_property -dict {LOC BK14 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[60]}]
#set_property -dict {LOC BK15 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[61]}]
#set_property -dict {LOC BL12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[62]}]
#set_property -dict {LOC BL13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[63]}]
#set_property -dict {LOC BE9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[64]}]
#set_property -dict {LOC BE10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[65]}]
#set_property -dict {LOC BF10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[66]}]
#set_property -dict {LOC BE11 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[67]}]
#set_property -dict {LOC BG13 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[68]}]
#set_property -dict {LOC BG12 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[69]}]
#set_property -dict {LOC BG9 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[70]}]
#set_property -dict {LOC BG10 IOSTANDARD POD12_DCI } [get_ports {ddr4_c1_dq[71]}]
#set_property -dict {LOC B13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[0]}]
#set_property -dict {LOC A13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[0]}]
#set_property -dict {LOC C10 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[1]}]
#set_property -dict {LOC C9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[1]}]
#set_property -dict {LOC D10 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[2]}]
#set_property -dict {LOC D9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[2]}]
#set_property -dict {LOC H10 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[3]}]
#set_property -dict {LOC G10 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[3]}]
#set_property -dict {LOC H15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[4]}]
#set_property -dict {LOC G15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[4]}]
#set_property -dict {LOC K14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[5]}]
#set_property -dict {LOC K13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[5]}]
#set_property -dict {LOC D15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[6]}]
#set_property -dict {LOC D14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[6]}]
#set_property -dict {LOC E13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[7]}]
#set_property -dict {LOC D12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[7]}]
#set_property -dict {LOC BL7 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[8]}]
#set_property -dict {LOC BM7 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[8]}]
#set_property -dict {LOC BP7 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[9]}]
#set_property -dict {LOC BP6 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[9]}]
#set_property -dict {LOC BL8 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[10]}]
#set_property -dict {LOC BM8 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[10]}]
#set_property -dict {LOC BP9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[11]}]
#set_property -dict {LOC BP8 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[11]}]
#set_property -dict {LOC BN15 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[12]}]
#set_property -dict {LOC BN14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[12]}]
#set_property -dict {LOC BP12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[13]}]
#set_property -dict {LOC BP11 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[13]}]
#set_property -dict {LOC BJ14 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[14]}]
#set_property -dict {LOC BK13 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[14]}]
#set_property -dict {LOC BJ11 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[15]}]
#set_property -dict {LOC BK11 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[15]}]
#set_property -dict {LOC BF12 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[16]}]
#set_property -dict {LOC BF11 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[16]}]
#set_property -dict {LOC BH10 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_t[17]}]
#set_property -dict {LOC BH9 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_c1_dqs_c[17]}]

View File

@@ -0,0 +1,222 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# XDC constraints for the Xilinx Alveo U45N/SN1022 board
# part: xcu26-vsva1365-2LV-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 72.9 [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
# limit with auxiliary PCIe power input connected
set_operating_conditions -design_power_budget 160
# System clocks
# 300 MHz
#set_property -dict {LOC AK23 IOSTANDARD LVDS} [get_ports clk_300mhz_p]
#set_property -dict {LOC AL23 IOSTANDARD LVDS} [get_ports clk_300mhz_n]
#create_clock -period 10 -name clk_300mhz [get_ports clk_300mhz_p]
# 300 MHz
#set_property -dict {LOC AN27 IOSTANDARD LVDS} [get_ports clk_ddr4_c0_p]
#set_property -dict {LOC AN28 IOSTANDARD LVDS} [get_ports clk_ddr4_c0_n]
#create_clock -period 10 -name clk_ddr4_c0 [get_ports clk_ddr4_c0_p]
# 300 MHz
#set_property -dict {LOC H34 IOSTANDARD LVDS} [get_ports clk_ddr4_c1_p]
#set_property -dict {LOC H35 IOSTANDARD LVDS} [get_ports clk_ddr4_c1_n]
#create_clock -period 10 -name clk_ddr4_c1 [get_ports clk_ddr4_c1_p]
# LEDs
set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {card_heart_bit}]
set_property -dict {LOC AL24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {card_status_led}]
set_property -dict {LOC AM23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_act[0]}]
set_property -dict {LOC AM22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_g[0]}]
set_property -dict {LOC AN23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_y[0]}]
set_property -dict {LOC AJ25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_act[1]}]
set_property -dict {LOC AH25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_g[1]}]
set_property -dict {LOC AN24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_y[1]}]
set_false_path -to [get_ports {qsfp_led_act[*] qsfp_led_stat_g[*] qsfp_led_stat_y[*]}]
set_output_delay 0 [get_ports {qsfp_led_act[*] qsfp_led_stat_g[*] qsfp_led_stat_y[*]}]
# UART (DMB-2 FT4232H channel CDBUS)
set_property -dict {LOC AP24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] ;# DMB-2 U4.39 RXD CDBUS1
set_property -dict {LOC AR24 IOSTANDARD LVCMOS18} [get_ports uart_rxd] ;# DMB-2 U4.38 TXD CDBUS0
set_false_path -to [get_ports {uart_txd}]
set_output_delay 0 [get_ports {uart_txd}]
set_false_path -from [get_ports {uart_rxd}]
set_input_delay 0 [get_ports {uart_rxd}]
# BMC
#set_property -dict {LOC AM17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {suc_gpio[0]}]
#set_property -dict {LOC AL18 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {suc_gpio[1]}]
#set_property -dict {LOC AK21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {suc_uart_txd}]
#set_property -dict {LOC AJ21 IOSTANDARD LVCMOS18} [get_ports {suc_uart_rxd}]
#set_false_path -to [get_ports {suc_uart_txd}]
#set_output_delay 0 [get_ports {suc_uart_txd}]
#set_false_path -from [get_ports {suc_gpio[*] suc_uart_rxd}]
#set_input_delay 0 [get_ports {suc_gpio[*] suc_uart_rxd}]
# SI5394 (SI5394J-A-GM)
# IN0: 20 MHz TCXO
# OUT1: 161.1328125 MHz to QSFP GTM and GTY
# OUT2: 100 MHz to ...
# OUT3: 300 MHz to ...
#set_property -dict {LOC AN20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {si5394_rst_b}]
#set_property -dict {LOC AH19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_int_b}]
#set_property -dict {LOC AJ19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_lol_b}]
#set_property -dict {LOC AJ20 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_los_b}]
#set_false_path -to [get_ports {si5394_rst_b}]
#set_output_delay 0 [get_ports {si5394_rst_b}]
#set_false_path -from [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
#set_input_delay 0 [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
# QSFP28 Interfaces
#set_property -dict {LOC A13} [get_ports {qsfp0_rx_p[0]}] ;# MGTMRXP0_234 GTM_DUAL_X0Y1 CH0
#set_property -dict {LOC A12} [get_ports {qsfp0_rx_n[0]}] ;# MGTMRXN0_234 GTM_DUAL_X0Y1 CH0
#set_property -dict {LOC C15} [get_ports {qsfp0_tx_p[0]}] ;# MGTMTXP0_234 GTM_DUAL_X0Y1 CH0
#set_property -dict {LOC C14} [get_ports {qsfp0_tx_n[0]}] ;# MGTMTXN0_234 GTM_DUAL_X0Y1 CH0
#set_property -dict {LOC A16} [get_ports {qsfp0_rx_p[1]}] ;# MGTMRXP1_234 GTM_DUAL_X0Y1 CH1
#set_property -dict {LOC A15} [get_ports {qsfp0_rx_n[1]}] ;# MGTMRXN1_234 GTM_DUAL_X0Y1 CH1
#set_property -dict {LOC C18} [get_ports {qsfp0_tx_p[1]}] ;# MGTMTXP1_234 GTM_DUAL_X0Y1 CH1
#set_property -dict {LOC C17} [get_ports {qsfp0_tx_n[1]}] ;# MGTMTXN1_234 GTM_DUAL_X0Y1 CH1
#set_property -dict {LOC A7 } [get_ports {qsfp0_rx_p[2]}] ;# MGTMRXP0_233 GTM_DUAL_X0Y0 CH0
#set_property -dict {LOC A6 } [get_ports {qsfp0_rx_n[2]}] ;# MGTMRXN0_233 GTM_DUAL_X0Y0 CH0
#set_property -dict {LOC C9 } [get_ports {qsfp0_tx_p[2]}] ;# MGTMTXP0_233 GTM_DUAL_X0Y0 CH0
#set_property -dict {LOC C8 } [get_ports {qsfp0_tx_n[2]}] ;# MGTMTXN0_233 GTM_DUAL_X0Y0 CH0
#set_property -dict {LOC A10} [get_ports {qsfp0_rx_p[3]}] ;# MGTMRXP1_233 GTM_DUAL_X0Y0 CH1
#set_property -dict {LOC A9 } [get_ports {qsfp0_rx_n[3]}] ;# MGTMRXN1_233 GTM_DUAL_X0Y0 CH1
#set_property -dict {LOC C12} [get_ports {qsfp0_tx_p[3]}] ;# MGTMTXP1_233 GTM_DUAL_X0Y0 CH1
#set_property -dict {LOC C11} [get_ports {qsfp0_tx_n[3]}] ;# MGTMTXN1_233 GTM_DUAL_X0Y0 CH1
#set_property -dict {LOC G10} [get_ports {qsfp0_mgt_refclk_0_p}] ;# MGTREFCLK0P_234 from SI5394 OUT1 via U16
#set_property -dict {LOC G9 } [get_ports {qsfp0_mgt_refclk_0_n}] ;# MGTREFCLK0N_234 from SI5394 OUT1 via U16
#set_property -dict {LOC J10} [get_ports {qsfp0_mgt_refclk_1_p}] ;# MGTREFCLK1P_233 from SI5394 OUT1 via U16
#set_property -dict {LOC J9 } [get_ports {qsfp0_mgt_refclk_1_n}] ;# MGTREFCLK1N_233 from SI5394 OUT1 via U16
# 161.1328125 MHz MGT reference clock (SI5394 OUT1 via U16)
#create_clock -period 6.206 -name qsfp0_mgt_refclk_0 [get_ports {qsfp0_mgt_refclk_0_p}]
#create_clock -period 6.206 -name qsfp0_mgt_refclk_1 [get_ports {qsfp0_mgt_refclk_1_p}]
set_property -dict {LOC K4} [get_ports {qsfp1_rx_p[0]}] ;# MGTYRXP0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC K3} [get_ports {qsfp1_rx_n[0]}] ;# MGTYRXN0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J7} [get_ports {qsfp1_tx_p[0]}] ;# MGTYTXP0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J6} [get_ports {qsfp1_tx_n[0]}] ;# MGTYTXN0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J2} [get_ports {qsfp1_rx_p[1]}] ;# MGTYRXP1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J1} [get_ports {qsfp1_rx_n[1]}] ;# MGTYRXN1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC H5} [get_ports {qsfp1_tx_p[1]}] ;# MGTYTXP1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC H4} [get_ports {qsfp1_tx_n[1]}] ;# MGTYTXN1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G2} [get_ports {qsfp1_rx_p[2]}] ;# MGTYRXP2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G1} [get_ports {qsfp1_rx_n[2]}] ;# MGTYRXN2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G7} [get_ports {qsfp1_tx_p[2]}] ;# MGTYTXP2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G6} [get_ports {qsfp1_tx_n[2]}] ;# MGTYTXN2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC E2} [get_ports {qsfp1_rx_p[3]}] ;# MGTYRXP3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC E1} [get_ports {qsfp1_rx_n[3]}] ;# MGTYRXN3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC F5} [get_ports {qsfp1_tx_p[3]}] ;# MGTYTXP3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC F4} [get_ports {qsfp1_tx_n[3]}] ;# MGTYTXN3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC P9} [get_ports {qsfp1_mgt_refclk_p}] ;# MGTREFCLK0P_231 from SI5394 OUT1 via U16
set_property -dict {LOC P8} [get_ports {qsfp1_mgt_refclk_n}] ;# MGTREFCLK0N_231 from SI5394 OUT1 via U16
# 161.1328125 MHz MGT reference clock (SI5394 OUT1 via U16)
create_clock -period 6.206 -name qsfp1_mgt_refclk [get_ports {qsfp1_mgt_refclk_p}]
# PCIe Interface
set_property -dict {LOC AF4 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AF3 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AD8 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AD7 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AG2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AG1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AE6 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AE5 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AJ2 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AJ1 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AG6 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AG5 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AK4 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AK3 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AH4 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AH3 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AJ6 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AJ5 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AM4 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AM3 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AL6 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AL5 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AN6 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AN5 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AP4 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AP3 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AP8 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AP7 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU6 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU5 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AR6 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AR5 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT8 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT7 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AR10} [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AR9 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU10} [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU9 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT12} [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT11} [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU14} [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU13} [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR14} [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR13} [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT16} [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT15} [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR18} [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR17} [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU18} [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU17} [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT20} [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT19} [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU22} [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU21} [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR22} [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR21} [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AF8 } [get_ports {pcie_refclk_0_p}] ;# MGTREFCLK0P_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AF7 } [get_ports {pcie_refclk_0_n}] ;# MGTREFCLK0N_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AE10} [get_ports {pcie_refclk_2_p}] ;# MGTREFCLK1P_227 (for async x8 bifurcated lanes 0-7)
#set_property -dict {LOC AE9 } [get_ports {pcie_refclk_2_n}] ;# MGTREFCLK1N_227 (for async x8 bifurcated lanes 0-7)
set_property -dict {LOC AL10} [get_ports {pcie_refclk_1_p}] ;# MGTREFCLK0P_225 (for x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC AL9 } [get_ports {pcie_refclk_1_n}] ;# MGTREFCLK0N_225 (for x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AK8 } [get_ports {pcie_refclk_3_p}] ;# MGTREFCLK1P_225 (for async x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AK7 } [get_ports {pcie_refclk_3_n}] ;# MGTREFCLK1N_225 (for async x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC AK18 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {pcie_reset_n}]
# 100 MHz MGT reference clock
#create_clock -period 10 -name pcie_mgt_refclk_0 [get_ports {pcie_refclk_0_p}]
create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports {pcie_refclk_1_p}]
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports {pcie_refclk_2_p}]
#create_clock -period 10 -name pcie_mgt_refclk_3 [get_ports {pcie_refclk_3_p}]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]

View File

@@ -0,0 +1,212 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# XDC constraints for the Xilinx Alveo U50 board
# part: xcu50-fsvh2104-2-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 85.0 [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
set_operating_conditions -design_power_budget 63
# System clocks
# 100 MHz
#set_property -dict {LOC G17 IOSTANDARD LVDS} [get_ports clk_100mhz_0_p]
#set_property -dict {LOC G16 IOSTANDARD LVDS} [get_ports clk_100mhz_0_n]
#create_clock -period 10 -name clk_100mhz_0 [get_ports clk_100mhz_0_p]
# 100 MHz
#set_property -dict {LOC BB18 IOSTANDARD LVDS} [get_ports clk_100mhz_1_p]
#set_property -dict {LOC BC18 IOSTANDARD LVDS} [get_ports clk_100mhz_1_n]
#create_clock -period 10 -name clk_100mhz_1 [get_ports clk_100mhz_1_p]
# LEDs
set_property -dict {LOC E18 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_led_act]
set_property -dict {LOC E16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_led_stat_g]
set_property -dict {LOC F17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports qsfp_led_stat_y]
set_false_path -to [get_ports {qsfp_led_act qsfp_led_stat_g qsfp_led_stat_y}]
set_output_delay 0 [get_ports {qsfp_led_act qsfp_led_stat_g qsfp_led_stat_y}]
# UART (DMB-1 FT4232H)
set_property -dict {LOC BE26 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[0]}] ;# DMB-1 U9.39 CDBUS1 RXD
set_property -dict {LOC BF26 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[0]}] ;# DMB-1 U9.38 CDBUS0 TXD
set_property -dict {LOC A17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[1]}] ;# DMB-1 U9.52 DDBUS1 RXD
set_property -dict {LOC B15 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[1]}] ;# DMB-1 U9.48 DDBUS0 TXD
set_property -dict {LOC A19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[2]}] ;# DMB-1 U18.39 CDBUS1 RXD
set_property -dict {LOC A18 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[2]}] ;# DMB-1 U18.38 CDBUS0 TXD
set_false_path -to [get_ports {uart_txd[*]}]
set_output_delay 0 [get_ports {uart_txd[*]}]
set_false_path -from [get_ports {uart_rxd[*]}]
set_input_delay 0 [get_ports {uart_rxd[*]}]
# BMC
#set_property -dict {LOC C16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
#set_property -dict {LOC C17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
#set_property -dict {LOC BB25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
#set_property -dict {LOC BB26 IOSTANDARD LVCMOS18} [get_ports {msp_uart_rxd}]
#set_false_path -to [get_ports {msp_uart_txd}]
#set_output_delay 0 [get_ports {msp_uart_txd}]
#set_false_path -from [get_ports {msp_gpio[*] msp_uart_rxd}]
#set_input_delay 0 [get_ports {msp_gpio[*] msp_uart_rxd}]
# HBM overtemp
set_property -dict {LOC J18 IOSTANDARD LVCMOS18} [get_ports hbm_cattrip]
set_false_path -to [get_ports {hbm_cattrip}]
set_output_delay 0 [get_ports {hbm_cattrip}]
# SI5394 (SI5394B-A10605-GM)
# I2C address 0x68
# IN0: 161.1328125 MHz from qsfp_recclk
# OUT0: 161.1328125 MHz to qsfp_mgt_refclk_0
# OUT2: 322.265625 MHz to qsfp_mgt_refclk_1
# OUT3: 100 MHz to clk_100mhz_0, clk_100mhz_1, pcie_refclk_2, pcie_refclk_3
#set_property -dict {LOC F20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {si5394_rst_b}]
#set_property -dict {LOC H18 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_int_b}]
#set_property -dict {LOC G19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_lol_b}]
#set_property -dict {LOC H19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_los_b}]
#set_property -dict {LOC J16 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports {si5394_sda}]
#set_property -dict {LOC L19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports {si5394_scl}]
#set_false_path -to [get_ports {si5394_rst_b}]
#set_output_delay 0 [get_ports {si5394_rst_b}]
#set_false_path -from [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
#set_input_delay 0 [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
#set_false_path -to [get_ports {si5394_i2c_sda si5394_i2c_scl}]
#set_output_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
#set_false_path -from [get_ports {si5394_i2c_sda si5394_i2c_scl}]
#set_input_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
# QSFP28 Interfaces
set_property -dict {LOC J45 } [get_ports {qsfp_rx_p[0]}] ;# MGTYRXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J46 } [get_ports {qsfp_rx_n[0]}] ;# MGTYRXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC D42 } [get_ports {qsfp_tx_p[0]}] ;# MGTYTXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC D43 } [get_ports {qsfp_tx_n[0]}] ;# MGTYTXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G45 } [get_ports {qsfp_rx_p[1]}] ;# MGTYRXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G46 } [get_ports {qsfp_rx_n[1]}] ;# MGTYRXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC C40 } [get_ports {qsfp_tx_p[1]}] ;# MGTYTXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC C41 } [get_ports {qsfp_tx_n[1]}] ;# MGTYTXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC F43 } [get_ports {qsfp_rx_p[2]}] ;# MGTYRXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC F44 } [get_ports {qsfp_rx_n[2]}] ;# MGTYRXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC B42 } [get_ports {qsfp_tx_p[2]}] ;# MGTYTXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC B43 } [get_ports {qsfp_tx_n[2]}] ;# MGTYTXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC E45 } [get_ports {qsfp_rx_p[3]}] ;# MGTYRXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC E46 } [get_ports {qsfp_rx_n[3]}] ;# MGTYRXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC A40 } [get_ports {qsfp_tx_p[3]}] ;# MGTYTXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC A41 } [get_ports {qsfp_tx_n[3]}] ;# MGTYTXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC N36 } [get_ports {qsfp_mgt_refclk_0_p}] ;# MGTREFCLK0P_131 from SI5394 OUT0
set_property -dict {LOC N37 } [get_ports {qsfp_mgt_refclk_0_n}] ;# MGTREFCLK0N_131 from SI5394 OUT0
#set_property -dict {LOC M38 } [get_ports {qsfp_mgt_refclk_1_p}] ;# MGTREFCLK1P_131 from SI5394 OUT2
#set_property -dict {LOC M39 } [get_ports {qsfp_mgt_refclk_1_n}] ;# MGTREFCLK1N_131 from SI5394 OUT2
#set_property -dict {LOC F19 IOSTANDARD LVDS} [get_ports {qsfp_recclk_p}] ;# to SI5394 IN0
#set_property -dict {LOC F18 IOSTANDARD LVDS} [get_ports {qsfp_recclk_n}] ;# to SI5394 IN0
# 161.1328125 MHz MGT reference clock (SI5394 OUT0)
create_clock -period 6.206 -name qsfp_mgt_refclk_0 [get_ports {qsfp_mgt_refclk_0_p}]
# 322.265625 MHz MGT reference clock (SI5394 OUT2)
#create_clock -period 3.103 -name qsfp_mgt_refclk_1 [get_ports {qsfp_mgt_refclk_1_p}]
# PCIe Interface
set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC Y5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC Y4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AA7 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AA6 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AK4 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AK3 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AB5 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AB4 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AC7 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AC6 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AP4 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AP3 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AD5 } [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AD4 } [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AF5 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AF4 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AE7 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AE6 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AH5 } [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AH4 } [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AG7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AG6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW2 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW1 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AJ7 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AJ6 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AL7 } [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AL6 } [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AM9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AM8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY4 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AY3 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AN7 } [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AN6 } [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB4 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB3 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AP9 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AP8 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BD4 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BD3 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR7 } [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR6 } [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BE6 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BE5 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT9 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT8 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AB9 } [get_ports {pcie_refclk_0_p}] ;# MGTREFCLK0P_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AB8 } [get_ports {pcie_refclk_0_n}] ;# MGTREFCLK0N_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AA11} [get_ports {pcie_refclk_2_p}] ;# MGTREFCLK1P_227 (for async x8 bifurcated lanes 0-7)
#set_property -dict {LOC AA10} [get_ports {pcie_refclk_2_n}] ;# MGTREFCLK1N_227 (for async x8 bifurcated lanes 0-7)
set_property -dict {LOC AF9 } [get_ports {pcie_refclk_1_p}] ;# MGTREFCLK0P_225 (for x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC AF8 } [get_ports {pcie_refclk_1_n}] ;# MGTREFCLK0N_225 (for x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AE11} [get_ports {pcie_refclk_3_p}] ;# MGTREFCLK1P_225 (for async x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AE10} [get_ports {pcie_refclk_3_n}] ;# MGTREFCLK1N_225 (for async x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC AW27 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {pcie_reset_n}]
# 100 MHz MGT reference clock
#create_clock -period 10 -name pcie_mgt_refclk_0 [get_ports {pcie_refclk_0_p}]
create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports {pcie_refclk_1_p}]
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports {pcie_refclk_2_p}]
#create_clock -period 10 -name pcie_mgt_refclk_3 [get_ports {pcie_refclk_3_p}]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]

View File

@@ -0,0 +1,253 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# XDC constraints for the Xilinx Alveo U55C/Alveo U55N/Varium C1100 board
# U55C part: xcu55c-fsvh2892-2L-e
# U55N/C1100 part: xcu55n-fsvh2892-2L-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.CONFIG.CONFIGFALLBACK ENABLE [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 85.0 [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
#set_operating_conditions -design_power_budget 63
# System clocks
# 100 MHz
#set_property -dict {LOC BK10 IOSTANDARD LVDS} [get_ports clk_100mhz_0_p]
#set_property -dict {LOC BL10 IOSTANDARD LVDS} [get_ports clk_100mhz_0_n]
#create_clock -period 10 -name clk_100mhz_0 [get_ports clk_100mhz_0_p]
# 100 MHz
#set_property -dict {LOC BK43 IOSTANDARD LVDS} [get_ports clk_100mhz_1_p]
#set_property -dict {LOC BK44 IOSTANDARD LVDS} [get_ports clk_100mhz_1_n]
#create_clock -period 10 -name clk_100mhz_1 [get_ports clk_100mhz_1_p]
# 100 MHz
#set_property -dict {LOC F24 IOSTANDARD LVDS} [get_ports clk_100mhz_2_p]
#set_property -dict {LOC F23 IOSTANDARD LVDS} [get_ports clk_100mhz_2_n]
#create_clock -period 10 -name clk_100mhz_2 [get_ports clk_100mhz_2_p]
# Reset button
set_property -dict {LOC BG45 IOSTANDARD LVCMOS18} [get_ports reset]
set_false_path -from [get_ports {reset}]
set_input_delay 0 [get_ports {reset}]
# LEDs
set_property -dict {LOC BL13 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_act[0]}]
set_property -dict {LOC BK11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_g[0]}]
set_property -dict {LOC BJ11 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_y[0]}]
set_property -dict {LOC BK14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_act[1]}]
set_property -dict {LOC BK15 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_g[1]}]
set_property -dict {LOC BL12 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {qsfp_led_stat_y[1]}]
set_false_path -to [get_ports {qsfp_led_act[*] qsfp_led_stat_g[*] qsfp_led_stat_y[*]}]
set_output_delay 0 [get_ports {qsfp_led_act[*] qsfp_led_stat_g[*] qsfp_led_stat_y[*]}]
# UART (U35 FT4232H/DMB-1 FT4232H)
set_property -dict {LOC BJ41 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[0]}] ;# U35.39 CDBUS1 RXD / DMB-1 U9.39 CDBUS1 RXD
set_property -dict {LOC BK41 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[0]}] ;# U35.38 CDBUS0 TXD / DMB-1 U9.38 CDBUS0 TXD
set_property -dict {LOC BN47 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[1]}] ;# U35.52 DDBUS1 RXD / DMB-1 U9.52 DDBUS1 RXD
set_property -dict {LOC BP47 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[1]}] ;# U35.48 DDBUS0 TXD / DMB-1 U9.48 DDBUS0 TXD
set_property -dict {LOC BL45 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {uart_txd[2]}] ;# DMB-1 U18.39 CDBUS1 RXD
set_property -dict {LOC BL46 IOSTANDARD LVCMOS18} [get_ports {uart_rxd[2]}] ;# DMB-1 U18.38 CDBUS0 TXD
set_false_path -to [get_ports {uart_txd[*]}]
set_output_delay 0 [get_ports {uart_txd[*]}]
set_false_path -from [get_ports {uart_rxd[*]}]
set_input_delay 0 [get_ports {uart_rxd[*]}]
# BMC
#set_property -dict {LOC BE46 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[0]}]
#set_property -dict {LOC BH46 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[1]}]
#set_property -dict {LOC BF45 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[2]}]
#set_property -dict {LOC BF46 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_gpio[3]}]
#set_property -dict {LOC BH42 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {msp_uart_txd}]
#set_property -dict {LOC BJ42 IOSTANDARD LVCMOS18} [get_ports {msp_uart_rxd}]
#set_false_path -to [get_ports {msp_uart_txd}]
#set_output_delay 0 [get_ports {msp_uart_txd}]
#set_false_path -from [get_ports {msp_gpio[*] msp_uart_rxd}]
#set_input_delay 0 [get_ports {msp_gpio[*] msp_uart_rxd}]
# HBM overtemp
set_property -dict {LOC BE45 IOSTANDARD LVCMOS18} [get_ports hbm_cattrip]
set_false_path -to [get_ports {hbm_cattrip}]
set_output_delay 0 [get_ports {hbm_cattrip}]
# SI5394 (SI5394B-A10605-GM)
# I2C address 0x68
# IN0: 161.1328125 MHz from qsfp_recclk
# OUT0: 161.1328125 MHz to qsfp0_mgt_refclk
# OUT1: 161.1328125 MHz to qsfp1_mgt_refclk
# OUT3: 100 MHz to clk_100mhz_0, clk_100mhz_1, pcie_refclk_2, pcie_refclk_3
#set_property -dict {LOC BM8 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {si5394_rst_b}]
#set_property -dict {LOC BM9 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_int_b}]
#set_property -dict {LOC BN10 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_lol_b}]
#set_property -dict {LOC BM10 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_los_b}]
#set_property -dict {LOC BN14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports {si5394_sda}]
#set_property -dict {LOC BM14 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8 PULLUP true} [get_ports {si5394_scl}]
#set_false_path -to [get_ports {si5394_rst_b}]
#set_output_delay 0 [get_ports {si5394_rst_b}]
#set_false_path -from [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
#set_input_delay 0 [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
#set_false_path -to [get_ports {si5394_i2c_sda si5394_i2c_scl}]
#set_output_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
#set_false_path -from [get_ports {si5394_i2c_sda si5394_i2c_scl}]
#set_input_delay 0 [get_ports {si5394_i2c_sda si5394_i2c_scl}]
# QSFP28 Interfaces
set_property -dict {LOC AD51} [get_ports {qsfp0_rx_p[0]}] ;# MGTYRXP0_130 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AD52} [get_ports {qsfp0_rx_n[0]}] ;# MGTYRXN0_130 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AD46} [get_ports {qsfp0_tx_p[0]}] ;# MGTYTXP0_130 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AD47} [get_ports {qsfp0_tx_n[0]}] ;# MGTYTXN0_130 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AC53} [get_ports {qsfp0_rx_p[1]}] ;# MGTYRXP1_130 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AC54} [get_ports {qsfp0_rx_n[1]}] ;# MGTYRXN1_130 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AC44} [get_ports {qsfp0_tx_p[1]}] ;# MGTYTXP1_130 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AC45} [get_ports {qsfp0_tx_n[1]}] ;# MGTYTXN1_130 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AC49} [get_ports {qsfp0_rx_p[2]}] ;# MGTYRXP2_130 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AC50} [get_ports {qsfp0_rx_n[2]}] ;# MGTYRXN2_130 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AB46} [get_ports {qsfp0_tx_p[2]}] ;# MGTYTXP2_130 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AB47} [get_ports {qsfp0_tx_n[2]}] ;# MGTYTXN2_130 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AB51} [get_ports {qsfp0_rx_p[3]}] ;# MGTYRXP3_130 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AB52} [get_ports {qsfp0_rx_n[3]}] ;# MGTYRXN3_130 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AA48} [get_ports {qsfp0_tx_p[3]}] ;# MGTYTXP3_130 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AA49} [get_ports {qsfp0_tx_n[3]}] ;# MGTYTXN3_130 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AD42} [get_ports {qsfp0_mgt_refclk_p}] ;# MGTREFCLK0P_130 from SI5394 OUT0
set_property -dict {LOC AD43} [get_ports {qsfp0_mgt_refclk_n}] ;# MGTREFCLK0N_130 from SI5394 OUT0
# 161.1328125 MHz MGT reference clock (SI5394 OUT0)
create_clock -period 6.206 -name qsfp0_mgt_refclk [get_ports {qsfp0_mgt_refclk_p}]
set_property -dict {LOC AA53} [get_ports {qsfp1_rx_p[0]}] ;# MGTYRXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AA54} [get_ports {qsfp1_rx_n[0]}] ;# MGTYRXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AA44} [get_ports {qsfp1_tx_p[0]}] ;# MGTYTXP0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AA45} [get_ports {qsfp1_tx_n[0]}] ;# MGTYTXN0_131 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC Y51 } [get_ports {qsfp1_rx_p[1]}] ;# MGTYRXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC Y52 } [get_ports {qsfp1_rx_n[1]}] ;# MGTYRXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC Y46 } [get_ports {qsfp1_tx_p[1]}] ;# MGTYTXP1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC Y47 } [get_ports {qsfp1_tx_n[1]}] ;# MGTYTXN1_131 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC W53 } [get_ports {qsfp1_rx_p[2]}] ;# MGTYRXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC W54 } [get_ports {qsfp1_rx_n[2]}] ;# MGTYRXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC W48 } [get_ports {qsfp1_tx_p[2]}] ;# MGTYTXP2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC W49 } [get_ports {qsfp1_tx_n[2]}] ;# MGTYTXN2_131 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC V51 } [get_ports {qsfp1_rx_p[3]}] ;# MGTYRXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC V52 } [get_ports {qsfp1_rx_n[3]}] ;# MGTYRXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC W44 } [get_ports {qsfp1_tx_p[3]}] ;# MGTYTXP3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC W45 } [get_ports {qsfp1_tx_n[3]}] ;# MGTYTXN3_131 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC AB42} [get_ports {qsfp1_mgt_refclk_p}] ;# MGTREFCLK0P_131 from SI5394 OUT1
set_property -dict {LOC AB43} [get_ports {qsfp1_mgt_refclk_n}] ;# MGTREFCLK0N_131 from SI5394 OUT1
# 161.1328125 MHz MGT reference clock (SI5394 OUT1)
create_clock -period 6.206 -name qsfp1_mgt_refclk [get_ports {qsfp1_mgt_refclk_p}]
# PCIe Interface
set_property -dict {LOC AL2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AL1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AL11} [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AL10} [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_227 GTYE4_CHANNEL_X1Y15 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM4 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM3 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM9 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AM8 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_227 GTYE4_CHANNEL_X1Y14 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN6 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN5 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN11} [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN10} [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_227 GTYE4_CHANNEL_X1Y13 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AN1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AP9 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AP8 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_227 GTYE4_CHANNEL_X1Y12 / GTYE4_COMMON_X1Y3
set_property -dict {LOC AP4 } [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AP3 } [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR11} [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR10} [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_226 GTYE4_CHANNEL_X1Y11 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR2 } [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR1 } [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR7 } [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AR6 } [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_226 GTYE4_CHANNEL_X1Y10 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT9 } [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AT8 } [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_226 GTYE4_CHANNEL_X1Y9 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU2 } [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU1 } [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU11} [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AU10} [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_226 GTYE4_CHANNEL_X1Y8 / GTYE4_COMMON_X1Y2
set_property -dict {LOC AV4 } [get_ports {pcie_rx_p[8]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AV3 } [get_ports {pcie_rx_n[8]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU7 } [get_ports {pcie_tx_p[8]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU6 } [get_ports {pcie_tx_n[8]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW6 } [get_ports {pcie_rx_p[9]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW5 } [get_ports {pcie_rx_n[9]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AV9 } [get_ports {pcie_tx_p[9]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AV8 } [get_ports {pcie_tx_n[9]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW2 } [get_ports {pcie_rx_p[10]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW1 } [get_ports {pcie_rx_n[10]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW11} [get_ports {pcie_tx_p[10]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AW10} [get_ports {pcie_tx_n[10]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY4 } [get_ports {pcie_rx_p[11]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY3 } [get_ports {pcie_rx_n[11]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY9 } [get_ports {pcie_tx_p[11]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AY8 } [get_ports {pcie_tx_n[11]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC BA6 } [get_ports {pcie_rx_p[12]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA5 } [get_ports {pcie_rx_n[12]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA11} [get_ports {pcie_tx_p[12]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA10} [get_ports {pcie_tx_n[12]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA2 } [get_ports {pcie_rx_p[13]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BA1 } [get_ports {pcie_rx_n[13]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB9 } [get_ports {pcie_tx_p[13]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB8 } [get_ports {pcie_tx_n[13]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB4 } [get_ports {pcie_rx_p[14]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BB3 } [get_ports {pcie_rx_n[14]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC11} [get_ports {pcie_tx_p[14]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC10} [get_ports {pcie_tx_n[14]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC2 } [get_ports {pcie_rx_p[15]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC1 } [get_ports {pcie_rx_n[15]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC7 } [get_ports {pcie_tx_p[15]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC BC6 } [get_ports {pcie_tx_n[15]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
#set_property -dict {LOC AL15} [get_ports {pcie_refclk_0_p}] ;# MGTREFCLK0P_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AL14} [get_ports {pcie_refclk_0_n}] ;# MGTREFCLK0N_227 (for x8 bifurcated lanes 0-7)
#set_property -dict {LOC AK13} [get_ports {pcie_refclk_2_p}] ;# MGTREFCLK1P_227 (for async x8 bifurcated lanes 0-7)
#set_property -dict {LOC AK12} [get_ports {pcie_refclk_2_n}] ;# MGTREFCLK1N_227 (for async x8 bifurcated lanes 0-7)
set_property -dict {LOC AR15} [get_ports {pcie_refclk_1_p}] ;# MGTREFCLK0P_225 (for x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC AR14} [get_ports {pcie_refclk_1_n}] ;# MGTREFCLK0N_225 (for x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AP13} [get_ports {pcie_refclk_3_p}] ;# MGTREFCLK1P_225 (for async x16 or x8 bifurcated lanes 8-16)
#set_property -dict {LOC AP12} [get_ports {pcie_refclk_3_n}] ;# MGTREFCLK1N_225 (for async x16 or x8 bifurcated lanes 8-16)
set_property -dict {LOC BF41 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {pcie_reset_n}]
# 100 MHz MGT reference clock
#create_clock -period 10 -name pcie_mgt_refclk_0 [get_ports {pcie_refclk_0_p}]
create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports {pcie_refclk_1_p}]
#create_clock -period 10 -name pcie_mgt_refclk_2 [get_ports {pcie_refclk_2_p}]
#create_clock -period 10 -name pcie_mgt_refclk_3 [get_ports {pcie_refclk_3_p}]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]
# set_property PACKAGE_PIN BN42 [get_ports "TESTCLK_OUT"] ;# Bank 65 VCCO - VCC1V8 - IO_L1P_T0L_N0_DBC_RS0_65
# set_property IOSTANDARD LVCMOS18 [get_ports "TESTCLK_OUT"] ;# Bank 65 VCCO - VCC1V8 - IO_L1P_T0L_N0_DBC_RS0_65
# set_property PACKAGE_PIN BJ33 [get_ports "PPS_IN_FPGA"] ;# Bank 64 VCCO - VCC1V8 - IO_L14P_T2L_N2_GC_64
# set_property IOSTANDARD LVCMOS18 [get_ports "PPS_IN_FPGA"] ;# Bank 64 VCCO - VCC1V8 - IO_L14P_T2L_N2_GC_64
# set_property PACKAGE_PIN BH32 [get_ports "PPS_OUT_FPGA"] ;# Bank 64 VCCO - VCC1V8 - IO_L13P_T2L_N0_GC_QBC_64
# set_property IOSTANDARD LVCMOS18 [get_ports "PPS_OUT_FPGA"] ;# Bank 64 VCCO - VCC1V8 - IO_L13P_T2L_N0_GC_QBC_64

View File

@@ -0,0 +1,168 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# XDC constraints for the Xilinx Alveo U45N/SN1022 board
# part: xcux35-vsva1365-3-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS TRUE [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 72.9 [current_design]
set_property BITSTREAM.CONFIG.EXTMASTERCCLK_EN DISABLE [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE YES [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN PULLUP [current_design]
set_property BITSTREAM.CONFIG.SPI_32BIT_ADDR YES [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
set_operating_conditions -design_power_budget 60
# System clocks
# 300 MHz
#set_property -dict {LOC AK23 IOSTANDARD LVDS} [get_ports clk_300mhz_p]
#set_property -dict {LOC AL23 IOSTANDARD LVDS} [get_ports clk_300mhz_n]
#create_clock -period 10 -name clk_300mhz [get_ports clk_300mhz_p]
# 300 MHz
#set_property -dict {LOC AN27 IOSTANDARD LVDS} [get_ports clk_ddr4_p]
#set_property -dict {LOC AN28 IOSTANDARD LVDS} [get_ports clk_ddr4_n]
#create_clock -period 10 -name clk_ddr4 [get_ports clk_ddr4_p]
# LEDs
set_property -dict {LOC AM23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_r[0]}]
set_property -dict {LOC AN23 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_g[0]}]
set_property -dict {LOC AM22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_b[0]}]
set_property -dict {LOC AN22 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_r[1]}]
set_property -dict {LOC AN25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_g[1]}]
set_property -dict {LOC AP25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_b[1]}]
set_property -dict {LOC AH24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_r[2]}]
set_property -dict {LOC AK24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_g[2]}]
set_property -dict {LOC AL24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_b[2]}]
set_property -dict {LOC AJ25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_r[3]}]
set_property -dict {LOC AN24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_g[3]}]
set_property -dict {LOC AH25 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {dsfp_led_b[3]}]
set_false_path -to [get_ports {dsfp_led_r[*] dsfp_led_g[*] dsfp_led_b[*]}]
set_output_delay 0 [get_ports {dsfp_led_r[*] dsfp_led_g[*] dsfp_led_b[*]}]
# PPS in/out
#set_property -dict {LOC AM25 IOSTANDARD LVCMOS18} [get_ports {pps_in}]
#set_property -dict {LOC AL25 IOSTANDARD LVCMOS18 SLEW FAST DRIVE 8} [get_ports {pps_out}]
#set_false_path -from [get_ports {pps_in}]
#set_input_delay 0 [get_ports {pps_in}]
#set_false_path -to [get_ports {pps_out}]
#set_output_delay 0 [get_ports {pps_out}]
# UART (DMB-2 FT4232H channel CDBUS)
set_property -dict {LOC AP24 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports uart_txd] ;# DMB-2 U4.39 RXD CDBUS1
set_property -dict {LOC AR24 IOSTANDARD LVCMOS18} [get_ports uart_rxd] ;# DMB-2 U4.38 TXD CDBUS0
set_false_path -to [get_ports {uart_txd}]
set_output_delay 0 [get_ports {uart_txd}]
set_false_path -from [get_ports {uart_rxd}]
set_input_delay 0 [get_ports {uart_rxd}]
# BMC
#set_property -dict {LOC AM17 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {suc_gpio[0]}]
#set_property -dict {LOC AL18 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {suc_gpio[1]}]
#set_property -dict {LOC AK21 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 4} [get_ports {suc_uart_txd}]
#set_property -dict {LOC AJ21 IOSTANDARD LVCMOS18} [get_ports {suc_uart_rxd}]
#set_false_path -to [get_ports {suc_uart_txd}]
#set_output_delay 0 [get_ports {suc_uart_txd}]
#set_false_path -from [get_ports {suc_gpio[*] suc_uart_rxd}]
#set_input_delay 0 [get_ports {suc_gpio[*] suc_uart_rxd}]
# SI5394 (SI5394J-A-GM)
# IN0: 20 MHz TCXO
# OUT1: 161.1328125 MHz to DSFP GTY
# OUT2: 100 MHz to ...
# OUT3: 300 MHz to ...
#set_property -dict {LOC AN20 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 8} [get_ports {si5394_rst_b}]
#set_property -dict {LOC AH19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_int_b}]
#set_property -dict {LOC AJ19 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_lol_b}]
#set_property -dict {LOC AJ20 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {si5394_los_b}]
#set_false_path -to [get_ports {si5394_rst_b}]
#set_output_delay 0 [get_ports {si5394_rst_b}]
#set_false_path -from [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
#set_input_delay 0 [get_ports {si5394_int_b si5394_lol_b si5394_los_b}]
# DSFP Interfaces
set_property -dict {LOC K4} [get_ports {dsfp1_rx_p[0]}] ;# MGTYRXP0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC K3} [get_ports {dsfp1_rx_n[0]}] ;# MGTYRXN0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J7} [get_ports {dsfp1_tx_p[0]}] ;# MGTYTXP0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J6} [get_ports {dsfp1_tx_n[0]}] ;# MGTYTXN0_231 GTYE4_CHANNEL_X0Y28 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J2} [get_ports {dsfp1_rx_p[1]}] ;# MGTYRXP1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC J1} [get_ports {dsfp1_rx_n[1]}] ;# MGTYRXN1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC H5} [get_ports {dsfp1_tx_p[1]}] ;# MGTYTXP1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC H4} [get_ports {dsfp1_tx_n[1]}] ;# MGTYTXN1_231 GTYE4_CHANNEL_X0Y29 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G2} [get_ports {dsfp0_rx_p[0]}] ;# MGTYRXP2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G1} [get_ports {dsfp0_rx_n[0]}] ;# MGTYRXN2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G7} [get_ports {dsfp0_tx_p[0]}] ;# MGTYTXP2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC G6} [get_ports {dsfp0_tx_n[0]}] ;# MGTYTXN2_231 GTYE4_CHANNEL_X0Y30 / GTYE4_COMMON_X0Y7
set_property -dict {LOC E2} [get_ports {dsfp0_rx_p[1]}] ;# MGTYRXP3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC E1} [get_ports {dsfp0_rx_n[1]}] ;# MGTYRXN3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC F5} [get_ports {dsfp0_tx_p[1]}] ;# MGTYTXP3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC F4} [get_ports {dsfp0_tx_n[1]}] ;# MGTYTXN3_231 GTYE4_CHANNEL_X0Y31 / GTYE4_COMMON_X0Y7
set_property -dict {LOC P9} [get_ports {dsfp_mgt_refclk_p}] ;# MGTREFCLK0P_231 from SI5394 OUT1 via U16
set_property -dict {LOC P8} [get_ports {dsfp_mgt_refclk_n}] ;# MGTREFCLK0N_231 from SI5394 OUT1 via U16
# 161.1328125 MHz MGT reference clock (SI5394 OUT1 via U16)
create_clock -period 6.206 -name dsfp_mgt_refclk [get_ports {dsfp_mgt_refclk_p}]
# PCIe Interface
set_property -dict {LOC AT4 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT3 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AP8 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AP7 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X1Y7 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU6 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU5 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AR6 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AR5 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X1Y6 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT8 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT7 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AR10} [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AR9 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X1Y5 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU10} [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU9 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT12} [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AT11} [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X1Y4 / GTYE4_COMMON_X1Y1
set_property -dict {LOC AU14} [get_ports {pcie_rx_p[4]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU13} [get_ports {pcie_rx_n[4]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR14} [get_ports {pcie_tx_p[4]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR13} [get_ports {pcie_tx_n[4]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X1Y3 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT16} [get_ports {pcie_rx_p[5]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT15} [get_ports {pcie_rx_n[5]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR18} [get_ports {pcie_tx_p[5]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR17} [get_ports {pcie_tx_n[5]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X1Y2 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU18} [get_ports {pcie_rx_p[6]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU17} [get_ports {pcie_rx_n[6]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT20} [get_ports {pcie_tx_p[6]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AT19} [get_ports {pcie_tx_n[6]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X1Y1 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU22} [get_ports {pcie_rx_p[7]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AU21} [get_ports {pcie_rx_n[7]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR22} [get_ports {pcie_tx_p[7]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AR21} [get_ports {pcie_tx_n[7]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X1Y0 / GTYE4_COMMON_X1Y0
set_property -dict {LOC AL10} [get_ports {pcie_refclk_p}] ;# MGTREFCLK0P_225
set_property -dict {LOC AL9 } [get_ports {pcie_refclk_n}] ;# MGTREFCLK0N_225
#set_property -dict {LOC AK8 } [get_ports {pcie_refclk_p}] ;# MGTREFCLK1P_225
#set_property -dict {LOC AK7 } [get_ports {pcie_refclk_n}] ;# MGTREFCLK1N_225
set_property -dict {LOC AK18 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {pcie_reset_n}]
#set_property -dict {LOC AM20 IOSTANDARD LVCMOS18 PULLUP true} [get_ports {pcie_pwrbrkn_n}]
# 100 MHz MGT reference clock
create_clock -period 10 -name pcie_mgt_refclk_1 [get_ports {pcie_refclk_p}]
set_false_path -from [get_ports {pcie_reset_n pcie_pwrbrkn_n}]
set_input_delay 0 [get_ports {pcie_reset_n pcie_pwrbrkn_n}]

View File

@@ -0,0 +1,18 @@
create_ip -name ddr4 -vendor xilinx.com -library ip -module_name ddr4_0
set_property -dict [list \
CONFIG.System_Clock {No_Buffer} \
CONFIG.C0.DDR4_AxiSelection {true} \
CONFIG.C0.DDR4_AxiDataWidth {512} \
CONFIG.C0.DDR4_AxiIDWidth {8} \
CONFIG.C0.DDR4_AxiArbitrationScheme {RD_PRI_REG} \
CONFIG.C0.DDR4_TimePeriod {833} \
CONFIG.C0.DDR4_InputClockPeriod {3332} \
CONFIG.C0.DDR4_MemoryType {RDIMMs} \
CONFIG.C0.DDR4_MemoryPart {MTA18ASF2G72PZ-2G3} \
CONFIG.C0.DDR4_AUTO_AP_COL_A3 {true} \
CONFIG.C0.DDR4_CasLatency {17} \
CONFIG.C0.DDR4_CasWriteLatency {12} \
CONFIG.C0.DDR4_Mem_Add_Map {ROW_COLUMN_BANK_INTLV}
] [get_ips ddr4_0]

View File

@@ -0,0 +1,18 @@
create_ip -name ddr4 -vendor xilinx.com -library ip -module_name ddr4_0
set_property -dict [list \
CONFIG.System_Clock {No_Buffer} \
CONFIG.C0.DDR4_AxiSelection {true} \
CONFIG.C0.DDR4_AxiDataWidth {512} \
CONFIG.C0.DDR4_AxiIDWidth {8} \
CONFIG.C0.DDR4_AxiArbitrationScheme {RD_PRI_REG} \
CONFIG.C0.DDR4_TimePeriod {833} \
CONFIG.C0.DDR4_InputClockPeriod {9996} \
CONFIG.C0.DDR4_MemoryType {RDIMMs} \
CONFIG.C0.DDR4_MemoryPart {MTA18ASF2G72PZ-2G3} \
CONFIG.C0.DDR4_AUTO_AP_COL_A3 {true} \
CONFIG.C0.DDR4_CasLatency {17} \
CONFIG.C0.DDR4_CasWriteLatency {12} \
CONFIG.C0.DDR4_Mem_Add_Map {ROW_COLUMN_BANK_INTLV}
] [get_ips ddr4_0]

View File

@@ -0,0 +1,30 @@
create_ip -name pcie4_uscale_plus -vendor xilinx.com -library ip -module_name pcie4_uscale_plus_0
set_property -dict [list \
CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \
CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X16} \
CONFIG.AXISTEN_IF_EXT_512_CQ_STRADDLE {false} \
CONFIG.AXISTEN_IF_EXT_512_RQ_STRADDLE {false} \
CONFIG.AXISTEN_IF_EXT_512_RC_4TLP_STRADDLE {false} \
CONFIG.axisten_if_enable_client_tag {true} \
CONFIG.axisten_if_width {512_bit} \
CONFIG.extended_tag_field {true} \
CONFIG.pf0_dev_cap_max_payload {1024_bytes} \
CONFIG.axisten_freq {250} \
CONFIG.PF0_Use_Class_Code_Lookup_Assistant {false} \
CONFIG.PF0_CLASS_CODE {020000} \
CONFIG.PF0_DEVICE_ID {C001} \
CONFIG.PF0_SUBSYSTEM_ID {90c8} \
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \
CONFIG.pf0_bar0_64bit {true} \
CONFIG.pf0_bar0_prefetchable {true} \
CONFIG.pf0_bar0_scale {Megabytes} \
CONFIG.pf0_bar0_size {16} \
CONFIG.pf0_msi_enabled {true} \
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
CONFIG.en_msi_per_vec_masking {true} \
CONFIG.legacy_ext_pcie_cfg_space_enabled {true} \
CONFIG.vendor_id {1234} \
CONFIG.mode_selection {Advanced} \
] [get_ips pcie4_uscale_plus_0]

View File

@@ -0,0 +1,30 @@
create_ip -name pcie4c_uscale_plus -vendor xilinx.com -library ip -module_name pcie4c_uscale_plus_0
set_property -dict [list \
CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {8.0_GT/s} \
CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X16} \
CONFIG.AXISTEN_IF_EXT_512_CQ_STRADDLE {false} \
CONFIG.AXISTEN_IF_EXT_512_RQ_STRADDLE {false} \
CONFIG.AXISTEN_IF_EXT_512_RC_4TLP_STRADDLE {false} \
CONFIG.axisten_if_enable_client_tag {true} \
CONFIG.axisten_if_width {512_bit} \
CONFIG.extended_tag_field {true} \
CONFIG.pf0_dev_cap_max_payload {1024_bytes} \
CONFIG.axisten_freq {250} \
CONFIG.PF0_Use_Class_Code_Lookup_Assistant {false} \
CONFIG.PF0_CLASS_CODE {020000} \
CONFIG.PF0_DEVICE_ID {C001} \
CONFIG.PF0_SUBSYSTEM_ID {9118} \
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \
CONFIG.pf0_bar0_64bit {true} \
CONFIG.pf0_bar0_prefetchable {true} \
CONFIG.pf0_bar0_scale {Megabytes} \
CONFIG.pf0_bar0_size {16} \
CONFIG.pf0_msi_enabled {true} \
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
CONFIG.en_msi_per_vec_masking {true} \
CONFIG.legacy_ext_pcie_cfg_space_enabled {true} \
CONFIG.vendor_id {1234} \
CONFIG.mode_selection {Advanced} \
] [get_ips pcie4c_uscale_plus_0]

View File

@@ -0,0 +1,30 @@
create_ip -name pcie4c_uscale_plus -vendor xilinx.com -library ip -module_name pcie4c_uscale_plus_0
set_property -dict [list \
CONFIG.PL_LINK_CAP_MAX_LINK_SPEED {16.0_GT/s} \
CONFIG.PL_LINK_CAP_MAX_LINK_WIDTH {X8} \
CONFIG.AXISTEN_IF_EXT_512_CQ_STRADDLE {false} \
CONFIG.AXISTEN_IF_EXT_512_RQ_STRADDLE {false} \
CONFIG.AXISTEN_IF_EXT_512_RC_4TLP_STRADDLE {false} \
CONFIG.axisten_if_enable_client_tag {true} \
CONFIG.axisten_if_width {512_bit} \
CONFIG.extended_tag_field {true} \
CONFIG.pf0_dev_cap_max_payload {1024_bytes} \
CONFIG.axisten_freq {250} \
CONFIG.PF0_Use_Class_Code_Lookup_Assistant {false} \
CONFIG.PF0_CLASS_CODE {020000} \
CONFIG.PF0_DEVICE_ID {C001} \
CONFIG.PF0_SUBSYSTEM_ID {9dc2} \
CONFIG.PF0_SUBSYSTEM_VENDOR_ID {10ee} \
CONFIG.pf0_bar0_64bit {true} \
CONFIG.pf0_bar0_prefetchable {true} \
CONFIG.pf0_bar0_scale {Megabytes} \
CONFIG.pf0_bar0_size {16} \
CONFIG.pf0_msi_enabled {true} \
CONFIG.PF0_MSI_CAP_MULTIMSGCAP {32_vectors} \
CONFIG.en_msi_per_vec_masking {true} \
CONFIG.legacy_ext_pcie_cfg_space_enabled {true} \
CONFIG.vendor_id {1234} \
CONFIG.mode_selection {Advanced} \
] [get_ips pcie4c_uscale_plus_0]

View File

@@ -0,0 +1 @@
../../../../../../

View File

@@ -0,0 +1,950 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2014-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga #
(
// simulation (set to avoid vendor primitives)
parameter logic SIM = 1'b0,
// vendor ("GENERIC", "XILINX", "ALTERA")
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// FW ID
parameter FPGA_ID = 32'h4B37093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h10ee_90c8,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
)
(
/*
* Reset: Push button, active low
*/
input wire logic reset,
/*
* GPIO
*/
input wire logic [3:0] sw,
output wire logic [2:0] led,
/*
* I2C for board management
*/
inout wire logic i2c_scl,
inout wire logic i2c_sda,
/*
* UART
*/
output wire logic uart_txd,
input wire logic uart_rxd,
/*
* Ethernet: QSFP28
*/
output wire logic qsfp0_tx_p[4],
output wire logic qsfp0_tx_n[4],
input wire logic qsfp0_rx_p[4],
input wire logic qsfp0_rx_n[4],
input wire logic qsfp0_mgt_refclk_0_p,
input wire logic qsfp0_mgt_refclk_0_n,
// input wire logic qsfp0_mgt_refclk_1_p,
// input wire logic qsfp0_mgt_refclk_1_n,
output wire logic qsfp0_modsell,
output wire logic qsfp0_resetl,
input wire logic qsfp0_modprsl,
input wire logic qsfp0_intl,
output wire logic qsfp0_lpmode,
// output wire logic qsfp0_refclk_reset,
// output wire logic [1:0] qsfp0_fs,
output wire logic qsfp1_tx_p[4],
output wire logic qsfp1_tx_n[4],
input wire logic qsfp1_rx_p[4],
input wire logic qsfp1_rx_n[4],
input wire logic qsfp1_mgt_refclk_0_p,
input wire logic qsfp1_mgt_refclk_0_n,
// input wire logic qsfp1_mgt_refclk_1_p,
// input wire logic qsfp1_mgt_refclk_1_n,
output wire logic qsfp1_modsell,
output wire logic qsfp1_resetl,
input wire logic qsfp1_modprsl,
input wire logic qsfp1_intl,
output wire logic qsfp1_lpmode,
// output wire logic qsfp1_refclk_reset,
// output wire logic [1:0] qsfp1_fs,
/*
* PCIe
*/
input wire logic [15:0] pcie_rx_p,
input wire logic [15:0] pcie_rx_n,
output wire logic [15:0] pcie_tx_p,
output wire logic [15:0] pcie_tx_n,
input wire logic pcie_refclk_p,
input wire logic pcie_refclk_n,
input wire logic pcie_reset_n
);
// Clock and reset
wire pcie_user_clk;
wire pcie_user_rst;
wire clk_156mhz_ref_int;
// Internal 125 MHz clock
wire clk_125mhz_mmcm_out;
wire clk_125mhz_int;
wire rst_125mhz_int;
wire mmcm_rst = 1'b0;
wire mmcm_locked;
wire mmcm_clkfb;
// MMCM instance
MMCME4_BASE #(
// 156.25 MHz input
.CLKIN1_PERIOD(6.4),
.REF_JITTER1(0.010),
// 156.25 MHz input / 1 = 156.25 MHz PFD (range 10 MHz to 500 MHz)
.DIVCLK_DIVIDE(1),
// 156.25 MHz PFD * 8 = 1250 MHz VCO (range 800 MHz to 1600 MHz)
.CLKFBOUT_MULT_F(8),
.CLKFBOUT_PHASE(0),
// 1250 MHz / 10 = 125 MHz, 0 degrees
.CLKOUT0_DIVIDE_F(10),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0),
// Not used
.CLKOUT1_DIVIDE(1),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT1_PHASE(0),
// Not used
.CLKOUT2_DIVIDE(1),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT2_PHASE(0),
// Not used
.CLKOUT3_DIVIDE(1),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT3_PHASE(0),
// Not used
.CLKOUT4_DIVIDE(1),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT4_PHASE(0),
.CLKOUT4_CASCADE("FALSE"),
// Not used
.CLKOUT5_DIVIDE(1),
.CLKOUT5_DUTY_CYCLE(0.5),
.CLKOUT5_PHASE(0),
// Not used
.CLKOUT6_DIVIDE(1),
.CLKOUT6_DUTY_CYCLE(0.5),
.CLKOUT6_PHASE(0),
// optimized bandwidth
.BANDWIDTH("OPTIMIZED"),
// don't wait for lock during startup
.STARTUP_WAIT("FALSE")
)
clk_mmcm_inst (
// 156.25 MHz input
.CLKIN1(clk_156mhz_ref_int),
// direct clkfb feeback
.CLKFBIN(mmcm_clkfb),
.CLKFBOUT(mmcm_clkfb),
.CLKFBOUTB(),
// 125 MHz, 0 degrees
.CLKOUT0(clk_125mhz_mmcm_out),
.CLKOUT0B(),
// Not used
.CLKOUT1(),
.CLKOUT1B(),
// Not used
.CLKOUT2(),
.CLKOUT2B(),
// Not used
.CLKOUT3(),
.CLKOUT3B(),
// Not used
.CLKOUT4(),
// Not used
.CLKOUT5(),
// Not used
.CLKOUT6(),
// reset input
.RST(mmcm_rst),
// don't power down
.PWRDWN(1'b0),
// locked output
.LOCKED(mmcm_locked)
);
BUFG
clk_125mhz_bufg_inst (
.I(clk_125mhz_mmcm_out),
.O(clk_125mhz_int)
);
taxi_sync_reset #(
.N(4)
)
sync_reset_125mhz_inst (
.clk(clk_125mhz_int),
.rst(~mmcm_locked),
.out(rst_125mhz_int)
);
// GPIO
wire [3:0] sw_int;
taxi_debounce_switch #(
.WIDTH(4),
.N(4),
.RATE(156000)
)
debounce_switch_inst (
.clk(clk_125mhz_int),
.rst(rst_125mhz_int),
.in({sw}),
.out({sw_int})
);
// SI570 I2C
wire i2c_scl_i;
wire i2c_scl_o = 1'b1;
wire i2c_scl_t = 1'b1;
wire i2c_sda_i;
wire i2c_sda_o = 1'b1;
wire i2c_sda_t = 1'b1;
assign i2c_scl_i = i2c_scl;
assign i2c_scl = i2c_scl_t ? 1'bz : i2c_scl_o;
assign i2c_sda_i = i2c_sda;
assign i2c_sda = i2c_sda_t ? 1'bz : i2c_sda_o;
localparam PORT_CNT = 2;
localparam GTY_QUAD_CNT = PORT_CNT;
localparam GTY_CNT = GTY_QUAD_CNT*4;
localparam GTY_CLK_CNT = GTY_QUAD_CNT;
wire eth_gty_tx_p[GTY_CNT];
wire eth_gty_tx_n[GTY_CNT];
wire eth_gty_rx_p[GTY_CNT];
wire eth_gty_rx_n[GTY_CNT];
wire eth_gty_mgt_refclk_p[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_n[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_out[GTY_CLK_CNT];
assign qsfp0_tx_p = eth_gty_tx_p[4*0 +: 4];
assign qsfp0_tx_n = eth_gty_tx_n[4*0 +: 4];
assign eth_gty_rx_p[4*0 +: 4] = qsfp0_rx_p;
assign eth_gty_rx_n[4*0 +: 4] = qsfp0_rx_n;
assign qsfp1_tx_p = eth_gty_tx_p[4*1 +: 4];
assign qsfp1_tx_n = eth_gty_tx_n[4*1 +: 4];
assign eth_gty_rx_p[4*1 +: 4] = qsfp1_rx_p;
assign eth_gty_rx_n[4*1 +: 4] = qsfp1_rx_n;
assign eth_gty_mgt_refclk_p[0] = qsfp0_mgt_refclk_0_p;
assign eth_gty_mgt_refclk_n[0] = qsfp0_mgt_refclk_0_n;
assign eth_gty_mgt_refclk_p[1] = qsfp1_mgt_refclk_0_p;
assign eth_gty_mgt_refclk_n[1] = qsfp1_mgt_refclk_0_n;
assign clk_156mhz_ref_int = eth_gty_mgt_refclk_out[0];
// Flash
wire qspi_clk_int;
wire [3:0] qspi_dq_int;
wire [3:0] qspi_dq_i_int;
wire [3:0] qspi_dq_o_int;
wire [3:0] qspi_dq_oe_int;
wire qspi_cs_int;
reg qspi_clk_reg;
reg [3:0] qspi_dq_o_reg;
reg [3:0] qspi_dq_oe_reg;
reg qspi_cs_reg;
always_ff @(posedge pcie_user_clk) begin
qspi_clk_reg <= qspi_clk_int;
qspi_dq_o_reg <= qspi_dq_o_int;
qspi_dq_oe_reg <= qspi_dq_oe_int;
qspi_cs_reg <= qspi_cs_int;
end
taxi_sync_signal #(
.WIDTH(8),
.N(2)
)
flash_sync_inst (
.clk(pcie_user_clk),
.in({qspi_dq_int}),
.out({qspi_dq_i_int})
);
STARTUPE3
startupe3_inst (
.CFGCLK(),
.CFGMCLK(),
.DI(qspi_dq_int),
.DO(qspi_dq_o_reg),
.DTS(~qspi_dq_oe_reg),
.EOS(),
.FCSBO(qspi_cs_reg),
.FCSBTS(1'b0),
.GSR(1'b0),
.GTS(1'b0),
.KEYCLEARB(1'b1),
.PACK(1'b0),
.PREQ(),
.USRCCLKO(qspi_clk_reg),
.USRCCLKTS(1'b0),
.USRDONEO(1'b0),
.USRDONETS(1'b1)
);
// FPGA boot
wire fpga_boot;
wire fpga_boot_sync;
taxi_sync_signal #(
.WIDTH(1),
.N(2)
)
fpga_boot_sync_inst (
.clk(clk_125mhz_int),
.in({fpga_boot}),
.out({fpga_boot_sync})
);
wire icap_avail;
logic [2:0] icap_state_reg = 0;
logic icap_csib_reg = 1'b1;
logic icap_rdwrb_reg = 1'b0;
logic [31:0] icap_di_reg = 32'hffffffff;
wire [31:0] icap_di_rev;
assign icap_di_rev[ 7] = icap_di_reg[ 0];
assign icap_di_rev[ 6] = icap_di_reg[ 1];
assign icap_di_rev[ 5] = icap_di_reg[ 2];
assign icap_di_rev[ 4] = icap_di_reg[ 3];
assign icap_di_rev[ 3] = icap_di_reg[ 4];
assign icap_di_rev[ 2] = icap_di_reg[ 5];
assign icap_di_rev[ 1] = icap_di_reg[ 6];
assign icap_di_rev[ 0] = icap_di_reg[ 7];
assign icap_di_rev[15] = icap_di_reg[ 8];
assign icap_di_rev[14] = icap_di_reg[ 9];
assign icap_di_rev[13] = icap_di_reg[10];
assign icap_di_rev[12] = icap_di_reg[11];
assign icap_di_rev[11] = icap_di_reg[12];
assign icap_di_rev[10] = icap_di_reg[13];
assign icap_di_rev[ 9] = icap_di_reg[14];
assign icap_di_rev[ 8] = icap_di_reg[15];
assign icap_di_rev[23] = icap_di_reg[16];
assign icap_di_rev[22] = icap_di_reg[17];
assign icap_di_rev[21] = icap_di_reg[18];
assign icap_di_rev[20] = icap_di_reg[19];
assign icap_di_rev[19] = icap_di_reg[20];
assign icap_di_rev[18] = icap_di_reg[21];
assign icap_di_rev[17] = icap_di_reg[22];
assign icap_di_rev[16] = icap_di_reg[23];
assign icap_di_rev[31] = icap_di_reg[24];
assign icap_di_rev[30] = icap_di_reg[25];
assign icap_di_rev[29] = icap_di_reg[26];
assign icap_di_rev[28] = icap_di_reg[27];
assign icap_di_rev[27] = icap_di_reg[28];
assign icap_di_rev[26] = icap_di_reg[29];
assign icap_di_rev[25] = icap_di_reg[30];
assign icap_di_rev[24] = icap_di_reg[31];
always_ff @(posedge clk_125mhz_int) begin
case (icap_state_reg)
0: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b1;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
if (fpga_boot_sync && icap_avail) begin
icap_state_reg <= 1;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
end
end
1: begin
icap_state_reg <= 2;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hAA995566; // sync word
end
2: begin
icap_state_reg <= 3;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
3: begin
icap_state_reg <= 4;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h30008001; // write 1 word to CMD
end
4: begin
icap_state_reg <= 5;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h0000000F; // IPROG
end
5: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
endcase
end
ICAPE3
icape3_inst (
.AVAIL(icap_avail),
.CLK(clk_125mhz_int),
.CSIB(icap_csib_reg),
.I(icap_di_rev),
.O(),
.PRDONE(),
.PRERROR(),
.RDWRB(icap_rdwrb_reg)
);
// PCIe
localparam AXIS_PCIE_DATA_W = 512;
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
localparam AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161;
localparam AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137;
localparam AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183;
localparam AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81;
localparam RC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 256;
localparam RQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
localparam RQ_SEQ_NUM_EN = 1;
localparam PCIE_TAG_CNT = AXIS_PCIE_RQ_USER_W == 60 ? 64 : 256;
localparam BAR0_APERTURE = 24;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CQ_USER_W)
) axis_pcie_cq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CC_USER_W)
) axis_pcie_cc();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RQ_USER_W)
) axis_pcie_rq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RC_USER_W)
) axis_pcie_rc();
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0;
wire pcie_rq_seq_num_vld0;
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1;
wire pcie_rq_seq_num_vld1;
wire [2:0] cfg_max_payload;
wire [2:0] cfg_max_read_req;
wire [3:0] cfg_rcb_status;
wire [9:0] cfg_mgmt_addr;
wire [7:0] cfg_mgmt_function_number;
wire cfg_mgmt_write;
wire [31:0] cfg_mgmt_write_data;
wire [3:0] cfg_mgmt_byte_enable;
wire cfg_mgmt_read;
wire [31:0] cfg_mgmt_read_data;
wire cfg_mgmt_read_write_done;
wire [7:0] cfg_fc_ph;
wire [11:0] cfg_fc_pd;
wire [7:0] cfg_fc_nph;
wire [11:0] cfg_fc_npd;
wire [7:0] cfg_fc_cplh;
wire [11:0] cfg_fc_cpld;
wire [2:0] cfg_fc_sel;
wire cfg_ext_read_received;
wire cfg_ext_write_received;
wire [9:0] cfg_ext_register_number;
wire [7:0] cfg_ext_function_number;
wire [31:0] cfg_ext_write_data;
wire [3:0] cfg_ext_write_byte_enable;
wire [31:0] cfg_ext_read_data;
wire cfg_ext_read_data_valid;
// wire [3:0] cfg_interrupt_msix_enable;
// wire [3:0] cfg_interrupt_msix_mask;
// wire [251:0] cfg_interrupt_msix_vf_enable;
// wire [251:0] cfg_interrupt_msix_vf_mask;
// wire [63:0] cfg_interrupt_msix_address;
// wire [31:0] cfg_interrupt_msix_data;
// wire cfg_interrupt_msix_int;
// wire [1:0] cfg_interrupt_msix_vec_pending;
// wire cfg_interrupt_msix_vec_pending_status;
// wire cfg_interrupt_msix_sent;
// wire cfg_interrupt_msix_fail;
// wire [7:0] cfg_interrupt_msi_function_number;
wire [3:0] cfg_interrupt_msi_enable;
wire [11:0] cfg_interrupt_msi_mmenable;
wire cfg_interrupt_msi_mask_update;
wire [31:0] cfg_interrupt_msi_data;
wire [1:0] cfg_interrupt_msi_select;
wire [31:0] cfg_interrupt_msi_int;
wire [31:0] cfg_interrupt_msi_pending_status;
wire cfg_interrupt_msi_pending_status_data_enable;
wire [1:0] cfg_interrupt_msi_pending_status_function_num;
wire cfg_interrupt_msi_sent;
wire cfg_interrupt_msi_fail;
wire [2:0] cfg_interrupt_msi_attr;
wire cfg_interrupt_msi_tph_present;
wire [1:0] cfg_interrupt_msi_tph_type;
wire [7:0] cfg_interrupt_msi_tph_st_tag;
wire [7:0] cfg_interrupt_msi_function_number;
wire stat_err_cor;
wire stat_err_uncor;
wire pcie_sys_clk;
wire pcie_sys_clk_gt;
IBUFDS_GTE4 #(
.REFCLK_HROW_CK_SEL(2'b00)
)
ibufds_gte4_pcie_refclk_inst (
.I (pcie_refclk_p),
.IB (pcie_refclk_n),
.CEB (1'b0),
.O (pcie_sys_clk_gt),
.ODIV2 (pcie_sys_clk)
);
pcie4_uscale_plus_0
pcie4_uscale_plus_inst (
.pci_exp_txn(pcie_tx_n),
.pci_exp_txp(pcie_tx_p),
.pci_exp_rxn(pcie_rx_n),
.pci_exp_rxp(pcie_rx_p),
.user_clk(pcie_user_clk),
.user_reset(pcie_user_rst),
.user_lnk_up(),
.s_axis_rq_tdata(axis_pcie_rq.tdata),
.s_axis_rq_tkeep(axis_pcie_rq.tkeep),
.s_axis_rq_tlast(axis_pcie_rq.tlast),
.s_axis_rq_tready(axis_pcie_rq.tready),
.s_axis_rq_tuser(axis_pcie_rq.tuser),
.s_axis_rq_tvalid(axis_pcie_rq.tvalid),
.m_axis_rc_tdata(axis_pcie_rc.tdata),
.m_axis_rc_tkeep(axis_pcie_rc.tkeep),
.m_axis_rc_tlast(axis_pcie_rc.tlast),
.m_axis_rc_tready(axis_pcie_rc.tready),
.m_axis_rc_tuser(axis_pcie_rc.tuser),
.m_axis_rc_tvalid(axis_pcie_rc.tvalid),
.m_axis_cq_tdata(axis_pcie_cq.tdata),
.m_axis_cq_tkeep(axis_pcie_cq.tkeep),
.m_axis_cq_tlast(axis_pcie_cq.tlast),
.m_axis_cq_tready(axis_pcie_cq.tready),
.m_axis_cq_tuser(axis_pcie_cq.tuser),
.m_axis_cq_tvalid(axis_pcie_cq.tvalid),
.s_axis_cc_tdata(axis_pcie_cc.tdata),
.s_axis_cc_tkeep(axis_pcie_cc.tkeep),
.s_axis_cc_tlast(axis_pcie_cc.tlast),
.s_axis_cc_tready(axis_pcie_cc.tready),
.s_axis_cc_tuser(axis_pcie_cc.tuser),
.s_axis_cc_tvalid(axis_pcie_cc.tvalid),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.pcie_rq_tag0(),
.pcie_rq_tag1(),
.pcie_rq_tag_av(),
.pcie_rq_tag_vld0(),
.pcie_rq_tag_vld1(),
.pcie_tfc_nph_av(),
.pcie_tfc_npd_av(),
.pcie_cq_np_req(1'b1),
.pcie_cq_np_req_count(),
.cfg_phy_link_down(),
.cfg_phy_link_status(),
.cfg_negotiated_width(),
.cfg_current_speed(),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_function_status(),
.cfg_function_power_state(),
.cfg_vf_status(),
.cfg_vf_power_state(),
.cfg_link_power_state(),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_mgmt_debug_access(1'b0),
.cfg_err_cor_out(),
.cfg_err_nonfatal_out(),
.cfg_err_fatal_out(),
.cfg_local_error_valid(),
.cfg_local_error_out(),
.cfg_ltssm_state(),
.cfg_rx_pm_state(),
.cfg_tx_pm_state(),
.cfg_rcb_status(cfg_rcb_status),
.cfg_obff_enable(),
.cfg_pl_status_change(),
.cfg_tph_requester_enable(),
.cfg_tph_st_mode(),
.cfg_vf_tph_requester_enable(),
.cfg_vf_tph_st_mode(),
.cfg_msg_received(),
.cfg_msg_received_data(),
.cfg_msg_received_type(),
.cfg_msg_transmit(1'b0),
.cfg_msg_transmit_type(3'd0),
.cfg_msg_transmit_data(32'd0),
.cfg_msg_transmit_done(),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_dsn(64'd0),
.cfg_bus_number(),
.cfg_power_state_change_ack(1'b1),
.cfg_power_state_change_interrupt(),
.cfg_err_cor_in(stat_err_cor),
.cfg_err_uncor_in(stat_err_uncor),
.cfg_flr_in_process(),
.cfg_flr_done(4'd0),
.cfg_vf_flr_in_process(),
.cfg_vf_flr_func_num(8'd0),
.cfg_vf_flr_done(8'd0),
.cfg_link_training_enable(1'b1),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_int(4'd0),
.cfg_interrupt_pending(4'd0),
.cfg_interrupt_sent(),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msi_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msi_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_pm_aspm_l1_entry_reject(1'b0),
.cfg_pm_aspm_tx_l0s_entry_disable(1'b0),
.cfg_hot_reset_out(),
.cfg_config_space_enable(1'b1),
.cfg_req_pm_transition_l23_ready(1'b0),
.cfg_hot_reset_in(1'b0),
.cfg_ds_port_number(8'd0),
.cfg_ds_bus_number(8'd0),
.cfg_ds_device_number(5'd0),
.sys_clk(pcie_sys_clk),
.sys_clk_gt(pcie_sys_clk_gt),
.sys_reset(pcie_reset_n),
.phy_rdy_out()
);
wire uart_rxd_int[1];
wire uart_txd_int[1];
assign uart_txd = uart_txd_int[0];
assign uart_rxd_int[0] = uart_rxd;
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// Board configuration
.SW_CNT(4),
.LED_CNT(3),
.UART_CNT(1),
.PORT_CNT(PORT_CNT),
.GTY_QUAD_CNT(GTY_QUAD_CNT),
.GTY_CNT(GTY_CNT),
.GTY_CLK_CNT(GTY_CLK_CNT),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_CLK_PER_NS_NUM(32),
.PTP_CLK_PER_NS_DENOM(5),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
)
core_inst (
/*
* Clock: 125MHz
* Synchronous reset
*/
.clk_125mhz(clk_125mhz_int),
.rst_125mhz(rst_125mhz_int),
/*
* GPIO
*/
.sw(sw_int),
.led(led),
.port_led_act(),
.port_led_stat_r(),
.port_led_stat_g(),
.port_led_stat_b(),
.port_led_stat_y(),
/*
* UART
*/
.uart_txd(uart_txd_int),
.uart_rxd(uart_rxd_int),
/*
* Ethernet
*/
.eth_gty_tx_p(eth_gty_tx_p),
.eth_gty_tx_n(eth_gty_tx_n),
.eth_gty_rx_p(eth_gty_rx_p),
.eth_gty_rx_n(eth_gty_rx_n),
.eth_gty_mgt_refclk_p(eth_gty_mgt_refclk_p),
.eth_gty_mgt_refclk_n(eth_gty_mgt_refclk_n),
.eth_gty_mgt_refclk_out(eth_gty_mgt_refclk_out),
.eth_port_modsell({qsfp1_modsell, qsfp0_modsell}),
.eth_port_resetl({qsfp1_resetl, qsfp0_resetl}),
.eth_port_modprsl({qsfp1_modprsl, qsfp0_modprsl}),
.eth_port_intl({qsfp1_intl, qsfp0_intl}),
.eth_port_lpmode({qsfp1_lpmode, qsfp0_lpmode}),
/*
* PCIe
*/
.pcie_clk(pcie_user_clk),
.pcie_rst(pcie_user_rst),
.s_axis_pcie_cq(axis_pcie_cq),
.m_axis_pcie_cc(axis_pcie_cc),
.m_axis_pcie_rq(axis_pcie_rq),
.s_axis_pcie_rc(axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msix_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msix_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk_int),
.qspi_dq_i(qspi_dq_i_int),
.qspi_dq_o(qspi_dq_o_int),
.qspi_dq_oe(qspi_dq_oe_int),
.qspi_cs(qspi_cs_int)
);
endmodule
`resetall

View File

@@ -0,0 +1,913 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2014-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga #
(
// simulation (set to avoid vendor primitives)
parameter logic SIM = 1'b0,
// vendor ("GENERIC", "XILINX", "ALTERA")
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// FW ID
parameter FPGA_ID = 32'h4B7D093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h10ee_9118,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
)
(
/*
* Reset: Push button, active low
*/
input wire logic reset,
/*
* GPIO
*/
output wire logic hbm_cattrip,
/*
* UART
*/
output wire logic uart_txd,
input wire logic uart_rxd,
/*
* Ethernet: QSFP28
*/
output wire logic qsfp0_tx_p[4],
output wire logic qsfp0_tx_n[4],
input wire logic qsfp0_rx_p[4],
input wire logic qsfp0_rx_n[4],
input wire logic qsfp0_mgt_refclk_0_p,
input wire logic qsfp0_mgt_refclk_0_n,
// input wire logic qsfp0_mgt_refclk_1_p,
// input wire logic qsfp0_mgt_refclk_1_n,
output wire logic qsfp0_refclk_oe_b,
output wire logic qsfp0_refclk_fs,
output wire logic qsfp1_tx_p[4],
output wire logic qsfp1_tx_n[4],
input wire logic qsfp1_rx_p[4],
input wire logic qsfp1_rx_n[4],
input wire logic qsfp1_mgt_refclk_0_p,
input wire logic qsfp1_mgt_refclk_0_n,
// input wire logic qsfp1_mgt_refclk_1_p,
// input wire logic qsfp1_mgt_refclk_1_n,
output wire logic qsfp1_refclk_oe_b,
output wire logic qsfp1_refclk_fs,
/*
* PCIe
*/
input wire logic [15:0] pcie_rx_p,
input wire logic [15:0] pcie_rx_n,
output wire logic [15:0] pcie_tx_p,
output wire logic [15:0] pcie_tx_n,
input wire logic pcie_refclk_1_p,
input wire logic pcie_refclk_1_n,
input wire logic pcie_reset_n
);
// Clock and reset
wire pcie_user_clk;
wire pcie_user_rst;
wire clk_156mhz_ref_int;
// Internal 125 MHz clock
wire clk_125mhz_mmcm_out;
wire clk_125mhz_int;
wire rst_125mhz_int;
wire mmcm_rst = ~reset;
wire mmcm_locked;
wire mmcm_clkfb;
// MMCM instance
MMCME4_BASE #(
// 156.25 MHz input
.CLKIN1_PERIOD(6.4),
.REF_JITTER1(0.010),
// 156.25 MHz input / 1 = 156.25 MHz PFD (range 10 MHz to 500 MHz)
.DIVCLK_DIVIDE(1),
// 156.25 MHz PFD * 8 = 1250 MHz VCO (range 800 MHz to 1600 MHz)
.CLKFBOUT_MULT_F(8),
.CLKFBOUT_PHASE(0),
// 1250 MHz / 10 = 125 MHz, 0 degrees
.CLKOUT0_DIVIDE_F(10),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0),
// Not used
.CLKOUT1_DIVIDE(1),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT1_PHASE(0),
// Not used
.CLKOUT2_DIVIDE(1),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT2_PHASE(0),
// Not used
.CLKOUT3_DIVIDE(1),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT3_PHASE(0),
// Not used
.CLKOUT4_DIVIDE(1),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT4_PHASE(0),
.CLKOUT4_CASCADE("FALSE"),
// Not used
.CLKOUT5_DIVIDE(1),
.CLKOUT5_DUTY_CYCLE(0.5),
.CLKOUT5_PHASE(0),
// Not used
.CLKOUT6_DIVIDE(1),
.CLKOUT6_DUTY_CYCLE(0.5),
.CLKOUT6_PHASE(0),
// optimized bandwidth
.BANDWIDTH("OPTIMIZED"),
// don't wait for lock during startup
.STARTUP_WAIT("FALSE")
)
clk_mmcm_inst (
// 156.25 MHz input
.CLKIN1(clk_156mhz_ref_int),
// direct clkfb feeback
.CLKFBIN(mmcm_clkfb),
.CLKFBOUT(mmcm_clkfb),
.CLKFBOUTB(),
// 125 MHz, 0 degrees
.CLKOUT0(clk_125mhz_mmcm_out),
.CLKOUT0B(),
// Not used
.CLKOUT1(),
.CLKOUT1B(),
// Not used
.CLKOUT2(),
.CLKOUT2B(),
// Not used
.CLKOUT3(),
.CLKOUT3B(),
// Not used
.CLKOUT4(),
// Not used
.CLKOUT5(),
// Not used
.CLKOUT6(),
// reset input
.RST(mmcm_rst),
// don't power down
.PWRDWN(1'b0),
// locked output
.LOCKED(mmcm_locked)
);
BUFG
clk_125mhz_bufg_inst (
.I(clk_125mhz_mmcm_out),
.O(clk_125mhz_int)
);
taxi_sync_reset #(
.N(4)
)
sync_reset_125mhz_inst (
.clk(clk_125mhz_int),
.rst(~mmcm_locked),
.out(rst_125mhz_int)
);
// GPIO
assign hbm_cattrip = 1'b0;
assign qsfp0_refclk_oe_b = 1'b0;
assign qsfp0_refclk_fs = 1'b1;
assign qsfp1_refclk_oe_b = 1'b0;
assign qsfp1_refclk_fs = 1'b1;
localparam PORT_CNT = 2;
localparam GTY_QUAD_CNT = PORT_CNT;
localparam GTY_CNT = GTY_QUAD_CNT*4;
localparam GTY_CLK_CNT = GTY_QUAD_CNT;
wire eth_gty_tx_p[GTY_CNT];
wire eth_gty_tx_n[GTY_CNT];
wire eth_gty_rx_p[GTY_CNT];
wire eth_gty_rx_n[GTY_CNT];
wire eth_gty_mgt_refclk_p[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_n[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_out[GTY_CLK_CNT];
assign qsfp0_tx_p = eth_gty_tx_p[4*0 +: 4];
assign qsfp0_tx_n = eth_gty_tx_n[4*0 +: 4];
assign eth_gty_rx_p[4*0 +: 4] = qsfp0_rx_p;
assign eth_gty_rx_n[4*0 +: 4] = qsfp0_rx_n;
assign qsfp1_tx_p = eth_gty_tx_p[4*1 +: 4];
assign qsfp1_tx_n = eth_gty_tx_n[4*1 +: 4];
assign eth_gty_rx_p[4*1 +: 4] = qsfp1_rx_p;
assign eth_gty_rx_n[4*1 +: 4] = qsfp1_rx_n;
assign eth_gty_mgt_refclk_p[0] = qsfp0_mgt_refclk_0_p;
assign eth_gty_mgt_refclk_n[0] = qsfp0_mgt_refclk_0_n;
assign eth_gty_mgt_refclk_p[1] = qsfp1_mgt_refclk_0_p;
assign eth_gty_mgt_refclk_n[1] = qsfp1_mgt_refclk_0_n;
assign clk_156mhz_ref_int = eth_gty_mgt_refclk_out[0];
// Flash
wire qspi_clk_int;
wire [3:0] qspi_dq_int;
wire [3:0] qspi_dq_i_int;
wire [3:0] qspi_dq_o_int;
wire [3:0] qspi_dq_oe_int;
wire qspi_cs_int;
reg qspi_clk_reg;
reg [3:0] qspi_dq_o_reg;
reg [3:0] qspi_dq_oe_reg;
reg qspi_cs_reg;
always_ff @(posedge pcie_user_clk) begin
qspi_clk_reg <= qspi_clk_int;
qspi_dq_o_reg <= qspi_dq_o_int;
qspi_dq_oe_reg <= qspi_dq_oe_int;
qspi_cs_reg <= qspi_cs_int;
end
taxi_sync_signal #(
.WIDTH(8),
.N(2)
)
flash_sync_inst (
.clk(pcie_user_clk),
.in({qspi_dq_int}),
.out({qspi_dq_i_int})
);
STARTUPE3
startupe3_inst (
.CFGCLK(),
.CFGMCLK(),
.DI(qspi_dq_int),
.DO(qspi_dq_o_reg),
.DTS(~qspi_dq_oe_reg),
.EOS(),
.FCSBO(qspi_cs_reg),
.FCSBTS(1'b0),
.GSR(1'b0),
.GTS(1'b0),
.KEYCLEARB(1'b1),
.PACK(1'b0),
.PREQ(),
.USRCCLKO(qspi_clk_reg),
.USRCCLKTS(1'b0),
.USRDONEO(1'b0),
.USRDONETS(1'b1)
);
// FPGA boot
wire fpga_boot;
wire fpga_boot_sync;
taxi_sync_signal #(
.WIDTH(1),
.N(2)
)
fpga_boot_sync_inst (
.clk(clk_125mhz_int),
.in({fpga_boot}),
.out({fpga_boot_sync})
);
wire icap_avail;
logic [2:0] icap_state_reg = 0;
logic icap_csib_reg = 1'b1;
logic icap_rdwrb_reg = 1'b0;
logic [31:0] icap_di_reg = 32'hffffffff;
wire [31:0] icap_di_rev;
assign icap_di_rev[ 7] = icap_di_reg[ 0];
assign icap_di_rev[ 6] = icap_di_reg[ 1];
assign icap_di_rev[ 5] = icap_di_reg[ 2];
assign icap_di_rev[ 4] = icap_di_reg[ 3];
assign icap_di_rev[ 3] = icap_di_reg[ 4];
assign icap_di_rev[ 2] = icap_di_reg[ 5];
assign icap_di_rev[ 1] = icap_di_reg[ 6];
assign icap_di_rev[ 0] = icap_di_reg[ 7];
assign icap_di_rev[15] = icap_di_reg[ 8];
assign icap_di_rev[14] = icap_di_reg[ 9];
assign icap_di_rev[13] = icap_di_reg[10];
assign icap_di_rev[12] = icap_di_reg[11];
assign icap_di_rev[11] = icap_di_reg[12];
assign icap_di_rev[10] = icap_di_reg[13];
assign icap_di_rev[ 9] = icap_di_reg[14];
assign icap_di_rev[ 8] = icap_di_reg[15];
assign icap_di_rev[23] = icap_di_reg[16];
assign icap_di_rev[22] = icap_di_reg[17];
assign icap_di_rev[21] = icap_di_reg[18];
assign icap_di_rev[20] = icap_di_reg[19];
assign icap_di_rev[19] = icap_di_reg[20];
assign icap_di_rev[18] = icap_di_reg[21];
assign icap_di_rev[17] = icap_di_reg[22];
assign icap_di_rev[16] = icap_di_reg[23];
assign icap_di_rev[31] = icap_di_reg[24];
assign icap_di_rev[30] = icap_di_reg[25];
assign icap_di_rev[29] = icap_di_reg[26];
assign icap_di_rev[28] = icap_di_reg[27];
assign icap_di_rev[27] = icap_di_reg[28];
assign icap_di_rev[26] = icap_di_reg[29];
assign icap_di_rev[25] = icap_di_reg[30];
assign icap_di_rev[24] = icap_di_reg[31];
always_ff @(posedge clk_125mhz_int) begin
case (icap_state_reg)
0: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b1;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
if (fpga_boot_sync && icap_avail) begin
icap_state_reg <= 1;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
end
end
1: begin
icap_state_reg <= 2;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hAA995566; // sync word
end
2: begin
icap_state_reg <= 3;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
3: begin
icap_state_reg <= 4;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h30008001; // write 1 word to CMD
end
4: begin
icap_state_reg <= 5;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h0000000F; // IPROG
end
5: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
endcase
end
ICAPE3
icape3_inst (
.AVAIL(icap_avail),
.CLK(clk_125mhz_int),
.CSIB(icap_csib_reg),
.I(icap_di_rev),
.O(),
.PRDONE(),
.PRERROR(),
.RDWRB(icap_rdwrb_reg)
);
// PCIe
localparam AXIS_PCIE_DATA_W = 512;
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
localparam AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161;
localparam AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137;
localparam AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183;
localparam AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81;
localparam RC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 256;
localparam RQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
localparam RQ_SEQ_NUM_EN = 1;
localparam PCIE_TAG_CNT = AXIS_PCIE_RQ_USER_W == 60 ? 64 : 256;
localparam BAR0_APERTURE = 24;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CQ_USER_W)
) axis_pcie_cq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CC_USER_W)
) axis_pcie_cc();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RQ_USER_W)
) axis_pcie_rq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RC_USER_W)
) axis_pcie_rc();
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0;
wire pcie_rq_seq_num_vld0;
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1;
wire pcie_rq_seq_num_vld1;
wire [2:0] cfg_max_payload;
wire [2:0] cfg_max_read_req;
wire [3:0] cfg_rcb_status;
wire [9:0] cfg_mgmt_addr;
wire [7:0] cfg_mgmt_function_number;
wire cfg_mgmt_write;
wire [31:0] cfg_mgmt_write_data;
wire [3:0] cfg_mgmt_byte_enable;
wire cfg_mgmt_read;
wire [31:0] cfg_mgmt_read_data;
wire cfg_mgmt_read_write_done;
wire [7:0] cfg_fc_ph;
wire [11:0] cfg_fc_pd;
wire [7:0] cfg_fc_nph;
wire [11:0] cfg_fc_npd;
wire [7:0] cfg_fc_cplh;
wire [11:0] cfg_fc_cpld;
wire [2:0] cfg_fc_sel;
wire cfg_ext_read_received;
wire cfg_ext_write_received;
wire [9:0] cfg_ext_register_number;
wire [7:0] cfg_ext_function_number;
wire [31:0] cfg_ext_write_data;
wire [3:0] cfg_ext_write_byte_enable;
wire [31:0] cfg_ext_read_data;
wire cfg_ext_read_data_valid;
// wire [3:0] cfg_interrupt_msix_enable;
// wire [3:0] cfg_interrupt_msix_mask;
// wire [251:0] cfg_interrupt_msix_vf_enable;
// wire [251:0] cfg_interrupt_msix_vf_mask;
// wire [63:0] cfg_interrupt_msix_address;
// wire [31:0] cfg_interrupt_msix_data;
// wire cfg_interrupt_msix_int;
// wire [1:0] cfg_interrupt_msix_vec_pending;
// wire cfg_interrupt_msix_vec_pending_status;
// wire cfg_interrupt_msix_sent;
// wire cfg_interrupt_msix_fail;
// wire [7:0] cfg_interrupt_msi_function_number;
wire [3:0] cfg_interrupt_msi_enable;
wire [11:0] cfg_interrupt_msi_mmenable;
wire cfg_interrupt_msi_mask_update;
wire [31:0] cfg_interrupt_msi_data;
wire [1:0] cfg_interrupt_msi_select;
wire [31:0] cfg_interrupt_msi_int;
wire [31:0] cfg_interrupt_msi_pending_status;
wire cfg_interrupt_msi_pending_status_data_enable;
wire [1:0] cfg_interrupt_msi_pending_status_function_num;
wire cfg_interrupt_msi_sent;
wire cfg_interrupt_msi_fail;
wire [2:0] cfg_interrupt_msi_attr;
wire cfg_interrupt_msi_tph_present;
wire [1:0] cfg_interrupt_msi_tph_type;
wire [7:0] cfg_interrupt_msi_tph_st_tag;
wire [7:0] cfg_interrupt_msi_function_number;
wire stat_err_cor;
wire stat_err_uncor;
wire pcie_sys_clk;
wire pcie_sys_clk_gt;
IBUFDS_GTE4 #(
.REFCLK_HROW_CK_SEL(2'b00)
)
ibufds_gte4_pcie_refclk_inst (
.I (pcie_refclk_1_p),
.IB (pcie_refclk_1_n),
.CEB (1'b0),
.O (pcie_sys_clk_gt),
.ODIV2 (pcie_sys_clk)
);
pcie4c_uscale_plus_0
pcie4c_uscale_plus_inst (
.pci_exp_txn(pcie_tx_n),
.pci_exp_txp(pcie_tx_p),
.pci_exp_rxn(pcie_rx_n),
.pci_exp_rxp(pcie_rx_p),
.user_clk(pcie_user_clk),
.user_reset(pcie_user_rst),
.user_lnk_up(),
.s_axis_rq_tdata(axis_pcie_rq.tdata),
.s_axis_rq_tkeep(axis_pcie_rq.tkeep),
.s_axis_rq_tlast(axis_pcie_rq.tlast),
.s_axis_rq_tready(axis_pcie_rq.tready),
.s_axis_rq_tuser(axis_pcie_rq.tuser),
.s_axis_rq_tvalid(axis_pcie_rq.tvalid),
.m_axis_rc_tdata(axis_pcie_rc.tdata),
.m_axis_rc_tkeep(axis_pcie_rc.tkeep),
.m_axis_rc_tlast(axis_pcie_rc.tlast),
.m_axis_rc_tready(axis_pcie_rc.tready),
.m_axis_rc_tuser(axis_pcie_rc.tuser),
.m_axis_rc_tvalid(axis_pcie_rc.tvalid),
.m_axis_cq_tdata(axis_pcie_cq.tdata),
.m_axis_cq_tkeep(axis_pcie_cq.tkeep),
.m_axis_cq_tlast(axis_pcie_cq.tlast),
.m_axis_cq_tready(axis_pcie_cq.tready),
.m_axis_cq_tuser(axis_pcie_cq.tuser),
.m_axis_cq_tvalid(axis_pcie_cq.tvalid),
.s_axis_cc_tdata(axis_pcie_cc.tdata),
.s_axis_cc_tkeep(axis_pcie_cc.tkeep),
.s_axis_cc_tlast(axis_pcie_cc.tlast),
.s_axis_cc_tready(axis_pcie_cc.tready),
.s_axis_cc_tuser(axis_pcie_cc.tuser),
.s_axis_cc_tvalid(axis_pcie_cc.tvalid),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.pcie_rq_tag0(),
.pcie_rq_tag1(),
.pcie_rq_tag_av(),
.pcie_rq_tag_vld0(),
.pcie_rq_tag_vld1(),
.pcie_tfc_nph_av(),
.pcie_tfc_npd_av(),
.pcie_cq_np_req(1'b1),
.pcie_cq_np_req_count(),
.cfg_phy_link_down(),
.cfg_phy_link_status(),
.cfg_negotiated_width(),
.cfg_current_speed(),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_function_status(),
.cfg_function_power_state(),
.cfg_vf_status(),
.cfg_vf_power_state(),
.cfg_link_power_state(),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_mgmt_debug_access(1'b0),
.cfg_err_cor_out(),
.cfg_err_nonfatal_out(),
.cfg_err_fatal_out(),
.cfg_local_error_valid(),
.cfg_local_error_out(),
.cfg_ltssm_state(),
.cfg_rx_pm_state(),
.cfg_tx_pm_state(),
.cfg_rcb_status(cfg_rcb_status),
.cfg_obff_enable(),
.cfg_pl_status_change(),
.cfg_tph_requester_enable(),
.cfg_tph_st_mode(),
.cfg_vf_tph_requester_enable(),
.cfg_vf_tph_st_mode(),
.cfg_msg_received(),
.cfg_msg_received_data(),
.cfg_msg_received_type(),
.cfg_msg_transmit(1'b0),
.cfg_msg_transmit_type(3'd0),
.cfg_msg_transmit_data(32'd0),
.cfg_msg_transmit_done(),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_dsn(64'd0),
.cfg_bus_number(),
.cfg_power_state_change_ack(1'b1),
.cfg_power_state_change_interrupt(),
.cfg_err_cor_in(stat_err_cor),
.cfg_err_uncor_in(stat_err_uncor),
.cfg_flr_in_process(),
.cfg_flr_done(4'd0),
.cfg_vf_flr_in_process(),
.cfg_vf_flr_func_num(8'd0),
.cfg_vf_flr_done(8'd0),
.cfg_link_training_enable(1'b1),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_int(4'd0),
.cfg_interrupt_pending(4'd0),
.cfg_interrupt_sent(),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msi_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msi_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_pm_aspm_l1_entry_reject(1'b0),
.cfg_pm_aspm_tx_l0s_entry_disable(1'b0),
.cfg_hot_reset_out(),
.cfg_config_space_enable(1'b1),
.cfg_req_pm_transition_l23_ready(1'b0),
.cfg_hot_reset_in(1'b0),
.cfg_ds_port_number(8'd0),
.cfg_ds_bus_number(8'd0),
.cfg_ds_device_number(5'd0),
.sys_clk(pcie_sys_clk),
.sys_clk_gt(pcie_sys_clk_gt),
.sys_reset(pcie_reset_n),
.phy_rdy_out()
);
wire uart_rxd_int[1];
wire uart_txd_int[1];
assign uart_txd = uart_txd_int[0];
assign uart_rxd_int[0] = uart_rxd;
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// Board configuration
.SW_CNT(4),
.LED_CNT(3),
.UART_CNT(1),
.PORT_CNT(PORT_CNT),
.GTY_QUAD_CNT(GTY_QUAD_CNT),
.GTY_CNT(GTY_CNT),
.GTY_CLK_CNT(GTY_CLK_CNT),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_CLK_PER_NS_NUM(32),
.PTP_CLK_PER_NS_DENOM(5),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
)
core_inst (
/*
* Clock: 125MHz
* Synchronous reset
*/
.clk_125mhz(clk_125mhz_int),
.rst_125mhz(rst_125mhz_int),
/*
* GPIO
*/
.sw('0),
.led(),
.port_led_act(),
.port_led_stat_r(),
.port_led_stat_g(),
.port_led_stat_b(),
.port_led_stat_y(),
/*
* UART
*/
.uart_txd(uart_txd_int),
.uart_rxd(uart_rxd_int),
/*
* Ethernet
*/
.eth_gty_tx_p(eth_gty_tx_p),
.eth_gty_tx_n(eth_gty_tx_n),
.eth_gty_rx_p(eth_gty_rx_p),
.eth_gty_rx_n(eth_gty_rx_n),
.eth_gty_mgt_refclk_p(eth_gty_mgt_refclk_p),
.eth_gty_mgt_refclk_n(eth_gty_mgt_refclk_n),
.eth_gty_mgt_refclk_out(eth_gty_mgt_refclk_out),
.eth_port_modsell(),
.eth_port_resetl(),
.eth_port_modprsl('0),
.eth_port_intl('0),
.eth_port_lpmode(),
/*
* PCIe
*/
.pcie_clk(pcie_user_clk),
.pcie_rst(pcie_user_rst),
.s_axis_pcie_cq(axis_pcie_cq),
.m_axis_pcie_cc(axis_pcie_cc),
.m_axis_pcie_rq(axis_pcie_rq),
.s_axis_pcie_rc(axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msix_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msix_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk_int),
.qspi_dq_i(qspi_dq_i_int),
.qspi_dq_o(qspi_dq_o_int),
.qspi_dq_oe(qspi_dq_oe_int),
.qspi_cs(qspi_cs_int)
);
endmodule
`resetall

View File

@@ -0,0 +1,895 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2014-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga #
(
// simulation (set to avoid vendor primitives)
parameter logic SIM = 1'b0,
// vendor ("GENERIC", "XILINX", "ALTERA")
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// Board configuration
parameter QSFP_CNT = 2,
parameter UART_CNT = 1,
// FW ID
parameter FPGA_ID = 32'h4AD5093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h10ee_902d,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
)
(
/*
* GPIO
*/
output wire logic card_heart_bit,
output wire logic card_status_led,
output wire logic [QSFP_CNT-1:0] qsfp_led_act,
output wire logic [QSFP_CNT-1:0] qsfp_led_stat_g,
output wire logic [QSFP_CNT-1:0] qsfp_led_stat_y,
/*
* UART
*/
output wire logic uart_txd,
input wire logic uart_rxd,
/*
* Ethernet: QSFP28
*/
// output wire logic qsfp0_tx_p[4],
// output wire logic qsfp0_tx_n[4],
// input wire logic qsfp0_rx_p[4],
// input wire logic qsfp0_rx_n[4],
// input wire logic qsfp0_mgt_refclk_0_p,
// input wire logic qsfp0_mgt_refclk_0_n,
// input wire logic qsfp0_mgt_refclk_1_p,
// input wire logic qsfp0_mgt_refclk_1_n,
output wire logic qsfp1_tx_p[4],
output wire logic qsfp1_tx_n[4],
input wire logic qsfp1_rx_p[4],
input wire logic qsfp1_rx_n[4],
input wire logic qsfp1_mgt_refclk_p,
input wire logic qsfp1_mgt_refclk_n,
/*
* PCIe
*/
input wire logic [15:0] pcie_rx_p,
input wire logic [15:0] pcie_rx_n,
output wire logic [15:0] pcie_tx_p,
output wire logic [15:0] pcie_tx_n,
input wire logic pcie_refclk_1_p,
input wire logic pcie_refclk_1_n,
input wire logic pcie_reset_n
);
// Clock and reset
wire pcie_user_clk;
wire pcie_user_rst;
wire clk_161mhz_ref_int;
// Internal 125 MHz clock
wire clk_125mhz_mmcm_out;
wire clk_125mhz_int;
wire rst_125mhz_int;
wire mmcm_rst = 1'b0;
wire mmcm_locked;
wire mmcm_clkfb;
// MMCM instance
MMCME4_BASE #(
// 161.13 MHz input
.CLKIN1_PERIOD(6.206),
.REF_JITTER1(0.010),
// 161.13 MHz input / 11 = 14.65 MHz PFD (range 10 MHz to 500 MHz)
.DIVCLK_DIVIDE(11),
// 14.65 MHz PFD * 64 = 937.5 MHz VCO (range 800 MHz to 1600 MHz)
.CLKFBOUT_MULT_F(64),
.CLKFBOUT_PHASE(0),
// 937.5 MHz / 7.5 = 125 MHz, 0 degrees
.CLKOUT0_DIVIDE_F(7.5),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0),
// Not used
.CLKOUT1_DIVIDE(1),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT1_PHASE(0),
// Not used
.CLKOUT2_DIVIDE(1),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT2_PHASE(0),
// Not used
.CLKOUT3_DIVIDE(1),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT3_PHASE(0),
// Not used
.CLKOUT4_DIVIDE(1),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT4_PHASE(0),
.CLKOUT4_CASCADE("FALSE"),
// Not used
.CLKOUT5_DIVIDE(1),
.CLKOUT5_DUTY_CYCLE(0.5),
.CLKOUT5_PHASE(0),
// Not used
.CLKOUT6_DIVIDE(1),
.CLKOUT6_DUTY_CYCLE(0.5),
.CLKOUT6_PHASE(0),
// optimized bandwidth
.BANDWIDTH("OPTIMIZED"),
// don't wait for lock during startup
.STARTUP_WAIT("FALSE")
)
clk_mmcm_inst (
// 161.13 MHz input
.CLKIN1(clk_161mhz_ref_int),
// direct clkfb feeback
.CLKFBIN(mmcm_clkfb),
.CLKFBOUT(mmcm_clkfb),
.CLKFBOUTB(),
// 125 MHz, 0 degrees
.CLKOUT0(clk_125mhz_mmcm_out),
.CLKOUT0B(),
// Not used
.CLKOUT1(),
.CLKOUT1B(),
// Not used
.CLKOUT2(),
.CLKOUT2B(),
// Not used
.CLKOUT3(),
.CLKOUT3B(),
// Not used
.CLKOUT4(),
// Not used
.CLKOUT5(),
// Not used
.CLKOUT6(),
// reset input
.RST(mmcm_rst),
// don't power down
.PWRDWN(1'b0),
// locked output
.LOCKED(mmcm_locked)
);
BUFG
clk_125mhz_bufg_inst (
.I(clk_125mhz_mmcm_out),
.O(clk_125mhz_int)
);
taxi_sync_reset #(
.N(4)
)
sync_reset_125mhz_inst (
.clk(clk_125mhz_int),
.rst(~mmcm_locked),
.out(rst_125mhz_int)
);
localparam PORT_CNT = QSFP_CNT;
localparam GTY_QUAD_CNT = 1;
localparam GTY_CNT = GTY_QUAD_CNT*4;
localparam GTY_CLK_CNT = GTY_QUAD_CNT;
wire eth_gty_tx_p[GTY_CNT];
wire eth_gty_tx_n[GTY_CNT];
wire eth_gty_rx_p[GTY_CNT];
wire eth_gty_rx_n[GTY_CNT];
wire eth_gty_mgt_refclk_p[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_n[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_out[GTY_CLK_CNT];
assign qsfp1_tx_p = eth_gty_tx_p[4*0 +: 4];
assign qsfp1_tx_n = eth_gty_tx_n[4*0 +: 4];
assign eth_gty_rx_p[4*0 +: 4] = qsfp1_rx_p;
assign eth_gty_rx_n[4*0 +: 4] = qsfp1_rx_n;
assign eth_gty_mgt_refclk_p[0] = qsfp1_mgt_refclk_p;
assign eth_gty_mgt_refclk_n[0] = qsfp1_mgt_refclk_n;
assign clk_161mhz_ref_int = eth_gty_mgt_refclk_out[0];
// Flash
wire qspi_clk_int;
wire [3:0] qspi_dq_int;
wire [3:0] qspi_dq_i_int;
wire [3:0] qspi_dq_o_int;
wire [3:0] qspi_dq_oe_int;
wire qspi_cs_int;
reg qspi_clk_reg;
reg [3:0] qspi_dq_o_reg;
reg [3:0] qspi_dq_oe_reg;
reg qspi_cs_reg;
always_ff @(posedge pcie_user_clk) begin
qspi_clk_reg <= qspi_clk_int;
qspi_dq_o_reg <= qspi_dq_o_int;
qspi_dq_oe_reg <= qspi_dq_oe_int;
qspi_cs_reg <= qspi_cs_int;
end
taxi_sync_signal #(
.WIDTH(8),
.N(2)
)
flash_sync_inst (
.clk(pcie_user_clk),
.in({qspi_dq_int}),
.out({qspi_dq_i_int})
);
STARTUPE3
startupe3_inst (
.CFGCLK(),
.CFGMCLK(),
.DI(qspi_dq_int),
.DO(qspi_dq_o_reg),
.DTS(~qspi_dq_oe_reg),
.EOS(),
.FCSBO(qspi_cs_reg),
.FCSBTS(1'b0),
.GSR(1'b0),
.GTS(1'b0),
.KEYCLEARB(1'b1),
.PACK(1'b0),
.PREQ(),
.USRCCLKO(qspi_clk_reg),
.USRCCLKTS(1'b0),
.USRDONEO(1'b0),
.USRDONETS(1'b1)
);
// FPGA boot
wire fpga_boot;
wire fpga_boot_sync;
taxi_sync_signal #(
.WIDTH(1),
.N(2)
)
fpga_boot_sync_inst (
.clk(clk_125mhz_int),
.in({fpga_boot}),
.out({fpga_boot_sync})
);
wire icap_avail;
logic [2:0] icap_state_reg = 0;
logic icap_csib_reg = 1'b1;
logic icap_rdwrb_reg = 1'b0;
logic [31:0] icap_di_reg = 32'hffffffff;
wire [31:0] icap_di_rev;
assign icap_di_rev[ 7] = icap_di_reg[ 0];
assign icap_di_rev[ 6] = icap_di_reg[ 1];
assign icap_di_rev[ 5] = icap_di_reg[ 2];
assign icap_di_rev[ 4] = icap_di_reg[ 3];
assign icap_di_rev[ 3] = icap_di_reg[ 4];
assign icap_di_rev[ 2] = icap_di_reg[ 5];
assign icap_di_rev[ 1] = icap_di_reg[ 6];
assign icap_di_rev[ 0] = icap_di_reg[ 7];
assign icap_di_rev[15] = icap_di_reg[ 8];
assign icap_di_rev[14] = icap_di_reg[ 9];
assign icap_di_rev[13] = icap_di_reg[10];
assign icap_di_rev[12] = icap_di_reg[11];
assign icap_di_rev[11] = icap_di_reg[12];
assign icap_di_rev[10] = icap_di_reg[13];
assign icap_di_rev[ 9] = icap_di_reg[14];
assign icap_di_rev[ 8] = icap_di_reg[15];
assign icap_di_rev[23] = icap_di_reg[16];
assign icap_di_rev[22] = icap_di_reg[17];
assign icap_di_rev[21] = icap_di_reg[18];
assign icap_di_rev[20] = icap_di_reg[19];
assign icap_di_rev[19] = icap_di_reg[20];
assign icap_di_rev[18] = icap_di_reg[21];
assign icap_di_rev[17] = icap_di_reg[22];
assign icap_di_rev[16] = icap_di_reg[23];
assign icap_di_rev[31] = icap_di_reg[24];
assign icap_di_rev[30] = icap_di_reg[25];
assign icap_di_rev[29] = icap_di_reg[26];
assign icap_di_rev[28] = icap_di_reg[27];
assign icap_di_rev[27] = icap_di_reg[28];
assign icap_di_rev[26] = icap_di_reg[29];
assign icap_di_rev[25] = icap_di_reg[30];
assign icap_di_rev[24] = icap_di_reg[31];
always_ff @(posedge clk_125mhz_int) begin
case (icap_state_reg)
0: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b1;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
if (fpga_boot_sync && icap_avail) begin
icap_state_reg <= 1;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
end
end
1: begin
icap_state_reg <= 2;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hAA995566; // sync word
end
2: begin
icap_state_reg <= 3;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
3: begin
icap_state_reg <= 4;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h30008001; // write 1 word to CMD
end
4: begin
icap_state_reg <= 5;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h0000000F; // IPROG
end
5: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
endcase
end
ICAPE3
icape3_inst (
.AVAIL(icap_avail),
.CLK(clk_125mhz_int),
.CSIB(icap_csib_reg),
.I(icap_di_rev),
.O(),
.PRDONE(),
.PRERROR(),
.RDWRB(icap_rdwrb_reg)
);
// PCIe
localparam AXIS_PCIE_DATA_W = 512;
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
localparam AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161;
localparam AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137;
localparam AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183;
localparam AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81;
localparam RC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 256;
localparam RQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
localparam RQ_SEQ_NUM_EN = 1;
localparam PCIE_TAG_CNT = AXIS_PCIE_RQ_USER_W == 60 ? 64 : 256;
localparam BAR0_APERTURE = 24;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CQ_USER_W)
) axis_pcie_cq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CC_USER_W)
) axis_pcie_cc();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RQ_USER_W)
) axis_pcie_rq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RC_USER_W)
) axis_pcie_rc();
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0;
wire pcie_rq_seq_num_vld0;
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1;
wire pcie_rq_seq_num_vld1;
wire [2:0] cfg_max_payload;
wire [2:0] cfg_max_read_req;
wire [3:0] cfg_rcb_status;
wire [9:0] cfg_mgmt_addr;
wire [7:0] cfg_mgmt_function_number;
wire cfg_mgmt_write;
wire [31:0] cfg_mgmt_write_data;
wire [3:0] cfg_mgmt_byte_enable;
wire cfg_mgmt_read;
wire [31:0] cfg_mgmt_read_data;
wire cfg_mgmt_read_write_done;
wire [7:0] cfg_fc_ph;
wire [11:0] cfg_fc_pd;
wire [7:0] cfg_fc_nph;
wire [11:0] cfg_fc_npd;
wire [7:0] cfg_fc_cplh;
wire [11:0] cfg_fc_cpld;
wire [2:0] cfg_fc_sel;
wire cfg_ext_read_received;
wire cfg_ext_write_received;
wire [9:0] cfg_ext_register_number;
wire [7:0] cfg_ext_function_number;
wire [31:0] cfg_ext_write_data;
wire [3:0] cfg_ext_write_byte_enable;
wire [31:0] cfg_ext_read_data;
wire cfg_ext_read_data_valid;
// wire [3:0] cfg_interrupt_msix_enable;
// wire [3:0] cfg_interrupt_msix_mask;
// wire [251:0] cfg_interrupt_msix_vf_enable;
// wire [251:0] cfg_interrupt_msix_vf_mask;
// wire [63:0] cfg_interrupt_msix_address;
// wire [31:0] cfg_interrupt_msix_data;
// wire cfg_interrupt_msix_int;
// wire [1:0] cfg_interrupt_msix_vec_pending;
// wire cfg_interrupt_msix_vec_pending_status;
// wire cfg_interrupt_msix_sent;
// wire cfg_interrupt_msix_fail;
// wire [7:0] cfg_interrupt_msi_function_number;
wire [3:0] cfg_interrupt_msi_enable;
wire [11:0] cfg_interrupt_msi_mmenable;
wire cfg_interrupt_msi_mask_update;
wire [31:0] cfg_interrupt_msi_data;
wire [1:0] cfg_interrupt_msi_select;
wire [31:0] cfg_interrupt_msi_int;
wire [31:0] cfg_interrupt_msi_pending_status;
wire cfg_interrupt_msi_pending_status_data_enable;
wire [1:0] cfg_interrupt_msi_pending_status_function_num;
wire cfg_interrupt_msi_sent;
wire cfg_interrupt_msi_fail;
wire [2:0] cfg_interrupt_msi_attr;
wire cfg_interrupt_msi_tph_present;
wire [1:0] cfg_interrupt_msi_tph_type;
wire [7:0] cfg_interrupt_msi_tph_st_tag;
wire [7:0] cfg_interrupt_msi_function_number;
wire stat_err_cor;
wire stat_err_uncor;
wire pcie_sys_clk;
wire pcie_sys_clk_gt;
IBUFDS_GTE4 #(
.REFCLK_HROW_CK_SEL(2'b00)
)
ibufds_gte4_pcie_refclk_inst (
.I (pcie_refclk_1_p),
.IB (pcie_refclk_1_n),
.CEB (1'b0),
.O (pcie_sys_clk_gt),
.ODIV2 (pcie_sys_clk)
);
pcie4c_uscale_plus_0
pcie4c_uscale_plus_inst (
.pci_exp_txn(pcie_tx_n),
.pci_exp_txp(pcie_tx_p),
.pci_exp_rxn(pcie_rx_n),
.pci_exp_rxp(pcie_rx_p),
.user_clk(pcie_user_clk),
.user_reset(pcie_user_rst),
.user_lnk_up(),
.s_axis_rq_tdata(axis_pcie_rq.tdata),
.s_axis_rq_tkeep(axis_pcie_rq.tkeep),
.s_axis_rq_tlast(axis_pcie_rq.tlast),
.s_axis_rq_tready(axis_pcie_rq.tready),
.s_axis_rq_tuser(axis_pcie_rq.tuser),
.s_axis_rq_tvalid(axis_pcie_rq.tvalid),
.m_axis_rc_tdata(axis_pcie_rc.tdata),
.m_axis_rc_tkeep(axis_pcie_rc.tkeep),
.m_axis_rc_tlast(axis_pcie_rc.tlast),
.m_axis_rc_tready(axis_pcie_rc.tready),
.m_axis_rc_tuser(axis_pcie_rc.tuser),
.m_axis_rc_tvalid(axis_pcie_rc.tvalid),
.m_axis_cq_tdata(axis_pcie_cq.tdata),
.m_axis_cq_tkeep(axis_pcie_cq.tkeep),
.m_axis_cq_tlast(axis_pcie_cq.tlast),
.m_axis_cq_tready(axis_pcie_cq.tready),
.m_axis_cq_tuser(axis_pcie_cq.tuser),
.m_axis_cq_tvalid(axis_pcie_cq.tvalid),
.s_axis_cc_tdata(axis_pcie_cc.tdata),
.s_axis_cc_tkeep(axis_pcie_cc.tkeep),
.s_axis_cc_tlast(axis_pcie_cc.tlast),
.s_axis_cc_tready(axis_pcie_cc.tready),
.s_axis_cc_tuser(axis_pcie_cc.tuser),
.s_axis_cc_tvalid(axis_pcie_cc.tvalid),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.pcie_rq_tag0(),
.pcie_rq_tag1(),
.pcie_rq_tag_av(),
.pcie_rq_tag_vld0(),
.pcie_rq_tag_vld1(),
.pcie_tfc_nph_av(),
.pcie_tfc_npd_av(),
.pcie_cq_np_req(1'b1),
.pcie_cq_np_req_count(),
.cfg_phy_link_down(),
.cfg_phy_link_status(),
.cfg_negotiated_width(),
.cfg_current_speed(),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_function_status(),
.cfg_function_power_state(),
.cfg_vf_status(),
.cfg_vf_power_state(),
.cfg_link_power_state(),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_mgmt_debug_access(1'b0),
.cfg_err_cor_out(),
.cfg_err_nonfatal_out(),
.cfg_err_fatal_out(),
.cfg_local_error_valid(),
.cfg_local_error_out(),
.cfg_ltssm_state(),
.cfg_rx_pm_state(),
.cfg_tx_pm_state(),
.cfg_rcb_status(cfg_rcb_status),
.cfg_obff_enable(),
.cfg_pl_status_change(),
.cfg_tph_requester_enable(),
.cfg_tph_st_mode(),
.cfg_vf_tph_requester_enable(),
.cfg_vf_tph_st_mode(),
.cfg_msg_received(),
.cfg_msg_received_data(),
.cfg_msg_received_type(),
.cfg_msg_transmit(1'b0),
.cfg_msg_transmit_type(3'd0),
.cfg_msg_transmit_data(32'd0),
.cfg_msg_transmit_done(),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_dsn(64'd0),
.cfg_bus_number(),
.cfg_power_state_change_ack(1'b1),
.cfg_power_state_change_interrupt(),
.cfg_err_cor_in(stat_err_cor),
.cfg_err_uncor_in(stat_err_uncor),
.cfg_flr_in_process(),
.cfg_flr_done(4'd0),
.cfg_vf_flr_in_process(),
.cfg_vf_flr_func_num(8'd0),
.cfg_vf_flr_done(8'd0),
.cfg_link_training_enable(1'b1),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_int(4'd0),
.cfg_interrupt_pending(4'd0),
.cfg_interrupt_sent(),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msi_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msi_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_pm_aspm_l1_entry_reject(1'b0),
.cfg_pm_aspm_tx_l0s_entry_disable(1'b0),
.cfg_hot_reset_out(),
.cfg_config_space_enable(1'b1),
.cfg_req_pm_transition_l23_ready(1'b0),
.cfg_hot_reset_in(1'b0),
.cfg_ds_port_number(8'd0),
.cfg_ds_bus_number(8'd0),
.cfg_ds_device_number(5'd0),
.sys_clk(pcie_sys_clk),
.sys_clk_gt(pcie_sys_clk_gt),
.sys_reset(pcie_reset_n),
.phy_rdy_out()
);
wire uart_rxd_int[1];
wire uart_txd_int[1];
assign uart_txd = uart_txd_int[0];
assign uart_rxd_int[0] = uart_rxd;
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// Board configuration
.SW_CNT(4),
.LED_CNT(2),
.UART_CNT(UART_CNT),
.PORT_CNT(PORT_CNT),
.GTY_QUAD_CNT(GTY_QUAD_CNT),
.GTY_CNT(GTY_CNT),
.GTY_CLK_CNT(GTY_CLK_CNT),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_CLK_PER_NS_NUM(1024),
.PTP_CLK_PER_NS_DENOM(165),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
)
core_inst (
/*
* Clock: 125MHz
* Synchronous reset
*/
.clk_125mhz(clk_125mhz_int),
.rst_125mhz(rst_125mhz_int),
/*
* GPIO
*/
.sw('0),
.led({card_heart_bit, card_status_led}),
.port_led_act(qsfp_led_act),
.port_led_stat_r(),
.port_led_stat_g(qsfp_led_stat_g),
.port_led_stat_b(),
.port_led_stat_y(qsfp_led_stat_y),
/*
* UART
*/
.uart_txd(uart_txd_int),
.uart_rxd(uart_rxd_int),
/*
* Ethernet
*/
.eth_gty_tx_p(eth_gty_tx_p),
.eth_gty_tx_n(eth_gty_tx_n),
.eth_gty_rx_p(eth_gty_rx_p),
.eth_gty_rx_n(eth_gty_rx_n),
.eth_gty_mgt_refclk_p(eth_gty_mgt_refclk_p),
.eth_gty_mgt_refclk_n(eth_gty_mgt_refclk_n),
.eth_gty_mgt_refclk_out(eth_gty_mgt_refclk_out),
.eth_port_modsell(),
.eth_port_resetl(),
.eth_port_modprsl('0),
.eth_port_intl('0),
.eth_port_lpmode(),
/*
* PCIe
*/
.pcie_clk(pcie_user_clk),
.pcie_rst(pcie_user_rst),
.s_axis_pcie_cq(axis_pcie_cq),
.m_axis_pcie_cc(axis_pcie_cc),
.m_axis_pcie_rq(axis_pcie_rq),
.s_axis_pcie_rc(axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msix_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msix_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk_int),
.qspi_dq_i(qspi_dq_i_int),
.qspi_dq_o(qspi_dq_o_int),
.qspi_dq_oe(qspi_dq_oe_int),
.qspi_cs(qspi_cs_int)
);
endmodule
`resetall

View File

@@ -0,0 +1,884 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2014-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga #
(
// simulation (set to avoid vendor primitives)
parameter logic SIM = 1'b0,
// vendor ("GENERIC", "XILINX", "ALTERA")
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// Board configuration
parameter QSFP_CNT = 1,
parameter UART_CNT = 3,
// FW ID
parameter FPGA_ID = 32'h4B77093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h10ee_9032,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
)
(
/*
* GPIO
*/
output wire logic [QSFP_CNT-1:0] qsfp_led_act,
output wire logic [QSFP_CNT-1:0] qsfp_led_stat_g,
output wire logic [QSFP_CNT-1:0] qsfp_led_stat_y,
output wire logic hbm_cattrip,
/*
* UART
*/
output wire logic uart_txd[UART_CNT],
input wire logic uart_rxd[UART_CNT],
/*
* Ethernet: QSFP28
*/
output wire logic qsfp_tx_p[4],
output wire logic qsfp_tx_n[4],
input wire logic qsfp_rx_p[4],
input wire logic qsfp_rx_n[4],
input wire logic qsfp_mgt_refclk_0_p,
input wire logic qsfp_mgt_refclk_0_n,
// input wire logic qsfp_mgt_refclk_1_p,
// input wire logic qsfp_mgt_refclk_1_n,
/*
* PCIe
*/
input wire logic [15:0] pcie_rx_p,
input wire logic [15:0] pcie_rx_n,
output wire logic [15:0] pcie_tx_p,
output wire logic [15:0] pcie_tx_n,
input wire logic pcie_refclk_1_p,
input wire logic pcie_refclk_1_n,
input wire logic pcie_reset_n
);
// Clock and reset
wire pcie_user_clk;
wire pcie_user_rst;
wire clk_161mhz_ref_int;
// Internal 125 MHz clock
wire clk_125mhz_mmcm_out;
wire clk_125mhz_int;
wire rst_125mhz_int;
wire mmcm_rst = 1'b0;
wire mmcm_locked;
wire mmcm_clkfb;
// MMCM instance
MMCME4_BASE #(
// 161.13 MHz input
.CLKIN1_PERIOD(6.206),
.REF_JITTER1(0.010),
// 161.13 MHz input / 11 = 14.65 MHz PFD (range 10 MHz to 500 MHz)
.DIVCLK_DIVIDE(11),
// 14.65 MHz PFD * 64 = 937.5 MHz VCO (range 800 MHz to 1600 MHz)
.CLKFBOUT_MULT_F(64),
.CLKFBOUT_PHASE(0),
// 937.5 MHz / 7.5 = 125 MHz, 0 degrees
.CLKOUT0_DIVIDE_F(7.5),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0),
// Not used
.CLKOUT1_DIVIDE(1),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT1_PHASE(0),
// Not used
.CLKOUT2_DIVIDE(1),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT2_PHASE(0),
// Not used
.CLKOUT3_DIVIDE(1),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT3_PHASE(0),
// Not used
.CLKOUT4_DIVIDE(1),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT4_PHASE(0),
.CLKOUT4_CASCADE("FALSE"),
// Not used
.CLKOUT5_DIVIDE(1),
.CLKOUT5_DUTY_CYCLE(0.5),
.CLKOUT5_PHASE(0),
// Not used
.CLKOUT6_DIVIDE(1),
.CLKOUT6_DUTY_CYCLE(0.5),
.CLKOUT6_PHASE(0),
// optimized bandwidth
.BANDWIDTH("OPTIMIZED"),
// don't wait for lock during startup
.STARTUP_WAIT("FALSE")
)
clk_mmcm_inst (
// 161.13 MHz input
.CLKIN1(clk_161mhz_ref_int),
// direct clkfb feeback
.CLKFBIN(mmcm_clkfb),
.CLKFBOUT(mmcm_clkfb),
.CLKFBOUTB(),
// 125 MHz, 0 degrees
.CLKOUT0(clk_125mhz_mmcm_out),
.CLKOUT0B(),
// Not used
.CLKOUT1(),
.CLKOUT1B(),
// Not used
.CLKOUT2(),
.CLKOUT2B(),
// Not used
.CLKOUT3(),
.CLKOUT3B(),
// Not used
.CLKOUT4(),
// Not used
.CLKOUT5(),
// Not used
.CLKOUT6(),
// reset input
.RST(mmcm_rst),
// don't power down
.PWRDWN(1'b0),
// locked output
.LOCKED(mmcm_locked)
);
BUFG
clk_125mhz_bufg_inst (
.I(clk_125mhz_mmcm_out),
.O(clk_125mhz_int)
);
taxi_sync_reset #(
.N(4)
)
sync_reset_125mhz_inst (
.clk(clk_125mhz_int),
.rst(~mmcm_locked),
.out(rst_125mhz_int)
);
// GPIO
assign hbm_cattrip = 1'b0;
localparam PORT_CNT = QSFP_CNT;
localparam GTY_QUAD_CNT = PORT_CNT;
localparam GTY_CNT = GTY_QUAD_CNT*4;
localparam GTY_CLK_CNT = GTY_QUAD_CNT;
wire eth_gty_tx_p[GTY_CNT];
wire eth_gty_tx_n[GTY_CNT];
wire eth_gty_rx_p[GTY_CNT];
wire eth_gty_rx_n[GTY_CNT];
wire eth_gty_mgt_refclk_p[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_n[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_out[GTY_CLK_CNT];
assign qsfp_tx_p = eth_gty_tx_p[4*0 +: 4];
assign qsfp_tx_n = eth_gty_tx_n[4*0 +: 4];
assign eth_gty_rx_p[4*0 +: 4] = qsfp_rx_p;
assign eth_gty_rx_n[4*0 +: 4] = qsfp_rx_n;
assign eth_gty_mgt_refclk_p[0] = qsfp_mgt_refclk_0_p;
assign eth_gty_mgt_refclk_n[0] = qsfp_mgt_refclk_0_n;
assign clk_161mhz_ref_int = eth_gty_mgt_refclk_out[0];
// Flash
wire qspi_clk_int;
wire [3:0] qspi_dq_int;
wire [3:0] qspi_dq_i_int;
wire [3:0] qspi_dq_o_int;
wire [3:0] qspi_dq_oe_int;
wire qspi_cs_int;
reg qspi_clk_reg;
reg [3:0] qspi_dq_o_reg;
reg [3:0] qspi_dq_oe_reg;
reg qspi_cs_reg;
always_ff @(posedge pcie_user_clk) begin
qspi_clk_reg <= qspi_clk_int;
qspi_dq_o_reg <= qspi_dq_o_int;
qspi_dq_oe_reg <= qspi_dq_oe_int;
qspi_cs_reg <= qspi_cs_int;
end
taxi_sync_signal #(
.WIDTH(8),
.N(2)
)
flash_sync_inst (
.clk(pcie_user_clk),
.in({qspi_dq_int}),
.out({qspi_dq_i_int})
);
STARTUPE3
startupe3_inst (
.CFGCLK(),
.CFGMCLK(),
.DI(qspi_dq_int),
.DO(qspi_dq_o_reg),
.DTS(~qspi_dq_oe_reg),
.EOS(),
.FCSBO(qspi_cs_reg),
.FCSBTS(1'b0),
.GSR(1'b0),
.GTS(1'b0),
.KEYCLEARB(1'b1),
.PACK(1'b0),
.PREQ(),
.USRCCLKO(qspi_clk_reg),
.USRCCLKTS(1'b0),
.USRDONEO(1'b0),
.USRDONETS(1'b1)
);
// FPGA boot
wire fpga_boot;
wire fpga_boot_sync;
taxi_sync_signal #(
.WIDTH(1),
.N(2)
)
fpga_boot_sync_inst (
.clk(clk_125mhz_int),
.in({fpga_boot}),
.out({fpga_boot_sync})
);
wire icap_avail;
logic [2:0] icap_state_reg = 0;
logic icap_csib_reg = 1'b1;
logic icap_rdwrb_reg = 1'b0;
logic [31:0] icap_di_reg = 32'hffffffff;
wire [31:0] icap_di_rev;
assign icap_di_rev[ 7] = icap_di_reg[ 0];
assign icap_di_rev[ 6] = icap_di_reg[ 1];
assign icap_di_rev[ 5] = icap_di_reg[ 2];
assign icap_di_rev[ 4] = icap_di_reg[ 3];
assign icap_di_rev[ 3] = icap_di_reg[ 4];
assign icap_di_rev[ 2] = icap_di_reg[ 5];
assign icap_di_rev[ 1] = icap_di_reg[ 6];
assign icap_di_rev[ 0] = icap_di_reg[ 7];
assign icap_di_rev[15] = icap_di_reg[ 8];
assign icap_di_rev[14] = icap_di_reg[ 9];
assign icap_di_rev[13] = icap_di_reg[10];
assign icap_di_rev[12] = icap_di_reg[11];
assign icap_di_rev[11] = icap_di_reg[12];
assign icap_di_rev[10] = icap_di_reg[13];
assign icap_di_rev[ 9] = icap_di_reg[14];
assign icap_di_rev[ 8] = icap_di_reg[15];
assign icap_di_rev[23] = icap_di_reg[16];
assign icap_di_rev[22] = icap_di_reg[17];
assign icap_di_rev[21] = icap_di_reg[18];
assign icap_di_rev[20] = icap_di_reg[19];
assign icap_di_rev[19] = icap_di_reg[20];
assign icap_di_rev[18] = icap_di_reg[21];
assign icap_di_rev[17] = icap_di_reg[22];
assign icap_di_rev[16] = icap_di_reg[23];
assign icap_di_rev[31] = icap_di_reg[24];
assign icap_di_rev[30] = icap_di_reg[25];
assign icap_di_rev[29] = icap_di_reg[26];
assign icap_di_rev[28] = icap_di_reg[27];
assign icap_di_rev[27] = icap_di_reg[28];
assign icap_di_rev[26] = icap_di_reg[29];
assign icap_di_rev[25] = icap_di_reg[30];
assign icap_di_rev[24] = icap_di_reg[31];
always_ff @(posedge clk_125mhz_int) begin
case (icap_state_reg)
0: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b1;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
if (fpga_boot_sync && icap_avail) begin
icap_state_reg <= 1;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
end
end
1: begin
icap_state_reg <= 2;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hAA995566; // sync word
end
2: begin
icap_state_reg <= 3;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
3: begin
icap_state_reg <= 4;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h30008001; // write 1 word to CMD
end
4: begin
icap_state_reg <= 5;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h0000000F; // IPROG
end
5: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
endcase
end
ICAPE3
icape3_inst (
.AVAIL(icap_avail),
.CLK(clk_125mhz_int),
.CSIB(icap_csib_reg),
.I(icap_di_rev),
.O(),
.PRDONE(),
.PRERROR(),
.RDWRB(icap_rdwrb_reg)
);
// PCIe
localparam AXIS_PCIE_DATA_W = 512;
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
localparam AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161;
localparam AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137;
localparam AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183;
localparam AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81;
localparam RC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 256;
localparam RQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
localparam RQ_SEQ_NUM_EN = 1;
localparam PCIE_TAG_CNT = AXIS_PCIE_RQ_USER_W == 60 ? 64 : 256;
localparam BAR0_APERTURE = 24;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CQ_USER_W)
) axis_pcie_cq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CC_USER_W)
) axis_pcie_cc();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RQ_USER_W)
) axis_pcie_rq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RC_USER_W)
) axis_pcie_rc();
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0;
wire pcie_rq_seq_num_vld0;
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1;
wire pcie_rq_seq_num_vld1;
wire [2:0] cfg_max_payload;
wire [2:0] cfg_max_read_req;
wire [3:0] cfg_rcb_status;
wire [9:0] cfg_mgmt_addr;
wire [7:0] cfg_mgmt_function_number;
wire cfg_mgmt_write;
wire [31:0] cfg_mgmt_write_data;
wire [3:0] cfg_mgmt_byte_enable;
wire cfg_mgmt_read;
wire [31:0] cfg_mgmt_read_data;
wire cfg_mgmt_read_write_done;
wire [7:0] cfg_fc_ph;
wire [11:0] cfg_fc_pd;
wire [7:0] cfg_fc_nph;
wire [11:0] cfg_fc_npd;
wire [7:0] cfg_fc_cplh;
wire [11:0] cfg_fc_cpld;
wire [2:0] cfg_fc_sel;
wire cfg_ext_read_received;
wire cfg_ext_write_received;
wire [9:0] cfg_ext_register_number;
wire [7:0] cfg_ext_function_number;
wire [31:0] cfg_ext_write_data;
wire [3:0] cfg_ext_write_byte_enable;
wire [31:0] cfg_ext_read_data;
wire cfg_ext_read_data_valid;
// wire [3:0] cfg_interrupt_msix_enable;
// wire [3:0] cfg_interrupt_msix_mask;
// wire [251:0] cfg_interrupt_msix_vf_enable;
// wire [251:0] cfg_interrupt_msix_vf_mask;
// wire [63:0] cfg_interrupt_msix_address;
// wire [31:0] cfg_interrupt_msix_data;
// wire cfg_interrupt_msix_int;
// wire [1:0] cfg_interrupt_msix_vec_pending;
// wire cfg_interrupt_msix_vec_pending_status;
// wire cfg_interrupt_msix_sent;
// wire cfg_interrupt_msix_fail;
// wire [7:0] cfg_interrupt_msi_function_number;
wire [3:0] cfg_interrupt_msi_enable;
wire [11:0] cfg_interrupt_msi_mmenable;
wire cfg_interrupt_msi_mask_update;
wire [31:0] cfg_interrupt_msi_data;
wire [1:0] cfg_interrupt_msi_select;
wire [31:0] cfg_interrupt_msi_int;
wire [31:0] cfg_interrupt_msi_pending_status;
wire cfg_interrupt_msi_pending_status_data_enable;
wire [1:0] cfg_interrupt_msi_pending_status_function_num;
wire cfg_interrupt_msi_sent;
wire cfg_interrupt_msi_fail;
wire [2:0] cfg_interrupt_msi_attr;
wire cfg_interrupt_msi_tph_present;
wire [1:0] cfg_interrupt_msi_tph_type;
wire [7:0] cfg_interrupt_msi_tph_st_tag;
wire [7:0] cfg_interrupt_msi_function_number;
wire stat_err_cor;
wire stat_err_uncor;
wire pcie_sys_clk;
wire pcie_sys_clk_gt;
IBUFDS_GTE4 #(
.REFCLK_HROW_CK_SEL(2'b00)
)
ibufds_gte4_pcie_refclk_inst (
.I (pcie_refclk_1_p),
.IB (pcie_refclk_1_n),
.CEB (1'b0),
.O (pcie_sys_clk_gt),
.ODIV2 (pcie_sys_clk)
);
pcie4c_uscale_plus_0
pcie4c_uscale_plus_inst (
.pci_exp_txn(pcie_tx_n),
.pci_exp_txp(pcie_tx_p),
.pci_exp_rxn(pcie_rx_n),
.pci_exp_rxp(pcie_rx_p),
.user_clk(pcie_user_clk),
.user_reset(pcie_user_rst),
.user_lnk_up(),
.s_axis_rq_tdata(axis_pcie_rq.tdata),
.s_axis_rq_tkeep(axis_pcie_rq.tkeep),
.s_axis_rq_tlast(axis_pcie_rq.tlast),
.s_axis_rq_tready(axis_pcie_rq.tready),
.s_axis_rq_tuser(axis_pcie_rq.tuser),
.s_axis_rq_tvalid(axis_pcie_rq.tvalid),
.m_axis_rc_tdata(axis_pcie_rc.tdata),
.m_axis_rc_tkeep(axis_pcie_rc.tkeep),
.m_axis_rc_tlast(axis_pcie_rc.tlast),
.m_axis_rc_tready(axis_pcie_rc.tready),
.m_axis_rc_tuser(axis_pcie_rc.tuser),
.m_axis_rc_tvalid(axis_pcie_rc.tvalid),
.m_axis_cq_tdata(axis_pcie_cq.tdata),
.m_axis_cq_tkeep(axis_pcie_cq.tkeep),
.m_axis_cq_tlast(axis_pcie_cq.tlast),
.m_axis_cq_tready(axis_pcie_cq.tready),
.m_axis_cq_tuser(axis_pcie_cq.tuser),
.m_axis_cq_tvalid(axis_pcie_cq.tvalid),
.s_axis_cc_tdata(axis_pcie_cc.tdata),
.s_axis_cc_tkeep(axis_pcie_cc.tkeep),
.s_axis_cc_tlast(axis_pcie_cc.tlast),
.s_axis_cc_tready(axis_pcie_cc.tready),
.s_axis_cc_tuser(axis_pcie_cc.tuser),
.s_axis_cc_tvalid(axis_pcie_cc.tvalid),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.pcie_rq_tag0(),
.pcie_rq_tag1(),
.pcie_rq_tag_av(),
.pcie_rq_tag_vld0(),
.pcie_rq_tag_vld1(),
.pcie_tfc_nph_av(),
.pcie_tfc_npd_av(),
.pcie_cq_np_req(1'b1),
.pcie_cq_np_req_count(),
.cfg_phy_link_down(),
.cfg_phy_link_status(),
.cfg_negotiated_width(),
.cfg_current_speed(),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_function_status(),
.cfg_function_power_state(),
.cfg_vf_status(),
.cfg_vf_power_state(),
.cfg_link_power_state(),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_mgmt_debug_access(1'b0),
.cfg_err_cor_out(),
.cfg_err_nonfatal_out(),
.cfg_err_fatal_out(),
.cfg_local_error_valid(),
.cfg_local_error_out(),
.cfg_ltssm_state(),
.cfg_rx_pm_state(),
.cfg_tx_pm_state(),
.cfg_rcb_status(cfg_rcb_status),
.cfg_obff_enable(),
.cfg_pl_status_change(),
.cfg_tph_requester_enable(),
.cfg_tph_st_mode(),
.cfg_vf_tph_requester_enable(),
.cfg_vf_tph_st_mode(),
.cfg_msg_received(),
.cfg_msg_received_data(),
.cfg_msg_received_type(),
.cfg_msg_transmit(1'b0),
.cfg_msg_transmit_type(3'd0),
.cfg_msg_transmit_data(32'd0),
.cfg_msg_transmit_done(),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_dsn(64'd0),
.cfg_bus_number(),
.cfg_power_state_change_ack(1'b1),
.cfg_power_state_change_interrupt(),
.cfg_err_cor_in(stat_err_cor),
.cfg_err_uncor_in(stat_err_uncor),
.cfg_flr_in_process(),
.cfg_flr_done(4'd0),
.cfg_vf_flr_in_process(),
.cfg_vf_flr_func_num(8'd0),
.cfg_vf_flr_done(8'd0),
.cfg_link_training_enable(1'b1),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_int(4'd0),
.cfg_interrupt_pending(4'd0),
.cfg_interrupt_sent(),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msi_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msi_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_pm_aspm_l1_entry_reject(1'b0),
.cfg_pm_aspm_tx_l0s_entry_disable(1'b0),
.cfg_hot_reset_out(),
.cfg_config_space_enable(1'b1),
.cfg_req_pm_transition_l23_ready(1'b0),
.cfg_hot_reset_in(1'b0),
.cfg_ds_port_number(8'd0),
.cfg_ds_bus_number(8'd0),
.cfg_ds_device_number(5'd0),
.sys_clk(pcie_sys_clk),
.sys_clk_gt(pcie_sys_clk_gt),
.sys_reset(pcie_reset_n),
.phy_rdy_out()
);
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// Board configuration
.SW_CNT(4),
.LED_CNT(3),
.UART_CNT(UART_CNT),
.PORT_CNT(PORT_CNT),
.GTY_QUAD_CNT(GTY_QUAD_CNT),
.GTY_CNT(GTY_CNT),
.GTY_CLK_CNT(GTY_CLK_CNT),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_CLK_PER_NS_NUM(1024),
.PTP_CLK_PER_NS_DENOM(165),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
)
core_inst (
/*
* Clock: 125MHz
* Synchronous reset
*/
.clk_125mhz(clk_125mhz_int),
.rst_125mhz(rst_125mhz_int),
/*
* GPIO
*/
.sw('0),
.led(),
.port_led_act(qsfp_led_act),
.port_led_stat_r(),
.port_led_stat_g(qsfp_led_stat_g),
.port_led_stat_b(),
.port_led_stat_y(qsfp_led_stat_y),
/*
* UART
*/
.uart_txd(uart_txd),
.uart_rxd(uart_rxd),
/*
* Ethernet
*/
.eth_gty_tx_p(eth_gty_tx_p),
.eth_gty_tx_n(eth_gty_tx_n),
.eth_gty_rx_p(eth_gty_rx_p),
.eth_gty_rx_n(eth_gty_rx_n),
.eth_gty_mgt_refclk_p(eth_gty_mgt_refclk_p),
.eth_gty_mgt_refclk_n(eth_gty_mgt_refclk_n),
.eth_gty_mgt_refclk_out(eth_gty_mgt_refclk_out),
.eth_port_modsell(),
.eth_port_resetl(),
.eth_port_modprsl('0),
.eth_port_intl('0),
.eth_port_lpmode(),
/*
* PCIe
*/
.pcie_clk(pcie_user_clk),
.pcie_rst(pcie_user_rst),
.s_axis_pcie_cq(axis_pcie_cq),
.m_axis_pcie_cc(axis_pcie_cc),
.m_axis_pcie_rq(axis_pcie_rq),
.s_axis_pcie_rc(axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msix_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msix_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk_int),
.qspi_dq_i(qspi_dq_i_int),
.qspi_dq_o(qspi_dq_o_int),
.qspi_dq_oe(qspi_dq_oe_int),
.qspi_cs(qspi_cs_int)
);
endmodule
`resetall

View File

@@ -0,0 +1,901 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2014-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga #
(
// simulation (set to avoid vendor primitives)
parameter logic SIM = 1'b0,
// vendor ("GENERIC", "XILINX", "ALTERA")
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// Board configuration
parameter QSFP_CNT = 2,
parameter UART_CNT = 3,
// FW ID
parameter FPGA_ID = 32'h4B7D093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h10ee_9037,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
)
(
/*
* Reset: Push button, active low
*/
input wire logic reset,
/*
* GPIO
*/
output wire logic [QSFP_CNT-1:0] qsfp_led_act,
output wire logic [QSFP_CNT-1:0] qsfp_led_stat_g,
output wire logic [QSFP_CNT-1:0] qsfp_led_stat_y,
output wire logic hbm_cattrip,
/*
* UART
*/
output wire logic uart_txd[UART_CNT],
input wire logic uart_rxd[UART_CNT],
/*
* Ethernet: QSFP28
*/
output wire logic qsfp0_tx_p[4],
output wire logic qsfp0_tx_n[4],
input wire logic qsfp0_rx_p[4],
input wire logic qsfp0_rx_n[4],
input wire logic qsfp0_mgt_refclk_p,
input wire logic qsfp0_mgt_refclk_n,
output wire logic qsfp1_tx_p[4],
output wire logic qsfp1_tx_n[4],
input wire logic qsfp1_rx_p[4],
input wire logic qsfp1_rx_n[4],
input wire logic qsfp1_mgt_refclk_p,
input wire logic qsfp1_mgt_refclk_n,
/*
* PCIe
*/
input wire logic [15:0] pcie_rx_p,
input wire logic [15:0] pcie_rx_n,
output wire logic [15:0] pcie_tx_p,
output wire logic [15:0] pcie_tx_n,
input wire logic pcie_refclk_1_p,
input wire logic pcie_refclk_1_n,
input wire logic pcie_reset_n
);
// Clock and reset
wire pcie_user_clk;
wire pcie_user_rst;
wire clk_161mhz_ref_int;
// Internal 125 MHz clock
wire clk_125mhz_mmcm_out;
wire clk_125mhz_int;
wire rst_125mhz_int;
wire mmcm_rst = 1'b0;
wire mmcm_locked;
wire mmcm_clkfb;
// MMCM instance
MMCME4_BASE #(
// 161.13 MHz input
.CLKIN1_PERIOD(6.206),
.REF_JITTER1(0.010),
// 161.13 MHz input / 11 = 14.65 MHz PFD (range 10 MHz to 500 MHz)
.DIVCLK_DIVIDE(11),
// 14.65 MHz PFD * 64 = 937.5 MHz VCO (range 800 MHz to 1600 MHz)
.CLKFBOUT_MULT_F(64),
.CLKFBOUT_PHASE(0),
// 937.5 MHz / 7.5 = 125 MHz, 0 degrees
.CLKOUT0_DIVIDE_F(7.5),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0),
// Not used
.CLKOUT1_DIVIDE(1),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT1_PHASE(0),
// Not used
.CLKOUT2_DIVIDE(1),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT2_PHASE(0),
// Not used
.CLKOUT3_DIVIDE(1),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT3_PHASE(0),
// Not used
.CLKOUT4_DIVIDE(1),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT4_PHASE(0),
.CLKOUT4_CASCADE("FALSE"),
// Not used
.CLKOUT5_DIVIDE(1),
.CLKOUT5_DUTY_CYCLE(0.5),
.CLKOUT5_PHASE(0),
// Not used
.CLKOUT6_DIVIDE(1),
.CLKOUT6_DUTY_CYCLE(0.5),
.CLKOUT6_PHASE(0),
// optimized bandwidth
.BANDWIDTH("OPTIMIZED"),
// don't wait for lock during startup
.STARTUP_WAIT("FALSE")
)
clk_mmcm_inst (
// 161.13 MHz input
.CLKIN1(clk_161mhz_ref_int),
// direct clkfb feeback
.CLKFBIN(mmcm_clkfb),
.CLKFBOUT(mmcm_clkfb),
.CLKFBOUTB(),
// 125 MHz, 0 degrees
.CLKOUT0(clk_125mhz_mmcm_out),
.CLKOUT0B(),
// Not used
.CLKOUT1(),
.CLKOUT1B(),
// Not used
.CLKOUT2(),
.CLKOUT2B(),
// Not used
.CLKOUT3(),
.CLKOUT3B(),
// Not used
.CLKOUT4(),
// Not used
.CLKOUT5(),
// Not used
.CLKOUT6(),
// reset input
.RST(mmcm_rst),
// don't power down
.PWRDWN(1'b0),
// locked output
.LOCKED(mmcm_locked)
);
BUFG
clk_125mhz_bufg_inst (
.I(clk_125mhz_mmcm_out),
.O(clk_125mhz_int)
);
taxi_sync_reset #(
.N(4)
)
sync_reset_125mhz_inst (
.clk(clk_125mhz_int),
.rst(~mmcm_locked),
.out(rst_125mhz_int)
);
// GPIO
assign hbm_cattrip = 1'b0;
localparam PORT_CNT = QSFP_CNT;
localparam GTY_QUAD_CNT = PORT_CNT;
localparam GTY_CNT = GTY_QUAD_CNT*4;
localparam GTY_CLK_CNT = GTY_QUAD_CNT;
wire eth_gty_tx_p[GTY_CNT];
wire eth_gty_tx_n[GTY_CNT];
wire eth_gty_rx_p[GTY_CNT];
wire eth_gty_rx_n[GTY_CNT];
wire eth_gty_mgt_refclk_p[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_n[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_out[GTY_CLK_CNT];
assign qsfp0_tx_p = eth_gty_tx_p[4*0 +: 4];
assign qsfp0_tx_n = eth_gty_tx_n[4*0 +: 4];
assign eth_gty_rx_p[4*0 +: 4] = qsfp0_rx_p;
assign eth_gty_rx_n[4*0 +: 4] = qsfp0_rx_n;
assign qsfp1_tx_p = eth_gty_tx_p[4*1 +: 4];
assign qsfp1_tx_n = eth_gty_tx_n[4*1 +: 4];
assign eth_gty_rx_p[4*1 +: 4] = qsfp1_rx_p;
assign eth_gty_rx_n[4*1 +: 4] = qsfp1_rx_n;
assign eth_gty_mgt_refclk_p[0] = qsfp0_mgt_refclk_p;
assign eth_gty_mgt_refclk_n[0] = qsfp0_mgt_refclk_n;
assign eth_gty_mgt_refclk_p[1] = qsfp1_mgt_refclk_p;
assign eth_gty_mgt_refclk_n[1] = qsfp1_mgt_refclk_n;
assign clk_161mhz_ref_int = eth_gty_mgt_refclk_out[0];
// Flash
wire qspi_clk_int;
wire [3:0] qspi_dq_int;
wire [3:0] qspi_dq_i_int;
wire [3:0] qspi_dq_o_int;
wire [3:0] qspi_dq_oe_int;
wire qspi_cs_int;
reg qspi_clk_reg;
reg [3:0] qspi_dq_o_reg;
reg [3:0] qspi_dq_oe_reg;
reg qspi_cs_reg;
always_ff @(posedge pcie_user_clk) begin
qspi_clk_reg <= qspi_clk_int;
qspi_dq_o_reg <= qspi_dq_o_int;
qspi_dq_oe_reg <= qspi_dq_oe_int;
qspi_cs_reg <= qspi_cs_int;
end
taxi_sync_signal #(
.WIDTH(8),
.N(2)
)
flash_sync_inst (
.clk(pcie_user_clk),
.in({qspi_dq_int}),
.out({qspi_dq_i_int})
);
STARTUPE3
startupe3_inst (
.CFGCLK(),
.CFGMCLK(),
.DI(qspi_dq_int),
.DO(qspi_dq_o_reg),
.DTS(~qspi_dq_oe_reg),
.EOS(),
.FCSBO(qspi_cs_reg),
.FCSBTS(1'b0),
.GSR(1'b0),
.GTS(1'b0),
.KEYCLEARB(1'b1),
.PACK(1'b0),
.PREQ(),
.USRCCLKO(qspi_clk_reg),
.USRCCLKTS(1'b0),
.USRDONEO(1'b0),
.USRDONETS(1'b1)
);
// FPGA boot
wire fpga_boot;
wire fpga_boot_sync;
taxi_sync_signal #(
.WIDTH(1),
.N(2)
)
fpga_boot_sync_inst (
.clk(clk_125mhz_int),
.in({fpga_boot}),
.out({fpga_boot_sync})
);
wire icap_avail;
logic [2:0] icap_state_reg = 0;
logic icap_csib_reg = 1'b1;
logic icap_rdwrb_reg = 1'b0;
logic [31:0] icap_di_reg = 32'hffffffff;
wire [31:0] icap_di_rev;
assign icap_di_rev[ 7] = icap_di_reg[ 0];
assign icap_di_rev[ 6] = icap_di_reg[ 1];
assign icap_di_rev[ 5] = icap_di_reg[ 2];
assign icap_di_rev[ 4] = icap_di_reg[ 3];
assign icap_di_rev[ 3] = icap_di_reg[ 4];
assign icap_di_rev[ 2] = icap_di_reg[ 5];
assign icap_di_rev[ 1] = icap_di_reg[ 6];
assign icap_di_rev[ 0] = icap_di_reg[ 7];
assign icap_di_rev[15] = icap_di_reg[ 8];
assign icap_di_rev[14] = icap_di_reg[ 9];
assign icap_di_rev[13] = icap_di_reg[10];
assign icap_di_rev[12] = icap_di_reg[11];
assign icap_di_rev[11] = icap_di_reg[12];
assign icap_di_rev[10] = icap_di_reg[13];
assign icap_di_rev[ 9] = icap_di_reg[14];
assign icap_di_rev[ 8] = icap_di_reg[15];
assign icap_di_rev[23] = icap_di_reg[16];
assign icap_di_rev[22] = icap_di_reg[17];
assign icap_di_rev[21] = icap_di_reg[18];
assign icap_di_rev[20] = icap_di_reg[19];
assign icap_di_rev[19] = icap_di_reg[20];
assign icap_di_rev[18] = icap_di_reg[21];
assign icap_di_rev[17] = icap_di_reg[22];
assign icap_di_rev[16] = icap_di_reg[23];
assign icap_di_rev[31] = icap_di_reg[24];
assign icap_di_rev[30] = icap_di_reg[25];
assign icap_di_rev[29] = icap_di_reg[26];
assign icap_di_rev[28] = icap_di_reg[27];
assign icap_di_rev[27] = icap_di_reg[28];
assign icap_di_rev[26] = icap_di_reg[29];
assign icap_di_rev[25] = icap_di_reg[30];
assign icap_di_rev[24] = icap_di_reg[31];
always_ff @(posedge clk_125mhz_int) begin
case (icap_state_reg)
0: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b1;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
if (fpga_boot_sync && icap_avail) begin
icap_state_reg <= 1;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
end
end
1: begin
icap_state_reg <= 2;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hAA995566; // sync word
end
2: begin
icap_state_reg <= 3;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
3: begin
icap_state_reg <= 4;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h30008001; // write 1 word to CMD
end
4: begin
icap_state_reg <= 5;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h0000000F; // IPROG
end
5: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
endcase
end
ICAPE3
icape3_inst (
.AVAIL(icap_avail),
.CLK(clk_125mhz_int),
.CSIB(icap_csib_reg),
.I(icap_di_rev),
.O(),
.PRDONE(),
.PRERROR(),
.RDWRB(icap_rdwrb_reg)
);
// PCIe
localparam AXIS_PCIE_DATA_W = 512;
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
localparam AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161;
localparam AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137;
localparam AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183;
localparam AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81;
localparam RC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 256;
localparam RQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
localparam RQ_SEQ_NUM_EN = 1;
localparam PCIE_TAG_CNT = AXIS_PCIE_RQ_USER_W == 60 ? 64 : 256;
localparam BAR0_APERTURE = 24;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CQ_USER_W)
) axis_pcie_cq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CC_USER_W)
) axis_pcie_cc();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RQ_USER_W)
) axis_pcie_rq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RC_USER_W)
) axis_pcie_rc();
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0;
wire pcie_rq_seq_num_vld0;
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1;
wire pcie_rq_seq_num_vld1;
wire [2:0] cfg_max_payload;
wire [2:0] cfg_max_read_req;
wire [3:0] cfg_rcb_status;
wire [9:0] cfg_mgmt_addr;
wire [7:0] cfg_mgmt_function_number;
wire cfg_mgmt_write;
wire [31:0] cfg_mgmt_write_data;
wire [3:0] cfg_mgmt_byte_enable;
wire cfg_mgmt_read;
wire [31:0] cfg_mgmt_read_data;
wire cfg_mgmt_read_write_done;
wire [7:0] cfg_fc_ph;
wire [11:0] cfg_fc_pd;
wire [7:0] cfg_fc_nph;
wire [11:0] cfg_fc_npd;
wire [7:0] cfg_fc_cplh;
wire [11:0] cfg_fc_cpld;
wire [2:0] cfg_fc_sel;
wire cfg_ext_read_received;
wire cfg_ext_write_received;
wire [9:0] cfg_ext_register_number;
wire [7:0] cfg_ext_function_number;
wire [31:0] cfg_ext_write_data;
wire [3:0] cfg_ext_write_byte_enable;
wire [31:0] cfg_ext_read_data;
wire cfg_ext_read_data_valid;
// wire [3:0] cfg_interrupt_msix_enable;
// wire [3:0] cfg_interrupt_msix_mask;
// wire [251:0] cfg_interrupt_msix_vf_enable;
// wire [251:0] cfg_interrupt_msix_vf_mask;
// wire [63:0] cfg_interrupt_msix_address;
// wire [31:0] cfg_interrupt_msix_data;
// wire cfg_interrupt_msix_int;
// wire [1:0] cfg_interrupt_msix_vec_pending;
// wire cfg_interrupt_msix_vec_pending_status;
// wire cfg_interrupt_msix_sent;
// wire cfg_interrupt_msix_fail;
// wire [7:0] cfg_interrupt_msi_function_number;
wire [3:0] cfg_interrupt_msi_enable;
wire [11:0] cfg_interrupt_msi_mmenable;
wire cfg_interrupt_msi_mask_update;
wire [31:0] cfg_interrupt_msi_data;
wire [1:0] cfg_interrupt_msi_select;
wire [31:0] cfg_interrupt_msi_int;
wire [31:0] cfg_interrupt_msi_pending_status;
wire cfg_interrupt_msi_pending_status_data_enable;
wire [1:0] cfg_interrupt_msi_pending_status_function_num;
wire cfg_interrupt_msi_sent;
wire cfg_interrupt_msi_fail;
wire [2:0] cfg_interrupt_msi_attr;
wire cfg_interrupt_msi_tph_present;
wire [1:0] cfg_interrupt_msi_tph_type;
wire [7:0] cfg_interrupt_msi_tph_st_tag;
wire [7:0] cfg_interrupt_msi_function_number;
wire stat_err_cor;
wire stat_err_uncor;
wire pcie_sys_clk;
wire pcie_sys_clk_gt;
IBUFDS_GTE4 #(
.REFCLK_HROW_CK_SEL(2'b00)
)
ibufds_gte4_pcie_refclk_inst (
.I (pcie_refclk_1_p),
.IB (pcie_refclk_1_n),
.CEB (1'b0),
.O (pcie_sys_clk_gt),
.ODIV2 (pcie_sys_clk)
);
pcie4c_uscale_plus_0
pcie4c_uscale_plus_inst (
.pci_exp_txn(pcie_tx_n),
.pci_exp_txp(pcie_tx_p),
.pci_exp_rxn(pcie_rx_n),
.pci_exp_rxp(pcie_rx_p),
.user_clk(pcie_user_clk),
.user_reset(pcie_user_rst),
.user_lnk_up(),
.s_axis_rq_tdata(axis_pcie_rq.tdata),
.s_axis_rq_tkeep(axis_pcie_rq.tkeep),
.s_axis_rq_tlast(axis_pcie_rq.tlast),
.s_axis_rq_tready(axis_pcie_rq.tready),
.s_axis_rq_tuser(axis_pcie_rq.tuser),
.s_axis_rq_tvalid(axis_pcie_rq.tvalid),
.m_axis_rc_tdata(axis_pcie_rc.tdata),
.m_axis_rc_tkeep(axis_pcie_rc.tkeep),
.m_axis_rc_tlast(axis_pcie_rc.tlast),
.m_axis_rc_tready(axis_pcie_rc.tready),
.m_axis_rc_tuser(axis_pcie_rc.tuser),
.m_axis_rc_tvalid(axis_pcie_rc.tvalid),
.m_axis_cq_tdata(axis_pcie_cq.tdata),
.m_axis_cq_tkeep(axis_pcie_cq.tkeep),
.m_axis_cq_tlast(axis_pcie_cq.tlast),
.m_axis_cq_tready(axis_pcie_cq.tready),
.m_axis_cq_tuser(axis_pcie_cq.tuser),
.m_axis_cq_tvalid(axis_pcie_cq.tvalid),
.s_axis_cc_tdata(axis_pcie_cc.tdata),
.s_axis_cc_tkeep(axis_pcie_cc.tkeep),
.s_axis_cc_tlast(axis_pcie_cc.tlast),
.s_axis_cc_tready(axis_pcie_cc.tready),
.s_axis_cc_tuser(axis_pcie_cc.tuser),
.s_axis_cc_tvalid(axis_pcie_cc.tvalid),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.pcie_rq_tag0(),
.pcie_rq_tag1(),
.pcie_rq_tag_av(),
.pcie_rq_tag_vld0(),
.pcie_rq_tag_vld1(),
.pcie_tfc_nph_av(),
.pcie_tfc_npd_av(),
.pcie_cq_np_req(1'b1),
.pcie_cq_np_req_count(),
.cfg_phy_link_down(),
.cfg_phy_link_status(),
.cfg_negotiated_width(),
.cfg_current_speed(),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_function_status(),
.cfg_function_power_state(),
.cfg_vf_status(),
.cfg_vf_power_state(),
.cfg_link_power_state(),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_mgmt_debug_access(1'b0),
.cfg_err_cor_out(),
.cfg_err_nonfatal_out(),
.cfg_err_fatal_out(),
.cfg_local_error_valid(),
.cfg_local_error_out(),
.cfg_ltssm_state(),
.cfg_rx_pm_state(),
.cfg_tx_pm_state(),
.cfg_rcb_status(cfg_rcb_status),
.cfg_obff_enable(),
.cfg_pl_status_change(),
.cfg_tph_requester_enable(),
.cfg_tph_st_mode(),
.cfg_vf_tph_requester_enable(),
.cfg_vf_tph_st_mode(),
.cfg_msg_received(),
.cfg_msg_received_data(),
.cfg_msg_received_type(),
.cfg_msg_transmit(1'b0),
.cfg_msg_transmit_type(3'd0),
.cfg_msg_transmit_data(32'd0),
.cfg_msg_transmit_done(),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_dsn(64'd0),
.cfg_bus_number(),
.cfg_power_state_change_ack(1'b1),
.cfg_power_state_change_interrupt(),
.cfg_err_cor_in(stat_err_cor),
.cfg_err_uncor_in(stat_err_uncor),
.cfg_flr_in_process(),
.cfg_flr_done(4'd0),
.cfg_vf_flr_in_process(),
.cfg_vf_flr_func_num(8'd0),
.cfg_vf_flr_done(8'd0),
.cfg_link_training_enable(1'b1),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_int(4'd0),
.cfg_interrupt_pending(4'd0),
.cfg_interrupt_sent(),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msi_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msi_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_pm_aspm_l1_entry_reject(1'b0),
.cfg_pm_aspm_tx_l0s_entry_disable(1'b0),
.cfg_hot_reset_out(),
.cfg_config_space_enable(1'b1),
.cfg_req_pm_transition_l23_ready(1'b0),
.cfg_hot_reset_in(1'b0),
.cfg_ds_port_number(8'd0),
.cfg_ds_bus_number(8'd0),
.cfg_ds_device_number(5'd0),
.sys_clk(pcie_sys_clk),
.sys_clk_gt(pcie_sys_clk_gt),
.sys_reset(pcie_reset_n),
.phy_rdy_out()
);
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// Board configuration
.SW_CNT(4),
.LED_CNT(3),
.UART_CNT(UART_CNT),
.PORT_CNT(PORT_CNT),
.GTY_QUAD_CNT(GTY_QUAD_CNT),
.GTY_CNT(GTY_CNT),
.GTY_CLK_CNT(GTY_CLK_CNT),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_CLK_PER_NS_NUM(1024),
.PTP_CLK_PER_NS_DENOM(165),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
)
core_inst (
/*
* Clock: 125MHz
* Synchronous reset
*/
.clk_125mhz(clk_125mhz_int),
.rst_125mhz(rst_125mhz_int),
/*
* GPIO
*/
.sw('0),
.led(),
.port_led_act(qsfp_led_act),
.port_led_stat_r(),
.port_led_stat_g(qsfp_led_stat_g),
.port_led_stat_b(),
.port_led_stat_y(qsfp_led_stat_y),
/*
* UART
*/
.uart_txd(uart_txd),
.uart_rxd(uart_rxd),
/*
* Ethernet
*/
.eth_gty_tx_p(eth_gty_tx_p),
.eth_gty_tx_n(eth_gty_tx_n),
.eth_gty_rx_p(eth_gty_rx_p),
.eth_gty_rx_n(eth_gty_rx_n),
.eth_gty_mgt_refclk_p(eth_gty_mgt_refclk_p),
.eth_gty_mgt_refclk_n(eth_gty_mgt_refclk_n),
.eth_gty_mgt_refclk_out(eth_gty_mgt_refclk_out),
.eth_port_modsell(),
.eth_port_resetl(),
.eth_port_modprsl('0),
.eth_port_intl('0),
.eth_port_lpmode(),
/*
* PCIe
*/
.pcie_clk(pcie_user_clk),
.pcie_rst(pcie_user_rst),
.s_axis_pcie_cq(axis_pcie_cq),
.m_axis_pcie_cc(axis_pcie_cc),
.m_axis_pcie_rq(axis_pcie_rq),
.s_axis_pcie_rc(axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msix_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msix_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk_int),
.qspi_dq_i(qspi_dq_i_int),
.qspi_dq_o(qspi_dq_o_int),
.qspi_dq_oe(qspi_dq_oe_int),
.qspi_cs(qspi_cs_int)
);
endmodule
`resetall

View File

@@ -0,0 +1,851 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2014-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA core logic
*/
module fpga_core #
(
// simulation (set to avoid vendor primitives)
parameter logic SIM = 1'b0,
// vendor ("GENERIC", "XILINX", "ALTERA")
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// Board configuration
parameter SW_CNT = 4,
parameter LED_CNT = 3,
parameter UART_CNT = 1,
parameter PORT_CNT = 2,
parameter PORT_LED_CNT = PORT_CNT,
parameter GTY_QUAD_CNT = PORT_CNT,
parameter GTY_CNT = GTY_QUAD_CNT*4,
parameter GTY_CLK_CNT = GTY_QUAD_CNT,
// FW ID
parameter FPGA_ID = 32'h4B37093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h10ee_90c8,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
parameter PTP_CLK_PER_NS_NUM = 32,
parameter PTP_CLK_PER_NS_DENOM = 5,
// PCIe interface configuration
parameter RQ_SEQ_NUM_W = 6,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
)
(
/*
* Clock: 125MHz
* Synchronous reset
*/
input wire logic clk_125mhz,
input wire logic rst_125mhz,
/*
* GPIO
*/
input wire logic [SW_CNT-1:0] sw,
output wire logic [LED_CNT-1:0] led,
output wire logic [PORT_LED_CNT-1:0] port_led_act,
output wire logic [PORT_LED_CNT-1:0] port_led_stat_r,
output wire logic [PORT_LED_CNT-1:0] port_led_stat_g,
output wire logic [PORT_LED_CNT-1:0] port_led_stat_b,
output wire logic [PORT_LED_CNT-1:0] port_led_stat_y,
/*
* UART
*/
output wire logic uart_txd[UART_CNT],
input wire logic uart_rxd[UART_CNT],
/*
* Ethernet
*/
output wire logic eth_gty_tx_p[GTY_CNT],
output wire logic eth_gty_tx_n[GTY_CNT],
input wire logic eth_gty_rx_p[GTY_CNT],
input wire logic eth_gty_rx_n[GTY_CNT],
input wire logic eth_gty_mgt_refclk_p[GTY_CLK_CNT],
input wire logic eth_gty_mgt_refclk_n[GTY_CLK_CNT],
output wire logic eth_gty_mgt_refclk_out[GTY_CLK_CNT],
output wire logic [PORT_CNT-1:0] eth_port_modsell,
output wire logic [PORT_CNT-1:0] eth_port_resetl,
input wire logic [PORT_CNT-1:0] eth_port_modprsl,
input wire logic [PORT_CNT-1:0] eth_port_intl,
output wire logic [PORT_CNT-1:0] eth_port_lpmode,
/*
* PCIe
*/
input wire logic pcie_clk,
input wire logic pcie_rst,
taxi_axis_if.snk s_axis_pcie_cq,
taxi_axis_if.src m_axis_pcie_cc,
taxi_axis_if.src m_axis_pcie_rq,
taxi_axis_if.snk s_axis_pcie_rc,
input wire logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0,
input wire logic pcie_rq_seq_num_vld0,
input wire logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1,
input wire logic pcie_rq_seq_num_vld1,
input wire logic [2:0] cfg_max_payload,
input wire logic [2:0] cfg_max_read_req,
input wire logic [3:0] cfg_rcb_status,
output wire logic [9:0] cfg_mgmt_addr,
output wire logic [7:0] cfg_mgmt_function_number,
output wire logic cfg_mgmt_write,
output wire logic [31:0] cfg_mgmt_write_data,
output wire logic [3:0] cfg_mgmt_byte_enable,
output wire logic cfg_mgmt_read,
output wire logic [31:0] cfg_mgmt_read_data,
input wire logic cfg_mgmt_read_write_done,
input wire logic [7:0] cfg_fc_ph,
input wire logic [11:0] cfg_fc_pd,
input wire logic [7:0] cfg_fc_nph,
input wire logic [11:0] cfg_fc_npd,
input wire logic [7:0] cfg_fc_cplh,
input wire logic [11:0] cfg_fc_cpld,
output wire logic [2:0] cfg_fc_sel,
input wire logic cfg_ext_read_received,
input wire logic cfg_ext_write_received,
input wire logic [9:0] cfg_ext_register_number,
input wire logic [7:0] cfg_ext_function_number,
input wire logic [31:0] cfg_ext_write_data,
input wire logic [3:0] cfg_ext_write_byte_enable,
output wire logic [31:0] cfg_ext_read_data,
output wire logic cfg_ext_read_data_valid,
input wire logic [3:0] cfg_interrupt_msi_enable,
input wire logic [11:0] cfg_interrupt_msi_mmenable,
input wire logic cfg_interrupt_msi_mask_update,
input wire logic [31:0] cfg_interrupt_msi_data,
output wire logic [1:0] cfg_interrupt_msi_select,
output wire logic [31:0] cfg_interrupt_msi_int,
output wire logic [31:0] cfg_interrupt_msi_pending_status,
output wire logic cfg_interrupt_msi_pending_status_data_enable,
output wire logic [1:0] cfg_interrupt_msi_pending_status_function_num,
input wire logic cfg_interrupt_msi_sent,
input wire logic cfg_interrupt_msi_fail,
output wire logic [2:0] cfg_interrupt_msi_attr,
output wire logic cfg_interrupt_msi_tph_present,
output wire logic [1:0] cfg_interrupt_msi_tph_type,
output wire logic [7:0] cfg_interrupt_msi_tph_st_tag,
output wire logic [7:0] cfg_interrupt_msi_function_number,
/*
* QSPI flash
*/
output wire logic fpga_boot,
output wire logic qspi_clk,
input wire logic [3:0] qspi_dq_i,
output wire logic [3:0] qspi_dq_o,
output wire logic [3:0] qspi_dq_oe,
output wire logic qspi_cs
);
localparam logic PTP_TS_FMT_TOD = 1'b0;
localparam PTP_TS_W = PTP_TS_FMT_TOD ? 96 : 48;
// flashing via PCIe VPD
pyrite_pcie_us_vpd_qspi #(
.VPD_CAP_ID(8'h03),
.VPD_CAP_OFFSET(8'hB0),
.VPD_CAP_NEXT(8'h00),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Flash
.FLASH_SEG_COUNT(2),
.FLASH_SEG_DEFAULT(1),
.FLASH_SEG_FALLBACK(0),
.FLASH_SEG0_SIZE(32'h01002000),
.FLASH_DATA_W(4),
.FLASH_DUAL_QSPI(1'b0)
)
pyrite_inst (
.clk(pcie_clk),
.rst(pcie_rst),
/*
* PCIe
*/
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk),
.qspi_0_dq_i(qspi_dq_i),
.qspi_0_dq_o(qspi_dq_o),
.qspi_0_dq_oe(qspi_dq_oe),
.qspi_0_cs(qspi_cs),
.qspi_1_dq_i('0),
.qspi_1_dq_o(),
.qspi_1_dq_oe(),
.qspi_1_cs()
);
// XFCP
taxi_axis_if #(.DATA_W(8), .USER_EN(1), .USER_W(1)) xfcp_ds(), xfcp_us();
taxi_xfcp_if_uart #(
.TX_FIFO_DEPTH(512),
.RX_FIFO_DEPTH(512)
)
xfcp_if_uart_inst (
.clk(clk_125mhz),
.rst(rst_125mhz),
/*
* UART interface
*/
.uart_rxd(uart_rxd[0]),
.uart_txd(uart_txd[0]),
/*
* XFCP downstream interface
*/
.xfcp_dsp_ds(xfcp_ds),
.xfcp_dsp_us(xfcp_us),
/*
* Configuration
*/
.prescale(16'(125000000/3000000))
);
localparam XFCP_PORTS = 1+GTY_QUAD_CNT;
taxi_axis_if #(.DATA_W(8), .USER_EN(1), .USER_W(1)) xfcp_sw_ds[XFCP_PORTS](), xfcp_sw_us[XFCP_PORTS]();
taxi_xfcp_switch #(
.XFCP_ID_STR("Alveo"),
.XFCP_EXT_ID(0),
.XFCP_EXT_ID_STR("Taxi example"),
.PORTS($size(xfcp_sw_us))
)
xfcp_sw_inst (
.clk(clk_125mhz),
.rst(rst_125mhz),
/*
* XFCP upstream port
*/
.xfcp_usp_ds(xfcp_ds),
.xfcp_usp_us(xfcp_us),
/*
* XFCP downstream ports
*/
.xfcp_dsp_ds(xfcp_sw_ds),
.xfcp_dsp_us(xfcp_sw_us)
);
taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(10)) axis_stat();
taxi_xfcp_mod_stats #(
.XFCP_ID_STR("Statistics"),
.XFCP_EXT_ID(0),
.XFCP_EXT_ID_STR(""),
.STAT_COUNT_W(64),
.STAT_PIPELINE(2)
)
xfcp_stats_inst (
.clk(clk_125mhz),
.rst(rst_125mhz),
/*
* XFCP upstream port
*/
.xfcp_usp_ds(xfcp_sw_ds[0]),
.xfcp_usp_us(xfcp_sw_us[0]),
/*
* Statistics increment input
*/
.s_axis_stat(axis_stat)
);
taxi_axis_if #(.DATA_W(16), .KEEP_W(1), .KEEP_EN(0), .LAST_EN(0), .USER_EN(1), .USER_W(1), .ID_EN(1), .ID_W(10)) axis_eth_stat[GTY_QUAD_CNT]();
taxi_axis_arb_mux #(
.S_COUNT($size(axis_eth_stat)),
.UPDATE_TID(1'b0),
.ARB_ROUND_ROBIN(1'b1),
.ARB_LSB_HIGH_PRIO(1'b0)
)
stat_mux_inst (
.clk(clk_125mhz),
.rst(rst_125mhz),
/*
* AXI4-Stream inputs (sink)
*/
.s_axis(axis_eth_stat),
/*
* AXI4-Stream output (source)
*/
.m_axis(axis_stat)
);
// Additional UARTs
for (genvar n = 1; n < UART_CNT; n = n + 1) begin : uart_ch
taxi_axis_if #(.DATA_W(8)) axis_uart();
taxi_uart
uart_inst (
.clk(clk_125mhz),
.rst(rst_125mhz),
/*
* AXI4-Stream input (sink)
*/
.s_axis_tx(axis_uart),
/*
* AXI4-Stream output (source)
*/
.m_axis_rx(axis_uart),
/*
* UART interface
*/
.rxd(uart_rxd[n]),
.txd(uart_txd[n]),
/*
* Status
*/
.tx_busy(),
.rx_busy(),
.rx_overrun_error(),
.rx_frame_error(),
/*
* Configuration
*/
.prescale(16'(125000000/115200))
);
end
// Ethernet
assign eth_port_modsell = '1;
assign eth_port_resetl = '1;
assign eth_port_lpmode = '0;
wire eth_gty_tx_clk[GTY_CNT];
wire eth_gty_tx_rst[GTY_CNT];
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1)) eth_gty_axis_tx[GTY_CNT]();
taxi_axis_if #(.DATA_W(PTP_TS_W), .KEEP_W(1), .ID_W(8)) eth_gty_axis_tx_cpl[GTY_CNT]();
wire eth_gty_rx_clk[GTY_CNT];
wire eth_gty_rx_rst[GTY_CNT];
taxi_axis_if #(.DATA_W(MAC_DATA_W), .ID_W(8), .USER_EN(1), .USER_W(1+PTP_TS_W)) eth_gty_axis_rx[GTY_CNT]();
wire eth_gty_rx_status[GTY_CNT];
wire [GTY_QUAD_CNT-1:0] eth_gty_gtpowergood;
wire eth_gty_mgt_refclk[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_bufg[GTY_CLK_CNT];
wire eth_gty_rst[GTY_CLK_CNT];
for (genvar n = 0; n < GTY_CLK_CNT; n = n + 1) begin : gty_clk
wire eth_gty_mgt_refclk_int;
if (SIM) begin
assign eth_gty_mgt_refclk[n] = eth_gty_mgt_refclk_p[n];
assign eth_gty_mgt_refclk_int = eth_gty_mgt_refclk_p[n];
assign eth_gty_mgt_refclk_bufg[n] = eth_gty_mgt_refclk_int;
end else begin
IBUFDS_GTE4 ibufds_gte4_eth_gty_mgt_refclk_inst (
.I (eth_gty_mgt_refclk_p[n]),
.IB (eth_gty_mgt_refclk_n[n]),
.CEB (1'b0),
.O (eth_gty_mgt_refclk[n]),
.ODIV2 (eth_gty_mgt_refclk_int)
);
BUFG_GT bufg_gt_eth_gty_mgt_refclk_inst (
.CE (&eth_gty_gtpowergood),
.CEMASK (1'b1),
.CLR (1'b0),
.CLRMASK (1'b1),
.DIV (3'd0),
.I (eth_gty_mgt_refclk_int),
.O (eth_gty_mgt_refclk_bufg[n])
);
end
assign eth_gty_mgt_refclk_out[n] = eth_gty_mgt_refclk_bufg[n];
taxi_sync_reset #(
.N(4)
)
qsfp_sync_reset_inst (
.clk(eth_gty_mgt_refclk_bufg[n]),
.rst(rst_125mhz),
.out(eth_gty_rst[n])
);
end
wire ptp_clk = eth_gty_mgt_refclk_bufg[0];
wire ptp_rst = eth_gty_rst[0];
wire ptp_sample_clk = clk_125mhz;
wire ptp_td_sd;
wire ptp_pps;
wire ptp_pps_str;
assign led[0] = ptp_pps_str;
localparam logic [8*8-1:0] STAT_PREFIX_STR_QSFP1[4] = '{"QSFP1.1", "QSFP1.2", "QSFP1.3", "QSFP1.4"};
localparam logic [8*8-1:0] STAT_PREFIX_STR_QSFP2[4] = '{"QSFP2.1", "QSFP2.2", "QSFP2.3", "QSFP2.4"};
for (genvar n = 0; n < GTY_QUAD_CNT; n = n + 1) begin : gty_quad
localparam CLK = n;
localparam CNT = 4;
taxi_apb_if #(
.ADDR_W(18),
.DATA_W(16)
)
gt_apb_ctrl();
taxi_xfcp_mod_apb #(
.XFCP_EXT_ID_STR("GTY CTRL")
)
xfcp_mod_apb_inst (
.clk(clk_125mhz),
.rst(rst_125mhz),
/*
* XFCP upstream port
*/
.xfcp_usp_ds(xfcp_sw_ds[n+1]),
.xfcp_usp_us(xfcp_sw_us[n+1]),
/*
* APB master interface
*/
.m_apb(gt_apb_ctrl)
);
taxi_eth_mac_25g_us #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
.CNT(CNT),
// GT config
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
// GT type
.GT_TYPE("GTY"),
// MAC/PHY config
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.DATA_W(MAC_DATA_W),
.PADDING_EN(1'b1),
.DIC_EN(1'b1),
.MIN_FRAME_LEN(64),
.PTP_TS_EN(PTP_TS_EN),
.PTP_TD_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(PTP_TS_FMT_TOD),
.PTP_TS_W(PTP_TS_W),
.PTP_TD_SDI_PIPELINE(2),
.PRBS31_EN(1'b0),
.TX_SERDES_PIPELINE(1),
.RX_SERDES_PIPELINE(1),
.COUNT_125US(125000/6.4),
.STAT_EN(1),
.STAT_TX_LEVEL(1),
.STAT_RX_LEVEL(1),
.STAT_ID_BASE(n*CNT*(16+16)),
.STAT_UPDATE_PERIOD(1024),
.STAT_STR_EN(1),
.STAT_PREFIX_STR(n == 0 ? STAT_PREFIX_STR_QSFP1 : STAT_PREFIX_STR_QSFP2)
)
mac_inst (
.xcvr_ctrl_clk(clk_125mhz),
.xcvr_ctrl_rst(eth_gty_rst[CLK]),
/*
* Transceiver control
*/
.s_apb_ctrl(gt_apb_ctrl),
/*
* Common
*/
.xcvr_gtpowergood_out(eth_gty_gtpowergood[n]),
.xcvr_gtrefclk00_in(eth_gty_mgt_refclk[CLK]),
.xcvr_qpll0pd_in(1'b0),
.xcvr_qpll0reset_in(1'b0),
.xcvr_qpll0pcierate_in(3'd0),
.xcvr_qpll0lock_out(),
.xcvr_qpll0clk_out(),
.xcvr_qpll0refclk_out(),
.xcvr_gtrefclk01_in(eth_gty_mgt_refclk[CLK]),
.xcvr_qpll1pd_in(1'b0),
.xcvr_qpll1reset_in(1'b0),
.xcvr_qpll1pcierate_in(3'd0),
.xcvr_qpll1lock_out(),
.xcvr_qpll1clk_out(),
.xcvr_qpll1refclk_out(),
/*
* Serial data
*/
.xcvr_txp(eth_gty_tx_p[n*CNT +: CNT]),
.xcvr_txn(eth_gty_tx_n[n*CNT +: CNT]),
.xcvr_rxp(eth_gty_rx_p[n*CNT +: CNT]),
.xcvr_rxn(eth_gty_rx_n[n*CNT +: CNT]),
/*
* MAC clocks
*/
.rx_clk(eth_gty_rx_clk[n*CNT +: CNT]),
.rx_rst_in('{CNT{1'b0}}),
.rx_rst_out(eth_gty_rx_rst[n*CNT +: CNT]),
.tx_clk(eth_gty_tx_clk[n*CNT +: CNT]),
.tx_rst_in('{CNT{1'b0}}),
.tx_rst_out(eth_gty_tx_rst[n*CNT +: CNT]),
/*
* Transmit interface (AXI stream)
*/
.s_axis_tx(eth_gty_axis_tx[n*CNT +: CNT]),
.m_axis_tx_cpl(eth_gty_axis_tx_cpl[n*CNT +: CNT]),
/*
* Receive interface (AXI stream)
*/
.m_axis_rx(eth_gty_axis_rx[n*CNT +: CNT]),
/*
* PTP clock
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_sample_clk(ptp_sample_clk),
.ptp_td_sdi(ptp_td_sd),
.tx_ptp_ts_in('{CNT{'0}}),
.tx_ptp_ts_out(),
.tx_ptp_ts_step_out(),
.tx_ptp_locked(),
.rx_ptp_ts_in('{CNT{'0}}),
.rx_ptp_ts_out(),
.rx_ptp_ts_step_out(),
.rx_ptp_locked(),
/*
* Link-level Flow Control (LFC) (IEEE 802.3 annex 31B PAUSE)
*/
.tx_lfc_req('{CNT{1'b0}}),
.tx_lfc_resend('{CNT{1'b0}}),
.rx_lfc_en('{CNT{1'b0}}),
.rx_lfc_req(),
.rx_lfc_ack('{CNT{1'b0}}),
/*
* Priority Flow Control (PFC) (IEEE 802.3 annex 31D PFC)
*/
.tx_pfc_req('{CNT{'0}}),
.tx_pfc_resend('{CNT{1'b0}}),
.rx_pfc_en('{CNT{'0}}),
.rx_pfc_req(),
.rx_pfc_ack('{CNT{'0}}),
/*
* Pause interface
*/
.tx_lfc_pause_en('{CNT{1'b0}}),
.tx_pause_req('{CNT{1'b0}}),
.tx_pause_ack(),
/*
* Statistics
*/
.stat_clk(clk_125mhz),
.stat_rst(rst_125mhz),
.m_axis_stat(axis_eth_stat[n]),
/*
* Status
*/
.tx_start_packet(),
.stat_tx_byte(),
.stat_tx_pkt_len(),
.stat_tx_pkt_ucast(),
.stat_tx_pkt_mcast(),
.stat_tx_pkt_bcast(),
.stat_tx_pkt_vlan(),
.stat_tx_pkt_good(),
.stat_tx_pkt_bad(),
.stat_tx_err_oversize(),
.stat_tx_err_user(),
.stat_tx_err_underflow(),
.rx_start_packet(),
.rx_error_count(),
.rx_block_lock(),
.rx_high_ber(),
.rx_status(eth_gty_rx_status[n*CNT +: CNT]),
.stat_rx_byte(),
.stat_rx_pkt_len(),
.stat_rx_pkt_fragment(),
.stat_rx_pkt_jabber(),
.stat_rx_pkt_ucast(),
.stat_rx_pkt_mcast(),
.stat_rx_pkt_bcast(),
.stat_rx_pkt_vlan(),
.stat_rx_pkt_good(),
.stat_rx_pkt_bad(),
.stat_rx_err_oversize(),
.stat_rx_err_bad_fcs(),
.stat_rx_err_bad_block(),
.stat_rx_err_framing(),
.stat_rx_err_preamble(),
.stat_rx_fifo_drop('{CNT{1'b0}}),
.stat_tx_mcf(),
.stat_rx_mcf(),
.stat_tx_lfc_pkt(),
.stat_tx_lfc_xon(),
.stat_tx_lfc_xoff(),
.stat_tx_lfc_paused(),
.stat_tx_pfc_pkt(),
.stat_tx_pfc_xon(),
.stat_tx_pfc_xoff(),
.stat_tx_pfc_paused(),
.stat_rx_lfc_pkt(),
.stat_rx_lfc_xon(),
.stat_rx_lfc_xoff(),
.stat_rx_lfc_paused(),
.stat_rx_pfc_pkt(),
.stat_rx_pfc_xon(),
.stat_rx_pfc_xoff(),
.stat_rx_pfc_paused(),
/*
* Configuration
*/
.cfg_tx_max_pkt_len('{CNT{16'd9218}}),
.cfg_tx_ifg('{CNT{8'd12}}),
.cfg_tx_enable('{CNT{1'b1}}),
.cfg_rx_max_pkt_len('{CNT{16'd9218}}),
.cfg_rx_enable('{CNT{1'b1}}),
.cfg_tx_prbs31_enable('{CNT{1'b0}}),
.cfg_rx_prbs31_enable('{CNT{1'b0}}),
.cfg_mcf_rx_eth_dst_mcast('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_mcf_rx_check_eth_dst_mcast('{CNT{1'b1}}),
.cfg_mcf_rx_eth_dst_ucast('{CNT{48'd0}}),
.cfg_mcf_rx_check_eth_dst_ucast('{CNT{1'b0}}),
.cfg_mcf_rx_eth_src('{CNT{48'd0}}),
.cfg_mcf_rx_check_eth_src('{CNT{1'b0}}),
.cfg_mcf_rx_eth_type('{CNT{16'h8808}}),
.cfg_mcf_rx_opcode_lfc('{CNT{16'h0001}}),
.cfg_mcf_rx_check_opcode_lfc('{CNT{1'b1}}),
.cfg_mcf_rx_opcode_pfc('{CNT{16'h0101}}),
.cfg_mcf_rx_check_opcode_pfc('{CNT{1'b1}}),
.cfg_mcf_rx_forward('{CNT{1'b0}}),
.cfg_mcf_rx_enable('{CNT{1'b0}}),
.cfg_tx_lfc_eth_dst('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_tx_lfc_eth_src('{CNT{48'h80_23_31_43_54_4C}}),
.cfg_tx_lfc_eth_type('{CNT{16'h8808}}),
.cfg_tx_lfc_opcode('{CNT{16'h0001}}),
.cfg_tx_lfc_en('{CNT{1'b0}}),
.cfg_tx_lfc_quanta('{CNT{16'hffff}}),
.cfg_tx_lfc_refresh('{CNT{16'h7fff}}),
.cfg_tx_pfc_eth_dst('{CNT{48'h01_80_C2_00_00_01}}),
.cfg_tx_pfc_eth_src('{CNT{48'h80_23_31_43_54_4C}}),
.cfg_tx_pfc_eth_type('{CNT{16'h8808}}),
.cfg_tx_pfc_opcode('{CNT{16'h0101}}),
.cfg_tx_pfc_en('{CNT{1'b0}}),
.cfg_tx_pfc_quanta('{CNT{'{8{16'hffff}}}}),
.cfg_tx_pfc_refresh('{CNT{'{8{16'h7fff}}}}),
.cfg_rx_lfc_opcode('{CNT{16'h0001}}),
.cfg_rx_lfc_en('{CNT{1'b0}}),
.cfg_rx_pfc_opcode('{CNT{16'h0101}}),
.cfg_rx_pfc_en('{CNT{1'b0}})
);
end
cndm_micro_pcie_us #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// Structural configuration
.PORTS(GTY_CNT),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_TS_FMT_TOD(1'b0),
.PTP_CLK_PER_NS_NUM(PTP_CLK_PER_NS_NUM),
.PTP_CLK_PER_NS_DENOM(PTP_CLK_PER_NS_DENOM),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W)
)
cndm_inst (
/*
* PCIe
*/
.pcie_clk(pcie_clk),
.pcie_rst(pcie_rst),
.s_axis_pcie_cq(s_axis_pcie_cq),
.m_axis_pcie_cc(m_axis_pcie_cc),
.m_axis_pcie_rq(m_axis_pcie_rq),
.s_axis_pcie_rc(s_axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* PTP
*/
.ptp_clk(ptp_clk),
.ptp_rst(ptp_rst),
.ptp_sample_clk(ptp_sample_clk),
.ptp_td_sdo(ptp_td_sd),
.ptp_pps(ptp_pps),
.ptp_pps_str(ptp_pps_str),
.ptp_sync_locked(),
.ptp_sync_ts_rel(),
.ptp_sync_ts_rel_step(),
.ptp_sync_ts_tod(),
.ptp_sync_ts_tod_step(),
.ptp_sync_pps(),
.ptp_sync_pps_str(),
/*
* Ethernet
*/
.mac_tx_clk(eth_gty_tx_clk),
.mac_tx_rst(eth_gty_tx_rst),
.mac_axis_tx(eth_gty_axis_tx),
.mac_axis_tx_cpl(eth_gty_axis_tx_cpl),
.mac_rx_clk(eth_gty_rx_clk),
.mac_rx_rst(eth_gty_rx_rst),
.mac_axis_rx(eth_gty_axis_rx)
);
endmodule
`resetall

View File

@@ -0,0 +1,892 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2014-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA top-level module
*/
module fpga #
(
// simulation (set to avoid vendor primitives)
parameter logic SIM = 1'b0,
// vendor ("GENERIC", "XILINX", "ALTERA")
parameter string VENDOR = "XILINX",
// device family
parameter string FAMILY = "virtexuplus",
// Board configuration
parameter PORT_CNT = 4,
parameter UART_CNT = 1,
// FW ID
parameter FPGA_ID = 32'h4AD5093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h10ee_9dc2,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
)
(
/*
* GPIO
*/
output wire logic [PORT_CNT-1:0] dsfp_led_r,
output wire logic [PORT_CNT-1:0] dsfp_led_g,
output wire logic [PORT_CNT-1:0] dsfp_led_b,
/*
* UART
*/
output wire logic uart_txd,
input wire logic uart_rxd,
/*
* Ethernet: QSFP28
*/
output wire logic dsfp0_tx_p[2],
output wire logic dsfp0_tx_n[2],
input wire logic dsfp0_rx_p[2],
input wire logic dsfp0_rx_n[2],
output wire logic dsfp1_tx_p[2],
output wire logic dsfp1_tx_n[2],
input wire logic dsfp1_rx_p[2],
input wire logic dsfp1_rx_n[2],
input wire logic dsfp_mgt_refclk_p,
input wire logic dsfp_mgt_refclk_n,
/*
* PCIe
*/
input wire logic [7:0] pcie_rx_p,
input wire logic [7:0] pcie_rx_n,
output wire logic [7:0] pcie_tx_p,
output wire logic [7:0] pcie_tx_n,
input wire logic pcie_refclk_p,
input wire logic pcie_refclk_n,
input wire logic pcie_reset_n
);
// Clock and reset
wire pcie_user_clk;
wire pcie_user_rst;
wire clk_161mhz_ref_int;
// Internal 125 MHz clock
wire clk_125mhz_mmcm_out;
wire clk_125mhz_int;
wire rst_125mhz_int;
wire mmcm_rst = 1'b0;
wire mmcm_locked;
wire mmcm_clkfb;
// MMCM instance
MMCME4_BASE #(
// 161.13 MHz input
.CLKIN1_PERIOD(6.206),
.REF_JITTER1(0.010),
// 161.13 MHz input / 11 = 14.65 MHz PFD (range 10 MHz to 500 MHz)
.DIVCLK_DIVIDE(11),
// 14.65 MHz PFD * 64 = 937.5 MHz VCO (range 800 MHz to 1600 MHz)
.CLKFBOUT_MULT_F(64),
.CLKFBOUT_PHASE(0),
// 937.5 MHz / 7.5 = 125 MHz, 0 degrees
.CLKOUT0_DIVIDE_F(7.5),
.CLKOUT0_DUTY_CYCLE(0.5),
.CLKOUT0_PHASE(0),
// Not used
.CLKOUT1_DIVIDE(1),
.CLKOUT1_DUTY_CYCLE(0.5),
.CLKOUT1_PHASE(0),
// Not used
.CLKOUT2_DIVIDE(1),
.CLKOUT2_DUTY_CYCLE(0.5),
.CLKOUT2_PHASE(0),
// Not used
.CLKOUT3_DIVIDE(1),
.CLKOUT3_DUTY_CYCLE(0.5),
.CLKOUT3_PHASE(0),
// Not used
.CLKOUT4_DIVIDE(1),
.CLKOUT4_DUTY_CYCLE(0.5),
.CLKOUT4_PHASE(0),
.CLKOUT4_CASCADE("FALSE"),
// Not used
.CLKOUT5_DIVIDE(1),
.CLKOUT5_DUTY_CYCLE(0.5),
.CLKOUT5_PHASE(0),
// Not used
.CLKOUT6_DIVIDE(1),
.CLKOUT6_DUTY_CYCLE(0.5),
.CLKOUT6_PHASE(0),
// optimized bandwidth
.BANDWIDTH("OPTIMIZED"),
// don't wait for lock during startup
.STARTUP_WAIT("FALSE")
)
clk_mmcm_inst (
// 161.13 MHz input
.CLKIN1(clk_161mhz_ref_int),
// direct clkfb feeback
.CLKFBIN(mmcm_clkfb),
.CLKFBOUT(mmcm_clkfb),
.CLKFBOUTB(),
// 125 MHz, 0 degrees
.CLKOUT0(clk_125mhz_mmcm_out),
.CLKOUT0B(),
// Not used
.CLKOUT1(),
.CLKOUT1B(),
// Not used
.CLKOUT2(),
.CLKOUT2B(),
// Not used
.CLKOUT3(),
.CLKOUT3B(),
// Not used
.CLKOUT4(),
// Not used
.CLKOUT5(),
// Not used
.CLKOUT6(),
// reset input
.RST(mmcm_rst),
// don't power down
.PWRDWN(1'b0),
// locked output
.LOCKED(mmcm_locked)
);
BUFG
clk_125mhz_bufg_inst (
.I(clk_125mhz_mmcm_out),
.O(clk_125mhz_int)
);
taxi_sync_reset #(
.N(4)
)
sync_reset_125mhz_inst (
.clk(clk_125mhz_int),
.rst(~mmcm_locked),
.out(rst_125mhz_int)
);
localparam GTY_QUAD_CNT = 1;
localparam GTY_CNT = GTY_QUAD_CNT*4;
localparam GTY_CLK_CNT = GTY_QUAD_CNT;
wire eth_gty_tx_p[GTY_CNT];
wire eth_gty_tx_n[GTY_CNT];
wire eth_gty_rx_p[GTY_CNT];
wire eth_gty_rx_n[GTY_CNT];
wire eth_gty_mgt_refclk_p[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_n[GTY_CLK_CNT];
wire eth_gty_mgt_refclk_out[GTY_CLK_CNT];
assign dsfp0_tx_p = eth_gty_tx_p[2*0 +: 2];
assign dsfp0_tx_n = eth_gty_tx_n[2*0 +: 2];
assign eth_gty_rx_p[2*0 +: 2] = dsfp0_rx_p;
assign eth_gty_rx_n[2*0 +: 2] = dsfp0_rx_n;
assign dsfp1_tx_p = eth_gty_tx_p[2*1 +: 2];
assign dsfp1_tx_n = eth_gty_tx_n[2*1 +: 2];
assign eth_gty_rx_p[2*1 +: 2] = dsfp1_rx_p;
assign eth_gty_rx_n[2*1 +: 2] = dsfp1_rx_n;
assign eth_gty_mgt_refclk_p[0] = dsfp_mgt_refclk_p;
assign eth_gty_mgt_refclk_n[0] = dsfp_mgt_refclk_n;
assign clk_161mhz_ref_int = eth_gty_mgt_refclk_out[0];
// Flash
wire qspi_clk_int;
wire [3:0] qspi_dq_int;
wire [3:0] qspi_dq_i_int;
wire [3:0] qspi_dq_o_int;
wire [3:0] qspi_dq_oe_int;
wire qspi_cs_int;
reg qspi_clk_reg;
reg [3:0] qspi_dq_o_reg;
reg [3:0] qspi_dq_oe_reg;
reg qspi_cs_reg;
always_ff @(posedge pcie_user_clk) begin
qspi_clk_reg <= qspi_clk_int;
qspi_dq_o_reg <= qspi_dq_o_int;
qspi_dq_oe_reg <= qspi_dq_oe_int;
qspi_cs_reg <= qspi_cs_int;
end
taxi_sync_signal #(
.WIDTH(8),
.N(2)
)
flash_sync_inst (
.clk(pcie_user_clk),
.in({qspi_dq_int}),
.out({qspi_dq_i_int})
);
STARTUPE3
startupe3_inst (
.CFGCLK(),
.CFGMCLK(),
.DI(qspi_dq_int),
.DO(qspi_dq_o_reg),
.DTS(~qspi_dq_oe_reg),
.EOS(),
.FCSBO(qspi_cs_reg),
.FCSBTS(1'b0),
.GSR(1'b0),
.GTS(1'b0),
.KEYCLEARB(1'b1),
.PACK(1'b0),
.PREQ(),
.USRCCLKO(qspi_clk_reg),
.USRCCLKTS(1'b0),
.USRDONEO(1'b0),
.USRDONETS(1'b1)
);
// FPGA boot
wire fpga_boot;
wire fpga_boot_sync;
taxi_sync_signal #(
.WIDTH(1),
.N(2)
)
fpga_boot_sync_inst (
.clk(clk_125mhz_int),
.in({fpga_boot}),
.out({fpga_boot_sync})
);
wire icap_avail;
logic [2:0] icap_state_reg = 0;
logic icap_csib_reg = 1'b1;
logic icap_rdwrb_reg = 1'b0;
logic [31:0] icap_di_reg = 32'hffffffff;
wire [31:0] icap_di_rev;
assign icap_di_rev[ 7] = icap_di_reg[ 0];
assign icap_di_rev[ 6] = icap_di_reg[ 1];
assign icap_di_rev[ 5] = icap_di_reg[ 2];
assign icap_di_rev[ 4] = icap_di_reg[ 3];
assign icap_di_rev[ 3] = icap_di_reg[ 4];
assign icap_di_rev[ 2] = icap_di_reg[ 5];
assign icap_di_rev[ 1] = icap_di_reg[ 6];
assign icap_di_rev[ 0] = icap_di_reg[ 7];
assign icap_di_rev[15] = icap_di_reg[ 8];
assign icap_di_rev[14] = icap_di_reg[ 9];
assign icap_di_rev[13] = icap_di_reg[10];
assign icap_di_rev[12] = icap_di_reg[11];
assign icap_di_rev[11] = icap_di_reg[12];
assign icap_di_rev[10] = icap_di_reg[13];
assign icap_di_rev[ 9] = icap_di_reg[14];
assign icap_di_rev[ 8] = icap_di_reg[15];
assign icap_di_rev[23] = icap_di_reg[16];
assign icap_di_rev[22] = icap_di_reg[17];
assign icap_di_rev[21] = icap_di_reg[18];
assign icap_di_rev[20] = icap_di_reg[19];
assign icap_di_rev[19] = icap_di_reg[20];
assign icap_di_rev[18] = icap_di_reg[21];
assign icap_di_rev[17] = icap_di_reg[22];
assign icap_di_rev[16] = icap_di_reg[23];
assign icap_di_rev[31] = icap_di_reg[24];
assign icap_di_rev[30] = icap_di_reg[25];
assign icap_di_rev[29] = icap_di_reg[26];
assign icap_di_rev[28] = icap_di_reg[27];
assign icap_di_rev[27] = icap_di_reg[28];
assign icap_di_rev[26] = icap_di_reg[29];
assign icap_di_rev[25] = icap_di_reg[30];
assign icap_di_rev[24] = icap_di_reg[31];
always_ff @(posedge clk_125mhz_int) begin
case (icap_state_reg)
0: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b1;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
if (fpga_boot_sync && icap_avail) begin
icap_state_reg <= 1;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hffffffff; // dummy word
end
end
1: begin
icap_state_reg <= 2;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'hAA995566; // sync word
end
2: begin
icap_state_reg <= 3;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
3: begin
icap_state_reg <= 4;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h30008001; // write 1 word to CMD
end
4: begin
icap_state_reg <= 5;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h0000000F; // IPROG
end
5: begin
icap_state_reg <= 0;
icap_csib_reg <= 1'b0;
icap_rdwrb_reg <= 1'b0;
icap_di_reg <= 32'h20000000; // type 1 noop
end
endcase
end
ICAPE3
icape3_inst (
.AVAIL(icap_avail),
.CLK(clk_125mhz_int),
.CSIB(icap_csib_reg),
.I(icap_di_rev),
.O(),
.PRDONE(),
.PRERROR(),
.RDWRB(icap_rdwrb_reg)
);
// PCIe
localparam AXIS_PCIE_DATA_W = 512;
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
localparam AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161;
localparam AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137;
localparam AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183;
localparam AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81;
localparam RC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 256;
localparam RQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CQ_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam CC_STRADDLE = 0; // AXIS_PCIE_DATA_W >= 512;
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
localparam RQ_SEQ_NUM_EN = 1;
localparam PCIE_TAG_CNT = AXIS_PCIE_RQ_USER_W == 60 ? 64 : 256;
localparam BAR0_APERTURE = 24;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CQ_USER_W)
) axis_pcie_cq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CC_USER_W)
) axis_pcie_cc();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RQ_USER_W)
) axis_pcie_rq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RC_USER_W)
) axis_pcie_rc();
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0;
wire pcie_rq_seq_num_vld0;
wire [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1;
wire pcie_rq_seq_num_vld1;
wire [2:0] cfg_max_payload;
wire [2:0] cfg_max_read_req;
wire [3:0] cfg_rcb_status;
wire [9:0] cfg_mgmt_addr;
wire [7:0] cfg_mgmt_function_number;
wire cfg_mgmt_write;
wire [31:0] cfg_mgmt_write_data;
wire [3:0] cfg_mgmt_byte_enable;
wire cfg_mgmt_read;
wire [31:0] cfg_mgmt_read_data;
wire cfg_mgmt_read_write_done;
wire [7:0] cfg_fc_ph;
wire [11:0] cfg_fc_pd;
wire [7:0] cfg_fc_nph;
wire [11:0] cfg_fc_npd;
wire [7:0] cfg_fc_cplh;
wire [11:0] cfg_fc_cpld;
wire [2:0] cfg_fc_sel;
wire cfg_ext_read_received;
wire cfg_ext_write_received;
wire [9:0] cfg_ext_register_number;
wire [7:0] cfg_ext_function_number;
wire [31:0] cfg_ext_write_data;
wire [3:0] cfg_ext_write_byte_enable;
wire [31:0] cfg_ext_read_data;
wire cfg_ext_read_data_valid;
// wire [3:0] cfg_interrupt_msix_enable;
// wire [3:0] cfg_interrupt_msix_mask;
// wire [251:0] cfg_interrupt_msix_vf_enable;
// wire [251:0] cfg_interrupt_msix_vf_mask;
// wire [63:0] cfg_interrupt_msix_address;
// wire [31:0] cfg_interrupt_msix_data;
// wire cfg_interrupt_msix_int;
// wire [1:0] cfg_interrupt_msix_vec_pending;
// wire cfg_interrupt_msix_vec_pending_status;
// wire cfg_interrupt_msix_sent;
// wire cfg_interrupt_msix_fail;
// wire [7:0] cfg_interrupt_msi_function_number;
wire [3:0] cfg_interrupt_msi_enable;
wire [11:0] cfg_interrupt_msi_mmenable;
wire cfg_interrupt_msi_mask_update;
wire [31:0] cfg_interrupt_msi_data;
wire [1:0] cfg_interrupt_msi_select;
wire [31:0] cfg_interrupt_msi_int;
wire [31:0] cfg_interrupt_msi_pending_status;
wire cfg_interrupt_msi_pending_status_data_enable;
wire [1:0] cfg_interrupt_msi_pending_status_function_num;
wire cfg_interrupt_msi_sent;
wire cfg_interrupt_msi_fail;
wire [2:0] cfg_interrupt_msi_attr;
wire cfg_interrupt_msi_tph_present;
wire [1:0] cfg_interrupt_msi_tph_type;
wire [7:0] cfg_interrupt_msi_tph_st_tag;
wire [7:0] cfg_interrupt_msi_function_number;
wire stat_err_cor;
wire stat_err_uncor;
wire pcie_sys_clk;
wire pcie_sys_clk_gt;
IBUFDS_GTE4 #(
.REFCLK_HROW_CK_SEL(2'b00)
)
ibufds_gte4_pcie_refclk_inst (
.I (pcie_refclk_p),
.IB (pcie_refclk_n),
.CEB (1'b0),
.O (pcie_sys_clk_gt),
.ODIV2 (pcie_sys_clk)
);
pcie4c_uscale_plus_0
pcie4c_uscale_plus_inst (
.pci_exp_txn(pcie_tx_n),
.pci_exp_txp(pcie_tx_p),
.pci_exp_rxn(pcie_rx_n),
.pci_exp_rxp(pcie_rx_p),
.user_clk(pcie_user_clk),
.user_reset(pcie_user_rst),
.user_lnk_up(),
.s_axis_rq_tdata(axis_pcie_rq.tdata),
.s_axis_rq_tkeep(axis_pcie_rq.tkeep),
.s_axis_rq_tlast(axis_pcie_rq.tlast),
.s_axis_rq_tready(axis_pcie_rq.tready),
.s_axis_rq_tuser(axis_pcie_rq.tuser),
.s_axis_rq_tvalid(axis_pcie_rq.tvalid),
.m_axis_rc_tdata(axis_pcie_rc.tdata),
.m_axis_rc_tkeep(axis_pcie_rc.tkeep),
.m_axis_rc_tlast(axis_pcie_rc.tlast),
.m_axis_rc_tready(axis_pcie_rc.tready),
.m_axis_rc_tuser(axis_pcie_rc.tuser),
.m_axis_rc_tvalid(axis_pcie_rc.tvalid),
.m_axis_cq_tdata(axis_pcie_cq.tdata),
.m_axis_cq_tkeep(axis_pcie_cq.tkeep),
.m_axis_cq_tlast(axis_pcie_cq.tlast),
.m_axis_cq_tready(axis_pcie_cq.tready),
.m_axis_cq_tuser(axis_pcie_cq.tuser),
.m_axis_cq_tvalid(axis_pcie_cq.tvalid),
.s_axis_cc_tdata(axis_pcie_cc.tdata),
.s_axis_cc_tkeep(axis_pcie_cc.tkeep),
.s_axis_cc_tlast(axis_pcie_cc.tlast),
.s_axis_cc_tready(axis_pcie_cc.tready),
.s_axis_cc_tuser(axis_pcie_cc.tuser),
.s_axis_cc_tvalid(axis_pcie_cc.tvalid),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.pcie_rq_tag0(),
.pcie_rq_tag1(),
.pcie_rq_tag_av(),
.pcie_rq_tag_vld0(),
.pcie_rq_tag_vld1(),
.pcie_tfc_nph_av(),
.pcie_tfc_npd_av(),
.pcie_cq_np_req(1'b1),
.pcie_cq_np_req_count(),
.cfg_phy_link_down(),
.cfg_phy_link_status(),
.cfg_negotiated_width(),
.cfg_current_speed(),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_function_status(),
.cfg_function_power_state(),
.cfg_vf_status(),
.cfg_vf_power_state(),
.cfg_link_power_state(),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_mgmt_debug_access(1'b0),
.cfg_err_cor_out(),
.cfg_err_nonfatal_out(),
.cfg_err_fatal_out(),
.cfg_local_error_valid(),
.cfg_local_error_out(),
.cfg_ltssm_state(),
.cfg_rx_pm_state(),
.cfg_tx_pm_state(),
.cfg_rcb_status(cfg_rcb_status),
.cfg_obff_enable(),
.cfg_pl_status_change(),
.cfg_tph_requester_enable(),
.cfg_tph_st_mode(),
.cfg_vf_tph_requester_enable(),
.cfg_vf_tph_st_mode(),
.cfg_msg_received(),
.cfg_msg_received_data(),
.cfg_msg_received_type(),
.cfg_msg_transmit(1'b0),
.cfg_msg_transmit_type(3'd0),
.cfg_msg_transmit_data(32'd0),
.cfg_msg_transmit_done(),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_dsn(64'd0),
.cfg_bus_number(),
.cfg_power_state_change_ack(1'b1),
.cfg_power_state_change_interrupt(),
.cfg_err_cor_in(stat_err_cor),
.cfg_err_uncor_in(stat_err_uncor),
.cfg_flr_in_process(),
.cfg_flr_done(4'd0),
.cfg_vf_flr_in_process(),
.cfg_vf_flr_func_num(8'd0),
.cfg_vf_flr_done(8'd0),
.cfg_link_training_enable(1'b1),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_int(4'd0),
.cfg_interrupt_pending(4'd0),
.cfg_interrupt_sent(),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msi_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msi_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_pm_aspm_l1_entry_reject(1'b0),
.cfg_pm_aspm_tx_l0s_entry_disable(1'b0),
.cfg_hot_reset_out(),
.cfg_config_space_enable(1'b1),
.cfg_req_pm_transition_l23_ready(1'b0),
.cfg_hot_reset_in(1'b0),
.cfg_ds_port_number(8'd0),
.cfg_ds_bus_number(8'd0),
.cfg_ds_device_number(5'd0),
.sys_clk(pcie_sys_clk),
.sys_clk_gt(pcie_sys_clk_gt),
.sys_reset(pcie_reset_n),
.phy_rdy_out()
);
wire uart_rxd_int[1];
wire uart_txd_int[1];
assign uart_txd = uart_txd_int[0];
assign uart_rxd_int[0] = uart_rxd;
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// Board configuration
.SW_CNT(4),
.LED_CNT(2),
.UART_CNT(UART_CNT),
.PORT_CNT(PORT_CNT),
.GTY_QUAD_CNT(GTY_QUAD_CNT),
.GTY_CNT(GTY_CNT),
.GTY_CLK_CNT(GTY_CLK_CNT),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_CLK_PER_NS_NUM(1024),
.PTP_CLK_PER_NS_DENOM(165),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
)
core_inst (
/*
* Clock: 125MHz
* Synchronous reset
*/
.clk_125mhz(clk_125mhz_int),
.rst_125mhz(rst_125mhz_int),
/*
* GPIO
*/
.sw('0),
.led(),
.port_led_act(),
.port_led_stat_r(dsfp_led_r),
.port_led_stat_g(dsfp_led_g),
.port_led_stat_b(dsfp_led_b),
.port_led_stat_y(),
/*
* UART
*/
.uart_txd(uart_txd_int),
.uart_rxd(uart_rxd_int),
/*
* Ethernet
*/
.eth_gty_tx_p(eth_gty_tx_p),
.eth_gty_tx_n(eth_gty_tx_n),
.eth_gty_rx_p(eth_gty_rx_p),
.eth_gty_rx_n(eth_gty_rx_n),
.eth_gty_mgt_refclk_p(eth_gty_mgt_refclk_p),
.eth_gty_mgt_refclk_n(eth_gty_mgt_refclk_n),
.eth_gty_mgt_refclk_out(eth_gty_mgt_refclk_out),
.eth_port_modsell(),
.eth_port_resetl(),
.eth_port_modprsl('0),
.eth_port_intl('0),
.eth_port_lpmode(),
/*
* PCIe
*/
.pcie_clk(pcie_user_clk),
.pcie_rst(pcie_user_rst),
.s_axis_pcie_cq(axis_pcie_cq),
.m_axis_pcie_cc(axis_pcie_cc),
.m_axis_pcie_rq(axis_pcie_rq),
.s_axis_pcie_rc(axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
// .cfg_interrupt_msix_enable(cfg_interrupt_msix_enable),
// .cfg_interrupt_msix_mask(cfg_interrupt_msix_mask),
// .cfg_interrupt_msix_vf_enable(cfg_interrupt_msix_vf_enable),
// .cfg_interrupt_msix_vf_mask(cfg_interrupt_msix_vf_mask),
// .cfg_interrupt_msix_address(cfg_interrupt_msix_address),
// .cfg_interrupt_msix_data(cfg_interrupt_msix_data),
// .cfg_interrupt_msix_int(cfg_interrupt_msix_int),
// .cfg_interrupt_msix_vec_pending(cfg_interrupt_msix_vec_pending),
// .cfg_interrupt_msix_vec_pending_status(cfg_interrupt_msix_vec_pending_status),
// .cfg_interrupt_msix_sent(cfg_interrupt_msix_sent),
// .cfg_interrupt_msix_fail(cfg_interrupt_msix_fail),
// .cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk_int),
.qspi_dq_i(qspi_dq_i_int),
.qspi_dq_o(qspi_dq_o_int),
.qspi_dq_oe(qspi_dq_oe_int),
.qspi_cs(qspi_cs_int)
);
endmodule
`resetall

View File

@@ -0,0 +1,86 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2020-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
TOPLEVEL_LANG = verilog
SIM ?= verilator
WAVES ?= 0
COCOTB_HDL_TIMEUNIT = 1ns
COCOTB_HDL_TIMEPRECISION = 1ps
RTL_DIR = ../../rtl
LIB_DIR = ../../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
DUT = fpga_core
COCOTB_TEST_MODULES = test_$(DUT)
COCOTB_TOPLEVEL = test_$(DUT)
MODULE = $(COCOTB_TEST_MODULES)
TOPLEVEL = $(COCOTB_TOPLEVEL)
VERILOG_SOURCES += $(COCOTB_TOPLEVEL).sv
VERILOG_SOURCES += $(RTL_DIR)/$(DUT).sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
VERILOG_SOURCES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
VERILOG_SOURCES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# handle file list files
process_f_file = $(call process_f_files,$(addprefix $(dir $1),$(shell cat $1)))
process_f_files = $(foreach f,$1,$(if $(filter %.f,$f),$(call process_f_file,$f),$f))
uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $(lastword $1)),$(notdir $f)),$f,))) $(lastword $1))
VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
# module parameters
export PARAM_SIM := "1'b1"
export PARAM_VENDOR := "\"XILINX\""
export PARAM_FAMILY := "\"virtexuplus\""
export PARAM_SW_CNT := 4
export PARAM_LED_CNT := 3
export PARAM_UART_CNT := 1
export PARAM_PORT_CNT := 2
export PARAM_PORT_LED_CNT := $(PARAM_PORT_CNT)
export PARAM_GTY_QUAD_CNT := $(PARAM_PORT_CNT)
export PARAM_GTY_CNT := $(shell echo $$(( 4 * $(PARAM_GTY_QUAD_CNT) )))
export PARAM_GTY_CLK_CNT := $(PARAM_GTY_QUAD_CNT)
# PTP configuration
export PARAM_PTP_TS_EN := 1
export PARAM_PTP_CLK_PER_NS_NUM := 32
export PARAM_PTP_CLK_PER_NS_DENOM := 5
# AXI lite interface configuration (control)
export PARAM_AXIL_CTRL_DATA_W := 32
export PARAM_AXIL_CTRL_ADDR_W := 24
# MAC configuration
export PARAM_CFG_LOW_LATENCY := 1
export PARAM_COMBINED_MAC_PCS := 1
export PARAM_MAC_DATA_W := "64"
ifeq ($(SIM), icarus)
PLUSARGS += -fst
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-P $(COCOTB_TOPLEVEL).$(subst PARAM_,,$(v))=$($(v)))
else ifeq ($(SIM), verilator)
COMPILE_ARGS += $(foreach v,$(filter PARAM_%,$(.VARIABLES)),-G$(subst PARAM_,,$(v))=$($(v)))
ifeq ($(WAVES), 1)
COMPILE_ARGS += --trace-fst
VERILATOR_TRACE = 1
endif
endif
include $(shell cocotb-config --makefiles)/Makefile.sim

View File

@@ -0,0 +1 @@
../../lib/taxi/src/eth/tb/baser.py

View File

@@ -0,0 +1 @@
../../lib/taxi/src/cndm/tb/cndm.py

View File

@@ -0,0 +1,547 @@
#!/usr/bin/env python
# SPDX-License-Identifier: MIT
"""
Copyright (c) 2020-2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
"""
import logging
import os
import sys
import pytest
import cocotb_test.simulator
import cocotb
from cocotb.clock import Clock
from cocotb.triggers import RisingEdge, FallingEdge, Timer
from cocotbext.axi import AxiStreamBus
from cocotbext.eth import XgmiiFrame
from cocotbext.uart import UartSource, UartSink
from cocotbext.pcie.core import RootComplex
from cocotbext.pcie.xilinx.us import UltraScalePlusPcieDevice
try:
from baser import BaseRSerdesSource, BaseRSerdesSink
import cndm
except ImportError:
# attempt import from current directory
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))
try:
from baser import BaseRSerdesSource, BaseRSerdesSink
import cndm
finally:
del sys.path[0]
class TB:
def __init__(self, dut):
self.dut = dut
self.log = logging.getLogger("cocotb.tb")
self.log.setLevel(logging.DEBUG)
# Clocks
cocotb.start_soon(Clock(dut.clk_125mhz, 8, units="ns").start())
# PCIe
self.rc = RootComplex()
self.rc.max_payload_size = 0x1 # 256 bytes
self.rc.max_read_request_size = 0x2 # 512 bytes
self.dev = UltraScalePlusPcieDevice(
# configuration options
pcie_generation=3,
pcie_link_width=16,
user_clk_frequency=250e6,
alignment="dword",
cq_straddle=False,
cc_straddle=False,
rq_straddle=False,
rc_straddle=False,
rc_4tlp_straddle=False,
pf_count=1,
max_payload_size=1024,
enable_client_tag=True,
enable_extended_tag=True,
enable_parity=False,
enable_rx_msg_interface=False,
enable_sriov=False,
enable_extended_configuration=False,
pf0_msi_enable=True,
pf0_msi_count=32,
pf1_msi_enable=False,
pf1_msi_count=1,
pf2_msi_enable=False,
pf2_msi_count=1,
pf3_msi_enable=False,
pf3_msi_count=1,
pf0_msix_enable=False,
pf0_msix_table_size=31,
pf0_msix_table_bir=4,
pf0_msix_table_offset=0x00000000,
pf0_msix_pba_bir=4,
pf0_msix_pba_offset=0x00008000,
pf1_msix_enable=False,
pf1_msix_table_size=0,
pf1_msix_table_bir=0,
pf1_msix_table_offset=0x00000000,
pf1_msix_pba_bir=0,
pf1_msix_pba_offset=0x00000000,
pf2_msix_enable=False,
pf2_msix_table_size=0,
pf2_msix_table_bir=0,
pf2_msix_table_offset=0x00000000,
pf2_msix_pba_bir=0,
pf2_msix_pba_offset=0x00000000,
pf3_msix_enable=False,
pf3_msix_table_size=0,
pf3_msix_table_bir=0,
pf3_msix_table_offset=0x00000000,
pf3_msix_pba_bir=0,
pf3_msix_pba_offset=0x00000000,
# signals
# Clock and Reset Interface
user_clk=dut.pcie_clk,
user_reset=dut.pcie_rst,
# user_lnk_up
# sys_clk
# sys_clk_gt
# sys_reset
# phy_rdy_out
# Requester reQuest Interface
rq_bus=AxiStreamBus.from_entity(dut.m_axis_pcie_rq),
pcie_rq_seq_num0=dut.pcie_rq_seq_num0,
pcie_rq_seq_num_vld0=dut.pcie_rq_seq_num_vld0,
pcie_rq_seq_num1=dut.pcie_rq_seq_num1,
pcie_rq_seq_num_vld1=dut.pcie_rq_seq_num_vld1,
# pcie_rq_tag0
# pcie_rq_tag1
# pcie_rq_tag_av
# pcie_rq_tag_vld0
# pcie_rq_tag_vld1
# Requester Completion Interface
rc_bus=AxiStreamBus.from_entity(dut.s_axis_pcie_rc),
# Completer reQuest Interface
cq_bus=AxiStreamBus.from_entity(dut.s_axis_pcie_cq),
# pcie_cq_np_req
# pcie_cq_np_req_count
# Completer Completion Interface
cc_bus=AxiStreamBus.from_entity(dut.m_axis_pcie_cc),
# Transmit Flow Control Interface
# pcie_tfc_nph_av=dut.pcie_tfc_nph_av,
# pcie_tfc_npd_av=dut.pcie_tfc_npd_av,
# Configuration Management Interface
cfg_mgmt_addr=dut.cfg_mgmt_addr,
cfg_mgmt_function_number=dut.cfg_mgmt_function_number,
cfg_mgmt_write=dut.cfg_mgmt_write,
cfg_mgmt_write_data=dut.cfg_mgmt_write_data,
cfg_mgmt_byte_enable=dut.cfg_mgmt_byte_enable,
cfg_mgmt_read=dut.cfg_mgmt_read,
cfg_mgmt_read_data=dut.cfg_mgmt_read_data,
cfg_mgmt_read_write_done=dut.cfg_mgmt_read_write_done,
# cfg_mgmt_debug_access
# Configuration Status Interface
# cfg_phy_link_down
# cfg_phy_link_status
# cfg_negotiated_width
# cfg_current_speed
cfg_max_payload=dut.cfg_max_payload,
cfg_max_read_req=dut.cfg_max_read_req,
# cfg_function_status
# cfg_vf_status
# cfg_function_power_state
# cfg_vf_power_state
# cfg_link_power_state
# cfg_err_cor_out
# cfg_err_nonfatal_out
# cfg_err_fatal_out
# cfg_local_error_out
# cfg_local_error_valid
# cfg_rx_pm_state
# cfg_tx_pm_state
# cfg_ltssm_state
cfg_rcb_status=dut.cfg_rcb_status,
# cfg_obff_enable
# cfg_pl_status_change
# cfg_tph_requester_enable
# cfg_tph_st_mode
# cfg_vf_tph_requester_enable
# cfg_vf_tph_st_mode
# Configuration Received Message Interface
# cfg_msg_received
# cfg_msg_received_data
# cfg_msg_received_type
# Configuration Transmit Message Interface
# cfg_msg_transmit
# cfg_msg_transmit_type
# cfg_msg_transmit_data
# cfg_msg_transmit_done
# Configuration Flow Control Interface
cfg_fc_ph=dut.cfg_fc_ph,
cfg_fc_pd=dut.cfg_fc_pd,
cfg_fc_nph=dut.cfg_fc_nph,
cfg_fc_npd=dut.cfg_fc_npd,
cfg_fc_cplh=dut.cfg_fc_cplh,
cfg_fc_cpld=dut.cfg_fc_cpld,
cfg_fc_sel=dut.cfg_fc_sel,
# Configuration Control Interface
# cfg_hot_reset_in
# cfg_hot_reset_out
# cfg_config_space_enable
# cfg_dsn
# cfg_bus_number
# cfg_ds_port_number
# cfg_ds_bus_number
# cfg_ds_device_number
# cfg_ds_function_number
# cfg_power_state_change_ack
# cfg_power_state_change_interrupt
# cfg_err_cor_in=dut.status_error_cor,
# cfg_err_uncor_in=dut.status_error_uncor,
# cfg_flr_in_process
# cfg_flr_done
# cfg_vf_flr_in_process
# cfg_vf_flr_func_num
# cfg_vf_flr_done
# cfg_pm_aspm_l1_entry_reject
# cfg_pm_aspm_tx_l0s_entry_disable
# cfg_req_pm_transition_l23_ready
# cfg_link_training_enable
# Configuration Interrupt Controller Interface
# cfg_interrupt_int
# cfg_interrupt_sent
# cfg_interrupt_pending
cfg_interrupt_msi_enable=dut.cfg_interrupt_msi_enable,
cfg_interrupt_msi_mmenable=dut.cfg_interrupt_msi_mmenable,
cfg_interrupt_msi_mask_update=dut.cfg_interrupt_msi_mask_update,
cfg_interrupt_msi_data=dut.cfg_interrupt_msi_data,
cfg_interrupt_msi_select=dut.cfg_interrupt_msi_select,
cfg_interrupt_msi_int=dut.cfg_interrupt_msi_int,
cfg_interrupt_msi_pending_status=dut.cfg_interrupt_msi_pending_status,
cfg_interrupt_msi_pending_status_data_enable=dut.cfg_interrupt_msi_pending_status_data_enable,
cfg_interrupt_msi_pending_status_function_num=dut.cfg_interrupt_msi_pending_status_function_num,
cfg_interrupt_msi_sent=dut.cfg_interrupt_msi_sent,
cfg_interrupt_msi_fail=dut.cfg_interrupt_msi_fail,
# cfg_interrupt_msix_enable=dut.cfg_interrupt_msix_enable,
# cfg_interrupt_msix_mask=dut.cfg_interrupt_msix_mask,
# cfg_interrupt_msix_vf_enable=dut.cfg_interrupt_msix_vf_enable,
# cfg_interrupt_msix_vf_mask=dut.cfg_interrupt_msix_vf_mask,
# cfg_interrupt_msix_address=dut.cfg_interrupt_msix_address,
# cfg_interrupt_msix_data=dut.cfg_interrupt_msix_data,
# cfg_interrupt_msix_int=dut.cfg_interrupt_msix_int,
# cfg_interrupt_msix_vec_pending=dut.cfg_interrupt_msix_vec_pending,
# cfg_interrupt_msix_vec_pending_status=dut.cfg_interrupt_msix_vec_pending_status,
# cfg_interrupt_msix_sent=dut.cfg_interrupt_msix_sent,
# cfg_interrupt_msix_fail=dut.cfg_interrupt_msix_fail,
cfg_interrupt_msi_attr=dut.cfg_interrupt_msi_attr,
cfg_interrupt_msi_tph_present=dut.cfg_interrupt_msi_tph_present,
cfg_interrupt_msi_tph_type=dut.cfg_interrupt_msi_tph_type,
cfg_interrupt_msi_tph_st_tag=dut.cfg_interrupt_msi_tph_st_tag,
cfg_interrupt_msi_function_number=dut.cfg_interrupt_msi_function_number,
# Configuration Extend Interface
# cfg_ext_read_received
# cfg_ext_write_received
# cfg_ext_register_number
# cfg_ext_function_number
# cfg_ext_write_data
# cfg_ext_write_byte_enable
# cfg_ext_read_data
# cfg_ext_read_data_valid
)
# self.dev.log.setLevel(logging.DEBUG)
self.rc.make_port().connect(self.dev)
self.dev.functions[0].configure_bar(0, 2**int(dut.uut.cndm_inst.axil_ctrl_bar.ADDR_W))
# UART
self.uart_sources = []
self.uart_sinks = []
for sig in dut.uart_rxd:
self.uart_sources.append(UartSource(sig, baud=3000000, bits=8, stop_bits=1))
for sig in dut.uart_txd:
self.uart_sinks.append(UartSink(sig, baud=3000000, bits=8, stop_bits=1))
# Ethernet
for clk in dut.eth_gty_mgt_refclk_p:
cocotb.start_soon(Clock(clk, 6.4, units="ns").start())
self.qsfp_sources = []
self.qsfp_sinks = []
for inst in dut.uut.gty_quad:
for ch in inst.mac_inst.ch:
gt_inst = ch.ch_inst.gt.gt_inst
if ch.ch_inst.DATA_W.value == 64:
if ch.ch_inst.CFG_LOW_LATENCY.value:
clk = 2.482
gbx_cfg = (66, [64, 65])
else:
clk = 2.56
gbx_cfg = None
else:
if ch.ch_inst.CFG_LOW_LATENCY.value:
clk = 3.102
gbx_cfg = (66, [64, 65])
else:
clk = 3.2
gbx_cfg = None
cocotb.start_soon(Clock(gt_inst.tx_clk, clk, units="ns").start())
cocotb.start_soon(Clock(gt_inst.rx_clk, clk, units="ns").start())
self.qsfp_sources.append(BaseRSerdesSource(
data=gt_inst.serdes_rx_data,
data_valid=gt_inst.serdes_rx_data_valid,
hdr=gt_inst.serdes_rx_hdr,
hdr_valid=gt_inst.serdes_rx_hdr_valid,
clock=gt_inst.rx_clk,
slip=gt_inst.serdes_rx_bitslip,
reverse=True,
gbx_cfg=gbx_cfg
))
self.qsfp_sinks.append(BaseRSerdesSink(
data=gt_inst.serdes_tx_data,
data_valid=gt_inst.serdes_tx_data_valid,
hdr=gt_inst.serdes_tx_hdr,
hdr_valid=gt_inst.serdes_tx_hdr_valid,
gbx_sync=gt_inst.serdes_tx_gbx_sync,
clock=gt_inst.tx_clk,
reverse=True,
gbx_cfg=gbx_cfg
))
dut.sw.setimmediatevalue(0)
dut.eth_port_modprsl.setimmediatevalue(0)
dut.eth_port_intl.setimmediatevalue(0)
self.loopback_enable = False
cocotb.start_soon(self._run_loopback())
async def init(self):
self.dut.rst_125mhz.setimmediatevalue(0)
await FallingEdge(self.dut.pcie_rst)
await Timer(100, 'ns')
for k in range(10):
await RisingEdge(self.dut.clk_125mhz)
self.dut.rst_125mhz.value = 1
for k in range(10):
await RisingEdge(self.dut.clk_125mhz)
self.dut.rst_125mhz.value = 0
for k in range(10):
await RisingEdge(self.dut.clk_125mhz)
await self.rc.enumerate()
async def _run_loopback(self):
while True:
await RisingEdge(self.dut.pcie_clk)
if self.loopback_enable:
for src, snk in zip(self.qsfp_sources, self.qsfp_sinks):
while not snk.empty():
await src.send(await snk.recv())
@cocotb.test()
async def run_test(dut):
tb = TB(dut)
await tb.init()
tb.log.info("Init driver model")
driver = cndm.Driver()
await driver.init_pcie_dev(tb.rc.find_device(tb.dev.functions[0].pcie_id))
tb.log.info("Init complete")
tb.log.info("Wait for block lock")
for k in range(1200):
await RisingEdge(tb.dut.clk_125mhz)
for snk in tb.qsfp_sinks:
snk.clear()
tb.log.info("Send and receive single packet on each port")
for k in range(len(driver.ports)):
data = f"Corundum rocks on port {k}!".encode('ascii')
await driver.ports[k].start_xmit(data)
pkt = await tb.qsfp_sinks[k].recv()
tb.log.info("Got TX packet: %s", pkt)
assert pkt.get_payload() == data.ljust(60, b'\x00')
assert pkt.check_fcs()
await tb.qsfp_sources[k].send(pkt)
pkt = await driver.ports[k].recv()
tb.log.info("Got RX packet: %s", pkt)
assert bytes(pkt) == data.ljust(60, b'\x00')
tb.log.info("Multiple small packets")
count = 64
pkts = [bytearray([(x+k) % 256 for x in range(60)]) for k in range(count)]
tb.loopback_enable = True
for p in pkts:
await driver.ports[0].start_xmit(p)
for k in range(count):
pkt = await driver.ports[0].recv()
tb.log.info("Got RX packet: %s", pkt)
assert bytes(pkt) == pkts[k].ljust(60, b'\x00')
tb.loopback_enable = False
tb.log.info("Multiple large packets")
count = 64
pkts = [bytearray([(x+k) % 256 for x in range(1514)]) for k in range(count)]
tb.loopback_enable = True
for p in pkts:
await driver.ports[0].start_xmit(p)
for k in range(count):
pkt = await driver.ports[0].recv()
tb.log.info("Got RX packet: %s", pkt)
assert bytes(pkt) == pkts[k].ljust(60, b'\x00')
tb.loopback_enable = False
await RisingEdge(dut.clk_125mhz)
await RisingEdge(dut.clk_125mhz)
# cocotb-test
tests_dir = os.path.abspath(os.path.dirname(__file__))
rtl_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'rtl'))
lib_dir = os.path.abspath(os.path.join(tests_dir, '..', '..', 'lib'))
taxi_src_dir = os.path.abspath(os.path.join(lib_dir, 'taxi', 'src'))
def process_f_files(files):
lst = {}
for f in files:
if f[-2:].lower() == '.f':
with open(f, 'r') as fp:
l = fp.read().split()
for f in process_f_files([os.path.join(os.path.dirname(f), x) for x in l]):
lst[os.path.basename(f)] = f
else:
lst[os.path.basename(f)] = f
return list(lst.values())
@pytest.mark.parametrize("mac_data_w", [32, 64])
def test_fpga_core(request, mac_data_w):
dut = "fpga_core"
module = os.path.splitext(os.path.basename(__file__))[0]
toplevel = module
verilog_sources = [
os.path.join(tests_dir, f"{toplevel}.sv"),
os.path.join(rtl_dir, f"{dut}.sv"),
os.path.join(taxi_src_dir, "cndm", "rtl", "cndm_micro_pcie_us.f"),
os.path.join(taxi_src_dir, "eth", "rtl", "us", "taxi_eth_mac_25g_us.f"),
os.path.join(taxi_src_dir, "xfcp", "rtl", "taxi_xfcp_if_uart.f"),
os.path.join(taxi_src_dir, "xfcp", "rtl", "taxi_xfcp_switch.sv"),
os.path.join(taxi_src_dir, "xfcp", "rtl", "taxi_xfcp_mod_apb.f"),
os.path.join(taxi_src_dir, "xfcp", "rtl", "taxi_xfcp_mod_stats.f"),
os.path.join(taxi_src_dir, "axis", "rtl", "taxi_axis_async_fifo.f"),
os.path.join(taxi_src_dir, "sync", "rtl", "taxi_sync_reset.sv"),
os.path.join(taxi_src_dir, "sync", "rtl", "taxi_sync_signal.sv"),
os.path.join(taxi_src_dir, "io", "rtl", "taxi_debounce_switch.sv"),
os.path.join(taxi_src_dir, "pyrite", "rtl", "pyrite_pcie_us_vpd_qspi.f"),
]
verilog_sources = process_f_files(verilog_sources)
parameters = {}
parameters['SIM'] = "1'b1"
parameters['VENDOR'] = "\"XILINX\""
parameters['FAMILY'] = "\"virtexuplus\""
parameters['SW_CNT'] = 4
parameters['LED_CNT'] = 3
parameters['UART_CNT'] = 1
parameters['PORT_CNT'] = 2
parameters['PORT_LED_CNT'] = parameters['PORT_CNT']
parameters['GTY_QUAD_CNT'] = parameters['PORT_CNT']
parameters['GTY_CNT'] = parameters['GTY_QUAD_CNT']*4
parameters['GTY_CLK_CNT'] = parameters['GTY_QUAD_CNT']
# PTP configuration
parameters['PTP_TS_EN'] = 1
parameters['PTP_CLK_PER_NS_NUM'] = 32
parameters['PTP_CLK_PER_NS_DENOM'] = 5
# AXI lite interface configuration (control)
parameters['AXIL_CTRL_DATA_W'] = 32
parameters['AXIL_CTRL_ADDR_W'] = 24
# MAC configuration
parameters['CFG_LOW_LATENCY'] = 1
parameters['COMBINED_MAC_PCS'] = 1
parameters['MAC_DATA_W'] = mac_data_w
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
sim_build = os.path.join(tests_dir, "sim_build",
request.node.name.replace('[', '-').replace(']', ''))
cocotb_test.simulator.run(
simulator="verilator",
python_search=[tests_dir],
verilog_sources=verilog_sources,
toplevel=toplevel,
module=module,
parameters=parameters,
sim_build=sim_build,
extra_env=extra_env,
)

View File

@@ -0,0 +1,349 @@
// SPDX-License-Identifier: MIT
/*
Copyright (c) 2026 FPGA Ninja, LLC
Authors:
- Alex Forencich
*/
`resetall
`timescale 1ns / 1ps
`default_nettype none
/*
* FPGA core logic testbench
*/
module test_fpga_core #
(
/* verilator lint_off WIDTHTRUNC */
parameter logic SIM = 1'b0,
parameter string VENDOR = "XILINX",
parameter string FAMILY = "virtexuplus",
// Board configuration
parameter SW_CNT = 4,
parameter LED_CNT = 3,
parameter UART_CNT = 1,
parameter PORT_CNT = 2,
parameter PORT_LED_CNT = PORT_CNT,
parameter GTY_QUAD_CNT = PORT_CNT,
parameter GTY_CNT = GTY_QUAD_CNT*4,
parameter GTY_CLK_CNT = GTY_QUAD_CNT,
// FW ID
parameter FPGA_ID = 32'h4B37093,
parameter FW_ID = 32'h0000C001,
parameter FW_VER = 32'h000_01_000,
parameter BOARD_ID = 32'h10ee_90c8,
parameter BOARD_VER = 32'h001_00_000,
parameter BUILD_DATE = 32'd602976000,
parameter GIT_HASH = 32'h5f87c2e8,
parameter RELEASE_INFO = 32'h00000000,
// PTP configuration
parameter logic PTP_TS_EN = 1'b1,
parameter PTP_CLK_PER_NS_NUM = 32,
parameter PTP_CLK_PER_NS_DENOM = 5,
// PCIe interface configuration
parameter AXIS_PCIE_DATA_W = 512,
parameter AXIS_PCIE_RC_USER_W = AXIS_PCIE_DATA_W < 512 ? 75 : 161,
parameter AXIS_PCIE_RQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 62 : 137,
parameter AXIS_PCIE_CQ_USER_W = AXIS_PCIE_DATA_W < 512 ? 85 : 183,
parameter AXIS_PCIE_CC_USER_W = AXIS_PCIE_DATA_W < 512 ? 33 : 81,
// AXI lite interface configuration (control)
parameter AXIL_CTRL_DATA_W = 32,
parameter AXIL_CTRL_ADDR_W = 24,
// MAC configuration
parameter logic CFG_LOW_LATENCY = 1'b1,
parameter logic COMBINED_MAC_PCS = 1'b1,
parameter MAC_DATA_W = 64
/* verilator lint_on WIDTHTRUNC */
)
();
localparam AXIS_PCIE_KEEP_W = (AXIS_PCIE_DATA_W/32);
localparam RQ_SEQ_NUM_W = AXIS_PCIE_RQ_USER_W == 60 ? 4 : 6;
logic clk_125mhz;
logic rst_125mhz;
logic [SW_CNT-1:0] sw;
logic [LED_CNT-1:0] led;
logic [PORT_LED_CNT-1:0] port_led_act;
logic [PORT_LED_CNT-1:0] port_led_stat_r;
logic [PORT_LED_CNT-1:0] port_led_stat_g;
logic [PORT_LED_CNT-1:0] port_led_stat_b;
logic [PORT_LED_CNT-1:0] port_led_stat_y;
logic uart_txd[UART_CNT-1:0];
logic uart_rxd[UART_CNT-1:0];
logic eth_gty_mgt_refclk_p[GTY_CLK_CNT];
logic eth_gty_mgt_refclk_n[GTY_CLK_CNT];
logic eth_gty_mgt_refclk_out[GTY_CLK_CNT];
logic [PORT_CNT-1:0] eth_port_modsell;
logic [PORT_CNT-1:0] eth_port_resetl;
logic [PORT_CNT-1:0] eth_port_modprsl;
logic [PORT_CNT-1:0] eth_port_intl;
logic [PORT_CNT-1:0] eth_port_lpmode;
logic pcie_clk;
logic pcie_rst;
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CQ_USER_W)
) s_axis_pcie_cq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_CC_USER_W)
) m_axis_pcie_cc();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RQ_USER_W)
) m_axis_pcie_rq();
taxi_axis_if #(
.DATA_W(AXIS_PCIE_DATA_W),
.KEEP_EN(1),
.KEEP_W(AXIS_PCIE_KEEP_W),
.USER_EN(1),
.USER_W(AXIS_PCIE_RC_USER_W)
) s_axis_pcie_rc();
logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num0;
logic pcie_rq_seq_num_vld0;
logic [RQ_SEQ_NUM_W-1:0] pcie_rq_seq_num1;
logic pcie_rq_seq_num_vld1;
logic [2:0] cfg_max_payload;
logic [2:0] cfg_max_read_req;
logic [3:0] cfg_rcb_status;
logic [9:0] cfg_mgmt_addr;
logic [7:0] cfg_mgmt_function_number;
logic cfg_mgmt_write;
logic [31:0] cfg_mgmt_write_data;
logic [3:0] cfg_mgmt_byte_enable;
logic cfg_mgmt_read;
logic [31:0] cfg_mgmt_read_data;
logic cfg_mgmt_read_write_done;
logic [7:0] cfg_fc_ph;
logic [11:0] cfg_fc_pd;
logic [7:0] cfg_fc_nph;
logic [11:0] cfg_fc_npd;
logic [7:0] cfg_fc_cplh;
logic [11:0] cfg_fc_cpld;
logic [2:0] cfg_fc_sel;
logic cfg_ext_read_received;
logic cfg_ext_write_received;
logic [9:0] cfg_ext_register_number;
logic [7:0] cfg_ext_function_number;
logic [31:0] cfg_ext_write_data;
logic [3:0] cfg_ext_write_byte_enable;
logic [31:0] cfg_ext_read_data;
logic cfg_ext_read_data_valid;
logic [3:0] cfg_interrupt_msi_enable;
logic [11:0] cfg_interrupt_msi_mmenable;
logic cfg_interrupt_msi_mask_update;
logic [31:0] cfg_interrupt_msi_data;
logic [1:0] cfg_interrupt_msi_select;
logic [31:0] cfg_interrupt_msi_int;
logic [31:0] cfg_interrupt_msi_pending_status;
logic cfg_interrupt_msi_pending_status_data_enable;
logic [1:0] cfg_interrupt_msi_pending_status_function_num;
logic cfg_interrupt_msi_sent;
logic cfg_interrupt_msi_fail;
logic [2:0] cfg_interrupt_msi_attr;
logic cfg_interrupt_msi_tph_present;
logic [1:0] cfg_interrupt_msi_tph_type;
logic [7:0] cfg_interrupt_msi_tph_st_tag;
logic [7:0] cfg_interrupt_msi_function_number;
logic fpga_boot;
logic qspi_clk;
logic [3:0] qspi_dq_i;
logic [3:0] qspi_dq_o;
logic [3:0] qspi_dq_oe;
logic qspi_cs;
fpga_core #(
.SIM(SIM),
.VENDOR(VENDOR),
.FAMILY(FAMILY),
// Board configuration
.SW_CNT(SW_CNT),
.LED_CNT(LED_CNT),
.UART_CNT(UART_CNT),
.PORT_CNT(PORT_CNT),
.PORT_LED_CNT(PORT_LED_CNT),
.GTY_QUAD_CNT(GTY_QUAD_CNT),
.GTY_CNT(GTY_CNT),
.GTY_CLK_CNT(GTY_CLK_CNT),
// FW ID
.FPGA_ID(FPGA_ID),
.FW_ID(FW_ID),
.FW_VER(FW_VER),
.BOARD_ID(BOARD_ID),
.BOARD_VER(BOARD_VER),
.BUILD_DATE(BUILD_DATE),
.GIT_HASH(GIT_HASH),
.RELEASE_INFO(RELEASE_INFO),
// PTP configuration
.PTP_TS_EN(PTP_TS_EN),
.PTP_CLK_PER_NS_NUM(PTP_CLK_PER_NS_NUM),
.PTP_CLK_PER_NS_DENOM(PTP_CLK_PER_NS_DENOM),
// PCIe interface configuration
.RQ_SEQ_NUM_W(RQ_SEQ_NUM_W),
// AXI lite interface configuration (control)
.AXIL_CTRL_DATA_W(AXIL_CTRL_DATA_W),
.AXIL_CTRL_ADDR_W(AXIL_CTRL_ADDR_W),
// MAC configuration
.CFG_LOW_LATENCY(CFG_LOW_LATENCY),
.COMBINED_MAC_PCS(COMBINED_MAC_PCS),
.MAC_DATA_W(MAC_DATA_W)
)
uut (
/*
* Clock: 125MHz
* Synchronous reset
*/
.clk_125mhz(clk_125mhz),
.rst_125mhz(rst_125mhz),
/*
* GPIO
*/
.sw(sw),
.led(led),
.port_led_act(port_led_act),
.port_led_stat_r(port_led_stat_r),
.port_led_stat_g(port_led_stat_g),
.port_led_stat_b(port_led_stat_b),
.port_led_stat_y(port_led_stat_y),
/*
* UART
*/
.uart_txd(uart_txd),
.uart_rxd(uart_rxd),
/*
* Ethernet
*/
.eth_gty_tx_p(),
.eth_gty_tx_n(),
.eth_gty_rx_p('{GTY_CNT{1'b0}}),
.eth_gty_rx_n('{GTY_CNT{1'b0}}),
.eth_gty_mgt_refclk_p(eth_gty_mgt_refclk_p),
.eth_gty_mgt_refclk_n(eth_gty_mgt_refclk_n),
.eth_gty_mgt_refclk_out(eth_gty_mgt_refclk_out),
.eth_port_modsell(eth_port_modsell),
.eth_port_resetl(eth_port_resetl),
.eth_port_modprsl(eth_port_modprsl),
.eth_port_intl(eth_port_intl),
.eth_port_lpmode(eth_port_lpmode),
/*
* PCIe
*/
.pcie_clk(pcie_clk),
.pcie_rst(pcie_rst),
.s_axis_pcie_cq(s_axis_pcie_cq),
.m_axis_pcie_cc(m_axis_pcie_cc),
.m_axis_pcie_rq(m_axis_pcie_rq),
.s_axis_pcie_rc(s_axis_pcie_rc),
.pcie_rq_seq_num0(pcie_rq_seq_num0),
.pcie_rq_seq_num_vld0(pcie_rq_seq_num_vld0),
.pcie_rq_seq_num1(pcie_rq_seq_num1),
.pcie_rq_seq_num_vld1(pcie_rq_seq_num_vld1),
.cfg_max_payload(cfg_max_payload),
.cfg_max_read_req(cfg_max_read_req),
.cfg_rcb_status(cfg_rcb_status),
.cfg_mgmt_addr(cfg_mgmt_addr),
.cfg_mgmt_function_number(cfg_mgmt_function_number),
.cfg_mgmt_write(cfg_mgmt_write),
.cfg_mgmt_write_data(cfg_mgmt_write_data),
.cfg_mgmt_byte_enable(cfg_mgmt_byte_enable),
.cfg_mgmt_read(cfg_mgmt_read),
.cfg_mgmt_read_data(cfg_mgmt_read_data),
.cfg_mgmt_read_write_done(cfg_mgmt_read_write_done),
.cfg_fc_ph(cfg_fc_ph),
.cfg_fc_pd(cfg_fc_pd),
.cfg_fc_nph(cfg_fc_nph),
.cfg_fc_npd(cfg_fc_npd),
.cfg_fc_cplh(cfg_fc_cplh),
.cfg_fc_cpld(cfg_fc_cpld),
.cfg_fc_sel(cfg_fc_sel),
.cfg_ext_read_received(cfg_ext_read_received),
.cfg_ext_write_received(cfg_ext_write_received),
.cfg_ext_register_number(cfg_ext_register_number),
.cfg_ext_function_number(cfg_ext_function_number),
.cfg_ext_write_data(cfg_ext_write_data),
.cfg_ext_write_byte_enable(cfg_ext_write_byte_enable),
.cfg_ext_read_data(cfg_ext_read_data),
.cfg_ext_read_data_valid(cfg_ext_read_data_valid),
.cfg_interrupt_msi_enable(cfg_interrupt_msi_enable),
.cfg_interrupt_msi_mmenable(cfg_interrupt_msi_mmenable),
.cfg_interrupt_msi_mask_update(cfg_interrupt_msi_mask_update),
.cfg_interrupt_msi_data(cfg_interrupt_msi_data),
.cfg_interrupt_msi_select(cfg_interrupt_msi_select),
.cfg_interrupt_msi_int(cfg_interrupt_msi_int),
.cfg_interrupt_msi_pending_status(cfg_interrupt_msi_pending_status),
.cfg_interrupt_msi_pending_status_data_enable(cfg_interrupt_msi_pending_status_data_enable),
.cfg_interrupt_msi_pending_status_function_num(cfg_interrupt_msi_pending_status_function_num),
.cfg_interrupt_msi_sent(cfg_interrupt_msi_sent),
.cfg_interrupt_msi_fail(cfg_interrupt_msi_fail),
.cfg_interrupt_msi_attr(cfg_interrupt_msi_attr),
.cfg_interrupt_msi_tph_present(cfg_interrupt_msi_tph_present),
.cfg_interrupt_msi_tph_type(cfg_interrupt_msi_tph_type),
.cfg_interrupt_msi_tph_st_tag(cfg_interrupt_msi_tph_st_tag),
.cfg_interrupt_msi_function_number(cfg_interrupt_msi_function_number),
/*
* QSPI flash
*/
.fpga_boot(fpga_boot),
.qspi_clk(qspi_clk),
.qspi_dq_i(qspi_dq_i),
.qspi_dq_o(qspi_dq_o),
.qspi_dq_oe(qspi_dq_oe),
.qspi_cs(qspi_cs)
);
endmodule
`resetall

View File

@@ -0,0 +1,35 @@
# Corundum for RK-XCKU5P-F
## Introduction
This design targets the RK-XCKU5P-F FPGA board.
* USB UART
* XFCP (3 Mbaud)
* QSFP28 cage
* 10GBASE-R or 25GBASE-R MAC via GTY transceiver
## Board details
* FPGA: xcku5p-ffvb676-2-e
* USB UART: FTDI FT2232
* PCIe: gen 3 x4 (~32 Gbps)
* Reference oscillator: Fixed 156.25 MHz
* 25GBASE-R PHY: Soft PCS with GTY transceiver
## Licensing
* Toolchain
* Vivado Standard (enterprise license not required)
* IP
* No licensed vendor IP or 3rd party IP
## How to build
Run `make` in the appropriate `fpga*` subdirectory to build the bitstream. Ensure that the Xilinx Vivado toolchain components are in PATH.
On the host system, run `make` in `modules/cndm` to build the driver. Ensure that the headers for the running kernel are installed, otherwise the driver cannot be compiled.
## How to test
Run `make program` to program the board with Vivado. Then, reboot the machine to re-enumerate the PCIe bus. Finally, load the driver on the host system with `insmod cndm.ko`. Check `dmesg` for output from driver initialization. Run `cndm_ddcmd.sh =p` to enable all debug messages.

View File

@@ -0,0 +1,153 @@
# SPDX-License-Identifier: MIT
###################################################################
#
# Xilinx Vivado FPGA Makefile
#
# Copyright (c) 2016-2025 Alex Forencich
#
###################################################################
#
# Parameters:
# FPGA_TOP - Top module name
# FPGA_FAMILY - FPGA family (e.g. VirtexUltrascale)
# FPGA_DEVICE - FPGA device (e.g. xcvu095-ffva2104-2-e)
# SYN_FILES - list of source files
# INC_FILES - list of include files
# XDC_FILES - list of timing constraint files
# XCI_FILES - list of IP XCI files
# IP_TCL_FILES - list of IP TCL files (sourced during project creation)
# CONFIG_TCL_FILES - list of config TCL files (sourced before each build)
#
# Note: both SYN_FILES and INC_FILES support file list files. File list
# files are files with a .f extension that contain a list of additional
# files to include, one path relative to the .f file location per line.
# The .f files are processed recursively, and then the complete file list
# is de-duplicated, with later files in the list taking precedence.
#
# Example:
#
# FPGA_TOP = fpga
# FPGA_FAMILY = VirtexUltrascale
# FPGA_DEVICE = xcvu095-ffva2104-2-e
# SYN_FILES = rtl/fpga.v
# XDC_FILES = fpga.xdc
# XCI_FILES = ip/pcspma.xci
# include ../common/vivado.mk
#
###################################################################
# phony targets
.PHONY: fpga vivado tmpclean clean distclean
# prevent make from deleting intermediate files and reports
.PRECIOUS: %.xpr %.bit %.bin %.ltx %.xsa %.mcs %.prm
.SECONDARY:
CONFIG ?= config.mk
-include $(CONFIG)
FPGA_TOP ?= fpga
PROJECT ?= $(FPGA_TOP)
XDC_FILES ?= $(PROJECT).xdc
# handle file list files
process_f_file = $(call process_f_files,$(addprefix $(dir $1),$(shell cat $1)))
process_f_files = $(foreach f,$1,$(if $(filter %.f,$f),$(call process_f_file,$f),$f))
uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $(lastword $1)),$(notdir $f)),$f,))) $(lastword $1))
SYN_FILES := $(call uniq_base,$(call process_f_files,$(SYN_FILES)))
INC_FILES := $(call uniq_base,$(call process_f_files,$(INC_FILES)))
###################################################################
# Main Targets
#
# all: build everything (fpga)
# fpga: build FPGA config
# vivado: open project in Vivado
# tmpclean: remove intermediate files
# clean: remove output files and project files
# distclean: remove archived output files
###################################################################
all: fpga
fpga: $(PROJECT).bit
vivado: $(PROJECT).xpr
vivado $(PROJECT).xpr
tmpclean::
-rm -rf *.log *.jou *.cache *.gen *.hbs *.hw *.ip_user_files *.runs *.xpr *.html *.xml *.sim *.srcs *.str .Xil defines.v
-rm -rf create_project.tcl update_config.tcl run_synth.tcl run_impl.tcl generate_bit.tcl
clean:: tmpclean
-rm -rf *.bit *.bin *.ltx *.xsa program.tcl generate_mcs.tcl *.mcs *.prm flash.tcl
-rm -rf *_utilization.rpt *_utilization_hierarchical.rpt
distclean:: clean
-rm -rf rev
###################################################################
# Target implementations
###################################################################
# Vivado project file
# create fresh project if Makefile or IP files have changed
create_project.tcl: Makefile $(XCI_FILES) $(IP_TCL_FILES)
rm -rf defines.v
touch defines.v
for x in $(DEFS); do echo '`define' $$x >> defines.v; done
echo "create_project -force -part $(FPGA_PART) $(PROJECT)" > $@
echo "add_files -fileset sources_1 defines.v $(SYN_FILES)" >> $@
echo "set_property top $(FPGA_TOP) [current_fileset]" >> $@
echo "add_files -fileset constrs_1 $(XDC_FILES)" >> $@
for x in $(XCI_FILES); do echo "import_ip $$x" >> $@; done
for x in $(IP_TCL_FILES); do echo "source $$x" >> $@; done
for x in $(CONFIG_TCL_FILES); do echo "source $$x" >> $@; done
# source config TCL scripts if any source file has changed
update_config.tcl: $(CONFIG_TCL_FILES) $(SYN_FILES) $(INC_FILES) $(XDC_FILES)
echo "open_project -quiet $(PROJECT).xpr" > $@
for x in $(CONFIG_TCL_FILES); do echo "source $$x" >> $@; done
$(PROJECT).xpr: create_project.tcl update_config.tcl
vivado -nojournal -nolog -mode batch $(foreach x,$?,-source $x)
# synthesis run
$(PROJECT).runs/synth_1/$(PROJECT).dcp: create_project.tcl update_config.tcl $(SYN_FILES) $(INC_FILES) $(XDC_FILES) | $(PROJECT).xpr
echo "open_project $(PROJECT).xpr" > run_synth.tcl
echo "reset_run synth_1" >> run_synth.tcl
echo "launch_runs -jobs 4 synth_1" >> run_synth.tcl
echo "wait_on_run synth_1" >> run_synth.tcl
vivado -nojournal -nolog -mode batch -source run_synth.tcl
# implementation run
$(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp: $(PROJECT).runs/synth_1/$(PROJECT).dcp
echo "open_project $(PROJECT).xpr" > run_impl.tcl
echo "reset_run impl_1" >> run_impl.tcl
echo "launch_runs -jobs 4 impl_1" >> run_impl.tcl
echo "wait_on_run impl_1" >> run_impl.tcl
echo "open_run impl_1" >> run_impl.tcl
echo "report_utilization -file $(PROJECT)_utilization.rpt" >> run_impl.tcl
echo "report_utilization -hierarchical -file $(PROJECT)_utilization_hierarchical.rpt" >> run_impl.tcl
vivado -nojournal -nolog -mode batch -source run_impl.tcl
# output files (including potentially bit, bin, ltx, and xsa)
$(PROJECT).bit $(PROJECT).bin $(PROJECT).ltx $(PROJECT).xsa: $(PROJECT).runs/impl_1/$(PROJECT)_routed.dcp
echo "open_project $(PROJECT).xpr" > generate_bit.tcl
echo "open_run impl_1" >> generate_bit.tcl
echo "write_bitstream -force -bin_file $(PROJECT).runs/impl_1/$(PROJECT).bit" >> generate_bit.tcl
echo "write_debug_probes -force $(PROJECT).runs/impl_1/$(PROJECT).ltx" >> generate_bit.tcl
echo "write_hw_platform -fixed -force -include_bit $(PROJECT).xsa" >> generate_bit.tcl
vivado -nojournal -nolog -mode batch -source generate_bit.tcl
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bit .
ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).bin .
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then ln -f -s $(PROJECT).runs/impl_1/$(PROJECT).ltx .; fi
mkdir -p rev
COUNT=100; \
while [ -e rev/$(PROJECT)_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bit rev/$(PROJECT)_rev$$COUNT.bit; \
cp -pv $(PROJECT).runs/impl_1/$(PROJECT).bin rev/$(PROJECT)_rev$$COUNT.bin; \
if [ -e $(PROJECT).runs/impl_1/$(PROJECT).ltx ]; then cp -pv $(PROJECT).runs/impl_1/$(PROJECT).ltx rev/$(PROJECT)_rev$$COUNT.ltx; fi; \
if [ -e $(PROJECT).xsa ]; then cp -pv $(PROJECT).xsa rev/$(PROJECT)_rev$$COUNT.xsa; fi

View File

@@ -0,0 +1,386 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# XDC constraints for the RK-XCKU5P-F
# part: xcku5p-ffvb676-2-e
# General configuration
set_property CFGBVS GND [current_design]
set_property CONFIG_VOLTAGE 1.8 [current_design]
set_property BITSTREAM.GENERAL.COMPRESS true [current_design]
set_property BITSTREAM.CONFIG.UNUSEDPIN Pullup [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 72.9 [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property BITSTREAM.CONFIG.SPI_FALL_EDGE Yes [current_design]
set_property BITSTREAM.CONFIG.OVERTEMPSHUTDOWN Enable [current_design]
# 200 MHz system clock (Y2)
set_property -dict {LOC T24 IOSTANDARD LVDS} [get_ports {clk_200mhz_p}]
set_property -dict {LOC U24 IOSTANDARD LVDS} [get_ports {clk_200mhz_n}]
create_clock -period 5.000 -name clk_200mhz [get_ports {clk_200mhz_p}]
# LEDs
set_property -dict {LOC H9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {led[0]}] ;# LED2
set_property -dict {LOC J9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {led[1]}] ;# LED3
set_property -dict {LOC G11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {led[2]}] ;# LED4
set_property -dict {LOC H11 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12} [get_ports {led[3]}] ;# LED5
set_false_path -to [get_ports {led[*]}]
set_output_delay 0 [get_ports {led[*]}]
# Buttons
set_property -dict {LOC K9 IOSTANDARD LVCMOS33} [get_ports {btn[0]}] ;# K1
set_property -dict {LOC K10 IOSTANDARD LVCMOS33} [get_ports {btn[1]}] ;# K2
set_property -dict {LOC J10 IOSTANDARD LVCMOS33} [get_ports {btn[2]}] ;# K3
set_property -dict {LOC J11 IOSTANDARD LVCMOS33} [get_ports {btn[3]}] ;# K4
set_false_path -from [get_ports {btn[*]}]
set_input_delay 0 [get_ports {btn[*]}]
# GPIO
#set_property -dict {LOC D10 IOSTANDARD LVCMOS33} [get_ports {gpio[0]}] ;# J1.3
#set_property -dict {LOC D11 IOSTANDARD LVCMOS33} [get_ports {gpio[1]}] ;# J1.4
#set_property -dict {LOC E10 IOSTANDARD LVCMOS33} [get_ports {gpio[2]}] ;# J1.5
#set_property -dict {LOC E11 IOSTANDARD LVCMOS33} [get_ports {gpio[3]}] ;# J1.6
#set_property -dict {LOC B11 IOSTANDARD LVCMOS33} [get_ports {gpio[4]}] ;# J1.7
#set_property -dict {LOC C11 IOSTANDARD LVCMOS33} [get_ports {gpio[5]}] ;# J1.8
#set_property -dict {LOC C9 IOSTANDARD LVCMOS33} [get_ports {gpio[6]}] ;# J1.9
#set_property -dict {LOC D9 IOSTANDARD LVCMOS33} [get_ports {gpio[7]}] ;# J1.10
#set_property -dict {LOC A9 IOSTANDARD LVCMOS33} [get_ports {gpio[8]}] ;# J1.11
#set_property -dict {LOC B9 IOSTANDARD LVCMOS33} [get_ports {gpio[9]}] ;# J1.12
#set_property -dict {LOC A10 IOSTANDARD LVCMOS33} [get_ports {gpio[10]}] ;# J1.13
#set_property -dict {LOC B10 IOSTANDARD LVCMOS33} [get_ports {gpio[11]}] ;# J1.14
#set_property -dict {LOC A12 IOSTANDARD LVCMOS33} [get_ports {gpio[12]}] ;# J1.15
#set_property -dict {LOC A13 IOSTANDARD LVCMOS33} [get_ports {gpio[13]}] ;# J1.16
#set_property -dict {LOC A14 IOSTANDARD LVCMOS33} [get_ports {gpio[14]}] ;# J1.17
#set_property -dict {LOC B14 IOSTANDARD LVCMOS33} [get_ports {gpio[15]}] ;# J1.18
#set_property -dict {LOC C13 IOSTANDARD LVCMOS33} [get_ports {gpio[16]}] ;# J1.19
#set_property -dict {LOC C14 IOSTANDARD LVCMOS33} [get_ports {gpio[17]}] ;# J1.20
#set_property -dict {LOC B12 IOSTANDARD LVCMOS33} [get_ports {gpio[18]}] ;# J1.21
#set_property -dict {LOC C12 IOSTANDARD LVCMOS33} [get_ports {gpio[19]}] ;# J1.22
#set_property -dict {LOC D13 IOSTANDARD LVCMOS33} [get_ports {gpio[20]}] ;# J1.23
#set_property -dict {LOC D14 IOSTANDARD LVCMOS33} [get_ports {gpio[21]}] ;# J1.24
#set_property -dict {LOC E12 IOSTANDARD LVCMOS33} [get_ports {gpio[22]}] ;# J1.25
#set_property -dict {LOC E13 IOSTANDARD LVCMOS33} [get_ports {gpio[23]}] ;# J1.26
#set_property -dict {LOC F13 IOSTANDARD LVCMOS33} [get_ports {gpio[24]}] ;# J1.27
#set_property -dict {LOC F14 IOSTANDARD LVCMOS33} [get_ports {gpio[25]}] ;# J1.28
#set_property -dict {LOC F12 IOSTANDARD LVCMOS33} [get_ports {gpio[26]}] ;# J1.29
#set_property -dict {LOC G12 IOSTANDARD LVCMOS33} [get_ports {gpio[27]}] ;# J1.30
#set_property -dict {LOC G14 IOSTANDARD LVCMOS33} [get_ports {gpio[28]}] ;# J1.31
#set_property -dict {LOC H14 IOSTANDARD LVCMOS33} [get_ports {gpio[29]}] ;# J1.32
#set_property -dict {LOC J14 IOSTANDARD LVCMOS33} [get_ports {gpio[30]}] ;# J1.33
#set_property -dict {LOC J15 IOSTANDARD LVCMOS33} [get_ports {gpio[31]}] ;# J1.34
#set_property -dict {LOC H13 IOSTANDARD LVCMOS33} [get_ports {gpio[32]}] ;# J1.35
#set_property -dict {LOC J13 IOSTANDARD LVCMOS33} [get_ports {gpio[33]}] ;# J1.36
# UART
set_property -dict {LOC AC14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {uart_txd}] ;# U9.38 BDBUS0
set_property -dict {LOC AD13 IOSTANDARD LVCMOS33} [get_ports {uart_rxd}] ;# U9.39 BDBUS1
set_false_path -to [get_ports {uart_txd}]
set_output_delay 0 [get_ports {uart_txd}]
set_false_path -from [get_ports {uart_rxd}]
set_input_delay 0 [get_ports {uart_rxd}]
# Micro SD
#set_property -dict {LOC Y15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 8} [get_ports {sd_clk}] ;# SD1.5 CLK SCLK
#set_property -dict {LOC AA15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 8} [get_ports {sd_cmd}] ;# SD1.3 CMD DI
#set_property -dict {LOC AB14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 8} [get_ports {sd_d[0]}] ;# SD1.7 D0 DO
#set_property -dict {LOC AA14 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 8} [get_ports {sd_d[1]}] ;# SD1.8 D1
#set_property -dict {LOC AB16 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 8} [get_ports {sd_d[2]}] ;# SD1.1 D2
#set_property -dict {LOC AB15 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 8} [get_ports {sd_d[3]}] ;# SD1.2 D3 CS
#set_property -dict {LOC Y16 IOSTANDARD LVCMOS33 SLEW FAST DRIVE 8} [get_ports {sd_cd}] ;# SD1.9 CD
# Fan
#set_property -dict {LOC G9 IOSTANDARD LVCMOS33 QUIETIO SLOW DRIVE 8} [get_ports {fan}] ;# J2
# Gigabit Ethernet RGMII PHY
#set_property -dict {LOC K22 IOSTANDARD LVCMOS18} [get_ports {phy_rx_clk}] ;# from U16.28 RXC
#set_property -dict {LOC L24 IOSTANDARD LVCMOS18} [get_ports {phy_rxd[0]}] ;# from U16.26 RXD0
#set_property -dict {LOC L25 IOSTANDARD LVCMOS18} [get_ports {phy_rxd[1]}] ;# from U16.25 RXD1
#set_property -dict {LOC K25 IOSTANDARD LVCMOS18} [get_ports {phy_rxd[2]}] ;# from U16.24 RXD2
#set_property -dict {LOC K26 IOSTANDARD LVCMOS18} [get_ports {phy_rxd[3]}] ;# from U16.23 RXD3
#set_property -dict {LOC K23 IOSTANDARD LVCMOS18} [get_ports {phy_rx_ctl}] ;# from U16.27 RXCTL
#set_property -dict {LOC M25 IOSTANDARD LVCMOS18 SLEW FAST DRIVE 12} [get_ports {phy_tx_clk}] ;# from U16.21 TXC
#set_property -dict {LOC L23 IOSTANDARD LVCMOS18 SLEW FAST DRIVE 12} [get_ports {phy_txd[0]}] ;# from U16.19 TXD0
#set_property -dict {LOC L22 IOSTANDARD LVCMOS18 SLEW FAST DRIVE 12} [get_ports {phy_txd[1]}] ;# from U16.18 TXD1
#set_property -dict {LOC L20 IOSTANDARD LVCMOS18 SLEW FAST DRIVE 12} [get_ports {phy_txd[2]}] ;# from U16.17 TXD2
#set_property -dict {LOC K20 IOSTANDARD LVCMOS18 SLEW FAST DRIVE 12} [get_ports {phy_txd[3]}] ;# from U16.16 TXD3
#set_property -dict {LOC M26 IOSTANDARD LVCMOS18 SLEW FAST DRIVE 12} [get_ports {phy_tx_ctl}] ;# from U16.20 TXCTL
#set_property -dict {LOC M19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {phy_mdio}] ;# from U16.14 MDIO
#set_property -dict {LOC L19 IOSTANDARD LVCMOS18 SLEW SLOW DRIVE 12} [get_ports {phy_mdc}] ;# from U16.13 MDC
#create_clock -period 8.000 -name {phy_rx_clk} [get_ports {phy_rx_clk}]
# QSFP28 Interface
set_property -dict {LOC Y2 } [get_ports {qsfp_rx_p[0]}] ;# MGTYRXP0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC Y1 } [get_ports {qsfp_rx_n[0]}] ;# MGTYRXN0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC AA5 } [get_ports {qsfp_tx_p[0]}] ;# MGTYTXP0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC AA4 } [get_ports {qsfp_tx_n[0]}] ;# MGTYTXN0_225 GTYE4_CHANNEL_X0Y4 / GTYE4_COMMON_X0Y1
set_property -dict {LOC V2 } [get_ports {qsfp_rx_p[1]}] ;# MGTYRXP1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC V1 } [get_ports {qsfp_rx_n[1]}] ;# MGTYRXN1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC W5 } [get_ports {qsfp_tx_p[1]}] ;# MGTYTXP1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC W4 } [get_ports {qsfp_tx_n[1]}] ;# MGTYTXN1_225 GTYE4_CHANNEL_X0Y5 / GTYE4_COMMON_X0Y1
set_property -dict {LOC T2 } [get_ports {qsfp_rx_p[2]}] ;# MGTYRXP2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC T1 } [get_ports {qsfp_rx_n[2]}] ;# MGTYRXN2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC U5 } [get_ports {qsfp_tx_p[2]}] ;# MGTYTXP2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC U4 } [get_ports {qsfp_tx_n[2]}] ;# MGTYTXN2_225 GTYE4_CHANNEL_X0Y6 / GTYE4_COMMON_X0Y1
set_property -dict {LOC P2 } [get_ports {qsfp_rx_p[3]}] ;# MGTYRXP3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC P1 } [get_ports {qsfp_rx_n[3]}] ;# MGTYRXN3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC R5 } [get_ports {qsfp_tx_p[3]}] ;# MGTYTXP3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC R4 } [get_ports {qsfp_tx_n[3]}] ;# MGTYTXN3_225 GTYE4_CHANNEL_X0Y7 / GTYE4_COMMON_X0Y1
set_property -dict {LOC V7 } [get_ports {qsfp_mgt_refclk_p}] ;# MGTREFCLK0P_225
set_property -dict {LOC V6 } [get_ports {qsfp_mgt_refclk_n}] ;# MGTREFCLK0N_225
set_property -dict {LOC W13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports qsfp_modsell]
set_property -dict {LOC W12 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports qsfp_resetl]
set_property -dict {LOC AA13 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_modprsl]
set_property -dict {LOC Y13 IOSTANDARD LVCMOS33 PULLUP true} [get_ports qsfp_intl]
set_property -dict {LOC W14 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports qsfp_lpmode]
#set_property -dict {LOC AE15 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {qsfp_i2c_scl}]
#set_property -dict {LOC AE13 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 12 PULLUP true} [get_ports {qsfp_i2c_sda}]
# 156.25 MHz MGT reference clock
create_clock -period 6.4 -name qsfp_mgt_refclk [get_ports {qsfp_mgt_refclk_p}]
set_false_path -to [get_ports {qsfp_modsell qsfp_resetl qsfp_lpmode}]
set_output_delay 0 [get_ports {qsfp_modsell qsfp_resetl qsfp_lpmode}]
set_false_path -from [get_ports {qsfp_modprsl qsfp_intl}]
set_input_delay 0 [get_ports {qsfp_modprsl qsfp_intl}]
#set_false_path -to [get_ports {qsfp_i2c_sda[*] qsfp_i2c_scl[*]}]
#set_output_delay 0 [get_ports {qsfp_i2c_sda[*] qsfp_i2c_scl[*]}]
#set_false_path -from [get_ports {qsfp_i2c_sda[*] qsfp_i2c_scl[*]}]
#set_input_delay 0 [get_ports {qsfp_i2c_sda[*] qsfp_i2c_scl[*]}]
# PCIe Interface
set_property -dict {LOC AB2 } [get_ports {pcie_rx_p[0]}] ;# MGTYRXP3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AB1 } [get_ports {pcie_rx_n[0]}] ;# MGTYRXN3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AC5 } [get_ports {pcie_tx_p[0]}] ;# MGTYTXP3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AC4 } [get_ports {pcie_tx_n[0]}] ;# MGTYTXN3_224 GTYE4_CHANNEL_X0Y3 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD2 } [get_ports {pcie_rx_p[1]}] ;# MGTYRXP2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD1 } [get_ports {pcie_rx_n[1]}] ;# MGTYRXN2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD7 } [get_ports {pcie_tx_p[1]}] ;# MGTYTXP2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AD6 } [get_ports {pcie_tx_n[1]}] ;# MGTYTXN2_224 GTYE4_CHANNEL_X0Y2 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE4 } [get_ports {pcie_rx_p[2]}] ;# MGTYRXP1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE3 } [get_ports {pcie_rx_n[2]}] ;# MGTYRXN1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE9 } [get_ports {pcie_tx_p[2]}] ;# MGTYTXP1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AE8 } [get_ports {pcie_tx_n[2]}] ;# MGTYTXN1_224 GTYE4_CHANNEL_X0Y1 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF2 } [get_ports {pcie_rx_p[3]}] ;# MGTYRXP0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF1 } [get_ports {pcie_rx_n[3]}] ;# MGTYRXN0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF7 } [get_ports {pcie_tx_p[3]}] ;# MGTYTXP0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AF6 } [get_ports {pcie_tx_n[3]}] ;# MGTYTXN0_224 GTYE4_CHANNEL_X0Y0 / GTYE4_COMMON_X0Y0
set_property -dict {LOC AB7 } [get_ports pcie_refclk_p] ;# MGTREFCLK1P_224
set_property -dict {LOC AB6 } [get_ports pcie_refclk_n] ;# MGTREFCLK1N_224
set_property -dict {LOC T19 IOSTANDARD LVCMOS12 PULLUP true} [get_ports pcie_reset_n]
set_false_path -from [get_ports {pcie_reset_n}]
set_input_delay 0 [get_ports {pcie_reset_n}]
# 100 MHz MGT reference clock
create_clock -period 10 -name pcie_mgt_refclk [get_ports pcie_refclk_p]
# FMC interface
# FMC HPC J4
#set_property -dict {LOC G24 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[0]}] ;# J4.G9 LA00_P_CC
#set_property -dict {LOC G25 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[0]}] ;# J4.G10 LA00_N_CC
#set_property -dict {LOC J23 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[1]}] ;# J4.D8 LA01_P_CC
#set_property -dict {LOC J24 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[1]}] ;# J4.D9 LA01_N_CC
#set_property -dict {LOC H21 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[2]}] ;# J4.H7 LA02_P
#set_property -dict {LOC H22 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[2]}] ;# J4.H8 LA02_N
#set_property -dict {LOC J19 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[3]}] ;# J4.G12 LA03_P
#set_property -dict {LOC J20 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[3]}] ;# J4.G13 LA03_N
#set_property -dict {LOC H26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[4]}] ;# J4.H10 LA04_P
#set_property -dict {LOC G26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[4]}] ;# J4.H11 LA04_N
#set_property -dict {LOC F24 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[5]}] ;# J4.D11 LA05_P
#set_property -dict {LOC F25 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[5]}] ;# J4.D12 LA05_N
#set_property -dict {LOC G20 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[6]}] ;# J4.C10 LA06_P
#set_property -dict {LOC G21 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[6]}] ;# J4.C11 LA06_N
#set_property -dict {LOC D24 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[7]}] ;# J4.H13 LA07_P
#set_property -dict {LOC D25 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[7]}] ;# J4.H14 LA07_N
#set_property -dict {LOC D26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[8]}] ;# J4.G12 LA08_P
#set_property -dict {LOC C26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[8]}] ;# J4.G13 LA08_N
#set_property -dict {LOC E25 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[9]}] ;# J4.D14 LA09_P
#set_property -dict {LOC E26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[9]}] ;# J4.D15 LA09_N
#set_property -dict {LOC B25 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[10]}] ;# J4.C14 LA10_P
#set_property -dict {LOC B26 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[10]}] ;# J4.C15 LA10_N
#set_property -dict {LOC A24 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[11]}] ;# J4.H16 LA11_P
#set_property -dict {LOC A25 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[11]}] ;# J4.H17 LA11_N
#set_property -dict {LOC D23 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[12]}] ;# J4.G15 LA12_P
#set_property -dict {LOC C24 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[12]}] ;# J4.G16 LA12_N
#set_property -dict {LOC F23 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[13]}] ;# J4.D17 LA13_P
#set_property -dict {LOC E23 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[13]}] ;# J4.D18 LA13_N
#set_property -dict {LOC C23 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[14]}] ;# J4.C18 LA14_P
#set_property -dict {LOC B24 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[14]}] ;# J4.C19 LA14_N
#set_property -dict {LOC H18 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[15]}] ;# J4.H19 LA15_P
#set_property -dict {LOC H19 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[15]}] ;# J4.H20 LA15_N
#set_property -dict {LOC E21 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[16]}] ;# J4.G18 LA16_P
#set_property -dict {LOC D21 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[16]}] ;# J4.G19 LA16_N
#set_property -dict {LOC C18 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[17]}] ;# J4.D20 LA17_P_CC
#set_property -dict {LOC C19 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[17]}] ;# J4.D21 LA17_N_CC
#set_property -dict {LOC D19 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[18]}] ;# J4.C22 LA18_P_CC
#set_property -dict {LOC D20 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[18]}] ;# J4.C23 LA18_N_CC
#set_property -dict {LOC A22 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[19]}] ;# J4.H22 LA19_P
#set_property -dict {LOC A23 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[19]}] ;# J4.H23 LA19_N
#set_property -dict {LOC F20 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[20]}] ;# J4.G21 LA20_P
#set_property -dict {LOC E20 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[20]}] ;# J4.G22 LA20_N
#set_property -dict {LOC C21 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[21]}] ;# J4.H25 LA21_P
#set_property -dict {LOC B21 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[21]}] ;# J4.H26 LA21_N
#set_property -dict {LOC H16 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[22]}] ;# J4.G24 LA22_P
#set_property -dict {LOC G16 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[22]}] ;# J4.G25 LA22_N
#set_property -dict {LOC C22 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[23]}] ;# J4.D23 LA23_P
#set_property -dict {LOC B22 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[23]}] ;# J4.D24 LA23_N
#set_property -dict {LOC A17 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[24]}] ;# J4.H28 LA24_P
#set_property -dict {LOC A18 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[24]}] ;# J4.H29 LA24_N
#set_property -dict {LOC E18 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[25]}] ;# J4.G27 LA25_P
#set_property -dict {LOC D18 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[25]}] ;# J4.G28 LA25_N
#set_property -dict {LOC A19 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[26]}] ;# J4.D26 LA26_P
#set_property -dict {LOC A20 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[26]}] ;# J4.D27 LA26_N
#set_property -dict {LOC F18 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[27]}] ;# J4.C26 LA27_P
#set_property -dict {LOC F19 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[27]}] ;# J4.C27 LA27_N
#set_property -dict {LOC C17 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[28]}] ;# J4.H31 LA28_P
#set_property -dict {LOC B17 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[28]}] ;# J4.H32 LA28_N
#set_property -dict {LOC E16 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[29]}] ;# J4.G30 LA29_P
#set_property -dict {LOC E17 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[29]}] ;# J4.G31 LA29_N
#set_property -dict {LOC D16 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[30]}] ;# J4.H34 LA30_P
#set_property -dict {LOC C16 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[30]}] ;# J4.H35 LA30_N
#set_property -dict {LOC G15 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[31]}] ;# J4.G33 LA31_P
#set_property -dict {LOC F15 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[31]}] ;# J4.G34 LA31_N
#set_property -dict {LOC B15 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[32]}] ;# J4.H37 LA32_P
#set_property -dict {LOC A15 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[32]}] ;# J4.H38 LA32_N
#set_property -dict {LOC E15 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_p[33]}] ;# J4.G36 LA33_P
#set_property -dict {LOC D15 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_la_n[33]}] ;# J4.G37 LA33_N
#set_property -dict {LOC H23 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_clk0_m2c_p}] ;# J4.H4 CLK0_M2C_P
#set_property -dict {LOC H24 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_clk0_m2c_n}] ;# J4.H5 CLK0_M2C_N
#set_property -dict {LOC B19 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_clk1_m2c_p}] ;# J4.G2 CLK1_M2C_P
#set_property -dict {LOC B20 IOSTANDARD LVDS DIFF_TERM_ADV TERM_100} [get_ports {fmc_clk1_m2c_n}] ;# J4.G3 CLK1_M2C_N
#set_property -dict {LOC F10 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {fmc_scl}] ;# J4.C30 SCL
#set_property -dict {LOC F9 IOSTANDARD LVCMOS33 SLEW SLOW DRIVE 8} [get_ports {fmc_sda}] ;# J4.C31 SDA
#set_property -dict {LOC G10 IOSTANDARD LVCMOS33} [get_ports {fmc_pg_m2c}] ;# J4.F1 PG_M2C
#set_property -dict {LOC N5 } [get_ports {fmc_dp_c2m_p[0]}] ;# MGTHTXP0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y3 from J4.C2 DP0_C2M_P
#set_property -dict {LOC N4 } [get_ports {fmc_dp_c2m_n[0]}] ;# MGTHTXN0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y3 from J4.C3 DP0_C2M_N
#set_property -dict {LOC M2 } [get_ports {fmc_dp_m2c_p[0]}] ;# MGTHRXP0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y3 from J4.C6 DP0_M2C_P
#set_property -dict {LOC M1 } [get_ports {fmc_dp_m2c_n[0]}] ;# MGTHRXN0_226 GTHE4_CHANNEL_X0Y8 / GTHE4_COMMON_X0Y3 from J4.C7 DP0_M2C_N
#set_property -dict {LOC L5 } [get_ports {fmc_dp_c2m_p[1]}] ;# MGTHTXP1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y3 from J4.A22 DP1_C2M_P
#set_property -dict {LOC L4 } [get_ports {fmc_dp_c2m_n[1]}] ;# MGTHTXN1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y3 from J4.A23 DP1_C2M_N
#set_property -dict {LOC K2 } [get_ports {fmc_dp_m2c_p[1]}] ;# MGTHRXP1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y3 from J4.A2 DP1_M2C_P
#set_property -dict {LOC K1 } [get_ports {fmc_dp_m2c_n[1]}] ;# MGTHRXN1_226 GTHE4_CHANNEL_X0Y9 / GTHE4_COMMON_X0Y3 from J4.A3 DP1_M2C_N
#set_property -dict {LOC J5 } [get_ports {fmc_dp_c2m_p[2]}] ;# MGTHTXP2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y3 from J4.A26 DP2_C2M_P
#set_property -dict {LOC J4 } [get_ports {fmc_dp_c2m_n[2]}] ;# MGTHTXN2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y3 from J4.A27 DP2_C2M_N
#set_property -dict {LOC H2 } [get_ports {fmc_dp_m2c_p[2]}] ;# MGTHRXP2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y3 from J4.A6 DP2_M2C_P
#set_property -dict {LOC H1 } [get_ports {fmc_dp_m2c_n[2]}] ;# MGTHRXN2_226 GTHE4_CHANNEL_X0Y10 / GTHE4_COMMON_X0Y3 from J4.A7 DP2_M2C_N
#set_property -dict {LOC G5 } [get_ports {fmc_dp_c2m_p[3]}] ;# MGTHTXP3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y3 from J4.A30 DP3_C2M_P
#set_property -dict {LOC G4 } [get_ports {fmc_dp_c2m_n[3]}] ;# MGTHTXN3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y3 from J4.A31 DP3_C2M_N
#set_property -dict {LOC F2 } [get_ports {fmc_dp_m2c_p[3]}] ;# MGTHRXP3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y3 from J4.A10 DP3_M2C_P
#set_property -dict {LOC F1 } [get_ports {fmc_dp_m2c_n[3]}] ;# MGTHRXN3_226 GTHE4_CHANNEL_X0Y11 / GTHE4_COMMON_X0Y3 from J4.A11 DP3_M2C_N
#set_property -dict {LOC F7 } [get_ports {fmc_dp_c2m_p[4]}] ;# MGTHTXP0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y4 from J4.A34 DP4_C2M_P
#set_property -dict {LOC F6 } [get_ports {fmc_dp_c2m_n[4]}] ;# MGTHTXN0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y4 from J4.A35 DP4_C2M_N
#set_property -dict {LOC D2 } [get_ports {fmc_dp_m2c_p[4]}] ;# MGTHRXP0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y4 from J4.A14 DP4_M2C_P
#set_property -dict {LOC D1 } [get_ports {fmc_dp_m2c_n[4]}] ;# MGTHRXN0_227 GTHE4_CHANNEL_X0Y12 / GTHE4_COMMON_X0Y4 from J4.A15 DP4_M2C_N
#set_property -dict {LOC E5 } [get_ports {fmc_dp_c2m_p[5]}] ;# MGTHTXP1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y4 from J4.A38 DP5_C2M_P
#set_property -dict {LOC E4 } [get_ports {fmc_dp_c2m_n[5]}] ;# MGTHTXN1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y4 from J4.A39 DP5_C2M_N
#set_property -dict {LOC C4 } [get_ports {fmc_dp_m2c_p[5]}] ;# MGTHRXP1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y4 from J4.A18 DP5_M2C_P
#set_property -dict {LOC C3 } [get_ports {fmc_dp_m2c_n[5]}] ;# MGTHRXN1_227 GTHE4_CHANNEL_X0Y13 / GTHE4_COMMON_X0Y4 from J4.A19 DP5_M2C_N
#set_property -dict {LOC D7 } [get_ports {fmc_dp_c2m_p[6]}] ;# MGTHTXP2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y4 from J4.B36 DP6_C2M_P
#set_property -dict {LOC D6 } [get_ports {fmc_dp_c2m_n[6]}] ;# MGTHTXN2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y4 from J4.B37 DP6_C2M_N
#set_property -dict {LOC B2 } [get_ports {fmc_dp_m2c_p[6]}] ;# MGTHRXP2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y4 from J4.B16 DP6_M2C_P
#set_property -dict {LOC B1 } [get_ports {fmc_dp_m2c_n[6]}] ;# MGTHRXN2_227 GTHE4_CHANNEL_X0Y14 / GTHE4_COMMON_X0Y4 from J4.B17 DP6_M2C_N
#set_property -dict {LOC B7 } [get_ports {fmc_dp_c2m_p[7]}] ;# MGTHTXP3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y4 from J4.B32 DP7_C2M_P
#set_property -dict {LOC B6 } [get_ports {fmc_dp_c2m_n[7]}] ;# MGTHTXN3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y4 from J4.B33 DP7_C2M_N
#set_property -dict {LOC A4 } [get_ports {fmc_dp_m2c_p[7]}] ;# MGTHRXP3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y4 from J4.B12 DP7_M2C_P
#set_property -dict {LOC A3 } [get_ports {fmc_dp_m2c_n[7]}] ;# MGTHRXN3_227 GTHE4_CHANNEL_X0Y15 / GTHE4_COMMON_X0Y4 from J4.B13 DP7_M2C_N
#set_property -dict {LOC P7 } [get_ports {fmc_mgt_refclk_0_p}] ;# MGTREFCLK0P_226 from J4.D4 GBTCLK0_M2C_P
#set_property -dict {LOC P6 } [get_ports {fmc_mgt_refclk_0_n}] ;# MGTREFCLK0N_226 from J4.D5 GBTCLK0_M2C_N
#set_property -dict {LOC K7 } [get_ports {fmc_mgt_refclk_1_p}] ;# MGTREFCLK0P_227 from J4.B20 GBTCLK1_M2C_P
#set_property -dict {LOC K6 } [get_ports {fmc_mgt_refclk_1_n}] ;# MGTREFCLK0N_227 from J4.B21 GBTCLK1_M2C_N
# reference clock
#create_clock -period 6.400 -name fmc_mgt_refclk_0 [get_ports {fmc_mgt_refclk_0_p}]
#create_clock -period 6.400 -name fmc_mgt_refclk_1 [get_ports {fmc_mgt_refclk_1_p}]
# DDR4
# 2x MT40A512M16LY-062E:E U3, U6
#set_property -dict {LOC Y22 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[0]}]
#set_property -dict {LOC Y25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[1]}]
#set_property -dict {LOC W23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[2]}]
#set_property -dict {LOC V26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[3]}]
#set_property -dict {LOC R26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[4]}]
#set_property -dict {LOC U26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[5]}]
#set_property -dict {LOC R21 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[6]}]
#set_property -dict {LOC W25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[7]}]
#set_property -dict {LOC R20 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[8]}]
#set_property -dict {LOC Y26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[9]}]
#set_property -dict {LOC R25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[10]}]
#set_property -dict {LOC V23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[11]}]
#set_property -dict {LOC AA24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[12]}]
#set_property -dict {LOC W26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[13]}]
#set_property -dict {LOC P23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[14]}]
#set_property -dict {LOC AA25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[15]}]
#set_property -dict {LOC T25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_adr[16]}]
#set_property -dict {LOC P21 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_ba[0]}]
#set_property -dict {LOC P26 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_ba[1]}]
#set_property -dict {LOC R22 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_bg[0]}]
#set_property -dict {LOC V24 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_ck_t}]
#set_property -dict {LOC W24 IOSTANDARD DIFF_SSTL12_DCI} [get_ports {ddr4_ck_c}]
#set_property -dict {LOC P20 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_cke}]
#set_property -dict {LOC P25 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_cs_n}]
#set_property -dict {LOC P24 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_act_n}]
#set_property -dict {LOC R23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_odt}]
#set_property -dict {LOC Y23 IOSTANDARD SSTL12_DCI } [get_ports {ddr4_par}]
#set_property -dict {LOC P19 IOSTANDARD LVCMOS12 } [get_ports {ddr4_reset_n}]
#set_property -dict {LOC U25 IOSTANDARD LVCMOS12 } [get_ports {ddr4_alert_n}]
#set_property -dict {LOC AB26 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[0]}]
#set_property -dict {LOC AB25 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[1]}]
#set_property -dict {LOC AF25 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[2]}]
#set_property -dict {LOC AF24 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[3]}]
#set_property -dict {LOC AD25 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[4]}]
#set_property -dict {LOC AD24 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[5]}]
#set_property -dict {LOC AC24 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[6]}]
#set_property -dict {LOC AB24 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[7]}]
#set_property -dict {LOC AE23 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[8]}]
#set_property -dict {LOC AD23 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[9]}]
#set_property -dict {LOC AC23 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[10]}]
#set_property -dict {LOC AC22 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[11]}]
#set_property -dict {LOC AE21 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[12]}]
#set_property -dict {LOC AD21 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[13]}]
#set_property -dict {LOC AC21 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[14]}]
#set_property -dict {LOC AB21 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[15]}]
#set_property -dict {LOC AC26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_dqs_t[0]}] ;# U3.G3 DQSL_T
#set_property -dict {LOC AD26 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_dqs_c[0]}] ;# U3.F3 DQSL_C
#set_property -dict {LOC AA22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_dqs_t[1]}] ;# U3.B7 DQSU_T
#set_property -dict {LOC AB22 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_dqs_c[1]}] ;# U3.A7 DQSU_C
#set_property -dict {LOC AE25 IOSTANDARD POD12_DCI } [get_ports {ddr4_dm_dbi_n[0]}] ;# U3.E7 DML_B/DBIL_B
#set_property -dict {LOC AE22 IOSTANDARD POD12_DCI } [get_ports {ddr4_dm_dbi_n[1]}] ;# U3.E2 DMU_B/DBIU_B
#set_property -dict {LOC AD19 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[0]}]
#set_property -dict {LOC AC19 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[1]}]
#set_property -dict {LOC AF19 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[2]}]
#set_property -dict {LOC AF18 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[3]}]
#set_property -dict {LOC AF17 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[4]}]
#set_property -dict {LOC AE17 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[5]}]
#set_property -dict {LOC AE16 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[6]}]
#set_property -dict {LOC AD16 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[7]}]
#set_property -dict {LOC AB19 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[8]}]
#set_property -dict {LOC AA19 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[9]}]
#set_property -dict {LOC AB20 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[10]}]
#set_property -dict {LOC AA20 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[11]}]
#set_property -dict {LOC AA17 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[12]}]
#set_property -dict {LOC Y17 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[13]}]
#set_property -dict {LOC AA18 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[14]}]
#set_property -dict {LOC Y18 IOSTANDARD POD12_DCI } [get_ports {ddr4_dq[15]}]
#set_property -dict {LOC AC18 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_dqs_t[2]}] ;# U6.G3 DQSL_T
#set_property -dict {LOC AD18 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_dqs_c[2]}] ;# U6.F3 DQSL_C
#set_property -dict {LOC AB17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_dqs_t[3]}] ;# U6.B7 DQSU_T
#set_property -dict {LOC AC17 IOSTANDARD DIFF_POD12_DCI } [get_ports {ddr4_dqs_c[3]}] ;# U6.A7 DQSU_C
#set_property -dict {LOC AD20 IOSTANDARD POD12_DCI } [get_ports {ddr4_dm_dbi_n[2]}] ;# U6.E7 DML_B/DBIL_B
#set_property -dict {LOC Y20 IOSTANDARD POD12_DCI } [get_ports {ddr4_dm_dbi_n[3]}] ;# U6.E2 DMU_B/DBIU_B

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcku5p-ffvb676-2-e
FPGA_TOP = fpga
FPGA_ARCH = kintexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_25g_us_gty_25g_156.tcl
IP_TCL_FILES += ../ip/pcie4_uscale_plus_0.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 32 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu256-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

View File

@@ -0,0 +1,131 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
set params [dict create]
# collect build information
set build_date [clock seconds]
set git_hash 00000000
set git_tag ""
if { [catch {set git_hash [exec git rev-parse --short=8 HEAD]}] } {
puts "Error running git or project not under version control"
}
if { [catch {set git_tag [exec git describe --tags HEAD]}] } {
puts "Error running git, project not under version control, or no tag found"
}
puts "Build date: ${build_date}"
puts "Git hash: ${git_hash}"
puts "Git tag: ${git_tag}"
if { ! [regsub {^.*(\d+\.\d+\.\d+([\.-]\d+)?).*$} $git_tag {\1} tag_ver ] } {
puts "Failed to extract version from git tag"
set tag_ver 0.0.1
}
puts "Tag version: ${tag_ver}"
# FW and board IDs
set fpga_id [expr 0x4A62093]
set fw_id [expr 0x0000C001]
set fw_ver $tag_ver
set board_vendor_id [expr 0x1234]
set board_device_id [expr 0x9005]
set board_ver 1.0
set release_info [expr 0x00000000]
# PCIe IDs
set pcie_vendor_id [expr 0x1234]
set pcie_device_id [expr 0xC001]
set pcie_class_code [expr 0x020000]
set pcie_revision_id [expr 0x00]
set pcie_subsystem_device_id $board_device_id
set pcie_subsystem_vendor_id $board_vendor_id
# FW ID
dict set params FPGA_ID [format "32'h%08x" $fpga_id]
dict set params FW_ID [format "32'h%08x" $fw_id]
dict set params FW_VER [format "32'h%03x%02x%03x" {*}[split $fw_ver .-] 0 0 0]
dict set params BOARD_ID [format "32'h%04x%04x" $board_vendor_id $board_device_id]
dict set params BOARD_VER [format "32'h%03x%02x%03x" {*}[split $board_ver .-] 0 0 0]
dict set params BUILD_DATE "32'd${build_date}"
dict set params GIT_HASH "32'h${git_hash}"
dict set params RELEASE_INFO [format "32'h%08x" $release_info]
# PTP configuration
dict set params PTP_TS_EN "1"
# AXI lite interface configuration (control)
dict set params AXIL_CTRL_DATA_W "32"
dict set params AXIL_CTRL_ADDR_W "24"
# MAC configuration
dict set params CFG_LOW_LATENCY "1"
dict set params COMBINED_MAC_PCS "1"
dict set params MAC_DATA_W "64"
# PCIe IP core settings
set pcie [get_ips pcie4_uscale_plus_0]
# configure BAR settings
proc configure_bar {pcie pf bar aperture} {
set size_list {Bytes Kilobytes Megabytes Gigabytes Terabytes Petabytes Exabytes}
for { set i 0 } { $i < [llength $size_list] } { incr i } {
set scale [lindex $size_list $i]
if {$aperture > 0 && $aperture < ($i+1)*10} {
set size [expr 1 << $aperture - ($i*10)]
puts "${pcie} PF${pf} BAR${bar}: aperture ${aperture} bits ($size $scale)"
set pcie_config [dict create]
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_enabled" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_type" {Memory}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_64bit" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_prefetchable" {true}
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_scale" $scale
dict set pcie_config "CONFIG.pf${pf}_bar${bar}_size" $size
set_property -dict $pcie_config $pcie
return
}
}
puts "${pcie} PF${pf} BAR${bar}: disabled"
set_property "CONFIG.pf${pf}_bar${bar}_enabled" {false} $pcie
}
# Control BAR (BAR 0)
configure_bar $pcie 0 0 [dict get $params AXIL_CTRL_ADDR_W]
# PCIe IP core configuration
set pcie_config [dict create]
# PCIe IDs
dict set pcie_config "CONFIG.vendor_id" [format "%04x" $pcie_vendor_id]
dict set pcie_config "CONFIG.PF0_DEVICE_ID" [format "%04x" $pcie_device_id]
dict set pcie_config "CONFIG.PF0_CLASS_CODE" [format "%06x" $pcie_class_code]
dict set pcie_config "CONFIG.PF0_REVISION_ID" [format "%02x" $pcie_revision_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_VENDOR_ID" [format "%04x" $pcie_subsystem_vendor_id]
dict set pcie_config "CONFIG.PF0_SUBSYSTEM_ID" [format "%04x" $pcie_subsystem_device_id]
# MSI
dict set pcie_config "CONFIG.pf0_msi_enabled" {true}
set_property -dict $pcie_config $pcie
# apply parameters to top-level
set param_list {}
dict for {name value} $params {
lappend param_list $name=$value
}
set_property generic $param_list [get_filesets sources_1]

View File

@@ -0,0 +1,98 @@
# SPDX-License-Identifier: MIT
#
# Copyright (c) 2025-2026 FPGA Ninja, LLC
#
# Authors:
# - Alex Forencich
#
# FPGA settings
FPGA_PART = xcku5p-ffvb676-2-e
FPGA_TOP = fpga
FPGA_ARCH = kintexuplus
RTL_DIR = ../rtl
LIB_DIR = ../lib
TAXI_SRC_DIR = $(LIB_DIR)/taxi/src
# Files for synthesis
SYN_FILES = $(RTL_DIR)/fpga.sv
SYN_FILES += $(RTL_DIR)/fpga_core.sv
SYN_FILES += $(TAXI_SRC_DIR)/cndm/rtl/cndm_micro_pcie_us.f
SYN_FILES += $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_mac_25g_us.f
SYN_FILES += $(TAXI_SRC_DIR)/axis/rtl/taxi_axis_async_fifo.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_if_uart.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_apb.f
SYN_FILES += $(TAXI_SRC_DIR)/xfcp/rtl/taxi_xfcp_mod_stats.f
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_reset.sv
SYN_FILES += $(TAXI_SRC_DIR)/sync/rtl/taxi_sync_signal.sv
SYN_FILES += $(TAXI_SRC_DIR)/io/rtl/taxi_debounce_switch.sv
SYN_FILES += $(TAXI_SRC_DIR)/pyrite/rtl/pyrite_pcie_us_vpd_qspi.f
# XDC files
XDC_FILES = ../fpga.xdc
XDC_FILES += $(TAXI_SRC_DIR)/eth/syn/vivado/taxi_eth_mac_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/axis/syn/vivado/taxi_axis_async_fifo.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_leaf.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_phc_regs.tcl
XDC_FILES += $(TAXI_SRC_DIR)/ptp/syn/vivado/taxi_ptp_td_rel2tod.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_reset.tcl
XDC_FILES += $(TAXI_SRC_DIR)/sync/syn/vivado/taxi_sync_signal.tcl
# IP
IP_TCL_FILES = $(TAXI_SRC_DIR)/eth/rtl/us/taxi_eth_phy_10g_us_gty_156.tcl
IP_TCL_FILES += ../ip/pcie4_uscale_plus_0.tcl
# Configuration
CONFIG_TCL_FILES = ./config.tcl
include ../common/vivado.mk
program: $(PROJECT).bit
echo "open_hw_manager" > program.tcl
echo "connect_hw_server" >> program.tcl
echo "open_hw_target" >> program.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> program.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> program.tcl
echo "set_property PROGRAM.FILE {$(PROJECT).bit} [current_hw_device]" >> program.tcl
echo "program_hw_devices [current_hw_device]" >> program.tcl
echo "exit" >> program.tcl
vivado -nojournal -nolog -mode batch -source program.tcl
$(PROJECT).mcs $(PROJECT).prm: $(PROJECT).bit
echo "write_cfgmem -force -format mcs -size 32 -interface SPIx4 -loadbit {up 0x0000000 $*.bit} -checksum -file $*.mcs" > generate_mcs.tcl
echo "exit" >> generate_mcs.tcl
vivado -nojournal -nolog -mode batch -source generate_mcs.tcl
mkdir -p rev
COUNT=100; \
while [ -e rev/$*_rev$$COUNT.bit ]; \
do COUNT=$$((COUNT+1)); done; \
COUNT=$$((COUNT-1)); \
for x in .mcs .prm; \
do cp $*$$x rev/$*_rev$$COUNT$$x; \
echo "Output: rev/$*_rev$$COUNT$$x"; done;
flash: $(PROJECT).mcs $(PROJECT).prm
echo "open_hw" > flash.tcl
echo "connect_hw_server" >> flash.tcl
echo "open_hw_target" >> flash.tcl
echo "current_hw_device [lindex [get_hw_devices] 0]" >> flash.tcl
echo "refresh_hw_device -update_hw_probes false [current_hw_device]" >> flash.tcl
echo "create_hw_cfgmem -hw_device [current_hw_device] [lindex [get_cfgmem_parts {mt25qu256-spi-x1_x2_x4}] 0]" >> flash.tcl
echo "current_hw_cfgmem -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM [current_hw_device]]" >> flash.tcl
echo "set_property PROGRAM.FILES [list \"$(PROJECT).mcs\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.PRM_FILES [list \"$(PROJECT).prm\"] [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ERASE 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CFG_PROGRAM 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.VERIFY 1 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.CHECKSUM 0 [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.ADDRESS_RANGE {use_file} [current_hw_cfgmem]" >> flash.tcl
echo "set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [current_hw_cfgmem]" >> flash.tcl
echo "create_hw_bitstream -hw_device [current_hw_device] [get_property PROGRAM.HW_CFGMEM_BITFILE [current_hw_device]]" >> flash.tcl
echo "program_hw_devices [current_hw_device]" >> flash.tcl
echo "refresh_hw_device [current_hw_device]" >> flash.tcl
echo "program_hw_cfgmem -hw_cfgmem [current_hw_cfgmem]" >> flash.tcl
echo "boot_hw_device [current_hw_device]" >> flash.tcl
echo "exit" >> flash.tcl
vivado -nojournal -nolog -mode batch -source flash.tcl

Some files were not shown because too many files have changed in this diff Show More