2014-03-12 2 views
0

Я пытаюсь написать универсальный буферный буфер. Чтобы сделать его универсальным, я использовал такой код.Fifo буфер в Verilog. генерировать всегда

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 

При моделировании она работает правильно, но в Quartus дает Error (10028): Не удается разрешить несколько постоянных драйверов для сети "Buffer [30] [6]" на fifo.v (33) и скоро.

Все Код

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 

Чтобы решить эту проблему, я должен поставить для внутренней всегда, но как я могу это сделать?

+3

Код выглядит отлично на [EDAplaygorund] (http://www.edaplayground.com/x/se). – Morgan

ответ

3

Я думаю, проблема заключается в том, что синтез не знает, что wr_ptr всегда кратно 3, следовательно, из точки синтеза 3 разные всегда блоки могут назначать каждой записи буфера. Я думаю, вы можете перекодировать свою логику, чтобы назначать только одну запись буфера на каждый блок.

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 

Также на http://www.edaplayground.com/x/23L (основаны от копии Моргана).

И вам не нужно добавлять действительный сигнал в fifo или данные, которые всегда доступны для входа?

+2

Насколько я предпочитаю видеть, сброс «начальных» блоков является допустимым способом инициализации значений для FPGA. – Morgan

+0

Спасибо @Morgan, я этого не знал. Я отредактировал это. – sgauria

1

Другое, тогда *_ptr в вашем коде должно быть присвоено неблокирующее присвоение (<=), в вашем коде действительно ничего плохого.

Если вы хотите назначить Buffer с для петли внутри из always блока, вы можете использовать следующее:

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] не будет компилироваться в Verilog, так как MSB и LSB биты выбора являются переменными. Verilog требует известного диапазона. +: предназначен для частичного выбора (также известного как срез), который позволяет индексировать выбор переменной и значение постоянного диапазона. Он был введен в IEEE Std 1364-2001 § 4.2.1. Вы также можете прочитать об этом в IEEE Std 1800-2012 § 11.5.1 или обратитесь к ранее задаваемым вопросам: What is `+:` and `-:`? и Indexing vectors and arrays with +:.

 Смежные вопросы

  • Нет связанных вопросов^_^