From 7d601d3f909a91692e8ca78fb7516a14ec9a8807 Mon Sep 17 00:00:00 2001 From: siddiquimohsin Date: Sun, 16 Apr 2023 02:17:41 +0500 Subject: [PATCH 01/12] Data value cannot simultaneously write in arithmetic operation --- .../scala/caravan/bus/tilelink/Harness.scala | 12 ++- .../caravan/bus/tilelink/TilelinkBus.scala | 4 + .../caravan/bus/tilelink/TilelinkConfig.scala | 4 +- .../caravan/bus/tilelink/TilelinkDevice.scala | 78 ++++++++++++++++++- .../caravan/bus/tilelink/TilelinkHost.scala | 16 +++- .../bus/tilelink/TilelinkOpcodes.scala | 4 + src/test/scala/tilelink/HarnessTest.scala | 41 ++++++++++ 7 files changed, 151 insertions(+), 8 deletions(-) diff --git a/src/main/scala/caravan/bus/tilelink/Harness.scala b/src/main/scala/caravan/bus/tilelink/Harness.scala index 24d8fc1..6c15c24 100644 --- a/src/main/scala/caravan/bus/tilelink/Harness.scala +++ b/src/main/scala/caravan/bus/tilelink/Harness.scala @@ -14,6 +14,10 @@ class TilelinkHarness/*(programFile: Option[String])*/(implicit val config: Tile val dataReq = Input(UInt((config.w * 8).W)) val byteLane = Input(UInt(config.w.W)) val isWrite = Input(Bool()) + val is_arithmetic = if(config.uh) Some(Input(Bool())) else None + val is_logical = if(config.uh) Some(Input(Bool())) else None + val is_intent = if(config.uh) Some(Input(Bool())) else None + val param = if(config.uh) Some(Input(UInt(3.W))) else None val validResp = Output(Bool()) val dataResp = Output(UInt(32.W)) @@ -38,12 +42,18 @@ class TilelinkHarness/*(programFile: Option[String])*/(implicit val config: Tile tlHost.io.reqIn.bits.dataRequest := io.dataReq tlHost.io.reqIn.bits.activeByteLane := io.byteLane tlHost.io.reqIn.bits.isWrite := io.isWrite - + if (config.uh){ + tlHost.io.reqIn.bits.is_arithmetic.get := io.is_arithmetic.get + tlHost.io.reqIn.bits.is_logical.get := io.is_logical.get + tlHost.io.reqIn.bits.is_intent.get := io.is_intent.get + tlHost.io.reqIn.bits.param.get := io.param.get + } tlSlave.io.reqOut <> memCtrl.io.req tlSlave.io.rspIn <> memCtrl.io.rsp + io.dataResp := tlHost.io.rspOut.bits.dataResponse io.validResp := tlHost.io.rspOut.valid // io.ackResp := tlHost.io.rspOut.bits.ackWrite diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala b/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala index 7dd78d0..2b8170d 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala @@ -9,6 +9,10 @@ class TLRequest(implicit val config: TilelinkConfig) extends AbstrRequest { override val dataRequest: UInt = UInt((config.w * 8).W) override val activeByteLane: UInt = UInt(config.w.W) override val isWrite: Bool = Bool() + val is_arithmetic = if(config.uh) Some(Bool()) else None + val is_logical = if(config.uh) Some(Bool()) else None + val is_intent = if(config.uh) Some(Bool()) else None + val param = if(config.uh) Some(UInt(3.W)) else None } class TLResponse(implicit val config: TilelinkConfig) extends AbstrResponse { diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala b/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala index a651911..20cc97d 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala @@ -1,5 +1,4 @@ package caravan.bus.tilelink - import caravan.bus.common.BusConfig @@ -22,5 +21,8 @@ case class TilelinkConfig val o: Int = 8, val i: Int = 1, + // TL-UH + val uh : Boolean = true + ) extends BusConfig diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index 6e11755..00f3fef 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -3,7 +3,7 @@ import caravan.bus.common.DeviceAdapter import chisel3._ import chisel3.stage.ChiselStage import chisel3.util._ - +import scala.math._ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter with OpCodes { val io = IO(new Bundle { val tlSlaveTransmitter = Decoupled(new TilelinkSlave()) @@ -16,9 +16,16 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter //val idle :: wait_for_resp :: Nil = Enum(2) //val stateReg = RegInit(idle) + val rspData = RegInit(0.U) io.tlMasterReceiver.ready := true.B io.rspIn.ready := false.B + if (config.uh){ + io.reqOut.bits.is_arithmetic.get := false.B + io.reqOut.bits.is_logical.get := false.B + io.reqOut.bits.is_intent.get := false.B + io.reqOut.bits.param.get := 0.U + } io.reqOut.bits.addrRequest := 0.U io.reqOut.bits.dataRequest := 0.U @@ -52,15 +59,78 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.rspIn.ready := true.B } + + //when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ + // io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address + // io.reqOut.bits.dataRequest := MuxCase(io.tlMasterReceiver.bits.a_data, Array( + // (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 0.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, + // io.tlMasterReceiver.bits.a_data.asSInt,io.rspIn.bits.dataResponse.asSInt).asUInt, +// + // (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 1.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, + // io.rspIn.bits.dataResponse.asSInt,io.tlMasterReceiver.bits.a_data.asSInt).asUInt, +// + // (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 4.U) -> (io.tlMasterReceiver.bits.a_data.asUInt + io.rspIn.bits.dataResponse.asUInt).asUInt, + // (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 0.U) -> (io.tlMasterReceiver.bits.a_data ^ io.rspIn.bits.dataResponse).asUInt, + // (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 1.U) -> (io.tlMasterReceiver.bits.a_data | io.rspIn.bits.dataResponse).asUInt, + // (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 2.U) -> (io.tlMasterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, + // (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 3.U) -> io.tlMasterReceiver.bits.a_data + // )) + // io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask + // io.reqOut.bits.isWrite := true.B + // io.reqOut.valid := true.B + // io.rspIn.ready := true.B + // rspData := io.rspIn.bits.dataResponse +// + //} //}.elsewhen(stateReg === wait_for_resp){ // io.rspIn.ready := true.B when(io.rspIn.valid){ - - io.tlSlaveTransmitter.bits.d_opcode := AccessAckData.U - io.tlSlaveTransmitter.bits.d_data := io.rspIn.bits.dataResponse + when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ + io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address + io.reqOut.bits.dataRequest := MuxCase(io.tlMasterReceiver.bits.a_data, Array( + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 0.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, + io.tlMasterReceiver.bits.a_data.asSInt,io.rspIn.bits.dataResponse.asSInt).asUInt, + + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 1.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, + io.rspIn.bits.dataResponse.asSInt,io.tlMasterReceiver.bits.a_data.asSInt).asUInt, + + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 4.U) -> (io.tlMasterReceiver.bits.a_data.asUInt + io.rspIn.bits.dataResponse.asUInt).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 0.U) -> (io.tlMasterReceiver.bits.a_data ^ io.rspIn.bits.dataResponse).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 1.U) -> (io.tlMasterReceiver.bits.a_data | io.rspIn.bits.dataResponse).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 2.U) -> (io.tlMasterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 3.U) -> io.tlMasterReceiver.bits.a_data + )) + io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask + io.reqOut.bits.isWrite := true.B + io.reqOut.valid := true.B + rspData := io.rspIn.bits.dataResponse + } + + io.tlSlaveTransmitter.bits.d_opcode := MuxCase(0.U, Array( + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U || io.tlMasterReceiver.bits.a_opcode === PutPartialData.U + || io.tlMasterReceiver.bits.a_opcode === PutFullData.U) -> AccessAckData.U, + + (io.tlMasterReceiver.bits.a_opcode === Intent.U) -> HintAck.U, + (io.tlMasterReceiver.bits.a_opcode === Get.U) -> AccessAck.U + )) + io.tlSlaveTransmitter.bits.d_data := MuxCase(io.rspIn.bits.dataResponse, Array( + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U) -> 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 diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala index f2bb1fe..4dc97eb 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala @@ -59,11 +59,23 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with when(io.reqIn.valid){ + println("Request Valid Accepted") - io.tlMasterTransmitter.bits.a_opcode := Mux(io.reqIn.bits.isWrite, Mux(io.reqIn.bits.activeByteLane === "b1111".U, PutFullData.U, PutPartialData.U) , Get.U)/*, 2.U)*/ + if (config.uh){ + io.tlMasterTransmitter.bits.a_opcode := Mux1H(Cat(io.reqIn.bits.is_intent.get,io.reqIn.bits.is_logical.get,io.reqIn.bits.is_arithmetic.get,~(io.reqIn.bits.is_intent.get | io.reqIn.bits.is_logical.get | io.reqIn.bits.is_arithmetic.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.tlMasterTransmitter.bits.a_data := io.reqIn.bits.dataRequest io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest - io.tlMasterTransmitter.bits.a_param := 0.U + + if (config.uh){ + io.tlMasterTransmitter.bits.a_param := io.reqIn.bits.param.get.asUInt + }else{ + io.tlMasterTransmitter.bits.a_param := 0.U + } io.tlMasterTransmitter.bits.a_source := 2.U io.tlMasterTransmitter.bits.a_size := MuxLookup(config.w.U, 2.U,Array( // default 32-bit (1.U) -> 0.U, diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkOpcodes.scala b/src/main/scala/caravan/bus/tilelink/TilelinkOpcodes.scala index 05ee70a..a63604c 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkOpcodes.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkOpcodes.scala @@ -6,4 +6,8 @@ trait OpCodes { val PutFullData = 0 val PutPartialData = 1 val AccessAck = 0 + val Arithmetic = 2 + val Logical = 3 + val Intent = 5 + val HintAck = 2 } \ No newline at end of file diff --git a/src/test/scala/tilelink/HarnessTest.scala b/src/test/scala/tilelink/HarnessTest.scala index fb60645..a76cab2 100644 --- a/src/test/scala/tilelink/HarnessTest.scala +++ b/src/test/scala/tilelink/HarnessTest.scala @@ -20,6 +20,12 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.valid.poke(true.B) c.io.addrReq.poke(8.U) c.io.dataReq.poke(24.U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) c.clock.step(1) @@ -30,13 +36,36 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.clock.step(1) } println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + println("Got the response now try arithmetic data") + c.clock.step(2) + c.io.valid.poke(true.B) + c.io.addrReq.poke(8.U) + c.io.dataReq.poke(9.U) + c.io.isWrite.poke(false.B) + c.io.byteLane.poke("b1111".U) + if(config.uh){ + c.io.is_arithmetic.get.poke(true.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + c.clock.step(1) + c.io.valid.poke(false.B) + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) println("Got the response now reading expected data") c.clock.step(2) c.io.dataReq.poke(0.U) c.io.isWrite.poke(false.B) c.io.valid.poke(true.B) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } c.clock.step(1) c.io.valid.poke(false.B) + c.clock.step(2) c.io.dataResp.expect(24.U) println("EXPECTED DATA IS: 24 GOT " + c.io.dataResp.peek().litValue().toInt.toString) } @@ -49,6 +78,12 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.valid.poke(true.B) c.io.addrReq.poke(8.U) c.io.dataReq.poke(0.U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } c.io.dataReq.poke("habcdef0f".U) c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) @@ -88,6 +123,12 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.valid.poke(true.B) c.io.addrReq.poke(8.U) c.io.dataReq.poke("habcdefbf".U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) c.clock.step(1) From f19b49a734c8eb0b5b41399d5284af82302bd482 Mon Sep 17 00:00:00 2001 From: siddiquimohsin Date: Mon, 17 Apr 2023 23:55:52 +0500 Subject: [PATCH 02/12] Converted data register into wire in Dummy Memory Controller but the Harness Test still failed --- .../caravan/bus/common/DummyMemory.scala | 2 +- .../scala/caravan/bus/tilelink/Harness.scala | 2 +- .../caravan/bus/tilelink/TilelinkDevice.scala | 62 +++++-------------- src/test/scala/tilelink/HarnessTest.scala | 10 +-- 4 files changed, 24 insertions(+), 52 deletions(-) diff --git a/src/main/scala/caravan/bus/common/DummyMemory.scala b/src/main/scala/caravan/bus/common/DummyMemory.scala index 49b9420..fb56f14 100644 --- a/src/main/scala/caravan/bus/common/DummyMemory.scala +++ b/src/main/scala/caravan/bus/common/DummyMemory.scala @@ -31,7 +31,7 @@ class DummyMemController/*(programFile: Option[String])*/(implicit val config: B // holds the data in byte vectors read from memory val rData = Reg(Vec(4,UInt(8.W))) // holds the bytes that must be read according to the activeByteLane - val data = Reg(Vec(4,UInt(8.W))) + val data = Wire(Vec(4,UInt(8.W))) when(io.req.fire() && io.req.bits.isWrite){ diff --git a/src/main/scala/caravan/bus/tilelink/Harness.scala b/src/main/scala/caravan/bus/tilelink/Harness.scala index 6c15c24..958d982 100644 --- a/src/main/scala/caravan/bus/tilelink/Harness.scala +++ b/src/main/scala/caravan/bus/tilelink/Harness.scala @@ -39,7 +39,7 @@ class TilelinkHarness/*(programFile: Option[String])*/(implicit val config: Tile //tlHost.io.reqIn.valid := Mux(tlHost.io.reqIn.ready, io.valid, false.B) tlHost.io.reqIn.valid := io.valid tlHost.io.reqIn.bits.addrRequest := io.addrReq - tlHost.io.reqIn.bits.dataRequest := io.dataReq + tlHost.io.reqIn.bits.dataRequest := io.dataReq.asUInt tlHost.io.reqIn.bits.activeByteLane := io.byteLane tlHost.io.reqIn.bits.isWrite := io.isWrite if (config.uh){ diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index 00f3fef..3241828 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -16,7 +16,6 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter //val idle :: wait_for_resp :: Nil = Enum(2) //val stateReg = RegInit(idle) - val rspData = RegInit(0.U) io.tlMasterReceiver.ready := true.B io.rspIn.ready := false.B @@ -60,43 +59,9 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter } - //when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ - // io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address - // io.reqOut.bits.dataRequest := MuxCase(io.tlMasterReceiver.bits.a_data, Array( - // (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 0.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, - // io.tlMasterReceiver.bits.a_data.asSInt,io.rspIn.bits.dataResponse.asSInt).asUInt, -// - // (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 1.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, - // io.rspIn.bits.dataResponse.asSInt,io.tlMasterReceiver.bits.a_data.asSInt).asUInt, -// - // (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 4.U) -> (io.tlMasterReceiver.bits.a_data.asUInt + io.rspIn.bits.dataResponse.asUInt).asUInt, - // (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 0.U) -> (io.tlMasterReceiver.bits.a_data ^ io.rspIn.bits.dataResponse).asUInt, - // (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 1.U) -> (io.tlMasterReceiver.bits.a_data | io.rspIn.bits.dataResponse).asUInt, - // (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 2.U) -> (io.tlMasterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, - // (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 3.U) -> io.tlMasterReceiver.bits.a_data - // )) - // io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask - // io.reqOut.bits.isWrite := true.B - // io.reqOut.valid := true.B - // io.rspIn.ready := true.B - // rspData := io.rspIn.bits.dataResponse -// - //} - - //}.elsewhen(stateReg === wait_for_resp){ - - // io.rspIn.ready := true.B - - when(io.rspIn.valid){ - when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ - io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address - io.reqOut.bits.dataRequest := MuxCase(io.tlMasterReceiver.bits.a_data, Array( + when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ + io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address + io.reqOut.bits.dataRequest := MuxCase(io.tlMasterReceiver.bits.a_data, Array( (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 0.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, io.tlMasterReceiver.bits.a_data.asSInt,io.rspIn.bits.dataResponse.asSInt).asUInt, @@ -115,11 +80,18 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 2.U) -> (io.tlMasterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 3.U) -> io.tlMasterReceiver.bits.a_data )) - io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask - io.reqOut.bits.isWrite := true.B - io.reqOut.valid := true.B - rspData := io.rspIn.bits.dataResponse - } + io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask + io.reqOut.bits.isWrite := true.B + io.reqOut.valid := true.B + io.rspIn.ready := true.B + + } + + //}.elsewhen(stateReg === wait_for_resp){ + + // io.rspIn.ready := true.B + + when(io.rspIn.valid){ io.tlSlaveTransmitter.bits.d_opcode := MuxCase(0.U, Array( (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U || io.tlMasterReceiver.bits.a_opcode === PutPartialData.U @@ -128,9 +100,9 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter (io.tlMasterReceiver.bits.a_opcode === Intent.U) -> HintAck.U, (io.tlMasterReceiver.bits.a_opcode === Get.U) -> AccessAck.U )) - io.tlSlaveTransmitter.bits.d_data := MuxCase(io.rspIn.bits.dataResponse, Array( + io.tlSlaveTransmitter.bits.d_data := Mux(io.tlMasterReceiver.bits.a_opcode === PutFullData.U || io.tlMasterReceiver.bits.a_opcode === PutPartialData.U ,0.U,io.rspIn.bits.dataResponse)/*MuxCase(io.rspIn.bits.dataResponse, Array( (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U) -> 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 diff --git a/src/test/scala/tilelink/HarnessTest.scala b/src/test/scala/tilelink/HarnessTest.scala index a76cab2..0cae1fb 100644 --- a/src/test/scala/tilelink/HarnessTest.scala +++ b/src/test/scala/tilelink/HarnessTest.scala @@ -40,14 +40,14 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.clock.step(2) c.io.valid.poke(true.B) c.io.addrReq.poke(8.U) - c.io.dataReq.poke(9.U) + c.io.dataReq.poke(48.U) c.io.isWrite.poke(false.B) c.io.byteLane.poke("b1111".U) if(config.uh){ - c.io.is_arithmetic.get.poke(true.B) - c.io.is_logical.get.poke(false.B) + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(true.B) c.io.is_intent.get.poke(false.B) - c.io.param.get.poke(0.U) + c.io.param.get.poke(1.U) } c.clock.step(1) c.io.valid.poke(false.B) @@ -65,7 +65,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil } c.clock.step(1) c.io.valid.poke(false.B) - c.clock.step(2) + c.clock.step(1) c.io.dataResp.expect(24.U) println("EXPECTED DATA IS: 24 GOT " + c.io.dataResp.peek().litValue().toInt.toString) } From 0addc2ad369c6472561c6115d6142596300f4a2b Mon Sep 17 00:00:00 2001 From: siddiquimohsin Date: Fri, 21 Apr 2023 01:29:32 +0500 Subject: [PATCH 03/12] Create state logic only for TL-UH and write one test 'should write and read full word with TL-UH' for testing purpose. All tests are passed --- .../caravan/bus/common/DummyMemory.scala | 64 +++++++++ .../scala/caravan/bus/tilelink/Harness.scala | 4 +- .../caravan/bus/tilelink/TilelinkDevice.scala | 128 +++++++++++------- src/test/scala/tilelink/HarnessTest.scala | 100 +++++++++----- 4 files changed, 215 insertions(+), 81 deletions(-) diff --git a/src/main/scala/caravan/bus/common/DummyMemory.scala b/src/main/scala/caravan/bus/common/DummyMemory.scala index fb56f14..6bb7932 100644 --- a/src/main/scala/caravan/bus/common/DummyMemory.scala +++ b/src/main/scala/caravan/bus/common/DummyMemory.scala @@ -65,4 +65,68 @@ class DummyMemController/*(programFile: Option[String])*/(implicit val config: B +} +class BlockRamWithMasking[A <: AbstrRequest, B <: AbstrResponse] + (gen: A, gen1: B, rows: Int) extends Module { + + + val io = IO(new Bundle { + val req = Flipped(Decoupled(gen)) + val rsp = Decoupled(gen1) + }) + + // holds the data in byte vectors to be written in memory + val wdata = Wire(Vec(4, UInt(8.W))) + // holds the data in byte vectors read from memory + val rdata = Wire(Vec(4, UInt(8.W))) + // holds the mask signals to be used for byte masking in memory + val mask = Wire(Vec(4, Bool())) + // holds the bytes that must be read according to the activeByteLane + val data = Wire(Vec(4, UInt(8.W))) + + wdata(0) := io.req.bits.dataRequest(7,0) + wdata(1) := io.req.bits.dataRequest(15,8) + wdata(2) := io.req.bits.dataRequest(23,16) + wdata(3) := io.req.bits.dataRequest(31,24) + + + // connecting the mask bits with activeByteLane bits + val byteLane = io.req.bits.activeByteLane.asBools() + mask zip byteLane map {case(m, b) => + m := b + } + + + // the register that sends valid along with the data read from memory + // a register is used so that it synchronizes along with the data that comes after one cycle + val validReg = RegInit(false.B) + io.rsp.valid := validReg + io.rsp.bits.error := false.B // assuming memory controller would never return an error + io.req.ready := true.B // assuming we are always ready to accept requests from device + + val mem = SyncReadMem(rows, Vec(4, UInt((32/4).W))) + + when(io.req.fire() && !io.req.bits.isWrite) { + // READ + rdata := mem.read(io.req.bits.addrRequest/4.U) + validReg := true.B + } .elsewhen(io.req.fire() && io.req.bits.isWrite) { + // WRITE + mem.write(io.req.bits.addrRequest/4.U, wdata, mask) + validReg := true.B + rdata map (_ := DontCare) + } .otherwise { + validReg := false.B + rdata map (_ := DontCare) + } + + /** return only those bytes which are enabled by mask + * else return 0s*/ + data := mask zip rdata map {case (b: Bool, i: UInt) => + Mux(b === true.B, i, 0.U) + } + + io.rsp.bits.dataResponse := Cat(data(3), data(2) ,data(1), data(0)) + + } \ No newline at end of file diff --git a/src/main/scala/caravan/bus/tilelink/Harness.scala b/src/main/scala/caravan/bus/tilelink/Harness.scala index 958d982..0b930d8 100644 --- a/src/main/scala/caravan/bus/tilelink/Harness.scala +++ b/src/main/scala/caravan/bus/tilelink/Harness.scala @@ -1,5 +1,5 @@ package caravan.bus.tilelink -import caravan.bus.common.{AddressMap, BusDecoder, DeviceAdapter, Switch1toN, DummyMemController} +import caravan.bus.common.{AddressMap, BusDecoder, DeviceAdapter, Switch1toN, DummyMemController,BlockRamWithMasking} import chisel3._ import chisel3.experimental.ChiselEnum import chisel3.stage.ChiselStage @@ -29,7 +29,7 @@ class TilelinkHarness/*(programFile: Option[String])*/(implicit val config: Tile val tlHost = Module(new TilelinkHost()) val tlSlave = Module(new TilelinkDevice()) - val memCtrl = Module(new DummyMemController()) + val memCtrl = Module(new BlockRamWithMasking(new TLRequest(),new TLResponse(),1024)) tlHost.io.rspOut.ready := true.B // IP always ready to accept data from wb host diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index 3241828..932b766 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -4,17 +4,16 @@ import chisel3._ import chisel3.stage.ChiselStage import chisel3.util._ import scala.math._ -class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter with OpCodes { +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 idle :: wait_for_resp :: Nil = Enum(2) - //val stateReg = RegInit(idle) + val idle :: uh :: wait_for_resp :: Nil = Enum(3) + val stateReg = RegInit(idle) + val rspData = RegInit(0.U) io.tlMasterReceiver.ready := true.B io.rspIn.ready := false.B @@ -24,7 +23,7 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.reqOut.bits.is_logical.get := false.B io.reqOut.bits.is_intent.get := false.B io.reqOut.bits.param.get := 0.U - } + } io.reqOut.bits.addrRequest := 0.U io.reqOut.bits.dataRequest := 0.U @@ -44,46 +43,90 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter // val stall = Module(new stallUnit) - //when(stateReg === idle){ + when(stateReg =/= idle){ + stateReg := idle + } + when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ + //val idle :: wait_for_resp :: Nil = Enum(2) + //val stateReg = RegInit(idle) + when(stateReg === idle){ when(io.tlMasterReceiver.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.isWrite := false.B io.reqOut.valid := true.B + stateReg := uh + } + } + .elsewhen(stateReg === uh){ + io.reqOut.valid := false.B + io.rspIn.ready := true.B + when(io.rspIn.valid){ + io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address + io.reqOut.bits.dataRequest := MuxCase(io.tlMasterReceiver.bits.a_data, Array( + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 0.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, + io.tlMasterReceiver.bits.a_data.asSInt,io.rspIn.bits.dataResponse.asSInt).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 1.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, + io.rspIn.bits.dataResponse.asSInt,io.tlMasterReceiver.bits.a_data.asSInt).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 4.U) -> (io.tlMasterReceiver.bits.a_data.asUInt + io.rspIn.bits.dataResponse.asUInt).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 0.U) -> (io.tlMasterReceiver.bits.a_data ^ io.rspIn.bits.dataResponse).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 1.U) -> (io.tlMasterReceiver.bits.a_data | io.rspIn.bits.dataResponse).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 2.U) -> (io.tlMasterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 3.U) -> io.tlMasterReceiver.bits.a_data + )) + io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask + io.reqOut.bits.isWrite := true.B + io.reqOut.valid := true.B + rspData := io.rspIn.bits.dataResponse + stateReg := wait_for_resp + } + } - //stateReg := wait_for_resp + .elsewhen(stateReg === wait_for_resp){ io.rspIn.ready := true.B + io.reqOut.valid := false.B + + when(io.rspIn.valid){ + io.rspIn.ready := false.B + + io.tlSlaveTransmitter.bits.d_opcode := MuxCase(0.U, Array( + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U + ) -> AccessAckData.U, + (io.tlMasterReceiver.bits.a_opcode === Intent.U) -> HintAck.U, + )) + io.tlSlaveTransmitter.bits.d_data := MuxCase(io.rspIn.bits.dataResponse, Array( + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U) -> 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 + + stateReg := idle + + } + } + + }.otherwise{ + when(io.tlMasterReceiver.valid){ - } - - when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address - io.reqOut.bits.dataRequest := MuxCase(io.tlMasterReceiver.bits.a_data, Array( - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 0.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, - io.tlMasterReceiver.bits.a_data.asSInt,io.rspIn.bits.dataResponse.asSInt).asUInt, - - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 1.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, - io.rspIn.bits.dataResponse.asSInt,io.tlMasterReceiver.bits.a_data.asSInt).asUInt, - - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 4.U) -> (io.tlMasterReceiver.bits.a_data.asUInt + io.rspIn.bits.dataResponse.asUInt).asUInt, - (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 0.U) -> (io.tlMasterReceiver.bits.a_data ^ io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 1.U) -> (io.tlMasterReceiver.bits.a_data | io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 2.U) -> (io.tlMasterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 3.U) -> io.tlMasterReceiver.bits.a_data - )) + io.reqOut.bits.dataRequest := io.tlMasterReceiver.bits.a_data io.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask - io.reqOut.bits.isWrite := true.B + io.reqOut.bits.isWrite := io.tlMasterReceiver.bits.a_opcode === PutFullData.U || io.tlMasterReceiver.bits.a_opcode === PutPartialData.U io.reqOut.valid := true.B - io.rspIn.ready := true.B + + //stateReg := wait_for_resp + io.rspIn.ready := true.B } @@ -93,16 +136,8 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter when(io.rspIn.valid){ - io.tlSlaveTransmitter.bits.d_opcode := MuxCase(0.U, Array( - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U || io.tlMasterReceiver.bits.a_opcode === PutPartialData.U - || io.tlMasterReceiver.bits.a_opcode === PutFullData.U) -> AccessAckData.U, - - (io.tlMasterReceiver.bits.a_opcode === Intent.U) -> HintAck.U, - (io.tlMasterReceiver.bits.a_opcode === Get.U) -> AccessAck.U - )) - io.tlSlaveTransmitter.bits.d_data := Mux(io.tlMasterReceiver.bits.a_opcode === PutFullData.U || io.tlMasterReceiver.bits.a_opcode === PutPartialData.U ,0.U,io.rspIn.bits.dataResponse)/*MuxCase(io.rspIn.bits.dataResponse, Array( - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U) -> rspData - ))*/ + 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 @@ -110,16 +145,15 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter 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.reqOut.valid := false.B //stateReg := idle io.rspIn.ready := false.B } - //} - + } + // Sending Response coming from Memory in the STALL to delay the response one cycle - } \ No newline at end of file diff --git a/src/test/scala/tilelink/HarnessTest.scala b/src/test/scala/tilelink/HarnessTest.scala index 0cae1fb..92ba791 100644 --- a/src/test/scala/tilelink/HarnessTest.scala +++ b/src/test/scala/tilelink/HarnessTest.scala @@ -20,12 +20,6 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.valid.poke(true.B) c.io.addrReq.poke(8.U) c.io.dataReq.poke(24.U) - if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) - c.io.param.get.poke(0.U) - } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) c.clock.step(1) @@ -36,36 +30,13 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.clock.step(1) } println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) - println("Got the response now try arithmetic data") - c.clock.step(2) - c.io.valid.poke(true.B) - c.io.addrReq.poke(8.U) - c.io.dataReq.poke(48.U) - c.io.isWrite.poke(false.B) - c.io.byteLane.poke("b1111".U) - if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(true.B) - c.io.is_intent.get.poke(false.B) - c.io.param.get.poke(1.U) - } - c.clock.step(1) - c.io.valid.poke(false.B) - println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) println("Got the response now reading expected data") c.clock.step(2) c.io.dataReq.poke(0.U) c.io.isWrite.poke(false.B) c.io.valid.poke(true.B) - if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) - c.io.param.get.poke(0.U) - } - c.clock.step(1) - c.io.valid.poke(false.B) c.clock.step(1) + //c.io.valid.poke(false.B) c.io.dataResp.expect(24.U) println("EXPECTED DATA IS: 24 GOT " + c.io.dataResp.peek().litValue().toInt.toString) } @@ -103,7 +74,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.byteLane.poke("b0001".U) c.io.isWrite.poke(false.B) c.clock.step(1) - c.io.valid.poke(false.B) + //c.io.valid.poke(false.B) println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) while(c.io.validResp.peek().litToBoolean != true) { println("wait") @@ -147,7 +118,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.byteLane.poke("b0011".U) c.io.isWrite.poke(false.B) c.clock.step(1) - c.io.valid.poke(false.B) + //c.io.valid.poke(false.B) println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) while(c.io.validResp.peek().litToBoolean != true) { println("wait") @@ -159,6 +130,71 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil println("EXPECTED DATA IS: " + "hefbf".U.litValue().toInt + " GOT " + c.io.dataResp.peek().litValue().toInt.toString) } } + "should write and read full word with TL-UH" in { + implicit val config = TilelinkConfig() + // val programFile = getFile + test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => + c.clock.step(5) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(24.U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + c.io.byteLane.poke("b1111".U) + c.io.isWrite.poke(true.B) + c.clock.step(1) + c.io.valid.poke(false.B) + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + + println("Got the response now try arithmetic data") + c.clock.step(2) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(9.U) + c.io.isWrite.poke(false.B) + c.io.byteLane.poke("b1111".U) + if(config.uh){ + c.io.is_arithmetic.get.poke(true.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(4.U) + } + c.clock.step(2) + + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + c.io.dataResp.expect(24.U) + println("EXPECTED DATA IS: 24 GOT " + c.io.dataResp.peek().litValue().toInt.toString) + c.io.valid.poke(false.B) + println("Got the response now reading expected data") + c.clock.step(2) + c.io.dataReq.poke(0.U) + c.io.isWrite.poke(false.B) + c.io.valid.poke(true.B) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + //c.clock.step(1) + //c.io.valid.poke(false.B) + c.clock.step(1) + c.io.dataResp.expect(33.U) + println("EXPECTED DATA IS: 33 GOT " + c.io.dataResp.peek().litValue().toInt.toString) + } + } //"should write and read full word" in { // implicit val config = TL_ULConfig() // // val programFile = getFile From f094348e4d56dcb3dd3d0817f07f0095f02d0676 Mon Sep 17 00:00:00 2001 From: devchadha-jmi Date: Thu, 27 Apr 2023 00:30:36 +0530 Subject: [PATCH 04/12] Added another Test-bench for TLUH which perform Random Atomic Operations and all tests are passed --- .../caravan/bus/tilelink/TilelinkDevice.scala | 8 +- src/test/scala/tilelink/HarnessTest.scala | 200 +++++++++++++++++- src/test/scala/tilelink/TLUHTest.scala | 127 +++++++++++ 3 files changed, 330 insertions(+), 5 deletions(-) create mode 100644 src/test/scala/tilelink/TLUHTest.scala diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index 932b766..508f17b 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -67,10 +67,10 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter when(io.rspIn.valid){ io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address io.reqOut.bits.dataRequest := MuxCase(io.tlMasterReceiver.bits.a_data, Array( - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 0.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, - io.tlMasterReceiver.bits.a_data.asSInt,io.rspIn.bits.dataResponse.asSInt).asUInt, - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 1.U) -> Mux(io.tlMasterReceiver.bits.a_data.asSInt < io.rspIn.bits.dataResponse.asSInt, - io.rspIn.bits.dataResponse.asSInt,io.tlMasterReceiver.bits.a_data.asSInt).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 3.U) -> Mux(io.tlMasterReceiver.bits.a_data < io.rspIn.bits.dataResponse, diff --git a/src/test/scala/tilelink/HarnessTest.scala b/src/test/scala/tilelink/HarnessTest.scala index 92ba791..245d061 100644 --- a/src/test/scala/tilelink/HarnessTest.scala +++ b/src/test/scala/tilelink/HarnessTest.scala @@ -130,7 +130,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil println("EXPECTED DATA IS: " + "hefbf".U.litValue().toInt + " GOT " + c.io.dataResp.peek().litValue().toInt.toString) } } - "should write and read full word with TL-UH" in { + "should write and read full word with TL-UH Arithmetic ADD" in { implicit val config = TilelinkConfig() // val programFile = getFile test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => @@ -195,6 +195,204 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil println("EXPECTED DATA IS: 33 GOT " + c.io.dataResp.peek().litValue().toInt.toString) } } + + "should write and read full word with TL-UH Arithmetic MAXU" in { + implicit val config = TilelinkConfig() + // val programFile = getFile + test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => + c.clock.step(5) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(24.U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + c.io.byteLane.poke("b1111".U) + c.io.isWrite.poke(true.B) + c.clock.step(1) + c.io.valid.poke(false.B) + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + + println("Got the response now try arithmetic data") + c.clock.step(2) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(9.U) + c.io.isWrite.poke(false.B) + c.io.byteLane.poke("b1111".U) + if(config.uh){ + c.io.is_arithmetic.get.poke(true.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(3.U) + } + c.clock.step(2) + + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + c.io.dataResp.expect(24.U) + println("EXPECTED DATA IS: 24 GOT " + c.io.dataResp.peek().litValue().toInt.toString) + c.io.valid.poke(false.B) + println("Got the response now reading expected data") + c.clock.step(2) + c.io.dataReq.poke(0.U) + c.io.isWrite.poke(false.B) + c.io.valid.poke(true.B) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + //c.clock.step(1) + //c.io.valid.poke(false.B) + c.clock.step(1) + c.io.dataResp.expect(24.U) + println("EXPECTED DATA IS: 24 GOT " + c.io.dataResp.peek().litValue().toInt.toString) + } + } + + "should write and read full word with TL-UH Logical OR" in { + implicit val config = TilelinkConfig() + // val programFile = getFile + test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => + c.clock.step(5) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(46.U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + c.io.byteLane.poke("b1111".U) + c.io.isWrite.poke(true.B) + c.clock.step(1) + c.io.valid.poke(false.B) + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + + println("Got the response now try Logical data") + c.clock.step(2) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(9.U) + c.io.isWrite.poke(false.B) + c.io.byteLane.poke("b1111".U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(true.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(1.U) + } + c.clock.step(2) + + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + c.io.dataResp.expect(46.U) + println("EXPECTED DATA IS: 46 GOT " + c.io.dataResp.peek().litValue().toInt.toString) + c.io.valid.poke(false.B) + println("Got the response now reading expected data") + c.clock.step(2) + c.io.dataReq.poke(0.U) + c.io.isWrite.poke(false.B) + c.io.valid.poke(true.B) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + //c.clock.step(1) + //c.io.valid.poke(false.B) + c.clock.step(1) + c.io.dataResp.expect(47.U) + println("EXPECTED DATA IS: 47 GOT " + c.io.dataResp.peek().litValue().toInt.toString) + } + } + + "should write and read full word with TL-UH Logical SWAP" in { + implicit val config = TilelinkConfig() + // val programFile = getFile + test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => + c.clock.step(5) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(46.U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + c.io.byteLane.poke("b1111".U) + c.io.isWrite.poke(true.B) + c.clock.step(1) + c.io.valid.poke(false.B) + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + + println("Got the response now try Logical data") + c.clock.step(2) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(9.U) + c.io.isWrite.poke(false.B) + c.io.byteLane.poke("b1111".U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(true.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(3.U) + } + c.clock.step(2) + + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + c.io.dataResp.expect(46.U) + println("EXPECTED DATA IS: 46 GOT " + c.io.dataResp.peek().litValue().toInt.toString) + c.io.valid.poke(false.B) + println("Got the response now reading expected data") + c.clock.step(2) + c.io.dataReq.poke(0.U) + c.io.isWrite.poke(false.B) + c.io.valid.poke(true.B) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + //c.clock.step(1) + //c.io.valid.poke(false.B) + c.clock.step(1) + c.io.dataResp.expect(9.U) + println("EXPECTED DATA IS: 9 GOT " + c.io.dataResp.peek().litValue().toInt.toString) + } + } //"should write and read full word" in { // implicit val config = TL_ULConfig() // // val programFile = getFile diff --git a/src/test/scala/tilelink/TLUHTest.scala b/src/test/scala/tilelink/TLUHTest.scala new file mode 100644 index 0000000..89f297f --- /dev/null +++ b/src/test/scala/tilelink/TLUHTest.scala @@ -0,0 +1,127 @@ +package tilelink +import caravan.bus.tilelink.{TilelinkHarness, TilelinkConfig} +import chisel3._ +import org.scalatest._ +import chiseltest._ +import chiseltest.ChiselScalatestTester +import chiseltest.internal.VerilatorBackendAnnotation +import chiseltest.experimental.TestOptionBuilder._ +import org.scalatest.FreeSpec +import scala.math._ + +import scala . util . Random + +import common.MemoryDumpFileHelper // necessary to import + +class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper { + "TL-UH Tests" in { + implicit val config = TilelinkConfig() + // val programFile = getFile + + test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => + val array_op = Array(2, 3) + + for ( i <- 0 until 20){ + val data_1 = Random.nextLong() & 0xFFFFFFFFL + val data_2 = Random.nextLong() & 0xFFFFFFFFL + val index = Random.nextInt(2) + val opCode = array_op(index) + val param = Random.nextInt(5) + + println (data_1.U) + println (data_2.U) + println (opCode.asUInt) + println (param.asUInt) + + val result = (opCode, param) match { + case (a,b) if a == 2 && b == 0 => min(data_1, data_2) + case (a,b) if a == 2 && b == 1 => max(data_1, data_2) + case (a,b) if a == 2 && b == 2 => min(data_1, data_2) + case (a,b) if a == 2 && b == 3 => max(data_1, data_2) + case (a,b) if a == 2 && b == 4 => data_1 + data_2 + case (a,b) if a == 3 && b == 0 => data_1 ^ data_2 + case (a,b) if a == 3 && b == 1 => data_1 | data_2 + case (a,b) if a == 3 && b == 2 => data_1 & data_2 + case (a,b) if a == 3 && b == 3 => data_2 + } + + val result1 : BigInt = if (result < 0) + (BigInt (0xFFFFFFFFL) + result +1) & 0xFFFFFFFFL + else result & 0xFFFFFFFFL + + c.clock.step(5) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(data_1.U) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + c.io.byteLane.poke("b1111".U) + c.io.isWrite.poke(true.B) + c.clock.step(1) + c.io.valid.poke(false.B) + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + + println("Got the response now try atomic operation") + c.clock.step(2) + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(data_2.U) + c.io.isWrite.poke(false.B) + c.io.byteLane.poke("b1111".U) + if(config.uh){ + if (opCode == 2){ + println("Got the response now try arithmetic operation") + c.io.is_arithmetic.get.poke(true.B) + } + else + c.io.is_arithmetic.get.poke(false.B) + + if (opCode == 3){ + println("Got the response now try logic operation") + c.io.is_logical.get.poke(true.B) + } + else + c.io.is_logical.get.poke(false.B) + + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(param.U) + } + c.clock.step(2) + + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + c.io.dataResp.expect(data_1.U) + println(s"EXPECTED DATA IS: ${data_1.U} GOT " + c.io.dataResp.peek().litValue().toInt.toString) + c.io.valid.poke(false.B) + println("Got the response now reading expected data") + c.clock.step(2) + c.io.dataReq.poke(0.U) + c.io.isWrite.poke(false.B) + c.io.valid.poke(true.B) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + } + //c.clock.step(1) + //c.io.valid.poke(false.B) + c.clock.step(1) + c.io.dataResp.expect(result1.U) + println(s"EXPECTED DATA IS: ${result1.U} GOT " + c.io.dataResp.peek().litValue().toInt.toString) + + } + } +} +} \ No newline at end of file From 8c163ab3a2f93b3aa6730d9e991468d3e7e8bf71 Mon Sep 17 00:00:00 2001 From: devchadha-jmi Date: Thu, 27 Apr 2023 00:51:01 +0530 Subject: [PATCH 05/12] Fixed the logic issue when OpCode is 3 and Param is 4 --- src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala | 2 +- src/test/scala/tilelink/TLUHTest.scala | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index 508f17b..549ff25 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -66,7 +66,7 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.rspIn.ready := true.B when(io.rspIn.valid){ io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address - io.reqOut.bits.dataRequest := MuxCase(io.tlMasterReceiver.bits.a_data, Array( + io.reqOut.bits.dataRequest := MuxCase(io.rspIn.bits.dataResponse, Array( (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 1.U) -> Mux(io.tlMasterReceiver.bits.a_data < io.rspIn.bits.dataResponse, diff --git a/src/test/scala/tilelink/TLUHTest.scala b/src/test/scala/tilelink/TLUHTest.scala index 89f297f..50f281d 100644 --- a/src/test/scala/tilelink/TLUHTest.scala +++ b/src/test/scala/tilelink/TLUHTest.scala @@ -42,7 +42,8 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe case (a,b) if a == 3 && b == 0 => data_1 ^ data_2 case (a,b) if a == 3 && b == 1 => data_1 | data_2 case (a,b) if a == 3 && b == 2 => data_1 & data_2 - case (a,b) if a == 3 && b == 3 => data_2 + case (a,b) if a == 3 && b == 3 => data_2 + case _ => data_1 } val result1 : BigInt = if (result < 0) From 6a4d59cd8d45206e3f10577246bcd11d9e2b32fe Mon Sep 17 00:00:00 2001 From: siddiquimohsin Date: Wed, 3 May 2023 02:14:26 +0500 Subject: [PATCH 06/12] Add logic for Burst Messages. Test this Burst messages for Get and Put operations and the test is passed --- .../caravan/bus/common/DummyMemory.scala | 4 +- .../scala/caravan/bus/tilelink/Harness.scala | 3 + .../caravan/bus/tilelink/TilelinkBus.scala | 1 + .../caravan/bus/tilelink/TilelinkConfig.scala | 2 +- .../caravan/bus/tilelink/TilelinkDevice.scala | 60 ++++++- .../caravan/bus/tilelink/TilelinkHost.scala | 68 +++++++- src/test/scala/tilelink/HarnessTest.scala | 14 ++ src/test/scala/tilelink/TLUHTest.scala | 149 ++++++++++++------ 8 files changed, 240 insertions(+), 61 deletions(-) diff --git a/src/main/scala/caravan/bus/common/DummyMemory.scala b/src/main/scala/caravan/bus/common/DummyMemory.scala index 6bb7932..a1d173c 100644 --- a/src/main/scala/caravan/bus/common/DummyMemory.scala +++ b/src/main/scala/caravan/bus/common/DummyMemory.scala @@ -108,11 +108,11 @@ class BlockRamWithMasking[A <: AbstrRequest, B <: AbstrResponse] when(io.req.fire() && !io.req.bits.isWrite) { // READ - rdata := mem.read(io.req.bits.addrRequest/4.U) + rdata := mem.read(io.req.bits.addrRequest) validReg := true.B } .elsewhen(io.req.fire() && io.req.bits.isWrite) { // WRITE - mem.write(io.req.bits.addrRequest/4.U, wdata, mask) + mem.write(io.req.bits.addrRequest, wdata, mask) validReg := true.B rdata map (_ := DontCare) } .otherwise { diff --git a/src/main/scala/caravan/bus/tilelink/Harness.scala b/src/main/scala/caravan/bus/tilelink/Harness.scala index 0b930d8..b333081 100644 --- a/src/main/scala/caravan/bus/tilelink/Harness.scala +++ b/src/main/scala/caravan/bus/tilelink/Harness.scala @@ -18,6 +18,8 @@ class TilelinkHarness/*(programFile: Option[String])*/(implicit val config: Tile val is_logical = if(config.uh) Some(Input(Bool())) else None val is_intent = if(config.uh) Some(Input(Bool())) else None val param = if(config.uh) Some(Input(UInt(3.W))) else None + val size = if (config.uh) Some(Input(UInt(config.z.W))) else None + val validResp = Output(Bool()) val dataResp = Output(UInt(32.W)) @@ -47,6 +49,7 @@ class TilelinkHarness/*(programFile: Option[String])*/(implicit val config: Tile tlHost.io.reqIn.bits.is_logical.get := io.is_logical.get tlHost.io.reqIn.bits.is_intent.get := io.is_intent.get tlHost.io.reqIn.bits.param.get := io.param.get + tlHost.io.reqIn.bits.size.get := io.size.get } diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala b/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala index 2b8170d..6fea12a 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala @@ -13,6 +13,7 @@ class TLRequest(implicit val config: TilelinkConfig) extends AbstrRequest { val is_logical = if(config.uh) Some(Bool()) else None val is_intent = if(config.uh) Some(Bool()) else None val param = if(config.uh) Some(UInt(3.W)) else None + val size = if (config.uh) Some(UInt(config.z.W)) else None } class TLResponse(implicit val config: TilelinkConfig) extends AbstrResponse { diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala b/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala index 20cc97d..7fd1698 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala @@ -17,7 +17,7 @@ case class TilelinkConfig val w: Int = 4, val a: Int = 32, - val z: Int = 2, + val z: Int = 8, val o: Int = 8, val i: Int = 1, diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index 549ff25..e035ba6 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -15,6 +15,11 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter val stateReg = RegInit(idle) val rspData = RegInit(0.U) + val add_reg_D = RegInit(0.U) + val mask_reg_D = RegInit(0.U) + val counter_D = RegInit(UInt((config.z/config.w).W),0.U) + val op_reg_D = RegInit(6.U) + io.tlMasterReceiver.ready := true.B io.rspIn.ready := false.B @@ -23,6 +28,7 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.reqOut.bits.is_logical.get := false.B io.reqOut.bits.is_intent.get := false.B io.reqOut.bits.param.get := 0.U + io.reqOut.bits.size.get := 0.U } io.reqOut.bits.addrRequest := 0.U @@ -50,6 +56,10 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ //val idle :: wait_for_resp :: Nil = Enum(2) //val stateReg = RegInit(idle) + add_reg_D := 0.U + mask_reg_D := 0.U + counter_D := 0.U + op_reg_D := 6.U when(stateReg === idle){ when(io.tlMasterReceiver.valid){ @@ -117,7 +127,19 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter } }.otherwise{ - when(io.tlMasterReceiver.valid){ + when(config.uh.asBool && counter_D > 0.U && op_reg_D === Get.U){ + io.reqOut.bits.addrRequest := add_reg_D + config.w.U + io.reqOut.bits.activeByteLane := mask_reg_D + io.reqOut.bits.isWrite := false.B + counter_D := counter_D -1.U + io.reqOut.valid := true.B + io.rspIn.ready := true.B + + } + .elsewhen(io.tlMasterReceiver.valid){ + op_reg_D := 6.U + add_reg_D := 0.U + mask_reg_D := 0.U io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address io.reqOut.bits.dataRequest := io.tlMasterReceiver.bits.a_data @@ -128,15 +150,38 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter //stateReg := wait_for_resp io.rspIn.ready := true.B + when(((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U) && io.tlMasterReceiver.bits.a_opcode === Get.U){ + op_reg_D := io.tlMasterReceiver.bits.a_opcode + add_reg_D := io.tlMasterReceiver.bits.a_address + mask_reg_D := io.tlMasterReceiver.bits.a_mask + counter_D := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt /config.w.U)-1.U + } + } //}.elsewhen(stateReg === wait_for_resp){ // io.rspIn.ready := true.B - when(io.rspIn.valid){ + when(io.rspIn.valid && config.uh.asBool && counter_D > 0.U && op_reg_D =/= Get.U){ + counter_D := counter_D -1.U - io.tlSlaveTransmitter.bits.d_opcode := AccessAckData.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 + } + .elsewhen(io.rspIn.valid){ + + when(io.tlMasterReceiver.bits.a_opcode === Get.U){ + io.tlSlaveTransmitter.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 @@ -145,9 +190,16 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter 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.reqOut.valid := false.B + //io.reqOut.valid := false.B + + when(((1.U << io.tlMasterReceiver.bits.a_size).asUInt > config.w.U) && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ + counter_D := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt /config.w.U)-1.U + op_reg_D := io.tlMasterReceiver.bits.a_opcode + } //stateReg := idle io.rspIn.ready := false.B + + } } diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala index 4dc97eb..5224b43 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala @@ -18,6 +18,12 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with //val idle :: wait_for_resp :: Nil = Enum(2) //val stateReg = RegInit(idle) val addrReg = RegInit(0.U) + val op_reg = RegInit(6.U) + val param_reg = RegInit(0.U) + val size_reg = RegInit(0.U) + val add_reg = RegInit(0.U) + val source_reg = RegInit(0.U) + val counter_host = RegInit(UInt((config.z/config.w).W),0.U) // val respReg = RegInit(false.B) // val readyReg = RegInit(true.B) // dontTouch(stateReg) @@ -57,8 +63,50 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with // stateReg := Mux(io.reqIn.valid, process_data, idle) // }.elsewhen(stateReg === process_data){ + when(io.reqIn.valid.asBool && counter_host > 0.U && op_reg =/= Get.U && op_reg =/= Intent.U){ + io.tlMasterTransmitter.bits.a_opcode := op_reg + io.tlMasterTransmitter.bits.a_param := param_reg + io.tlMasterTransmitter.bits.a_size := size_reg + io.tlMasterTransmitter.bits.a_source := source_reg + io.tlMasterTransmitter.bits.a_address := add_reg + config.w.U + 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.reqIn.ready := false.B + counter_host := counter_host - 1.U + op_reg := io.tlMasterTransmitter.bits.a_opcode + param_reg := io.tlMasterTransmitter.bits.a_param + size_reg := io.tlMasterTransmitter.bits.a_size + source_reg := io.tlMasterTransmitter.bits.a_source + add_reg := io.tlMasterTransmitter.bits.a_address + + } + .elsewhen(io.reqIn.valid.asBool && counter_host > 0.U && op_reg === Get.U){ + counter_host := counter_host - 1.U + + //io.tlMasterTransmitter.bits.a_opcode := 6.U + //io.tlMasterTransmitter.bits.a_data := 0.U + //io.tlMasterTransmitter.bits.a_address := 0.U + //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 := false.B + //io.tlMasterTransmitter.valid := io.reqIn.valid + io.reqIn.ready := false.B + } + + + + .elsewhen(io.reqIn.valid.asBool && counter_host === 0.U){ - when(io.reqIn.valid){ + op_reg := 6.U + param_reg := 0.U + size_reg := 0.U + source_reg := 0.U + add_reg := 0.U + counter_host := 0.U println("Request Valid Accepted") if (config.uh){ @@ -76,13 +124,27 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with }else{ io.tlMasterTransmitter.bits.a_param := 0.U } - io.tlMasterTransmitter.bits.a_source := 2.U + io.tlMasterTransmitter.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)){ + op_reg := io.tlMasterTransmitter.bits.a_opcode + param_reg := io.tlMasterTransmitter.bits.a_param + size_reg := io.tlMasterTransmitter.bits.a_size + source_reg := io.tlMasterTransmitter.bits.a_source + add_reg := io.tlMasterTransmitter.bits.a_address + counter_host := ((1.U << io.tlMasterTransmitter.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 (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 @@ -91,6 +153,8 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with //io.tlSlaveReceiver.ready := true.B addrReg := io.reqIn.bits.addrRequest io.reqIn.ready := false.B + + } diff --git a/src/test/scala/tilelink/HarnessTest.scala b/src/test/scala/tilelink/HarnessTest.scala index 245d061..0bf8cdf 100644 --- a/src/test/scala/tilelink/HarnessTest.scala +++ b/src/test/scala/tilelink/HarnessTest.scala @@ -54,6 +54,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } c.io.dataReq.poke("habcdef0f".U) c.io.byteLane.poke("b1111".U) @@ -99,6 +100,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) @@ -143,6 +145,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) @@ -166,6 +169,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(4.U) + c.io.size.get.poke(2.U) } c.clock.step(2) @@ -187,6 +191,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } //c.clock.step(1) //c.io.valid.poke(false.B) @@ -209,6 +214,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) @@ -232,6 +238,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(3.U) + c.io.size.get.poke(2.U) } c.clock.step(2) @@ -253,6 +260,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } //c.clock.step(1) //c.io.valid.poke(false.B) @@ -275,6 +283,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) @@ -298,6 +307,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(true.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(1.U) + c.io.size.get.poke(2.U) } c.clock.step(2) @@ -319,6 +329,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } //c.clock.step(1) //c.io.valid.poke(false.B) @@ -341,6 +352,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) @@ -364,6 +376,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(true.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(3.U) + c.io.size.get.poke(2.U) } c.clock.step(2) @@ -385,6 +398,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(2.U) } //c.clock.step(1) //c.io.valid.poke(false.B) diff --git a/src/test/scala/tilelink/TLUHTest.scala b/src/test/scala/tilelink/TLUHTest.scala index 50f281d..91acfae 100644 --- a/src/test/scala/tilelink/TLUHTest.scala +++ b/src/test/scala/tilelink/TLUHTest.scala @@ -21,13 +21,15 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => val array_op = Array(2, 3) - for ( i <- 0 until 20){ + for ( i <- 0 until 1){ val data_1 = Random.nextLong() & 0xFFFFFFFFL val data_2 = Random.nextLong() & 0xFFFFFFFFL val index = Random.nextInt(2) val opCode = array_op(index) val param = Random.nextInt(5) + var counter_test = 0 + println (data_1.U) println (data_2.U) println (opCode.asUInt) @@ -59,9 +61,18 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) + c.io.size.get.poke(4.U) + + if((math.pow(2,c.io.size.get.peek().litValue.toDouble) > config.w)){ + counter_test = (math.pow(2,c.io.size.get.peek().litValue.toDouble)/config.w).toInt-1 + } } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) + //c.io.valid.poke(false.B) + + + //c.io.valid.poke(false.B) c.clock.step(1) c.io.valid.poke(false.B) println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) @@ -69,60 +80,94 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe println("wait") c.clock.step(1) } - - println("Got the response now try atomic operation") - c.clock.step(2) - c.io.valid.poke(true.B) - c.io.addrReq.poke(0.U) - c.io.dataReq.poke(data_2.U) - c.io.isWrite.poke(false.B) - c.io.byteLane.poke("b1111".U) - if(config.uh){ - if (opCode == 2){ - println("Got the response now try arithmetic operation") - c.io.is_arithmetic.get.poke(true.B) - } - else - c.io.is_arithmetic.get.poke(false.B) + while((counter_test > 0)){ - if (opCode == 3){ - println("Got the response now try logic operation") - c.io.is_logical.get.poke(true.B) - } - else - c.io.is_logical.get.poke(false.B) - - c.io.is_intent.get.poke(false.B) - c.io.param.get.poke(param.U) - } - c.clock.step(2) - - println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) - while(c.io.validResp.peek().litToBoolean != true) { - println("wait") - c.clock.step(1) - } - c.io.dataResp.expect(data_1.U) - println(s"EXPECTED DATA IS: ${data_1.U} GOT " + c.io.dataResp.peek().litValue().toInt.toString) - c.io.valid.poke(false.B) - println("Got the response now reading expected data") - c.clock.step(2) - c.io.dataReq.poke(0.U) - c.io.isWrite.poke(false.B) - c.io.valid.poke(true.B) - if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) - c.io.param.get.poke(0.U) - } - //c.clock.step(1) - //c.io.valid.poke(false.B) + c.io.valid.poke(true.B) + val data_3 = Random.nextLong() & 0xFFFFFFFFL + c.io.dataReq.poke(data_3.U) + println("beat") + counter_test = counter_test - 1 + c.clock.step(1) + //c.io.valid.poke(false.B) + + } + + c.io.valid.poke(false.B) + c.clock.step(2) + println("Got the response now try atomic operation") + + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(data_2.U) + c.io.isWrite.poke(false.B) + c.io.byteLane.poke("b1111".U) + if(config.uh){ + if (opCode == 2){ + println("Got the response now try arithmetic operation") + c.io.is_arithmetic.get.poke(true.B) + } + else + c.io.is_arithmetic.get.poke(false.B) + + if (opCode == 3){ + println("Got the response now try logic operation") + c.io.is_logical.get.poke(true.B) + } + else + c.io.is_logical.get.poke(false.B) + + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(param.U) + c.io.size.get.poke(2.U) + + } + c.clock.step(2) + + println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + c.io.dataResp.expect(data_1.U) + println(s"EXPECTED DATA IS: ${data_1.U} GOT " + c.io.dataResp.peek().litValue().toInt) + c.io.valid.poke(false.B) + println("Got the response now reading expected data") + c.clock.step(2) + c.io.addrReq.poke(4.U) + c.io.dataReq.poke(0.U) + c.io.isWrite.poke(false.B) + c.io.valid.poke(true.B) + if(config.uh){ + c.io.is_arithmetic.get.poke(false.B) + c.io.is_logical.get.poke(false.B) + c.io.is_intent.get.poke(false.B) + c.io.param.get.poke(0.U) + c.io.size.get.poke(3.U) + if((math.pow(2,c.io.size.get.peek().litValue.toDouble) > config.w)){ + counter_test = (math.pow(2,c.io.size.get.peek().litValue.toDouble)/config.w).toInt-1 + } + } c.clock.step(1) - c.io.dataResp.expect(result1.U) - println(s"EXPECTED DATA IS: ${result1.U} GOT " + c.io.dataResp.peek().litValue().toInt.toString) + c.io.valid.poke(false.B) + while((counter_test > 0)){ + + c.io.valid.poke(true.B) + val data_3 = Random.nextLong() & 0xFFFFFFFFL + c.io.dataReq.poke(data_3.U) + println("beat") + counter_test = counter_test - 1 + c.clock.step(1) + //c.io.valid.poke(false.B) + + } + + //c.clock.step(1) + //c.io.valid.poke(false.B) + c.clock.step(1) + c.io.dataResp.expect(result1.U) + println(s"EXPECTED DATA IS: ${result1.U} GOT " + c.io.dataResp.peek().litValue().toInt) } } -} + } } \ No newline at end of file From 570534b771ddcb11f3fb9f9dd453e0512eb6c703 Mon Sep 17 00:00:00 2001 From: siddiquimohsin Date: Thu, 25 May 2023 01:58:32 +0500 Subject: [PATCH 07/12] Back to the old logic where Get and Put are outside of the state logic --- src/main/resources/sram.v | 144 ++++++++++++++ src/main/resources/sram_top.v | 80 ++++++++ .../scala/caravan/bus/tilelink/MemIO.scala | 26 +++ .../scala/caravan/bus/tilelink/SRamTop.scala | 181 ++++++++++++++++++ .../caravan/bus/tilelink/TilelinkConfig.scala | 2 +- .../caravan/bus/tilelink/TilelinkHost.scala | 6 +- src/test/scala/tilelink/HarnessTest.scala | 8 +- src/test/scala/tilelink/New_Test.scala | 54 ++++++ src/test/scala/tilelink/TLUHTest.scala | 10 +- 9 files changed, 497 insertions(+), 14 deletions(-) create mode 100644 src/main/resources/sram.v create mode 100644 src/main/resources/sram_top.v create mode 100644 src/main/scala/caravan/bus/tilelink/MemIO.scala create mode 100644 src/main/scala/caravan/bus/tilelink/SRamTop.scala create mode 100644 src/test/scala/tilelink/New_Test.scala diff --git a/src/main/resources/sram.v b/src/main/resources/sram.v new file mode 100644 index 0000000..a3a86a8 --- /dev/null +++ b/src/main/resources/sram.v @@ -0,0 +1,144 @@ +// SPDX-FileCopyrightText: 2020 fabless Corporation +// +// 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 + +//`default_nettype none +// OpenRAM SRAM model +// Words: 256 +// Word size: 32 +// Write size: 8 + +module sram #( + parameter NUM_WMASKS = 4, + parameter DATA_WIDTH = 32, + parameter ADDR_WIDTH = 13, + parameter RAM_DEPTH = 1 << ADDR_WIDTH, + // FIXME: This delay is arbitrary. + parameter DELAY = 3, + parameter IZERO = 0 , // binary / Initial RAM with zeros (has priority over INITFILE) + parameter IFILE = "" +) +( +/*`ifdef USE_POWER_PINS + vdd, + gnd, +`endif */ +// Port 0: RW + clk0,csb0,web0,wmask0,addr0,din0,dout0, +// Port 1: R + clk1,csb1,addr1,dout1 + ); + + +/*`ifdef USE_POWER_PINS + inout vdd; + inout gnd; +`endif + */ + input clk0; // clock + input csb0; // active low chip select + input web0; // active low write control + input [NUM_WMASKS-1:0] wmask0; // write mask + input [ADDR_WIDTH-1:0] addr0; + input [DATA_WIDTH-1:0] din0; + output [DATA_WIDTH-1:0] dout0; + input clk1; // clock + input csb1; // active low chip select + input [ADDR_WIDTH-1:0] addr1; + output [DATA_WIDTH-1:0] dout1; + + reg csb0_reg; + reg web0_reg; + reg [NUM_WMASKS-1:0] wmask0_reg; + reg [ADDR_WIDTH-1:0] addr0_reg; + reg [DATA_WIDTH-1:0] din0_reg; + reg [DATA_WIDTH-1:0] dout0; + + // All inputs are registers + always @(posedge clk0) + begin + csb0_reg = csb0; + web0_reg = web0; + wmask0_reg = wmask0; + addr0_reg = addr0; + din0_reg = din0; + //dout0 = 32'bx0; +/*`ifdef DBG + if ( !csb0_reg && web0_reg ) + $display($time," Reading %m addr0=%b dout0=%b",addr0_reg,mem[addr0_reg]); + if ( !csb0_reg && !web0_reg ) + $display($time," Writing %m addr0=%b din0=%b wmask0=%b",addr0_reg,din0_reg,wmask0_reg); +`endif +*/ end + + reg csb1_reg; + reg [ADDR_WIDTH-1:0] addr1_reg; + reg [DATA_WIDTH-1:0] dout1; + + // All inputs are registers + always @(posedge clk1) + begin + csb1_reg = csb1; + addr1_reg = addr1; +//`ifdef DBG +// if (!csb0 && !web0 && !csb1 && (addr0 == addr1)) +// $display($time," WARNING: Writing and reading addr0=%b and addr1=%b simultaneously!",addr0,addr1); +// dout1 = 32'bx; +// if ( !csb1_reg ) +// $display($time," Reading %m addr1=%b dout1=%b",addr1_reg,mem[addr1_reg]); +//`endif + end +integer i; +reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1]; +initial + if (IZERO) + for (i=0; i {if (programFile.isDefined) programFile.get else ""}) +) with HasBlackBoxResource { + val io = IO(new SRAMIO) + addResource("/sram_top.v") + addResource("/sram.v") +} + +//package nucleusrv.components +// +//import chisel3._ +//import chisel3.util._ +//import chisel3.experimental._ +//import chisel3.util.experimental._ +// +// +//class SRamTop(val programFile:Option[String] ) extends Module { +// val io = IO(new Bundle { +// val req = Flipped(Decoupled(new MemRequestIO)) +// val rsp = Decoupled(new MemResponseIO) +// }) +// +// // the register that sends valid along with the data read from memory +// // a register is used so that it synchronizes along with the data that comes after one cycle +// val validReg = RegInit(false.B) +// io.rsp.valid := validReg +// io.req.ready := true.B // assuming we are always ready to accept requests from device +// +// val rdata = Wire(UInt(32.W)) +// +// // the memory +// val sram = Module(new sram(programFile)) +// +// val clk = WireInit(clock.asUInt()(0)) +// +// sram.io.clk0 := clk +// sram.io.csb0 := 1.B +// sram.io.web0 := DontCare +// sram.io.wmask0 := DontCare +// sram.io.addr0 := DontCare +// sram.io.din0 := DontCare +// // io.dout0 := a.io.dout0 +// +// sram.io.clk1 := DontCare +// sram.io.csb1 := DontCare +// sram.io.addr1 := DontCare +// +// dontTouch(io.req.valid) +// +// when(io.req.valid && !io.req.bits.isWrite) { +// // READ +// // rdata := mem.read(io.req.bits.addrRequest/4.U) +// validReg := true.B +// sram.io.csb0 := false.B +// sram.io.web0 := true.B +// sram.io.addr0 := io.req.bits.addrRequest +// +// rdata := sram.io.dout0 +// } .elsewhen(io.req.valid && io.req.bits.isWrite) { +// // WRITE +// // mem.write(io.req.bits.addrRequest/4.U, wdata, mask) +// // validReg := true.B +// // rdata map (_ := DontCare) +// sram.io.csb0 := false.B +// sram.io.web0 := false.B +// sram.io.wmask0 := io.req.bits.activeByteLane +// sram.io.addr0 := io.req.bits.addrRequest +// sram.io.din0 := io.req.bits.dataRequest +// validReg := true.B +// rdata := DontCare +// } .otherwise { +// validReg := false.B +// // rdata map (_ := DontCare) +// rdata := DontCare +// } +// +// io.rsp.bits.dataResponse := rdata +//} +// +//class SRAMIO extends Bundle { +// val clk0 = Input(Bool()) +// val csb0 = Input(Bool()) +// val web0 = Input(Bool()) +// val wmask0 = Input(UInt(4.W)) +// val addr0 = Input(UInt(10.W)) +// val din0 = Input(UInt(32.W)) +// val dout0 = Output(UInt(32.W)) +// +// val clk1 = Input(Bool()) +// val csb1 = Input(Bool()) +// val addr1 = Input(UInt(10.W)) +// val dout1 = Output(UInt(32.W)) +// +//} +//class sram(programFile:Option[String] ) extends BlackBox( +// Map("IFILE" -> {if (programFile.isDefined) programFile.get else ""}) +//) with HasBlackBoxResource { +// val io = IO(new SRAMIO) +// addResource("/sram.v") +//} \ No newline at end of file diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala b/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala index 7fd1698..29abfcc 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala @@ -22,7 +22,7 @@ case class TilelinkConfig val i: Int = 1, // TL-UH - val uh : Boolean = true + val uh : Boolean = false ) extends BusConfig diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala index fa591c1..175a0da 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala @@ -63,7 +63,7 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with // stateReg := Mux(io.reqIn.valid, process_data, idle) // }.elsewhen(stateReg === process_data){ - when(io.reqIn.valid.asBool && counter_host > 0.U && op_reg =/= Get.U && op_reg =/= Intent.U){ + when(counter_host > 0.U && op_reg =/= Get.U && op_reg =/= Intent.U){ io.tlMasterTransmitter.bits.a_opcode := op_reg io.tlMasterTransmitter.bits.a_param := param_reg io.tlMasterTransmitter.bits.a_size := size_reg @@ -82,7 +82,7 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with add_reg := io.tlMasterTransmitter.bits.a_address } - .elsewhen(io.reqIn.valid.asBool && counter_host > 0.U && op_reg === Get.U){ + .elsewhen(counter_host > 0.U && op_reg === Get.U){ counter_host := counter_host - 1.U //io.tlMasterTransmitter.bits.a_opcode := 6.U @@ -99,7 +99,7 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with - .elsewhen(io.reqIn.valid.asBool && counter_host === 0.U){ + .elsewhen(counter_host === 0.U){ op_reg := 6.U param_reg := 0.U diff --git a/src/test/scala/tilelink/HarnessTest.scala b/src/test/scala/tilelink/HarnessTest.scala index 38ff79c..89a8fc2 100644 --- a/src/test/scala/tilelink/HarnessTest.scala +++ b/src/test/scala/tilelink/HarnessTest.scala @@ -133,7 +133,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil } } "should write and read full word with TL-UH Arithmetic ADD" in { - implicit val config = TilelinkConfig() + implicit val config = TilelinkConfig(uh = true) // val programFile = getFile test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => c.clock.step(5) @@ -202,7 +202,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil } "should write and read full word with TL-UH Arithmetic MAXU" in { - implicit val config = TilelinkConfig() + implicit val config = TilelinkConfig(uh = true) // val programFile = getFile test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => c.clock.step(5) @@ -271,7 +271,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil } "should write and read full word with TL-UH Logical OR" in { - implicit val config = TilelinkConfig() + implicit val config = TilelinkConfig(uh = true) // val programFile = getFile test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => c.clock.step(5) @@ -340,7 +340,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil } "should write and read full word with TL-UH Logical SWAP" in { - implicit val config = TilelinkConfig() + implicit val config = TilelinkConfig(uh = true) // val programFile = getFile test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => c.clock.step(5) diff --git a/src/test/scala/tilelink/New_Test.scala b/src/test/scala/tilelink/New_Test.scala new file mode 100644 index 0000000..24e6ac2 --- /dev/null +++ b/src/test/scala/tilelink/New_Test.scala @@ -0,0 +1,54 @@ +package tilelink +import caravan.bus.tilelink.{TilelinkHarness, TilelinkConfig} +import chisel3._ +import org.scalatest._ +import chiseltest._ +import chiseltest.ChiselScalatestTester +import chiseltest.internal.VerilatorBackendAnnotation +import chiseltest.experimental.TestOptionBuilder._ +import org.scalatest.FreeSpec +import scala.math._ +import scala . util . Random +import common.MemoryDumpFileHelper // necessary to import +class New_Test extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper { + + "New_Test" in { + implicit val config = TilelinkConfig() + // val programFile = getFile + test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => + c.io.valid.poke(true.B) + c.io.addrReq.poke(0.U) + c.io.dataReq.poke(45.U) + c.io.isWrite.poke(true.B) + c.io.byteLane.poke("b1111".U) + + + //c.io.is_arithmetic.get.poke(false.B) + //c.io.is_logical.get.poke(false.B) + //c.io.is_intent.get.poke(false.B) + //c.io.param.get.poke(0.U) + //c.io.size.get.poke(2.U) + + c.clock.step(1) + c.io.valid.poke(false.B) + c.clock.step(10) + + c.io.valid.poke(true.B) + + c.io.isWrite.poke(false.B) + + c.clock.step(2) + c.io.dataResp.expect(45.U) + c.io.valid.poke(false.B) + c.clock.step(10) + + + + + + + } + + } + +} \ No newline at end of file diff --git a/src/test/scala/tilelink/TLUHTest.scala b/src/test/scala/tilelink/TLUHTest.scala index 91acfae..9befd3b 100644 --- a/src/test/scala/tilelink/TLUHTest.scala +++ b/src/test/scala/tilelink/TLUHTest.scala @@ -15,7 +15,7 @@ import common.MemoryDumpFileHelper // necessary to import class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper { "TL-UH Tests" in { - implicit val config = TilelinkConfig() + implicit val config = TilelinkConfig(uh = true) // val programFile = getFile test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => @@ -85,7 +85,6 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.valid.poke(true.B) val data_3 = Random.nextLong() & 0xFFFFFFFFL c.io.dataReq.poke(data_3.U) - println("beat") counter_test = counter_test - 1 c.clock.step(1) //c.io.valid.poke(false.B) @@ -118,7 +117,7 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.is_intent.get.poke(false.B) c.io.param.get.poke(param.U) - c.io.size.get.poke(2.U) + c.io.size.get.poke(4.U) } c.clock.step(2) @@ -133,7 +132,7 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.valid.poke(false.B) println("Got the response now reading expected data") c.clock.step(2) - c.io.addrReq.poke(4.U) + c.io.addrReq.poke(0.U) c.io.dataReq.poke(0.U) c.io.isWrite.poke(false.B) c.io.valid.poke(true.B) @@ -142,7 +141,7 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) - c.io.size.get.poke(3.U) + c.io.size.get.poke(4.U) if((math.pow(2,c.io.size.get.peek().litValue.toDouble) > config.w)){ counter_test = (math.pow(2,c.io.size.get.peek().litValue.toDouble)/config.w).toInt-1 } @@ -154,7 +153,6 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.valid.poke(true.B) val data_3 = Random.nextLong() & 0xFFFFFFFFL c.io.dataReq.poke(data_3.U) - println("beat") counter_test = counter_test - 1 c.clock.step(1) //c.io.valid.poke(false.B) From e344bded31b21f535a807e537ccdc5d8106461a5 Mon Sep 17 00:00:00 2001 From: siddiquimohsin Date: Thu, 25 May 2023 18:15:50 +0500 Subject: [PATCH 08/12] The TLUH Test Error Resolved --- .../caravan/bus/tilelink/TilelinkDevice.scala | 53 +++-- .../caravan/bus/tilelink/TilelinkHost.scala | 109 ++++------- .../scala/tilelink/SwitchHarnessTest.scala | 4 +- src/test/scala/tilelink/TLUHTest.scala | 183 +++++++++++------- 4 files changed, 184 insertions(+), 165 deletions(-) diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index e035ba6..c2135fa 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -17,11 +17,12 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter val add_reg_D = RegInit(0.U) val mask_reg_D = RegInit(0.U) - val counter_D = RegInit(UInt((config.z/config.w).W),0.U) + val counter_D = RegInit(UInt(config.z.W),0.U) val op_reg_D = RegInit(6.U) io.tlMasterReceiver.ready := true.B io.rspIn.ready := false.B + dontTouch(io.rspIn.ready) if (config.uh){ io.reqOut.bits.is_arithmetic.get := false.B @@ -52,30 +53,43 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter when(stateReg =/= idle){ stateReg := idle } + when(counter_D === 0.U){ + op_reg_D := 6.U + add_reg_D := 0.U + mask_reg_D := 0.U + } when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ //val idle :: wait_for_resp :: Nil = Enum(2) //val stateReg = RegInit(idle) - add_reg_D := 0.U - mask_reg_D := 0.U - counter_D := 0.U - op_reg_D := 6.U when(stateReg === idle){ when(io.tlMasterReceiver.valid){ - io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address + when(op_reg_D =/= 6.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ + io.reqOut.bits.addrRequest := add_reg_D + config.w.U + add_reg_D := add_reg_D + config.w.U + counter_D := counter_D - 1.U + }.otherwise{ + 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 := false.B io.reqOut.valid := true.B + io.rspIn.ready := true.B stateReg := uh + when(op_reg_D === 6.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ + add_reg_D := io.tlMasterReceiver.bits.a_address + op_reg_D := io.tlMasterReceiver.bits.a_opcode + counter_D := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() / config.w.U)- 1.U + } } } .elsewhen(stateReg === uh){ io.reqOut.valid := false.B io.rspIn.ready := true.B when(io.rspIn.valid){ - io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address + io.reqOut.bits.addrRequest := add_reg_D io.reqOut.bits.dataRequest := MuxCase(io.rspIn.bits.dataResponse, Array( (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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, @@ -85,7 +99,7 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.tlMasterReceiver.bits.a_data,io.rspIn.bits.dataResponse), (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 4.U) -> (io.tlMasterReceiver.bits.a_data.asUInt + io.rspIn.bits.dataResponse.asUInt).asUInt, + (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 4.U) -> (io.tlMasterReceiver.bits.a_data + io.rspIn.bits.dataResponse), (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 0.U) -> (io.tlMasterReceiver.bits.a_data ^ io.rspIn.bits.dataResponse).asUInt, (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 1.U) -> (io.tlMasterReceiver.bits.a_data | io.rspIn.bits.dataResponse).asUInt, (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 2.U) -> (io.tlMasterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, @@ -96,6 +110,7 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.reqOut.valid := true.B rspData := io.rspIn.bits.dataResponse stateReg := wait_for_resp + } } @@ -105,14 +120,9 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter when(io.rspIn.valid){ io.rspIn.ready := false.B - - io.tlSlaveTransmitter.bits.d_opcode := MuxCase(0.U, Array( - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U - ) -> AccessAckData.U, - (io.tlMasterReceiver.bits.a_opcode === Intent.U) -> HintAck.U, - )) - io.tlSlaveTransmitter.bits.d_data := MuxCase(io.rspIn.bits.dataResponse, Array( - (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U || io.tlMasterReceiver.bits.a_opcode === Logical.U) -> rspData)) + io.tlSlaveTransmitter.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 @@ -128,18 +138,17 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter }.otherwise{ when(config.uh.asBool && counter_D > 0.U && op_reg_D === Get.U){ - io.reqOut.bits.addrRequest := add_reg_D + config.w.U + io.reqOut.bits.addrRequest := add_reg_D + config.w.U io.reqOut.bits.activeByteLane := mask_reg_D io.reqOut.bits.isWrite := false.B counter_D := counter_D -1.U io.reqOut.valid := true.B io.rspIn.ready := true.B + add_reg_D := io.reqOut.bits.addrRequest + } .elsewhen(io.tlMasterReceiver.valid){ - op_reg_D := 6.U - add_reg_D := 0.U - mask_reg_D := 0.U io.reqOut.bits.addrRequest := io.tlMasterReceiver.bits.a_address io.reqOut.bits.dataRequest := io.tlMasterReceiver.bits.a_data @@ -156,14 +165,16 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter mask_reg_D := io.tlMasterReceiver.bits.a_mask counter_D := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt /config.w.U)-1.U } + } //}.elsewhen(stateReg === wait_for_resp){ // io.rspIn.ready := true.B - + when(io.rspIn.valid && config.uh.asBool && counter_D > 0.U && op_reg_D =/= Get.U){ + io.rspIn.ready := false.B counter_D := counter_D -1.U io.tlSlaveTransmitter.bits.d_opcode := 3.U diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala index 175a0da..6d924d6 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala @@ -4,7 +4,6 @@ import chisel3._ import chisel3.experimental.DataMirror import chisel3.stage.ChiselStage import chisel3.util._ - class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with OpCodes { val io = IO(new Bundle { val tlMasterTransmitter = Decoupled(new TilelinkMaster()) @@ -12,18 +11,16 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with val reqIn = Flipped(Decoupled(new TLRequest())) val rspOut = Decoupled(new TLResponse()) }) - - //FSM for indicating valid response only when the response comes. //val idle :: wait_for_resp :: Nil = Enum(2) //val stateReg = RegInit(idle) - val addrReg = RegInit(0.U) + //val addrReg = RegInit(0.U) val op_reg = RegInit(6.U) val param_reg = RegInit(0.U) val size_reg = RegInit(0.U) val add_reg = RegInit(0.U) val source_reg = RegInit(0.U) - val counter_host = RegInit(UInt((config.z/config.w).W),0.U) + val counter_host = RegInit(UInt(config.z.W),0.U) // val respReg = RegInit(false.B) // val readyReg = RegInit(true.B) // dontTouch(stateReg) @@ -34,41 +31,43 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with // when(stateReg === latch_data) { // readyReg := true.B // } - io.tlSlaveReceiver.ready := false.B io.reqIn.ready := true.B dontTouch(io.reqIn.ready) - - // io.rspOut.bits.dataResponse := io.tlSlaveReceiver.bits.d_data + // io.rspOut.bits.dataResponse := io.tlSlaveReceiver.bits.d_data // io.rspOut.bits.error := io.tlSlaveReceiver.bits.d_denied // io.rspOut.bits.ackWrite := io.tlSlaveReceiver.bits.d_opcode === AccessAckData.U - io.tlMasterTransmitter.bits.a_opcode := 0.U io.tlMasterTransmitter.bits.a_data := 0.U - io.tlMasterTransmitter.bits.a_address := addrReg + io.tlMasterTransmitter.bits.a_address := 0.U 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.rspOut.bits.dataResponse := 0.U + io.rspOut.bits.dataResponse := 0.U io.rspOut.bits.error := 0.U // io.rspOut.bits.ackWrite := 0.U io.rspOut.valid := false.B - - //when(stateReg === idle){ // stateReg := Mux(io.reqIn.valid, process_data, idle) // }.elsewhen(stateReg === process_data){ - - when(counter_host > 0.U && op_reg =/= Get.U && op_reg =/= Intent.U){ + when(~(io.reqIn.valid.asBool) && counter_host > 0.U){ + counter_host := 0.U + } + when(io.reqIn.valid.asBool && counter_host > 0.U && op_reg =/= Get.U && op_reg =/= Intent.U){ io.tlMasterTransmitter.bits.a_opcode := op_reg io.tlMasterTransmitter.bits.a_param := param_reg io.tlMasterTransmitter.bits.a_size := size_reg io.tlMasterTransmitter.bits.a_source := source_reg - io.tlMasterTransmitter.bits.a_address := add_reg + config.w.U + + when(op_reg =/= Arithmetic.U && op_reg =/= Logical.U){ + io.tlMasterTransmitter.bits.a_address := add_reg + config.w.U + } + .otherwise{ + io.tlMasterTransmitter.bits.a_address := add_reg + } 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 @@ -80,12 +79,10 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with size_reg := io.tlMasterTransmitter.bits.a_size source_reg := io.tlMasterTransmitter.bits.a_source add_reg := io.tlMasterTransmitter.bits.a_address - } - .elsewhen(counter_host > 0.U && op_reg === Get.U){ + .elsewhen(io.reqIn.valid.asBool && counter_host > 0.U && op_reg === Get.U){ counter_host := counter_host - 1.U - - //io.tlMasterTransmitter.bits.a_opcode := 6.U + //io.tlMasterTransmitter.bits.a_opcode := op_reg //io.tlMasterTransmitter.bits.a_data := 0.U //io.tlMasterTransmitter.bits.a_address := 0.U //io.tlMasterTransmitter.bits.a_param := 0.U @@ -93,22 +90,18 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with //io.tlMasterTransmitter.bits.a_size := 0.U //io.tlMasterTransmitter.bits.a_mask := 0.U //io.tlMasterTransmitter.bits.a_corrupt := false.B - //io.tlMasterTransmitter.valid := io.reqIn.valid + io.tlMasterTransmitter.valid := io.reqIn.valid + //io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest + //io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest io.reqIn.ready := false.B } - - - - .elsewhen(counter_host === 0.U){ - + .elsewhen(io.reqIn.valid){ op_reg := 6.U param_reg := 0.U size_reg := 0.U source_reg := 0.U add_reg := 0.U counter_host := 0.U - - println("Request Valid Accepted") if (config.uh){ io.tlMasterTransmitter.bits.a_opcode := Mux1H(Cat(io.reqIn.bits.is_intent.get,io.reqIn.bits.is_logical.get,io.reqIn.bits.is_arithmetic.get,~(io.reqIn.bits.is_intent.get | io.reqIn.bits.is_logical.get | io.reqIn.bits.is_arithmetic.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 @@ -118,24 +111,26 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with } io.tlMasterTransmitter.bits.a_data := io.reqIn.bits.dataRequest io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest - if (config.uh){ io.tlMasterTransmitter.bits.a_param := io.reqIn.bits.param.get.asUInt }else{ io.tlMasterTransmitter.bits.a_param := 0.U } io.tlMasterTransmitter.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)){ - op_reg := io.tlMasterTransmitter.bits.a_opcode - param_reg := io.tlMasterTransmitter.bits.a_param - size_reg := io.tlMasterTransmitter.bits.a_size - source_reg := io.tlMasterTransmitter.bits.a_source - add_reg := io.tlMasterTransmitter.bits.a_address - counter_host := ((1.U << io.tlMasterTransmitter.bits.a_size.asUInt)/config.w.U)-1.U + op_reg := io.tlMasterTransmitter.bits.a_opcode + param_reg := io.tlMasterTransmitter.bits.a_param + size_reg := io.tlMasterTransmitter.bits.a_size + source_reg := io.tlMasterTransmitter.bits.a_source + add_reg := io.tlMasterTransmitter.bits.a_address + when(io.tlMasterTransmitter.bits.a_opcode === Arithmetic.U || io.tlMasterTransmitter.bits.a_opcode === Logical.U){ + counter_host := 3.U * ((1.U << io.tlMasterTransmitter.bits.a_size.asUInt)/config.w.U).asUInt + } + .otherwise{ + counter_host := ((1.U << io.tlMasterTransmitter.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 @@ -148,51 +143,42 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with io.tlMasterTransmitter.bits.a_mask := io.reqIn.bits.activeByteLane io.tlMasterTransmitter.bits.a_corrupt := false.B io.tlMasterTransmitter.valid := io.reqIn.valid - //stateReg := wait_for_resp - //io.tlSlaveReceiver.ready := true.B - addrReg := io.reqIn.bits.addrRequest + //io.tlSlaveReceiver.ready := true.B + //addrReg := io.reqIn.bits.addrRequest io.reqIn.ready := false.B - - } - - //}.elsewhen(stateReg === wait_for_resp){ - // io.tlSlaveReceiver.ready := true.B // io.reqIn.ready := false.B - when(io.tlSlaveReceiver.valid){ //io.tlSlaveReceiver.ready := false.B //io.reqIn.ready := false.B - io.rspOut.bits.dataResponse := io.tlSlaveReceiver.bits.d_data + io.rspOut.bits.dataResponse := io.tlSlaveReceiver.bits.d_data io.rspOut.bits.error := io.tlSlaveReceiver.bits.d_denied // io.rspOut.bits.ackWrite := io.tlSlaveReceiver.bits.d_opcode === AccessAckData.U io.rspOut.valid := io.tlSlaveReceiver.valid //stateReg := idle - io.tlSlaveReceiver.ready := false.B - io.reqIn.ready := true.B + when(counter_host > 0.U){ + io.reqIn.ready := false.B + }.otherwise{ + io.reqIn.ready := true.B + } } - /*.elsewhen(io.tlSlaveReceiver.ready){ println("Valid Not Recieved") io.reqIn.ready := false.B }*/ - // } - // io.tlSlaveReceiver.ready := true.B // io.reqIn.ready := true.B - - // when(io.reqIn.valid){ // io.tlMasterTransmitter.bits.a_opcode := /*Mux(readyReg,*/ Mux(io.reqIn.bits.isWrite, Mux(io.reqIn.bits.activeByteLane === "b1111".U, PutFullData.U, PutPartialData.U) , Get.U)/*, 2.U)*/ // io.tlMasterTransmitter.bits.a_data := io.reqIn.bits.dataRequest // io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest // io.tlMasterTransmitter.bits.a_param := 0.U - // io.tlMasterTransmitter.bits.a_source := 2.U + // io.tlMasterTransmitter.bits.a_source := 2.U // io.tlMasterTransmitter.bits.a_size := MuxLookup(config.w.U, 2.U,Array( // default 32-bit // (1.U) -> 0.U, // (2.U) -> 1.U, @@ -202,7 +188,6 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with // io.tlMasterTransmitter.bits.a_mask := io.reqIn.bits.activeByteLane // io.tlMasterTransmitter.bits.a_corrupt := false.B // io.tlMasterTransmitter.valid := io.reqIn.valid - // } otherwise { // io.tlMasterTransmitter.bits.a_opcode := 2.U // 2 is used for DontCare // io.tlMasterTransmitter.bits.a_data := DontCare @@ -214,14 +199,11 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with // io.tlMasterTransmitter.bits.a_corrupt := DontCare // io.tlMasterTransmitter.valid := false.B // } - // response is valid when either acknowledment or error is coming back. // respReg := MuxCase(false.B,Array( // ((io.tlSlaveReceiver.bits.d_opcode === AccessAck.U || io.tlSlaveReceiver.bits.d_opcode === AccessAckData.U) && !io.tlSlaveReceiver.bits.d_denied) -> true.B, // (io.tlSlaveReceiver.bits.d_denied & io.tlSlaveReceiver.valid) -> true.B, // )) - - // when(stateReg === idle){ // stateReg := Mux( // (io.tlSlaveReceiver.bits.d_denied | @@ -233,11 +215,4 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with // respReg := false.B // response is invalid for idle state // stateReg := idle // } - - - - // only valid resp is Reg'ed because data and error are coming from device after being stalled already. - - - } \ No newline at end of file diff --git a/src/test/scala/tilelink/SwitchHarnessTest.scala b/src/test/scala/tilelink/SwitchHarnessTest.scala index f43fba4..99c7bee 100644 --- a/src/test/scala/tilelink/SwitchHarnessTest.scala +++ b/src/test/scala/tilelink/SwitchHarnessTest.scala @@ -86,7 +86,7 @@ class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryD c.io.byteLane.poke(byteLane) c.io.isWrite.poke(isWrite) c.clock.step(1) - c.io.valid.poke(false.B) + //c.io.valid.poke(false.B) } } } @@ -115,7 +115,7 @@ class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryD c.io.byteLane.poke(byteLane) c.io.isWrite.poke(isWrite) c.clock.step(1) - c.io.valid.poke(false.B) + //c.io.valid.poke(false.B) } } } diff --git a/src/test/scala/tilelink/TLUHTest.scala b/src/test/scala/tilelink/TLUHTest.scala index 9befd3b..89da4c8 100644 --- a/src/test/scala/tilelink/TLUHTest.scala +++ b/src/test/scala/tilelink/TLUHTest.scala @@ -8,96 +8,106 @@ import chiseltest.internal.VerilatorBackendAnnotation import chiseltest.experimental.TestOptionBuilder._ import org.scalatest.FreeSpec import scala.math._ - import scala . util . Random - import common.MemoryDumpFileHelper // necessary to import - class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper { "TL-UH Tests" in { implicit val config = TilelinkConfig(uh = true) // val programFile = getFile - - test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => - val array_op = Array(2, 3) - - for ( i <- 0 until 1){ - val data_1 = Random.nextLong() & 0xFFFFFFFFL - val data_2 = Random.nextLong() & 0xFFFFFFFFL - val index = Random.nextInt(2) - val opCode = array_op(index) + test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => + val array_op = Array(2, 3) + val opCode = array_op(Random.nextInt(array_op.length)) val param = Random.nextInt(5) - + // this value behaves like (2**size_value = x Bytes operation) + /* + Recently it is 3 which means all operations are 8 bytes,but + we have (w=4 bytes) data width. we divide (8/4=2) which means + all operations (either PUT or GET or ATOMIC) take 2 beats. + */ + val size_value = 4 var counter_test = 0 - - println (data_1.U) - println (data_2.U) - println (opCode.asUInt) - println (param.asUInt) - - val result = (opCode, param) match { - case (a,b) if a == 2 && b == 0 => min(data_1, data_2) - case (a,b) if a == 2 && b == 1 => max(data_1, data_2) - case (a,b) if a == 2 && b == 2 => min(data_1, data_2) - case (a,b) if a == 2 && b == 3 => max(data_1, data_2) - case (a,b) if a == 2 && b == 4 => data_1 + data_2 - case (a,b) if a == 3 && b == 0 => data_1 ^ data_2 - case (a,b) if a == 3 && b == 1 => data_1 | data_2 - case (a,b) if a == 3 && b == 2 => data_1 & data_2 - case (a,b) if a == 3 && b == 3 => data_2 - case _ => data_1 + var index_counter = 0 + val data1 = Array.fill(math.pow(2,size_value).toInt/config.w)(Random.nextLong() & 0xFFFFFFFFL) + val data2 = Array.fill(math.pow(2,size_value).toInt/config.w)(Random.nextLong() & 0xFFFFFFFFL) + val operate = (a:Long,b:Long) => { + if (opCode == 2 && param == 0){ + min(a, b) + } + else if (opCode == 2 && param == 1){ + max(a, b) + } + else if (opCode == 2 && param == 2){ + min(a, b) + } + else if (opCode == 2 && param == 3){ + max(a, b) + } + else if (opCode == 2 && param == 4){ + a + b + } + else if (opCode == 3 && param == 0){ + a ^ b + } + else if (opCode == 3 && param == 1){ + a | b + } + else if (opCode == 3 && param == 2){ + a & b + } + else if (opCode == 3 && param == 3){ + b + } + else{ + a + } } - - val result1 : BigInt = if (result < 0) - (BigInt (0xFFFFFFFFL) + result +1) & 0xFFFFFFFFL - else result & 0xFFFFFFFFL - + val final_result:((Long,Long) => Long,Long,Long)=> BigInt=(f:(Long,Long)=>Long,a:Long,b:Long)=>{ + val r = f(a,b) + if (r < 0) + (BigInt (0xFFFFFFFFL) + r +1) & 0xFFFFFFFFL + else r & 0xFFFFFFFFL + } + val result = data1.zip(data2).map{case(a,b)=> final_result(operate,a,b)} c.clock.step(5) c.io.valid.poke(true.B) c.io.addrReq.poke(0.U) - c.io.dataReq.poke(data_1.U) + c.io.dataReq.poke(data1(index_counter).U) if(config.uh){ c.io.is_arithmetic.get.poke(false.B) c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) - c.io.size.get.poke(4.U) - + c.io.size.get.poke(size_value.U) if((math.pow(2,c.io.size.get.peek().litValue.toDouble) > config.w)){ counter_test = (math.pow(2,c.io.size.get.peek().litValue.toDouble)/config.w).toInt-1 } } c.io.byteLane.poke("b1111".U) c.io.isWrite.poke(true.B) - //c.io.valid.poke(false.B) - - - //c.io.valid.poke(false.B) c.clock.step(1) c.io.valid.poke(false.B) - println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + println(s"VALID RESPONSE FOR PUT BEAT${index_counter}= " + c.io.validResp.peek().litToBoolean.toString) while(c.io.validResp.peek().litToBoolean != true) { println("wait") c.clock.step(1) } + index_counter += 1 while((counter_test > 0)){ - c.io.valid.poke(true.B) - val data_3 = Random.nextLong() & 0xFFFFFFFFL - c.io.dataReq.poke(data_3.U) + c.io.addrReq.poke((c.io.addrReq.peek().litValue+config.w).asUInt) + c.io.dataReq.poke(data1(index_counter).U) counter_test = counter_test - 1 + index_counter += 1 c.clock.step(1) //c.io.valid.poke(false.B) - } - c.io.valid.poke(false.B) c.clock.step(2) + index_counter = 0 println("Got the response now try atomic operation") - c.io.valid.poke(true.B) c.io.addrReq.poke(0.U) - c.io.dataReq.poke(data_2.U) + c.io.dataReq.poke(data2(index_counter).U) c.io.isWrite.poke(false.B) c.io.byteLane.poke("b1111".U) if(config.uh){ @@ -107,29 +117,44 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe } else c.io.is_arithmetic.get.poke(false.B) - if (opCode == 3){ println("Got the response now try logic operation") c.io.is_logical.get.poke(true.B) } else c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) c.io.param.get.poke(param.U) - c.io.size.get.poke(4.U) - + c.io.size.get.poke(size_value.U) + if((math.pow(2,c.io.size.get.peek().litValue.toDouble) > config.w)){ + counter_test = (math.pow(2,c.io.size.get.peek().litValue.toDouble)/config.w).toInt-1 + } } c.clock.step(2) - - println("VALID RESPONSE = " + c.io.validResp.peek().litToBoolean.toString) + println(s"VALID RESPONSE FOR ATOMIC BEAT${index_counter} = " + c.io.validResp.peek().litToBoolean.toString) while(c.io.validResp.peek().litToBoolean != true) { - println("wait") - c.clock.step(1) + println("wait") + c.clock.step(1) + } + c.io.dataResp.expect(data1(index_counter).asUInt) + println(s"EXPECTED DATA FOR ATOMIC IN BEAT${index_counter} IS: ${data1(index_counter).asUInt} GOT " + c.io.dataResp.peek()) + index_counter += 1 + while((counter_test > 0)){ + c.io.dataReq.poke(data2(index_counter).U) + c.io.addrReq.poke((c.io.addrReq.peek().litValue+config.w).asUInt) + counter_test = counter_test - 1 + c.clock.step(2) + println(s"VALID RESPONSE FOR ATOMIC BEAT${index_counter} = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + c.io.dataResp.expect(data1(index_counter).asUInt) + println(s"EXPECTED DATA FOR ATOMIC IN BEAT${index_counter} IS: ${data1(index_counter).asUInt} GOT " + c.io.dataResp.peek()) + index_counter +=1 } - c.io.dataResp.expect(data_1.U) - println(s"EXPECTED DATA IS: ${data_1.U} GOT " + c.io.dataResp.peek().litValue().toInt) c.io.valid.poke(false.B) + index_counter = 0 println("Got the response now reading expected data") c.clock.step(2) c.io.addrReq.poke(0.U) @@ -141,31 +166,39 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.is_logical.get.poke(false.B) c.io.is_intent.get.poke(false.B) c.io.param.get.poke(0.U) - c.io.size.get.poke(4.U) + c.io.size.get.poke(size_value.U) if((math.pow(2,c.io.size.get.peek().litValue.toDouble) > config.w)){ counter_test = (math.pow(2,c.io.size.get.peek().litValue.toDouble)/config.w).toInt-1 } } c.clock.step(1) - c.io.valid.poke(false.B) + println(s"VALID RESPONSE FOR GET BEAT${index_counter} = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) + } + c.io.dataResp.expect(result(index_counter).U) + println(s"EXPECTED DATA FOR GET IN BEAT${index_counter} IS: ${result(index_counter).asUInt} GOT " + c.io.dataResp.peek()) + index_counter +=1 + //c.io.valid.poke(false.B) while((counter_test > 0)){ - c.io.valid.poke(true.B) - val data_3 = Random.nextLong() & 0xFFFFFFFFL - c.io.dataReq.poke(data_3.U) + //val data_3 = Random.nextLong() & 0xFFFFFFFFL + c.io.dataReq.poke(0.U) + //c.io.addrReq.poke((c.io.addrReq.peek().litValue+config.w).asUInt) counter_test = counter_test - 1 c.clock.step(1) - //c.io.valid.poke(false.B) - + println(s"VALID RESPONSE FOR GET BEAT${index_counter} = " + c.io.validResp.peek().litToBoolean.toString) + while(c.io.validResp.peek().litToBoolean != true) { + println("wait") + c.clock.step(1) } - - //c.clock.step(1) - //c.io.valid.poke(false.B) - c.clock.step(1) - c.io.dataResp.expect(result1.U) - println(s"EXPECTED DATA IS: ${result1.U} GOT " + c.io.dataResp.peek().litValue().toInt) - + c.io.dataResp.expect(result(index_counter).U) + println(s"EXPECTED DATA FOR GET IN BEAT${index_counter} IS: ${result(index_counter).asUInt} GOT " + c.io.dataResp.peek()) + index_counter +=1 + } + c.io.valid.poke(false.B) + //c.clock.step(1) } } - } } \ No newline at end of file From 387bc3b466366a34617f3058919d585e0dd21f0e Mon Sep 17 00:00:00 2001 From: siddiquimohsin Date: Fri, 26 May 2023 23:19:42 +0500 Subject: [PATCH 09/12] Made Changes in Burst Logic --- .../caravan/bus/tilelink/TilelinkDevice.scala | 16 +- .../caravan/bus/tilelink/TilelinkHost.scala | 173 ++++++++---------- src/test/scala/tilelink/TLUHTest.scala | 4 +- 3 files changed, 87 insertions(+), 106 deletions(-) diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index c2135fa..729be91 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -50,22 +50,19 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter // val stall = Module(new stallUnit) - when(stateReg =/= idle){ - stateReg := idle - } when(counter_D === 0.U){ op_reg_D := 6.U add_reg_D := 0.U mask_reg_D := 0.U } - when(config.uh.asBool() && io.tlMasterReceiver.bits.a_opcode =/= PutFullData.U && io.tlMasterReceiver.bits.a_opcode =/= PutPartialData.U && io.tlMasterReceiver.bits.a_opcode =/= Get.U){ - //val idle :: wait_for_resp :: Nil = Enum(2) - //val stateReg = RegInit(idle) + when(config.uh.asBool() && (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U + || io.tlMasterReceiver.bits.a_opcode === Logical.U )){ + when(stateReg === idle){ when(io.tlMasterReceiver.valid){ - when(op_reg_D =/= 6.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ + when(counter_D > 0.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ io.reqOut.bits.addrRequest := add_reg_D + config.w.U add_reg_D := add_reg_D + config.w.U counter_D := counter_D - 1.U @@ -78,9 +75,8 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.reqOut.valid := true.B io.rspIn.ready := true.B stateReg := uh - when(op_reg_D === 6.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ + when(counter_D === 0.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ add_reg_D := io.tlMasterReceiver.bits.a_address - op_reg_D := io.tlMasterReceiver.bits.a_opcode counter_D := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() / config.w.U)- 1.U } } @@ -149,7 +145,7 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter } .elsewhen(io.tlMasterReceiver.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 diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala index 6d924d6..6bfef03 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala @@ -50,20 +50,30 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with io.rspOut.bits.error := 0.U // io.rspOut.bits.ackWrite := 0.U io.rspOut.valid := false.B - //when(stateReg === idle){ - // stateReg := Mux(io.reqIn.valid, process_data, idle) - // }.elsewhen(stateReg === process_data){ - when(~(io.reqIn.valid.asBool) && counter_host > 0.U){ - counter_host := 0.U - } - when(io.reqIn.valid.asBool && counter_host > 0.U && op_reg =/= Get.U && op_reg =/= Intent.U){ + + when(~(io.reqIn.valid) && counter_host > 0.U){ + counter_host := 0.U + } + when(counter_host === 0.U){ + op_reg := 6.U + param_reg := 0.U + size_reg := 0.U + source_reg := 0.U + add_reg := 0.U + counter_host := 0.U + } + + + when(io.reqIn.valid){ + when(config.uh.asBool && counter_host > 0.U){ + when(op_reg =/= Get.U){ io.tlMasterTransmitter.bits.a_opcode := op_reg io.tlMasterTransmitter.bits.a_param := param_reg io.tlMasterTransmitter.bits.a_size := size_reg io.tlMasterTransmitter.bits.a_source := source_reg - when(op_reg =/= Arithmetic.U && op_reg =/= Logical.U){ io.tlMasterTransmitter.bits.a_address := add_reg + config.w.U + add_reg := add_reg + config.w.U } .otherwise{ io.tlMasterTransmitter.bits.a_address := add_reg @@ -74,98 +84,73 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with io.tlMasterTransmitter.valid := io.reqIn.valid io.reqIn.ready := false.B counter_host := counter_host - 1.U - op_reg := io.tlMasterTransmitter.bits.a_opcode - param_reg := io.tlMasterTransmitter.bits.a_param - size_reg := io.tlMasterTransmitter.bits.a_size - source_reg := io.tlMasterTransmitter.bits.a_source - add_reg := io.tlMasterTransmitter.bits.a_address } - .elsewhen(io.reqIn.valid.asBool && counter_host > 0.U && op_reg === Get.U){ + .elsewhen(op_reg === Get.U){ counter_host := counter_host - 1.U - //io.tlMasterTransmitter.bits.a_opcode := op_reg - //io.tlMasterTransmitter.bits.a_data := 0.U - //io.tlMasterTransmitter.bits.a_address := 0.U - //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 := false.B - io.tlMasterTransmitter.valid := io.reqIn.valid - //io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest - //io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest io.reqIn.ready := false.B } - .elsewhen(io.reqIn.valid){ - op_reg := 6.U - param_reg := 0.U - size_reg := 0.U - source_reg := 0.U - add_reg := 0.U - counter_host := 0.U - if (config.uh){ - io.tlMasterTransmitter.bits.a_opcode := Mux1H(Cat(io.reqIn.bits.is_intent.get,io.reqIn.bits.is_logical.get,io.reqIn.bits.is_arithmetic.get,~(io.reqIn.bits.is_intent.get | io.reqIn.bits.is_logical.get | io.reqIn.bits.is_arithmetic.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.tlMasterTransmitter.bits.a_data := io.reqIn.bits.dataRequest - io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest - if (config.uh){ - io.tlMasterTransmitter.bits.a_param := io.reqIn.bits.param.get.asUInt - }else{ - io.tlMasterTransmitter.bits.a_param := 0.U - } - io.tlMasterTransmitter.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)){ - op_reg := io.tlMasterTransmitter.bits.a_opcode - param_reg := io.tlMasterTransmitter.bits.a_param - size_reg := io.tlMasterTransmitter.bits.a_size - source_reg := io.tlMasterTransmitter.bits.a_source - add_reg := io.tlMasterTransmitter.bits.a_address - when(io.tlMasterTransmitter.bits.a_opcode === Arithmetic.U || io.tlMasterTransmitter.bits.a_opcode === Logical.U){ - counter_host := 3.U * ((1.U << io.tlMasterTransmitter.bits.a_size.asUInt)/config.w.U).asUInt - } - .otherwise{ - counter_host := ((1.U << io.tlMasterTransmitter.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 - (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 - //stateReg := wait_for_resp - //io.tlSlaveReceiver.ready := true.B - //addrReg := io.reqIn.bits.addrRequest - io.reqIn.ready := false.B + }.otherwise{ + + if (config.uh){ + io.tlMasterTransmitter.bits.a_opcode := Mux1H(Cat(io.reqIn.bits.is_intent.get,io.reqIn.bits.is_logical.get,io.reqIn.bits.is_arithmetic.get,~(io.reqIn.bits.is_intent.get | io.reqIn.bits.is_logical.get | io.reqIn.bits.is_arithmetic.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) } - //}.elsewhen(stateReg === wait_for_resp){ - // io.tlSlaveReceiver.ready := true.B - // io.reqIn.ready := false.B - when(io.tlSlaveReceiver.valid){ - //io.tlSlaveReceiver.ready := false.B - //io.reqIn.ready := false.B - io.rspOut.bits.dataResponse := io.tlSlaveReceiver.bits.d_data - io.rspOut.bits.error := io.tlSlaveReceiver.bits.d_denied - // io.rspOut.bits.ackWrite := io.tlSlaveReceiver.bits.d_opcode === AccessAckData.U - io.rspOut.valid := io.tlSlaveReceiver.valid - //stateReg := idle - io.tlSlaveReceiver.ready := false.B - when(counter_host > 0.U){ - io.reqIn.ready := false.B - }.otherwise{ - io.reqIn.ready := true.B - } + io.tlMasterTransmitter.bits.a_data := io.reqIn.bits.dataRequest + io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest + if (config.uh){ + io.tlMasterTransmitter.bits.a_param := io.reqIn.bits.param.get.asUInt + }else{ + io.tlMasterTransmitter.bits.a_param := 0.U + } + io.tlMasterTransmitter.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)){ + op_reg := io.tlMasterTransmitter.bits.a_opcode + param_reg := io.tlMasterTransmitter.bits.a_param + size_reg := io.tlMasterTransmitter.bits.a_size + source_reg := io.tlMasterTransmitter.bits.a_source + add_reg := io.tlMasterTransmitter.bits.a_address + when(io.tlMasterTransmitter.bits.a_opcode === Arithmetic.U || io.tlMasterTransmitter.bits.a_opcode === Logical.U){ + counter_host := 3.U * ((1.U << io.tlMasterTransmitter.bits.a_size.asUInt)/config.w.U).asUInt - 1.U + } + .otherwise{ + counter_host := ((1.U << io.tlMasterTransmitter.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 + (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.reqIn.ready := false.B + } + } + + when(io.tlSlaveReceiver.valid){ + + io.rspOut.bits.dataResponse := io.tlSlaveReceiver.bits.d_data + io.rspOut.bits.error := io.tlSlaveReceiver.bits.d_denied + + io.rspOut.valid := io.tlSlaveReceiver.valid + + io.tlSlaveReceiver.ready := false.B + when(counter_host > 0.U){ + io.reqIn.ready := false.B + }.otherwise{ + io.reqIn.ready := true.B } + } /*.elsewhen(io.tlSlaveReceiver.ready){ println("Valid Not Recieved") io.reqIn.ready := false.B diff --git a/src/test/scala/tilelink/TLUHTest.scala b/src/test/scala/tilelink/TLUHTest.scala index 89da4c8..a9abae6 100644 --- a/src/test/scala/tilelink/TLUHTest.scala +++ b/src/test/scala/tilelink/TLUHTest.scala @@ -94,7 +94,7 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe index_counter += 1 while((counter_test > 0)){ c.io.valid.poke(true.B) - c.io.addrReq.poke((c.io.addrReq.peek().litValue+config.w).asUInt) + //c.io.addrReq.poke((c.io.addrReq.peek().litValue+config.w).asUInt) c.io.dataReq.poke(data1(index_counter).U) counter_test = counter_test - 1 index_counter += 1 @@ -141,7 +141,7 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe index_counter += 1 while((counter_test > 0)){ c.io.dataReq.poke(data2(index_counter).U) - c.io.addrReq.poke((c.io.addrReq.peek().litValue+config.w).asUInt) + //c.io.addrReq.poke((c.io.addrReq.peek().litValue+config.w).asUInt) counter_test = counter_test - 1 c.clock.step(2) println(s"VALID RESPONSE FOR ATOMIC BEAT${index_counter} = " + c.io.validResp.peek().litToBoolean.toString) From a4963e596bac8a629128c7e08976f7016a021efd Mon Sep 17 00:00:00 2001 From: siddiquimohsin Date: Sat, 27 May 2023 01:54:39 +0500 Subject: [PATCH 10/12] Made some changes in TL-UH and all tests with compliance test are passed --- .../scala/caravan/bus/tilelink/TilelinkDevice.scala | 13 ++++++++----- src/test/scala/tilelink/TLUHTest.scala | 4 ++-- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index 729be91..125abea 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -51,14 +51,17 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter // val stall = Module(new stallUnit) when(counter_D === 0.U){ - op_reg_D := 6.U + when(io.tlMasterReceiver.valid){ + op_reg_D := io.tlMasterReceiver.bits.a_opcode + }.otherwise{ + op_reg_D := 6.U + } add_reg_D := 0.U mask_reg_D := 0.U } - when(config.uh.asBool() && (io.tlMasterReceiver.bits.a_opcode === Arithmetic.U - || io.tlMasterReceiver.bits.a_opcode === Logical.U )){ - + when(config.uh.asBool() && (op_reg_D === Arithmetic.U + || op_reg_D === Logical.U )){ when(stateReg === idle){ when(io.tlMasterReceiver.valid){ @@ -140,7 +143,7 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter counter_D := counter_D -1.U io.reqOut.valid := true.B io.rspIn.ready := true.B - add_reg_D := io.reqOut.bits.addrRequest + add_reg_D := add_reg_D + config.w.U } diff --git a/src/test/scala/tilelink/TLUHTest.scala b/src/test/scala/tilelink/TLUHTest.scala index a9abae6..24822b4 100644 --- a/src/test/scala/tilelink/TLUHTest.scala +++ b/src/test/scala/tilelink/TLUHTest.scala @@ -130,7 +130,7 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe counter_test = (math.pow(2,c.io.size.get.peek().litValue.toDouble)/config.w).toInt-1 } } - c.clock.step(2) + c.clock.step(1) println(s"VALID RESPONSE FOR ATOMIC BEAT${index_counter} = " + c.io.validResp.peek().litToBoolean.toString) while(c.io.validResp.peek().litToBoolean != true) { println("wait") @@ -143,7 +143,7 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.dataReq.poke(data2(index_counter).U) //c.io.addrReq.poke((c.io.addrReq.peek().litValue+config.w).asUInt) counter_test = counter_test - 1 - c.clock.step(2) + c.clock.step(1) println(s"VALID RESPONSE FOR ATOMIC BEAT${index_counter} = " + c.io.validResp.peek().litToBoolean.toString) while(c.io.validResp.peek().litToBoolean != true) { println("wait") From 8a936068ded46648050aa3620a8ddbb0c7f5df16 Mon Sep 17 00:00:00 2001 From: devchadha-jmi Date: Sun, 28 May 2023 01:09:39 +0530 Subject: [PATCH 11/12] Changes made according to the reviews --- .../scala/caravan/bus/tilelink/Harness.scala | 12 +- .../scala/caravan/bus/tilelink/MemIO.scala | 6 +- .../caravan/bus/tilelink/TilelinkBus.scala | 6 +- .../caravan/bus/tilelink/TilelinkConfig.scala | 18 +- .../caravan/bus/tilelink/TilelinkDevice.scala | 118 +++++++------ .../caravan/bus/tilelink/TilelinkHost.scala | 161 ++++++------------ .../bus/tilelink/TilelinkOpcodes.scala | 1 + src/test/scala/tilelink/HarnessTest.scala | 86 +++++----- src/test/scala/tilelink/New_Test.scala | 54 ------ src/test/scala/tilelink/TLUHTest.scala | 24 +-- 10 files changed, 182 insertions(+), 304 deletions(-) delete mode 100644 src/test/scala/tilelink/New_Test.scala diff --git a/src/main/scala/caravan/bus/tilelink/Harness.scala b/src/main/scala/caravan/bus/tilelink/Harness.scala index b333081..f6f0bd8 100644 --- a/src/main/scala/caravan/bus/tilelink/Harness.scala +++ b/src/main/scala/caravan/bus/tilelink/Harness.scala @@ -14,9 +14,9 @@ class TilelinkHarness/*(programFile: Option[String])*/(implicit val config: Tile val dataReq = Input(UInt((config.w * 8).W)) val byteLane = Input(UInt(config.w.W)) val isWrite = Input(Bool()) - val is_arithmetic = if(config.uh) Some(Input(Bool())) else None - val is_logical = if(config.uh) Some(Input(Bool())) else None - val is_intent = if(config.uh) Some(Input(Bool())) else None + val isArithmetic = if(config.uh) Some(Input(Bool())) else None + val isLogical = if(config.uh) Some(Input(Bool())) else None + val isIntent = if(config.uh) Some(Input(Bool())) else None val param = if(config.uh) Some(Input(UInt(3.W))) else None val size = if (config.uh) Some(Input(UInt(config.z.W))) else None @@ -45,9 +45,9 @@ class TilelinkHarness/*(programFile: Option[String])*/(implicit val config: Tile tlHost.io.reqIn.bits.activeByteLane := io.byteLane tlHost.io.reqIn.bits.isWrite := io.isWrite if (config.uh){ - tlHost.io.reqIn.bits.is_arithmetic.get := io.is_arithmetic.get - tlHost.io.reqIn.bits.is_logical.get := io.is_logical.get - tlHost.io.reqIn.bits.is_intent.get := io.is_intent.get + tlHost.io.reqIn.bits.isArithmetic.get := io.isArithmetic.get + tlHost.io.reqIn.bits.isLogical.get := io.isLogical.get + tlHost.io.reqIn.bits.isIntent.get := io.isIntent.get tlHost.io.reqIn.bits.param.get := io.param.get tlHost.io.reqIn.bits.size.get := io.size.get } diff --git a/src/main/scala/caravan/bus/tilelink/MemIO.scala b/src/main/scala/caravan/bus/tilelink/MemIO.scala index 1794696..a551100 100644 --- a/src/main/scala/caravan/bus/tilelink/MemIO.scala +++ b/src/main/scala/caravan/bus/tilelink/MemIO.scala @@ -12,9 +12,9 @@ class MemRequestIO(implicit val config: TilelinkConfig) extends Bundle { val dataRequest: UInt = Input(UInt(32.W)) val activeByteLane: UInt = Input(UInt(4.W)) val isWrite: Bool = Input(Bool()) - val is_arithmetic = if(config.uh) Some(Bool()) else None - val is_logical = if(config.uh) Some(Bool()) else None - val is_intent = if(config.uh) Some(Bool()) else None + val isArithmetic = if(config.uh) Some(Bool()) else None + val isLogical = if(config.uh) Some(Bool()) else None + val isIntent = if(config.uh) Some(Bool()) else None val param = if(config.uh) Some(UInt(3.W)) else None val size = if (config.uh) Some(UInt(config.z.W)) else None diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala b/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala index 6fea12a..1339018 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkBus.scala @@ -9,9 +9,9 @@ class TLRequest(implicit val config: TilelinkConfig) extends AbstrRequest { override val dataRequest: UInt = UInt((config.w * 8).W) override val activeByteLane: UInt = UInt(config.w.W) override val isWrite: Bool = Bool() - val is_arithmetic = if(config.uh) Some(Bool()) else None - val is_logical = if(config.uh) Some(Bool()) else None - val is_intent = if(config.uh) Some(Bool()) else None + val isArithmetic = if(config.uh) Some(Bool()) else None + val isLogical = if(config.uh) Some(Bool()) else None + val isIntent = if(config.uh) Some(Bool()) else None val param = if(config.uh) Some(UInt(3.W)) else None val size = if (config.uh) Some(UInt(config.z.W)) else None } diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala b/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala index 29abfcc..d248c1c 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkConfig.scala @@ -7,22 +7,20 @@ case class TilelinkConfig /* - w => Width of the data bus in bytes. || DUW => width of device user bits, default 4 - a => Width of each address field in bits. || AW => width of address bus, default 32 - z => Width of each size field in bits. || SZW => size width, covers 2^(x) <= DBW; (2 bit for 4B) - o => Number of bits needed to disambiguate per-link master sources. || AIW => width of address source (ID) bus, default 8 - i => Number of bits needed to disambiguate per-link slave sinks. || DIW => width of sink bits, default 1 - + w => Width of the data bus in bytes. || DUW => width of device user bits, default 4 + a => Width of each address field in bits. || AW => width of address bus, default 32 + z => Width of each size field in bits. || SZW => size width, covers 2^(x) <= DBW; (2 bit for 4B) + o => Number of bits needed to disambiguate per-link master sources. || AIW => width of address source (ID) bus, default 8 + i => Number of bits needed to disambiguate per-link slave sinks. || DIW => width of sink bits, default 1 + uh => Decides whether TileLink UH or UL */ val w: Int = 4, val a: Int = 32, - val z: Int = 8, + val z: Int = 2, val o: Int = 8, val i: Int = 1, - - // TL-UH - val uh : Boolean = false + val uh: Boolean = false ) extends BusConfig diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index 125abea..df95870 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -11,23 +11,29 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter val reqOut = Decoupled(new TLRequest()) val rspIn = Flipped(Decoupled(new TLResponse())) }) - val idle :: uh :: wait_for_resp :: Nil = Enum(3) + /* + NOTICE: This state logic is only for Atomic Operations + idle : Address sent to memory to perform READ + uh : The read data is MODIFIED and WRITTEN back to same memory location + waitResponse : In this state the old data value is responded to the host + */ + val idle :: uh :: waitResponse :: Nil = Enum(3) val stateReg = RegInit(idle) val rspData = RegInit(0.U) - val add_reg_D = RegInit(0.U) - val mask_reg_D = RegInit(0.U) - val counter_D = RegInit(UInt(config.z.W),0.U) - val op_reg_D = RegInit(6.U) + val addRegD = RegInit(0.U) + val maskRegD = RegInit(0.U) + val counterD = RegInit(UInt(config.z.W),0.U) + val opRegD = RegInit(NoOp.U) io.tlMasterReceiver.ready := true.B io.rspIn.ready := false.B dontTouch(io.rspIn.ready) if (config.uh){ - io.reqOut.bits.is_arithmetic.get := false.B - io.reqOut.bits.is_logical.get := false.B - io.reqOut.bits.is_intent.get := false.B + io.reqOut.bits.isArithmetic.get := false.B + io.reqOut.bits.isLogical.get := false.B + io.reqOut.bits.isIntent.get := false.B io.reqOut.bits.param.get := 0.U io.reqOut.bits.size.get := 0.U } @@ -48,27 +54,26 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.tlSlaveTransmitter.bits.d_corrupt := 0.U io.tlSlaveTransmitter.valid := 0.U - // val stall = Module(new stallUnit) - when(counter_D === 0.U){ + when(counterD === 0.U){ when(io.tlMasterReceiver.valid){ - op_reg_D := io.tlMasterReceiver.bits.a_opcode + opRegD := io.tlMasterReceiver.bits.a_opcode }.otherwise{ - op_reg_D := 6.U + opRegD := NoOp.U } - add_reg_D := 0.U - mask_reg_D := 0.U + addRegD := 0.U + maskRegD := 0.U } - when(config.uh.asBool() && (op_reg_D === Arithmetic.U - || op_reg_D === Logical.U )){ + when(config.uh.asBool() && (opRegD === Arithmetic.U || opRegD === Logical.U )){ when(stateReg === idle){ when(io.tlMasterReceiver.valid){ - - when(counter_D > 0.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ - io.reqOut.bits.addrRequest := add_reg_D + config.w.U - add_reg_D := add_reg_D + config.w.U - counter_D := counter_D - 1.U + + // 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)){ + 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 } @@ -78,17 +83,17 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.reqOut.valid := true.B io.rspIn.ready := true.B stateReg := uh - when(counter_D === 0.U && ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U)){ - add_reg_D := io.tlMasterReceiver.bits.a_address - counter_D := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt() / config.w.U)- 1.U + 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 } } } .elsewhen(stateReg === uh){ - io.reqOut.valid := false.B - io.rspIn.ready := true.B - when(io.rspIn.valid){ - io.reqOut.bits.addrRequest := add_reg_D + io.reqOut.valid := false.B + io.rspIn.ready := true.B + 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 && 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, @@ -108,12 +113,12 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.reqOut.bits.isWrite := true.B io.reqOut.valid := true.B rspData := io.rspIn.bits.dataResponse - stateReg := wait_for_resp + stateReg := waitResponse } } - .elsewhen(stateReg === wait_for_resp){ + .elsewhen(stateReg === waitResponse){ io.rspIn.ready := true.B io.reqOut.valid := false.B @@ -136,14 +141,14 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter } }.otherwise{ - when(config.uh.asBool && counter_D > 0.U && op_reg_D === Get.U){ - io.reqOut.bits.addrRequest := add_reg_D + config.w.U - io.reqOut.bits.activeByteLane := mask_reg_D + when(config.uh.asBool && counterD > 0.U && opRegD === Get.U){ + io.reqOut.bits.addrRequest := addRegD + config.w.U + io.reqOut.bits.activeByteLane := maskRegD io.reqOut.bits.isWrite := false.B - counter_D := counter_D -1.U + counterD := counterD -1.U io.reqOut.valid := true.B io.rspIn.ready := true.B - add_reg_D := add_reg_D + config.w.U + addRegD := addRegD + config.w.U } @@ -155,26 +160,22 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter io.reqOut.bits.isWrite := io.tlMasterReceiver.bits.a_opcode === PutFullData.U || io.tlMasterReceiver.bits.a_opcode === PutPartialData.U io.reqOut.valid := true.B - //stateReg := wait_for_resp io.rspIn.ready := true.B when(((1.U << io.tlMasterReceiver.bits.a_size).asUInt() > config.w.U) && io.tlMasterReceiver.bits.a_opcode === Get.U){ - op_reg_D := io.tlMasterReceiver.bits.a_opcode - add_reg_D := io.tlMasterReceiver.bits.a_address - mask_reg_D := io.tlMasterReceiver.bits.a_mask - counter_D := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt /config.w.U)-1.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 } } - //}.elsewhen(stateReg === wait_for_resp){ - - // io.rspIn.ready := true.B - when(io.rspIn.valid && config.uh.asBool && counter_D > 0.U && op_reg_D =/= Get.U){ + when(io.rspIn.valid && config.uh.asBool && counterD > 0.U && opRegD =/= Get.U){ io.rspIn.ready := false.B - counter_D := counter_D -1.U + counterD := counterD -1.U io.tlSlaveTransmitter.bits.d_opcode := 3.U io.tlSlaveTransmitter.bits.d_data := 0.U @@ -191,31 +192,26 @@ class TilelinkDevice(implicit val config: TilelinkConfig) extends DeviceAdapter when(io.tlMasterReceiver.bits.a_opcode === Get.U){ io.tlSlaveTransmitter.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 - //io.reqOut.valid := false.B + 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){ - counter_D := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt /config.w.U)-1.U - op_reg_D := io.tlMasterReceiver.bits.a_opcode + counterD := ((1.U << io.tlMasterReceiver.bits.a_size).asUInt /config.w.U)-1.U + opRegD := io.tlMasterReceiver.bits.a_opcode } - //stateReg := idle io.rspIn.ready := false.B } } - - - // Sending Response coming from Memory in the STALL to delay the response one cycle } \ No newline at end of file diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala index 6bfef03..f9e84ad 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala @@ -11,32 +11,19 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with val reqIn = Flipped(Decoupled(new TLRequest())) val rspOut = Decoupled(new TLResponse()) }) - //FSM for indicating valid response only when the response comes. - //val idle :: wait_for_resp :: Nil = Enum(2) - //val stateReg = RegInit(idle) - //val addrReg = RegInit(0.U) - val op_reg = RegInit(6.U) - val param_reg = RegInit(0.U) - val size_reg = RegInit(0.U) - val add_reg = RegInit(0.U) - val source_reg = RegInit(0.U) - val counter_host = RegInit(UInt(config.z.W),0.U) - // val respReg = RegInit(false.B) - // val readyReg = RegInit(true.B) - // dontTouch(stateReg) + + val opReg = RegInit(NoOp.U) + val paramReg = RegInit(0.U) + val sizeReg = RegInit(0.U) + val addReg = RegInit(0.U) + val sourceReg = RegInit(0.U) + val counterHost = RegInit(UInt(config.z.W),0.U) + dontTouch(io.reqIn.valid) - // when(fire) { - // readyReg := false.B - // } - // when(stateReg === latch_data) { - // readyReg := true.B - // } + io.tlSlaveReceiver.ready := false.B io.reqIn.ready := true.B dontTouch(io.reqIn.ready) - // io.rspOut.bits.dataResponse := io.tlSlaveReceiver.bits.d_data - // io.rspOut.bits.error := io.tlSlaveReceiver.bits.d_denied - // io.rspOut.bits.ackWrite := io.tlSlaveReceiver.bits.d_opcode === AccessAckData.U io.tlMasterTransmitter.bits.a_opcode := 0.U io.tlMasterTransmitter.bits.a_data := 0.U io.tlMasterTransmitter.bits.a_address := 0.U @@ -48,51 +35,50 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with io.tlMasterTransmitter.valid := 0.U io.rspOut.bits.dataResponse := 0.U io.rspOut.bits.error := 0.U - // io.rspOut.bits.ackWrite := 0.U io.rspOut.valid := false.B - when(~(io.reqIn.valid) && counter_host > 0.U){ - counter_host := 0.U + when(~(io.reqIn.valid) && counterHost > 0.U){ + counterHost := 0.U } - when(counter_host === 0.U){ - op_reg := 6.U - param_reg := 0.U - size_reg := 0.U - source_reg := 0.U - add_reg := 0.U - counter_host := 0.U + when(counterHost === 0.U){ + opReg := NoOp.U + paramReg := 0.U + sizeReg := 0.U + sourceReg := 0.U + addReg := 0.U + counterHost := 0.U } when(io.reqIn.valid){ - when(config.uh.asBool && counter_host > 0.U){ - when(op_reg =/= Get.U){ - io.tlMasterTransmitter.bits.a_opcode := op_reg - io.tlMasterTransmitter.bits.a_param := param_reg - io.tlMasterTransmitter.bits.a_size := size_reg - io.tlMasterTransmitter.bits.a_source := source_reg - when(op_reg =/= Arithmetic.U && op_reg =/= Logical.U){ - io.tlMasterTransmitter.bits.a_address := add_reg + config.w.U - add_reg := add_reg + config.w.U - } - .otherwise{ - io.tlMasterTransmitter.bits.a_address := add_reg + 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 + when(opReg =/= Arithmetic.U && opReg =/= Logical.U){ + io.tlMasterTransmitter.bits.a_address := addReg + config.w.U + addReg := addReg + config.w.U + } + .otherwise{ + io.tlMasterTransmitter.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.reqIn.ready := false.B + counterHost := counterHost - 1.U } - 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.reqIn.ready := false.B - counter_host := counter_host - 1.U - } - .elsewhen(op_reg === Get.U){ - counter_host := counter_host - 1.U + .elsewhen(opReg === Get.U){ + counterHost := counterHost - 1.U io.reqIn.ready := false.B } }.otherwise{ if (config.uh){ - io.tlMasterTransmitter.bits.a_opcode := Mux1H(Cat(io.reqIn.bits.is_intent.get,io.reqIn.bits.is_logical.get,io.reqIn.bits.is_arithmetic.get,~(io.reqIn.bits.is_intent.get | io.reqIn.bits.is_logical.get | io.reqIn.bits.is_arithmetic.get)) + 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)) ,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{ @@ -109,20 +95,20 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with 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)){ - op_reg := io.tlMasterTransmitter.bits.a_opcode - param_reg := io.tlMasterTransmitter.bits.a_param - size_reg := io.tlMasterTransmitter.bits.a_size - source_reg := io.tlMasterTransmitter.bits.a_source - add_reg := io.tlMasterTransmitter.bits.a_address + opReg := io.tlMasterTransmitter.bits.a_opcode + paramReg := io.tlMasterTransmitter.bits.a_param + sizeReg := io.tlMasterTransmitter.bits.a_size + sourceReg := io.tlMasterTransmitter.bits.a_source + addReg := io.tlMasterTransmitter.bits.a_address when(io.tlMasterTransmitter.bits.a_opcode === Arithmetic.U || io.tlMasterTransmitter.bits.a_opcode === Logical.U){ - counter_host := 3.U * ((1.U << io.tlMasterTransmitter.bits.a_size.asUInt)/config.w.U).asUInt - 1.U + counterHost := 3.U * ((1.U << io.tlMasterTransmitter.bits.a_size.asUInt)/config.w.U).asUInt - 1.U } .otherwise{ - counter_host := ((1.U << io.tlMasterTransmitter.bits.a_size.asUInt)/config.w.U)-1.U + counterHost := ((1.U << io.tlMasterTransmitter.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.tlMasterTransmitter.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, @@ -145,59 +131,10 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with io.rspOut.valid := io.tlSlaveReceiver.valid io.tlSlaveReceiver.ready := false.B - when(counter_host > 0.U){ + when(counterHost > 0.U){ io.reqIn.ready := false.B }.otherwise{ io.reqIn.ready := true.B } } - /*.elsewhen(io.tlSlaveReceiver.ready){ - println("Valid Not Recieved") - io.reqIn.ready := false.B - }*/ - // } - // io.tlSlaveReceiver.ready := true.B - // io.reqIn.ready := true.B - // when(io.reqIn.valid){ - // io.tlMasterTransmitter.bits.a_opcode := /*Mux(readyReg,*/ Mux(io.reqIn.bits.isWrite, Mux(io.reqIn.bits.activeByteLane === "b1111".U, PutFullData.U, PutPartialData.U) , Get.U)/*, 2.U)*/ - // io.tlMasterTransmitter.bits.a_data := io.reqIn.bits.dataRequest - // io.tlMasterTransmitter.bits.a_address := io.reqIn.bits.addrRequest - // io.tlMasterTransmitter.bits.a_param := 0.U - // io.tlMasterTransmitter.bits.a_source := 2.U - // io.tlMasterTransmitter.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 - // } otherwise { - // io.tlMasterTransmitter.bits.a_opcode := 2.U // 2 is used for DontCare - // io.tlMasterTransmitter.bits.a_data := DontCare - // io.tlMasterTransmitter.bits.a_address := DontCare - // io.tlMasterTransmitter.bits.a_param := DontCare - // io.tlMasterTransmitter.bits.a_source := DontCare - // io.tlMasterTransmitter.bits.a_size := DontCare - // io.tlMasterTransmitter.bits.a_mask := DontCare - // io.tlMasterTransmitter.bits.a_corrupt := DontCare - // io.tlMasterTransmitter.valid := false.B - // } - // response is valid when either acknowledment or error is coming back. - // respReg := MuxCase(false.B,Array( - // ((io.tlSlaveReceiver.bits.d_opcode === AccessAck.U || io.tlSlaveReceiver.bits.d_opcode === AccessAckData.U) && !io.tlSlaveReceiver.bits.d_denied) -> true.B, - // (io.tlSlaveReceiver.bits.d_denied & io.tlSlaveReceiver.valid) -> true.B, - // )) - // when(stateReg === idle){ - // stateReg := Mux( - // (io.tlSlaveReceiver.bits.d_denied | - // (io.tlSlaveReceiver.bits.d_opcode === AccessAck.U || io.tlSlaveReceiver.bits.d_opcode === AccessAckData.U)), - // latch_data, - // idle - // ) - // }.elsewhen(stateReg === latch_data){ - // respReg := false.B // response is invalid for idle state - // stateReg := idle - // } } \ No newline at end of file diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkOpcodes.scala b/src/main/scala/caravan/bus/tilelink/TilelinkOpcodes.scala index a63604c..6176dfb 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkOpcodes.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkOpcodes.scala @@ -10,4 +10,5 @@ trait OpCodes { val Logical = 3 val Intent = 5 val HintAck = 2 + val NoOp = 6 } \ No newline at end of file diff --git a/src/test/scala/tilelink/HarnessTest.scala b/src/test/scala/tilelink/HarnessTest.scala index 89a8fc2..be38e66 100644 --- a/src/test/scala/tilelink/HarnessTest.scala +++ b/src/test/scala/tilelink/HarnessTest.scala @@ -50,9 +50,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.addrReq.poke(8.U) c.io.dataReq.poke(0.U) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } @@ -96,9 +96,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.addrReq.poke(8.U) c.io.dataReq.poke("habcdefbf".U) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } @@ -133,7 +133,7 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil } } "should write and read full word with TL-UH Arithmetic ADD" in { - implicit val config = TilelinkConfig(uh = true) + implicit val config = TilelinkConfig(uh = true, z = 8) // val programFile = getFile test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => c.clock.step(5) @@ -141,9 +141,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.addrReq.poke(0.U) c.io.dataReq.poke(24.U) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } @@ -165,9 +165,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.isWrite.poke(false.B) c.io.byteLane.poke("b1111".U) if(config.uh){ - c.io.is_arithmetic.get.poke(true.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(true.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(4.U) c.io.size.get.poke(2.U) } @@ -187,9 +187,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.isWrite.poke(false.B) c.io.valid.poke(true.B) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } @@ -210,9 +210,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.addrReq.poke(0.U) c.io.dataReq.poke(24.U) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } @@ -234,9 +234,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.isWrite.poke(false.B) c.io.byteLane.poke("b1111".U) if(config.uh){ - c.io.is_arithmetic.get.poke(true.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(true.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(3.U) c.io.size.get.poke(2.U) } @@ -256,9 +256,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.isWrite.poke(false.B) c.io.valid.poke(true.B) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } @@ -279,9 +279,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.addrReq.poke(0.U) c.io.dataReq.poke(46.U) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } @@ -303,9 +303,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.isWrite.poke(false.B) c.io.byteLane.poke("b1111".U) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(true.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(true.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(1.U) c.io.size.get.poke(2.U) } @@ -325,9 +325,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.isWrite.poke(false.B) c.io.valid.poke(true.B) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } @@ -348,9 +348,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.addrReq.poke(0.U) c.io.dataReq.poke(46.U) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } @@ -372,9 +372,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.isWrite.poke(false.B) c.io.byteLane.poke("b1111".U) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(true.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(true.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(3.U) c.io.size.get.poke(2.U) } @@ -394,9 +394,9 @@ class HarnessTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFil c.io.isWrite.poke(false.B) c.io.valid.poke(true.B) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(2.U) } diff --git a/src/test/scala/tilelink/New_Test.scala b/src/test/scala/tilelink/New_Test.scala deleted file mode 100644 index 24e6ac2..0000000 --- a/src/test/scala/tilelink/New_Test.scala +++ /dev/null @@ -1,54 +0,0 @@ -package tilelink -import caravan.bus.tilelink.{TilelinkHarness, TilelinkConfig} -import chisel3._ -import org.scalatest._ -import chiseltest._ -import chiseltest.ChiselScalatestTester -import chiseltest.internal.VerilatorBackendAnnotation -import chiseltest.experimental.TestOptionBuilder._ -import org.scalatest.FreeSpec -import scala.math._ -import scala . util . Random -import common.MemoryDumpFileHelper // necessary to import -class New_Test extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper { - - "New_Test" in { - implicit val config = TilelinkConfig() - // val programFile = getFile - test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => - c.io.valid.poke(true.B) - c.io.addrReq.poke(0.U) - c.io.dataReq.poke(45.U) - c.io.isWrite.poke(true.B) - c.io.byteLane.poke("b1111".U) - - - //c.io.is_arithmetic.get.poke(false.B) - //c.io.is_logical.get.poke(false.B) - //c.io.is_intent.get.poke(false.B) - //c.io.param.get.poke(0.U) - //c.io.size.get.poke(2.U) - - c.clock.step(1) - c.io.valid.poke(false.B) - c.clock.step(10) - - c.io.valid.poke(true.B) - - c.io.isWrite.poke(false.B) - - c.clock.step(2) - c.io.dataResp.expect(45.U) - c.io.valid.poke(false.B) - c.clock.step(10) - - - - - - - } - - } - -} \ No newline at end of file diff --git a/src/test/scala/tilelink/TLUHTest.scala b/src/test/scala/tilelink/TLUHTest.scala index 24822b4..bafcd5d 100644 --- a/src/test/scala/tilelink/TLUHTest.scala +++ b/src/test/scala/tilelink/TLUHTest.scala @@ -12,7 +12,7 @@ import scala . util . Random import common.MemoryDumpFileHelper // necessary to import class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHelper { "TL-UH Tests" in { - implicit val config = TilelinkConfig(uh = true) + implicit val config = TilelinkConfig(uh = true, z = 8) // val programFile = getFile test(new TilelinkHarness()).withAnnotations(Seq(VerilatorBackendAnnotation)) {c => val array_op = Array(2, 3) @@ -73,9 +73,9 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.addrReq.poke(0.U) c.io.dataReq.poke(data1(index_counter).U) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(size_value.U) if((math.pow(2,c.io.size.get.peek().litValue.toDouble) > config.w)){ @@ -113,17 +113,17 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe if(config.uh){ if (opCode == 2){ println("Got the response now try arithmetic operation") - c.io.is_arithmetic.get.poke(true.B) + c.io.isArithmetic.get.poke(true.B) } else - c.io.is_arithmetic.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) if (opCode == 3){ println("Got the response now try logic operation") - c.io.is_logical.get.poke(true.B) + c.io.isLogical.get.poke(true.B) } else - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(param.U) c.io.size.get.poke(size_value.U) if((math.pow(2,c.io.size.get.peek().litValue.toDouble) > config.w)){ @@ -162,9 +162,9 @@ class TLUHTest extends FreeSpec with ChiselScalatestTester with MemoryDumpFileHe c.io.isWrite.poke(false.B) c.io.valid.poke(true.B) if(config.uh){ - c.io.is_arithmetic.get.poke(false.B) - c.io.is_logical.get.poke(false.B) - c.io.is_intent.get.poke(false.B) + c.io.isArithmetic.get.poke(false.B) + c.io.isLogical.get.poke(false.B) + c.io.isIntent.get.poke(false.B) c.io.param.get.poke(0.U) c.io.size.get.poke(size_value.U) if((math.pow(2,c.io.size.get.peek().litValue.toDouble) > config.w)){ From 338e08ad2c0c5edbde44381c34f2d1f3754f53dd Mon Sep 17 00:00:00 2001 From: siddiquimohsin Date: Tue, 30 May 2023 22:30:26 +0500 Subject: [PATCH 12/12] Resolved Switch Harness Issue --- .../caravan/bus/tilelink/SwitchHarness.scala | 4 +-- .../caravan/bus/tilelink/TilelinkDevice.scala | 35 ++++++++++++------- .../caravan/bus/tilelink/TilelinkHost.scala | 9 +++-- .../scala/tilelink/SwitchHarnessTest.scala | 4 +-- 4 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/main/scala/caravan/bus/tilelink/SwitchHarness.scala b/src/main/scala/caravan/bus/tilelink/SwitchHarness.scala index f87c5b2..cbb044e 100644 --- a/src/main/scala/caravan/bus/tilelink/SwitchHarness.scala +++ b/src/main/scala/caravan/bus/tilelink/SwitchHarness.scala @@ -1,5 +1,5 @@ package caravan.bus.tilelink -import caravan.bus.common.{AddressMap, BusDecoder, DeviceAdapter, Switch1toN, DummyMemController, Peripherals} +import caravan.bus.common.{AddressMap, BusDecoder, DeviceAdapter, Switch1toN, DummyMemController,BlockRamWithMasking, Peripherals} import chisel3._ import chisel3.experimental.ChiselEnum import chisel3.stage.ChiselStage @@ -29,7 +29,7 @@ class SwitchHarness/*(programFile: Option[String])*/(implicit val config: Tileli val host = Module(new TilelinkHost()) val dccmDev = Module(new TilelinkDevice()) val gpioDev = Module(new TilelinkDevice()) - val memCtrl = Module(new DummyMemController()) + val memCtrl = Module(new DummyMemController())//BlockRamWithMasking(new TLRequest(),new TLResponse(),1024)) val gpioCtrl = Module(new DummyGpioController()) val tlErr = Module(new TilelinkError()) diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala index df95870..b1c9fc1 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkDevice.scala @@ -95,20 +95,29 @@ 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 && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && 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.tlMasterReceiver.bits.a_opcode === Arithmetic.U && io.tlMasterReceiver.bits.a_param === 4.U) -> (io.tlMasterReceiver.bits.a_data + io.rspIn.bits.dataResponse), - (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 0.U) -> (io.tlMasterReceiver.bits.a_data ^ io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 1.U) -> (io.tlMasterReceiver.bits.a_data | io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 2.U) -> (io.tlMasterReceiver.bits.a_data & io.rspIn.bits.dataResponse).asUInt, - (io.tlMasterReceiver.bits.a_opcode === Logical.U && io.tlMasterReceiver.bits.a_param === 3.U) -> io.tlMasterReceiver.bits.a_data + (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.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.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.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.tlMasterReceiver.bits.a_param === 4.U)-> (io.tlMasterReceiver.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.reqOut.bits.activeByteLane := io.tlMasterReceiver.bits.a_mask io.reqOut.bits.isWrite := true.B io.reqOut.valid := true.B diff --git a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala index f9e84ad..74ec51f 100644 --- a/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala +++ b/src/main/scala/caravan/bus/tilelink/TilelinkHost.scala @@ -12,6 +12,7 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with val rspOut = Decoupled(new TLResponse()) }) + val opReg = RegInit(NoOp.U) val paramReg = RegInit(0.U) val sizeReg = RegInit(0.U) @@ -26,7 +27,7 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with dontTouch(io.reqIn.ready) io.tlMasterTransmitter.bits.a_opcode := 0.U io.tlMasterTransmitter.bits.a_data := 0.U - io.tlMasterTransmitter.bits.a_address := 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 @@ -45,7 +46,6 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with paramReg := 0.U sizeReg := 0.U sourceReg := 0.U - addReg := 0.U counterHost := 0.U } @@ -70,10 +70,12 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with io.tlMasterTransmitter.valid := io.reqIn.valid io.reqIn.ready := false.B counterHost := counterHost - 1.U + io.tlSlaveReceiver.ready := true.B } .elsewhen(opReg === Get.U){ counterHost := counterHost - 1.U io.reqIn.ready := false.B + io.tlSlaveReceiver.ready := true.B } }.otherwise{ @@ -99,7 +101,6 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with paramReg := io.tlMasterTransmitter.bits.a_param sizeReg := io.tlMasterTransmitter.bits.a_size sourceReg := io.tlMasterTransmitter.bits.a_source - addReg := io.tlMasterTransmitter.bits.a_address 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 } @@ -120,6 +121,8 @@ class TilelinkHost(implicit val config: TilelinkConfig) extends HostAdapter with io.tlMasterTransmitter.valid := io.reqIn.valid io.reqIn.ready := false.B + io.tlSlaveReceiver.ready := true.B + addReg := io.reqIn.bits.addrRequest } } diff --git a/src/test/scala/tilelink/SwitchHarnessTest.scala b/src/test/scala/tilelink/SwitchHarnessTest.scala index 99c7bee..f43fba4 100644 --- a/src/test/scala/tilelink/SwitchHarnessTest.scala +++ b/src/test/scala/tilelink/SwitchHarnessTest.scala @@ -86,7 +86,7 @@ class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryD c.io.byteLane.poke(byteLane) c.io.isWrite.poke(isWrite) c.clock.step(1) - //c.io.valid.poke(false.B) + c.io.valid.poke(false.B) } } } @@ -115,7 +115,7 @@ class SwitchHarnessTest extends FreeSpec with ChiselScalatestTester with MemoryD c.io.byteLane.poke(byteLane) c.io.isWrite.poke(isWrite) c.clock.step(1) - //c.io.valid.poke(false.B) + c.io.valid.poke(false.B) } } }