blob: c8753865d30b2c06e20b03c46fa36bf94fa1c5e3 [file] [log] [blame]
// 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
}