fifo知识整理

fifo知识整理

说明:均为网上资源整理,如有版权问题请联系删除

同步FIFO

21.跨时钟域
时钟的时序特性包括时钟周期、时钟占空比、时钟转换时间、时钟延迟、时钟偏斜和时钟抖动。
21.1格雷码与二进制转换
格雷码转二进制:
n位的二进制:Bn, Bn-1, Bn-2 … B2, B1, B0;
n位的格雷码:Gn, Gn-1, Gn-2 … G2, G1, G0;
转换公式: Bn =Gn;
Bi-1 = Bi ^ Gi-1;( i=0,1,2,n-1;
产生任意深度的 FIFO:
(1)格雷码是对称的,去掉中间几位格雷码,可以达到首尾相差 1 位,深度为偶数。
(2)深度为一般值,自行设计逻辑电路,或查找表。格雷码的 bus skew 不能超过一个周期,否则格雷码多位数据跳变失去作用。格雷码是对称的,去掉中间的或者去掉两头可以产生循环码。
Gray = Bin^(Bin>>1);错位异或的结果,(二进制转格雷码)
错位异或^ 异或:相同为0,相异为1
在这里插入图片描述

21.2同步fifo
同步fifo:同一时钟域下的,同时用于写入和读取操作。同步FIFO用于临时存储数据,此时写人和读取操作可以同时发生,也可发生在不同时刻。
clk : 该时钟为同步FIFO读写操作的工作时钟。
rst_n : 该信号为同步FIFO的复位信号,低电平有效。
wren : 该信号为同步FIFO的写使能。
rden : 该信号为同步FIFO的读使能。
wdata : 该总线为写数据总线。
rdata : 该总线为读数据总线。
full : 该信号为FIFO已满标志。如果 FIFO 为满状态,则禁止再写数据。
empty : 该信号为FIFO已空标志。如果 FIFO 为空状态,则禁止再读数据

同步FIFO结构:memory、写控制逻辑、读控制逻辑、空满标志判断

在这里插入图片描述

在 FIFO 中常用的RAM包括单口RAM、简单双口RAM、真双口RAM、单口ROM、双口ROM这5种类型的RAM,也可以使用寄存器来实现FIFO的存储器。
在这里插入图片描述

wclk : 该时钟为双口RAM写操作的工作时钟。
wren : 该信号为双口RAM的写使能。
waddr : 该总线为双口RAM的写地址总线。
wdata : 该总线为双口RAM的写数据总线。
rclk : 该时钟为双口RAM读操作的工作时钟。
rden : 该信号为双口RAM的读使能。
raddr : 该总线为双口RAM的读地址总线。
rdata: 该总线为双口RAM的读数据总线。
在这里插入图片描述

写控制逻辑----------------------------------------------------------------------------

always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
	    waddr <= {
   ADDR_WIDTH{
   1'b0}};
	else if (wren && !wfull)  //只有写使能并且没写满的时候才能操作写地址
	begin
        if(waddr == DEPTH - 1)	//如果快要计数到最大,则清零重新给读地址。
          waddr <= {
   ADDR_WIDTH{
   1'b0}};
	    else
		    waddr <= waddr + 1'd1;
	end
	else
	    waddr <= waddr;
end

读控制逻辑----------------------------------------------------------------------------

always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
	    raddr <= {
   ADDR_WIDTH{
   1'b0}};
	else if (rden && !rempty)//只有读使能并且没读空的时候才能操作读地址
	begin
        if(raddr == DEPTH - 1)//如果快要计数到最大,则清零重新给读地址。
            raddr <= {
   ADDR_WIDTH{
   1'b0}};			
	    else
		    raddr <= raddr + 1'd1;
	end
	else
	    raddr <= raddr;
end

空满标志产生逻辑(两种解法)----------------------------------------------------------------------------
一:用地址计数器addr_cnt,在执行一次写操作时addr_cnt加1,执行一次读操作时addr_cnt减1。
1.如何操作地址计数器

always@(posedge clk or negedge rst_n)
	begin
	    if(!rst_n) //复位时为0
		    addr_cout <= {
   (ADDR_WIDTH){
   1'b0}};
		else if(wren && !rden && !wfull && (addr_cout < DEPTH-1))
//条件为写使能,不读使能,并且没写满时,地址<深度减一  
防止在读写使能同时有效,FIFO已经存满时读使能无效,造成地址计数器向上溢出,产生错误的读空标志。
			addr_cout <= addr_cout + 1'd1;
	    else if(!wren&& rden && !rempty && (addr_cout > 0))
//条件不写使能,读使能,并且没读空时,地址>0 
防止在读写使能同时有效,FIFO只有1位时(此时地址计数器值为0),写使能无效,造成地址计数器向下溢出,产生错误的写满标志.
			addr_cout <= addr_cout - 1'd1;
		else
		    addr_cout <= addr_cout;
End

2.写满标志位产生

   always@(posedge clk or negedge rst_n)
   begin
       if(!rst_n)
   	    wfull <= 1'b0;
   	else
   		wfull <= ((!rinc) && (((addr_cout== DEPTH-2)&&winc)||(addr_cout== DEPTH-1)));
   end

当读使能无效,地址计数器计数值等于FIFO的深度减1时,写满标志有效。
当读使能无效,地址计数器计数值等于FIFO的深度减2,写使能有效时。写满标志有效。

3.读空标志位产生

always@(posedge clk or negedge rst_n)
begin
    if(!rst_n)
	    rempty <= 1'b1;
    else   
		rempty <= ((!winc) && (((addr_cout== 1)&&rinc)||(addr_cout==0)));
end

当写使能无效,地址计数器计数值等于0时,读空标志有效。
当写使能无效,地址计数器计数值等于1时,读使能有效时。读空标志有效。

module  sync_fifo#(
	parameter	WIDTH = 8,
	parameter 	DEPTH = 16
)(
	input 					clk		, //读写时钟
	input 					rst_n	, //异步复位
	input 					wren	, //写使能
	input 			 		rden	, //读使能
	input 		[WIDTH-1:0]	wdata	, //写数据

	output wire				wfull	, //写满信号
	output wire				rempty	, //读空信号
	output wire [WIDTH-1:0]	rdata     //读数据
);
	/********************** 内部信号声明 **********************/
	localparam    ADDR_WIDTH = $clog2(DEPTH);   //地址位宽
	
	wire                       wenc     ;       //双端口RAM写使能
	wire                       renc     ;  	    //双端口RAM读使能
	reg    [ADDR_WIDTH:0]      waddr    ;       //写地址寄存器
	reg    [ADDR_WIDTH:0]      raddr    ;       //读地址寄存器
	/*************************功能定义*************************/	
    
	assign    wenc = wren && !wfull;
	assign    renc = rden && !rempty;
	
	//双端口RAM
    dual_port_RAM #(.DEPTH(DEPTH),.WIDTH(WIDTH))
	dual_port_RAM_U1
	(
	    .wclk     (clk                  ),   //写数据时钟
	    .wenc     (wenc                 ),   //写使能
	    .
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sr_shirui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值