SystemVerilog: writing into an array using a write pointer

1.5k Views Asked by At

imagine that I have a certain buffer of bytes and a write pointer for this buffer, like:

reg[N-1:0][7:0]mybuffer;
reg[$clog2(N+1)-1:0] wptr;

where wptr points to the next position in the buffer where I want to store incoming data.

Now, imagine that my input data is also a block of bytes, like:

reg[M-1:0][7:0] indata;

with M < N.

If I code something like:

mybuffer[wptr +: M] = indata;

everything works, with the noticeable exception of when wptr > N-M, which in my application will never happen.

However, this doesn't seem a very clean way to approach the problem, and cause warnings with linting tools. Extending the buffer doesn't seem a nice approach either.

What is a clean and correct way to implement something like this?

Thanks.

1

There are 1 best solutions below

2
Serge On

I will explain my comment in the answer field here.

You have declared both indata and mybuf as 2-dimensional reg arrays:

reg[N-1:0][7:0]mybuffer;
reg[M-1:0][7:0] indata;

So, the above declares packed arrays of vectors, where the second dimension [7:0] is dimension of the vector in the memory. Usually in this situation the wptr handles the first dimension. Something like the following:

always @(posedge clk) begin
   mybuffer[wrpt] <= indata[wrpt];
   if (wrpt == M - 1)
      wrpt <= 0; // this will prevent from coping indexes from M to N-1
   else
      wrpt <= wrpt + 1;
end

so, wrpt pointer points to the next 8-bit chunk. Otherwise I see no reason to have this pointer at all. For bulk copy you can just have something like the following:

   always_comb mybufer = indata;

The above is possible for packed arrays which you declared (or unpacked arrays with the same ranges)

Update: Added another example

I guess, based on your question you are looking for some solution where you can repeatably insert 'indata' into 'mybuffer' till the latter gets filled up. In this case something like the following could be done, using remainder R.

parameter N = 10;
parameter M = 3;
parameter R = N % M;

initial begin 
  int wrpt;
  for (wrpt = 0; wrpt < N; wrpt  += M) 
    mybuffer[wrpt  +: M ] = indata;
  
  if (R != 0)
    mybuffer[(wrpt - N)  +: R ] = indata[0 +: R];
end