module cmsdk_mcu_mtx4x2_arb_M0 (

    // Common AHB signals
    HCLK ,
    HRESETn,

    // Input port request signals
    req_port0,
    req_port2,
    req_port3,

    HREADYM,
    HSELM,
    HTRANSM,
    HBURSTM,
    HMASTLOCKM,

    // Arbiter outputs
    addr_in_port,
    no_port

    );


// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------

    // Common AHB signals
    input        HCLK;         // AHB system clock
    input        HRESETn;      // AHB system reset

    input        req_port0;     // Port 0 request signal
    input        req_port2;     // Port 2 request signal
    input        req_port3;     // Port 3 request signal

    input        HREADYM;      // Transfer done
    input        HSELM;        // Slave select line
    input  [1:0] HTRANSM;      // Transfer type
    input  [2:0] HBURSTM;      // Burst type
    input        HMASTLOCKM;   // Locked transfer

    output [1:0] addr_in_port;   // Port address input
    output       no_port;       // No port selected signal


// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
    wire       HCLK;           // AHB system clock
    wire       HRESETn;        // AHB system reset
    wire       req_port0;       // Port 0 request signal
    wire       req_port2;       // Port 2 request signal
    wire       req_port3;       // Port 3 request signal
    wire       HREADYM;        // Transfer done
    wire       HSELM;          // Slave select line
    wire [1:0] HTRANSM;        // Transfer type
    wire       HMASTLOCKM;     // Locked transfer
    wire [1:0] addr_in_port;     // Port address input
    reg        no_port;         // No port selected signal


// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
    reg  [1:0] addr_in_port_next; // D-input of addr_in_port
    reg  [1:0] iaddr_in_port;    // Internal version of addr_in_port
    reg        no_port_next;     // D-input of no_port


// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Port Selection
//------------------------------------------------------------------------------
// The Output Arbitration function looks at all the requests to use the
//  output port and determines which is the highest priority request. This
//  version of the arbitration logic uses a fixed priority scheme where input
//  port 0 is the highest priority, input port 1 is the second highest
//  priority, etc.
// If none of the input ports are requesting then the current port will
//  remain active if it is performing IDLE transfers to the selected slave. If
//  this is not the case then the no_port signal will be asserted which
//  indicates that no input port should be selected.

  always @ (
             req_port0 or
             req_port2 or
             req_port3 or
             HSELM or HTRANSM or HMASTLOCKM or iaddr_in_port
           )

  begin : p_sel_port_comb
    // Default values are used for addr_in_port_next and no_port_next
    no_port_next     = 1'b0;
    addr_in_port_next = iaddr_in_port;

    if (HMASTLOCKM)
      addr_in_port_next = iaddr_in_port;
    else if ( req_port0 | ( (iaddr_in_port == 2'b00) & HSELM &
                            (HTRANSM != 2'b00) ) )
      addr_in_port_next = 2'b00;
    else if ( req_port2 | ( (iaddr_in_port == 2'b10) & HSELM &
                            (HTRANSM != 2'b00) ) )
      addr_in_port_next = 2'b10;
    else if ( req_port3 | ( (iaddr_in_port == 2'b11) & HSELM &
                            (HTRANSM != 2'b00) ) )
      addr_in_port_next = 2'b11;
    else if (HSELM)
      addr_in_port_next = iaddr_in_port;
    else
      no_port_next = 1'b1;
  end // block: p_sel_port_comb


  // Sequential process
  always @ (negedge HRESETn or posedge HCLK)
  begin : p_addr_in_port_reg
    if (~HRESETn)
      begin
        no_port      <= 1'b1;
        iaddr_in_port <= {2{1'b0}};
      end
    else
      if (HREADYM)
        begin
          no_port      <= no_port_next;
          iaddr_in_port <= addr_in_port_next;
        end
  end // block: p_addr_in_port_reg

  // Drive output with internal version
  assign addr_in_port = iaddr_in_port;


endmodule