Master_AXI_Write_Response_Channel.v 3.38 KB
Newer Older
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 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136

// Master AXI Write Response Channel

// A read channel with connects an AXI write response channel to a system
// register read.

// The control interface enables the read channel by raising and holding
// control_enable until control_done is also raised (AXI ready/valid
// handshake). The skid buffer then accepts one (or two, if multiple
// transactions in flight have completed) write response transactions from the
// AXI interface. The channel then raises system_valid to indicate a response
// can be read out.

// The system interface reads out a write response by raising system_ready for
// one cycle. The response is only valid if read while system_valid is high,
// else it is old or undefined data. Once a single response is read out, the
// transaction is done and the control interface must re-enable the read channel
// again.

`default_nettype none

module Master_AXI_Write_Response_Channel
#(
    // Do not alter at instantiation. Set by AXI4 spec.
    parameter BRESP_WIDTH = 2
)
(
    input   wire                        clock,

    // System interface
    output  wire    [BRESP_WIDTH-1:0]   system_response,
    input   wire                        system_ready,
    output  wire                        system_valid,

    // Control interface
    input   wire                        control_enable,
    output  reg                         control_done,

    // AXI interface
    input   wire    [BRESP_WIDTH-1:0]   bresp,
    input   wire                        bvalid,
    output  wire                        bready
);

// --------------------------------------------------------------------------
// Selectively disconnect the master and slave interfaces of the skid buffer.
// This is used to enforce an idle state (accept nothing from AXI and
// system interfaces).

// ---- Slave interface to AXI

    wire s_valid;
    wire s_ready;

    Annuller
    #(
        .WORD_WIDTH (1)
    )
    slave_valid
    (
        .annul      (control_enable == 1'b0),
        .in         (bvalid),
        .out        (s_valid)
    );

    Annuller
    #(
        .WORD_WIDTH (1)
    )
    slave_ready
    (
        .annul      (control_enable == 1'b0),
        .in         (s_ready),
        .out        (bready)
    );

// ---- Master interface to system

    wire m_ready;
    wire m_valid;

    Annuller
    #(
        .WORD_WIDTH (1)
    )
    master_valid
    (
        .annul      (control_enable == 1'b0),
        .in         (m_valid),
        .out        (system_valid)
    );

    Annuller
    #(
        .WORD_WIDTH (1)
    )
    master_ready
    (
        .annul      (control_enable == 1'b0),
        .in         (system_ready),
        .out        (m_ready)
    );

// --------------------------------------------------------------------------
// Receive and buffer the AXI write response

    skid_buffer
    #(
        .WORD_WIDTH (BRESP_WIDTH)
    )
    read_channel
    (
        .clock      (clock),

        .s_valid    (s_valid),
        .s_ready    (s_ready),
        .s_data     (bresp),

        .m_valid    (m_valid),
        .m_ready    (m_ready),
        .m_data     (system_response)
    );


// --------------------------------------------------------------------------
// Signal that the transaction is done once a single response is read out.

    reg system_read = 1'b0;

    always @(*) begin
        system_read  = (m_valid == 1'b1) && (m_ready == 1'b1);
        control_done = system_read;
    end

endmodule