HDL 设设设设设设 ---- FIFO 设设 设设设设设设设设设设设设设设设设设 610 设 设设设
Feb 25, 2016
HDL 设计描述实例---- FIFO 设计
国防科技大学计算机学院微电子研究所 610 室曾献君
FIFO 类型• 同步控制的 FIFO FIFO 的读写时钟相同。• 异步控制的 FIFO 用于跨时钟域的数据交换; FIFO 的读写时钟不同、读写时钟之间不一定存在相位、周期方面的约束关系;
同步 FIFO 设计同步 FIFO 存在 3 种状态: 空; 满; 非空非满FIFO 为空,不可从 FIFO 读数据,但可写;FIFO 为满,不可向 FIFO 写数据,但可读;非空非满时, FIFO 可读、可写。FIFO 的读写受同一时钟控制;FIFO 的大小为 N 字
同步 FIFO 的操作1 、 同步 FIFO 的外部接口信号 时钟信号 clk :控制 FIFO 的读写; 写请求信号 Wreq: 向 FIFO 发送写请求信号; 写数据 WData[Size-1:0] : 写数据; 写有效信号 WEn : WEn=1 表示写有效,否则写无效,作废写请求,并使写请求等待; 读请求信号 Rreq: 向 FIFO 发送读请求信号; 读数据 RData[Size-1:0] : 读数据; 读有效信号 REn : REn=1 表示读有效,否则读无效,作废读请求,并使读请求等待;
同步 FIFO 的操作1 、 同步 FIFO 的操作 当 FIFO 不满且 Wreq 有效时,向 FIFO 写数据,并置写使能 WEn 有效; 当 FIFO 不空且 Rreq 有效时,从 FIFO 从读出数据并置读使能 REn 有效; 当 FIFO 满且 Wreq 有效时,置写使能 WEn 无效且作废此次写操作; 当 FIFO 空且 Rreq 有效时,置读使能 REn 无效且作废此次读操作。
同步 FIFO 的操作问题:1. 如何判断 FIFO 为空、满?2. FIFO 的读写操作的位置如何判定?
同步 FIFO 的操作算法上的考虑:设置一个 Count 计数器,用于计数 FIFO 中的元素的个数, Count<=N ;设置 FIFO 的读指针 Rptr , 0<=Rptr <= N-1;设置 FIFO 的写指针 Wptr , 0<=Wptr <= N-1;FIFO 初始操作时, Count = 0 , Rptr = Wp
tr = 0.
同步 FIFO 的操作• FIFO 的操作可用下述几个进程表示:1) 初始化进程: Count = Wptr = Rptr =0;2)FIFO 读进程: if (Rreq ==1 && Count >0) begin
RData = FIFO[Rptr]; Rptr = (Rptr +1 )mod N;
REn = 1 ; end
3) FIFO 写进程 if (Wreq==1 && Count < N) begin
FIFO[Wptr] = WData; Wptr = (Wptr +1) mod N;
WEn = 1;end
4) Count 计数进程 if (Wreq ==1 && Count < N && Rreq !=1) Count = Count +1; if (Rreq == 1 && Count >0 && Wreq !=1) Count = Count -1;
同步 FIFO 的操作
同步 FIFO 的操作FIFO 的初始化只进行一次, FIFO 的读进程、写进程、 Count 的计数进程相互之间并行。如何将上述进程(算法)转化为相应的硬件实现?
同步 FIFO 设计• 根据 FIFO 的大小 N ,决定 Count 、 Wptr 、
Rptr 的位宽 log2N;• 设置寄存器分别保存 Count 、 Wptr 、 Rptr的值;• 同步 FIFO 必须有异步 Reset ;• 当 FIFO 复位时, Count = 0 , Wptr = 0 ,
Rptr = 0 ;• FIFO 正常操作时,受时钟控制。
module Synch_FIFO(clk, Reset, Wreq, WData, Rreq, RData, WEn, REn);parameter Size = 64;input clk;input Reset;input Wreq;input [Size-1] WData;input Rreq;output [Size-1] RData;output WEn;output REn;
parameter L = log2N ;reg [Size-1] RData;reg WEn, REn;reg [L-1:0] Count;reg [L-1:0] Wptr;reg [L-1:0] Rptr;
always @(posedge clk or negedge Reset) if (~Reset) // 初始化 begin
Count <= 0;Wptr <= 0;Rptr <= 0;
end else begin // FIFO 写操作 if ( (Wreq ==1’b1) && (Count < N))
beginFIFO[Wptr] <= WData;Wptr <= (Wptr +1) % N;
WEn <= 1’b1; endelse WEn <= 1’b0;
//FIFO 读操作if ((Rreq==1’b1) && (Count >0)) begin RData <= FIFO[Rptr]; Rptr <= (Rptr +1 ) %N; REn <= 1’b1; endelse REn <= 1’b0;
//Count 计数if ((Rreq==1) && (Wreq!=1) && Count >0) Count = Count -1;if ((Wreq==1) && (Rreq!=1) && Count <N) Count = Count +1;
end
1. HDL 设计描述是否存在问题?
2. 问题出现在哪里?
3. 如何改进设计描述?
always @(posedge clk or negedge Reset) if (~Reset) // 初始化 WEn = 1’b0; else begin // FIFO 写操作 if ( (Wreq ==1’b1) && (Count < N))
beginFIFO[Wptr] <= WData;Wptr <= (Wptr +1) % N;
WEn <= 1’b1; endelse WEn <= 1’b0;
end
always @(posedge clk or negedge Reset) if (~Reset) begin Count <= 0; Wptr <= 0; Rptr <= 0; end else begin //Count 计数 if ((Rreq==1) && (Wreq!=1) && Count >0) Count = Count -1; if ((Wreq==1) && (Rreq!=1) && Count <N) Count = Count +1; end
always @(posedge clk or negedge Reset) if (~Reset)
REn <= 1’b0; else //FIFO 读操作 begin if ((Rreq==1’b1) && (Count >0)) begin RData <= FIFO[Rptr]; Rptr <= (Rptr +1 ) %N; REn <= 1’b1; end else REn <= 1’b0; end
异步 FIFO 的设计• 异步 FIFO 的数据读、写受不同时钟的控制;• 异步 FIFO 的空、满状态不能依靠计数的方式进行,因为读、写均需要对计数器进行操作;• 如何判断异步 FIFO 的空、满情形?如何操作?
如何判断异步 FIFO 的空、满?异步 FIFO 为空条件: Reset 情形下,异步 FIFO 为空; 在正常读、写情形,当读指针追上写指针,异步 FIFO 为空。异步 FIFO 为满条件: 在正常读、写情形,读、写指针相同,且写指针追上读指针时。读、写指针均相同时, FIFO 到底是空还是满?
异步 FIFO 的设计
FIFO体的描述
读指针被写时钟采样的模块
写指针被读时钟采样的模块
判别FIFO
为空的设计模
块
判别FIFO
为满的设计模
块
异步FIFO
结
构
关于异步 FIFO 设计更多的资料