您的位置:首页 > 其它

【引用】关于ALTERA提供的FIFO核使用原理

2013-12-22 20:12 351 查看
原文:
/article/9431722.html

本文引用自Suinchang《关于ALTERA提供的FIFO核使用原理》

ALTERA提供了LPM_FIFO参数宏模块,可以在代码中例化使用。

FIFO有两种工作模式:(1)SCFIFO,(2)DCFIFO

其中SCFIFO指读写用一个时钟进行同步,可以支持同时读写的功能。

其中DCFIFO指读写使用不同的时钟进行同步,这在设计多时钟系统中相当有用,可用于不同时钟同步信号之间的同步调整。

首先看看DCFIFO模式下的几个比较重要的信号:

[A]在写端,主要有以下几个信号:

(1) data[n-1:0]:写入数据信号总线;

(2) wrreq:写入请求信号,高有效

(2) wrclk:写入同步时钟;

(3) wrfull, wrempty:用于指示写端FIFO为空或者满的状态;

(4) wrusedw[log2(SIZE_FIFO)-1:0] :写入的数据个数,按写入个数递增;

上述信号都与写入时钟srclk同步;

[B]在读端,主要有以下几个信号:

(1) q[n-1:0]:读取数据信号总线;

(2) rdreq:读取请求/确认信号,高有效

(2) rdclk:读取同步时钟;

(3) rdfull, rdempty:用于指示读端FIFO为空或者满的状态;

(4) rdusedw[log2(SIZE_FIFO)-1:0] :读取的数据个数,按读取顺序递减;

FIFO主要有两种工作模式:

(1) Legacy mode(Legacy synchronous FIFO mode )

(2) Show-ahead mode(Show-ahead synchronous FIFO mode)

其中:

在Legacy mode,读端的rdreq信号作为读取FIFO的请求信号(REQ),读取数据在rdreq置位后的第二个时钟周期有效。

在Show-ahead mode,读端的rdreq信号作为读取FIFO的确认信号(ACK),读取数据在rdreq置位后立即有效,不要额外的读取周期。

下面分别给出Legacy mode和Show-ahead mode的读写时序:

[A] Legacy mode





[B] Show-ahead mode









由上述时序可以看出两种模式的区别。

值得注意的是:

读端在读取数据的时候,必须等待写端数据准备好,即rdempty为低之后开始读取数据,为高期间表明FIFO状态为空,写端写入数据未有效。

相应的在写端如果wrfull为高,则表明FIFO状态以满,不能再写入数据,此时写入的数据无效。

下面给出一个FIFO操作的具体实例:完成将10MHz同步输入的总线同步缓冲到72MHz+6MHz的同步组合输出。

// ----------------------------------------------------------------------------------

// Copyright (c) 2007 by College of Communication Engineering,Chongqing University.

// ----------------------------------------------------------------------------------

// Project:

//

// ----------------------------------------------------------------------------------

// File Name:CNGI_PLCP2TxPHY_SyncProc.v

// Module:

//

// Top Module:

//

// ----------------------------------------------------------------------------------

//

// Major Functions:

//

// ----------------------------------------------------------------------------------

//

// Revision History :

// ----------------------------------------------------------------------------------

// Ver :| Author :| Mod. Date :| Changes Made: :| E-mail

// V1.0 :| ZHANG-xuying :| 01/08/07 :| Initial Revision :| zh_xuying@126.com

// ----------------------------------------------------------------------------------

`define PLME_RESET_IND (4'b1001)

`define CCA_RESET_IND (4'b1010)

`define TxSTARTreq_IND (4'b1011)

`define TxMPDU_IND (4'b1100)

module CNGI_PLCP2TxPHY_SyncProc(

reset, //poewer on reset

PLCP2TxPHY_clk,

PLCP2TxPHY_ind,

PLCP2TxPHY_msg,

//

clk, //Tx PHY Local(此处不区分原语和MPDU直接采用数据的基带时钟读取)

clk_ena,

//

LENGTH,

syncPLCP2TxPHY_ind,

syncPLCP2TxPHY_msg

);

//

input wire reset;

input wire PLCP2TxPHY_clk;

input wire [3:0] PLCP2TxPHY_ind;

input wire [7:0] PLCP2TxPHY_msg;

//

input wire clk,clk_ena;

input wire [11:0] LENGTH;

//

output wire [3:0] syncPLCP2TxPHY_ind;

output wire [7:0] syncPLCP2TxPHY_msg;

//Generate wrreq

reg fifo_wrreq;

reg [11:0] fifo_wrdata;

always @(posedge PLCP2TxPHY_clk or posedge reset)begin

if(reset) fifo_wrreq<=1'b0;

else fifo_wrreq<=PLCP2TxPHY_ind[3];

end

//

always @(posedge PLCP2TxPHY_clk or posedge reset)begin

if(reset) fifo_wrdata<=12'd0;

else fifo_wrdata<={PLCP2TxPHY_ind,PLCP2TxPHY_msg};

end

//

reg [3:0] BUS_IND_TYPE;

always @(posedge PLCP2TxPHY_clk or posedge reset)begin

if(reset) BUS_IND_TYPE<=4'h0;

else begin

case(PLCP2TxPHY_ind)

`PLME_RESET_IND: BUS_IND_TYPE<=`PLME_RESET_IND;

`CCA_RESET_IND: BUS_IND_TYPE<=`CCA_RESET_IND;

`TxSTARTreq_IND: BUS_IND_TYPE<=`TxSTARTreq_IND;

`TxMPDU_IND: BUS_IND_TYPE<=`TxMPDU_IND;

default: BUS_IND_TYPE<=BUS_IND_TYPE;

endcase

end

end

//

wire fifo_rdempty;

reg fifo_rdack;

reg [2:0] cnt_a,cnt_b;

reg [2:0] cnt_c;

reg [11:0] cnt_d;

always @(posedge clk or posedge reset)begin

if(reset)begin

cnt_a<=3'd0;

cnt_b<=3'd0;

cnt_c<=3'd0;

cnt_d<=12'd0;

fifo_rdack<=1'b0;

end

else if(clk_ena)begin

if(BUS_IND_TYPE==`PLME_RESET_IND || BUS_IND_TYPE==`CCA_RESET_IND) begin

if(!fifo_rdempty)begin

if(cnt_a==0)begin

fifo_rdack<=1'b1;

cnt_a<=cnt_a+1;

end

else if(cnt_a==1)begin

fifo_rdack<=1'b0;

cnt_a<=cnt_a;

end

end

end

else if(BUS_IND_TYPE==`TxSTARTreq_IND)begin

if(!fifo_rdempty)begin

if(cnt_b<=5)begin

fifo_rdack<=1'b1;

cnt_b<=cnt_b+1;

end

else if(cnt_b==6)begin

fifo_rdack<=1'b0;

cnt_b<=cnt_b;

end

end

end

else if(BUS_IND_TYPE==`TxMPDU_IND)begin

if(!fifo_rdempty)begin

if(cnt_c>=7)begin

if(cnt_d<LENGTH)begin

fifo_rdack<=1'b1;

cnt_d<=cnt_d+1;

cnt_c<=3'd0;

end

else if(cnt_d==LENGTH)begin

fifo_rdack<=1'b0;

cnt_d<=cnt_d;

cnt_c<=cnt_c;

end

end

else cnt_c<=cnt_c+1;

end

end

end

else fifo_rdack<=1'b0;

end

wire [11:0] fifo_Q;

PLCP2TxPHY_FIFO u1(

.aclr(reset),

.data(fifo_wrdata),

.rdclk(clk),

.rdreq(fifo_rdack),

.wrclk(PLCP2TxPHY_clk),

.wrreq(fifo_wrreq),

.q(fifo_Q),

.rdempty(fifo_rdempty)

);

//

assign syncPLCP2TxPHY_ind=fifo_Q[11:8];

assign syncPLCP2TxPHY_msg=fifo_Q[7:0];

endmodule
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: