同步FIFO電路設計
阿新 • • 發佈:2020-09-07
同步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)beginfifo_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