话不多说,直接上代码!
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2022/05/18 17:28:24
// Design Name:
// Module Name: sync_FIFO
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
// 设计目标为:读写数据位宽16 , FIFO深度64 的同步FIFO
// 主要包括 (1)计数逻辑 (2)地址指针逻辑 (3)读写数据逻辑 (4)空满标志产生
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module sync_FIFO (
input clk,
input rst_n,
//read signal
output reg [15:0] rd_data,
input rd_en,
output empty,
//write signal
input [15:0] wr_data,
input wr_en,
output full
);
reg [6:0] cnt; //cnt位宽要比地址指针多一位 , 因为cnt要记到64
reg [5:0] wr_ptr; //循环指针, 0-63-0-63
reg [5:0] rd_ptr;
reg [15:0] RAM [63:0];
//counter
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt <= 6'b0;
else if((wr_en && !full) && (rd_en && !empty))//必须首先写此else if项,否则可能出错; if-else是优先级电路
cnt <= cnt;
else if(wr_en && !full)
cnt <= cnt + 1'b1;
else if(rd_en && !empty)
cnt <= cnt - 1'b1;
else
cnt <= cnt;
end
//wr_pointer & rd_pointer
always @(posedge clk or negedge rst_n) begin
if(!rst_n) begin
wr_ptr <= 6'b0;
rd_ptr <= 6'b0;
end
else begin
if(wr_en && !full) //两个if语句,每一个都要执行;就可以比counter逻辑简化
wr_ptr <= wr_ptr + 1'b1;
if(rd_en && !empty)
rd_ptr <= rd_ptr + 1'b1;
end
end
//read data
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
rd_data <= 16'd0;
else if(rd_en & !empty)
rd_data <= RAM[rd_ptr];
end
//write data
always @(posedge clk) begin //可以不对存储器进行复位
if(wr_en & !full)
RAM[wr_ptr] <= wr_data;
end
//flag of empty & full
assign full = (cnt == 7'd64);
assign empty = (cnt == 7'd0);
endmodule