//////////////////////////////////////////////////////////////////////////////////
module fifo_case #(
parameter DATA_WIDTH=4
) (
input clk,
input wr_en,
input rd_en,
input rst,
input [DATA_WIDTH-1:0]wr,
output reg [DATA_WIDTH-1:0]rd,
output reg fifo_empty,
output reg fifo_full
);
parameter ADDER_WIDTH=4;
parameter MAX_COUNT=15;
reg [ADDER_WIDTH-1:0] count;
always @(posedge clk or posedge rst)begin
if(rst) count<=0;
else begin
case({wr_en,rd_en})
2'b00:count<=count;
2'b01:
if(count!==0) count<=count-1;
else count<=0;
2'b10:
if(count!==MAX_COUNT) count<=count+1;
else count<=MAX_COUNT;
2'b11:count<=count;
endcase
end
end
//1.自己添加的读出写法
always @(posedge clk or posedge rst)begin
if(rst) begin
rd <= 4'd0;
fifo[wr_adder] <= 4'd0;
end
else begin
case({wr_en,rd_en})
2'b00:begin
rd <= 4'd0;
fifo[wr_adder] <= 4'd0;
end
2'b01:begin
rd <= fifo[rd_adder];
//wr <= wr;
end
2'b10:begin
rd <= rd;
fifo[wr_adder] <= wr;
end
2'b11:begin
rd <= rd;
//wr <= wr;
end
endcase
end
end
always @(posedge clk) begin
if(count==0)fifo_empty <= 1;
else fifo_empty <= 0;
end
always @(posedge clk)begin
if(count==MAX_COUNT) fifo_full <= 1;
else fifo_full <= 0;
end
reg [ADDER_WIDTH-1:0] wr_adder;
reg [ADDER_WIDTH-1:0] rd_adder;
always @(posedge clk)begin
if(rst)wr_adder<=0;
else if(fifo_full==0&&wr_en==1) wr_adder<=wr_adder+1;
else if(fifo_full==0&&wr_en==0) wr_adder<=wr_adder;
else wr_adder<=0;
end
always @(posedge clk)begin
if(rst) rd_adder<=0;
else if(fifo_empty==0&&rd_en==1) rd_adder<=rd_adder+1;
else if(fifo_empty==0&&rd_en==0) rd_adder<=rd_adder;
else rd_adder<=0;
end
parameter WIDTH=16;
reg [WIDTH-1:0]fifo[0:WIDTH-1];
//下面是对rd读出的不同写法进行了仿真讨论
//2.会有一些不确定输出的问题
//always @(posedge clk )begin
// if(rd_en) rd<=fifo[rd_adder];
// else rd<= rd;
//end
//
//always @(posedge clk )begin
// if(wr_en) fifo[wr_adder]<=wr;
// else fifo[wr_adder] <= fifo[wr_adder];
//end
//3.类似上面begin_case写法的应用
//always @(*)begin
// if(rd_en) rd = fifo[rd_adder];
// else rd<=0;
//end
//
//always @(*)begin
// if(wr_en) fifo[wr_adder] = wr;
//end
endmodule