module syn_fifo(
input clk,
input rst_n,
input [7:0] din,
input wr_en,
input rd_en,
output [7:0] dout,
output full,
output empty
);
reg wr_en_r;
reg rd_en_r;
always@(posedge clk or negedge rst_n)begin
if(!rst_n) wr_en_r <= 0;
else wr_en_r <= wr_en;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n) rd_en_r <= 0;
else rd_en_r <= rd_en;
end
reg [3:0] status_cnt;
always@(posedge clk or negedge rst_n)begin
if(!rst_n) status_cnt <= 0;
else if(wr_en_r && !rd_en && status_cnt != 4'd15 )
status_cnt <= status_cnt + 1'b1;
else if(rd_en_r && !wr_en && status_cnt != 0 )
status_cnt <= status_cnt - 1'b1;
else status_cnt <= status_cnt;
end
wire full_r1;
reg full_r2;
assign full_r1 = (status_cnt == 15)?1'b1:1'b0;
always@(posedge clk or negedge rst_n)begin
if(!rst_n) full_r2 <= 0;
else full_r2 <= full_r1;
end
assign full = full_r1 && full_r2;
wire empty_r1;
reg empty_r2;
assign empty_r1 = (status_cnt == 0)?1'b1:1'b0;
always@(posedge clk or negedge rst_n)begin
if(!rst_n) empty_r2 <= 1;
else empty_r2 <= empty_r1;
end
assign empty = empty_r1 && empty_r2;
reg [3:0] wr_cnt;
reg [3:0] rd_cnt;
always@(posedge clk or negedge rst_n)begin
if(!rst_n) wr_cnt <= 0;
else if (wr_en && !full)begin
if(wr_cnt < 15) wr_cnt <= wr_cnt + 1'b1;
else wr_cnt <= 0;
end
else wr_cnt <= wr_cnt;
end
always@(posedge clk or negedge rst_n)begin
if(!rst_n) rd_cnt <= 0;
else if (rd_en && !empty)begin
if(rd_cnt < 15) rd_cnt <= rd_cnt + 1'b1;
else rd_cnt <= 0;
end
else rd_cnt <= rd_cnt;
end
//write
reg [7:0] DATA [15:0];
always@(posedge clk or negedge rst_n)begin
if(!rst_n) begin
DATA[0] <= 0;
DATA[1] <= 0;
DATA[2] <= 0;
DATA[3] <= 0;
DATA[4] <= 0;
DATA[5] <= 0;
DATA[6] <= 0;
DATA[7] <= 0;
DATA[8] <= 0;
DATA[9] <= 0;
DATA[10] <= 0;
DATA[11] <= 0;
DATA[12] <= 0;
DATA[13] <= 0;
DATA[14] <= 0;
DATA[15] <= 0;
end
else if(wr_en && !full)
DATA[wr_cnt] <= din;
end
//READ
reg [7:0] data_r;
always@(posedge clk or negedge rst_n)begin
if(!rst_n) data_r <= 0;
else if(rd_en_r && !empty)
data_r <= DATA[rd_cnt];
// else data_r <= 0;
else data_r <= data_r;
end
assign dout = data_r;
endmodule
用Verilog实现一个同步FIFO,深度16,数据位宽8bit
最新推荐文章于 2024-07-22 19:30:03 发布