I'm trying to understand the intricacies of implementing a ROM in an FPGA. I've searched around and come up with some useful tidbits, but I was hoping someone here could clear up a few issues with doing it "right" for those looking to learn. I would greatly appreciate any comments on the "correctness" of the following (using VHDL):

- There seem to be two common ways to do the implementation: one is to create an array and essentially index into it using a mux, the other seems to involve generating RAM with predefined values and then defining it as read-only. The latter seems to be preferred for large LUTs (why?).

-- On that note, is there a preferred template for doing the latter? I know what a RAM template looks like, how does one go about forcing it to predefined values and setting it to read only? (or is it just a matter of directing the RAM input/enable ports nowhere)

-- Also, I notice Altera has a ROM megafunction, am I restricted (at least in terms of ease of creation) to the altera megafunction or is it relatively easy to roll my own RAM based ROM?

- Are there any particular considerations if I am looking for a dual ported ROM? (except for the fact that the megafunction doesn't seem to support dual ports)

- What about initialization? Right now I have a Matlab file that spits out text that is formatted such that I can cut and paste. Is there an easier way with the VHDL file read functions, that still remains synthesizable? Any considerations in this regard for RAM based versus mux based?

For the curious, I'm trying my hand at direct digital synthesis: this is a 1/2 wave LUT (the other half is just the negative of the first, done on the fly, I haven't tried to reduce this to 1/4 yet). The dual ports stem from the need to access the sine and cos portion (phase and phase-(1/4 wave length) index).

I realize this topic roughly comes up in one form or another every now and then, but I am trying to put the knowledge in one place and figure out how to do it "right" for the sake of learning.



Reply to
Chris Maryan
Loading thread data ...

Most FPGAs have internal RAM blocks for the specific purpose of implementations of memory-based constructs such as roms, rams, fifos etc. Using these RAM blocks as intended obviously gives best resource allocation usage and performance, not to mention build times.

You can roll your own, yes, however vendor-specific synthesis tools will often infer implementations based on these RAM blocks, so you end up with the same result.

The altera megafunctions are simply gui tools that produce wrappers around the various entities for the device resources. For example, I took the VHDL output of a megafunction for a dual-port RAM and added generics to allow me to instantiate dual-port RAMs of any width/depth using my modified wrapper, negating the need to generate a plethora of megawizard objects.

FWIW you can also instruct the megawizard explicitly to implement the memory in logic (LUT) or RAM blocks if you so desire. IIRC the default setting is AUTO, where it chooses for you.

There are certainly dual-port megafunctions for rom & ram, so I'm not sure why you can't find them?

As for initialisation, by far the best and most flexible way I've found is to use intel .hex file formats. They have the advantage that they're easy to produce from other sources, and the same file will work for both synthesis and simulation (eg ModelSim). IMHO, don't touch .MIF files.

On an Altera-based platform, I'd still use the megawizard (Memory Compiler->ROM: 2-PORT). If you're curious, look at the Verilog/VHDL output and you can see how it thinly wraps an altsyncram resource.


Mark McDougall, Engineer
Virtual Logic Pty Ltd, 
 Click to see the full signature
Reply to
Mark McDougall

See the ROM example here:

formatting link

-- Mike Treseler

Reply to
Mike Treseler

It's a matter of size. A LUT with 4 bits input and one bit output may be within your technology only one gate. A ROM with 16 bit input and

16 bit output may be very easy (for example each output is depending on only one input) and therefore be no more than a few gates, or very complex. Each output bit might be a function of each input bit (here are again more simple functions possible (like AND of all 16 bit inputs) or complex functions (eg. AND of 14 inputs if the last two are "00" else OR of 14 inputs if the last two inputs are "11" else something completely different). A ROM based on RAM has allways a defined size (which might be degrees smaller than a LUT).

bye Thomas

Reply to
Thomas Stanka

There are other coding styles to create a ROM, see the (oldish) paper below although I would stick to whatever is recommended by your synthesis tool.

formatting link


formatting link

The latter seems to be preferred for large

Reply to

I've always coded the former, and ended up (post-synthesis) with the latter :-) For very small ROMs, the synth tool might not produce a RAM block, unless you provide it with some guidance through attributes or similar.

Writing a constant array and then indexing into it is a trivial bit of code, it states clearly to the reader what you want to do and you can leave the "how" bit to the synth tool.

Write your matlab so that it spits out a file which is valid VHDL, just a package body and the constant you need. Put the package with a deferred constant in a separate file.

Then you need only compile your matlab generated file when it changes and rerun your simulation very quickly.

I've never had much joy with using external files for initialising values, they work fine for simualation, but synth tools don't support file reading functions, even for init yet...

One thing to be aware of if this goes into any kind of system that needs to be robust: You can end up with a corrupted ROM if your clock goes awry:

formatting link

Cheers, Martin

TRW Conekt - Consultancy in Engineering, Knowledge and Technology
 Click to see the full signature
Reply to
Martin Thompson

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.