-
Notifications
You must be signed in to change notification settings - Fork 0
Xilinx FPGA Cheatsheet
T_IDELAYRESOLUTION = 1/(32 x 2 x F_REF)
Reference Frequency (MHz) | IDELAY Resolution (ps) |
---|---|
200 | 78.125 |
300 | 52.03 |
400 | 39.0625 |
Reference: DS187
In instances where one needs a clock signal but the only ones available are coming in on the GT transceiver clocks, they must be routed through some GT specific BUFGs before being used. The chain is demonstrated below as follows.
IBUFDS_GTE4 ibfuds_gte4_inst(
.I(GT_CLK_P),
.IB(GT_CLK_N),
.CEB('0),
.O(),
.ODIV2(gt_clk_copy)
);
BUFG_GT gt_clk_bufg(
.I(gt_clk_copy),
.CE('1),
.CE_MASK('1),
.CLR('0),
.CLRMASK('1),
.DIV('0),
.O(gt_ref_clk)
);
The usage of the signal coming out of ODIV2 is intentional. The O output from the IBUF is only usable by the transceiver itself.
The Vivado placer sometimes can place the BUFG_GT of the transceiver reference clock in an inappropriate location relative to where the transceiver is. This can cause a variety of violations/failures in subsequent implementation stages. The solution to this is to set a manual constraint for the placement of the BUFG so that it is close to, but NOT NECESSARILY in the same region, as the GT transceiver itself. This is because, according to UG572, certain UltraScale+ devices cannot route clocks buffered in the X0 columns where the GT transceivers are located to regions further to the "right" of the chip. As such, assuming we are attempting to set a location constraint for a GT transceiver's reference clock where the transceiver is located in region X0Y3, we would want to set the constraint to someplace like location X1Y4, like so.
set_property USER_CLOCK_ROOT X1Y4 [get_nets -of [get_pins path/to/bufg_gt.bufg_gt_userclk_inst/O]]
set_property USER_CLOCK_ROOT X1Y4 [get_nets -of [get_pins path/to/bufg_gt.bufg_gt_userclk2_inst/O]]
Note the presence of the clk2. To determine what the full path to the BUFG_GT is, one generally needs to wait for the error to first pop up and point to the relevant BUFG_GT instance.
The errors that have been documented as resulting from this problem are as follows.
- Timing Total Pulse Width Violation
- Place 30-754
References
- Vivado Timing Closure Techniques, Total Pulse Width Violation (TPWS) Part 1
- UG572 Chapter 2: Clocking Resources - BUFG_GT and BUFG_GT_SYNC
In at least the 10G/25G ethernet IP core, Xilinx added a qpllreset_in_0 port sometime around Vivado 2020.1. The purpose of this port is self-explanatory from its name, it is for resetting the QPLLs that generate the user TX and RX clocks using the GT reference clock as an input. As such in those cases where the GT reference clock might not be stable immediately upon power-on, this reset helps delay initialization of the QPLLs until the clock has stabilized. The necessity of this port is because the preexisting sys_reset port does not actually connect to the QPLLs, nor is there any other reset signal internal to the IP core that triggers a reset of the QPLLs when sys_reset is toggled. More specifically, while there is a QPLL reset port in one of the internal modules, this port is hooked up to an undeclared net that is further not connected to anything else.
In the 10G/25G ethernet IP core, when the RX clock is run independently of the TX clock, the RX user reset does not actually start out asserted. This can cause problems because it will remain deasserted for a short period when the RX clock actually starts running, meaning any logic that was dependent on the RX user reset to actually reset itself will be in an undefined state. By the time the RX user reset actually asserts, in simulation at least, the damage will already have been done. The work around for this is to have a separate reset signal that starts out asserted and only deasserts upon detection of a falling edge of the RX user reset.
This behavior is present in at least Vivado 2022.1.
When filling out a device tree entry for a PL component for Linux, the "interrupts" field requires an interrupt number. If one looks at PG201 or UG1085, they note that the PL group 0 interrupts start at 121. This is not the starting offset that the device tree entry wants. The GIC interrupt cell has three fields, the first of which indicates whether something is a private peripheral/per processor interrupt (PPI) or shared processor interrupt (SPI). For both PPI and SPI, their interrupt numbers start at 0, with PPIs topping out at 31. As the PL interrupts are SPI, there is an implicit offset of 32 that needs to be applied to the interrupt index in the Xilinx user guide. As such the "first" PL interrupt number for the device tree entry is actually 89.
References