打印

帮忙分析一下程序,FIFO的?

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

相关帖子

沙发
jlgcumt|  楼主 | 2012-12-6 22:43 | 只看该作者
网上看到的程序,
问一下那个assign Wr_NextAddr_Gray = (Wr_NextAddr_Bin >> 1) ^ Wr_NextAddr_Bin;是什么意思?
在问一下 输入写时钟和读时钟是怎么回事?
总之这个程序看不明白!

使用特权

评论回复
板凳
jlgcumt|  楼主 | 2012-12-6 22:44 | 只看该作者
always @ (posedge Wr_Clk)
begin
  Sync_Rd_Addr2_Gray <= Sync_Rd_Addr1_Gray;//读信号同步到写时钟
  Sync_Rd_Addr1_Gray <= Sync_Rd_Addr0_Gray;
end
这几句也看不明白?

使用特权

评论回复
地板
jlgcumt|  楼主 | 2012-12-6 23:08 | 只看该作者
本帖最后由 jlgcumt 于 2012-12-6 23:12 编辑

always @ (posedge Wr_Clk)
begin
  if (~nWr & ~Full) Buff[FIFO_Entry_Addr] <= Din;
  else              Buff[FIFO_Entry_Addr] <= Buff[FIFO_Entry_Addr];
end
这个也看不大明白,Wr_Clk不是检测的上升沿吗,怎么会出现低电平呢?

使用特权

评论回复
5
GoldSunMonkey| | 2012-12-6 23:29 | 只看该作者
jlgcumt 发表于 2012-12-6 22:43
网上看到的程序,
问一下那个assign Wr_NextAddr_Gray = (Wr_NextAddr_Bin >> 1) ^ Wr_NextAddr_Bin;是什么 ...

移位后拼接?

使用特权

评论回复
6
GoldSunMonkey| | 2012-12-6 23:30 | 只看该作者
jlgcumt 发表于 2012-12-6 22:44
always @ (posedge Wr_Clk)
begin
  Sync_Rd_Addr2_Gray

延时几拍为了对齐?

使用特权

评论回复
7
GoldSunMonkey| | 2012-12-6 23:30 | 只看该作者
jlgcumt 发表于 2012-12-6 23:08
always @ (posedge Wr_Clk)
begin
  if (~nWr & ~Full) Buff[FIFO_Entry_Addr]

什么低点评?

使用特权

评论回复
8
jlgcumt|  楼主 | 2012-12-7 12:06 | 只看该作者
GoldSunMonkey 发表于 2012-12-6 23:29
移位后拼接?

大哥,你不会是问我吧? 晕

使用特权

评论回复
9
jlgcumt|  楼主 | 2012-12-7 12:09 | 只看该作者
GoldSunMonkey 发表于 2012-12-6 23:30
什么低点评?

posedge上升沿之后不是高电平吗?
~nWr只有在nWr为低电平的时候才会有效,if (~nWr & ~Full) Buff[FIFO_Entry_Addr]不就永远执行不了吗?

使用特权

评论回复
10
jlgcumt|  楼主 | 2012-12-7 12:10 | 只看该作者
GoldSunMonkey 发表于 2012-12-6 23:30
延时几拍为了对齐?

什么信号对齐?

使用特权

评论回复
11
cuianbin| | 2012-12-7 17:22 | 只看该作者
LZ 仔细看吧 你这个程序俺当初做课程设计的时候 也是用的这个 异步FIFO 的程序   俺当时分析透了  现在好久不用了 也忘了  不过俺当时写的一点东西 你可以参考下
201121010125_大帅哥_课程设计.zip (90.2 KB)

使用特权

评论回复
12
zxr456| | 2012-12-10 15:33 | 只看该作者
jlgcumt 发表于 2012-12-6 22:43
网上看到的程序,
问一下那个assign Wr_NextAddr_Gray = (Wr_NextAddr_Bin >> 1) ^ Wr_NextAddr_Bin;是什么 ...

你明白格雷码算法就明白这条是实现什么功能!!!

使用特权

评论回复
13
zxr456| | 2012-12-10 15:43 | 只看该作者
jlgcumt 发表于 2012-12-6 23:08
always @ (posedge Wr_Clk)
begin
  if (~nWr & ~Full) Buff[FIFO_Entry_Addr]

这个有什么冲突?

使用特权

评论回复
14
zxr456| | 2012-12-10 15:49 | 只看该作者
jlgcumt 发表于 2012-12-7 12:09
posedge上升沿之后不是高电平吗?
~nWr只有在nWr为低电平的时候才会有效,if (~nWr & ~Full) Buff[FIFO_E ...

你理解always @ (posedge Wr_Clk) 这句是什么意思? posedge上升沿之后Wr_clk是高电平,不能代表nWr就是高电平

使用特权

评论回复
15
Dick00| | 2012-12-10 16:22 | 只看该作者
小菜一枚,学习下。

使用特权

评论回复
16
jlgcumt|  楼主 | 2012-12-10 20:57 | 只看该作者
zxr456 发表于 2012-12-10 15:49
你理解always @ (posedge Wr_Clk) 这句是什么意思? posedge上升沿之后Wr_clk是高电平,不能代表nWr就是 ...

我把这两个看成一个信号了,看错了,才有上面一说!
我再问一下那个Wr_Clk是怎么来的?  来自CPU的写信号(就是rd线),还是FPGA自己产生时钟来读写?

使用特权

评论回复
17
jlgcumt|  楼主 | 2012-12-10 21:20 | 只看该作者
zxr456 发表于 2012-12-10 15:33
你明白格雷码算法就明白这条是实现什么功能!!!

呵呵,多谢你了!这个搞明白了,我在问一下下面的读信号同步到写时钟是什么意思?
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

使用特权

评论回复
18
GoldSunMonkey| | 2012-12-10 21:39 | 只看该作者
jlgcumt 发表于 2012-12-7 12:06
大哥,你不会是问我吧? 晕

。。。我是忘记了具体,只是讨论一下。不算是问你。

使用特权

评论回复
19
GoldSunMonkey| | 2012-12-10 21:40 | 只看该作者
jlgcumt 发表于 2012-12-7 12:09
posedge上升沿之后不是高电平吗?
~nWr只有在nWr为低电平的时候才会有效,if (~nWr & ~Full) Buff[FIFO_E ...

这两个事情不挨着。

使用特权

评论回复
20
GoldSunMonkey| | 2012-12-10 21:40 | 只看该作者
jlgcumt 发表于 2012-12-7 12:10
什么信号对齐?

。。。我都没仔细看,但是肯定是为了对齐比方地址位啊,或着其他的。

使用特权

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

本版积分规则

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

183

主题

733

帖子

4

粉丝