原创 一个可综合的Verilog 写的FIFO存储器

2009-7-6 11:45 3701 3 4 分类: EDA/ IP/ 设计与制造
Synthesizable FIFO Model


This example describes a synthesizable implementation of a FIFO. The FIFO depth and FIFO width in bits can be modified by simply changing the value of two parameters, `FWIDTH and `FDEPTH. For this example, the FIFO depth is 4 and the FIFO width is 32 bits. The input/output ports of the FIFO are shown in Figure F-1.



Figure F-1. FIFO Input/Output Ports

2005111125915321.gif


Input ports  All ports with a suffix "N" are low-asserted.


Clk— Clock signal


RstN— Reset signal


Data_In— 32-bit data into the FIFO


FInN— Write into FIFO signal


FClrN— Clear signal to FIFO


FOutN— Read from FIFO signal


Output ports


F_Data— 32-bit output data from FIFO


F_FullN— Signal indicating that FIFO is full


F_EmptyN— Signal indicating that FIFO is empty


F_LastN— Signal indicating that FIFO has space for one data value


F_SLastN— Signal indicating that FIFO has space for two data values


F_FirstN— Signal indicating that there is only one data value in FIFO


 


The Verilog HDL code for the FIFO implementation is shown in Example F-1.


Example F-1 Synthesizable FIFO Model

`define FWIDTH 32
`define FDEPTH 4 // Depth of the FIFO.
`define FCWIDTH 2 // Counter Width of the FIFO 2 to power
// FCWIDTH = FDEPTH.
module FIFO( Clk,
RstN,
Data_In,
FClrN,
FInN,
FOutN,
F_Data,
F_FullN,
F_LastN,
F_SLastN,
F_FirstN,
F_EmptyN
);
input Clk; // CLK signal.
input RstN; // Low Asserted Reset signal.
input [(`FWIDTH-1):0] Data_In; // Data into FIFO.
input FInN; // Write into FIFO Signal.
input FClrN; // Clear signal to FIFO.
input FOutN; // Read from FIFO signal.
output [(`FWIDTH-1):0] F_Data; // FIFO data out.
output F_FullN; // FIFO full indicating signal.
output F_EmptyN; // FIFO empty indicating signal.
output F_LastN; // FIFO Last but one signal.
output F_SLastN; // FIFO SLast but one signal.
output F_FirstN; // Signal indicating only one
// word in FIFO.
reg F_FullN;
reg F_EmptyN;
reg F_LastN;
reg F_SLastN;
reg F_FirstN;
reg [`FCWIDTH:0] fcounter; //counter indicates num of data in FIFO
reg [(`FCWIDTH-1):0] rd_ptr; // Current read pointer.
reg [(`FCWIDTH-1):0] wr_ptr; // Current write pointer.
wire [(`FWIDTH-1):0] FIFODataOut; // Data out from FIFO MemBlk
wire [(`FWIDTH-1):0] FIFODataIn; // Data into FIFO MemBlk
wire ReadN = FOutN;
wire WriteN = FInN;
assign F_Data = FIFODataOut;
assign FIFODataIn = Data_In;
FIFO_MEM_BLK memblk(.clk(Clk),
.writeN(WriteN),
.rd_addr(rd_ptr),
.wr_addr(wr_ptr),
.data_in(FIFODataIn),
.data_out(FIFODataOut)
);
// Control circuitry for FIFO. If reset or clr signal is asserted,
// all the counters are set to 0. If write only the write counter
// is incremented else if read only read counter is incremented
// else if both, read and write counters are incremented.
// fcounter indicates the num of items in the FIFO. Write only
// increments the fcounter, read only decrements the counter, and
// read && write doesn't change the counter value.
always @(posedge Clk or negedge RstN)
begin
if(!RstN) begin
fcounter <= 0;
rd_ptr <= 0;
wr_ptr <= 0;
end
else begin
if(!FClrN ) begin
fcounter <= 0;
rd_ptr <= 0;
wr_ptr <= 0;
end
else begin
if(!WriteN && F_FullN)
wr_ptr <= wr_ptr + 1;
if(!ReadN && F_EmptyN)
rd_ptr <= rd_ptr + 1;
if(!WriteN && ReadN && F_FullN)
fcounter <= fcounter + 1;
else if(WriteN && !ReadN && F_EmptyN)
fcounter <= fcounter - 1;
end
end
end
// All the FIFO status signals depends on the value of fcounter.
// If the fcounter is equal to fdepth, indicates FIFO is full.
// If the fcounter is equal to zero, indicates the FIFO is empty.
// F_EmptyN signal indicates FIFO Empty Status. By default it is
// asserted, indicating the FIFO is empty. After the First Data is
// put into the FIFO the signal is deasserted.
always @(posedge Clk or negedge RstN)
begin
if(!RstN)
F_EmptyN <= 1'b0;
else begin
if(FClrN==1'b1) begin
if(F_EmptyN==1'b0 && WriteN==1'b0)
F_EmptyN <= 1'b1;
else if(F_FirstN==1'b0 && ReadN==1'b0 && WriteN==1'b1)
F_EmptyN <= 1'b0;
end
else
F_EmptyN <= 1'b0;
end
end
// F_FirstN signal indicates that there is only one datum sitting
// in the FIFO. When the FIFO is empty and a write to FIFO occurs,
// this signal gets asserted.
always @(posedge Clk or negedge RstN)
begin
if(!RstN)
F_FirstN <= 1'b1;
else begin
if(FClrN==1'b1) begin
if((F_EmptyN==1'b0 && WriteN==1'b0) ||
(fcounter==2 && ReadN==1'b0 && WriteN==1'b1))
F_FirstN <= 1'b0;
else if (F_FirstN==1'b0 && (WriteN ^ ReadN))
F_FirstN <= 1'b1;
end
else begin
F_FirstN <= 1'b1;
end
end
end
// F_SLastN indicates that there is space for only two data words
//in the FIFO.
always @(posedge Clk or negedge RstN)
begin
if(!RstN)
F_SLastN <= 1'b1;
else begin
if(FClrN==1'b1) begin
if( (F_LastN==1'b0 && ReadN==1'b0 && WriteN==1'b1) ||
(fcounter == (`FDEPTH-3) && WriteN==1'b0 && ReadN==1'b1))
F_SLastN <= 1'b0;
else if(F_SLastN==1'b0 && (ReadN ^ WriteN) )
F_SLastN <= 1'b1;
end
else
F_SLastN <= 1'b1;
end
end
// F_LastN indicates that there is one space for only one data
// word in the FIFO.
always @(posedge Clk or negedge RstN)
begin
if(!RstN)
F_LastN <= 1'b1;
else begin
if(FClrN==1'b1) begin
if ((F_FullN==1'b0 && ReadN==1'b0) ||
(fcounter == (`FDEPTH-2) && WriteN==1'b0 && ReadN==1'b1))
F_LastN <= 1'b0;
else if(F_LastN==1'b0 && (ReadN ^ WriteN) )
F_LastN <= 1'b1;
end
else
F_LastN <= 1'b1;
end
end
// F_FullN indicates that the FIFO is full.
always @(posedge Clk or negedge RstN)
begin
if(!RstN)
F_FullN <= 1'b1;
else begin
if(FClrN==1'b1) begin
if (F_LastN==1'b0 && WriteN==1'b0 && ReadN==1'b1)
F_FullN <= 1'b0;
else if(F_FullN==1'b0 && ReadN==1'b0)
F_FullN <= 1'b1;
end
else
F_FullN <= 1'b1;
end
end
endmodule
///////////////////////////////////////////////////////////////////
//
//
// Configurable memory block for fifo. The width of the mem
// block is configured via FWIDTH. All the data into fifo is done
// synchronous to block.
//
// Author : Venkata Ramana Kalapatapu
//
///////////////////////////////////////////////////////////////////
module FIFO_MEM_BLK( clk,
writeN,
wr_addr,
rd_addr,
data_in,
data_out
);
input clk; // input clk.
input writeN; // Write Signal to put data into fifo.
input [(`FCWIDTH-1):0] wr_addr; // Write Address.
input [(`FCWIDTH-1):0] rd_addr; // Read Address.
input [(`FWIDTH-1):0] data_in; // DataIn in to Memory Block
output [(`FWIDTH-1):0] data_out; // Data Out from the Memory
// Block(FIFO)
wire [(`FWIDTH-1):0] data_out;
reg [(`FWIDTH-1):0] FIFO[0`FDEPTH-1)];
assign data_out = FIFO[rd_addr];
always @(posedge clk)
begin
if(writeN==1'b0)
FIFO[wr_addr] <= data_in;
end
endmodule
PARTNER CONTENT

文章评论1条评论)

登录后参与讨论

用户377235 2013-8-14 17:08

hi
相关推荐阅读
用户1471583 2012-01-11 22:32
SOPC设计中多时钟域间的数据传递《转》
1 引言   可编程系统芯片SOPC的设计过程中经常会遇到如磁盘控制器、CD/DVD-ROM控制器、调制解调器、网络处理器等不同模块或系统间的数据传输。不同功能模块之间往往使用不同的时钟频率,各...
用户1471583 2012-01-11 22:30
FPGA异步时钟设计中的同步策略《转》
1 引言   基于FPGA的数字系统设计中大都推荐采用同步时序的设计,也就是单时钟系统。但是实际的工程中,纯粹单时钟系统设计的情况很少,特别是设计模块与外围芯片的通信中,跨时钟域的情况经常不可...
用户1471583 2012-01-11 22:20
MATLAB画双纵坐标
具有两个纵坐标标度的图形 在MATLAB中,如果需要绘制出具有不同纵坐标标度的两个图形,可以使用plotyy绘图函数。调用格式为: plotyy(x1,y1,x2,y2) 其中x1,y1对应...
用户1471583 2009-09-16 10:58
什么是TLB ?
TLB的基本概念:  TLB:Translation lookaside buffer,即旁路转换缓冲,或称为页表缓冲;里面存放的是一些页表文件(虚拟地址到物理地址的转换表)。  X86保护模式下的寻...
用户1471583 2009-07-26 15:52
Intel hex 文件格式(z)
Intel hex 文件常用来保存单片机或其他处理器的目标程序代码。它保存物理程序存储区中的目标代码映象。一般的编程器都支持这种格式。    Intel hex 文件全部由可打印的ASCII字符组成(...
用户1471583 2009-07-26 15:50
关于QuartusII里面调用MATLAB里生成的mif文件的一些问题(转)
最近做DDS正弦信号发生器,需要用到MATLAB生成一个正弦信号的ROM(MIF文件)。首先在MATLAB里面建立一个M-File,程序如下:depth=4096;                 %...
EE直播间
更多
我要评论
1
3
关闭 站长推荐上一条 /3 下一条