COE File embedded in BIT file?


Recommended Posts



my name is Patrick and I am a computer scientist. I am starting to dive a bit into FPGAs (and in my case VHDL).


So after doing some basic stuff, I wanna try to emulate a ROM IC for an old german gaming console much like the Atari 2600.


So the task is basically turning an 11 bit address input into (the correct) 8 bit data output aswell as matching/shifting the levels (5V to 3.3V (input into Papilio), 3.3V to 5V (output of Papilio)) and fulfill the right timing constraint (~400ns between adress input and data output).


I used an IP Core/Vendor module (Block memory generator/Single port ROM) for the ROM memory and initialized it with a COE file. In the simulator everything is working fine and i can see the change of the data output according to the change of the address input change. But when I look into the generated BIT file I cannot see that the data from the COE file is embedded in it. I cannot find e.g. the first two byte sequence in the BIT file.  


So my question is: Is the ROM initialization (COE file) embedded into the BIT file or do I need to so some extra steps such that the ROM initialization is embeeded into the configuration/BIT file. Is this even possible since due to the "black box"-warning of the Xlinix ISE I guess nothing for the ROM module is even generated into the BIT file?


Sorry, if this is a beginners question.

Link to comment
Share on other sites



you could compare with an inferred ROM to "test your testbench".

Attached is a (Verilog) example for a dual-port memory that (usually) results in RAMB instantiations during synthesis.


Here it -is- used as RAM but if you replace this part


   integer    ix;
     for (ix = 0; ix < 'h1FF; ix = ix + 1)
       ram[ix] = 0;



initial begin ram[0] = 123; ram[1] = 234; ... end


and don't write, you can use it as ROM.

The initial values do get synthesized correctly, otherwise the synthesis tool would be seriously broken.

Note the added register stage => output changes only after 2 clock cycles.


Personally, I'd avoid IP blocks wherever possible, instead use generic inferable code.

Link to comment
Share on other sites

In Verilog you can also use $readmemh to initialize the ROM data.


Here is an example of a 1Kword 16-bit ROM initialized from a file:


  reg [15:0] mem [1023:0];

  reg [15:0] romDataOut;

  initial $readmemh("rom.mem", mem);
  always @(posedge clk)
    romDataOut <= mem[memoryAddr]];


The rom.mem file is just a list of hexadecimal values for the ROM data, like this:







Link to comment
Share on other sites

I would guess that the memory (BRAM) contents included in the bitstream are either compressed or scrambled.  At any rate, looking at the .bit file from my current design, I don't find the strings from my program.  But I believe it's there, otherwise it wouldn't work.


I agree with offroad's statement regarding inferring memories rather than using the Xilinx core blocks.  It's easy, it's portable, and it harmonizes nicely with your Verilog or VHDL code.

Link to comment
Share on other sites



You can verify whether the data has been loaded to your bit file by using the Xilinx data2mem tool:


This should dump the contents of the bit file to a text file you can read, then search for the BRAM sections:

data2mem -bm {bmmfilename}.bmm -bt {bitfilename}.bit -d > out.dmp

This is the format I have in my notes to use it, I believe the bmm file should be optional.



Link to comment
Share on other sites

You can also use data2mem to merge data into your bit file instead of using the coe file.


You need to add a bmm file to your project to do so, there should be guides on the Internet how to create a BMM file. Then the command would be:

data2mem -bm {bmmfilename}.bmm -bt {bitfilename}.bit -bd out.mem -o b out.bit

You can look at this Makefile for an example of it in action:



Link to comment
Share on other sites



thanks for all the useful answers.


Instead of using the IPCore from Xilinx (Block Memory Generator), I am now using an array as I found it here: reading values from the array I do not use a case-statement as used in this post but rather converting the STD_LOGIC_VECTOR into an usigned integer with 'data_out <= my_rom(to_integer(unsigned(addr_in)));'.


I still don't see the values in the bit file. So I think my biggest mistake was to assume that those (plain) values must somehow be contained in the generated bit file.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.