Store std_logic bits in ascending order into a large array

1.1k views Asked by At

I have an array of 2048-bits and i would want to store the incoming bits from 0 - 2047 in ascending bit order as it comes in FPGA on each rising edge of the clock cycle.

Eg:

array[0] <= 1st bit
array[1] <= 2nd bit
...
..
array[2047] <= 2048 th bit.

i know it can be done in VHDL by array indexing like

array(index) <= incoming_bit.

However, is there any other better approach like using bitwise operations (shifting) to achieve this. (without array indexing method), so that it eventually reduces the routing complexity in the FPGA.

3

There are 3 answers

2
Bruno JJE On BEST ANSWER

Block RAM

The most efficient way to overcome routing problem in the case you describe is probably to store the bit in a block ram.

If you use the array you describe with a code written in the correct way, it is probably already what the synthesizer has infered for you.

But if you have used a reset in your code to load your array with all '0', the synthesizer won't be able to infer a BlockRAM, thus producing something that will probably not be as efficient.

FIFO

If you always use the bits one after the other, and don't use it after that, you can use a FIFO (that will probably be implemented with a BlockRAM by the synthesizer).

The bits will be stored in the FIFO as they come in, and only the oldest not yet processed bit will be presented to you at the output of the FIFO.

If the position of the bit matters, you can have a 11 bits counter that increment each time you read a bit from the fifo, thus it will always reflect the position of the bit you are fetching out of the FIFO.

Hope this helps.

7
Morgan On

Barrel Shifter

If access to data is not required until loading 2048 is complete then in verilog you can imply a barrel shifter. Every clock cycle the data gets shifted down 1 position. At the end of the 2048 bits every thing would be in the correct place.

reg [2048-1:0] arr;

always @( posedge clk or negedge rst_n) begin
  if (~rst_n) begin
    arr <= 'b0;
  end
  else begin
    arr[2048-1:0] <= {data_in, arr[2048-1:1]} 
  end
end

RAM

If access to first bits are required before the full 2048 bits have been loaded a RAM is ideal for this. RAMs typically can not be initialised in 1 clockcycle, no async reset. Therefore you must only read data from locations you have written to. You can specify initial conditions for an FPGA and I believe the FPGA startup routing can initialise it for you. but no easy way to clear it once running.

input            data_in;
input [10:0]     wr_addr;
reg   [2048-1:0] arr;

always @( posedge clk ) begin
  arr[wr_addr] <= data_in; 
end

// Optional FPGA initialisation
integer i;
initial begin
  for(i=0; i<2048; i=i+1) begin
    arr[i] <= 'b0;
  end
end
0
Martin Thompson On

Fundamentally, if you need access to all the bits at once, there's not much you can do about the routing complexity - the inputs and outputs all have to be there all the time.

If (on the other hand) you are getting the input bits one at a time (or only need access to them one at a time), then you could store them in a memory block which will reduce the resource usage.