当前位置: 代码迷 >> 综合 >> FIFO IP核使用感受
  详细解决方案

FIFO IP核使用感受

热度:50   发布时间:2024-03-07 23:25:06.0

FIFO IP核使用感受

  • 创建IP核
  • 写入开始
  • 写入结束
  • 读取开始
  • 读取结束
    • **欢迎自行测试**

创建IP核

本次实验创建了一个8位输入 4位输出的IP核心,并将IP核心所有信号都进行添加

在这里插入图片描述
先进行前仿真,写入时钟为读取时钟的两倍

写入开始

在这里插入图片描述
在这里插入图片描述

  1. 第1个 wclk 上升沿,wrreq <= 1;
  2. 第2个 wclk 上升沿,当 wrreq 置 1,此时写入送入到 data 端口的数据,此时写入值为 8’h12 ,写入过程发生在上升沿
  3. 第3个 wclk 上升沿, wrempty 置 0,同时 wrusedw 输出 0;此时写入值为 8’h13
  4. 第4个 wclk 上升沿,同时 wrusedw 输出 1;此时写入值为 8’h14
  5. 第6至17个 wclk 上升沿,此时写入值为 8’h15至8‘h21, 同时 wrusedw 输出 2-14;
  6. 第18个 wclk 上升沿,wrusedw 输出 1,wrfull 置为 1;此时无法检测出wrfull 为1
  7. 第19个 wclk 上升沿,可以检测wrfull ,
    所以一个完整写入fifo,并检测FIFO是否写入满需要经过4个周期
// 写入0:beginwrreq <= 1;data <= DIN;end1:wrreq <= 0//写入中2:;//等待wrfull置为13:;//判断是狗写入满

写入结束

在这里插入图片描述
在这里插入图片描述
对于写入时的 rdempty和 rdusedw变化情况
本实验创建fifo的深度为16,所以对图 wrusedw 范围为0~15 ,而对于rdusedw是0~31。
当wrusedw 输出 1时rdusedw输出为0,此时rdempty还为高,下个写入时钟rdusedw输出为2,根据写入时钟变化
当超额写入时写入信号时rdusedw wrusedw 为 0,但是实际并没写入 当rdusedw == 31 时 rdfull = 1

读取开始

.在这里插入图片描述

  1. 第1个 rclk 上升沿,rdreq <= 1;
  2. 第2个 rclk 上升沿,当 rdreq 置 1;
  3. 第3个 rclk 上升沿,输出数据低位 4’h2;
  4. 第4个 rclk 上升沿,输出数据高位 4’h1;此时rdusedw 输出31
  5. 第5个 rclk 上升沿,输出数据高位 4’h3;此时rdusedw 输出30
  6. 顺序读出.

读取结束

在这里插入图片描述
当输出完成后rdempty同步变化,但是rdusedw 为检测到读空后的下个周期变化

欢迎自行测试

`timescale 1ns/1ns `define clk_period 20module fifo_test();reg clk;reg rst_n;reg	[7:0]	data	;reg			rdclk   ;
//	reg			rdreq   ;wire			wrclk   ;reg			wrreq   ;wire	[3:0]	q       ;wire			rdempty ;wire			rdfull  ;wire	[4:0]	rdusedw ;wire			wrempty ;wire			wrfull  ;wire	[3:0]	wrusedw ;
//	reg	[3:0]	data_out;
fifotest fifotest(.data			  (data	),.rdclk            (rdclk   ),.rdreq            (   ),.wrclk            (wrclk   ),.wrreq            (wrreq   ),.q                (q       ),.rdempty          (rdempty ),.rdfull           (rdfull  ),.rdusedw          (rdusedw ),.wrempty          (wrempty ),.wrfull           (wrfull  ),.wrusedw          (wrusedw ));assign wrclk = clk;initial clk = 1;always#(`clk_period/2) clk = ~clk;initial rdclk = 1;always#(`clk_period/5) rdclk = ~rdclk;always@(posedge wrclk or negedge rst_n)if(!rst_n)begindata <= 8'h11;wrreq <= 0;endelse if(!wrfull)beginif(data <= 8'h19)beginwrreq <= 1;data <= data + 1'b1;endelse beginwrreq <= 0;data <= data;endendelse beginwrreq <= 0;data <= 8'h11;end//	always@(posedge rdclk or negedge rst_n)
//	if(!rst_n)begin
//		rdreq <= 0;
//		data_out <= 4'hf; // end // else if(!rdempty & !wrreq)begin // rdreq <= 1; // data_out <= q; // end // else begin // rdreq <= 0; // data_out <= 4'hf;
//	endinitial beginrst_n = 0;#(`clk_period*20);rst_n = 1;#(`clk_period*500);$stop;end endmodule