axi_dacfifo: Optimize the AXI read logic
Save the valid AXI beats number of the last AXI transaction, and the valid DMA beats number of the last AXI beat, so the read back logic can use this data and prevent to feel up the CDC memory with invalid samples. Also in this way the end of the read back cycle get a more robust control: no more duplicated samples at the end of the buffer.main
parent
e46990e508
commit
b9a5bb3549
|
@ -200,7 +200,9 @@ module axi_dacfifo (
|
|||
wire dac_rd_ready_s;
|
||||
wire dac_rd_valid_s;
|
||||
wire [31:0] axi_last_addr_s;
|
||||
wire [31:0] dma_last_addr_s;
|
||||
wire [ 3:0] axi_last_beats_s;
|
||||
wire axi_dlast_s;
|
||||
wire [ 3:0] dma_last_beats_s;
|
||||
wire [(DAC_DATA_WIDTH-1):0] dac_data_s;
|
||||
wire dma_ready_s;
|
||||
wire dma_valid_bp_s;
|
||||
|
@ -221,8 +223,9 @@ module axi_dacfifo (
|
|||
.dma_valid (dma_valid),
|
||||
.dma_xfer_req (dma_xfer_req),
|
||||
.dma_xfer_last (dma_xfer_last),
|
||||
.dma_last_beats (dma_last_beats_s),
|
||||
.axi_last_addr (axi_last_addr_s),
|
||||
.dma_last_addr (dma_last_addr_s),
|
||||
.axi_last_beats (axi_last_beats_s),
|
||||
.axi_xfer_out (axi_xfer_req_s),
|
||||
.axi_clk (axi_clk),
|
||||
.axi_resetn (axi_resetn),
|
||||
|
@ -257,8 +260,9 @@ module axi_dacfifo (
|
|||
.AXI_LENGTH (AXI_LENGTH),
|
||||
.AXI_ADDRESS (AXI_ADDRESS)
|
||||
) i_rd (
|
||||
.axi_last_raddr (axi_last_addr_s),
|
||||
.axi_xfer_req (axi_xfer_req_s),
|
||||
.axi_last_raddr (axi_last_addr_s),
|
||||
.axi_last_beats (axi_last_beats_s),
|
||||
.axi_clk (axi_clk),
|
||||
.axi_resetn (axi_resetn),
|
||||
.axi_arvalid (axi_arvalid),
|
||||
|
@ -283,7 +287,8 @@ module axi_dacfifo (
|
|||
.axi_rerror (axi_rerror),
|
||||
.axi_dvalid (axi_rd_valid_s),
|
||||
.axi_ddata (axi_rd_data_s),
|
||||
.axi_dready (axi_rd_ready_s));
|
||||
.axi_dready (axi_rd_ready_s),
|
||||
.axi_dlast (axi_dlast_s));
|
||||
|
||||
axi_dacfifo_dac #(
|
||||
.AXI_DATA_WIDTH (AXI_DATA_WIDTH),
|
||||
|
@ -294,8 +299,9 @@ module axi_dacfifo (
|
|||
.axi_dvalid (dac_rd_valid_s),
|
||||
.axi_ddata (dac_rd_data_s),
|
||||
.axi_dready (axi_rd_ready_s),
|
||||
.axi_dlast (axi_dlast_s),
|
||||
.axi_xfer_req (axi_xfer_req_s),
|
||||
.dma_last_addr (dma_last_addr_s),
|
||||
.dma_last_beats (dma_last_beats_s),
|
||||
.dac_clk (dac_clk),
|
||||
.dac_rst (dac_rst),
|
||||
.dac_valid (dac_valid),
|
||||
|
|
|
@ -45,9 +45,10 @@ module axi_dacfifo_dac (
|
|||
axi_dvalid,
|
||||
axi_ddata,
|
||||
axi_dready,
|
||||
axi_dlast,
|
||||
axi_xfer_req,
|
||||
|
||||
dma_last_addr,
|
||||
dma_last_beats,
|
||||
|
||||
dac_clk,
|
||||
dac_rst,
|
||||
|
@ -84,9 +85,10 @@ module axi_dacfifo_dac (
|
|||
input axi_dvalid;
|
||||
input [(AXI_DATA_WIDTH-1):0] axi_ddata;
|
||||
output axi_dready;
|
||||
input axi_dlast;
|
||||
input axi_xfer_req;
|
||||
|
||||
input [31:0] dma_last_addr;
|
||||
input [ 3:0] dma_last_beats;
|
||||
|
||||
// dac read
|
||||
|
||||
|
@ -100,7 +102,9 @@ module axi_dacfifo_dac (
|
|||
// internal registers
|
||||
|
||||
reg [(AXI_ADDRESS_WIDTH-1):0] axi_mem_waddr = 'd0;
|
||||
reg [(AXI_ADDRESS_WIDTH-1):0] axi_mem_laddr = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] axi_mem_waddr_g = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] axi_mem_laddr_g = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] axi_mem_raddr = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] axi_mem_raddr_m1 = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] axi_mem_raddr_m2 = 'd0;
|
||||
|
@ -108,11 +112,13 @@ module axi_dacfifo_dac (
|
|||
reg axi_dready = 'd0;
|
||||
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_raddr = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_raddr_next = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_raddr_g = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_waddr = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_waddr_m1 = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_waddr_m2 = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_laddr = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_laddr_m1 = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_laddr_m2 = 'd0;
|
||||
reg [(DAC_ADDRESS_WIDTH-1):0] dac_mem_addr_diff = 'd0;
|
||||
reg dac_mem_init = 1'b0;
|
||||
reg dac_mem_init_d = 1'b0;
|
||||
|
@ -121,24 +127,26 @@ module axi_dacfifo_dac (
|
|||
reg [ 2:0] dac_xfer_req_m = 3'b0;
|
||||
reg dac_xfer_init = 1'b0;
|
||||
|
||||
reg [31:0] dac_raddr_cnt = 32'b0;
|
||||
reg [31:0] dac_last_raddr = 32'b0;
|
||||
reg [31:0] dac_last_raddr_m = 32'b0;
|
||||
reg dac_almost_full = 1'b0;
|
||||
reg dac_almost_empty = 1'b0;
|
||||
reg [ 3:0] dac_last_beats = 4'b0;
|
||||
reg [ 3:0] dac_last_beats_m = 4'b0;
|
||||
reg dac_dunf = 1'b0;
|
||||
reg [ 3:0] dac_beat_cnt = 4'b0;
|
||||
reg dac_dlast = 1'b0;
|
||||
reg dac_dlast_m1 = 1'b0;
|
||||
reg dac_dlast_m2 = 1'b0;
|
||||
reg dac_dlast_inmem = 1'b0;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire [AXI_ADDRESS_WIDTH:0] axi_mem_addr_diff_s;
|
||||
wire [(AXI_ADDRESS_WIDTH-1):0] axi_mem_raddr_s;
|
||||
wire [(DAC_ADDRESS_WIDTH-1):0] axi_mem_waddr_s;
|
||||
wire [(DAC_ADDRESS_WIDTH-1):0] axi_mem_laddr_s;
|
||||
|
||||
wire [DAC_ADDRESS_WIDTH:0] dac_mem_addr_diff_s;
|
||||
wire [DAC_ADDRESS_WIDTH:0] dac_mem_raddr_diff_s;
|
||||
wire [(DAC_ADDRESS_WIDTH-1):0] dac_mem_waddr_s;
|
||||
wire dac_mem_valid_s;
|
||||
wire dac_xfer_init_s;
|
||||
wire dac_last_axi_beats_s;
|
||||
|
||||
// binary to grey conversion
|
||||
|
||||
|
@ -186,11 +194,14 @@ module axi_dacfifo_dac (
|
|||
if (axi_xfer_req == 1'b0) begin
|
||||
axi_mem_waddr <= 'd0;
|
||||
axi_mem_waddr_g <= 'd0;
|
||||
axi_mem_laddr <= {AXI_ADDRESS_WIDTH{1'b1}};
|
||||
end else begin
|
||||
if (axi_dvalid == 1'b1) begin
|
||||
axi_mem_waddr <= axi_mem_waddr + 1'b1;
|
||||
axi_mem_laddr <= (axi_dlast == 1'b1) ? axi_mem_waddr : axi_mem_laddr;
|
||||
end
|
||||
axi_mem_waddr_g <= b2g(axi_mem_waddr_s);
|
||||
axi_mem_laddr_g <= b2g(axi_mem_laddr_s);
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -204,6 +215,10 @@ module axi_dacfifo_dac (
|
|||
(MEM_RATIO == 2) ? {axi_mem_waddr, 1'b0} :
|
||||
(MEM_RATIO == 4) ? {axi_mem_waddr, 2'b0} :
|
||||
{axi_mem_waddr, 3'b0};
|
||||
assign axi_mem_laddr_s = (MEM_RATIO == 1) ? axi_mem_laddr :
|
||||
(MEM_RATIO == 2) ? {axi_mem_laddr, 1'b0} :
|
||||
(MEM_RATIO == 4) ? {axi_mem_laddr, 2'b0} :
|
||||
{axi_mem_laddr, 3'b0};
|
||||
|
||||
// incomming data flow control
|
||||
|
||||
|
@ -268,42 +283,63 @@ module axi_dacfifo_dac (
|
|||
dac_mem_waddr <= 'b0;
|
||||
dac_mem_waddr_m1 <= 'b0;
|
||||
dac_mem_waddr_m2 <= 'b0;
|
||||
dac_mem_laddr <= 'b0;
|
||||
dac_mem_laddr_m1 <= 'b0;
|
||||
dac_mem_laddr_m2 <= 'b0;
|
||||
dac_dlast <= 1'b0;
|
||||
dac_dlast_m1 <= 1'b0;
|
||||
dac_dlast_m2 <= 1'b0;
|
||||
end else begin
|
||||
dac_mem_waddr_m1 <= axi_mem_waddr_g;
|
||||
dac_mem_waddr_m2 <= dac_mem_waddr_m1;
|
||||
dac_mem_waddr <= g2b(dac_mem_waddr_m2);
|
||||
dac_mem_laddr_m1 <= axi_mem_laddr_g;
|
||||
dac_mem_laddr_m2 <= dac_mem_laddr_m1;
|
||||
dac_mem_laddr <= g2b(dac_mem_laddr_m2);
|
||||
dac_dlast_m1 <= axi_dlast;
|
||||
dac_dlast_m2 <= dac_dlast_m1;
|
||||
dac_dlast <= dac_dlast_m2;
|
||||
end
|
||||
end
|
||||
|
||||
assign dac_mem_addr_diff_s = {1'b1, dac_mem_waddr} - dac_mem_raddr;
|
||||
assign dac_mem_raddr_diff_s = {1'b1, dac_mem_raddr_next} - dac_mem_raddr;
|
||||
assign dac_mem_valid_s = (dac_mem_enable) ? dac_valid : 1'b0;
|
||||
|
||||
// CDC for the dma_last_addr
|
||||
// CDC for the dma_last_beats
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_rst == 1'b1) begin
|
||||
dac_last_raddr <= 32'b0;
|
||||
dac_last_raddr_m <= 32'b0;
|
||||
dac_last_beats <= 32'b0;
|
||||
dac_last_beats_m <= 32'b0;
|
||||
end else begin
|
||||
dac_last_raddr_m <= dma_last_addr;
|
||||
dac_last_raddr <= dac_last_raddr_m;
|
||||
dac_last_beats_m <= dma_last_beats;
|
||||
dac_last_beats <= dac_last_beats_m;
|
||||
end
|
||||
end
|
||||
|
||||
// If the MEM_RATIO is grater than one, it can happen that not all the DAC beats from
|
||||
// an AXI beat are valid. In this case the invalid data is dropped.
|
||||
// The axi_dlast indicates the last AXI beat. The valid number of DAC beats on the last AXI beat
|
||||
// commes from the AXI write module. (axi_dacfifo_wr.v)
|
||||
|
||||
assign dac_last_axi_beats_s = ((dac_dlast_inmem == 1'b1) && (dac_mem_raddr >= dac_mem_laddr) && (dac_mem_raddr < dac_mem_laddr + MEM_RATIO)) ? 1'b1 : 1'b0;
|
||||
|
||||
always @(posedge dac_clk) begin
|
||||
if (dac_xfer_out == 1'b0) begin
|
||||
dac_mem_raddr <= 'd0;
|
||||
dac_mem_raddr_next <= DAC_ARINCR;
|
||||
dac_mem_raddr_g <= 'd0;
|
||||
dac_mem_addr_diff <= 'd0;
|
||||
dac_beat_cnt <= 'd0;
|
||||
dac_dlast_inmem <= 1'b0;
|
||||
end else begin
|
||||
dac_mem_addr_diff <= dac_mem_addr_diff_s[DAC_ADDRESS_WIDTH-1:0];
|
||||
if (dac_mem_valid_s == 1'b1) begin
|
||||
dac_raddr_cnt <= (dac_raddr_cnt == dac_last_raddr) ? 32'b0 : dac_raddr_cnt + 1;
|
||||
dac_mem_raddr <= (dac_raddr_cnt == dac_last_raddr) ? dac_mem_raddr_next : dac_mem_raddr + 1'b1;
|
||||
if (dac_dlast == 1'b1) begin
|
||||
dac_dlast_inmem <= 1'b1;
|
||||
end else if (dac_mem_raddr == dac_mem_laddr + MEM_RATIO) begin
|
||||
dac_dlast_inmem <= 1'b0;
|
||||
end
|
||||
if (dac_mem_valid_s == 1'b1) begin
|
||||
dac_beat_cnt <= ((dac_beat_cnt >= MEM_RATIO-1) ||
|
||||
((dac_last_beats > 1'b1) && (dac_last_axi_beats_s > 1'b0) && (dac_beat_cnt == dac_last_beats-1))) ? 0 : dac_beat_cnt + 1;
|
||||
dac_mem_raddr <= ((dac_last_axi_beats_s) && (dac_beat_cnt == dac_last_beats-1)) ? (dac_mem_laddr + MEM_RATIO) : dac_mem_raddr + 1'b1;
|
||||
end
|
||||
dac_mem_raddr_next <= (dac_mem_raddr_diff_s[DAC_ADDRESS_WIDTH-1:0] <= 1) ? dac_mem_raddr_next + DAC_ARINCR : dac_mem_raddr_next;
|
||||
dac_mem_raddr_g <= b2g(dac_mem_raddr);
|
||||
end
|
||||
end
|
||||
|
@ -312,15 +348,10 @@ module axi_dacfifo_dac (
|
|||
|
||||
always @(posedge dac_clk) begin
|
||||
if(dac_xfer_out == 1'b0) begin
|
||||
dac_almost_full <= 1'b0;
|
||||
dac_almost_empty <= 1'b0;
|
||||
dac_mem_addr_diff <= 'b0;
|
||||
dac_dunf <= 1'b0;
|
||||
end else begin
|
||||
if (dac_mem_addr_diff < DAC_BUF_THRESHOLD_LO) begin
|
||||
dac_almost_empty <= 1'b1;
|
||||
end else begin
|
||||
dac_almost_empty <= 1'b0;
|
||||
end
|
||||
dac_mem_addr_diff <= dac_mem_addr_diff_s[DAC_ADDRESS_WIDTH-1:0];
|
||||
dac_dunf <= (dac_mem_addr_diff == 1'b0) ? 1'b1 : 1'b0;
|
||||
end
|
||||
end
|
||||
|
|
|
@ -45,6 +45,7 @@ module axi_dacfifo_rd (
|
|||
|
||||
axi_xfer_req,
|
||||
axi_last_raddr,
|
||||
axi_last_beats,
|
||||
|
||||
// axi read address and read data channels
|
||||
|
||||
|
@ -78,7 +79,8 @@ module axi_dacfifo_rd (
|
|||
|
||||
axi_dvalid,
|
||||
axi_ddata,
|
||||
axi_dready);
|
||||
axi_dready,
|
||||
axi_dlast);
|
||||
|
||||
// parameters
|
||||
|
||||
|
@ -93,6 +95,7 @@ module axi_dacfifo_rd (
|
|||
|
||||
input axi_xfer_req;
|
||||
input [31:0] axi_last_raddr;
|
||||
input [ 3:0] axi_last_beats;
|
||||
|
||||
// axi interface
|
||||
|
||||
|
@ -127,25 +130,30 @@ module axi_dacfifo_rd (
|
|||
output axi_dvalid;
|
||||
output [(AXI_DATA_WIDTH-1):0] axi_ddata;
|
||||
input axi_dready;
|
||||
output axi_dlast;
|
||||
|
||||
// internal registers
|
||||
|
||||
reg [ 31:0] axi_rd_addr_h = 32'b0;
|
||||
reg axi_rnext = 1'b0;
|
||||
reg axi_ractive = 1'b0;
|
||||
reg axi_arvalid = 1'b0;
|
||||
reg [ 31:0] axi_araddr = 32'b0;
|
||||
reg [ 31:0] axi_araddr_prev = 32'b0;
|
||||
reg [(AXI_DATA_WIDTH-1):0] axi_ddata = 'b0;
|
||||
reg axi_dvalid = 1'b0;
|
||||
reg axi_dlast = 1'b0;
|
||||
reg axi_rready = 1'b0;
|
||||
reg axi_rerror = 1'b0;
|
||||
reg [ 1:0] axi_xfer_req_m = 2'b0;
|
||||
reg [ 4:0] axi_last_beats_cntr = 16'b0;
|
||||
|
||||
// internal signals
|
||||
|
||||
wire axi_ready_s;
|
||||
wire axi_xfer_req_init;
|
||||
wire axi_dvalid_s;
|
||||
wire axi_dlast_s;
|
||||
wire [ 4:0] axi_last_beats_s;
|
||||
|
||||
assign axi_ready_s = (~axi_arvalid | axi_arready) & axi_dready;
|
||||
|
||||
|
@ -170,6 +178,16 @@ module axi_dacfifo_rd (
|
|||
|
||||
assign axi_xfer_req_init = axi_xfer_req_m[0] & ~axi_xfer_req_m[1];
|
||||
|
||||
always @(posedge axi_clk) begin
|
||||
if ((axi_resetn == 1'b0) || (axi_xfer_req == 1'b0)) begin
|
||||
axi_last_beats_cntr <= 0;
|
||||
end else begin
|
||||
if ((axi_rready == 1'b1) && (axi_rvalid == 1'b1)) begin
|
||||
axi_last_beats_cntr <= (axi_rlast == 1'b1) ? 0 : axi_last_beats_cntr + 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// address channel
|
||||
|
||||
assign axi_arid = 4'b0000;
|
||||
|
@ -185,8 +203,8 @@ module axi_dacfifo_rd (
|
|||
always @(posedge axi_clk) begin
|
||||
if (axi_resetn == 1'b0) begin
|
||||
axi_arvalid <= 'd0;
|
||||
axi_araddr <= 'd0;
|
||||
axi_rd_addr_h <= 'd0;
|
||||
axi_araddr <= AXI_ADDRESS;
|
||||
axi_araddr_prev <= AXI_ADDRESS;
|
||||
end else begin
|
||||
if (axi_arvalid == 1'b1) begin
|
||||
if (axi_arready == 1'b1) begin
|
||||
|
@ -197,20 +215,20 @@ module axi_dacfifo_rd (
|
|||
axi_arvalid <= 1'b1;
|
||||
end
|
||||
end
|
||||
if ((axi_xfer_req_init == 1'b1)) begin
|
||||
axi_araddr <= AXI_ADDRESS;
|
||||
axi_rd_addr_h <= axi_last_raddr;
|
||||
end else if ((axi_xfer_req == 1'b1) &&
|
||||
(axi_arvalid == 1'b1) &&
|
||||
(axi_arready == 1'b1)) begin
|
||||
axi_araddr <= (axi_araddr >= axi_rd_addr_h) ? AXI_ADDRESS : axi_araddr + AXI_AWINCR;
|
||||
if ((axi_xfer_req == 1'b1) &&
|
||||
(axi_arvalid == 1'b1) &&
|
||||
(axi_arready == 1'b1)) begin
|
||||
axi_araddr <= (axi_araddr >= axi_last_raddr) ? AXI_ADDRESS : axi_araddr + AXI_AWINCR;
|
||||
axi_araddr_prev <= axi_araddr;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// read data channel
|
||||
|
||||
assign axi_dvalid_s = axi_rvalid & axi_rready;
|
||||
assign axi_last_beats_s = {1'b0, axi_last_beats} - 1;
|
||||
assign axi_dvalid_s = ((axi_last_beats_cntr > axi_last_beats_s) && (axi_araddr_prev == axi_last_raddr)) ? 0 : axi_rvalid & axi_rready;
|
||||
assign axi_dlast_s = (axi_araddr_prev == axi_last_raddr) ? 1 : 0;
|
||||
|
||||
always @(posedge axi_clk) begin
|
||||
if (axi_resetn == 1'b0) begin
|
||||
|
@ -220,6 +238,7 @@ module axi_dacfifo_rd (
|
|||
end else begin
|
||||
axi_ddata <= axi_rdata;
|
||||
axi_dvalid <= axi_dvalid_s;
|
||||
axi_dlast <= axi_dlast_s;
|
||||
if (axi_xfer_req == 1'b1) begin
|
||||
axi_rready <= axi_rvalid;
|
||||
end
|
||||
|
|
|
@ -52,11 +52,12 @@ module axi_dacfifo_wr (
|
|||
|
||||
dma_xfer_req,
|
||||
dma_xfer_last,
|
||||
dma_last_beats,
|
||||
|
||||
// syncronization for the read side
|
||||
|
||||
axi_last_addr,
|
||||
dma_last_addr,
|
||||
axi_last_beats,
|
||||
axi_xfer_out,
|
||||
|
||||
// axi write address, write data and write response channels
|
||||
|
@ -124,9 +125,10 @@ module axi_dacfifo_wr (
|
|||
|
||||
input dma_xfer_req;
|
||||
input dma_xfer_last;
|
||||
output [ 3:0] dma_last_beats;
|
||||
|
||||
output [31:0] axi_last_addr;
|
||||
output [31:0] dma_last_addr;
|
||||
output [ 3:0] axi_last_beats;
|
||||
output axi_xfer_out;
|
||||
|
||||
// axi interface
|
||||
|
@ -171,8 +173,8 @@ module axi_dacfifo_wr (
|
|||
reg dma_rst_m1 = 1'b0;
|
||||
reg dma_rst_m2 = 1'b0;
|
||||
reg [ 2:0] dma_mem_last_read_toggle_m = 3'b0;
|
||||
reg [31:0] dma_addr_cnt = 32'b0;
|
||||
reg [31:0] dma_last_addr = 32'b0;
|
||||
reg dma_xfer_req_d = 1'b0;
|
||||
reg [ 3:0] dma_last_beats = 4'b0;
|
||||
|
||||
reg [ 4:0] axi_xfer_req_m = 3'b0;
|
||||
reg [ 4:0] axi_xfer_last_m = 3'b0;
|
||||
|
@ -196,6 +198,7 @@ module axi_dacfifo_wr (
|
|||
reg axi_reset = 1'b0;
|
||||
reg axi_xfer_out = 1'b0;
|
||||
reg [31:0] axi_last_addr = 32'b0;
|
||||
reg [ 3:0] axi_last_beats = 15'b0;
|
||||
reg axi_awvalid = 1'b0;
|
||||
reg [31:0] axi_awaddr = 32'b0;
|
||||
reg axi_xfer_init = 1'b0;
|
||||
|
@ -210,6 +213,7 @@ module axi_dacfifo_wr (
|
|||
wire [(DMA_MEM_ADDRESS_WIDTH):0] dma_mem_addr_diff_s;
|
||||
wire [(DMA_MEM_ADDRESS_WIDTH-1):0] dma_mem_raddr_s;
|
||||
wire dma_mem_last_read_s;
|
||||
wire dma_xfer_init;
|
||||
wire dma_mem_wea_s;
|
||||
wire dma_rst_s;
|
||||
|
||||
|
@ -304,10 +308,21 @@ module axi_dacfifo_wr (
|
|||
end
|
||||
assign dma_rst_s = dma_rst_m2;
|
||||
|
||||
// Write address generation for the asymmetric memory
|
||||
// DMA beat counter
|
||||
|
||||
// There is no underflow or overflow. All the data movements are controlled by
|
||||
// this module.
|
||||
assign dma_xfer_init = dma_xfer_req & ~dma_xfer_req_d;
|
||||
always @(posedge dma_clk) begin
|
||||
dma_xfer_req_d <= dma_xfer_req;
|
||||
if ((dma_rst_s == 1'b1) || (dma_xfer_init == 1'b1)) begin
|
||||
dma_last_beats <= 4'b0;
|
||||
end else begin
|
||||
if ((dma_ready == 1'b1) && (dma_valid == 1'b1)) begin
|
||||
dma_last_beats <= (dma_last_beats < MEM_RATIO-1) ? dma_last_beats + 1 : 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Write address generation for the asymmetric memory
|
||||
|
||||
assign dma_mem_addr_diff_s = {1'b1, dma_mem_waddr} - dma_mem_raddr_s;
|
||||
assign dma_mem_raddr_s = (MEM_RATIO == 1) ? dma_mem_raddr :
|
||||
|
@ -327,6 +342,11 @@ module axi_dacfifo_wr (
|
|||
dma_mem_last_read_toggle_m = {dma_mem_last_read_toggle_m[1:0], axi_mem_last_read_toggle};
|
||||
if (dma_mem_wea_s == 1'b1) begin
|
||||
dma_mem_waddr <= dma_mem_waddr + 8'b1;
|
||||
if (dma_xfer_last == 1'b1) begin
|
||||
if (dma_last_beats != (MEM_RATIO - 1)) begin
|
||||
dma_mem_waddr <= dma_mem_waddr + (MEM_RATIO - dma_last_beats);
|
||||
end
|
||||
end
|
||||
end
|
||||
if (dma_mem_last_read_s == 1'b1) begin
|
||||
dma_mem_waddr <= 'h0;
|
||||
|
@ -357,21 +377,6 @@ module axi_dacfifo_wr (
|
|||
end
|
||||
end
|
||||
|
||||
// An absolute address counter with DMA's granularity, this address will be
|
||||
// used on read back
|
||||
|
||||
always @(posedge dma_clk) begin
|
||||
if (dma_rst_s == 1'b1) begin
|
||||
dma_addr_cnt <= 32'b0;
|
||||
dma_last_addr <= 32'b0;
|
||||
end else begin
|
||||
if((dma_valid == 1'b1) && (dma_xfer_req == 1'b1)) begin
|
||||
dma_addr_cnt <= (dma_xfer_last == 1'b1) ? 32'b0 : dma_addr_cnt + 1;
|
||||
dma_last_addr <= (dma_xfer_last == 1'b1) ? dma_addr_cnt : dma_last_addr;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Read address generation for the asymmetric memory
|
||||
|
||||
// CDC for the memory write address, xfer_req and xfer_last
|
||||
|
@ -546,4 +551,18 @@ module axi_dacfifo_wr (
|
|||
end
|
||||
end
|
||||
|
||||
// AXI beat counter
|
||||
|
||||
always @(posedge axi_clk) begin
|
||||
if(axi_resetn == 1'b0) begin
|
||||
axi_last_beats <= 4'b0;
|
||||
end else begin
|
||||
if ((axi_endof_transaction == 1'b1) && (axi_awready == 1'b1) && (axi_awvalid == 1'b1)) begin
|
||||
axi_last_beats <= axi_mem_addr_diff;
|
||||
end else begin
|
||||
axi_last_beats <= axi_last_beats;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
Loading…
Reference in New Issue