Skip to content

Commit

Permalink
axi_dmac: Eliminate beat counter for the destination interfaces
Browse files Browse the repository at this point in the history
Currently both the source side and the destination side interfaces employ a
beat counter to identify the last beat in a burst.

The burst memory already has an internal last signal on the destination
side. Exporting it allows the destination side interfaces to use it instead
of having to generate their own signal. This allows to eliminate the beat
counters on the destination side and simplify the data path logic.

Signed-off-by: Lars-Peter Clausen <[email protected]>
  • Loading branch information
larsclausen authored and Lars-Peter Clausen committed Jul 3, 2018
1 parent 71e14f6 commit 0d337ed
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 153 deletions.
27 changes: 25 additions & 2 deletions library/axi_dmac/axi_dmac_burst_memory.v
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,11 @@ module axi_dmac_burst_memory #(
output dest_data_valid,
input dest_data_ready,
output [DATA_WIDTH_DEST-1:0] dest_data,
output dest_data_last,

output [ID_WIDTH-1:0] dest_request_id
output [ID_WIDTH-1:0] dest_request_id,
input [ID_WIDTH-1:0] dest_data_request_id,
output [ID_WIDTH-1:0] dest_data_response_id
);

localparam DATA_WIDTH = DATA_WIDTH_SRC > DATA_WIDTH_DEST ?
Expand Down Expand Up @@ -202,7 +205,7 @@ assign dest_beat = dest_valid & dest_ready;
assign dest_last_beat = dest_last & dest_beat;
assign dest_raddr = {dest_id_reduced,dest_beat_counter};

assign dest_burst_valid = dest_src_id != dest_id_next;
assign dest_burst_valid = dest_data_request_id != dest_id_next;
assign dest_burst_ready = ~dest_valid | dest_last_beat;

/*
Expand Down Expand Up @@ -236,6 +239,25 @@ always @(posedge dest_clk) begin
end
end

/*
* This clears dest_data_last after the last beat. Strictly speaking this is not
* necessary if this followed AXI handshaking rules since dest_data_last would
* be qualified by dest_data_valid and it is OK to retain the previous value of
* dest_data_last when dest_data_valid is not asserted. But clearing the signal
* here doesn't cost much and can simplify some of the more congested
* combinatorical logic further up the pipeline since we can assume that
* fifo_last == 1'b1 implies fifo_valid == 1'b1.
*/
always @(posedge dest_clk) begin
if (dest_reset == 1'b1) begin
dest_mem_data_last <= 1'b0;
end else if (dest_beat == 1'b1) begin
dest_mem_data_last <= dest_last;
end else if (dest_mem_data_ready == 1'b1) begin
dest_mem_data_last <= 1'b0;
end
end

assign dest_id_next_inc = inc_id(dest_id_next);

always @(posedge dest_clk) begin
Expand Down Expand Up @@ -341,5 +363,6 @@ sync_bits #(
);

assign dest_request_id = dest_src_id;
assign dest_data_response_id = dest_id;

endmodule
63 changes: 7 additions & 56 deletions library/axi_dmac/dest_axi_mm.v
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,14 @@ module dmac_dest_mm_axi #(
input [ID_WIDTH-1:0] request_id,
output [ID_WIDTH-1:0] response_id,

output [ID_WIDTH-1:0] data_id,
output [ID_WIDTH-1:0] address_id,
input data_eot,
input address_eot,
input response_eot,

input fifo_valid,
output fifo_ready,
input [DMA_DATA_WIDTH-1:0] fifo_data,
input fifo_last,

// Write address
input m_axi_awready,
Expand All @@ -94,30 +93,8 @@ module dmac_dest_mm_axi #(
output m_axi_bready
);

wire address_req_valid;
wire address_req_ready;
wire data_req_valid;
wire data_req_ready;

wire address_enabled;

splitter #(
.NUM_M(2)
) i_req_splitter (
.clk(m_axi_aclk),
.resetn(m_axi_aresetn),
.s_valid(req_valid),
.s_ready(req_ready),
.m_valid({
address_req_valid,
data_req_valid
}),
.m_ready({
address_req_ready,
data_req_ready
})
);

dmac_address_generator #(
.ID_WIDTH(ID_WIDTH),
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH),
Expand All @@ -135,8 +112,8 @@ dmac_address_generator #(
.id(address_id),
.request_id(request_id),

.req_valid(address_req_valid),
.req_ready(address_req_ready),
.req_valid(req_valid),
.req_ready(req_ready),
.req_address(req_address),
.req_last_burst_length(req_last_burst_length),

Expand All @@ -152,36 +129,10 @@ dmac_address_generator #(
.cache(m_axi_awcache)
);

dmac_data_mover # (
.ID_WIDTH(ID_WIDTH),
.DATA_WIDTH(DMA_DATA_WIDTH),
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH)
) i_data_mover (
.clk(m_axi_aclk),
.resetn(m_axi_aresetn),

/* Unused. AXI protocol guarantees ordering */
.enable(1'b1),
.enabled(),

.xfer_req(),

.request_id(address_id),
.response_id(data_id),
.eot(data_eot),

.req_valid(data_req_valid),
.req_ready(data_req_ready),
.req_last_burst_length(req_last_burst_length),

.s_axi_valid(fifo_valid),
.s_axi_ready(fifo_ready),
.s_axi_data(fifo_data),
.m_axi_valid(m_axi_wvalid),
.m_axi_ready(m_axi_wready),
.m_axi_data(m_axi_wdata),
.m_axi_last(m_axi_wlast)
);
assign m_axi_wvalid = fifo_valid;
assign fifo_ready = m_axi_wready;
assign m_axi_wlast = fifo_last;
assign m_axi_wdata = fifo_data;

assign m_axi_wstrb = {(DMA_DATA_WIDTH/8){1'b1}};

Expand Down
87 changes: 51 additions & 36 deletions library/axi_dmac/dest_axi_stream.v
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ module dmac_dest_axi_stream #(
output enabled,
output xfer_req,

input [ID_WIDTH-1:0] request_id,
output [ID_WIDTH-1:0] response_id,
output [ID_WIDTH-1:0] data_id,
input data_eot,
Expand All @@ -60,6 +59,7 @@ module dmac_dest_axi_stream #(
output fifo_ready,
input fifo_valid,
input [S_AXIS_DATA_WIDTH-1:0] fifo_data,
input fifo_last,

input req_valid,
output req_ready,
Expand All @@ -72,50 +72,65 @@ module dmac_dest_axi_stream #(
output [1:0] response_resp
);

`include "inc_id.h"

reg data_enabled = 1'b0;
reg req_xlast_d = 1'b0;
reg active = 1'b0;

wire data_enabled;
wire m_axis_last_s;
reg [ID_WIDTH-1:0] id = 'h0;

/* Last beat of the burst */
wire fifo_last_beat;
/* Last beat of the segment */
wire fifo_eot_beat;

/* fifo_last == 1'b1 implies fifo_valid == 1'b1 */
assign fifo_last_beat = fifo_ready & fifo_last;
assign fifo_eot_beat = fifo_last_beat & data_eot;

assign req_ready = fifo_eot_beat | ~active;
assign data_id = id;
assign xfer_req = active;

assign m_axis_valid = fifo_valid & active;
assign fifo_ready = m_axis_ready & active;
assign m_axis_last = req_xlast_d & fifo_last & data_eot;
assign m_axis_data = fifo_data;

always @(posedge s_axis_aclk) begin
if(req_ready == 1'b1) begin
req_xlast_d <= req_xlast;
if (s_axis_aresetn == 1'b0) begin
data_enabled <= 1'b0;
end else if (enable == 1'b1) begin
data_enabled <= 1'b1;
end else if (m_axis_valid == 1'b0 || m_axis_ready == 1'b1) begin
data_enabled <= 1'b0;
end
end

assign m_axis_last = (req_xlast_d == 1'b1) ? m_axis_last_s : 1'b0;
always @(posedge s_axis_aclk) begin
if (req_ready == 1'b1) begin
req_xlast_d <= req_xlast;
end
end

dmac_data_mover # (
.ID_WIDTH(ID_WIDTH),
.DATA_WIDTH(S_AXIS_DATA_WIDTH),
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH),
.DISABLE_WAIT_FOR_ID(0),
.LAST(1)
) i_data_mover (
.clk(s_axis_aclk),
.resetn(s_axis_aresetn),
always @(posedge s_axis_aclk) begin
if (s_axis_aresetn == 1'b0) begin
active <= 1'b0;
end else if (req_valid == 1'b1) begin
active <= 1'b1;
end else if (fifo_eot_beat == 1'b1) begin
active <= 1'b0;
end
end

.enable(enable),
.enabled(data_enabled),
.xfer_req(xfer_req),

.request_id(request_id),
.response_id(data_id),
.eot(data_eot),

.req_valid(req_valid),
.req_ready(req_ready),
.req_last_burst_length(req_last_burst_length),

.m_axi_ready(m_axis_ready),
.m_axi_valid(m_axis_valid),
.m_axi_data(m_axis_data),
.m_axi_last(m_axis_last_s),
.s_axi_ready(fifo_ready),
.s_axi_valid(fifo_valid),
.s_axi_data(fifo_data)
);
always @(posedge s_axis_aclk) begin
if (s_axis_aresetn == 1'b0) begin
id <= 'h00;
end else if (fifo_last_beat == 1'b1) begin
id <= inc_id(id);
end
end

dmac_response_generator # (
.ID_WIDTH(ID_WIDTH)
Expand All @@ -126,7 +141,7 @@ dmac_response_generator # (
.enable(data_enabled),
.enabled(enabled),

.request_id(data_id),
.request_id(id),
.response_id(response_id),

.eot(response_eot),
Expand Down
83 changes: 41 additions & 42 deletions library/axi_dmac/dest_fifo_inf.v
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,11 @@ module dmac_dest_fifo_inf #(
input enable,
output enabled,

input [ID_WIDTH-1:0] request_id,
input req_valid,
output req_ready,

output [ID_WIDTH-1:0] response_id,
output [ID_WIDTH-1:0] data_id,
output reg [ID_WIDTH-1:0] data_id = 'h0,
input data_eot,
input response_eot,

Expand All @@ -61,65 +63,62 @@ module dmac_dest_fifo_inf #(
output fifo_ready,
input fifo_valid,
input [DATA_WIDTH-1:0] fifo_data,

input req_valid,
output req_ready,
input [BEATS_PER_BURST_WIDTH-1:0] req_last_burst_length,
input fifo_last,

output response_valid,
input response_ready,
output response_resp_eot,
output [1:0] response_resp
);

wire [DATA_WIDTH-1:0] dout_s;
wire data_ready;
wire data_valid;
`include "inc_id.h"

reg active = 1'b0;

/* Last beat of the burst */
wire fifo_last_beat;
/* Last beat of the segment */
wire fifo_eot_beat;

assign enabled = enable;
assign data_ready = en & (data_valid | ~enable);

dmac_data_mover # (
.ID_WIDTH(ID_WIDTH),
.DATA_WIDTH(DATA_WIDTH),
.BEATS_PER_BURST_WIDTH(BEATS_PER_BURST_WIDTH),
.DISABLE_WAIT_FOR_ID(0)
) i_data_mover (
.clk(clk),
.resetn(resetn),
assign fifo_ready = en & (fifo_valid | ~enable);

.enable(enable),
.enabled(),
.xfer_req(xfer_req),

.request_id(request_id),
.response_id(data_id),
.eot(data_eot),

.req_valid(req_valid),
.req_ready(req_ready),
.req_last_burst_length(req_last_burst_length),

.s_axi_ready(fifo_ready),
.s_axi_valid(fifo_valid),
.s_axi_data(fifo_data),
.m_axi_ready(data_ready),
.m_axi_valid(data_valid),
.m_axi_data(dout_s),
.m_axi_last()
);
/* fifo_last == 1'b1 implies fifo_valid == 1'b1 */
assign fifo_last_beat = fifo_ready & fifo_last;
assign fifo_eot_beat = fifo_last_beat & data_eot;

assign req_ready = fifo_eot_beat | ~active;
assign xfer_req = active;

always @(posedge clk) begin
if (en) begin
dout <= (data_valid) ? dout_s : {DATA_WIDTH{1'b0}};
valid <= data_valid & enable;
underflow <= ~(data_valid & enable);
dout <= fifo_valid ? fifo_data : {DATA_WIDTH{1'b0}};
valid <= fifo_valid & enable;
underflow <= ~(fifo_valid & enable);
end else begin
valid <= 1'b0;
underflow <= 1'b0;
end
end

always @(posedge clk) begin
if (resetn == 1'b0) begin
data_id <= 'h00;
end else if (fifo_last_beat == 1'b1) begin
data_id <= inc_id(data_id);
end
end

always @(posedge clk) begin
if (resetn == 1'b0) begin
active <= 1'b0;
end else if (req_valid == 1'b1) begin
active <= 1'b1;
end else if (fifo_eot_beat == 1'b1) begin
active <= 1'b0;
end
end

dmac_response_generator # (
.ID_WIDTH(ID_WIDTH)
) i_response_generator (
Expand Down
Loading

0 comments on commit 0d337ed

Please sign in to comment.