Repository navigation
open flow: DNA_PORT reads 0 on a Zynq XC7Z020 (die D); prjxray lists its pins as always-on pseudo-pips #8661
Description
Defect under the self-host epic (see #5980). Found while bringing up die D (see #8635, #8655).
Problem
On the open flow (yosys 0.63, nextpnr-xilinx from openXC7, prjxray-db zynq7, xc7frames2bit), DNA_PORT reads 0 on die D: a Zynq XC7Z020 rev 2, IDCODE 0x23727093. The JTAG instructions read the same die's DNA without trouble:
- XSC_DNA raw
00543179c5206c74, decoded05c6c09473d1854; - FUSE_DNA
2a18bce290363a73.
tri-net reports DNA_PORT reading 0 on the open flow as well.
Observed, 2026-10-10, one SRAM load
The design was the first die_probe.t27, which contained the reader below. Its USER1 read gave d1e108d7 6131e7a2 00000000 00000000:
- the read-done flag (bit 0 of
d1e108d7) is set; - the 57-bit DNA field is all zero;
- the rest of the design (STARTUPE2, BSCANE2, the ring race) worked.
The FASM routes every DNA_PORT pin:
CFG_CENTER_TOP_X123Y94.CFG_CENTER_DNA_PORT_CLK.CFG_CENTER_TOP_DNA_PORT_CLK
CFG_CENTER_MID_X123Y84.CFG_CENTER_MID_DNA_PORT_CLK.CFG_CENTER_CLK1_8
CFG_CENTER_TOP_X123Y94.CFG_CENTER_LOGIC_OUTS_B23_5.CFG_CENTER_DNA_PORT_DOUT
CFG_CENTER_TOP_X123Y94.CFG_CENTER_DNA_PORT_READ.CFG_CENTER_IMUX41_5
CFG_CENTER_TOP_X123Y94.CFG_CENTER_DNA_PORT_SHIFT.CFG_CENTER_IMUX42_5
CFG_CENTER_TOP_X123Y94.CFG_CENTER_DNA_PORT_DIN.CFG_CENTER_IMUX43_5
In prjxray-db zynq7, all six of these are always pseudo-pips (ppips_cfg_center_top.db, ppips_cfg_center_mid.db), and there is no segbits_cfg_center_top.db. So nothing in the bitstream configures them. If the hardware needs a bit to connect the clock route or the pins, the db does not know it.
Minimal repro
dna_read.t27: the reader on its own. Against a model of DNA_PORT, it passes t27c test-report (1/1) on master 1f6fc41, so the logic is not the suspect. The wrapper instantiates DNA_PORT dna (.CLK(clk), .READ(dna_read), .SHIFT(dna_shift), .DIN(1'b0), .DOUT(dout)), with the same BUFG clock as this module (STARTUPE2 CFGMCLK).
// SPDX-License-Identifier: Apache-2.0
module DnaRead;
// Reads DNA_PORT: READ for one cycle, then sample DOUT and pulse SHIFT, 57 times; the first
// bit out is the most significant. dout is DNA_PORT.DOUT; dna_read and dna_shift drive READ
// and SHIFT; the wrapper ties DIN to 0 and clocks DNA_PORT and this module from one BUFG.
const LAST_BIT : u8 = 56
var step : u8 = 0
var bits : u8 = 0
var dna : u64 = 0
var dna_read : bool = false
var dna_shift : bool = false
var done : bool = false
fn bit64(b: bool) -> u64 { if (b) { return 1; } return 0; }
fn on_clock(dout: bool) {
if (done == false) {
if (step == 0) { dna_read = true; step = 1; } else {
if (step == 1) { dna_read = false; step = 2; } else {
if ((step & 1) == 0) {
dna = (dna << 1) | bit64(dout);
if (bits == LAST_BIT) { done = true; } else { dna_shift = true; }
bits = bits + 1;
} else { dna_shift = false; }
step = step + 1;
}
}
}
}
test a_model_dna_port_reads_back_msb_first {
step = 0; bits = 0; dna = 0; dna_read = false; dna_shift = false; done = false;
var want : u64 = 26014484963072084;
var reg : u64 = 0;
var dout : bool = false;
var i : u32 = 0;
while (i < 200) {
var r : bool = dna_read;
var s : bool = dna_shift;
on_clock(dout);
if (r) { reg = want; } else { if (s) { reg = (reg << 1) % 144115188075855872; } }
dout = ((reg >> 56) & 1) == 1;
i = i + 1;
}
assert_eq(dna, want);
assert_eq(done, true);
}
Next
- Diff the CFG_CENTER frames of a vendor-built DNA_PORT design against the open-flow frames for the same die, to find the missing bits.
- Repeat on an Artix die (A, B or C) to see whether this is zynq7 only.
- Until then, the die's name comes from the JTAG reads (specs/verified/device_dna.t27), and specs/fpga/die_probe.t27 does not use DNA_PORT.
User Scenarios
- Given a Zynq XC7Z020 rev 2 (die D, IDCODE 0x23727093) and an open-flow bitstream built with prjxray-db zynq7, when the design instantiates DNA_PORT and sequences READ then SHIFT 57 times, then the 57-bit DNA field returned is all zeros while the read-done flag is set.
- Given the same die, when JTAG instructions XSC_DNA and FUSE_DNA are issued, then they return non-zero DNA values (XSC_DNA decoded
05c6c09473d1854, FUSE_DNA2a18bce290363a73). - Given the prjxray-db zynq7 database, when the FASM for a DNA_PORT design is inspected, then all six DNA_PORT pins route through
alwayspseudo-pips inppips_cfg_center_top.dbandppips_cfg_center_mid.dbwith no corresponding entries insegbits_cfg_center_top.db.
Requirements
- FR-001: The open-flow build MUST produce a bitstream that configures the CFG_CENTER frames necessary for DNA_PORT to return the die's DNA on die D.
- FR-002: The prjxray-db zynq7 database MUST represent any required configuration bits for DNA_PORT clock and data routes in
segbits_cfg_center_top.db(or equivalent) rather than only asalwayspseudo-pips. - FR-003: The
dna_read.t27minimal reproducer MUST pass its model test (t27c test-reportexit 0) and, when synthesized through the open flow and loaded on die D, MUST read a non-zero DNA value matching the JTAG reads. - FR-004: The
specs/fpga/die_probe.t27specification MUST be updated to use DNA_PORT for die identification once the open flow correctly reads DNA on die D. - FR-005: A frame diff between a vendor-built DNA_PORT bitstream and an open-flow DNA_PORT bitstream for the same die MUST identify the missing CFG_CENTER bits.
Success Criteria
t27c test-report specs/xilinx7/flow.t27exits 0 and shows the open-flow DNA_PORT sequence produces non-zero DNA on die D.- Frame diff of CFG_CENTER_TOP and CFG_CENTER_MID between vendor and open-flow bitstreams for die D yields a concrete list of missing bit addresses (count ≥ 1).
t27c test-report specs/verified/device_dna.t27exits 0 with 1 test passing (JTAG DNA reads).t27c test-report specs/fpga/die_probe.t27exits 0 with 1 test passing (die_probe uses DNA_PORT after fix).- New or updated
segbits_cfg_center_top.dbentries for DNA_PORT pins exist in prjxray-db zynq7 (verified by grepping the db).
Boundary
- specs/verified/device_dna.t27
- specs/fpga/die_probe.t27
- specs/xilinx7/flow.t27
- dna_read.t27
Activity