1、满标志没有拉高;2、深度为8的fifo,写了10个数据(满没拉高),读了10次,空也没立即拉高,可以读出10个数据;3、没来rd_en之前就有第一个读数据输出
这是之前的实验《给CodeBuddy写的async fifo做了个验证,发现了两个bug》,发现满标志逻辑有错误。今天用clause也做了同样的实验,也有同样的bug。下面总结了遇到的几个问题:
1、满标志没有拉高
2、深度为8的fifo,写了10个数据(满没拉高),读了10次,空也没立即拉高,可以读出10个数据
3、没来rd_en之前就有第一个读数据输出
给ai出错信息,他去修改迭代,三次后逻辑终于正确了。最终的verilog代码如下:
module async_fifo #(
parameter DATA_WIDTH = 8,
parameter FIFO_DEPTH = 8
)(
input wire wr_clk,
input wire wr_rst_n,
input wire wr_en,
input wire [DATA_WIDTH-1:0] wr_data,
output wire full,
input wire rd_clk,
input wire rd_rst_n,
input wire rd_en,
output reg [DATA_WIDTH-1:0] rd_data,
output wire empty
);
localparam ADDR_WIDTH = $clog2(FIFO_DEPTH);
localparam PTR_WIDTH = ADDR_WIDTH + 1;
reg [DATA_WIDTH-1:0] fifo_mem [0:FIFO_DEPTH-1];
reg [PTR_WIDTH-1:0] wr_ptr_bin;
reg [PTR_WIDTH-1:0] rd_ptr_bin;
reg [PTR_WIDTH-1:0] wr_ptr_gray;
reg [PTR_WIDTH-1:0] rd_ptr_gray;
reg [PTR_WIDTH-1:0] wr_ptr_gray_sync1, wr_ptr_gray_sync2;
reg [PTR_WIDTH-1:0] rd_ptr_gray_sync1, rd_ptr_gray_sync2;
wire [PTR_WIDTH-1:0] wr_ptr_bin_next;
wire [PTR_WIDTH-1:0] rd_ptr_bin_next;
wire [PTR_WIDTH-1:0] wr_ptr_gray_next;
wire [PTR_WIDTH-1:0] rd_ptr_gray_next;
wire wr_valid;
wire rd_valid;
function [PTR_WIDTH-1:0] bin2gray;
input [PTR_WIDTH-1:0] bin;
begin
bin2gray = bin ^ (bin >> 1);
end
endfunction
assign wr_valid = wr_en && !full;
assign rd_valid = rd_en && !empty;
assign wr_ptr_bin_next = wr_ptr_bin + wr_valid;
assign wr_ptr_gray_next = bin2gray(wr_ptr_bin_next);
always @(posedge wr_clk or negedge wr_rst_n) begin
if (!wr_rst_n) begin
wr_ptr_bin <= {PTR_WIDTH{1'b0}};
wr_ptr_gray <= {PTR_WIDTH{1'b0}};
end else begin
wr_ptr_bin <= wr_ptr_bin_next;
wr_ptr_gray <= wr_ptr_gray_next;
end
end
always @(posedge wr_clk) begin
if (wr_valid) begin
fifo_mem[wr_ptr_bin[ADDR_WIDTH-1:0]] <= wr_data;
end
end
always @(posedge wr_clk or negedge wr_rst_n) begin
if (!wr_rst_n) begin
rd_ptr_gray_sync1 <= {PTR_WIDTH{1'b0}};
rd_ptr_gray_sync2 <= {PTR_WIDTH{1'b0}};
end else begin
rd_ptr_gray_sync1 <= rd_ptr_gray;
rd_ptr_gray_sync2 <= rd_ptr_gray_sync1;
end
end
assign full = (wr_ptr_gray[PTR_WIDTH-1] != rd_ptr_gray_sync2[PTR_WIDTH-1] ) &&
(wr_ptr_gray[PTR_WIDTH-2] != rd_ptr_gray_sync2[PTR_WIDTH-2] ) &&
(wr_ptr_gray[PTR_WIDTH-3:0] == rd_ptr_gray_sync2[PTR_WIDTH-3:0]);
assign rd_ptr_bin_next = rd_ptr_bin + rd_valid;
assign rd_ptr_gray_next = bin2gray(rd_ptr_bin_next);
always @(posedge rd_clk or negedge rd_rst_n) begin
if (!rd_rst_n) begin
rd_ptr_bin <= {PTR_WIDTH{1'b0}};
rd_ptr_gray <= {PTR_WIDTH{1'b0}};
end else begin
rd_ptr_bin <= rd_ptr_bin_next;
rd_ptr_gray <= rd_ptr_gray_next;
end
end
always @(posedge rd_clk or negedge rd_rst_n) begin
if (!rd_rst_n) begin
rd_data <= {DATA_WIDTH{1'b0}};
end else if (rd_valid) begin
rd_data <= fifo_mem[rd_ptr_bin[ADDR_WIDTH-1:0]];
end
end
always @(posedge rd_clk or negedge rd_rst_n) begin
if (!rd_rst_n) begin
wr_ptr_gray_sync1 <= {PTR_WIDTH{1'b0}};
wr_ptr_gray_sync2 <= {PTR_WIDTH{1'b0}};
end else begin
wr_ptr_gray_sync1 <= wr_ptr_gray;
wr_ptr_gray_sync2 <= wr_ptr_gray_sync1;
end
end
assign empty = (rd_ptr_gray == wr_ptr_gray_sync2);
endmodule
总结:ai需要与用户多次交互,反复修改,才能实现需要的功能。并不是想像中的一步就能提供正确无误的结果。比起用户从零开始写,还是能节省很多时间。如果用户能够细化设计需求,提供每一段逻辑的实现方式,那ai应该可以做得更好更快。