Add a per-speed raw dump to the GC test app
Removing ~9 ns from the MISO path (EXI_J4 merge, the CS mux, then the whole fabric route via an SB_IO output register) left the hardware result BYTE IDENTICAL: 0B 80 at index 5, ok=[1,1,1,1,1,0]. A ~9 ns reduction against an 18.5 ns half-period budget cannot change nothing if propagation were the cause, so it is not, despite being speed-dependent. t_raw_sweep reads the same 8 slots at EVERY speed index and reports the first two bytes per index, so the shift can be seen as a curve rather than a single point: a shift that appears or grows with clock rate is a timing problem, one that is constant across indices is structural. Run against a PHASE_METER bitstream it reads the bit engine's byte phase directly at each speed, with the register file and both byte FIFOs out of the path. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -186,6 +186,36 @@ static int t_gap_sweep(char *m, size_t n)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int t_raw_sweep(char *m, size_t n)
|
||||
{
|
||||
/* The SAME 8-slot read at EVERY speed index, reported as the first two
|
||||
* bytes per index. This is the measurement that distinguishes the two
|
||||
* remaining explanations for a one-bit MISO lag:
|
||||
* - a shift that APPEARS or GROWS with clock rate is a timing problem;
|
||||
* - a shift that is constant across indices is structural.
|
||||
* Run it against a PHASE_METER bitstream and every byte should read 80
|
||||
* (aligned) / 40 (one bit late) / 20 (two bits late), with the register
|
||||
* file and both byte FIFOs out of the path entirely. */
|
||||
u32 saved = bba_speed, s;
|
||||
int off = 0, bad = 0;
|
||||
m[0] = 0;
|
||||
for (s = 0; s <= EXI_SPEED32MHZ; s++) {
|
||||
u8 b[8];
|
||||
bba_speed = s;
|
||||
if (bba_read(REG_NWAYS, b, sizeof(b)) < 0) {
|
||||
off += snprintf(m + off, n - off, "%u:ERR ", (unsigned)s);
|
||||
bad++;
|
||||
continue;
|
||||
}
|
||||
off += snprintf(m + off, n - off, "%u:%02X%02X ",
|
||||
(unsigned)s, b[0], b[1]);
|
||||
if (b[0] != NWAYS_LINKUP)
|
||||
bad++;
|
||||
}
|
||||
bba_speed = saved;
|
||||
return bad ? 1 : 0;
|
||||
}
|
||||
|
||||
static int t_raw_reg(char *m, size_t n)
|
||||
{
|
||||
/* Clock EIGHT data bytes for a one-byte register read and show them all.
|
||||
@@ -361,6 +391,7 @@ static test_t s_exi[] = {
|
||||
{"Gap sweep", "min header->data idle gap the device needs", t_gap_sweep, T_PENDING, {0}},
|
||||
{"Raw reg dump", "8 slots of a NWAYS read - WHERE does 0x17 land?", t_raw_reg, T_PENDING, {0}},
|
||||
{"Raw ID dump", "8 slots of the device-ID query - where is 0x04?", t_raw_id, T_PENDING, {0}},
|
||||
{"Per-speed dump","first 2 slots at EVERY speed - does the shift move?",t_raw_sweep, T_PENDING, {0}},
|
||||
};
|
||||
static test_t s_eth[] = {
|
||||
{"MAC readback", "PAR0-5 hold a Nintendo-OUI MAC", t_mac_read, T_PENDING, {0}},
|
||||
@@ -376,7 +407,7 @@ suite_t g_suites[] = {
|
||||
{"Identity", "device enumerates and reports itself", s_identity, 3},
|
||||
{"Registers", "register file is readable and writable", s_regs, 4},
|
||||
{"Reset/control", "NCRA reset and control bits behave", s_reset, 2},
|
||||
{"EXI integrity", "the EXI link is error-free, and how fast", s_exi, 5},
|
||||
{"EXI integrity", "the EXI link is error-free, and how fast", s_exi, 6},
|
||||
{"Ethernet", "frames get to and from the W5100", s_eth, 3},
|
||||
{"SPRAM/DMA", "bulk reads stream correctly from the ring", s_spram, 2},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user