#!/usr/bin/env python3 # retroDE_ps2 — bin_to_hex # # Convert a raw 32-bit binary image (e.g. a PS2 BIOS dump) to the text # hex format iverilog's $readmemh expects: one 32-bit word per line, # hex (no 0x prefix), newline-terminated. iverilog reads the first line # into memory index 0 and advances by one per line. # # Typical usage: # python3 sim/golden/bin_to_hex.py path/to/ps2_bios.bin > /tmp/bios.hex # make -C sim tb_iop_core_bios_smoke BIOS=/tmp/bios.hex # # Endianness: # PS2 BIOS images on disk are little-endian byte order, which matches # how the core will see each 32-bit word once it's fetched from the # bios_rom_stub backing memory. We emit words using ` int: parser = argparse.ArgumentParser( description="Convert a binary BIOS image to hex-text for $readmemh.") parser.add_argument("input", help="input .bin file") parser.add_argument( "-o", "--output", help="output .hex path (default: stdout)") parser.add_argument( "--words", type=int, default=DEFAULT_SIZE_WORDS, help=f"total words to emit (default {DEFAULT_SIZE_WORDS}, the " f"bios_rom_stub default depth)") parser.add_argument( "--pad", default="00000000", help="pad word used when input is shorter than --words " "(default 00000000 = SLL $0,$0,0 = NOP)") args = parser.parse_args() with open(args.input, "rb") as fh: raw = fh.read() if len(raw) % 4 != 0: print( f"warning: input length {len(raw)} not a multiple of 4; " "trailing bytes dropped", file=sys.stderr) raw = raw[: len(raw) - (len(raw) % 4)] words = list(struct.iter_unpack(" args.words: print( f"error: input has {n_input} words but only {args.words} " "will be emitted; refusing to truncate", file=sys.stderr) return 2 out_fh = open(args.output, "w") if args.output else sys.stdout try: for (w,) in words: out_fh.write(f"{w:08x}\n") pad_word = int(args.pad, 16) for _ in range(args.words - n_input): out_fh.write(f"{pad_word:08x}\n") finally: if args.output: out_fh.close() print( f"[bin_to_hex] wrote {args.words} words " f"({n_input} from input, {args.words - n_input} pad) " f"to {args.output or 'stdout'}", file=sys.stderr) return 0 if __name__ == "__main__": sys.exit(main())