同步FIFO与异步FIFO代码
时间: 2024-01-09 14:51:35 浏览: 69
同步FIFO代码:
```verilog
module sync_fifo (
input clk,
input rst,
input wr_en,
input rd_en,
input [DATA_WIDTH-1:0] wr_data,
output [DATA_WIDTH-1:0] rd_data,
output full,
output empty
);
parameter ADDR_WIDTH = 4;
parameter DATA_WIDTH = 8;
parameter FIFO_DEPTH = 2**ADDR_WIDTH;
reg [DATA_WIDTH-1:0] mem [0:FIFO_DEPTH-1];
reg [ADDR_WIDTH-1:0] wr_ptr;
reg [ADDR_WIDTH-1:0] rd_ptr;
reg [ADDR_WIDTH-1:0] count;
wire [ADDR_WIDTH-1:0] new_wr_ptr;
wire [ADDR_WIDTH-1:0] new_rd_ptr;
assign full = (count == FIFO_DEPTH);
assign empty = (count == 0);
assign rd_data = mem[rd_ptr];
// Write pointer logic
always @(posedge clk or posedge rst) begin
if (rst) begin
wr_ptr <= 0;
end else if (wr_en && !full) begin
wr_ptr <= new_wr_ptr;
end
end
assign new_wr_ptr = (wr_ptr + 1 == FIFO_DEPTH) ? 0 : wr_ptr + 1;
// Read pointer logic
always @(posedge clk or posedge rst) begin
if (rst) begin
rd_ptr <= 0;
end else if (rd_en && !empty) begin
rd_ptr <= new_rd_ptr;
end
end
assign new_rd_ptr = (rd_ptr + 1 == FIFO_DEPTH) ? 0 : rd_ptr + 1;
// Count logic
always @(posedge clk or posedge rst) begin
if (rst) begin
count <= 0;
end else if (wr_en && !full) begin
count <= count + 1;
end else if (rd_en && !empty) begin
count <= count - 1;
end
end
// Write data logic
always @(posedge clk or posedge rst) begin
if (rst) begin
mem <= '{default:1'b0};
end else if (wr_en && !full) begin
mem[wr_ptr] <= wr_data;
end
end
endmodule
```
异步FIFO代码:
```verilog
module async_fifo (
input clk,
input rst,
input wr_en,
input rd_en,
input [DATA_WIDTH-1:0] wr_data,
output [DATA_WIDTH-1:0] rd_data,
output full,
output empty
);
parameter ADDR_WIDTH = 4;
parameter DATA_WIDTH = 8;
parameter FIFO_DEPTH = 2**ADDR_WIDTH;
reg [DATA_WIDTH-1:0] mem [0:FIFO_DEPTH-1];
reg [ADDR_WIDTH-1:0] wr_ptr;
reg [ADDR_WIDTH-1:0] rd_ptr;
reg [ADDR_WIDTH-1:0] count;
reg [1:0] wr_sync;
reg [1:0] rd_sync;
wire [ADDR_WIDTH-1:0] new_wr_ptr;
wire [ADDR_WIDTH-1:0] new_rd_ptr;
assign full = (count == FIFO_DEPTH);
assign empty = (count == 0);
assign rd_data = mem[rd_ptr];
// Write pointer logic
always @(posedge clk or posedge rst) begin
if (rst) begin
wr_ptr <= 0;
wr_sync <= 2'b00;
end else begin
case (wr_sync)
2'b00: if (wr_en && !full) begin wr_sync <= 2'b01; end
2'b01: if (wr_en) begin wr_ptr <= new_wr_ptr; wr_sync <= 2'b10; end
2'b10: wr_sync <= 2'b00;
endcase
end
end
assign new_wr_ptr = (wr_ptr + 1 == FIFO_DEPTH) ? 0 : wr_ptr + 1;
// Read pointer logic
always @(posedge clk or posedge rst) begin
if (rst) begin
rd_ptr <= 0;
rd_sync <= 2'b00;
end else begin
case (rd_sync)
2'b00: if (rd_en && !empty) begin rd_sync <= 2'b01; end
2'b01: if (rd_en) begin rd_ptr <= new_rd_ptr; rd_sync <= 2'b10; end
2'b10: rd_sync <= 2'b00;
endcase
end
end
assign new_rd_ptr = (rd_ptr + 1 == FIFO_DEPTH) ? 0 : rd_ptr + 1;
// Count logic
always @(posedge clk or posedge rst) begin
if (rst) begin
count <= 0;
end else begin
if (wr_sync == 2'b01 && !full) begin
count <= count + 1;
end
if (rd_sync == 2'b01 && !empty) begin
count <= count - 1;
end
end
end
// Write data logic
always @(posedge clk or posedge rst) begin
if (rst) begin
mem <= '{default:1'b0};
end else begin
if (wr_sync == 2'b01 && !full) begin
mem[wr_ptr] <= wr_data;
end
end
end
endmodule
```
阅读全文