| #!/usr/bin/env python3 |
| |
| import sys |
| import textwrap |
| |
| # Very basic bitstream to SVF converter, tested with the ULX3S WiFi interface |
| |
| max_row_size = 8000 # needed for ULX3S Wifi |
| |
| |
| def bitreverse(x): |
| y = 0 |
| for i in range(8): |
| if (x >> (7 - i)) & 1 == 1: |
| y |= (1 << i) |
| return y |
| |
| with open(sys.argv[1], 'rb') as bitf: |
| bs = bitf.read() |
| # Autodetect IDCODE from bitstream |
| idcode_cmd = bytes([0xE2, 0x00, 0x00, 0x00]) |
| idcode = None |
| for i in range(len(bs) - 4): |
| if bs[i:i+4] == idcode_cmd: |
| idcode = bs[i+4] << 24 |
| idcode |= bs[i+5] << 16 |
| idcode |= bs[i+6] << 8 |
| idcode |= bs[i+7] |
| break |
| if idcode is None: |
| print("Failed to find IDCODE in bitstream, check bitstream is valid") |
| sys.exit(1) |
| print("IDCODE in bitstream is 0x%08x" % idcode) |
| bitf.seek(0) |
| with open(sys.argv[2], 'w') as svf: |
| print(""" |
| HDR 0; |
| HIR 0; |
| TDR 0; |
| TIR 0; |
| ENDDR DRPAUSE; |
| ENDIR IRPAUSE; |
| STATE IDLE; |
| """, file=svf) |
| print(""" |
| SIR 8 TDI (E0); |
| SDR 32 TDI (00000000) |
| TDO ({:08X}) |
| MASK (FFFFFFFF); |
| """.format(idcode), file=svf) |
| print(""" |
| SIR 8 TDI (1C); |
| SDR 510 TDI (3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF |
| FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF); |
| |
| SIR 8 TDI (C6); |
| SDR 8 TDI (00); |
| RUNTEST IDLE 2 TCK 1.00E-02 SEC; |
| |
| SIR 8 TDI (3C); |
| SDR 32 TDI (00000000) |
| TDO (00000000) |
| MASK (0000B000); |
| |
| SIR 8 TDI (46); |
| SDR 8 TDI (01); |
| RUNTEST IDLE 2 TCK 1.00E-02 SEC; |
| |
| SIR 8 TDI (7A); |
| RUNTEST IDLE 2 TCK 1.00E-02 SEC; |
| |
| """, file=svf) |
| while True: |
| chunk = bitf.read(max_row_size//8) |
| if not chunk: |
| break |
| # Convert chunk to bit-reversed hex |
| br_chunk = [bitreverse(x) for x in chunk] |
| hex_chunk = ["{:02X}".format(x) for x in reversed(br_chunk)] |
| print("\n".join(textwrap.wrap("SDR {} TDI ({});".format(8*len(chunk), "".join(hex_chunk)), 100)), file=svf) |
| |
| print(""" |
| SIR 8 TDI (FF); |
| RUNTEST IDLE 100 TCK 1.00E-02 SEC; |
| |
| |
| SIR 8 TDI (C0); |
| RUNTEST IDLE 2 TCK 1.00E-03 SEC; |
| SDR 32 TDI (00000000) |
| TDO (00000000) |
| MASK (FFFFFFFF); |
| |
| ! Shift in ISC DISABLE(0x26) instruction |
| SIR 8 TDI (26); |
| RUNTEST IDLE 2 TCK 2.00E-01 SEC; |
| ! Shift in BYPASS(0xFF) instruction |
| SIR 8 TDI (FF); |
| RUNTEST IDLE 2 TCK 1.00E-03 SEC; |
| |
| ! Shift in LSC_READ_STATUS(0x3C) instruction |
| SIR 8 TDI (3C); |
| SDR 32 TDI (00000000) |
| TDO (00000100) |
| MASK (00002100); |
| """, file=svf) |