Skip to content

open flow: DNA_PORT reads 0 on a Zynq XC7Z020 (die D); prjxray lists its pins as always-on pseudo-pips #8661

Open

Description

@gHashTag

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, decoded 05c6c09473d1854;
  • 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_DNA 2a18bce290363a73).
  • Given the prjxray-db zynq7 database, when the FASM for a DNA_PORT design is inspected, then all six DNA_PORT pins route through always pseudo-pips in ppips_cfg_center_top.db and ppips_cfg_center_mid.db with no corresponding entries in segbits_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 as always pseudo-pips.
  • FR-003: The dna_read.t27 minimal reproducer MUST pass its model test (t27c test-report exit 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.t27 specification 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.t27 exits 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.t27 exits 0 with 1 test passing (JTAG DNA reads).
  • t27c test-report specs/fpga/die_probe.t27 exits 0 with 1 test passing (die_probe uses DNA_PORT after fix).
  • New or updated segbits_cfg_center_top.db entries 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

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions