Hace un tiempo, agregué una función a GNU binutils para convertir archivos a archivos mem verilog, adecuados para leer con $ readmemh. La salida está muy cerca de lo que podría obtener con la utilidad data2mem de xilinx. Estoy usando ambos sistemas para intentar inicializar un BRAM con $ readmemh, y en mi código, parece que solo funciona con archivos de datos de 0x300 bytes de longitud o menos.
Los archivos mem comienzan con @ 00000000 y tienen un par de otras @ líneas, pero no hay espacios en los datos. Aquí hay un ejemplo de entrada:
// MEM file.
//
// Release 14.1 - Data2MEM P.49d, build 2.8 Mar 16, 2012
// Copyright (c) 1995-2013 Xilinx, Inc. All rights reserved.
//
// Command: data2mem -bd bootrom.elf -d -o m bootrom.mem
//
// bootrom.elf
// Program header record #0, Size = 0x300, at 0x00000000 to 0x000002FF.
@00000000
01 10 10 00 0C 00 2E 00 01 20 10 00 00 00 01 30 00 00 13 18 01 40 10 00 00 08 29 42 2E 55 0E 45
C0 0C 0C 63 00 00 00 00 0D 26 00 00 00 00 82 04 83 04 94 01 1A 00 00 00 10 1E 01 20 10 00 00 08
01 30 10 00 00 2C 2E 44 0E 23 C0 07 0D 24 00 00 00 00 82 04 1A 00 00 00 10 48 01 20 00 00 FE ED
24 20 F0 00 00 00 2E 22 2E 33 2E 44 03 00 00 00 12 32 1A 00 00 00 10 72 06 1B 91 18 01 30 00 00
13 1B 01 20 00 00 13 18 29 32 01 40 00 00 00 06 0E 34 D4 04 02 E0 9E 04 07 EB 04 00 01 30 00 00
00 00 2E 44 0E 34 C3 F6 19 30 1A 00 00 00 10 94 06 1B 91 18 01 40 00 00 13 18 01 20 00 00 13 18
29 42 01 30 00 00 00 02 2D 43 01 30 00 00 00 1F 02 54 27 53 02 35 05 34 01 40 00 00 00 01 2D 34
2E 44 0E 34 C4 04 02 E0 9E 04 07 EB 04 00 01 50 00 00 00 00 0E 54 C3 F7 19 50 1A 00 00 00 10 E6
06 18 06 19 06 1A 06 1B 91 18 01 30 00 00 00 18 1D 20 10 00 00 08 28 23 27 23 2E 33 0E 23 C4 32
08 20 10 00 00 0C 01 80 00 00 13 0C 01 90 00 00 13 08 29 89 01 A0 00 00 00 02 2D 8A 98 01 0E 28
E0 0E 82 01 09 20 10 00 00 0C 28 2A 02 39 05 32 0A 23 19 20 08 20 10 00 00 0C 0E 28 D3 F2 03 00
00 00 10 78 01 30 00 00 00 00 2E 22 0E 32 C0 04 01 20 00 00 13 10 19 30 1B 20 00 00 00 01 1F 20
10 00 00 08 02 E0 9E 10 07 EB 07 EA 07 E9 07 E8 04 00 91 18 04 00 06 1B 91 18 01 40 00 00 00 00
2E 22 0E 42 C0 07 01 20 00 00 13 10 01 30 10 00 00 10 19 40 2E 22 08 30 00 00 13 14 0E 32 C0 09
01 30 00 00 00 00 0E 32 C0 04 01 20 00 00 13 14 19 30 03 00 00 00 10 B0 02 E0 9E 04 07 EB 04 00
91 18 04 00 06 1B 01 20 00 07 A1 20 2E 33 0F 00 92 01 0E 23 C7 FC 02 E0 9E 04 07 EB 04 00 06 1B
01 40 00 00 00 01 0E 34 C0 08 01 40 00 00 00 03 0E 34 C0 07 2E 44 0E 34 C4 08 82 02 1A 00 00 00
12 2A 82 06 1A 00 00 00 12 2A 02 E0 9E 04 07 EB 04 00 06 18 06 19 91 18 2E 22 01 90 00 00 11 E4
02 82 88 01 24 20 F0 00 00 00 19 90 02 28 1A 00 00 00 12 40 91 0C 0B 10 02 01 06 12 06 13 06 14
06 15 06 16 06 17 06 18 06 19 06 1A 06 1B 06 1C 06 1D 06 1E 06 1F A2 05 A3 02 A4 03 03 00 00 00
11 FE 0D 02 00 00 00 04 02 20 92 38 02 12 07 1F 07 1E 07 1D 07 1C 07 1B 07 1A 07 19 07 18 07 17
07 16 07 15 07 14 07 13 07 12 04 00 06 18 06 19 06 1B 91 18 08 20 00 00 13 00 01 90 FF FF FF FF
0E 29 C0 0A 01 80 00 00 12 FC 19 20 98 04 0C 28 00 00 00 04 0E 29 C7 F9 02 E0 9E 0C 07 EB 07 E9
07 E8 04 00 91 18 04 00 03 00 00 00 11 96 03 00 00 00 12 AC 04 00 03 00 00 00 11 00 04 00 00 00
// Program header record #1, Size = 0x18, at 0x00000300 to 0x00000317.
@00000300
FF FF FF FF 00 00 00 00 FF FF FF FF 00 00 00 00 00 00 00 00 00 00 00 00
// Program header record #2, Size = 0x8, at 0x00000318 to 0x0000031F.
@00000318
00 00 00 00 55 55 55 55
xst, en este caso, me da un par de errores como este: ADVERTENCIA: HDLCompiler: 568 - "Desconocido" Línea 0: el valor constante se trunca para que quepa en < 8 > pedacitos y el BRAM no parece estar inicializado de ninguna forma reconocible para archivos superiores a 0x300 (es decir, mi núcleo está leyendo instrucciones inesperadas del BRAM resultante).
Si elimino las líneas 3 @ (@ 00000000, @ 00000300 y @ 00000318) no recibo estas advertencias y todo parece funcionar perfectamente. ¿Qué está pasando?
Para lo que vale, aquí está mi módulo simple leyendo el archivo de datos:
¡Gracias!