|
轉(zhuǎn)了一篇?jiǎng)e人寫(xiě)的,沒(méi)看一眼代碼,因?yàn)樽畈幌矚g的就是看別人寫(xiě)的代碼。今天抽空自己寫(xiě)了一段小代碼,在ModelSim中仿真了,結(jié)果還是正確的。
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; //讀數(shù)據(jù)指示器
reg [4:0] cnt_wr; //寫(xiě)數(shù)據(jù)指示器
reg [4:0] cnt_data; //數(shù)據(jù)個(gè)數(shù)指示器
reg [7:0] fiforam[15:0]; //FIFO存儲(chǔ)數(shù)組
reg empty,full,half_full;
always @ (posedge clk or negedge rst)
begin
if(!rst) //異步復(fù)位
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: //只寫(xiě)操作
begin
if(!full) //FIFO沒(méi)有寫(xiě)滿(mǎn),則執(zhí)行寫(xiě)操作
begin
if(cnt_data==5'd16) //FIFO中已經(jīng)有15個(gè)數(shù)據(jù),再寫(xiě)就滿(mǎn)了
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) //半滿(mǎn)標(biāo)志
half_full<=1'd1;
else
half_full<=1'd0;
empty<=1'd0; //只寫(xiě)時(shí)空標(biāo)志為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沒(méi)有讀空,則執(zhí)行讀操作
begin
if(cnt_data==5'd0) //FIFO中只有1個(gè)數(shù)據(jù),再讀就空了
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; //只寫(xiě)時(shí)空標(biāo)志為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: //讀寫(xiě)同時(shí)進(jìn)行
begin
case({full,empty})
2'b00: //既沒(méi)有寫(xiě)滿(mǎn)也沒(méi)有讀空的情況
begin
dout<=fiforam[cnt_rd-1];
if(cnt_rd==5'd16) //如果指示器到最后了,則轉(zhuǎn)到開(kāi)始
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: //沒(méi)有寫(xiě)滿(mǎn),但已讀空的情況
begin
dout<=din;
end
2'b10: //寫(xiě)滿(mǎn)的情況
begin
dout<=fiforam[cnt_rd-1];
if(cnt_rd==5'd16) //如果指示器到最后了,則轉(zhuǎn)到開(kāi)始
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
|
|