打印

FIFO_ASYNC 256x8 怎么写也写不满,FULL没有起作用

[复制链接]
1641|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
shell.albert|  楼主 | 2012-9-26 10:13 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用verilog实现了一个异步的fifo,学习了网上格雷码的方式,但是现在的问题是,就是写不满数据啊。往里直写数据,full始终没有变化啊?
这是怎么回事啊?

module FIFO(Wr_Clk,//write FIFO clock
   nWr,   //write FIFO signal
   Din,   //write FIFO data
   Rd_Clk,//read  FIFO clock
   nRd,   //read  FIFO signal
   Dout,  //read  FIFO data

   Full,  // 1 = FIFO full
   Empty);// 1 = FIFO empty
parameter
  Dsize = 256, Asize = 8,
  Bsize = 8;
input  Wr_Clk, nWr, Rd_Clk, nRd;
input  [Bsize-1:0] Din;
output [Bsize-1:0] Dout;
output Full, Empty;
reg Full, Empty;
reg [Bsize-1:0] Buff [Dsize-1:0];
reg [Asize:0] Wr_Addr_Bin, Rd_Addr_Bin;
reg [Asize:0] Sync_Wr_Addr0_Gray, Sync_Wr_Addr1_Gray, Sync_Wr_Addr2_Gray;
reg [Asize:0] Sync_Rd_Addr0_Gray, Sync_Rd_Addr1_Gray, Sync_Rd_Addr2_Gray;
wire [Asize-1:0] FIFO_Entry_Addr, FIFO_Exit_Addr;
wire [Asize:0] Wr_NextAddr_Bin, Rd_NextAddr_Bin;
wire [Asize:0] Wr_NextAddr_Gray, Rd_NextAddr_Gray;
wire Asyn_Full, Asyn_Empty;
initial
begin
  Full   = 0;
  Empty  = 1;
  Wr_Addr_Bin = 0;
  Rd_Addr_Bin = 0;
  Sync_Wr_Addr0_Gray = 0;
  Sync_Wr_Addr1_Gray = 0;
  Sync_Wr_Addr2_Gray = 0;
  Sync_Rd_Addr0_Gray = 0;
  Sync_Rd_Addr1_Gray = 0;
  Sync_Rd_Addr2_Gray = 0;
end
////////////////////FIFO数据的写入与输出//////////////////////////////////////
assign FIFO_Exit_Addr  = Rd_Addr_Bin[Asize-1:0];
assign FIFO_Entry_Addr = Wr_Addr_Bin[Asize-1:0];
assign Dout = Buff[FIFO_Exit_Addr];
always @ (posedge Wr_Clk)
begin
  if (~nWr & ~Full) Buff[FIFO_Entry_Addr] <= Din;
  else              Buff[FIFO_Entry_Addr] <= Buff[FIFO_Entry_Addr];
end
///////////////////FIFO读写的地址生成器///////////////////////////////////////
assign Wr_NextAddr_Bin = (~nWr&~Full) ?Wr_Addr_Bin[Asize:0]+1:Wr_Addr_Bin[Asize:0];
assign Rd_NextAddr_Bin = (~nRd&~Empty)?Rd_Addr_Bin[Asize:0]+1:Rd_Addr_Bin[Asize:0];
assign Wr_NextAddr_Gray = (Wr_NextAddr_Bin >> 1) ^ Wr_NextAddr_Bin;
assign Rd_NextAddr_Gray = (Rd_NextAddr_Bin >> 1) ^ Rd_NextAddr_Bin;
always @ (posedge Wr_Clk)
begin
  Wr_Addr_Bin        <= Wr_NextAddr_Bin;
  Sync_Wr_Addr0_Gray <= Wr_NextAddr_Gray;
end
always @ (posedge Rd_Clk)
begin
  Rd_Addr_Bin        <= Rd_NextAddr_Bin;
  Sync_Rd_Addr0_Gray <= Rd_NextAddr_Gray;
end
///////////////////采用双锁存器把异步信号同步起来/////////////////////////////
always @ (posedge Wr_Clk)
begin
  Sync_Rd_Addr2_Gray <= Sync_Rd_Addr1_Gray;//读信号同步到写时钟
  Sync_Rd_Addr1_Gray <= Sync_Rd_Addr0_Gray;
end
always @ (posedge Rd_Clk)
begin
  Sync_Wr_Addr2_Gray <= Sync_Wr_Addr1_Gray;//写信号同步到读时钟
  Sync_Wr_Addr1_Gray <= Sync_Wr_Addr0_Gray;
end
/////////////////将产生的Full信号和Empty信号同步的各自的时钟域上//////////////
assign Asyn_Empty = (Rd_NextAddr_Gray==Sync_Wr_Addr2_Gray);
assign Asyn_Full  = (Wr_NextAddr_Gray=={~Sync_Rd_Addr2_Gray[Asize:Asize-1],
                                          Sync_Rd_Addr2_Gray[Asize-2:0]});
always @ (posedge Wr_Clk)
begin
  Full <= Asyn_Full;
end
always @ (posedge Rd_Clk)
begin
  Empty <= Asyn_Empty;
end
//////////////////////////////////////////////////////////////////////////////
endmodule
/*TestBench*/
module FIFO_TestBench;
  
  reg Wr_Clk;
  reg nWr;
  reg [7:0] Din;
  wire Full;
    reg [4:0] i;
  initial begin
    i=0;
    Wr_Clk=0;
    nWr=1;
    forever #1 Wr_Clk=~Wr_Clk;
  end
[email=always@(posedge]always@(posedge[/email] Wr_Clk)
    begin
      case(i)
          5'd0:begin nWr=1;Din=8'b1111_0000;i<=i+1;end
          5'd1:begin nWr=0;i<=i+1;end
          5'd2:begin nWr=1;i<=i+1;end
          5'd3:begin i<=5'd0;end
      endcase
    end
FIFO u1(
  .Wr_Clk(Wr_Clk),
  .nWr(nWr),
  .Din(Din),
  .Full(Full));
endmodule

相关帖子

沙发
GoldSunMonkey| | 2012-9-26 23:50 | 只看该作者
已经过了看代码的年龄了,
不过为什么要自己写fifo呢?

使用特权

评论回复
板凳
shell.albert|  楼主 | 2012-9-27 16:32 | 只看该作者
为了实现通用性啊。
这样不管用哪个片子,一编译,引脚重新分配一下就完事了。

使用特权

评论回复
地板
GoldSunMonkey| | 2012-9-27 16:49 | 只看该作者
为了实现通用性啊。
这样不管用哪个片子,一编译,引脚重新分配一下就完事了。
shell.albert 发表于 2012-9-27 16:32

但是 内部的硬件浪费了。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:烟台电工@張紹言

32

主题

1934

帖子

8

粉丝