赞
踩
同步FIFO(First in first out),先入先出。
Deign Spec:
RTL代码:
- module sync_fifo#(
- parameter DEPTH = 16, //DEPTH = 2^n
- parameter WIDTH = 8
- )(
- input clk,
- input rstn,
-
- //write
- input wr_en, //write enable
- input [WIDTH-1:0] wr_data, //write data
- output full,
-
- //read
- input rd_en, //read enable
- output reg [WIDTH-1:0] rd_data, //read data
- output empty,
-
- output reg [$clog2(DEPTH):0] cnt
- );
-
- reg [$clog2(DEPTH)-1:0] rd_ptr, wr_ptr;
- reg [WIDTH-1:0] mem [0:DEPTH-1];
-
- //********** read start **********//
- always@(posedge clk, negedge rstn) begin
- if(~rstn) begin
- rd_ptr <= 0;
- end
- else if(rd_en && ~empty) begin
- rd_ptr <= rd_ptr + 1'b1;
- end
- else if(rd_en && empty && wr_en) begin
- rd_ptr <= rd_ptr + 1'b1;
- end
- end
-
- always@(posedge clk, negedge rstn) begin
- if(~rstn) begin
- rd_data <= 0;
- end
- else if(rd_en && ~empty) begin
- rd_data <= mem[rd_ptr];
- end
- else if(rd_en && empty && wr_en) begin
- rd_data <= wr_data;
- end
- else begin
- rd_data <= 0;
- end
- end
- //********** read end **********//
-
- //********** write start **********//
- always@(posedge clk, negedge rstn) begin
- if(~rstn) begin
- wr_ptr <= 0;
- end
- else if(wr_en && ~full) begin
- wr_ptr <= wr_ptr + 1'b1;
- end
- else if(wr_en && full && rd_en) begin
- wr_ptr <= wr_ptr + 1'b1;
- end
- end
-
- always@(posedge clk) begin
- if(wr_en && ~full) begin
- mem[wr_ptr] <= wr_data;
- end
- else if(wr_en && full && rd_en) begin
- mem[wr_ptr] <= wr_data;
- end
- end
- //********** write end **********//
-
- //********** cnt **********//
- always@(posedge clk, negedge rstn) begin
- if(~rstn) begin
- cnt <= 0;
- end
- else if(wr_en && rd_en) begin
- cnt <= cnt;
- end
- else if(wr_en && ~full) begin
- cnt <= cnt + 1'b1;
- end
- else if(rd_en && ~empty) begin
- cnt <= cnt - 1'b1;
- end
- end
-
- assign full = (cnt == DEPTH);
- assign empty = (cnt == 0);
-
- endmodule

TB代码:
- module test#(
- parameter DEPTH = 16,
- parameter WIDTH = 8
- );
-
- reg clk;
- reg rstn;
- reg wr_en;
- reg [WIDTH-1:0] wr_data;
- wire full;
- reg rd_en;
- wire [WIDTH-1:0] rd_data;
- wire empty;
- wire [$clog2(DEPTH):0] cnt;
-
- sync_fifo u0(
- .clk(clk),
- .rstn(rstn),
- .wr_en(wr_en),
- .wr_data(wr_data),
- .full(full),
- .rd_en(rd_en),
- .rd_data(rd_data),
- .empty(empty),
- .cnt(cnt)
- );
-
- initial begin
- clk = 0;
- rstn = 0;
- wr_en = 0;
- wr_data = 0;
- rd_en = 0;
- #30 rstn = 1;
- end
-
- always #10 clk = ~clk;
-
- always@(posedge clk) begin
- if(({$random()}%16)<10) wr_en <= 1;
- else wr_en <= 0;
- if(({$random()}%16)<7) rd_en <= 1;
- else rd_en <= 0;
- end
-
- always@(posedge clk) begin
- wr_data <= {$random()} & 8'hff;
- end
-
- initial begin
- #4000 $finish;
- end
-
- endmodule

波形:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。