// SPDX-FileCopyrightText: 2020 Muhammad Hadir Khan
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use 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.
// SPDX-License-Identifier: Apache-2.0
package merl.uit.tilelink

import chisel3._
import chisel3.util.{log2Ceil}

class TLSocket1_N(N: Int)(implicit val conf: TLConfiguration) extends Module {
  val io = IO(new Bundle {
    val tl_h_i = Flipped(new TL_H2D)
    val tl_h_o = new TL_D2H

    val tl_d_o = Vec(N, new TL_H2D)
    val tl_d_i = Flipped(Vec(N, new TL_D2H))

    val dev_sel = Input(UInt(log2Ceil(N+1).W))
  })

  // An intermediate bundle of wires for error responder
  // the tl_err_h_o takes the host input from tl_h_i and then will eventually send it to error responder
  val tl_err_h_o = Wire(new TL_H2D)
  // the tl_err_d_i takes the input from the error responder and sends it to the host output tl_h_o
  val tl_err_d_i = Wire(Flipped(new TL_D2H))

  // by default connecting the response with the error bundle
  // this would be connected with the correct device according to dev_sel
  // if dev_sel does not match any device than it will remain connected with this error bundle.
  io.tl_h_o <> tl_err_d_i

  for(i <- 0 until N) {
    io.tl_d_o(i).a_valid := io.tl_h_i.a_valid && (io.dev_sel === i.asUInt)
    io.tl_d_o(i).a_opcode := io.tl_h_i.a_opcode
    io.tl_d_o(i).a_param := io.tl_h_i.a_param
    io.tl_d_o(i).a_size := io.tl_h_i.a_size
    io.tl_d_o(i).a_source := io.tl_h_i.a_source
    io.tl_d_o(i).a_address := io.tl_h_i.a_address
    io.tl_d_o(i).a_mask := io.tl_h_i.a_mask
    io.tl_d_o(i).a_data := io.tl_h_i.a_data
    io.tl_d_o(i).d_ready := io.tl_h_i.d_ready

  }

  // looping over all the devices and seeing if dev_sel matches the device number
  for(id <- 0 until N) {
    // routing the ready signal of the device we are addressing with dev_sel
    // if dev_sel matches no devices then it means the dev_sel is out of range and
    // we connect it with the error responder device which will route an error
    when(io.dev_sel === id.asUInt) {
//      io.tl_h_o.a_ready := io.tl_h_i.a_valid && io.tl_d_i(id).a_ready
      io.tl_h_o.a_ready := io.tl_d_i(id).a_ready
      io.tl_h_o.d_valid := io.tl_d_i(id).d_valid
      io.tl_h_o.d_opcode := io.tl_d_i(id).d_opcode
      io.tl_h_o.d_param := io.tl_d_i(id).d_param
      io.tl_h_o.d_size := io.tl_d_i(id).d_size
      io.tl_h_o.d_source := io.tl_d_i(id).d_source
      io.tl_h_o.d_sink := io.tl_d_i(id).d_sink
      io.tl_h_o.d_data := io.tl_d_i(id).d_data
      io.tl_h_o.d_error := io.tl_d_i(id).d_error
    }
  }



  tl_err_h_o.a_valid := io.tl_h_i.a_valid && (io.dev_sel === N.asUInt)
  tl_err_h_o.a_opcode := io.tl_h_i.a_opcode
  tl_err_h_o.a_param := io.tl_h_i.a_param
  tl_err_h_o.a_size := io.tl_h_i.a_size
  tl_err_h_o.a_source := io.tl_h_i.a_source
  tl_err_h_o.a_address := io.tl_h_i.a_address
  tl_err_h_o.a_mask := io.tl_h_i.a_mask
  tl_err_h_o.a_data := io.tl_h_i.a_data
  tl_err_h_o.d_ready := io.tl_h_i.d_ready

  val tl_errResp = Module(new TL_ErrResp)
  tl_errResp.io.tl_h_i <> tl_err_h_o
  tl_err_d_i <> tl_errResp.io.tl_d_o
}
