Skip to content
This repository has been archived by the owner on Jan 16, 2020. It is now read-only.

Potential forbidden axi write handshake dependency in debugging unit (#182) #8

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion axi_AW_allocator.sv
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,25 @@ 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;

// 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;
else
r_busy <= awvalid_o & ~|awready_o;
end
assign push_ID_o = (awvalid_o & (awvalid_o ^ r_busy)) & grant_FIFO_ID_i;


generate
for(i=0;i<N_TARG_PORT;i++)
Expand Down
24 changes: 22 additions & 2 deletions axi_address_decoder_AW.sv
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,26 @@ module axi_address_decoder_AW


assign DEST_o = match_region[N_INIT_PORT-1:0];
assign push_DEST_o = |(awvalid_i & awready_o) & ~error_detected;


// 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;
else
r_busy <= awvalid_i & ~awready_o;
end
assign push_DEST_o = (awvalid_i & (awvalid_i ^ r_busy)) & ~error_detected;


enum logic [1:0] { OPERATIVE, COMPLETE_PENDING, ACCEPT_WDATA , COMPLETE_ERROR_RESP } CS, NS;

Expand Down Expand Up @@ -188,7 +207,8 @@ module axi_address_decoder_AW
end
end

assign local_increm = |(awvalid_o & awready_i);
assign local_increm = (awvalid_i & (awvalid_i ^ r_busy));


always_comb
begin
Expand Down