打印

fifo

[复制链接]
1894|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jlgcumt|  楼主 | 2013-2-27 22:46 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
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

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;

parameter
  Dsize = 256, Asize = 8,
  Bsize = 8;

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

问题:Rd_Clk和nRd是什么关系,Rd_Clk是不是一直都有,但nRd可能是随机的产生?

相关帖子

沙发
ifpga| | 2013-2-28 08:36 | 只看该作者
一般情况下, rd_clk 是一直都有的
nrd 应该就是读使能

使用特权

评论回复
板凳
1003704680| | 2013-2-28 12:36 | 只看该作者
同学,这样贴代码没人会看的。。。

使用特权

评论回复
地板
GoldSunMonkey| | 2013-3-3 23:33 | 只看该作者
什么意思?

使用特权

评论回复
5
xjsxjtu| | 2013-3-4 15:55 | 只看该作者
GoldSunMonkey 发表于 2013-3-3 23:33
什么意思?

不明白啊

使用特权

评论回复
6
GoldSunMonkey| | 2013-3-4 16:07 | 只看该作者
我也不太明白啊

使用特权

评论回复
7
myx0709| | 2013-3-4 16:12 | 只看该作者
Rd_Clk是读FIFO的时钟信号,代码里看不出是不是一直有,因为是输入信号,但是以平时FIFO的常规使用经验来看,读时钟是一直输入存在的;nRd是低有效的读使能信号,它可以说是随机的,只要满足FIFO里面不空的时候就可以使nRd有效去读取FIFO里的数据,这是FIFO输入信号你自己来控制;Rd_Clk和nRd没有必然的逻辑关系,只是读取FIFO数据的时候nRd是靠Rd_Clk时钟采样的。看看FIFO的使用方法吧,这些就都可以理解了

使用特权

评论回复
8
shang651| | 2013-3-4 16:21 | 只看该作者
myx0709 发表于 2013-3-4 16:12
Rd_Clk是读FIFO的时钟信号,代码里看不出是不是一直有,因为是输入信号,但是以平时FIFO的常规使用经验来看 ...

他没问问题,你都能看出来问题

使用特权

评论回复
9
myx0709| | 2013-3-4 17:57 | 只看该作者
shang651 发表于 2013-3-4 16:21
他没问问题,你都能看出来问题

:sleepy:

使用特权

评论回复
10
qin552011373| | 2013-3-4 23:25 | 只看该作者
myx0709 发表于 2013-3-4 17:57

传说中的高手?

使用特权

评论回复
11
myx0709| | 2013-3-5 10:26 | 只看该作者
qin552011373 发表于 2013-3-4 23:25
传说中的高手?

没有没有,就是以前用过,说点儿知道的;P

使用特权

评论回复
12
qin552011373| | 2013-3-5 11:55 | 只看该作者
myx0709 发表于 2013-3-5 10:26
没有没有,就是以前用过,说点儿知道的

谦虚

使用特权

评论回复
13
jlgcumt|  楼主 | 2013-3-10 10:46 | 只看该作者
myx0709 发表于 2013-3-4 16:12
Rd_Clk是读FIFO的时钟信号,代码里看不出是不是一直有,因为是输入信号,但是以平时FIFO的常规使用经验来看 ...

这段代码看了我一个月,总算看明白了(自己认为的),读地址同步到写信号上去是保守的,有可能在还没满的时候就会读满(原因是对读地址进行了两次同步,为了降低亚稳态的出来),写地址也是一样的,原来想着连续读或者连续写的时候可能会出问题,后来想想这段代码是保守的读和写,不知道我的理解对不对!

使用特权

评论回复
14
jlgcumt|  楼主 | 2013-3-10 10:46 | 只看该作者
结贴了

使用特权

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

本版积分规则

个人签名:善攻者,动于九天之上,善守者,藏于九地之下!

183

主题

733

帖子

4

粉丝