I have a piece of memory which I need to access cell by cell:

parameter RAM_LENGTH = 1024;
reg [7:0] mem [RAM_LENGTH - 1:0];

I need to iterate cells sequentially. It looks like there are at least two ways to do this. The first approach is to index memory as if it were C array of bytes:

reg [7:0] ram_addr = 0;    
reg [7:0] current;

and then

current = mem[ram_addr];
ram_addr = ram_addr + 1;

This is cheap for CPU. But what if Verilog builder will attempt to build a 1024 channel 8 byte width multiplexer for me? This would be a digital circuit of tremendous size that this memory may not deserve. Or is the Verilog builder smart enough to implement access by index more reasonably?

The alternative approach would be to shift the cells every time the value is needed:

current <= mem[0];
for (i = 1; i < RAM_LENGTH; i++)
  mem[i] <= mem[i-1];

in this case, I would hope from the builder to generate a shift register rather than overgrown multiplexer, as all values that define the loop are constants.

Which approach is more reasonable and would be typically used by an experienced Verlilog developer?

  • \$\begingroup\$ "s the Verilog builder smart enough to implement access by index more reasonably?" - if it infers or is specified as a "block RAM", then these come with an efficient decoder as part of the design, both in FPGA and ASIC flows. \$\endgroup\$ – pjc50 Feb 26 '18 at 13:31

Both approaches are viable, depending on what you want the synthesized implementation to be.

The indexed version would typically be used if you want the memory to be implemented using the internal block ram in the target device. In this case, the clock speed is limited by the memory access time.

The shift register version will use the registers in the logic cells, or in the case of Xilinx could use the SRL shift register mode of the LUTs. The shift register mode could potentially be faster, but it will use more routing and LUT resources.

In any case, you can always directly instantiate FPGA specific logic blocks in order to remove any ambiguity about how things get synthesized. The "generate custom IP" functions of FPGA development environments allow you to generate custom sized memories, FIFOs, shift registers, etc.


Use block RAM to construct a FIFO buffer. All of the FPGA vendors have a "wizard" of some sort to help configure FIFOs, since it's such a commonly-used subcircuit.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.