【同步FIFO Verilog&IC】详解

一、介绍
  FIFO是一种先进先出的数据缓存器,通常用于接口电路的数据缓存。与普通存储器的区别是没有外部读写地址线,可以用两个时钟分别进行读写操作,FIFO只能顺序写入与顺序读出数据,其数据地址由内部数据读写指针自动加1完成,不能像普通存储器那样由地址线决定读出或写入某个地址。
  FIFO由存储块与控制FIFO传输通道的控制器组成,每次只对一个存储器进行存取操作,而不是对整个寄存器阵列进行。FIFO有两个地址指针,一个将数据写入存储器,一个将数据读出存储器。
二、整体结构
在这里插入图片描述

三、读写控制过程
  内部双口ram的读写时钟(图中只用clk表示)分别为wclk/rclk,由外部clk提供,ram的读写使能分别来自于FIFO控制端的读写有效信号,ram的读写地址信号来自于控制端,ram的输入输出数据接口,分别为写入与读出数据。
  再看FIFO控制端,来自外部的读写有效信号与时钟信号,剩余需要我们关注的是write_ptr、read_ptr(写地址与读地址),stack_full与stack_empty(写满与读空信号)。
首先分析什么情况写入数据,也就是此时写地址需+1,条件是:写使能有效&&没写满,读地址同样如此,条件读使能有效&&没读空
  其次什么情况下写满与写空呢,例如我们需要写一个深度为4的FIFO,此时我们的地址位本来应该为2位的,但是这里多取1位做写满读空标志位,也就是写地址与读地址为3位信号。
在这里插入图片描述
深度为8,数据位宽为8的FIFO代码:

module FIFO_Buffer #(parameter stack_width = 8,
	                 parameter stack_height = 8,
	                 parameter stack_ptr_wedth =3)(
	//system signals
	input  								clk, 
	input								rst,
	input                    write_to_stack,
	input                   read_from_stack,
	input         [7:0]              data_in,
	//
	output        [7:0]              data_out
    

);
   wire [stack_ptr_wedth:0] write_ptr;
   wire [stack_ptr_wedth:0] read_ptr;

   FIFO_control u_FIFO_control(
        .clk(clk),
        .rst(rst),
        .write_to_stack(write_to_stack),
        .read_from_stack(read_from_stack), 
        .write_ptr(write_ptr),
        .read_ptr(read_ptr),
        .stack_full(stack_full),
        .stack_empty(satck_empty)
   	);

   dual_ram u_dual_ram(
        .wclk(clk),
        .rclk(clk),
        .we(write_to_stack),
        .rd(read_from_stack),
        .addr_w(write_ptr[stack_ptr_wedth-1:0]),
        .addr_r(read_ptr[stack_ptr_wedth-1:0]),
        .d(data_in),
        .q(data_out)
   	);

endmodule

module FIFO_control (
	//system signals
	input  								              clk, 
	input								              rst,
	input                                  write_to_stack,
	input                                 read_from_stack,
	//
	output  reg  [stack_ptr_wedth:0]            write_ptr,
	output  reg  [stack_ptr_wedth:0]             read_ptr,
	output  reg                                stack_full,
    output  reg                                stack_empty

);
    parameter stack_width = 8;//FIFO数据位宽
    parameter stack_height = 8;//FIFO深度
    parameter stack_ptr_wedth = 3;//FIFO数据地址位宽,最高位为标志位 
    

    
    always @(posedge clk or posedge rst) begin
    	if (rst) begin
    		write_ptr <='b0;
    		read_ptr <='b0;
            
    	end
    	else if (write_to_stack&&(~read_from_stack)&&(~stack_full)) begin
            
    		write_ptr <= write_ptr+1; 
    	end
    	else if((~write_to_stack)&&read_from_stack&&(~stack_empty)) begin

    	    read_ptr <= read_ptr+1;
    	end

    end
    
    always @(posedge clk or negedge rst) begin : proc_
    	if(~rst) begin
    		stack_full <= 'b0;
    		stack_empty<='b0;
    	end 
    	else begin
    		stack_full <= (read_ptr=={~write_ptr[stack_ptr_wedth],write_ptr[stack_ptr_wedth-1:0]});
            stack_empty <= (read_ptr==write_ptr);
    	end
    end

endmodule

module dual_ram #(parameter stack_width = 8,
	              parameter stack_height = 8,
	              parameter stack_ptr_wedth =3)(
	input wclk,    // Clock
	input rclk,
	input we,
	input rd, 
	input [stack_width-1:0] d,
    input [stack_ptr_wedth-1:0] addr_w,
    input [stack_ptr_wedth-1:0] addr_r,

	output reg [stack_width-1:0] q 
	
);

reg [stack_width-1:0] ram_mem [stack_height-1:0];
   always @(posedge wclk) begin
   	  if(we)
   	  	ram_mem[addr_w] <= d;
   end

   always @(posedge rclk) begin
   	  if(rd)
   	  	q <= ram_mem[addr_r];
   end	
endmodule 


  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值