1. 程式人生 > 實用技巧 >同步FIFO電路設計

同步FIFO電路設計

同步FIFO指的是寫操作和讀操作都是同一個時鐘。為了保證資料的正確性,必須保證FIFO在滿的情況下不能進行寫操作,在空的狀態下不能進行讀操作。同時還需要明白一個就是寫入了什麼的資料,那麼才能讀出什麼資料。電路的程式碼設計如下:

module fifo(
input sys_clk,
input sys_rst_n,
input [7:0]datain,
input wr,
input rd,
output reg [7:0]dataout,
output empt,
output full
);
reg [3:0]cnt;
reg [3:0]wr_ptr;
reg [3:0]rd_ptr;
reg [7
:0]fifo_mem[15:0]; parameter s0=2'b00; parameter s1=2'b01; parameter s2=2'b10; parameter s3=2'b11; always @(posedge sys_clk or negedge sys_rst_n)begin if(!sys_rst_n)begin cnt<=4'b0; wr_ptr<=4'b0; rd_ptr<=4'b0; dataout<=8'b0; end else begin case({rd,wr}) s0:begin cnt<=cnt; wr_ptr<=wr_ptr; rd_ptr
<=rd_ptr; dataout<=8'b0; end s1:begin if(!full)begin fifo_mem[wr_ptr]<=datain; wr_ptr<=wr_ptr+1'b1; cnt<=cnt+1'b1; dataout<=8'b0; end end s2:begin if(!empt)begin dataout<=fifo_mem[rd_ptr]; rd_ptr<=rd_ptr+1'b1; wr_ptr<=wr_ptr; cnt<=cnt-1'b1; end end s3:begin if(!full)begin
fifo_mem[wr_ptr]<=datain; wr_ptr<=wr_ptr+1'b1; end if(!empt)begin dataout<=fifo_mem[rd_ptr]; rd_ptr<=rd_ptr+1'b1; end end default:; endcase end end assign full=(cnt==4'd15); assign empt=(cnt==4'd0); endmodule

電路的模擬程式碼設計如下:

`timescale 1ns/1ns
module fifo_tb;
reg sys_clk;
reg sys_rst_n;
reg [7:0]datain;
reg wr;
reg rd;
wire [7:0]dataout;
wire empt;
wire full;
initial begin
sys_clk=1'b1;
sys_rst_n=1'b0;
datain=0;
#10 sys_rst_n=1'b1;
#40 wr=1'b1;
#20 rd=1'b1;
#20 rd=1'b0;
#170 wr=1'b0;
#200 rd=1'b1;
#40 rd=1'b0;
#60 rd=1'b1;
#40 rd=1'b0;
#1000 $stop;
end
always #10 sys_clk=~sys_clk;
always @(posedge sys_clk)begin
datain<=datain+1'b1;
end
fifo u_fifo(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.datain (datain),
.wr (wr),
.rd (rd),
.dataout (dataout),
.empt (empt),
.full (full)
);
endmodule