axi_dmac: fifo_inf: Handle overflow and underflow correctly

Refactor the fifo_inf modules to always correctly generate the underflow and
overflow status signals. Before it was possible that in some cases they
were not generated when they should have been.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
main
Lars-Peter Clausen 2015-02-19 14:11:58 +01:00
parent 6edcaa478a
commit aa594e15f3
2 changed files with 15 additions and 39 deletions

View File

@ -53,8 +53,8 @@ module dmac_dest_fifo_inf (
input en, input en,
output [C_DATA_WIDTH-1:0] dout, output [C_DATA_WIDTH-1:0] dout,
output reg valid, output valid,
output reg underflow, output underflow,
output fifo_ready, output fifo_ready,
input fifo_valid, input fifo_valid,
@ -80,28 +80,23 @@ wire data_enabled;
wire _fifo_ready; wire _fifo_ready;
assign fifo_ready = _fifo_ready | ~enabled; assign fifo_ready = _fifo_ready | ~enabled;
reg data_ready; reg en_d1;
wire data_ready;
wire data_valid; wire data_valid;
always @(posedge clk) always @(posedge clk)
begin begin
if (resetn == 1'b0) begin if (resetn == 1'b0) begin
data_ready <= 1'b1; en_d1 <= 1'b0;
underflow <= 1'b0;
valid <= 1'b0;
end else begin end else begin
if (enable == 1'b1) begin en_d1 <= en;
valid <= data_valid & en;
data_ready <= en & data_valid;
underflow <= en & ~data_valid;
end else begin
valid <= 1'b0;
data_ready <= 1'b1;
underflow <= en;
end
end end
end end
assign underflow = en_d1 & (~data_valid | ~enable);
assign data_ready = en_d1 & (data_valid | ~enable);
assign valid = en_d1 & data_valid & enable;
dmac_data_mover # ( dmac_data_mover # (
.C_ID_WIDTH(C_ID_WIDTH), .C_ID_WIDTH(C_ID_WIDTH),
.C_DATA_WIDTH(C_DATA_WIDTH), .C_DATA_WIDTH(C_DATA_WIDTH),

View File

@ -69,21 +69,18 @@ parameter C_ID_WIDTH = 3;
parameter C_DATA_WIDTH = 64; parameter C_DATA_WIDTH = 64;
parameter C_BEATS_PER_BURST_WIDTH = 4; parameter C_BEATS_PER_BURST_WIDTH = 4;
reg valid = 1'b0;
wire ready; wire ready;
reg [C_DATA_WIDTH-1:0] buffer = 'h00;
reg buffer_sync = 1'b0;
reg needs_sync = 1'b0; reg needs_sync = 1'b0;
wire has_sync = ~needs_sync | buffer_sync; wire has_sync = ~needs_sync | sync;
wire sync_valid = valid & has_sync; wire sync_valid = en & ready & has_sync;
always @(posedge clk) always @(posedge clk)
begin begin
if (resetn == 1'b0) begin if (resetn == 1'b0) begin
needs_sync <= 1'b0; needs_sync <= 1'b0;
end else begin end else begin
if (ready && valid && buffer_sync) begin if (ready && en && sync) begin
needs_sync <= 1'b0; needs_sync <= 1'b0;
end else if (req_valid && req_ready) begin end else if (req_valid && req_ready) begin
needs_sync <= req_sync_transfer_start; needs_sync <= req_sync_transfer_start;
@ -91,30 +88,14 @@ begin
end end
end end
always @(posedge clk)
begin
if (en) begin
buffer <= din;
buffer_sync <= sync;
end
end
always @(posedge clk) always @(posedge clk)
begin begin
if (resetn == 1'b0) begin if (resetn == 1'b0) begin
valid <= 1'b0;
overflow <= 1'b0; overflow <= 1'b0;
end else begin end else begin
if (enable) begin if (enable) begin
if (en) begin overflow <= en & ~ready;
valid <= 1'b1;
end else if (ready || ~xfer_req) begin
valid <= 1'b0;
end
overflow <= en & valid & ~ready;
end else begin end else begin
if (ready || ~xfer_req)
valid <= 1'b0;
overflow <= en; overflow <= en;
end end
end end
@ -147,7 +128,7 @@ dmac_data_mover # (
.s_axi_ready(ready), .s_axi_ready(ready),
.s_axi_valid(sync_valid), .s_axi_valid(sync_valid),
.s_axi_data(buffer), .s_axi_data(din),
.m_axi_ready(fifo_ready), .m_axi_ready(fifo_ready),
.m_axi_valid(fifo_valid), .m_axi_valid(fifo_valid),
.m_axi_data(fifo_data), .m_axi_data(fifo_data),