0

I'm tring to write universal fifo buffer. To make it universal i used code like this.

genvar i;
generate
for(i=0;i<BusWidthIn;i=i+1) begin: i_buffin
  always @ (negedge clkin) begin
    if (!full)
      Buffer[wr_ptr+i] <= datain[i*BitPerWord+BitPerWord-1:i*BitPerWord];
  end
end
endgenerate

In simulation it works properly, but in Quartus it gives Error (10028): Can't resolve multiple constant drivers for net "Buffer[30][6]" at fifo.v(33) and so on.

All Code

module fifo_m(clkin,datain,clkout,dataout,full,empty);
parameter BusWidthIn  = 3, //in 10*bits
          BusWidthOut = 1, //in 10*bits
          BufferLen   = 4, // in power of 2 , e.g. 4 will be 2^4=16 bytes
          BitPerWord  = 10;

input                               clkin;
input  [BusWidthIn*BitPerWord-1:0]  datain;
input                               clkout;
output [BusWidthOut*BitPerWord-1:0] dataout;
output                              full;
output                              empty;

reg    [BusWidthOut*BitPerWord-1:0] dataout;
reg    [BitPerWord-1:0]             Buffer [(1 << BufferLen)-1  : 0];
wire   [BusWidthIn*BitPerWord-1:0]  tbuff;
reg    [BufferLen - 1 : 0]          rd_ptr, wr_ptr;
wire   [BufferLen - 1 : 0]          cnt_buff;
wire                                full;
wire                                empty;

assign cnt_buff = wr_ptr > rd_ptr ? wr_ptr - rd_ptr  :  (1 << BufferLen)  -  rd_ptr + wr_ptr;
assign full     = cnt_buff > (1 << BufferLen) - BusWidthIn;
assign empty    = cnt_buff < BusWidthOut;

initial  begin
rd_ptr = 0;
wr_ptr = 0;
end

genvar i;
generate
for(i=0;i<BusWidthIn;i=i+1) begin: i_buffin
  always @ (negedge clkin) begin
    if (!full)
      Buffer[wr_ptr+i] <= datain[i*BitPerWord+BitPerWord-1:i*BitPerWord];
  end
end
endgenerate

always @ (negedge clkin)
begin   
  if (!full)
    wr_ptr = wr_ptr + BusWidthIn;
end

genvar j;
generate 
for(j=0;j<BusWidthOut;j=j+1) begin : i_buffout
  always @ (posedge clkout) begin
    dataout[j*BitPerWord+BitPerWord-1:j*BitPerWord] <= Buffer[rd_ptr+j];
  end
end
endgenerate

always @ (posedge clkout)
begin
  if (!empty) 
    rd_ptr = rd_ptr + BusWidthOut;
end

endmodule

To solve this problem I must put for inside always, but how I can do it?

1
  • 3
    Code look fine on EDAplaygorund. Commented Mar 12, 2014 at 11:56

2 Answers 2

3

I think the issue is that synthesis doesn't know that wr_ptr is always a multiple of 3, hence from the synthesis point of view 3 different always blocks can assign to each Buffer entry. I think you can recode your logic to assign just a single Buffer entry per always block.

genvar i, j;
generate
for(i=0;i < (1<<(BufferLen)); i=i+1) begin: i_buffin
for(j = (i%BusWidthIn);j == (i%BusWidthIn); j++) begin // a long way to write 'j = (i%BusWidthIn);'
  always @ (negedge clkin) begin
    if (!full) begin
      if (wr_ptr*BusWidthIn + j == i) begin
        Buffer[i] <= datain[j*BitPerWord+BitPerWord-1:j*BitPerWord];
      end
    end
  end
end
end
endgenerate

Also at http://www.edaplayground.com/x/23L (based off of Morgan's copy).

And, don't you need to add a valid signal into the fifo, or is the data actually always available to be pushed in ?

Sign up to request clarification or add additional context in comments.

1 Comment

As much I prefer to see resets initial blocks are a valid way of initializing values for an FPGA.
1

Other then the *_ptr in your code should be assigned with non-blocking assignment (<=), there really isn't anything wrong with your code.

If you want to assign Buffer with a for-loop inside of an always block, you can use the following:

integer i;

always @(negedge clkin) begin
  if (!full) begin
    for (i=0;i<BusWidthIn;i=i+1) begin: i_buffin
      Buffer[wr_ptr+i] <= datain[i*BitPerWord +: BitPerWord];
    end
    wr_ptr <= wr_ptr + BusWidthIn;
  end
end

datain[i*BitPerWord+BitPerWord-1:i*BitPerWord] will not compile in Verilog because the MSB and LSB select bits are variables. Verilog requires a known range. +: is for part-select (also known as a slice) allows a variable select index and a constant range value. It was introduced in IEEE Std 1364-2001 § 4.2.1. You can also read more about it in IEEE Std 1800-2012 § 11.5.1, or refer to previously asked questions: What is `+:` and `-:`? and Indexing vectors and arrays with +:.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.