📄 asynfifo.v
字号:
//-----------------------------------------------------------//// Design : asynFifo// Author : Allen Leng//// Description : FIFO for code rate adjust in E1 to STM-1(SDH)// the interface is as follows: // -------------// WrClk -->| |// WrEn -->| |<-- RdClk// Din ==>| |<-- RdEn// | asynFifo |// Full <--| |==> Dout// | |--> Empty// Rst -->| |// -------------// Notes: 1) ////// History : // Jul.26,2005 Allen Leng Created this file////----------------------------------------------------------- module asynFifo(Rst, WrClk, WrEn, Din,Full, RdClk, RdEn, Dout,Empty ); parameter AW = 6, // Number of memory address bits DW = 8; // the data width input Rst; // global reset signal, high level input WrClk; // ----- write port input WrEn; // write enable input [DW-1:0] Din; output Full; // almost full for protected input RdClk; // ----- read port input RdEn; // read enable output [DW-1:0] Dout; output Empty; // almost empty for protected reg Full,Empty; wire [AW-1:0] wrAddr,rdAddr; // the address for wr/rd of Ram wire enWr; // write protect when full wire enRd; // read protect when empty assign enWr = (~Full && WrEn); assign enRd = (~Empty &&RdEn); // (2^AW)*DW RAM Ram #(AW,DW) U_RAM(.Clk(WrClk), .EnWr(enWr), .AddrWr(wrAddr), .Din(Din), .AddrRd(rdAddr), .Dout(Dout) ); // *************************** // write address generation // *************************** reg [AW:0] wrPtr, // the current wr pointer wrPtrGray; // the gray code of wr pointer wire [AW:0] wrPtrNxt,wrPtrGrayNxt; assign wrAddr = wrPtr[AW-1:0]; assign wrPtrNxt = wrPtr + enWr; assign wrPtrGrayNxt = (wrPtrNxt >> 1) ^ wrPtrNxt; // write pointer always @ (posedge Rst or posedge WrClk) if(Rst) begin wrPtr <= 0; wrPtrGray <= 0; end else {wrPtr,wrPtrGray} <= {wrPtrNxt,wrPtrGrayNxt}; //wrPtr sync to rdClk domain (read side) reg [AW:0] wrPtrRd,wrPtrGrayRd,wrPtrTmp; // wrPtrGray sync to read side always @ (posedge Rst or posedge RdClk) if(Rst) begin wrPtrTmp <= 0; wrPtrGrayRd <= 0; end else begin wrPtrTmp <= wrPtrGray; wrPtrGrayRd <= wrPtrTmp; end integer i; // gray to binary: wrPtrGrayRd to wrPtrRd always @(wrPtrGrayRd) for (i=0; i<=AW; i=i+1) wrPtrRd[i] = ^(wrPtrGrayRd>>i); // *************************** // read address generation // *************************** reg [AW:0] rdPtr, // the current read pointer rdPtrGray; // rdPtr in gray code wire [AW:0] rdPtrNxt,rdPtrGrayNxt; assign rdAddr = rdPtr[AW-1:0]; assign rdPtrNxt = rdPtr + enRd; assign rdPtrGrayNxt = (rdPtrNxt >> 1) ^ rdPtrNxt; // the current read pointer,including gray code always @ (posedge Rst or posedge RdClk) if(Rst) {rdPtr,rdPtrGray} <= 0; else {rdPtr,rdPtrGray} <= {rdPtrNxt,rdPtrGrayNxt}; //rdPtr sync to wrClk domain reg [AW:0] rdPtrWr,rdPtrGrayWr,ptrTmp; // rdPtrGray sync to write side always @ (posedge Rst or posedge WrClk) if(Rst) begin ptrTmp <= 0; rdPtrGrayWr <= 0; end else begin ptrTmp <= rdPtrGray; rdPtrGrayWr <= ptrTmp; end // gray to binary: rdPtrGrayWr to rdPtrWr always @(rdPtrGrayWr) for (i=0; i<=AW; i=i+1) rdPtrWr[i] = ^(rdPtrGrayWr>>i); //wr almost full generation: different page, and wrPtr catch up with // rdPtr within 5 cycles. always @ (wrPtr or rdPtrWr) if ((wrPtr[AW] != rdPtrWr[AW]) && ((wrPtr[AW-1:0] + 3'b101) >= rdPtrWr[AW-1:0])) Full = 1'b1; // 5 ???? else Full = 1'b0; always @ (wrPtrRd or rdPtr) if(wrPtrRd == rdPtr) Empty = 1'b1; else Empty = 1'b0; endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -