0

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.

arandomuser
  • 521
  • 1
  • 7
  • 22
  • 1
    it seems that all your data is 8-bit wide. Why not use a simple indexing then, `mybuffer[wptr]`? you will get `x` values if wptr >=M. So, you might want to add a checker for wpttr value. – Serge Jun 30 '20 at 16:13
  • @Serge thanks for you comment. What do you mean exactly? I need to bulk copy ```indata``` into ```mybuffer```, how can I use simple indexing? – arandomuser Jun 30 '20 at 16:37

1 Answers1

1

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



Serge
  • 11,616
  • 3
  • 18
  • 28
  • thanks again! Actually, ```indata``` is more than one byte, and I need to copy all its M bytes in one go into ```mybuffer```, starting from the position ```wptr```. ```wptr``` will be then incremented by M. – arandomuser Jun 30 '20 at 21:31
  • I added anther example. – Serge Jul 01 '20 at 14:57