# Problem initializing Xilinx BRAM

A while ago I added a feature to GNU binutils to convert files to verilog mem files, suitable for reading with $readmemh. The output is very close to what you might get with xilinx's data2mem utility. I am using both systems to try to initialize a BRAM with$readmemh, and in my code, it only seems to work with data files 0x300 bytes long or less.

The mem files start with @00000000, and have a couple of other @ lines, but there are no gaps in the data. Here's a sample input:

// 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, in this case, gives me a couple of errors like this: WARNING:HDLCompiler:568 - "Unknown" Line 0: Constant value is truncated to fit in <8> bits and the BRAM doesn't appear to be initialized in any recognizable way for files greater than 0x300 (that is.. my core is reading unexpected instructions from the resulting BRAM).

If I strip out the 3 @ lines (@00000000, @00000300 and @00000318) I don't get these warnings and everything appears to work perfectly. What's going on??

For what it's worth, here's my simple module reading the data file:

https://github.com/atgreen/moxie-cores/blob/master/soc/marin/rtl/bootrom16.v

Thanks!

• What devices are you targetting? And what version of XST? – Martin Thompson Mar 14 '13 at 1:16
• $readmemh is really a command to a simulator, rather than a synthesis construct. There are formal ways to specify an initialization file if you explicitly instantiate a block ram, it sounds like you may be inferring one (or perhaps you are actually inferring a LUT ram, or a different size block ram than you think). Essentially my advice is that when you encounter weirdness, consider telling the tool explicitly what you want in its terms. Also consider if the initialization data may need to be a in a different width * length format than the way you are using the BRAM. – Chris Stratton Mar 14 '13 at 1:19 • @Martin I'm targeting a spartan6 on a nexys3 board ... xc6slx16-3-csg324 , and using xst 14.4. – AnthonyGreen Mar 14 '13 at 1:23 • @Chris, yes, I am inferring the BRAM. I thought that would be easiest, and it worked for a while. I guess I need pointers on doing it any other way. – AnthonyGreen Mar 14 '13 at 1:25 • your paste links seem broken - can you inline the code? – Martin Thompson Mar 14 '13 at 11:26 ## 1 Answer This old thread implies it doesn't work: http://forums.xilinx.com/t5/Synthesis/Error-initializing-memory-using-readmemh-Xst-2319-bug/td-p/44680 The XST synthesis guide says $readmemh is supported, but doesn't say much more about the level of support...

• Well, I guess I shouldn't be surprised. It's just one more Xst disappointment in the growing list... – AnthonyGreen Mar 16 '13 at 14:22