diff --git a/exi_bba/bba_top.py b/exi_bba/bba_top.py index 1e740a1..ca8e363 100644 --- a/exi_bba/bba_top.py +++ b/exi_bba/bba_top.py @@ -424,6 +424,13 @@ if __name__ == "__main__": # delays: one half-period = HALF * (1/54 MHz), preserving the old meaning # of HALF so the rates in the table above still hold. HP = Period(MHz=54) * HALF + # Gap between transactions (CS high). cs_active reaches the exi domain + # through a 2-stage FFSynchronizer at 24 MHz, so CS must stay high for + # ~3 exi cycles or the register file never sees the transaction end and + # swallows the next one's header as data. At EXI_HALF=1 one HP is only + # 18.5 ns, far too short -- a real host leaves microseconds between + # exi_deselect() and the next exi_select(). + CS_GAP = Period(MHz=24) * 6 async def spi_byte(ctx, mosi_val): """Drive one EXI Mode-3 byte; return the assembled MISO byte.""" @@ -457,7 +464,7 @@ if __name__ == "__main__": await ctx.delay(HP * (HALF * 12)) result = [await spi_byte(ctx, 0x00) for _ in range(length)] ctx.set(dut.exi_cs_n, 1) - await ctx.delay(HP * (HALF)) + await ctx.delay(CS_GAP) return result async def exi_write(ctx, addr, data): @@ -472,7 +479,7 @@ if __name__ == "__main__": for b in data: await spi_byte(ctx, b) ctx.set(dut.exi_cs_n, 1) - await ctx.delay(HP * (HALF)) + await ctx.delay(CS_GAP) async def exi_devid(ctx): """EXI_GetID: write 0x0000 (two bytes) then clock four read bytes.""" @@ -484,7 +491,7 @@ if __name__ == "__main__": await ctx.delay(HP * (HALF * 12)) out = [await spi_byte(ctx, 0x00) for _ in range(4)] ctx.set(dut.exi_cs_n, 1) - await ctx.delay(HP * (HALF)) + await ctx.delay(CS_GAP) return out # ── W5100 indirect-bus slave model (drives w5100_data_i) ───────────── diff --git a/exi_bba/exi_capture.py b/exi_bba/exi_capture.py index 2567435..909d8ed 100644 --- a/exi_bba/exi_capture.py +++ b/exi_bba/exi_capture.py @@ -181,6 +181,12 @@ if __name__ == "__main__": # ratio is ~2; use 4 here for a clean, well-oversampled functional check. HALF = 4 + # No capture domain any more: the bit engine is clocked by the EXI + + # pin, so drive the SPI clock with real delays instead of ticks. + + HP = Period(MHz=54) * HALF + async def spi_byte(ctx, mosi_val): """Clock one SPI Mode 3 byte; return the assembled MISO byte.""" miso = 0 diff --git a/exi_bba/exi_j4.py b/exi_bba/exi_j4.py index 923a44b..97e9cc9 100644 --- a/exi_bba/exi_j4.py +++ b/exi_bba/exi_j4.py @@ -42,6 +42,15 @@ if __name__ == "__main__": from exi_bba.bba_top import BBATop HALF = 8 # capture ticks per SPI half-period (well oversampled) + + + # No capture domain any more: the bit engine is clocked by the EXI + + + # pin, so drive the SPI clock with real delays instead of ticks. + + + HP = Period(MHz=54) * HALF DEVICE_ID = [0x04, 0x02, 0x02, 0x00] class _Harness(Elaboratable):