主模块:
`timescale 1ns / 1ps
module Async_FIFO#(
parameter ADDR_WIDTH = 4,
DATA_WIDTH = 8,
ALMOST_GAP = 3
)(
input wire wr_clk , //写时钟
input wire wr_rst_n, //写复位
input wire wr_en , //写使能
input wire [DATA_WIDTH-1:0] wr_data , //用于写入的数据
input wire rd_clk , //读时钟
input wire rd_rst_n, //读复位
input wire rd_en , //读使能
output reg full , //FIFO写满信号,使用输出寄存器以保证与控制时钟同步
output reg empty , //FIFO读空信号,使用输出寄存器以保证与控制时钟同步
output reg almost_full,//FIFO将满信号,使用输出寄存器以保证与控制时钟同步
output reg almost_empty,//FIFO将空信号,使用输出寄存器以保证与控制时钟同步
output wire [DATA_WIDTH-1:0] rd_data //读出的数据
);
wire full_next, empty_next, almost_empty_next, almost_full_next;//空满信号次态逻辑
reg [ADDR_WIDTH:0] wr_addr_ptr_next, rd_addr_ptr_next;//读写地址指针二进制码次态逻辑
reg [ADDR_WIDTH:0] wr_addr_ptr, rd_addr_ptr; //读写地址指针
wire [ADDR_WIDTH-1:0] wr_addr, rd_addr; //读写地址
//读写地址赋值
assign wr_addr = wr_addr_ptr[ADDR_WIDTH-1:0];
assign rd_addr = rd_addr_ptr[ADDR_WIDTH-1:0];
wire [ADDR_WIDTH:0] wr_addr_ptr_gray_next, rd_addr_ptr_gray_next; //读写地址指针格雷码次态逻辑
reg [ADDR_WIDTH:0] wr_addr_ptr_gray, wr_addr_ptr_gray1, wr_addr_ptr_gray2; //写地址指针格雷码转换及跨时钟打拍信号
reg [ADDR_WIDTH:0] rd_addr_ptr_gray, rd_addr_ptr_gray1, rd_addr_ptr_gray2; //读地址指针格雷码转换及跨时钟打拍信号
// *************************** 写时钟域时序逻辑 ***************************** //
//数据更新
always@(posedge wr_clk or negedge wr_rst_n)
if(!wr_rst_n) begin
wr_addr_ptr <= 0;
wr_addr_ptr_gray <= 0;
full <= 0;
almost_full <= 0;
end
else begin
wr_addr_ptr <= wr_addr_ptr_next;
wr_addr_ptr_gray <= wr_addr_ptr_gray_next;
full <= full_next;
almost_full <= almost_full_next;
end
/