summaryrefslogtreecommitdiff
path: root/rtl/wb2axip/aximwr2wbsp.v
diff options
context:
space:
mode:
Diffstat (limited to 'rtl/wb2axip/aximwr2wbsp.v')
-rw-r--r--rtl/wb2axip/aximwr2wbsp.v751
1 files changed, 751 insertions, 0 deletions
diff --git a/rtl/wb2axip/aximwr2wbsp.v b/rtl/wb2axip/aximwr2wbsp.v
new file mode 100644
index 0000000..074467c
--- /dev/null
+++ b/rtl/wb2axip/aximwr2wbsp.v
@@ -0,0 +1,751 @@
+////////////////////////////////////////////////////////////////////////////////
+//
+// Filename: aximwr2wbsp.v
+// {{{
+// Project: WB2AXIPSP: bus bridges and other odds and ends
+//
+// Purpose: Convert the three AXI4 write channels to a single wishbone
+// channel to write the results.
+//
+// Creator: Dan Gisselquist, Ph.D.
+// Gisselquist Technology, LLC
+//
+////////////////////////////////////////////////////////////////////////////////
+// }}}
+// Copyright (C) 2015-2024, Gisselquist Technology, LLC
+// {{{
+// This file is part of the WB2AXIP project.
+//
+// The WB2AXIP project contains free software and gateware, licensed under the
+// Apache License, Version 2.0 (the "License"). You may not use this project,
+// or this file, except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+//
+//
+`default_nettype none
+// }}}
+module aximwr2wbsp #(
+ // {{{
+ parameter C_AXI_ID_WIDTH = 6,
+ parameter C_AXI_DATA_WIDTH = 32,
+ parameter C_AXI_ADDR_WIDTH = 28,
+ parameter [0:0] OPT_SWAP_ENDIANNESS = 1'b0,
+ localparam AXI_LSBS = $clog2(C_AXI_DATA_WIDTH)-3,
+ localparam AW = C_AXI_ADDR_WIDTH-AXI_LSBS,
+
+ parameter LGFIFO = 5
+ // }}}
+ ) (
+ // {{{
+ input wire S_AXI_ACLK, // System clock
+ input wire S_AXI_ARESETN,
+ // Incoming AXI bus connections
+ // {{{
+ // AXI write address channel signals
+ input wire S_AXI_AWVALID,
+ output wire S_AXI_AWREADY,
+ input wire [C_AXI_ID_WIDTH-1:0] S_AXI_AWID,
+ input wire [C_AXI_ADDR_WIDTH-1:0] S_AXI_AWADDR,
+ input wire [7:0] S_AXI_AWLEN,
+ input wire [2:0] S_AXI_AWSIZE,
+ input wire [1:0] S_AXI_AWBURST,
+ input wire [0:0] S_AXI_AWLOCK,
+ input wire [3:0] S_AXI_AWCACHE,
+ input wire [2:0] S_AXI_AWPROT,
+ input wire [3:0] S_AXI_AWQOS,
+
+ // AXI write data channel signals
+ input wire S_AXI_WVALID,
+ output wire S_AXI_WREADY,
+ input wire [C_AXI_DATA_WIDTH-1:0] S_AXI_WDATA,
+ input wire [C_AXI_DATA_WIDTH/8-1:0] S_AXI_WSTRB,
+ input wire S_AXI_WLAST,
+
+ // AXI write response channel signals
+ output wire S_AXI_BVALID,
+ input wire S_AXI_BREADY,
+ output wire [C_AXI_ID_WIDTH-1:0] S_AXI_BID,
+ output wire [1:0] S_AXI_BRESP,
+ // }}}
+ // Downstream wishbone bus
+ // {{{
+ // We'll share the clock and the reset
+ output reg o_wb_cyc,
+ output reg o_wb_stb,
+ output reg [(AW-1):0] o_wb_addr,
+ output reg [(C_AXI_DATA_WIDTH-1):0] o_wb_data,
+ output reg [(C_AXI_DATA_WIDTH/8-1):0] o_wb_sel,
+ input wire i_wb_stall,
+ input wire i_wb_ack,
+ // input [(C_AXI_DATA_WIDTH-1):0] i_wb_data,
+ input wire i_wb_err
+ // }}}
+
+ // }}}
+ );
+
+ // Register/net declarations
+ // {{{
+ localparam DW = C_AXI_DATA_WIDTH;
+ wire w_reset;
+
+ wire skid_awvalid;
+ reg accept_write_burst;
+ wire [C_AXI_ID_WIDTH-1:0] skid_awid;
+ wire [C_AXI_ADDR_WIDTH-1:0] skid_awaddr;
+ wire [7:0] skid_awlen;
+ wire [2:0] skid_awsize;
+ wire [1:0] skid_awburst;
+ //
+ wire skid_wvalid, skid_wlast;
+ reg skid_wready;
+ wire [C_AXI_DATA_WIDTH-1:0] skid_wdata;
+ wire [C_AXI_DATA_WIDTH/8-1:0] skid_wstrb;
+
+ reg skid_awready;
+ reg [7:0] axi_wlen, wlen;
+ reg [C_AXI_ID_WIDTH-1:0] axi_wid;
+ reg [C_AXI_ADDR_WIDTH-1:0] axi_waddr;
+ wire [C_AXI_ADDR_WIDTH-1:0] next_addr;
+ reg [1:0] axi_wburst;
+ reg [2:0] axi_wsize;
+
+ reg [LGFIFO+7:0] acks_expected;
+ reg [LGFIFO:0] writes_expected;
+ reg last_ack;
+ reg err_state;
+
+ reg read_ack_fifo;
+ wire [7:0] fifo_ack_ln;
+ reg [8:0] acklen;
+ reg ack_last, ack_err, ack_empty;
+
+ reg [LGFIFO:0] total_fifo_fill;
+ reg total_fifo_full;
+
+ wire wb_ack_fifo_full, wb_ack_fifo_empty;
+ wire [LGFIFO:0] wb_ack_fifo_fill;
+
+ wire err_fifo_full, err_fifo_empty;
+ wire [LGFIFO:0] err_fifo_fill;
+ reg err_fifo_write;
+
+ wire bid_fifo_full, bid_fifo_empty;
+ wire [LGFIFO:0] bid_fifo_fill;
+
+ reg [8:0] next_acklen;
+ reg [1:0] next_acklow;
+
+ assign w_reset = (S_AXI_ARESETN == 1'b0);
+ // }}}
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Skid buffers--all incoming signals go throug skid buffers
+ // {{{
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //
+
+ // write address skid buffer
+ // {{{
+ skidbuffer #(
+ .OPT_OUTREG(0),
+ .DW(C_AXI_ADDR_WIDTH+C_AXI_ID_WIDTH+8+3+2))
+ awskid(S_AXI_ACLK, !S_AXI_ARESETN, S_AXI_AWVALID, S_AXI_AWREADY,
+ { S_AXI_AWID, S_AXI_AWADDR, S_AXI_AWLEN,
+ S_AXI_AWSIZE, S_AXI_AWBURST },
+ skid_awvalid, accept_write_burst,
+ { skid_awid, skid_awaddr, skid_awlen,
+ skid_awsize, skid_awburst });
+ // }}}
+
+ // write channel skid buffer
+ // {{{
+ skidbuffer #(
+`ifdef FORMAL
+ .OPT_PASSTHROUGH(1'b1),
+`endif
+ .OPT_OUTREG(0),
+ .DW(C_AXI_DATA_WIDTH + C_AXI_DATA_WIDTH/8+1))
+ wskid(S_AXI_ACLK, !S_AXI_ARESETN,
+ S_AXI_WVALID, S_AXI_WREADY,
+ { S_AXI_WDATA, S_AXI_WSTRB, S_AXI_WLAST },
+ skid_wvalid, skid_wready,
+ { skid_wdata, skid_wstrb, skid_wlast });
+ // }}}
+
+ // accept_write_burst
+ // {{{
+ always @(*)
+ begin
+ accept_write_burst = (skid_awready)&&(!o_wb_stb || !i_wb_stall)
+ &&(!err_state)&&(skid_awvalid)
+ &&(!total_fifo_full);
+ if (axi_wid != skid_awid && (acks_expected > 0))
+ accept_write_burst = 0;
+ if (!skid_wvalid)
+ accept_write_burst = 0;
+ end
+ // }}}
+
+ // skid_wready
+ // {{{
+ always @(*)
+ skid_wready = (!o_wb_stb || !i_wb_stall || err_state)
+ &&(!skid_awready || accept_write_burst);
+ // }}}
+
+ // skid_awready
+ // {{{
+ initial skid_awready = 1'b1;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN)
+ skid_awready <= 1'b1;
+ else if (accept_write_burst)
+ skid_awready <= (skid_awlen == 0)&&(skid_wvalid)&&(skid_wlast);
+ else if (skid_wvalid && skid_wready && skid_wlast)
+ skid_awready <= 1'b1;
+ // }}}
+
+ // }}}
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Burst unwinding
+ // {{{
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //
+
+ // axi_w*, wlen -- properties of the currently active burst
+ // {{{
+ always @(posedge S_AXI_ACLK)
+ if (accept_write_burst)
+ begin
+ axi_wid <= skid_awid;
+ axi_waddr <= skid_awaddr;
+ axi_wsize <= skid_awsize;
+ axi_wburst <= skid_awburst;
+ axi_wlen <= skid_awlen;
+ wlen <= skid_awlen;
+ end else if (skid_wvalid && skid_wready)
+ begin
+ axi_waddr <= next_addr;
+ if (!skid_awready)
+ wlen <= wlen - 1;
+ end
+ // }}}
+
+ // next_addr
+ // {{{
+ axi_addr #(.AW(C_AXI_ADDR_WIDTH), .DW(C_AXI_DATA_WIDTH))
+ next_write_addr(axi_waddr, axi_wsize, axi_wburst, axi_wlen, next_addr);
+ // }}}
+
+ // }}}
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Issue the Wishbone request
+ // {{{
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //
+
+ // o_wb_cyc, o_wb_stb
+ // {{{
+ initial { o_wb_cyc, o_wb_stb } = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN || err_state || (o_wb_cyc && i_wb_err))
+ begin
+ o_wb_cyc <= 1'b0;
+ o_wb_stb <= 1'b0;
+ end else if (accept_write_burst)
+ begin
+ o_wb_cyc <= 1'b1;
+ o_wb_stb <= skid_wvalid && skid_wready;
+ end else begin
+ if (!o_wb_stb || !i_wb_stall)
+ o_wb_stb <= (!skid_awready)&&(skid_wvalid&&skid_wready);
+ if (o_wb_cyc && last_ack && i_wb_ack && !skid_awvalid)
+ o_wb_cyc <= 0;
+ end
+ // }}}
+
+ always @(*)
+ o_wb_addr = axi_waddr[C_AXI_ADDR_WIDTH-1:AXI_LSBS];
+
+ // o_wb_data, o_wb_sel
+ // {{{
+ generate if (OPT_SWAP_ENDIANNESS)
+ begin : SWAP_ENDIANNESS
+ integer ik;
+
+ always @(posedge S_AXI_ACLK)
+ if (!o_wb_stb || !i_wb_stall)
+ begin
+ for(ik=0; ik<DW/8; ik=ik+1)
+ begin
+ o_wb_data[ik*8 +: 8]
+ <= skid_wdata[(DW/8-1-ik)*8 +: 8];
+ o_wb_sel[ik] <= skid_wstrb[DW/8-1-ik];
+ end
+ end
+
+ end else begin : KEEP_ENDIANNESS
+
+ always @(posedge S_AXI_ACLK)
+ if (!o_wb_stb || !i_wb_stall)
+ begin
+ o_wb_data <= skid_wdata;
+ o_wb_sel <= skid_wstrb;
+ end
+
+ end endgenerate
+ // }}}
+
+ // }}}
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // FIFO usage tracking
+ // {{{
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //
+
+ // writes_expected
+ // {{{
+ initial writes_expected = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN)
+ begin
+ writes_expected <= 0;
+ end else case({skid_wvalid && skid_wready && skid_wlast,
+ S_AXI_BVALID && S_AXI_BREADY })
+ 2'b01: writes_expected <= writes_expected - 1;
+ 2'b10: writes_expected <= writes_expected + 1;
+ default: begin end
+ endcase
+ // }}}
+
+ // acks_expected
+ // {{{
+ initial acks_expected = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN || i_wb_err || err_state)
+ begin
+ acks_expected <= 0;
+ end else case({skid_awvalid && accept_write_burst, {i_wb_ack|i_wb_err}})
+ 2'b01: acks_expected <= acks_expected - 1;
+ 2'b10: acks_expected <= acks_expected + ({{(LGFIFO){1'b0}},skid_awlen} + 1);
+ 2'b11: acks_expected <= acks_expected + {{(LGFIFO){1'b0}},skid_awlen};
+ default: begin end
+ endcase
+ // }}}
+
+ // last_ack
+ // {{{
+ initial last_ack = 1;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN || i_wb_err || err_state)
+ begin
+ last_ack <= 1;
+ end else case({skid_awvalid && accept_write_burst, i_wb_ack })
+ 2'b01: last_ack <= (acks_expected <= 2);
+ 2'b10: last_ack <= (acks_expected == 0)&&(skid_awlen == 0);
+ 2'b11: last_ack <= last_ack && (skid_awlen == 0);
+ default: begin end
+ endcase
+
+ // }}}
+
+ // total_fifo_fill
+ // {{{
+ initial total_fifo_fill = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN)
+ total_fifo_fill <= 0;
+ else case({ accept_write_burst, S_AXI_BVALID && S_AXI_BREADY })
+ 2'b01: total_fifo_fill <= total_fifo_fill - 1;
+ 2'b10: total_fifo_fill <= total_fifo_fill + 1;
+ default: begin end
+ endcase
+ // }}}
+
+ // total_fifo_full
+ // {{{
+ always @(*)
+ total_fifo_full = total_fifo_fill[LGFIFO];
+ // }}}
+ // }}}
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Return channel
+ // {{{
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //
+
+ // wb_ack_fifo
+ // {{{
+ sfifo #(.BW(8), .LGFLEN(LGFIFO),
+ .OPT_ASYNC_READ(1'b1))
+ wb_ack_fifo(S_AXI_ACLK, !S_AXI_ARESETN,
+ accept_write_burst, skid_awlen,
+ wb_ack_fifo_full, wb_ack_fifo_fill,
+ read_ack_fifo, fifo_ack_ln, wb_ack_fifo_empty);
+ // }}}
+
+ // read_ack_fifo
+ // {{{
+ always @(*)
+ begin
+ read_ack_fifo = ack_last && (i_wb_ack || i_wb_err);
+ if (err_state || ack_empty)
+ read_ack_fifo = 1;
+ if (wb_ack_fifo_empty)
+ read_ack_fifo = 1'b0;
+ end
+ // }}}
+
+ // next_acklen
+ // {{{
+ always @(*)
+ next_acklen = fifo_ack_ln + ((acklen[0] ? 1:0)
+ + ((i_wb_ack|i_wb_err)? 0:1));
+ // }}}
+
+ // next_acklow
+ // {{{
+ always @(*)
+ next_acklow = fifo_ack_ln[0] + ((acklen[0] ? 1:0)
+ + ((i_wb_ack|i_wb_err)? 0:1));
+ // }}}
+
+ // acklen, ack_last, ack_empty
+ // {{{
+ initial acklen = 0;
+ initial ack_last = 0;
+ initial ack_empty = 1;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN || err_state)
+ begin
+ acklen <= 0;
+ ack_last <= 0;
+ ack_empty<= 1;
+ end else if (read_ack_fifo)
+ begin
+ acklen <= next_acklen;
+ ack_last <= (fifo_ack_ln < 2)&&(next_acklow == 1);
+ ack_empty<= (fifo_ack_ln == 0)&&(!acklen[0])
+ &&(i_wb_ack || i_wb_err);
+ end else if (i_wb_ack || i_wb_err)
+ begin
+ if (acklen > 0)
+ acklen <= acklen - 1;
+ ack_last <= (acklen == 2);
+ ack_empty <= ack_last;
+ end
+ // }}}
+
+ // ack_err
+ // {{{
+ always @(posedge S_AXI_ACLK)
+ if (read_ack_fifo)
+ begin
+ ack_err <= (wb_ack_fifo_empty) || err_state || i_wb_err;
+ end else if (i_wb_ack || i_wb_err || err_state)
+ ack_err <= ack_err || (i_wb_err || err_state);
+ // }}}
+
+ // err_state
+ // {{{
+ initial err_state = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN)
+ err_state <= 0;
+ else if (o_wb_cyc && i_wb_err)
+ err_state <= 1;
+ else if ((total_fifo_fill == bid_fifo_fill)
+ &&(total_fifo_fill == err_fifo_fill))
+ err_state <= 0;
+ // }}}
+
+ // err_fifo_write
+ // {{{
+ initial err_fifo_write = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN)
+ err_fifo_write <= 0;
+ else if (read_ack_fifo && ack_empty && fifo_ack_ln == 0)
+ err_fifo_write <= (i_wb_ack || i_wb_err || err_state);
+ else if (ack_last)
+ err_fifo_write <= (i_wb_ack || i_wb_err || err_state);
+ else
+ err_fifo_write <= 1'b0;
+ // }}}
+
+ // bid_fifo - Keep track of BID's
+ // {{{
+ sfifo #(.BW(C_AXI_ID_WIDTH), .LGFLEN(LGFIFO))
+ bid_fifo(S_AXI_ACLK, !S_AXI_ARESETN,
+ skid_wvalid && skid_wready && skid_wlast,
+ (total_fifo_fill == bid_fifo_fill) ? skid_awid:axi_wid,
+ bid_fifo_full, bid_fifo_fill,
+ S_AXI_BVALID & S_AXI_BREADY, S_AXI_BID, bid_fifo_empty);
+ // }}}
+
+ // err_fifo - Keep track of error returns
+ // {{{
+ sfifo #(.BW(1), .LGFLEN(LGFIFO))
+ err_fifo(S_AXI_ACLK, !S_AXI_ARESETN,
+ err_fifo_write, { ack_err || i_wb_err },
+ err_fifo_full, err_fifo_fill,
+ S_AXI_BVALID & S_AXI_BREADY, S_AXI_BRESP[1], err_fifo_empty);
+ // }}}
+
+ assign S_AXI_BVALID = !bid_fifo_empty && !err_fifo_empty;
+ assign S_AXI_BRESP[0]= 1'b0;
+ // }}}
+
+ // Make Verilator happy
+ // {{{
+ // verilator lint_on UNUSED
+ wire unused;
+ assign unused = &{ 1'b0, S_AXI_AWBURST, S_AXI_AWSIZE,
+ S_AXI_AWLOCK, S_AXI_AWCACHE, S_AXI_AWPROT,
+ S_AXI_AWQOS, S_AXI_WLAST,
+ wb_ack_fifo_full, wb_ack_fifo_fill,
+ bid_fifo_full, err_fifo_full,
+ w_reset
+ };
+ // verilator lint_off UNUSED
+ // }}}
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+//
+// Formal property section
+// {{{
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+`ifdef FORMAL
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // The following are a subset of the properties used to verify this
+ // core
+ //
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //
+ // Formal only register/wire/parameter definitions
+ // {{{
+ localparam F_LGDEPTH = (LGFIFO>8) ? LGFIFO+1 : 10,
+ F_LGRDFIFO = 72; // 9*F_LGFIFO;
+ reg f_past_valid;
+ initial f_past_valid = 1'b0;
+ always @(posedge S_AXI_ACLK)
+ f_past_valid <= 1'b1;
+
+ localparam F_LGDEPTH = (LGFIFO>8) ? LGFIFO+1 : 10, F_LGRDFIFO = 72; // 9*F_LGFIFO;
+ wire [(F_LGDEPTH-1):0]
+ fwb_nreqs, fwb_nacks, fwb_outstanding;
+
+ //
+ // ...
+ //
+
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Wishbone properties
+ // {{{
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //
+ fwb_master #(
+ // {{{
+ .AW(AW), .DW(C_AXI_DATA_WIDTH), .F_MAX_STALL(2),
+ .F_MAX_ACK_DELAY(3), .F_LGDEPTH(F_LGDEPTH),
+ .F_OPT_DISCONTINUOUS(1)
+ // }}}
+ ) fwb(S_AXI_ACLK, w_reset,
+ // {{{
+ o_wb_cyc, o_wb_stb, 1'b1, o_wb_addr, o_wb_data, o_wb_sel,
+ i_wb_ack, i_wb_stall, {(DW){1'b0}}, i_wb_err,
+ fwb_nreqs, fwb_nacks, fwb_outstanding
+ // }}}
+ );
+
+ //
+ // ...
+ //
+
+ // }}}
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // AXI bus properties
+ // {{{
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //
+ faxi_slave #(
+ // {{{
+ .C_AXI_DATA_WIDTH(C_AXI_DATA_WIDTH),
+ .C_AXI_ADDR_WIDTH(C_AXI_ADDR_WIDTH),
+ .C_AXI_ID_WIDTH(C_AXI_ID_WIDTH),
+ .F_LGDEPTH(F_LGDEPTH),
+ .F_AXI_MAXSTALL(0),
+ .F_AXI_MAXDELAY(0)
+ // }}}
+ ) faxi(.i_clk(S_AXI_ACLK), .i_axi_reset_n(S_AXI_ARESETN),
+ // {{{
+ .i_axi_awready(S_AXI_AWREADY),
+ .i_axi_awid( S_AXI_AWID),
+ .i_axi_awaddr( S_AXI_AWADDR),
+ .i_axi_awlen( S_AXI_AWLEN),
+ .i_axi_awsize( S_AXI_AWSIZE),
+ .i_axi_awburst(S_AXI_AWBURST),
+ .i_axi_awlock( S_AXI_AWLOCK),
+ .i_axi_awcache(S_AXI_AWCACHE),
+ .i_axi_awprot( S_AXI_AWPROT),
+ .i_axi_awqos( S_AXI_AWQOS),
+ .i_axi_awvalid(S_AXI_AWVALID),
+ //
+ .i_axi_wready(S_AXI_WREADY),
+ .i_axi_wdata( S_AXI_WDATA),
+ .i_axi_wstrb( S_AXI_WSTRB),
+ .i_axi_wlast( S_AXI_WLAST),
+ .i_axi_wvalid(S_AXI_WVALID),
+ //
+ .i_axi_bid( S_AXI_BID),
+ .i_axi_bresp( S_AXI_BRESP),
+ .i_axi_bvalid(S_AXI_BVALID),
+ .i_axi_bready(S_AXI_BREADY),
+ //
+ .i_axi_arready(1'b0),
+ .i_axi_arid( {(C_AXI_ID_WIDTH){1'b0}}),
+ .i_axi_araddr({(C_AXI_ADDR_WIDTH){1'b0}}),
+ .i_axi_arlen( 8'h0),
+ .i_axi_arsize( 3'h0),
+ .i_axi_arburst(2'h0),
+ .i_axi_arlock( 1'b0),
+ .i_axi_arcache(4'h0),
+ .i_axi_arprot( 3'h0),
+ .i_axi_arqos( 4'h0),
+ .i_axi_arvalid(1'b0),
+ //
+ .i_axi_rresp( 2'h0),
+ .i_axi_rid( {(C_AXI_ID_WIDTH){1'b0}}),
+ .i_axi_rvalid(1'b0),
+ .i_axi_rdata( {(C_AXI_DATA_WIDTH){1'b0}}),
+ .i_axi_rlast( 1'b0),
+ .i_axi_rready(1'b0)
+ //
+ // ...
+ //
+ );
+
+
+ // never_err control(s)
+ // {{{
+ always @(*)
+ if (never_err)
+ begin
+ assume(!i_wb_err);
+ assert(!err_state);
+ if (!skid_awvalid)
+ assert(o_wb_cyc == (acks_expected != 0));
+ if (!skid_awready)
+ assert(o_wb_cyc);
+ if (S_AXI_BVALID)
+ assert(!S_AXI_BRESP[1]);
+ assert(!S_AXI_BRESP[0]);
+ end
+ // }}}
+
+ // }}}
+ ////////////////////////////////////////////////////////////////////////
+ //
+ // Cover checks
+ // {{{
+ ////////////////////////////////////////////////////////////////////////
+ //
+ //
+
+ // Cover registers
+ // {{{
+ reg [3:0] cvr_writes, cvr_write_bursts,
+ cvr_wrid_bursts;
+ reg [C_AXI_ID_WIDTH-1:0] cvr_write_id;
+ // }}}
+
+ // cvr_writes
+ // {{{
+ initial cvr_writes = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN)
+ cvr_writes <= 1;
+ else if (i_wb_err)
+ cvr_writes <= 0;
+ else if (S_AXI_BVALID && S_AXI_BREADY && !cvr_writes[3]
+ && cvr_writes > 0)
+ cvr_writes <= cvr_writes + 1;
+ // }}}
+
+ // cvr_write_bursts
+ // {{{
+ initial cvr_write_bursts = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN)
+ cvr_write_bursts <= 1;
+ else if (S_AXI_AWVALID && S_AXI_AWLEN < 1)
+ cvr_write_bursts <= 0;
+ else if (i_wb_err)
+ cvr_write_bursts <= 0;
+ else if (S_AXI_BVALID && S_AXI_BREADY
+ && !cvr_write_bursts[3] && cvr_write_bursts > 0)
+ cvr_write_bursts <= cvr_write_bursts + 1;
+ // }}}
+
+ // cvr_write_id
+ // {{{
+ initial cvr_write_id = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN)
+ cvr_write_id <= 1;
+ else if (S_AXI_BVALID && S_AXI_BREADY)
+ cvr_write_id <= cvr_write_id + 1;
+ // }}}
+
+ // cvr_wrid_bursts
+ // {{{
+ initial cvr_wrid_bursts = 0;
+ always @(posedge S_AXI_ACLK)
+ if (!S_AXI_ARESETN)
+ cvr_wrid_bursts <= 1;
+ else if (S_AXI_AWVALID && S_AXI_AWLEN < 1)
+ cvr_wrid_bursts <= 0;
+ else if (i_wb_err)
+ cvr_wrid_bursts <= 0;
+ else if (S_AXI_BVALID && S_AXI_BREADY
+ && S_AXI_BID == cvr_write_id
+ && !cvr_wrid_bursts[3] && cvr_wrid_bursts > 0)
+ cvr_wrid_bursts <= cvr_wrid_bursts + 1;
+ // }}}
+
+ always @(*) cover(cvr_writes == 4);
+ always @(*) cover(cvr_write_bursts == 4);
+ always @(*) cover(cvr_wrid_bursts == 4);
+ // }}}
+`endif
+// }}}
+endmodule