FIFO相关问题(二)

15.同步FIFO实现代码

15.1. FIFO模块(FIFO_sync)

//synchronous FIFO
  module FIFO_sync(clk,
                 rst_n,
                  w_en,
                  r_en,
                w_data,
                r_data,
                 count,
                  full,
                  empty
                    );
    
    //parameter defines
    parameter DATA_WIDTH = 8;
    parameter FIFO_DEPTH = 8;
    parameter ADDR_WIDTH = 3;

    //signals direction declaration 
    input           clk;
    input			      rst_n;
    input			      w_en;
    input			      r_en;
    input	          w_data;

    output	        r_data;
    output			    full;
    output			    empty;
    output			    count;

    //register declaration
    reg [ADDR_WIDTH-1:0] w_ptr;
    reg [ADDR_WIDTH-1:0] r_ptr;
    reg [DATA_WIDTH-1:0] r_data;
    reg [ADDR_WIDTH:0]	 count;
    reg [DATA_WIDTH-1:0] mem[0:FIFO_DEPTH-1];
    integer i;

    //write operation
    always@(posedge clk or negedge rst_n)
    begin
      if(!rst_n)        w_ptr <= {ADDR_WIDTH{1'b0}};
      else
      begin
        if(w_en && ~full)
        begin
        	mem[w_ptr] <= w_data;
        	w_ptr <= w_ptr + 1'b1;
        end
      end
    end

    //read operation
    always@(posedge clk or negedge rst_n)
    begin
      if(!rst_n)
      begin
        r_data <= {DATA_WIDTH{1'b0}};
        r_ptr <= {ADDR_WIDTH{1'b0}};
      end
      else
      begin
        if(r_en &&  ~empty)
        begin
          r_data <= mem[r_ptr];
          r_ptr <= r_ptr + 1;
        end
      end
    end

  //count signal process
  always@(posedge clk or negedge rst_n) 
  begin
    if(!rst_n)   count <= {(ADDR_WIDTH+1){1'b0}};
    else
    begin
      if(w_en && ~full && r_en && ~empty)    count <= count;
      else if(w_en && ~full)                 count <= count + 1'b1;
      else if(r_en && ~empty)                count <= count - 1'b1;	
    end
   end

	//mem initialization
	always@(posedge clk or negedge rst_n)
	begin
		if(!rst_n)
		begin
			for(i=0;i<FIFO_DEPTH;i=i+1)      mem[i] <= {DATA_WIDTH{1'b0}};	
		end
	end

  //empty and full signal process
  assign empty = (count == 0);
  assign full = (count == {ADDR_WIDTH{1'b1}} + 1);
    
  endmodule

信号列表:

系统信号:

clk:系统时钟

rst_n:复位信号

输入:

w_en:写使能

r_en:读使能

w_data:写入FIFO数据(外部输入,线网类型)

输出:

r_data:读出FIFO数据(输出缓存,reg类型)

full:FIFO满信号

empty:FIFO空信号

count:FIFO数据数量

寄存器:

w_ptr:写指针

r_ptr:读指针

mem:FIFO存储空间

参数定义:

DATA_WIDTH:数据位宽(FIFO中存储的数据比特位数)

FIFO_DEPTH:FIFO深度(容量)

ADDR_WIDTH:地址位宽(log2FIFO_DEPTH

内部逻辑分为四部分:写操作,读操作,count处理模块,men初始化

写操作:复位场景下w_ptr复位(清0);满足写条件时,数据写入mem[w_ptr],写指针+1;

读操作:复位场景下r_datar_ptr复位(清0);满足读条件时,数据从mem[r_ptr]读到r_data,读指针+1;

count:复位场景下count清0;同时读写count不变,只写时count自增1,只读时count自减1。

mem:复位场景,内存块清0。

最后添加emptyfull判断逻辑。

15.2. 测试模块(FIFO_sync_top)

//test file of FIFO_syno

module FIFO_sync_top;

  reg 		  clk;
  reg 		  rst_n;
  reg		    w_en;
  reg		    r_en;
  reg	[7:0]	w_data;
  reg	[3:0]	count;
  reg	[7:0]	r_data;

  wire		full;
  wire		empty;

  initial begin
    clk 	  = 0;
    rst_n 	= 0;
    w_data 	= 8'b0000_0000;
    w_en 	  = 0;
    r_en 	  = 0;

    #25   rst_n  = 1;
    #50   rst_n  = 0;
    #100  rst_n  = 1;
    #25   w_en   = 1;
    #100  r_en   = 1;
    #100  w_en   = 0;     r_en  = 0;
    #100  w_en   = 1;
    #1200 r_en   = 1;     w_en  = 0;
  end

  initial begin
    for(int i = 0; i < 50; i = i + 1) begin
      #100 w_data = i;
    end
  end

  //generate system clock
  always begin
    #50 clk = ~clk;
  end

  //finish simulation
  initial
  begin
 	  #4000 
 	  $stop();
  end 

  //instance FIFO_sync module
  FIFO_sync ut(
               .clk(clk),
               .rst_n(rst_n),
               .w_data(w_data),
               .r_data(r_data),
               .w_en(w_en),
               .r_en(r_en),
               .count(count),
               .full(full),
               .empty(empty)
               );

endmodule

定义信号

输入FIFO(激励):clk,rst,w_en,r_en,w_data

接收FIFO输出:count,r_data

两个initial块:产生激励。

always块:产生系统时钟信号。

实例化FIFO_sync并连接相应信号线。

3.波形分析

编译命令:

vcs FIFO_sync_test.sv FIFO_sync.v -sverilog -debug_all

仿真命令:

./simv -gui

波形:

在这里插入图片描述

波形分析:

0~250 系统复位
250~ 写入第一个数据
350 同时读写,写入02,读出数据为01----------------------------------------------------(同时读写)
450 不读写,count不变为1------------------------------------------------------------------(不读不写)
550-1150 持续写入数据,1150时刻count为8,FIFO为满 full信号拉高-----------(不读只写入)
1150~1650 FIFO为满,此区间w_en为高,r_en为低,数据无法写入------------------------(写边界)
1700 时刻w_en拉底,r_拉高进行读操作
1750~2450 数据持续读出,2450时刻FIFO为空,empty拉高------------------------------(不写只读出)
2550~ w_en为低,r_en为高,empty为高,无法读出数据-----------------------------(读边界)

参考文献:

https://zhuanlan.zhihu.com/p/404518524

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

搬砖小张

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

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

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

打赏作者

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

抵扣说明:

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

余额充值