同步FIFO
同步FIFO
module fifo#(parameter fifo_depth = 8, addr_width = 3, data_width = 16) (input clk, input rst_n, input [15:0] data_in, output reg [15:0] data_out, input rd_en, input wr_en, output reg empty, output reg full); reg [15:0] mem [7:0]; reg [3:0] rd_addr_ptr; reg [3:0] wr_addr_ptr; wire [2:0] rd_addr; wire [2:0] wr_addr; assign rd_addr = rd_addr_ptr[2:0]; assign wr_addr = wr_addr_ptr[2:0]; assign empty = wr_addr_ptr == rd_addr_ptr; assign full = {~wr_addr_ptr[3],wr_addr_ptr[2:0]} == rd_addr_ptr; // 读写指针 always@(posedge clk or negedge rst_n) begin if(!rst_n) begin wr_addr <= h’0; end else if (wr_en & ~full) wr_addr <= wr_addr + 1’b1; end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin rd_addr <= h’0; end else if (rd_en & ~empty) rd_addr <= rd_addr + 1’b1; end //读写数据 always@(posedge clk or negedge rst_n) begin if(!rst_n) begin data_out <= h’0; end else if(rd_en & ~empty) data_out <= mem[rd_addr]; end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin mem[wr_addr] <= h’0; end else if(wr_en & ~full) mem[wr_addr] <= data_in; end endmodule
module FIFO_sync( clk, rst, w_en, r_en, data_in, data_out, count, full, empty ); parameter FIFO_data_size=16, FIFO_addr_size=8; input clk,rst; input w_en,r_en; input[FIFO_data_size-1:0] data_in; output[FIFO_data_size-1:0] data_out; output full,empty; output[FIFO_addr_size:0]count; reg [FIFO_data_size-1:0] data_out; reg [FIFO_addr_size:0]count; reg [FIFO_addr_size-1:0]w_addr,r_addr; reg [FIFO_data_size-1:0]mem[{FIFO_addr_size{1'b1}}:0]; integer i; //memory的初始化以及写操作 always@(posedge clk or negedge rst) begin if(!rst) begin w_addr<=0; for(i=0;i<={FIFO_addr_size{1'b1}};i=i+1) mem[i]<={FIFO_data_size{1'b0}}; end else if(w_en&(~full)) begin mem[w_addr]<=data_in; w_addr<=w_addr+1; end end //读操作 always@(posedge clk or negedge rst) begin if(!rst) begin data_out<={(FIFO_data_size-1){1'b0}}; r_addr<=0; end else if(r_en&(~empty)) begin data_out<=mem[r_addr]; r_addr<=r_addr+1; end end //count产生空满标志符 always@(posedge clk or negedge rst) begin if(!rst) count<=0; else if(((w_en)&(~full))&(~((r_en)&(~empty)))) count<=count+1; else if(((r_en)&(~empty))&(~((w_en)&(~full)))) count<=count-1; end assign empty=(count==0); assign full=(count=={FIFO_addr_size{1'b1}}+1); endmodule