axi_dacfifo: Optimize the AXI write logic
parent
c75289be21
commit
b48401175a
|
@ -174,9 +174,8 @@ module axi_dacfifo_wr (
|
|||
reg [31:0] dma_addr_cnt = 32'b0;
|
||||
reg [31:0] dma_last_addr = 32'b0;
|
||||
|
||||
|
||||
reg [ 2:0] axi_xfer_req_m = 3'b0;
|
||||
reg [ 2:0] axi_xfer_last_m = 3'b0;
|
||||
reg [ 4:0] axi_xfer_req_m = 3'b0;
|
||||
reg [ 4:0] axi_xfer_last_m = 3'b0;
|
||||
|
||||
reg [(DMA_MEM_ADDRESS_WIDTH-1):0] axi_mem_waddr_m1 = 'b0;
|
||||
reg [(DMA_MEM_ADDRESS_WIDTH-1):0] axi_mem_waddr_m2 = 'b0;
|
||||
|
@ -190,6 +189,7 @@ module axi_dacfifo_wr (
|
|||
reg [(AXI_MEM_ADDRESS_WIDTH-1):0] axi_mem_raddr_g = 'd0;
|
||||
reg axi_mem_read_en = 1'b0;
|
||||
reg axi_mem_read_en_d = 1'b0;
|
||||
reg axi_mem_read_en_delay = 1'b0;
|
||||
reg [(AXI_MEM_ADDRESS_WIDTH-1):0] axi_mem_addr_diff = 'b0;
|
||||
reg axi_mem_last_read_toggle = 1'b0;
|
||||
|
||||
|
@ -202,8 +202,8 @@ module axi_dacfifo_wr (
|
|||
reg axi_werror = 1'b0;
|
||||
reg [ 3:0] axi_wvalid_counter = 4'b0;
|
||||
|
||||
reg axi_last_transaction = 1'b0;
|
||||
reg axi_last_transaction_d = 1'b0;
|
||||
reg axi_endof_transaction = 1'b0;
|
||||
reg axi_endof_transaction_d = 1'b0;
|
||||
|
||||
// internal signals
|
||||
|
||||
|
@ -218,7 +218,6 @@ module axi_dacfifo_wr (
|
|||
wire [(AXI_DATA_WIDTH-1):0] axi_mem_rdata_s;
|
||||
wire axi_mem_rvalid_s;
|
||||
wire axi_mem_last_s;
|
||||
wire axi_mem_eot_s;
|
||||
|
||||
wire axi_waddr_ready_s;
|
||||
wire axi_wready_s;
|
||||
|
@ -379,15 +378,15 @@ module axi_dacfifo_wr (
|
|||
|
||||
always @(posedge axi_clk) begin
|
||||
if (axi_resetn == 1'b0) begin
|
||||
axi_xfer_req_m <= 3'b0;
|
||||
axi_xfer_last_m <= 3'b0;
|
||||
axi_xfer_req_m <= 4'b0;
|
||||
axi_xfer_last_m <= 5'b0;
|
||||
axi_xfer_init <= 1'b0;
|
||||
axi_mem_waddr_m1 <= 'b0;
|
||||
axi_mem_waddr_m2 <= 'b0;
|
||||
axi_mem_waddr <= 'b0;
|
||||
end else begin
|
||||
axi_xfer_req_m <= {axi_xfer_req_m[1:0], dma_xfer_req};
|
||||
axi_xfer_last_m <= {axi_xfer_last_m[1:0], dma_xfer_last};
|
||||
axi_xfer_req_m <= {axi_xfer_req_m[3:0], dma_xfer_req};
|
||||
axi_xfer_last_m <= {axi_xfer_last_m[3:0], dma_xfer_last};
|
||||
axi_xfer_init = ~axi_xfer_req_m[2] & axi_xfer_req_m[1];
|
||||
axi_mem_waddr_m1 <= dma_mem_waddr_g;
|
||||
axi_mem_waddr_m2 <= axi_mem_waddr_m1;
|
||||
|
@ -409,6 +408,22 @@ module axi_dacfifo_wr (
|
|||
|
||||
assign axi_mem_addr_diff_s = {1'b1, axi_mem_waddr_s} - axi_mem_raddr;
|
||||
|
||||
always @(posedge axi_clk) begin
|
||||
if (axi_resetn == 1'b0) begin
|
||||
axi_endof_transaction <= 1'b0;
|
||||
axi_endof_transaction_d <= 1'b0;
|
||||
axi_mem_addr_diff <= 'b0;
|
||||
end else begin
|
||||
axi_mem_addr_diff <= axi_mem_addr_diff_s[(AXI_MEM_ADDRESS_WIDTH-1):0];
|
||||
axi_endof_transaction_d <= axi_endof_transaction;
|
||||
if ((axi_xfer_req_m[4] == 1'b1) && (axi_xfer_last_m[4] == 1'b1) && (axi_xfer_last_m[3] == 1'b0)) begin
|
||||
axi_endof_transaction <= 1'b1;
|
||||
end else if((axi_endof_transaction == 1'b1) && (axi_wlast == 1'b1) && ((axi_mem_addr_diff == 0) || (axi_mem_addr_diff > AXI_LENGTH))) begin
|
||||
axi_endof_transaction <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// The asymmetric memory have to have enough data for at least one AXI burst,
|
||||
// before the controller start an AXI write transaction.
|
||||
|
||||
|
@ -416,27 +431,29 @@ module axi_dacfifo_wr (
|
|||
if (axi_resetn == 1'b0) begin
|
||||
axi_mem_read_en <= 1'b0;
|
||||
axi_mem_read_en_d <= 1'b0;
|
||||
axi_mem_read_en_delay <= 1'b0;
|
||||
axi_mem_addr_diff <= 'b0;
|
||||
end else begin
|
||||
axi_mem_addr_diff <= axi_mem_addr_diff_s[(AXI_MEM_ADDRESS_WIDTH-1):0];
|
||||
if (axi_mem_read_en == 1'b0) begin
|
||||
if (((axi_xfer_req_m[2] == 1'b1) && (axi_mem_addr_diff > AXI_LENGTH) && (axi_last_transaction_d == 1'b0)) ||
|
||||
(axi_last_transaction == 1'b1) && (axi_last_transaction_d == 1'b0)) begin
|
||||
if ((axi_mem_read_en == 1'b0) && (axi_mem_read_en_delay == 1'b0)) begin
|
||||
if (((axi_xfer_req_m[2] == 1'b1) && (axi_mem_addr_diff > AXI_LENGTH)) ||
|
||||
((axi_endof_transaction == 1'b1) && (axi_mem_addr_diff > AXI_LENGTH)) ||
|
||||
((axi_endof_transaction == 1'b1) && (axi_mem_addr_diff > 0))) begin
|
||||
axi_mem_read_en <= 1'b1;
|
||||
end
|
||||
end else if (axi_mem_last_s == 1'b1) begin
|
||||
axi_mem_read_en <= 1'b0;
|
||||
axi_mem_read_en_delay <= 1;
|
||||
end
|
||||
if (axi_wlast == 1'b1) begin
|
||||
axi_mem_read_en_delay <= 0;
|
||||
end
|
||||
axi_mem_read_en_d <= axi_mem_read_en;
|
||||
end
|
||||
end
|
||||
|
||||
// If there is enough data and the AXI interface is ready, we can start to read
|
||||
// out data from the memory
|
||||
|
||||
assign axi_mem_rvalid_s = axi_mem_read_en & axi_wready_s;
|
||||
assign axi_mem_last_s = (axi_wvalid_counter == axi_awlen) ? axi_mem_rvalid_s : 1'b0;
|
||||
assign axi_mem_eot_s = axi_wlast & axi_last_transaction;
|
||||
|
||||
always @(posedge axi_clk) begin
|
||||
if (axi_resetn == 1'b0) begin
|
||||
|
@ -457,9 +474,9 @@ module axi_dacfifo_wr (
|
|||
axi_mem_rdata <= axi_mem_rdata_s;
|
||||
if (axi_mem_rvalid_s == 1'b1) begin
|
||||
axi_mem_raddr <= axi_mem_raddr + 1;
|
||||
axi_wvalid_counter <= (axi_wvalid_counter == axi_awlen) ? 4'b0 : axi_wvalid_counter + 1;
|
||||
axi_wvalid_counter <= ((axi_wvalid_counter == axi_awlen) || (axi_xfer_init == 1'b1)) ? 4'b0 : axi_wvalid_counter + 1;
|
||||
end
|
||||
if (axi_mem_eot_s == 1'b1) begin
|
||||
if ((axi_endof_transaction == 1'b0) && (axi_endof_transaction_d == 1'b1)) begin
|
||||
axi_mem_raddr <= 'b0;
|
||||
axi_mem_last_read_toggle <= ~axi_mem_last_read_toggle;
|
||||
end
|
||||
|
@ -467,20 +484,6 @@ module axi_dacfifo_wr (
|
|||
end
|
||||
end
|
||||
|
||||
always @(posedge axi_clk) begin
|
||||
if (axi_resetn == 1'b0) begin
|
||||
axi_last_transaction <= 1'b0;
|
||||
axi_last_transaction_d <= 1'b0;
|
||||
end else begin
|
||||
if ((axi_xfer_req_m[2] == 1'b1) && (axi_xfer_last_m[2] == 1'b1)) begin
|
||||
axi_last_transaction <= 1'b1;
|
||||
end else if (axi_wlast == 1'b1) begin
|
||||
axi_last_transaction <= 1'b0;
|
||||
end
|
||||
axi_last_transaction_d <= axi_last_transaction;
|
||||
end
|
||||
end
|
||||
|
||||
// AXI Memory Map interface write address channel
|
||||
|
||||
assign axi_awid = 4'b0000;
|
||||
|
@ -518,9 +521,11 @@ module axi_dacfifo_wr (
|
|||
axi_awaddr <= axi_awaddr + AXI_AWINCR;
|
||||
end
|
||||
if (axi_xfer_last_m[2] == 1'b1) begin
|
||||
axi_last_addr <= axi_awaddr;
|
||||
axi_xfer_out <= 1'b1;
|
||||
end
|
||||
if ((axi_awvalid == 1'b1) && (axi_endof_transaction == 1'b1)) begin
|
||||
axi_last_addr <= axi_awaddr;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue