From 881000d978d971992c60810ba70503e1be76144d Mon Sep 17 00:00:00 2001 From: shahzaibk23 Date: Thu, 29 Aug 2024 21:39:29 +0500 Subject: [PATCH 1/6] generalized DeviceAdapter --- src/main/scala/caravan/bus/common/Transaction.scala | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/scala/caravan/bus/common/Transaction.scala b/src/main/scala/caravan/bus/common/Transaction.scala index e23c808..68d1439 100644 --- a/src/main/scala/caravan/bus/common/Transaction.scala +++ b/src/main/scala/caravan/bus/common/Transaction.scala @@ -1,5 +1,7 @@ package caravan.bus.common import chisel3._ +import chisel3.util.DecoupledIO + /** * This abstract class provides a template for other protocols to implement the transaction wires. @@ -27,6 +29,11 @@ class BusDevice extends Bundle /** The HostAdapter and DeviceAdapter is a class from which each host/device adapter * of a specific bus protocol will extend (beneficial for switch) */ +abstract class DeviceAdapterIO extends Bundle +{ + val reqOut: DecoupledIO[AbstrRequest] + val rspIn : DecoupledIO[AbstrResponse] +} abstract class DeviceAdapter extends Module abstract class HostAdapter extends Module From e64229a416c3b986e4ce4501d2514231186ce8e2 Mon Sep 17 00:00:00 2001 From: shahzaibk23 Date: Thu, 29 Aug 2024 21:39:49 +0500 Subject: [PATCH 2/6] update TL and WB Device a/c to new abstraction --- .../caravan/bus/tilelink/TilelinkDevice.scala | 18 +++++++++++------- .../caravan/bus/wishbone/WishboneDevice.scala | 17 ++++++++++------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index b1c9fc1..83bc29d 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -1,16 +1,20 @@ package caravan.bus.tilelink -import caravan.bus.common.DeviceAdapter +import caravan.bus.common.{DeviceAdapter, DeviceAdapterIO} import chisel3._ import chisel3.stage.ChiselStage import chisel3.util._ import scala.math._ + +class TilelinkDeviceIO(implicit val config: TilelinkConfig) extends DeviceAdapterIO +{ + val tlSlaveTransmitter = Decoupled(new TilelinkSlave()) + val tlMasterReceiver = Flipped(Decoupled(new TilelinkMaster())) + val reqOut = Decoupled(new TLRequest()) + val rspIn = Flipped(Decoupled(new TLResponse())) +} + class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter with OpCodes{ - val io = IO(new Bundle { - val tlSlaveTransmitter = Decoupled(new TilelinkSlave()) - val tlMasterReceiver = Flipped(Decoupled(new TilelinkMaster())) - val reqOut = Decoupled(new TLRequest()) - val rspIn = Flipped(Decoupled(new TLResponse())) - }) + val io = IO(new TilelinkDeviceIO) /* NOTICE: This state logic is only for Atomic Operations idle : Address sent to memory to perform READ diff --git a/src/main/scala/caravan/bus/wishbone/WishboneDevice.scala b/src/main/scala/caravan/bus/wishbone/WishboneDevice.scala index d008370..2b3792d 100644 --- a/src/main/scala/caravan/bus/wishbone/WishboneDevice.scala +++ b/src/main/scala/caravan/bus/wishbone/WishboneDevice.scala @@ -1,16 +1,19 @@ package caravan.bus.wishbone -import caravan.bus.common.DeviceAdapter +import caravan.bus.common.{DeviceAdapter, DeviceAdapterIO} import chisel3._ import chisel3.stage.ChiselStage import chisel3.util.Decoupled +class WishboneDeviceIO(implicit val config: WishboneConfig) extends DeviceAdapterIO +{ + val wbSlaveTransmitter = Decoupled(new WishboneSlave()) + val wbMasterReceiver = Flipped(Decoupled(new WishboneMaster())) + val reqOut = Decoupled(new WBRequest()) + val rspIn = Flipped(Decoupled(new WBResponse())) +} + class WishboneDevice(implicit val config: WishboneConfig) extends DeviceAdapter { - val io = IO(new Bundle { - val wbSlaveTransmitter = Decoupled(new WishboneSlave()) - val wbMasterReceiver = Flipped(Decoupled(new WishboneMaster())) - val reqOut = Decoupled(new WBRequest()) - val rspIn = Flipped(Decoupled(new WBResponse())) - }) + val io = IO(new WishboneDeviceIO()) /** fire() is a handy function indicating whenever the master sends a valid request */ def fire(): Bool = io.wbMasterReceiver.valid && io.wbMasterReceiver.bits.cyc && io.wbMasterReceiver.bits.stb From 5622e10fd942b5936dbd7f7ec56db007474cc490 Mon Sep 17 00:00:00 2001 From: shahzaibk23 Date: Wed, 20 Nov 2024 21:19:21 +0000 Subject: [PATCH 3/6] updated signals to generic from tl prefix --- .../scala/caravan/bus/tilelink/Harness.scala | 4 +- .../bus/tilelink/TilelinkAdapter.scala | 27 +-- .../caravan/bus/tilelink/TilelinkDevice.scala | 162 +++++++++--------- .../caravan/bus/tilelink/TilelinkError.scala | 51 +++--- .../caravan/bus/tilelink/TilelinkHost.scala | 115 +++++++------ 5 files changed, 188 insertions(+), 171 deletions(-) diff --git a/src/main/scala/caravan/bus/tilelink/Harness.scala b/src/main/scala/caravan/bus/tilelink/Harness.scala index f6f0bd8..1228b6b 100644 --- a/src/main/scala/caravan/bus/tilelink/Harness.scala +++ b/src/main/scala/caravan/bus/tilelink/Harness.scala @@ -35,8 +35,8 @@ class TilelinkHarness/*(programFile: Option[String])*/(implicit val config: Tile tlHost.io.rspOut.ready := true.B // IP always ready to accept data from wb host - tlHost.io.tlMasterTransmitter <> tlSlave.io.tlMasterReceiver - tlSlave.io.tlSlaveTransmitter <> tlHost.io.tlSlaveReceiver + tlHost.io.masterTransmitter <> tlSlave.io.masterReceiver + tlSlave.io.slaveTransmitter <> tlHost.io.slaveReceiver //tlHost.io.reqIn.valid := Mux(tlHost.io.reqIn.ready, io.valid, false.B) tlHost.io.reqIn.valid := io.valid diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkAdapter.scala b/src/main/scala/caravan/bus/tilelink/TilelinkAdapter.scala index 8cfcbcb..3ed1325 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkAdapter.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkAdapter.scala @@ -3,26 +3,31 @@ package caravan.bus.tilelink import chisel3._ import chisel3.util._ -class TilelinkAdapter(implicit val config:TilelinkConfig) extends Module { - val io = IO(new Bundle{ +import caravan.bus.common._ - /* MASTER SIDE */ - val reqIn = Flipped(Decoupled(new TLRequest)) - val rspOut = Decoupled(new TLResponse) +class TilelinkAdapterIO(implicit val config:TilelinkConfig) extends BusAdapterIO{ - /* SLAVE SIDE */ - val reqOut = Decoupled(new TLRequest) - val rspIn = Flipped(Decoupled(new TLResponse)) - }) + /* MASTER SIDE */ + val reqIn = Flipped(Decoupled(new TLRequest)) + val rspOut = Decoupled(new TLResponse) + + /* SLAVE SIDE */ + val reqOut = Decoupled(new TLRequest) + val rspIn = Flipped(Decoupled(new TLResponse)) + +} + +class TilelinkAdapter(implicit val config:TilelinkConfig) extends BusAdapter { + val io = IO(new TilelinkAdapterIO) val tlHost = Module(new TilelinkHost) val tlSlave = Module(new TilelinkDevice) /* Connecting Master Interconnects */ - tlHost.io.tlMasterTransmitter <> tlSlave.io.tlMasterReceiver + tlHost.io.masterTransmitter <> tlSlave.io.masterReceiver /* Connecting Slave Interconnects */ - tlSlave.io.tlSlaveTransmitter <> tlHost.io.tlSlaveReceiver + tlSlave.io.slaveTransmitter <> tlHost.io.slaveReceiver /* Sending Request in Master */ tlHost.io.reqIn <> io.reqIn diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index 83bc29d..73c7bc6 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -7,8 +7,8 @@ import scala.math._ class TilelinkDeviceIO(implicit val config: TilelinkConfig) extends DeviceAdapterIO { - val tlSlaveTransmitter = Decoupled(new TilelinkSlave()) - val tlMasterReceiver = Flipped(Decoupled(new TilelinkMaster())) + val slaveTransmitter = Decoupled(new TilelinkSlave()) + val masterReceiver = Flipped(Decoupled(new TilelinkMaster())) val reqOut = Decoupled(new TLRequest()) val rspIn = Flipped(Decoupled(new TLResponse())) } @@ -30,7 +30,7 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter val counterD = RegInit(UInt(config.z.W),0.U) val opRegD = RegInit(NoOp.U) - io.tlMasterReceiver.ready := true.B + io.masterReceiver.ready := true.B io.rspIn.ready := false.B dontTouch(io.rspIn.ready) @@ -48,20 +48,20 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.reqOut.bits.isWrite := 0.U io.reqOut.valid := 0.U - io.tlSlaveTransmitter.bits.d_opcode := 0.U - io.tlSlaveTransmitter.bits.d_data := 0.U - io.tlSlaveTransmitter.bits.d_param := 0.U - io.tlSlaveTransmitter.bits.d_size := 0.U - io.tlSlaveTransmitter.bits.d_source := 0.U - io.tlSlaveTransmitter.bits.d_sink := 0.U - io.tlSlaveTransmitter.bits.d_denied := 0.U // d_denied pin is used for representing Mem error - io.tlSlaveTransmitter.bits.d_corrupt := 0.U - io.tlSlaveTransmitter.valid := 0.U + io.slaveTransmitter.bits.d_opcode := 0.U + io.slaveTransmitter.bits.d_data := 0.U + io.slaveTransmitter.bits.d_param := 0.U + io.slaveTransmitter.bits.d_size := 0.U + io.slaveTransmitter.bits.d_source := 0.U + io.slaveTransmitter.bits.d_sink := 0.U + io.slaveTransmitter.bits.d_denied := 0.U // d_denied pin is used for representing Mem error + io.slaveTransmitter.bits.d_corrupt := 0.U + io.slaveTransmitter.valid := 0.U when(counterD === 0.U){ - when(io.tlMasterReceiver.valid){ - opRegD := io.tlMasterReceiver.bits.a_opcode + when(io.masterReceiver.valid){ + opRegD := io.masterReceiver.bits.a_opcode }.otherwise{ opRegD := NoOp.U } @@ -71,25 +71,25 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter when(config.uh.asBool() && (opRegD === Arithmetic.U || opRegD === Logical.U )){ when(stateReg === idle){ - when(io.tlMasterReceiver.valid){ + when(io.masterReceiver.valid){ // Address for Atomic operations changes in Tilelink Device during Burst Operations - when(counterD > 0.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ + when(counterD > 0.U && ((1.U << io.masterReceiver.bits.a_size).asUInt() > config.w.U)){ io.reqOut.bits.addrRequest := addRegD + config.w.U addRegD := addRegD + config.w.U counterD := counterD - 1.U }.otherwise{ - io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address + io.reqOut.bits.addrRequest := io.masterReceiver.bits.a_address } - io.reqOut.bits.dataRequest := io.tlMasterReceiver.bits.a_data - io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask + io.reqOut.bits.dataRequest := io.masterReceiver.bits.a_data + io.reqOut.bits.activeByteLane := io.masterReceiver.bits.a_mask io.reqOut.bits.isWrite := false.B io.reqOut.valid := true.B io.rspIn.ready := true.B stateReg := uh - when(counterD === 0.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ - addRegD := io.tlMasterReceiver.bits.a_address - counterD := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() / config.w.U)- 1.U + when(counterD === 0.U && ((1.U << io.masterReceiver.bits.a_size).asUInt() > config.w.U)){ + addRegD := io.masterReceiver.bits.a_address + counterD := ((1.U << io.masterReceiver.bits.a_size).asUInt() / config.w.U)- 1.U } } } @@ -99,30 +99,30 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter when(io.rspIn.valid){ io.reqOut.bits.addrRequest := addRegD io.reqOut.bits.dataRequest := MuxCase(io.rspIn.bits.dataResponse, Array( - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U) -> MuxCase(io.rspIn.bits.dataResponse,Array( - (io.tlMasterReceiver.bits.a_param === 0.U)-> Mux(io.tlMasterReceiver.bits.a_data < io.rspIn.bits.dataResponse, - io.tlMasterReceiver.bits.a_data,io.rspIn.bits.dataResponse).asUInt, + (io.masterReceiver.bits.a_opcode === Arithmetic.U) -> MuxCase(io.rspIn.bits.dataResponse,Array( + (io.masterReceiver.bits.a_param === 0.U)-> Mux(io.masterReceiver.bits.a_data < io.rspIn.bits.dataResponse, + io.masterReceiver.bits.a_data,io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_param === 1.U)-> Mux(io.tlMasterReceiver.bits.a_data < io.rspIn.bits.dataResponse, - io.rspIn.bits.dataResponse,io.tlMasterReceiver.bits.a_data).asUInt, + (io.masterReceiver.bits.a_param === 1.U)-> Mux(io.masterReceiver.bits.a_data < io.rspIn.bits.dataResponse, + io.rspIn.bits.dataResponse,io.masterReceiver.bits.a_data).asUInt, - (io.tlMasterReceiver.bits.a_param === 2.U)-> Mux(io.tlMasterReceiver.bits.a_data < io.rspIn.bits.dataResponse, - io.tlMasterReceiver.bits.a_data,io.rspIn.bits.dataResponse), + (io.masterReceiver.bits.a_param === 2.U)-> Mux(io.masterReceiver.bits.a_data < io.rspIn.bits.dataResponse, + io.masterReceiver.bits.a_data,io.rspIn.bits.dataResponse), - (io.tlMasterReceiver.bits.a_param === 3.U)-> Mux(io.tlMasterReceiver.bits.a_data < io.rspIn.bits.dataResponse, - io.rspIn.bits.dataResponse,io.tlMasterReceiver.bits.a_data), + (io.masterReceiver.bits.a_param === 3.U)-> Mux(io.masterReceiver.bits.a_data < io.rspIn.bits.dataResponse, + io.rspIn.bits.dataResponse,io.masterReceiver.bits.a_data), - (io.tlMasterReceiver.bits.a_param === 4.U)-> (io.tlMasterReceiver.bits.a_data + io.rspIn.bits.dataResponse) + (io.masterReceiver.bits.a_param === 4.U)-> (io.masterReceiver.bits.a_data + io.rspIn.bits.dataResponse) )), - (io.tlMasterReceiver.bits.a_opcode === Logical.U) -> MuxCase(io.rspIn.bits.dataResponse,Array( - (io.tlMasterReceiver.bits.a_param === 0.U)-> (io.tlMasterReceiver.bits.a_data ^ io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_param === 1.U)-> (io.tlMasterReceiver.bits.a_data | io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_param === 2.U)-> (io.tlMasterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_param === 3.U)-> io.tlMasterReceiver.bits.a_data + (io.masterReceiver.bits.a_opcode === Logical.U) -> MuxCase(io.rspIn.bits.dataResponse,Array( + (io.masterReceiver.bits.a_param === 0.U)-> (io.masterReceiver.bits.a_data ^ io.rspIn.bits.dataResponse).asUInt, + (io.masterReceiver.bits.a_param === 1.U)-> (io.masterReceiver.bits.a_data | io.rspIn.bits.dataResponse).asUInt, + (io.masterReceiver.bits.a_param === 2.U)-> (io.masterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, + (io.masterReceiver.bits.a_param === 3.U)-> io.masterReceiver.bits.a_data )) )) - io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask + io.reqOut.bits.activeByteLane := io.masterReceiver.bits.a_mask io.reqOut.bits.isWrite := true.B io.reqOut.valid := true.B rspData := io.rspIn.bits.dataResponse @@ -137,16 +137,16 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter when(io.rspIn.valid){ io.rspIn.ready := false.B - io.tlSlaveTransmitter.bits.d_opcode := AccessAckData.U + io.slaveTransmitter.bits.d_opcode := AccessAckData.U - io.tlSlaveTransmitter.bits.d_data := rspData - io.tlSlaveTransmitter.bits.d_param := 0.U - io.tlSlaveTransmitter.bits.d_size := io.tlMasterReceiver.bits.a_size - io.tlSlaveTransmitter.bits.d_source := io.tlMasterReceiver.bits.a_source - io.tlSlaveTransmitter.bits.d_sink := 0.U - io.tlSlaveTransmitter.bits.d_denied := io.rspIn.bits.error // d_denied pin is used for representing Mem error - io.tlSlaveTransmitter.bits.d_corrupt := 0.U - io.tlSlaveTransmitter.valid := io.rspIn.valid + io.slaveTransmitter.bits.d_data := rspData + io.slaveTransmitter.bits.d_param := 0.U + io.slaveTransmitter.bits.d_size := io.masterReceiver.bits.a_size + io.slaveTransmitter.bits.d_source := io.masterReceiver.bits.a_source + io.slaveTransmitter.bits.d_sink := 0.U + io.slaveTransmitter.bits.d_denied := io.rspIn.bits.error // d_denied pin is used for representing Mem error + io.slaveTransmitter.bits.d_corrupt := 0.U + io.slaveTransmitter.valid := io.rspIn.valid stateReg := idle @@ -165,21 +165,21 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter } - .elsewhen(io.tlMasterReceiver.valid){ + .elsewhen(io.masterReceiver.valid){ - io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address - io.reqOut.bits.dataRequest := io.tlMasterReceiver.bits.a_data - io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask - io.reqOut.bits.isWrite := io.tlMasterReceiver.bits.a_opcode === PutFullData.U || io.tlMasterReceiver.bits.a_opcode === PutPartialData.U + io.reqOut.bits.addrRequest := io.masterReceiver.bits.a_address + io.reqOut.bits.dataRequest := io.masterReceiver.bits.a_data + io.reqOut.bits.activeByteLane := io.masterReceiver.bits.a_mask + io.reqOut.bits.isWrite := io.masterReceiver.bits.a_opcode === PutFullData.U || io.masterReceiver.bits.a_opcode === PutPartialData.U io.reqOut.valid := true.B io.rspIn.ready := true.B - when(((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U) && io.tlMasterReceiver.bits.a_opcode === Get.U){ - opRegD := io.tlMasterReceiver.bits.a_opcode - addRegD := io.tlMasterReceiver.bits.a_address - maskRegD := io.tlMasterReceiver.bits.a_mask - counterD := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt /config.w.U)-1.U + when(((1.U << io.masterReceiver.bits.a_size).asUInt() > config.w.U) && io.masterReceiver.bits.a_opcode === Get.U){ + opRegD := io.masterReceiver.bits.a_opcode + addRegD := io.masterReceiver.bits.a_address + maskRegD := io.masterReceiver.bits.a_mask + counterD := ((1.U << io.masterReceiver.bits.a_size).asUInt /config.w.U)-1.U } @@ -190,34 +190,34 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.rspIn.ready := false.B counterD := counterD -1.U - io.tlSlaveTransmitter.bits.d_opcode := 3.U - io.tlSlaveTransmitter.bits.d_data := 0.U - io.tlSlaveTransmitter.bits.d_param := 0.U - io.tlSlaveTransmitter.bits.d_size := 0.U - io.tlSlaveTransmitter.bits.d_source := 0.U - io.tlSlaveTransmitter.bits.d_sink := 0.U - io.tlSlaveTransmitter.bits.d_denied := 0.U // d_denied pin is used for representing Mem error - io.tlSlaveTransmitter.bits.d_corrupt := 0.U - io.tlSlaveTransmitter.valid := 0.U + io.slaveTransmitter.bits.d_opcode := 3.U + io.slaveTransmitter.bits.d_data := 0.U + io.slaveTransmitter.bits.d_param := 0.U + io.slaveTransmitter.bits.d_size := 0.U + io.slaveTransmitter.bits.d_source := 0.U + io.slaveTransmitter.bits.d_sink := 0.U + io.slaveTransmitter.bits.d_denied := 0.U // d_denied pin is used for representing Mem error + io.slaveTransmitter.bits.d_corrupt := 0.U + io.slaveTransmitter.valid := 0.U } .elsewhen(io.rspIn.valid){ - when(io.tlMasterReceiver.bits.a_opcode === Get.U){ - io.tlSlaveTransmitter.bits.d_opcode := AccessAck.U + when(io.masterReceiver.bits.a_opcode === Get.U){ + io.slaveTransmitter.bits.d_opcode := AccessAck.U }.otherwise{ - io.tlSlaveTransmitter.bits.d_opcode := AccessAckData.U} - io.tlSlaveTransmitter.bits.d_data := io.rspIn.bits.dataResponse - io.tlSlaveTransmitter.bits.d_param := 0.U - io.tlSlaveTransmitter.bits.d_size := io.tlMasterReceiver.bits.a_size - io.tlSlaveTransmitter.bits.d_source := io.tlMasterReceiver.bits.a_source - io.tlSlaveTransmitter.bits.d_sink := 0.U - io.tlSlaveTransmitter.bits.d_denied := io.rspIn.bits.error // d_denied pin is used for representing Mem error - io.tlSlaveTransmitter.bits.d_corrupt := 0.U - io.tlSlaveTransmitter.valid := io.rspIn.valid - - when(((1.U << io.tlMasterReceiver.bits.a_size).asUInt > config.w.U) && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ - counterD := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt /config.w.U)-1.U - opRegD := io.tlMasterReceiver.bits.a_opcode + io.slaveTransmitter.bits.d_opcode := AccessAckData.U} + io.slaveTransmitter.bits.d_data := io.rspIn.bits.dataResponse + io.slaveTransmitter.bits.d_param := 0.U + io.slaveTransmitter.bits.d_size := io.masterReceiver.bits.a_size + io.slaveTransmitter.bits.d_source := io.masterReceiver.bits.a_source + io.slaveTransmitter.bits.d_sink := 0.U + io.slaveTransmitter.bits.d_denied := io.rspIn.bits.error // d_denied pin is used for representing Mem error + io.slaveTransmitter.bits.d_corrupt := 0.U + io.slaveTransmitter.valid := io.rspIn.valid + + when(((1.U << io.masterReceiver.bits.a_size).asUInt > config.w.U) && io.masterReceiver.bits.a_opcode =/= Get.U){ + counterD := ((1.U << io.masterReceiver.bits.a_size).asUInt /config.w.U)-1.U + opRegD := io.masterReceiver.bits.a_opcode } io.rspIn.ready := false.B diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkError.scala b/src/main/scala/caravan/bus/tilelink/TilelinkError.scala index a7532f3..083f64a 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkError.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkError.scala @@ -2,38 +2,45 @@ package caravan.bus.tilelink import chisel3._ import chisel3.stage.ChiselStage import chisel3.util.{Decoupled, Fill} + +import caravan.bus.common.{ErrorDevice, ErrorDeviceIO} + // import caravan.bus.common.DeviceAdapter -abstract class TLErr extends Module -class TilelinkError(implicit val config: TilelinkConfig) extends TLErr { - val io = IO(new Bundle { - val tlSlaveTransmitter = Decoupled(new TilelinkSlave()) - val tlMasterReceiver = Flipped(Decoupled(new TilelinkMaster())) - }) - // def fire(): Bool = io.tlMasterReceiver.valid && io.tlMasterReceiver.bits.cyc && io.tlMasterReceiver.bits.stb +class TilelinkErrorIO(implicit val config: TilelinkConfig) extends ErrorDeviceIO{ + val slaveTransmitter = Decoupled(new TilelinkSlave()) + val masterReceiver = Flipped(Decoupled(new TilelinkMaster())) +} + + +// abstract class TLErr extends Module +class TilelinkError(implicit val config: TilelinkConfig) extends ErrorDevice { + val io = IO(new TilelinkErrorIO) + + // def fire(): Bool = io.masterReceiver.valid && io.masterReceiver.bits.cyc && io.masterReceiver.bits.stb val ackReg = RegInit(true.B) val dataReg = RegInit(0.U) val errReg = RegInit(false.B) val validReg = RegInit(false.B) - val opCodeReg = RegInit(Mux(io.tlMasterReceiver.bits.a_opcode === 4.U, 1.U, 0.U)) + val opCodeReg = RegInit(Mux(io.masterReceiver.bits.a_opcode === 4.U, 1.U, 0.U)) val paramReg = RegInit(0.U) - val sizeReg = RegInit(io.tlMasterReceiver.bits.a_size) + val sizeReg = RegInit(io.masterReceiver.bits.a_size) /** FIXME: Assuming tilelink slave is always ready to accept master req */ - io.tlMasterReceiver.ready := true.B + io.masterReceiver.ready := true.B - when(io.tlMasterReceiver.fire()) { + when(io.masterReceiver.fire()) { // a valid request from the host. The decoder pointed to us which means there was a wrong address given by the user // for writes we are going to ignore them completely. // for reads we are going to signal an err out and send all FFFs. errReg := true.B validReg := true.B - when(io.tlMasterReceiver.bits.a_opcode === 0.U || io.tlMasterReceiver.bits.a_opcode === 1.U) { + when(io.masterReceiver.bits.a_opcode === 0.U || io.masterReceiver.bits.a_opcode === 1.U) { // WRITE dataReg := DontCare - } .elsewhen(io.tlMasterReceiver.bits.a_opcode === 4.U) { + } .elsewhen(io.masterReceiver.bits.a_opcode === 4.U) { // READ dataReg := Fill((config.w * 8)/4, "hf".U) } @@ -45,16 +52,16 @@ class TilelinkError(implicit val config: TilelinkConfig) extends TLErr { validReg := false.B } - io.tlSlaveTransmitter.valid := validReg - io.tlSlaveTransmitter.bits.d_denied := errReg - io.tlSlaveTransmitter.bits.d_data := dataReg - io.tlSlaveTransmitter.bits.d_corrupt := errReg + io.slaveTransmitter.valid := validReg + io.slaveTransmitter.bits.d_denied := errReg + io.slaveTransmitter.bits.d_data := dataReg + io.slaveTransmitter.bits.d_corrupt := errReg - io.tlSlaveTransmitter.bits.d_opcode := opCodeReg - io.tlSlaveTransmitter.bits.d_param := paramReg - io.tlSlaveTransmitter.bits.d_size := sizeReg - io.tlSlaveTransmitter.bits.d_source := paramReg // TODO: Add dynamic logic for source - io.tlSlaveTransmitter.bits.d_sink := paramReg + io.slaveTransmitter.bits.d_opcode := opCodeReg + io.slaveTransmitter.bits.d_param := paramReg + io.slaveTransmitter.bits.d_size := sizeReg + io.slaveTransmitter.bits.d_source := paramReg // TODO: Add dynamic logic for source + io.slaveTransmitter.bits.d_sink := paramReg } diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala index 74ec51f..65045ba 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala @@ -1,16 +1,21 @@ package caravan.bus.tilelink -import caravan.bus.common.HostAdapter +import caravan.bus.common.{HostAdapter, HostAdapterIO} import chisel3._ import chisel3.experimental.DataMirror import chisel3.stage.ChiselStage import chisel3.util._ + +class TilelinkHostIO(implicit val config: TilelinkConfig) extends HostAdapterIO{ + val masterTransmitter = Decoupled(new TilelinkMaster()) + val slaveReceiver = Flipped(Decoupled(new TilelinkSlave())) + val reqIn = Flipped(Decoupled(new TLRequest())) + val rspOut = Decoupled(new TLResponse()) +} + class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with OpCodes { - val io = IO(new Bundle { - val tlMasterTransmitter = Decoupled(new TilelinkMaster()) - val tlSlaveReceiver = Flipped(Decoupled(new TilelinkSlave())) - val reqIn = Flipped(Decoupled(new TLRequest())) - val rspOut = Decoupled(new TLResponse()) - }) + val io = IO(new TilelinkHostIO) + + def getAddressPin: UInt = io.masterTransmitter.bits.a_address val opReg = RegInit(NoOp.U) @@ -22,18 +27,18 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with dontTouch(io.reqIn.valid) - io.tlSlaveReceiver.ready := false.B + io.slaveReceiver.ready := false.B io.reqIn.ready := true.B dontTouch(io.reqIn.ready) - io.tlMasterTransmitter.bits.a_opcode := 0.U - io.tlMasterTransmitter.bits.a_data := 0.U - io.tlMasterTransmitter.bits.a_address := addReg - io.tlMasterTransmitter.bits.a_param := 0.U - io.tlMasterTransmitter.bits.a_source := 0.U - io.tlMasterTransmitter.bits.a_size := 0.U - io.tlMasterTransmitter.bits.a_mask := 0.U - io.tlMasterTransmitter.bits.a_corrupt := 0.U - io.tlMasterTransmitter.valid := 0.U + io.masterTransmitter.bits.a_opcode := 0.U + io.masterTransmitter.bits.a_data := 0.U + io.masterTransmitter.bits.a_address := addReg + io.masterTransmitter.bits.a_param := 0.U + io.masterTransmitter.bits.a_source := 0.U + io.masterTransmitter.bits.a_size := 0.U + io.masterTransmitter.bits.a_mask := 0.U + io.masterTransmitter.bits.a_corrupt := 0.U + io.masterTransmitter.valid := 0.U io.rspOut.bits.dataResponse := 0.U io.rspOut.bits.error := 0.U io.rspOut.valid := false.B @@ -53,87 +58,87 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with when(io.reqIn.valid){ when(config.uh.asBool && counterHost > 0.U){ when(opReg =/= Get.U){ - io.tlMasterTransmitter.bits.a_opcode := opReg - io.tlMasterTransmitter.bits.a_param := paramReg - io.tlMasterTransmitter.bits.a_size := sizeReg - io.tlMasterTransmitter.bits.a_source := sourceReg + io.masterTransmitter.bits.a_opcode := opReg + io.masterTransmitter.bits.a_param := paramReg + io.masterTransmitter.bits.a_size := sizeReg + io.masterTransmitter.bits.a_source := sourceReg when(opReg =/= Arithmetic.U && opReg =/= Logical.U){ - io.tlMasterTransmitter.bits.a_address := addReg + config.w.U + io.masterTransmitter.bits.a_address := addReg + config.w.U addReg := addReg + config.w.U } .otherwise{ - io.tlMasterTransmitter.bits.a_address := addReg + io.masterTransmitter.bits.a_address := addReg } - io.tlMasterTransmitter.bits.a_data := io.reqIn.bits.dataRequest - io.tlMasterTransmitter.bits.a_mask := io.reqIn.bits.activeByteLane - io.tlMasterTransmitter.bits.a_corrupt := false.B - io.tlMasterTransmitter.valid := io.reqIn.valid + io.masterTransmitter.bits.a_data := io.reqIn.bits.dataRequest + io.masterTransmitter.bits.a_mask := io.reqIn.bits.activeByteLane + io.masterTransmitter.bits.a_corrupt := false.B + io.masterTransmitter.valid := io.reqIn.valid io.reqIn.ready := false.B counterHost := counterHost - 1.U - io.tlSlaveReceiver.ready := true.B + io.slaveReceiver.ready := true.B } .elsewhen(opReg === Get.U){ counterHost := counterHost - 1.U io.reqIn.ready := false.B - io.tlSlaveReceiver.ready := true.B + io.slaveReceiver.ready := true.B } }.otherwise{ if (config.uh){ - io.tlMasterTransmitter.bits.a_opcode := Mux1H(Cat(io.reqIn.bits.isIntent.get,io.reqIn.bits.isLogical.get,io.reqIn.bits.isArithmetic.get,~(io.reqIn.bits.isIntent.get | io.reqIn.bits.isLogical.get | io.reqIn.bits.isArithmetic.get)) + io.masterTransmitter.bits.a_opcode := Mux1H(Cat(io.reqIn.bits.isIntent.get,io.reqIn.bits.isLogical.get,io.reqIn.bits.isArithmetic.get,~(io.reqIn.bits.isIntent.get | io.reqIn.bits.isLogical.get | io.reqIn.bits.isArithmetic.get)) ,Seq(Mux(io.reqIn.bits.isWrite, Mux(io.reqIn.bits.activeByteLane === "b1111".U, PutFullData.U, PutPartialData.U) , Get.U),Arithmetic.U,Logical.U,Intent.U )) }else{ - io.tlMasterTransmitter.bits.a_opcode := Mux(io.reqIn.bits.isWrite, Mux(io.reqIn.bits.activeByteLane === "b1111".U, PutFullData.U, PutPartialData.U) , Get.U) + io.masterTransmitter.bits.a_opcode := Mux(io.reqIn.bits.isWrite, Mux(io.reqIn.bits.activeByteLane === "b1111".U, PutFullData.U, PutPartialData.U) , Get.U) } - io.tlMasterTransmitter.bits.a_data := io.reqIn.bits.dataRequest - io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest + io.masterTransmitter.bits.a_data := io.reqIn.bits.dataRequest + io.masterTransmitter.bits.a_address := io.reqIn.bits.addrRequest if (config.uh){ - io.tlMasterTransmitter.bits.a_param := io.reqIn.bits.param.get.asUInt + io.masterTransmitter.bits.a_param := io.reqIn.bits.param.get.asUInt }else{ - io.tlMasterTransmitter.bits.a_param := 0.U + io.masterTransmitter.bits.a_param := 0.U } - io.tlMasterTransmitter.bits.a_source := 2.U + io.masterTransmitter.bits.a_source := 2.U if(config.uh){ - io.tlMasterTransmitter.bits.a_size := io.reqIn.bits.size.get - when(((1.U << io.tlMasterTransmitter.bits.a_size).asUInt > config.w.U)){ - opReg := io.tlMasterTransmitter.bits.a_opcode - paramReg := io.tlMasterTransmitter.bits.a_param - sizeReg := io.tlMasterTransmitter.bits.a_size - sourceReg := io.tlMasterTransmitter.bits.a_source - when(io.tlMasterTransmitter.bits.a_opcode === Arithmetic.U || io.tlMasterTransmitter.bits.a_opcode === Logical.U){ - counterHost := 3.U * ((1.U << io.tlMasterTransmitter.bits.a_size.asUInt)/config.w.U).asUInt - 1.U + io.masterTransmitter.bits.a_size := io.reqIn.bits.size.get + when(((1.U << io.masterTransmitter.bits.a_size).asUInt > config.w.U)){ + opReg := io.masterTransmitter.bits.a_opcode + paramReg := io.masterTransmitter.bits.a_param + sizeReg := io.masterTransmitter.bits.a_size + sourceReg := io.masterTransmitter.bits.a_source + when(io.masterTransmitter.bits.a_opcode === Arithmetic.U || io.masterTransmitter.bits.a_opcode === Logical.U){ + counterHost := 3.U * ((1.U << io.masterTransmitter.bits.a_size.asUInt)/config.w.U).asUInt - 1.U } .otherwise{ - counterHost := ((1.U << io.tlMasterTransmitter.bits.a_size.asUInt)/config.w.U)-1.U + counterHost := ((1.U << io.masterTransmitter.bits.a_size.asUInt)/config.w.U)-1.U } } }else{ - io.tlMasterTransmitter.bits.a_size := MuxLookup(config.w.U, 2.U,Array( // default 32-bit + io.masterTransmitter.bits.a_size := MuxLookup(config.w.U, 2.U,Array( // default 32-bit (1.U) -> 0.U, (2.U) -> 1.U, (4.U) -> 2.U, (8.U) -> 3.U )) } - io.tlMasterTransmitter.bits.a_mask := io.reqIn.bits.activeByteLane - io.tlMasterTransmitter.bits.a_corrupt := false.B - io.tlMasterTransmitter.valid := io.reqIn.valid + io.masterTransmitter.bits.a_mask := io.reqIn.bits.activeByteLane + io.masterTransmitter.bits.a_corrupt := false.B + io.masterTransmitter.valid := io.reqIn.valid io.reqIn.ready := false.B - io.tlSlaveReceiver.ready := true.B + io.slaveReceiver.ready := true.B addReg := io.reqIn.bits.addrRequest } } - when(io.tlSlaveReceiver.valid){ + when(io.slaveReceiver.valid){ - io.rspOut.bits.dataResponse := io.tlSlaveReceiver.bits.d_data - io.rspOut.bits.error := io.tlSlaveReceiver.bits.d_denied + io.rspOut.bits.dataResponse := io.slaveReceiver.bits.d_data + io.rspOut.bits.error := io.slaveReceiver.bits.d_denied - io.rspOut.valid := io.tlSlaveReceiver.valid + io.rspOut.valid := io.slaveReceiver.valid - io.tlSlaveReceiver.ready := false.B + io.slaveReceiver.ready := false.B when(counterHost > 0.U){ io.reqIn.ready := false.B }.otherwise{ From 7d2a8a0f162489a60acda940e944fbe2ab0371f2 Mon Sep 17 00:00:00 2001 From: shahzaibk23 Date: Sat, 22 Mar 2025 15:40:56 +0000 Subject: [PATCH 4/6] generic abstract classes for host, dev, and error --- .../caravan/bus/common/Transaction.scala | 42 ++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/src/main/scala/caravan/bus/common/Transaction.scala b/src/main/scala/caravan/bus/common/Transaction.scala index 68d1439..101856d 100644 --- a/src/main/scala/caravan/bus/common/Transaction.scala +++ b/src/main/scala/caravan/bus/common/Transaction.scala @@ -33,9 +33,47 @@ abstract class DeviceAdapterIO extends Bundle { val reqOut: DecoupledIO[AbstrRequest] val rspIn : DecoupledIO[AbstrResponse] + val slaveTransmitter: DecoupledIO[BusDevice] + val masterReceiver: DecoupledIO[BusHost] +} +abstract class DeviceAdapter extends Module{ + val io: DeviceAdapterIO +} + +abstract class HostAdapterIO extends Bundle +{ + val reqIn: DecoupledIO[AbstrRequest] + val rspOut: DecoupledIO[AbstrResponse] + val masterTransmitter: DecoupledIO[BusHost] + val slaveReceiver: DecoupledIO[BusDevice] +} + +abstract class HostAdapter extends Module { + val io: HostAdapterIO + + def getAddressPin: UInt +} + +abstract class ErrorDeviceIO extends Bundle +{ + val slaveTransmitter: DecoupledIO[BusDevice] + val masterReceiver: DecoupledIO[BusHost] +} +abstract class ErrorDevice extends Module{ + val io: ErrorDeviceIO +} + +abstract class BusAdapterIO extends Bundle +{ + val reqIn: DecoupledIO[AbstrRequest] + val rspOut: DecoupledIO[AbstrResponse] + val reqOut: DecoupledIO[AbstrRequest] + val rspIn: DecoupledIO[AbstrResponse] +} +abstract class BusAdapter extends Module +{ + val io: BusAdapterIO } -abstract class DeviceAdapter extends Module -abstract class HostAdapter extends Module // created a trait so that each specific bus protocol // can extend from it (beneficial for type paremterization) From 2a1a5c1ace56a1f29ae464450c47d9c1daa5b2d3 Mon Sep 17 00:00:00 2001 From: shahzaibk23 Date: Sat, 22 Mar 2025 15:41:30 +0000 Subject: [PATCH 5/6] tl switch harness generalized masterTransmitter and slaveReceiver modified --- .../scala/caravan/bus/tilelink/SwitchHarness.scala | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/scala/caravan/bus/tilelink/SwitchHarness.scala b/src/main/scala/caravan/bus/tilelink/SwitchHarness.scala index cbb044e..04effd4 100644 --- a/src/main/scala/caravan/bus/tilelink/SwitchHarness.scala +++ b/src/main/scala/caravan/bus/tilelink/SwitchHarness.scala @@ -49,18 +49,18 @@ class SwitchHarness/*(programFile: Option[String])*/(implicit val config: Tileli host.io.reqIn.bits.activeByteLane := io.byteLane host.io.reqIn.bits.isWrite := io.isWrite - switch.io.hostIn <> host.io.tlMasterTransmitter - switch.io.hostOut <> host.io.tlSlaveReceiver + switch.io.hostIn <> host.io.masterTransmitter + switch.io.hostOut <> host.io.slaveReceiver for (i <- 0 until devices.size) { - switch.io.devIn(devices(i)._2.litValue().toInt) <> devices(i)._1.asInstanceOf[TilelinkDevice].io.tlSlaveTransmitter - switch.io.devOut(devices(i)._2.litValue().toInt) <> devices(i)._1.asInstanceOf[TilelinkDevice].io.tlMasterReceiver + switch.io.devIn(devices(i)._2.litValue().toInt) <> devices(i)._1.asInstanceOf[TilelinkDevice].io.slaveTransmitter + switch.io.devOut(devices(i)._2.litValue().toInt) <> devices(i)._1.asInstanceOf[TilelinkDevice].io.masterReceiver } - switch.io.devOut(devices.size) <> tlErr.io.tlMasterReceiver - switch.io.devIn(devices.size) <> tlErr.io.tlSlaveTransmitter + switch.io.devOut(devices.size) <> tlErr.io.masterReceiver + switch.io.devIn(devices.size) <> tlErr.io.slaveTransmitter - switch.io.devSel := BusDecoder.decode(host.io.tlMasterTransmitter.bits.a_address, addressMap) + switch.io.devSel := BusDecoder.decode(host.io.masterTransmitter.bits.a_address, addressMap) dccmDev.io.reqOut <> memCtrl.io.req dccmDev.io.rspIn <> memCtrl.io.rsp From e73bacdb61fceff70bbadb488a24b40d19439ec0 Mon Sep 17 00:00:00 2001 From: shahzaibk23 Date: Sat, 22 Mar 2025 15:42:07 +0000 Subject: [PATCH 6/6] removed wb prefix from master and slave signals --- .../scala/caravan/bus/wishbone/Harness.scala | 18 ++--- .../bus/wishbone/WishboneAdapter.scala | 25 ++++--- .../caravan/bus/wishbone/WishboneDevice.scala | 72 +++++++++---------- .../caravan/bus/wishbone/WishboneErr.scala | 27 +++---- .../caravan/bus/wishbone/WishboneHost.scala | 59 ++++++++------- 5 files changed, 106 insertions(+), 95 deletions(-) diff --git a/src/main/scala/caravan/bus/wishbone/Harness.scala b/src/main/scala/caravan/bus/wishbone/Harness.scala index 842a94c..7987e26 100644 --- a/src/main/scala/caravan/bus/wishbone/Harness.scala +++ b/src/main/scala/caravan/bus/wishbone/Harness.scala @@ -27,8 +27,8 @@ class WishboneHarness/*(programFile: Option[String])*/(implicit val config: Wish wbHost.io.rspOut.ready := true.B // IP always ready to accept data from wb host - wbHost.io.wbMasterTransmitter <> wbSlave.io.wbMasterReceiver - wbSlave.io.wbSlaveTransmitter <> wbHost.io.wbSlaveReceiver + wbHost.io.masterTransmitter <> wbSlave.io.masterReceiver + wbSlave.io.slaveTransmitter <> wbHost.io.slaveReceiver wbHost.io.reqIn.valid := Mux(wbHost.io.reqIn.ready, io.valid, false.B) wbHost.io.reqIn.bits.addrRequest := io.addrReq @@ -89,18 +89,18 @@ class SwitchHarness/*(programFile: Option[String])*/(implicit val config: Wishbo host.io.reqIn.bits.activeByteLane := io.byteLane host.io.reqIn.bits.isWrite := io.isWrite - switch.io.hostIn <> host.io.wbMasterTransmitter - switch.io.hostOut <> host.io.wbSlaveReceiver + switch.io.hostIn <> host.io.masterTransmitter + switch.io.hostOut <> host.io.slaveReceiver for (i <- 0 until devices.size) { - switch.io.devIn(devices(i)._2.litValue().toInt) <> devices(i)._1.asInstanceOf[WishboneDevice].io.wbSlaveTransmitter - switch.io.devOut(devices(i)._2.litValue().toInt) <> devices(i)._1.asInstanceOf[WishboneDevice].io.wbMasterReceiver + switch.io.devIn(devices(i)._2.litValue().toInt) <> devices(i)._1.asInstanceOf[WishboneDevice].io.slaveTransmitter + switch.io.devOut(devices(i)._2.litValue().toInt) <> devices(i)._1.asInstanceOf[WishboneDevice].io.masterReceiver } - switch.io.devOut(devices.size) <> wbErr.io.wbMasterReceiver - switch.io.devIn(devices.size) <> wbErr.io.wbSlaveTransmitter + switch.io.devOut(devices.size) <> wbErr.io.masterReceiver + switch.io.devIn(devices.size) <> wbErr.io.slaveTransmitter - switch.io.devSel := BusDecoder.decode(host.io.wbMasterTransmitter.bits.adr, addressMap) + switch.io.devSel := BusDecoder.decode(host.io.masterTransmitter.bits.adr, addressMap) dccmDev.io.reqOut <> memCtrl.io.req dccmDev.io.rspIn <> memCtrl.io.rsp diff --git a/src/main/scala/caravan/bus/wishbone/WishboneAdapter.scala b/src/main/scala/caravan/bus/wishbone/WishboneAdapter.scala index 08f7870..e2e6667 100644 --- a/src/main/scala/caravan/bus/wishbone/WishboneAdapter.scala +++ b/src/main/scala/caravan/bus/wishbone/WishboneAdapter.scala @@ -3,27 +3,30 @@ package caravan.bus.wishbone import chisel3._ import chisel3.util._ import caravan.bus.wishbone._ +import caravan.bus.common.{BusAdapter, BusAdapterIO} -class WishboneAdapter(implicit val config:WishboneConfig) extends Module { - val io = IO(new Bundle{ +class WishboneAdapterIO(implicit val config:WishboneConfig) extends BusAdapterIO{ - /* MASTER SIDE */ - val reqIn = Flipped(Decoupled(new WBRequest)) - val rspOut = Decoupled(new WBResponse) + /* MASTER SIDE */ + val reqIn = Flipped(Decoupled(new WBRequest)) + val rspOut = Decoupled(new WBResponse) - /* SLAVE SIDE */ - val reqOut = Decoupled(new WBRequest) - val rspIn = Flipped(Decoupled(new WBResponse)) - }) + /* SLAVE SIDE */ + val reqOut = Decoupled(new WBRequest) + val rspIn = Flipped(Decoupled(new WBResponse)) +} + +class WishboneAdapter(implicit val config:WishboneConfig) extends BusAdapter { + val io = IO(new WishboneAdapterIO) val wbHost = Module(new WishboneHost) val wbSlave = Module(new WishboneDevice) /* Connecting Master Interconnects */ - wbHost.io.wbMasterTransmitter <> wbSlave.io.wbMasterReceiver + wbHost.io.masterTransmitter <> wbSlave.io.masterReceiver /* Connecting Slave Interconnects */ - wbSlave.io.wbSlaveTransmitter <> wbHost.io.wbSlaveReceiver + wbSlave.io.slaveTransmitter <> wbHost.io.slaveReceiver /* Sending Request in Master */ wbHost.io.reqIn <> io.reqIn diff --git a/src/main/scala/caravan/bus/wishbone/WishboneDevice.scala b/src/main/scala/caravan/bus/wishbone/WishboneDevice.scala index 2b3792d..016af6b 100644 --- a/src/main/scala/caravan/bus/wishbone/WishboneDevice.scala +++ b/src/main/scala/caravan/bus/wishbone/WishboneDevice.scala @@ -6,8 +6,8 @@ import chisel3.util.Decoupled class WishboneDeviceIO(implicit val config: WishboneConfig) extends DeviceAdapterIO { - val wbSlaveTransmitter = Decoupled(new WishboneSlave()) - val wbMasterReceiver = Flipped(Decoupled(new WishboneMaster())) + val slaveTransmitter = Decoupled(new WishboneSlave()) + val masterReceiver = Flipped(Decoupled(new WishboneMaster())) val reqOut = Decoupled(new WBRequest()) val rspIn = Flipped(Decoupled(new WBResponse())) } @@ -16,20 +16,20 @@ class WishboneDevice(implicit val config: WishboneConfig) extends DeviceAdapter val io = IO(new WishboneDeviceIO()) /** fire() is a handy function indicating whenever the master sends a valid request */ - def fire(): Bool = io.wbMasterReceiver.valid && io.wbMasterReceiver.bits.cyc && io.wbMasterReceiver.bits.stb + def fire(): Bool = io.masterReceiver.valid && io.masterReceiver.bits.cyc && io.masterReceiver.bits.stb val ack = WireInit(false.B) /** FIXME: Assuming wishbone slave is always ready to accept master req */ - io.wbMasterReceiver.ready := true.B - dontTouch(io.wbMasterReceiver.ready) - dontTouch(io.wbSlaveTransmitter.ready) + io.masterReceiver.ready := true.B + dontTouch(io.masterReceiver.ready) + dontTouch(io.slaveTransmitter.ready) /** FIXME: Assuming wishbone slave is always ready to accept ip response data */ io.rspIn.ready := true.B when(fire()) { - when(!io.wbMasterReceiver.bits.we) { + when(!io.masterReceiver.bits.we) { // READ CYCLE - val addr = io.wbMasterReceiver.bits.adr - val activeByteLane = io.wbMasterReceiver.bits.sel + val addr = io.masterReceiver.bits.adr + val activeByteLane = io.masterReceiver.bits.sel /** FIXME: Assuming ip is always ready to accept wishbone slave's request */ io.reqOut.valid := true.B io.reqOut.bits.addrRequest := addr @@ -38,44 +38,44 @@ class WishboneDevice(implicit val config: WishboneConfig) extends DeviceAdapter io.reqOut.bits.isWrite := false.B when(io.rspIn.valid && !io.rspIn.bits.error) { /** FIXME: Assuming wishbone master is always ready to accept slave's data response */ - io.wbSlaveTransmitter.valid := true.B + io.slaveTransmitter.valid := true.B ack := true.B - io.wbSlaveTransmitter.bits.err := false.B - io.wbSlaveTransmitter.bits.dat := io.rspIn.bits.dataResponse + io.slaveTransmitter.bits.err := false.B + io.slaveTransmitter.bits.dat := io.rspIn.bits.dataResponse } .elsewhen(io.rspIn.valid && io.rspIn.bits.error) { - io.wbSlaveTransmitter.valid := true.B + io.slaveTransmitter.valid := true.B ack := false.B - io.wbSlaveTransmitter.bits.err := true.B - io.wbSlaveTransmitter.bits.dat := io.rspIn.bits.dataResponse + io.slaveTransmitter.bits.err := true.B + io.slaveTransmitter.bits.dat := io.rspIn.bits.dataResponse } .otherwise { - io.wbSlaveTransmitter.valid := false.B + io.slaveTransmitter.valid := false.B ack := false.B - io.wbSlaveTransmitter.bits.err := false.B - io.wbSlaveTransmitter.bits.dat := DontCare + io.slaveTransmitter.bits.err := false.B + io.slaveTransmitter.bits.dat := DontCare } } .otherwise { // WRITE CYCLE io.reqOut.valid := true.B - io.reqOut.bits.addrRequest := io.wbMasterReceiver.bits.adr - io.reqOut.bits.dataRequest := io.wbMasterReceiver.bits.dat - io.reqOut.bits.activeByteLane := io.wbMasterReceiver.bits.sel - io.reqOut.bits.isWrite := io.wbMasterReceiver.bits.we + io.reqOut.bits.addrRequest := io.masterReceiver.bits.adr + io.reqOut.bits.dataRequest := io.masterReceiver.bits.dat + io.reqOut.bits.activeByteLane := io.masterReceiver.bits.sel + io.reqOut.bits.isWrite := io.masterReceiver.bits.we when(io.rspIn.valid && !io.rspIn.bits.error) { - io.wbSlaveTransmitter.valid := true.B + io.slaveTransmitter.valid := true.B ack := true.B - io.wbSlaveTransmitter.bits.err := false.B - io.wbSlaveTransmitter.bits.dat := DontCare + io.slaveTransmitter.bits.err := false.B + io.slaveTransmitter.bits.dat := DontCare } .elsewhen(io.rspIn.valid && io.rspIn.bits.error) { - io.wbSlaveTransmitter.valid := true.B + io.slaveTransmitter.valid := true.B ack := false.B - io.wbSlaveTransmitter.bits.err := true.B - io.wbSlaveTransmitter.bits.dat := DontCare + io.slaveTransmitter.bits.err := true.B + io.slaveTransmitter.bits.dat := DontCare } .otherwise { - io.wbSlaveTransmitter.valid := false.B + io.slaveTransmitter.valid := false.B ack := false.B - io.wbSlaveTransmitter.bits.err := false.B - io.wbSlaveTransmitter.bits.err := false.B - io.wbSlaveTransmitter.bits.dat := DontCare + io.slaveTransmitter.bits.err := false.B + io.slaveTransmitter.bits.err := false.B + io.slaveTransmitter.bits.dat := DontCare } } @@ -87,13 +87,13 @@ class WishboneDevice(implicit val config: WishboneConfig) extends DeviceAdapter io.reqOut.bits.activeByteLane := DontCare io.reqOut.bits.isWrite := DontCare - io.wbSlaveTransmitter.valid := false.B + io.slaveTransmitter.valid := false.B ack := false.B - io.wbSlaveTransmitter.bits.err := false.B - io.wbSlaveTransmitter.bits.dat := DontCare + io.slaveTransmitter.bits.err := false.B + io.slaveTransmitter.bits.dat := DontCare } - io.wbSlaveTransmitter.bits.ack := ack + io.slaveTransmitter.bits.ack := ack /** * Rule 3.35: In standard mode, the cycle terminating signals ack_o, err_o and rty_o must be generated * in response to the logical AND of cyc_i and stb_i. diff --git a/src/main/scala/caravan/bus/wishbone/WishboneErr.scala b/src/main/scala/caravan/bus/wishbone/WishboneErr.scala index 1239b8c..c650125 100644 --- a/src/main/scala/caravan/bus/wishbone/WishboneErr.scala +++ b/src/main/scala/caravan/bus/wishbone/WishboneErr.scala @@ -2,21 +2,24 @@ package caravan.bus.wishbone import chisel3._ import chisel3.stage.ChiselStage import chisel3.util.{Decoupled, Fill} +import caravan.bus.common.{ErrorDevice, ErrorDeviceIO} -class WishboneErr(implicit val config: WishboneConfig) extends Module { - val io = IO(new Bundle { - val wbSlaveTransmitter = Decoupled(new WishboneSlave()) - val wbMasterReceiver = Flipped(Decoupled(new WishboneMaster())) - }) +class WishboneErrIO(implicit val config: WishboneConfig) extends ErrorDeviceIO { + val slaveTransmitter = Decoupled(new WishboneSlave()) + val masterReceiver = Flipped(Decoupled(new WishboneMaster())) +} + +class WishboneErr(implicit val config: WishboneConfig) extends ErrorDevice { + val io = IO(new WishboneErrIO) - def fire(): Bool = io.wbMasterReceiver.valid && io.wbMasterReceiver.bits.cyc && io.wbMasterReceiver.bits.stb + def fire(): Bool = io.masterReceiver.valid && io.masterReceiver.bits.cyc && io.masterReceiver.bits.stb val ackReg = RegInit(false.B) val dataReg = RegInit(0.U) val errReg = RegInit(false.B) val validReg = RegInit(false.B) /** FIXME: Assuming wishbone slave is always ready to accept master req */ - io.wbMasterReceiver.ready := true.B + io.masterReceiver.ready := true.B when(fire()) { // a valid request from the host. The decoder pointed to us which means there was a wrong address given by the user @@ -24,7 +27,7 @@ class WishboneErr(implicit val config: WishboneConfig) extends Module { // for reads we are going to signal an err out and send all FFFs. errReg := true.B validReg := true.B - when(io.wbMasterReceiver.bits.we) { + when(io.masterReceiver.bits.we) { // WRITE dataReg := DontCare } .otherwise { @@ -39,10 +42,10 @@ class WishboneErr(implicit val config: WishboneConfig) extends Module { validReg := false.B } - io.wbSlaveTransmitter.valid := validReg - io.wbSlaveTransmitter.bits.ack := ackReg - io.wbSlaveTransmitter.bits.dat := dataReg - io.wbSlaveTransmitter.bits.err := errReg + io.slaveTransmitter.valid := validReg + io.slaveTransmitter.bits.ack := ackReg + io.slaveTransmitter.bits.dat := dataReg + io.slaveTransmitter.bits.err := errReg } diff --git a/src/main/scala/caravan/bus/wishbone/WishboneHost.scala b/src/main/scala/caravan/bus/wishbone/WishboneHost.scala index a98eb77..6b3879b 100644 --- a/src/main/scala/caravan/bus/wishbone/WishboneHost.scala +++ b/src/main/scala/caravan/bus/wishbone/WishboneHost.scala @@ -1,31 +1,36 @@ package caravan.bus.wishbone -import caravan.bus.common.HostAdapter +import caravan.bus.common.{HostAdapter, HostAdapterIO} import chisel3._ import chisel3.experimental.DataMirror import chisel3.stage.ChiselStage import chisel3.util.{Decoupled, Enum, MuxCase} +class WishboneHostIO(implicit val config: WishboneConfig) extends HostAdapterIO { + val masterTransmitter = Decoupled(new WishboneMaster()) + val slaveReceiver = Flipped(Decoupled(new WishboneSlave())) + val reqIn = Flipped(Decoupled(new WBRequest())) + val rspOut = Decoupled(new WBResponse()) +} + // Support only for Single READ/WRITE cycles for now class WishboneHost(implicit val config: WishboneConfig) extends HostAdapter { - val io = IO(new Bundle { - val wbMasterTransmitter = Decoupled(new WishboneMaster()) - val wbSlaveReceiver = Flipped(Decoupled(new WishboneSlave())) - val reqIn = Flipped(Decoupled(new WBRequest())) - val rspOut = Decoupled(new WBResponse()) - }) - - def fire(): Bool = io.reqIn.valid && io.wbMasterTransmitter.ready + val io = IO(new WishboneHostIO) + + def getAddressPin: UInt = io.masterTransmitter.bits.adr + + + def fire(): Bool = io.reqIn.valid && io.masterTransmitter.ready /** * Since valid indicates a valid request, the stb signal from wishbone * also indicates the same. So stb and valid are connected together. */ - io.wbMasterTransmitter.valid := io.wbMasterTransmitter.bits.stb + io.masterTransmitter.valid := io.masterTransmitter.bits.stb /** FIXME: Assuming Master is always ready to accept data from Slave */ - io.wbSlaveReceiver.ready := true.B - dontTouch(io.wbMasterTransmitter.ready) - dontTouch(io.wbSlaveReceiver.ready) + io.slaveReceiver.ready := true.B + dontTouch(io.masterTransmitter.ready) + dontTouch(io.slaveReceiver.ready) when(reset.asBool() === true.B) { /** @@ -34,14 +39,14 @@ class WishboneHost(implicit val config: WishboneConfig) extends HostAdapter { * cyc_o * all other signals are in an undefined state */ - io.wbMasterTransmitter.bits.getElements.filter(w => DataMirror.directionOf(w) == ActualDirection.Output).map(_ := 0.U) + io.masterTransmitter.bits.getElements.filter(w => DataMirror.directionOf(w) == ActualDirection.Output).map(_ := 0.U) } val startWBTransaction = RegInit(false.B) // registers used to provide the response to the ip. val dataReg = RegInit(0.U(config.dataWidth.W)) val respReg = RegInit(false.B) val errReg = RegInit(false.B) - val ackReg = RegInit(io.wbSlaveReceiver.bits.ack) + val ackReg = RegInit(io.slaveReceiver.bits.ack) // new changes added here val stbReg = RegInit(false.B) val cycReg = RegInit(false.B) @@ -92,32 +97,32 @@ class WishboneHost(implicit val config: WishboneConfig) extends HostAdapter { selReg := io.reqIn.bits.activeByteLane } - io.wbMasterTransmitter.bits.stb := stbReg - io.wbMasterTransmitter.bits.cyc := cycReg - io.wbMasterTransmitter.bits.we := weReg - io.wbMasterTransmitter.bits.adr := adrReg - io.wbMasterTransmitter.bits.dat := datReg - io.wbMasterTransmitter.bits.sel := selReg + io.masterTransmitter.bits.stb := stbReg + io.masterTransmitter.bits.cyc := cycReg + io.masterTransmitter.bits.we := weReg + io.masterTransmitter.bits.adr := adrReg + io.masterTransmitter.bits.dat := datReg + io.masterTransmitter.bits.sel := selReg when(!startWBTransaction) { - io.wbMasterTransmitter.bits.getElements.filter(w => DataMirror.directionOf(w) == ActualDirection.Output).map(_ := 0.U) + io.masterTransmitter.bits.getElements.filter(w => DataMirror.directionOf(w) == ActualDirection.Output).map(_ := 0.U) } - when(io.wbSlaveReceiver.bits.ack && !io.wbSlaveReceiver.bits.err) { - dataReg := io.wbSlaveReceiver.bits.dat + when(io.slaveReceiver.bits.ack && !io.slaveReceiver.bits.err) { + dataReg := io.slaveReceiver.bits.dat respReg := true.B errReg := false.B // making the register false when ack received so that in the next cycle stb, cyc and other signals get low startWBTransaction := false.B - } .elsewhen(io.wbSlaveReceiver.bits.err && !io.wbSlaveReceiver.bits.ack) { - dataReg := io.wbSlaveReceiver.bits.dat + } .elsewhen(io.slaveReceiver.bits.err && !io.slaveReceiver.bits.ack) { + dataReg := io.slaveReceiver.bits.dat respReg := true.B errReg := true.B startWBTransaction := false.B } when(stateReg === idle) { - stateReg := Mux(io.wbSlaveReceiver.bits.ack || io.wbSlaveReceiver.bits.err, latch_data, idle) + stateReg := Mux(io.slaveReceiver.bits.ack || io.slaveReceiver.bits.err, latch_data, idle) } .elsewhen(stateReg === latch_data) { respReg := false.B stateReg := idle