From 6b1fc738a35724fdfccd65569ec9b9112900b2db Mon Sep 17 00:00:00 2001 From: BarrydeBruin Date: Mon, 1 Apr 2019 20:28:48 +0200 Subject: [PATCH 1/3] - the master must not wait for the slave to assert AWREADY or WREADY before asserting AWVALID or WVALID --- axi_AW_allocator.sv | 17 ++++++++++++++++- axi_address_decoder_AW.sv | 23 +++++++++++++++++++++-- 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/axi_AW_allocator.sv b/axi_AW_allocator.sv index b1296e1..d57ff2a 100644 --- a/axi_AW_allocator.sv +++ b/axi_AW_allocator.sv @@ -115,7 +115,22 @@ assign awid_o[AXI_ID_OUT-1:AXI_ID_IN] = ID_o[LOG_N_TARG+N_TARG_PORT-1:N_T assign awready_o = {N_TARG_PORT{grant_FIFO_ID_i}} & awready_int; assign awvalid_o = awvalid_int & grant_FIFO_ID_i; -assign push_ID_o = awvalid_o & awready_i & grant_FIFO_ID_i; +//assign push_ID_o = awvalid_o & awready_i & grant_FIFO_ID_i; +// we push the first cycle that awvalid is asserted +logic r_busy; +always @(posedge clk) begin + if(rst_n == 1'b0) + r_busy <= 0; //reset condition + else begin + if (awready_o == 1'b0) + r_busy <= awvalid_o; // acknowledge delayed; only issue push once + else + r_busy <= 0; // acknowledge issued; keep pushing until aw_ready_o goes low + end +end +assign push_ID_o = (awvalid_o & (awvalid_o ^ r_busy)) & grant_FIFO_ID_i; +// end (added) + generate for(i=0;i Date: Wed, 3 Apr 2019 15:42:24 +0200 Subject: [PATCH 2/3] - cleaned code of previous commit a bit and added some comments (functionality is identical) --- axi_AW_allocator.sv | 23 +++++++++++++---------- axi_address_decoder_AW.sv | 27 ++++++++++++++------------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/axi_AW_allocator.sv b/axi_AW_allocator.sv index d57ff2a..8f6aa68 100644 --- a/axi_AW_allocator.sv +++ b/axi_AW_allocator.sv @@ -115,21 +115,24 @@ assign awid_o[AXI_ID_OUT-1:AXI_ID_IN] = ID_o[LOG_N_TARG+N_TARG_PORT-1:N_T assign awready_o = {N_TARG_PORT{grant_FIFO_ID_i}} & awready_int; assign awvalid_o = awvalid_int & grant_FIFO_ID_i; -//assign push_ID_o = awvalid_o & awready_i & grant_FIFO_ID_i; -// we push the first cycle that awvalid is asserted + +// Original code contains false dependency +// - AXI4 standard: 'the master must not wait for the slave to assert AWREADY or WREADY before asserting AWVALID or WVALID' +// - original code: assign push_ID_o = awvalid_o & awready_i & grant_FIFO_ID_i; + +// Therefore, push awvalid the first cycle that awvalid is asserted +// case 1: awvalid is asserted before awready is asserted +// - awvalid is pushed once. If awready goes high, r_busy is cleared for the next cycle. +// case 2: awvalid is asserted while awready is asserted (e.g. default accept) +// - awvalid is pushed, and r_busy is cleared for the next cycle. logic r_busy; always @(posedge clk) begin if(rst_n == 1'b0) - r_busy <= 0; //reset condition - else begin - if (awready_o == 1'b0) - r_busy <= awvalid_o; // acknowledge delayed; only issue push once - else - r_busy <= 0; // acknowledge issued; keep pushing until aw_ready_o goes low - end + r_busy <= 0; + else + r_busy <= awvalid_o & ~awready_o; end assign push_ID_o = (awvalid_o & (awvalid_o ^ r_busy)) & grant_FIFO_ID_i; -// end (added) generate diff --git a/axi_address_decoder_AW.sv b/axi_address_decoder_AW.sv index 71a6720..f8f3748 100644 --- a/axi_address_decoder_AW.sv +++ b/axi_address_decoder_AW.sv @@ -101,23 +101,25 @@ module axi_address_decoder_AW assign DEST_o = match_region[N_INIT_PORT-1:0]; - // causes dependency such that wvalid is not passed through if awready is not asserted by the slave - //assign push_DEST_o = |(awvalid_i & awready_o) & ~error_detected; - // we push the first cycle that awvalid is asserted + // Original code contains false dependency + // - AXI4 standard: 'the master must not wait for the slave to assert AWREADY or WREADY before asserting AWVALID or WVALID' + // - original code: assign push_DEST_o = |(awvalid_i & awready_o) & ~error_detected; + + // Therefore, push awvalid the first cycle that awvalid is asserted + // case 1: awvalid is asserted before awready is asserted + // - awvalid is pushed once. If awready goes high, r_busy is cleared for the next cycle. + // case 2: awvalid is asserted while awready is asserted (e.g. default accept) + // - awvalid is pushed, and r_busy is cleared for the next cycle. logic r_busy; always @(posedge clk) begin - if(rst_n == 1'b0) - r_busy <= 0; //reset condition - else begin - if (awready_o == 1'b0) - r_busy <= awvalid_i; // acknowledge delayed; only issue push once - else - r_busy <= 0; // acknowledge issued; keep pushing until aw_ready_o goes low - end + if(rst_n == 1'b0) + r_busy <= 0; + else + r_busy <= awvalid_i & ~awready_o; end assign push_DEST_o = (awvalid_i & (awvalid_i ^ r_busy)) & ~error_detected; - // end (added) + enum logic [1:0] { OPERATIVE, COMPLETE_PENDING, ACCEPT_WDATA , COMPLETE_ERROR_RESP } CS, NS; @@ -205,7 +207,6 @@ module axi_address_decoder_AW end end - //assign local_increm = |(awvalid_o & awready_i); assign local_increm = (awvalid_i & (awvalid_i ^ r_busy)); From e08b90bfb5182e2dc7afd384ffceabbbe0d3b77b Mon Sep 17 00:00:00 2001 From: BarrydeBruin Date: Wed, 10 Apr 2019 23:01:20 +0200 Subject: [PATCH 3/3] - small bugfix --- axi_AW_allocator.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axi_AW_allocator.sv b/axi_AW_allocator.sv index 8f6aa68..423f443 100644 --- a/axi_AW_allocator.sv +++ b/axi_AW_allocator.sv @@ -130,7 +130,7 @@ always @(posedge clk) begin if(rst_n == 1'b0) r_busy <= 0; else - r_busy <= awvalid_o & ~awready_o; + r_busy <= awvalid_o & ~|awready_o; end assign push_ID_o = (awvalid_o & (awvalid_o ^ r_busy)) & grant_FIFO_ID_i;