Verilog FIFO代码写的不同风格.一个坏了,另一个也坏了.有人能解释一下吗?



我已经为fifo编写了verilog代码,使用fillcount检查作为检查它是满的还是空的手段。相同的代码有两个版本。一个是我有一个单独的always always块,用于读取,写入,空/满,填充计数,和一个用于增加指针。这工作得很好,我已经测试过了,它工作得很好。

module FIFO (clk, reset, data_in, put, get, data_out, fillcount, empty, full); 
parameter DEPTHP2 = 8 ;
parameter WIDTH = 8 ;
input [WIDTH-1:0] data_in;
input put, get, reset, clk; 
output fillcount;
output reg [WIDTH-1:0] data_out;
output reg empty, full; 


reg [3:0]fillcount ;
reg [WIDTH-1:0] fifo_1[0:DEPTHP2-1];
reg [2:0] rp,wp;

always@(posedge clk or posedge reset)
begin
   if( reset )
   begin
      wp <= 0;
      rp <= 0;
   end
   else
   begin
      if( !full && put )    wp <= wp + 1;
          else  wp <= wp;
      if( !empty && get )   rp <= rp + 1;
      else rp <= rp;
   end
end
always @(fillcount)
begin
if(fillcount==0)
  empty =1 ;
  else
  empty=0;
  if(fillcount==8)
   full=1;
   else
   full=0;
end
always @(posedge clk or posedge reset)
begin
   if( reset )
       fillcount <= 0;
   else if( (!full && put) && ( !empty && get ) )
       fillcount <= fillcount;
   else if( !full && put )
       fillcount <= fillcount + 1;
   else if( !empty && get )
       fillcount <= fillcount - 1;
   else
      fillcount <= fillcount;
end
always @( posedge clk or posedge reset)
begin:Reading
   if( reset )
      data_out <= 0;
   else
   begin
      if( get && !empty )
         data_out <= fifo_1[rp];
      else
         data_out <= data_out;
   end
end
always @(posedge clk)
begin:Writing
   if( put && !full )
      fifo_1[ wp ] <= data_in;
   else
      fifo_1[ wp ] <= fifo_1[ wp ];
end
endmodule

另一种方法是我将几个总是块组合在一起,影响逻辑(在我的理解中!!)但它不工作的情况下,当我试图读取数据后立即写入。它通过了所有其他的测试用例。

我不知道哪里出了问题。如果有人能指出我错在哪里就太好了。

//The code that is not working
always@(posedge clk or posedge reset)
begin:Writing
         if(reset)
        wp<=0;
        else 
        if( put && !full)
        begin
            fifo1[wp]<=data_in;
            wp<=wp+1;
        end
        else
        begin
            fifo1[wp]<=fifo1[wp];
            wp<=wp;
        end
end

always@(posedge clk or posedge reset)
begin:Reading
    if(reset)
    begin
        rp<=0;
        data_out<=0;
    end
        else
    if(get && !empty)
    begin
        data_out<=fifo1[rp];
        rp<=rp+1;
    end 
    else
    begin
        fifo1[rp]<=fifo1[rp];
        rp<=rp;
    end
end
always@(posedge clk or posedge reset)
begin:Fillcount
    if(reset)
        fillcount<=0;
        else
    if((!full && put ) && ( !empty && get))
        fillcount<=fillcount;
    else if(!full && put)
        fillcount<=fillcount+1;
    else if(!empty && get)
        fillcount<=fillcount-1;
    else
        fillcount<=fillcount;
end
always@(fillcount)
begin
    full=(fillcount==8);
    empty=(fillcount==0);
end
endmodule

另一个问题:据我所知,在verilog中编码的一般方法是使用fsm来绘制状态图并使用它们,但是当我尝试为fifo,Tcam或双时钟fifo等内存元素编码时,我遇到了困难。是否有任何方法或方法为这些元素做编码。

抱歉,这个问题很长

在您的"Reading"过程中,您无意中写入您的fifo内存:

fifo1[rp]<=fifo1[rp];

如果你把它去掉,看起来事情应该可以正常工作。

作为旁注,在顺序过程中,您不需要显式地设置不会更改的值。

例如,如果你采用你的流程:

always@(posedge clk or posedge reset)
begin:Writing
  if(reset)
    wp<=0;
  else 
    if( put && !full)
    begin
        fifo1[wp]<=data_in;
        wp<=wp+1;
    end
    else
    begin
        fifo1[wp]<=fifo1[wp];
        wp<=wp;
    end
end

可以重写为:

always@(posedge clk or posedge reset)
begin:Writing
  if(reset)
    wp<=0;
  else 
    if( put && !full)
    begin
        fifo1[wp]<=data_in;
        wp<=wp+1;
    end
end

,你会得到完全相同的行为在sim和相同的硬件,当你合成。你在代码中暗示了寄存器,除非显式地更改,否则它们将保持其状态。

相关内容

最新更新