Follow along with the video below to see how to install our site as a web app on your home screen.
Note: This feature may not be available in some browsers.
"o_axi_wvalid && o_axi_awvalid" appears in an expression and both are outputs. this is not specifically an error, but likely is one.
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 reg [$clog2(MAX_BURST_LENGTH)-1:0] num_of_write_transactions; always @(posedge clk) begin if(reset) num_of_write_transactions <= 0; else if(o_axi_wvalid && o_axi_awvalid) num_of_write_transactions <= (o_axi_wlast) ? 1 : num_of_write_transactions + 1; end
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 reg [$clog2(MAX_BURST_LENGTH)-1:0] num_of_write_data_sent; always @(posedge clk) begin if(reset) begin o_axi_wvalid <= 0; num_of_write_data_sent <= 0; end else if(!(o_axi_wvalid && !i_axi_wready)) begin o_axi_wvalid <= (o_axi_wlast && write_response_is_ok) ? 0 : (num_of_write_data_sent < o_axi_awlen); if(write_response_is_ok) num_of_write_data_sent <= num_of_write_data_sent + 1; end end wire ddr_write_address_range_is_valid = (o_axi_awaddr < (1 << C_AXI_ADDR_WIDTH)); always @(posedge clk) begin if(reset) o_axi_awvalid <= 0; // AXI specification: A3.3.1 Dependencies between channel handshake signal // the VALID signal of the AXI interface sending information must not be dependent on // the READY signal of the AXI interface receiving that information // this is to prevent deadlock // since AXI slave could wait for i_axi_awvalid to be true before setting o_axi_awready true. // Note: For same interface, VALID cannot depend upon READY, but READY can depends upon VALID // Note: Once VALID is asserted, it MUST be kept asserted until READY is asserted. // VALID signal needs to be set (initially) independent of READY signal, // and then only ever adjusted if !(VALID && !READY) // Note: the master must not wait for the slave to assert AWREADY before asserting AWVALID // Note: (!(o_axi_awvalid && !i_axi_awready)) == (!awvalid || awready) // == (!awvalid || (awvalid && awready)). // it means "no transaction in progress or transaction accepted" else if(!(o_axi_awvalid && !i_axi_awready)) o_axi_awvalid <= /*i_axi_awready &&*/ (ddr_write_address_range_is_valid); end
// convenient common subexpressions
assign w_accept = (w_valid && w_ready);
assign aw_accept = (aw_valid && aw_ready);
// next-value logic also useful for use in the ready logic
// can be written in other ways to make it more clear.
// w_accept && !aw_block is the same as w_accept && !aww_accept effectively.
// (retain set ) reset
assign next_w_block <= (w_block || (w_accept && !aw_block)) && !aw_accept;
assign next_aw_block <= (aw_block || (aw_accept && !w_block)) && !w_accept;
always @(posedge clk) begin
// boilerplate assigns for the 2-process style logic.
w_block <= next_w_block;
aw_block <= next_aw_block;
// these have to be registered by axi spec.
// realistically, probably becomes something really simple or really complex.
// can be moved to another always block that uses next_w_block/next_aw_block.
w_ready <= !next_w_block && logic_for_w_ready;
aw_ready <= !next_aw_block && logic_for_aw_ready;
// reset
if (rst) begin
w_block <= 1'b0;
aw_block <= 1'b0;
w_ready <= 1'b0;
aw_ready <= 1'b0;
end
end
// true when both aw and w accepted. "aww" sounds cute. for the read channel,
// "arr" sounds like a pirate. although it does mean there is w, aw, and aww
// prefixes, so typos could be an issue.
assign aww_accept = (w_accept && aw_accept) // both on same cycle
|| (w_accept && aw_block) // w on this cycle, aw on some previous cycle
|| (w_block && aw_accept); // aw on this cycle, w on some previous cycle
// these can happen when the logic for the ready signals is not based on the block signals.
assert(!(w_block && w_accept)); // w accepted after blocking
assert(!(aw_block && aw_accept)); // aw accepted after blocking
assert(!(aw_block && w_block)); // invalid state.
Code Verilog - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 always @(posedge clk) begin if(reset) begin o_axi_wvalid <= 0; end else if(!(o_axi_wvalid && !i_axi_wready)) begin // Note that both o_axi_awsize , o_axi_awlen are of hardware constants, so no multiply hardware // since this is for testing, WDATA just uses some values up to the total size of the write address space // see [url]https://i.imgur.com/LBO9pQz.png[/url] in which AW* payloads are sent first, followed by W* payloads // Note: a master must not wait for AWREADY to be asserted before driving WVALID o_axi_wvalid <= (o_axi_wlast) ? 0 : (o_axi_wdata < (o_axi_awsize*o_axi_awlen)) && o_axi_awvalid; end end
Write strobes must only be asserted for the correct byte lanes as determined from the: Start Address, Transfer Size and Beat Number.