转了一篇别人写的,没看一眼代码,因为最不喜欢的就是看别人写的代码。今天抽空自己写了一段小代码,在ModelSim中仿真了,结果还是正确的。
module chipfifo(clk,rst,wr,din,rd,dout,full,empty,half_full);
input clk,rst;
input wr,rd;
input [7:0] din;
output [7:0] dout;
output full,empty,half_full;
reg [7:0] dout;
reg [4:0] cnt_rd; //读数据指示器
reg [4:0] cnt_wr; //写数据指示器
reg [4:0] cnt_data; //数据个数指示器
reg [7:0] fiforam[15:0]; //FIFO存储数组
reg empty,full,half_full;
always @ (posedge clk or negedge rst)
begin
if(!rst) //异步复位
begin
cnt_rd<=5'd0;
cnt_wr<=5'd0;
cnt_data<=5'd0;
full<=1'd0;
empty<=1'd0;
half_full<=1'd0;
end
else
begin
case({rd,wr})
2'b01: //只写操作
begin
if(!full) //FIFO没有写满,则执行写操作
begin
if(cnt_data==5'd16) //FIFO中已经有15个数据,再写就满了
begin
fiforam[cnt_wr-1]<=din;
cnt_data<=cnt_data;
full<=1'd1;
cnt_wr<=4'd0;
end
else
begin
fiforam[cnt_wr-1]<=din;
cnt_data<=cnt_data+5'd1;
full<=1'd0;
if(cnt_wr==5'd16)
cnt_wr<=4'd1;
else
cnt_wr<=cnt_wr+5'd1;
end
if(cnt_wr==5'd8) //半满标志
half_full<=1'd1;
else
half_full<=1'd0;
empty<=1'd0; //只写时空标志为0
end
else
begin
cnt_rd<=cnt_rd;
cnt_wr<=cnt_wr;
cnt_data<=cnt_data;
full<=full;
empty<=empty;
half_full<=half_full;
end
end
2'b10: //只读操作
begin
if(!empty) //FIFO没有读空,则执行读操作
begin
if(cnt_data==5'd0) //FIFO中只有1个数据,再读就空了
begin
dout<=fiforam[cnt_rd-1];
cnt_data<=cnt_data;
empty<=1'd1;
cnt_rd<=5'd0;
end
else
begin
dout<=fiforam[cnt_rd-1];
cnt_data<=cnt_data-5'd1;
empty<=1'd0;
if(cnt_rd==5'd16)
cnt_rd<=5'd0;
else
cnt_rd<=cnt_rd+5'd1;
end
full<=1'd0; //只写时空标志为0
end
else
begin
cnt_rd<=cnt_rd;
cnt_wr<=cnt_wr;
cnt_data<=cnt_data;
full<=full;
empty<=empty;
half_full<=half_full;
end
end
2'b11: //读写同时进行
begin
case({full,empty})
2'b00: //既没有写满也没有读空的情况
begin
dout<=fiforam[cnt_rd-1];
if(cnt_rd==5'd16) //如果指示器到最后了,则转到开始
cnt_rd<=5'd1;
else
cnt_rd<=cnt_rd+5'd1;
fiforam[cnt_wr-1]<=din;
if(cnt_wr==5'd16)
cnt_wr<=5'd1;
else
cnt_wr<=cnt_wr+5'd1;
end
2'b01: //没有写满,但已读空的情况
begin
dout<=din;
end
2'b10: //写满的情况
begin
dout<=fiforam[cnt_rd-1];
if(cnt_rd==5'd16) //如果指示器到最后了,则转到开始
cnt_rd<=4'd0;
else
cnt_rd<=cnt_rd+4'd1;
fiforam[cnt_wr-1]<=din;
if(cnt_wr==5'd16)
cnt_wr<=4'd0;
else
cnt_wr<=cnt_wr+4'd1;
end
endcase
end
default:
begin
cnt_rd<=cnt_rd;
cnt_wr<=cnt_wr;
cnt_data<=cnt_data;
full<=full;
empty<=empty;
half_full<=half_full;
end
endcase
end
end
endmodule
文章评论(0条评论)
登录后参与讨论