260 likes | 480 Views
HDL 设计描述实例. ---- FIFO 设计 国防科技大学计算机学院微电子研究所 610 室 曾献君. FIFO 类型. 同步控制的 FIFO FIFO 的读写时钟相同。 异步控制的 FIFO 用于跨时钟域的数据交换; FIFO 的读写时钟不同、读写时钟之间不一定存在相位、周期方面的约束关系;. 同步 FIFO 设计. 同步 FIFO 存在 3 种状态: 空; 满; 非空非满 FIFO 为空,不可从 FIFO 读数据,但可写; FIFO 为满,不可向 FIFO 写数据,但可读; 非空非满时, FIFO 可读、可写。
E N D
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的操作 问题: • 如何判断FIFO为空、满? • FIFO的读写操作的位置如何判定?
同步FIFO的操作 算法上的考虑: 设置一个Count计数器,用于计数FIFO中的元素的个数,Count<=N; 设置FIFO的读指针Rptr,0<=Rptr <= N-1; 设置FIFO的写指针Wptr,0<=Wptr <= N-1; FIFO初始操作时,Count=0, Rptr = Wptr = 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
同步FIFO的操作 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的读进程、写进程、Count的计数进程相互之间并行。 如何将上述进程(算法)转化为相应的硬件实现?
同步FIFO设计 • 根据FIFO的大小N,决定Count、Wptr、Rptr的位宽log2N; • 设置寄存器分别保存Count、Wptr、Rptr的值; • 同步FIFO必须有异步Reset; • 当FIFO复位时,Count=0,Wptr=0,Rptr=0; • FIFO正常操作时,受时钟控制。
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; 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; 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)) begin FIFO[Wptr] <= WData; Wptr <= (Wptr +1) % N; WEn <= 1’b1; end else WEn <= 1’b0;
//FIFO读操作 if ((Rreq==1’b1) && (Count >0)) begin RData <= FIFO[Rptr]; Rptr <= (Rptr +1 ) %N; REn <= 1’b1; end else 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 • HDL设计描述是否存在问题? • 问题出现在哪里? • 如何改进设计描述?
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) //初始化 WEn = 1’b0; else begin // FIFO 写操作 if ( (Wreq ==1’b1) && (Count < N)) begin FIFO[Wptr] <= WData; Wptr <= (Wptr +1) % N; WEn <= 1’b1; end else WEn <= 1’b0; 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到底是空还是满?