From 4877df9bec5e8c5cf48f375a37e21a438ac3279d Mon Sep 17 00:00:00 2001 From: Rejeesh Kutty Date: Wed, 25 Jun 2014 08:59:36 -0400 Subject: [PATCH] axi_fifo2s: make read dead slow --- library/axi_fifo2s/axi_fifo2s.v | 55 ++++++++++++- library/axi_fifo2s/axi_fifo2s_rd.v | 120 ++++++++--------------------- library/axi_fifo2s/axi_fifo2s_wr.v | 51 ++++++++---- 3 files changed, 119 insertions(+), 107 deletions(-) diff --git a/library/axi_fifo2s/axi_fifo2s.v b/library/axi_fifo2s/axi_fifo2s.v index 1dec6ce66..b61795c5c 100755 --- a/library/axi_fifo2s/axi_fifo2s.v +++ b/library/axi_fifo2s/axi_fifo2s.v @@ -101,6 +101,12 @@ module axi_fifo2s ( axi_rdata, axi_rready, + dbg_adc_clk, + dbg_adc_data, + + dbg_axi_clk, + dbg_axi_data, + // transfer request axi_xfer_req); @@ -111,6 +117,7 @@ module axi_fifo2s ( parameter AXI_SIZE = 2; parameter AXI_LENGTH = 16; parameter AXI_ADDRESS = 32'h00000000; + parameter AXI_ADDRLIMIT = 32'h00000000; // fifo interface @@ -176,19 +183,61 @@ module axi_fifo2s ( input axi_xfer_req; + output dbg_adc_clk; + output [ 17:0] dbg_adc_data; + + output dbg_axi_clk; + output [165:0] dbg_axi_data; + // internal signals wire axi_rd_req_s; wire [ 31:0] axi_rd_addr_s; wire axi_rd_status_s; + // debug + + assign dbg_adc_clk = m_clk; + assign dbg_adc_data[15: 0] = m_wdata[15:0]; + assign dbg_adc_data[16:16] = m_wr; + assign dbg_adc_data[17:17] = m_wovf; + + assign dbg_axi_clk = axi_clk; + assign dbg_axi_data[ 15: 0] = axi_mwdata[15:0]; + assign dbg_axi_data[ 16: 16] = axi_mwr; + assign dbg_axi_data[ 17: 17] = axi_mwovf; + assign dbg_axi_data[ 18: 18] = axi_mwpfull; + assign dbg_axi_data[ 19: 19] = axi_awvalid; + assign dbg_axi_data[ 51: 20] = axi_awaddr; + assign dbg_axi_data[ 52: 52] = axi_awready; + assign dbg_axi_data[ 53: 53] = axi_wvalid; + assign dbg_axi_data[ 69: 54] = axi_wdata[15:0]; + assign dbg_axi_data[ 70: 70] = axi_wlast; + assign dbg_axi_data[ 71: 71] = axi_wready; + assign dbg_axi_data[ 72: 72] = axi_bvalid; + assign dbg_axi_data[ 74: 73] = axi_bresp; + assign dbg_axi_data[ 75: 75] = axi_bready; + assign dbg_axi_data[ 76: 76] = axi_arvalid; + assign dbg_axi_data[108: 77] = axi_araddr; + assign dbg_axi_data[109:109] = axi_arready; + assign dbg_axi_data[110:110] = axi_rvalid; + assign dbg_axi_data[112:111] = axi_rresp; + assign dbg_axi_data[113:113] = axi_rlast; + assign dbg_axi_data[129:114] = axi_rdata[15:0]; + assign dbg_axi_data[130:130] = axi_rready; + assign dbg_axi_data[131:131] = axi_xfer_req; + assign dbg_axi_data[132:132] = axi_rd_req_s; + assign dbg_axi_data[164:133] = axi_rd_addr_s; + assign dbg_axi_data[165:165] = axi_rd_status_s; + // instantiations axi_fifo2s_wr #( .DATA_WIDTH (DATA_WIDTH), .AXI_SIZE (AXI_SIZE), .AXI_LENGTH (AXI_LENGTH), - .AXI_ADDRESS (AXI_ADDRESS)) + .AXI_ADDRESS (AXI_ADDRESS), + .AXI_ADDRLIMIT (AXI_ADDRLIMIT)) i_wr ( .axi_xfer_req (axi_xfer_req), .axi_rd_req (axi_rd_req_s), @@ -228,7 +277,9 @@ module axi_fifo2s ( axi_fifo2s_rd #( .DATA_WIDTH (DATA_WIDTH), .AXI_SIZE (AXI_SIZE), - .AXI_LENGTH (AXI_LENGTH)) + .AXI_LENGTH (AXI_LENGTH), + .AXI_ADDRESS (AXI_ADDRESS), + .AXI_ADDRLIMIT (AXI_ADDRLIMIT)) i_rd ( .axi_xfer_req (axi_xfer_req), .axi_rd_req (axi_rd_req_s), diff --git a/library/axi_fifo2s/axi_fifo2s_rd.v b/library/axi_fifo2s/axi_fifo2s_rd.v index a7e410064..efca3dcc7 100755 --- a/library/axi_fifo2s/axi_fifo2s_rd.v +++ b/library/axi_fifo2s/axi_fifo2s_rd.v @@ -84,6 +84,9 @@ module axi_fifo2s_rd ( parameter DATA_WIDTH = 32; parameter AXI_SIZE = 2; parameter AXI_LENGTH = 16; + parameter AXI_ADDRESS = 32'h00000000; + parameter AXI_ADDRLIMIT = 32'h00000000; + localparam AXI_AWINCR = (AXI_LENGTH * DATA_WIDTH)/8; localparam BUF_THRESHOLD_LO = 6'd3; localparam BUF_THRESHOLD_HI = 6'd60; @@ -127,16 +130,10 @@ module axi_fifo2s_rd ( // internal registers - reg [ 5:0] axi_waddr = 'd0; - reg [ 5:0] axi_raddr = 'd0; reg axi_rd = 'd0; - reg axi_rd_d = 'd0; - reg [ 31:0] axi_rdata_d = 'd0; - reg [ 5:0] axi_addr_diff = 'd0; - reg axi_almost_full = 'd0; - reg axi_unf = 'd0; - reg axi_almost_empty = 'd0; - reg axi_ovf = 'd0; + reg axi_rd_active = 'd0; + reg [ 2:0] axi_xfer_req_m = 'd0; + reg axi_xfer_init = 'd0; reg axi_arerror = 'd0; reg axi_arvalid = 'd0; reg [ 31:0] axi_araddr = 'd0; @@ -149,78 +146,30 @@ module axi_fifo2s_rd ( // internal signals - wire axi_wr_s; - wire [ 31:0] axi_wdata_s; - wire axi_arready_s; - wire axi_fifo_ready_s; - wire axi_rd_s; - wire [ 6:0] axi_addr_diff_s; - wire [ 31:0] axi_rdata_s; + wire axi_ready_s; - // queue requests + // read is way too slow- buffer mode - assign axi_wr_s = axi_rd_req; - assign axi_wdata_s = axi_rd_addr; + assign axi_ready_s = (~axi_arvalid | axi_arready) & ~axi_mwpfull; always @(posedge axi_clk or negedge axi_resetn) begin if (axi_resetn == 1'b0) begin - axi_waddr <= 'd0; - end else begin - if (axi_wr_s == 1'b1) begin - axi_waddr <= axi_waddr + 1'b1; - end - end - end - - // read queue - - assign axi_arready_s = ~axi_arvalid | axi_arready; - assign axi_fifo_ready_s = ~axi_xfer_req | ~axi_mwpfull; - assign axi_rd_s = (axi_waddr == axi_raddr) ? 1'b0 : (axi_arready_s & axi_fifo_ready_s); - - always @(posedge axi_clk or negedge axi_resetn) begin - if (axi_resetn == 1'b0) begin - axi_raddr <= 'd0; axi_rd <= 'd0; - axi_rd_d <= 'd0; - axi_rdata_d <= 'd0; + axi_rd_active <= 'd0; + axi_xfer_req_m <= 'd0; + axi_xfer_init <= 'd0; end else begin - if (axi_rd_s == 1'b1) begin - axi_raddr <= axi_raddr + 1'b1; - end - axi_rd <= axi_rd_s; - axi_rd_d <= axi_rd; - axi_rdata_d <= axi_rdata_s; - end - end - - // overflow (no underflow possible) - - assign axi_addr_diff_s = {1'b1, axi_waddr} - axi_raddr; - - always @(posedge axi_clk or negedge axi_resetn) begin - if (axi_resetn == 1'b0) begin - axi_addr_diff <= 'd0; - axi_almost_full <= 'd0; - axi_unf <= 'd0; - axi_almost_empty <= 'd0; - axi_ovf <= 'd0; - end else begin - axi_addr_diff <= axi_addr_diff_s[5:0]; - if (axi_addr_diff > BUF_THRESHOLD_HI) begin - axi_almost_full <= 1'b1; - axi_unf <= axi_almost_empty; - end else begin - axi_almost_full <= 1'b0; - axi_unf <= 1'b0; - end - if (axi_addr_diff < BUF_THRESHOLD_LO) begin - axi_almost_empty <= 1'b1; - axi_ovf <= axi_almost_full; - end else begin - axi_almost_empty <= 1'b0; - axi_ovf <= 1'b0; + if (axi_rd_active == 1'b1) begin + axi_rd <= 1'b0; + if (axi_rlast == 1'b1) begin + axi_rd_active <= 1'b0; + end + end else if ((axi_ready_s == 1'b1) && (axi_araddr < axi_rd_addr)) begin + axi_rd <= 1'b1; + axi_rd_active <= 1'b1; end + axi_xfer_req_m <= {axi_xfer_req_m[1:0], axi_xfer_req}; + axi_xfer_init <= axi_xfer_req_m[1] & ~axi_xfer_req_m[2]; end end @@ -242,18 +191,20 @@ module axi_fifo2s_rd ( axi_arvalid <= 'd0; axi_araddr <= 'd0; end else begin - axi_arerror <= axi_rd_d & axi_arvalid; + axi_arerror <= axi_rd & axi_arvalid; if (axi_arvalid == 1'b1) begin if (axi_arready == 1'b1) begin axi_arvalid <= 1'b0; end end else begin - if (axi_rd_d == 1'b1) begin + if (axi_rd == 1'b1) begin axi_arvalid <= 1'b1; end end - if ((axi_rd_d == 1'b1) && (axi_arvalid == 1'b0)) begin - axi_araddr <= axi_rdata_d; + if (axi_xfer_init == 1'b1) begin + axi_araddr <= AXI_ADDRESS; + end else if ((axi_arvalid == 1'b1) && (axi_arready == 1'b1)) begin + axi_araddr <= axi_araddr + AXI_AWINCR; end end end @@ -268,7 +219,7 @@ module axi_fifo2s_rd ( end else begin axi_mwr <= axi_rvalid & axi_rready; axi_mwdata <= axi_rdata; - axi_rready <= axi_fifo_ready_s; + axi_rready <= 1'b1; end end @@ -296,21 +247,10 @@ module axi_fifo2s_rd ( if (axi_resetn == 1'b0) begin axi_rd_status <= 'd0; end else begin - axi_rd_status <= axi_mwovf | axi_ovf | axi_unf | axi_arerror | axi_rerror; + axi_rd_status <= axi_mwovf | axi_arerror | axi_rerror; end end - // buffer - - ad_mem #(.DATA_WIDTH(32), .ADDR_WIDTH(6)) i_mem ( - .clka (axi_clk), - .wea (axi_wr_s), - .addra (axi_waddr), - .dina (axi_wdata_s), - .clkb (axi_clk), - .addrb (axi_raddr), - .doutb (axi_rdata_s)); - endmodule // *************************************************************************** diff --git a/library/axi_fifo2s/axi_fifo2s_wr.v b/library/axi_fifo2s/axi_fifo2s_wr.v index 504fa0138..4ea5f01f5 100755 --- a/library/axi_fifo2s/axi_fifo2s_wr.v +++ b/library/axi_fifo2s/axi_fifo2s_wr.v @@ -90,6 +90,7 @@ module axi_fifo2s_wr ( parameter AXI_SIZE = 2; parameter AXI_LENGTH = 16; parameter AXI_ADDRESS = 32'h00000000; + parameter AXI_ADDRLIMIT = 32'h00000000; localparam AXI_AWINCR = (AXI_LENGTH * DATA_WIDTH)/8; localparam BUF_THRESHOLD_LO = 6'd3; localparam BUF_THRESHOLD_HI = 6'd60; @@ -139,6 +140,11 @@ module axi_fifo2s_wr ( // internal registers + reg [ 2:0] m_xfer_req_m = 'd0; + reg m_xfer_init = 'd0; + reg m_xfer_limit = 'd0; + reg m_xfer_enable = 'd0; + reg [ 31:0] m_xfer_addr = 'd0; reg [ 5:0] m_waddr = 'd0; reg [ 5:0] m_waddr_g = 'd0; reg m_rel_enable = 'd0; @@ -156,8 +162,8 @@ module axi_fifo2s_wr ( reg axi_unf = 'd0; reg axi_almost_empty = 'd0; reg axi_ovf = 'd0; - reg [ 2:0] axi_xfer_enable_m = 'd0; - reg axi_xfer_enable = 'd0; + reg [ 2:0] axi_xfer_req_m = 'd0; + reg axi_xfer_init = 'd0; reg [ 5:0] axi_raddr = 'd0; reg axi_rd = 'd0; reg axi_rlast = 'd0; @@ -223,16 +229,35 @@ module axi_fifo2s_wr ( if (m_rst == 1'b1) begin m_waddr <= 'd0; m_waddr_g <= 'd0; + m_xfer_req_m <= 'd0; + m_xfer_init <= 'd0; + m_xfer_limit <= 'd0; + m_xfer_enable <= 'd0; + m_xfer_addr <= 'd0; m_rel_enable <= 'd0; m_rel_toggle <= 'd0; m_rel_waddr <= 'd0; m_status_m <= 'd0; m_wovf <= 'd0; end else begin - if (m_wr == 1'b1) begin + if ((m_wr == 1'b1) && (m_xfer_enable == 1'b1)) begin m_waddr <= m_waddr + 1'b1; end m_waddr_g <= b2g(m_waddr); + m_xfer_req_m <= {m_xfer_req_m[1:0], axi_xfer_req}; + m_xfer_init <= m_xfer_req_m[1] & ~m_xfer_req_m[2]; + if (m_xfer_init == 1'b1) begin + m_xfer_limit <= 1'd1; + end else if (m_xfer_addr >= AXI_ADDRLIMIT) begin + m_xfer_limit <= 1'd0; + end + if (m_xfer_init == 1'b1) begin + m_xfer_enable <= 1'b1; + m_xfer_addr <= AXI_ADDRESS; + end else if ((m_waddr[1:0] == 2'h3) && (m_wr == 1'b1)) begin + m_xfer_enable <= m_xfer_req_m[2] & m_xfer_limit; + m_xfer_addr <= m_xfer_addr + AXI_AWINCR; + end if (m_waddr[1:0] == 2'h3) begin m_rel_enable <= m_wr; end else begin @@ -303,20 +328,18 @@ module axi_fifo2s_wr ( always @(posedge axi_clk or negedge axi_resetn) begin if (axi_resetn == 1'b0) begin - axi_xfer_enable_m <= 'd0; - axi_xfer_enable <= 'd0; + axi_xfer_req_m <= 'd0; + axi_xfer_init <= 'd0; end else begin - axi_xfer_enable_m <= {axi_xfer_enable_m[1:0], axi_xfer_req}; - if (axi_rel_toggle_s == 1'b1) begin - axi_xfer_enable <= axi_xfer_enable_m[2]; - end + axi_xfer_req_m <= {axi_xfer_req_m[1:0], axi_xfer_req}; + axi_xfer_init <= axi_xfer_req_m[1] & ~axi_xfer_req_m[2]; end end // read is initiated if xfer enabled assign axi_wready_s = ~axi_wvalid | axi_wready; - assign axi_rd_s = (axi_rel_waddr == axi_raddr) ? 1'b0 : (axi_wready_s & axi_xfer_enable); + assign axi_rd_s = (axi_rel_waddr == axi_raddr) ? 1'b0 : axi_wready_s; assign axi_req_s = (axi_raddr[1:0] == 2'h0) ? axi_rd_s : 1'b0; assign axi_rlast_s = (axi_raddr[1:0] == 2'h3) ? axi_rd_s : 1'b0; @@ -329,9 +352,7 @@ module axi_fifo2s_wr ( axi_rlast_d <= 'd0; axi_rdata_d <= 'd0; end else begin - if (axi_xfer_enable == 1'b0) begin - axi_raddr <= axi_rel_waddr; - end else if (axi_rd_s == 1'b1) begin + if (axi_rd_s == 1'b1) begin axi_raddr <= axi_raddr + 1'b1; end axi_rd <= axi_rd_s; @@ -350,7 +371,7 @@ module axi_fifo2s_wr ( axi_rd_addr <= 'd0; end else begin axi_rd_req <= axi_rlast_s; - if (axi_xfer_enable == 1'b0) begin + if (axi_xfer_init == 1'b1) begin axi_rd_addr <= AXI_ADDRESS; end else if (axi_rd_req == 1'b1) begin axi_rd_addr <= axi_rd_addr + AXI_AWINCR; @@ -386,7 +407,7 @@ module axi_fifo2s_wr ( axi_awvalid <= 1'b1; end end - if (axi_xfer_enable == 1'b0) begin + if (axi_xfer_init == 1'b1) begin axi_awaddr <= AXI_ADDRESS; end else if ((axi_awvalid == 1'b1) && (axi_awready == 1'b1)) begin axi_awaddr <= axi_awaddr + AXI_AWINCR;