Skip to content

Commit

Permalink
[rtl] support zvk
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas-Wye committed Aug 19, 2024
1 parent e0cc123 commit cadd091
Show file tree
Hide file tree
Showing 25 changed files with 871 additions and 56 deletions.
5 changes: 3 additions & 2 deletions configgen/generated/blastoise.json
Original file line number Diff line number Diff line change
Expand Up @@ -167,8 +167,9 @@
]
]
],
"zvbbModuleParameters": []
"zvbbModuleParameters": [],
"zvkModuleParameters": []
}
},
"generator": "org.chipsalliance.t1.rtl.T1"
}
}
5 changes: 3 additions & 2 deletions configgen/generated/machamp.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@
]
],
"floatModuleParameters": [],
"zvbbModuleParameters": []
"zvbbModuleParameters": [],
"zvkModuleParameters": []
}
},
"generator": "org.chipsalliance.t1.rtl.T1"
}
}
19 changes: 18 additions & 1 deletion configgen/generated/psyduck.json
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,25 @@
3
]
]
],
"zvkModuleParameters": [
[
{
"parameter": {
"datapathWidth": 32,
"latency": 3
},
"generator": "org.chipsalliance.t1.rtl.LaneZvk"
},
[
0,
1,
2,
3
]
]
]
}
},
"generator": "org.chipsalliance.t1.rtl.T1"
}
}
5 changes: 3 additions & 2 deletions configgen/generated/sandslash.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@
]
],
"floatModuleParameters": [],
"zvbbModuleParameters": []
"zvbbModuleParameters": [],
"zvkModuleParameters": []
}
},
"generator": "org.chipsalliance.t1.rtl.T1"
}
}
13 changes: 9 additions & 4 deletions configgen/src/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ object Main {
Seq(0, 1, 2, 3))),
floatModuleParameters =
Seq((SerializableModuleGenerator(classOf[LaneFloat], LaneFloatParam(32, 3)), Seq(0, 1, 2, 3))),
zvbbModuleParameters = Seq()
zvbbModuleParameters = Seq(),
zvkModuleParameters = Seq(),
)
)
if (doEmit) param.emit(targetFile)
Expand Down Expand Up @@ -151,7 +152,9 @@ object Main {
floatModuleParameters =
Seq((SerializableModuleGenerator(classOf[LaneFloat], LaneFloatParam(32, 3)), Seq(0, 1, 2, 3))),
zvbbModuleParameters =
Seq((SerializableModuleGenerator(classOf[LaneZvbb], LaneZvbbParam(32, 3)), Seq(0, 1, 2, 3)))
Seq((SerializableModuleGenerator(classOf[LaneZvbb], LaneZvbbParam(32, 3)), Seq(0, 1, 2, 3))),
zvkModuleParameters =
Seq((SerializableModuleGenerator(classOf[LaneZvk], LaneZvkParam(32, 3)), Seq(0, 1, 2, 3))),
)
)
if (doEmit) param.emit(targetFile)
Expand Down Expand Up @@ -201,7 +204,8 @@ object Main {
),
Seq(0, 1, 2, 3))),
floatModuleParameters = Seq(),
zvbbModuleParameters = Seq() // TODO
zvbbModuleParameters = Seq(),
zvkModuleParameters = Seq(),
)
)
if (doEmit) param.emit(targetFile)
Expand Down Expand Up @@ -251,7 +255,8 @@ object Main {
),
Seq(0, 1, 2, 3))),
floatModuleParameters = Seq(),
zvbbModuleParameters = Seq() // TODO
zvbbModuleParameters = Seq(),
zvkModuleParameters = Seq(),
)
)
if (doEmit) param.emit(targetFile)
Expand Down
3 changes: 2 additions & 1 deletion t1/src/Bundles.scala
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,7 @@ class ExecutionUnitRecord(parameter: LaneParameter)(isLastSlot: Boolean) extends
val executeIndex: Bool = Bool()
val source: Vec[UInt] = Vec(3, UInt(parameter.datapathWidth.W))
val crossReadSource: Option[UInt] = Option.when(isLastSlot)(UInt((parameter.datapathWidth * 2).W))
val zvkCrossReadSource: Option[UInt] = Option.when(isLastSlot && parameter.zvkEnable)(UInt((parameter.datapathWidth * 2).W))
/** groupCounter need use to update `Lane.maskFormatResultForGroup` */
val groupCounter: UInt = UInt(parameter.groupNumberBits.W)
val sSendResponse: Option[Bool] = Option.when(isLastSlot)(Bool())
Expand Down Expand Up @@ -722,4 +723,4 @@ class T1Retire(xLen: Int) extends Bundle {
val rd: ValidIO[T1RdRetire] = Valid(new T1RdRetire(xLen))
val csr: ValidIO[T1CSRRetire] = Valid(new T1CSRRetire)
val mem: ValidIO[EmptyBundle] = Valid(new EmptyBundle)
}
}
108 changes: 96 additions & 12 deletions t1/src/Lane.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,16 +81,18 @@ object LaneParameter {
* TODO: cover the queue full.
*/
case class LaneParameter(
vLen: Int,
datapathWidth: Int,
laneNumber: Int,
chainingSize: Int,
crossLaneVRFWriteEscapeQueueSize: Int,
fpuEnable: Boolean,
portFactor: Int,
vrfRamType: RamType,
decoderParam: DecoderParam,
vfuInstantiateParameter: VFUInstantiateParameter)
vLen: Int,
datapathWidth: Int,
laneNumber: Int,
chainingSize: Int,
crossLaneVRFWriteEscapeQueueSize: Int,
crossLaneVRFWriteEscapeZvkQueueSize: Int,
fpuEnable: Boolean,
zvkEnable: Boolean,
portFactor: Int,
vrfRamType: RamType,
decoderParam: DecoderParam,
vfuInstantiateParameter: VFUInstantiateParameter)
extends SerializableModuleParameter {

/** 1 in MSB for instruction order. */
Expand Down Expand Up @@ -132,7 +134,7 @@ case class LaneParameter(
*
* for each number in table below, it represent a [[datapathWidth]]
* {{{
* lane0 | lane1 | ... | lane8
* lane0 | lane1 | ... | lane7
* offset0 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
* offset1 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15
* offset2 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23
Expand Down Expand Up @@ -210,8 +212,26 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[
* TODO: benchmark the usecase for tuning the Ring Bus width.
* find a real world case for using `narrow` and `widen` aggressively.
*/
// 0: 0.0 - 0.1
// 1: 0.2 - 0.3
// 2: 0.4 - 0.5
// 3: 0.6 - 0.7
// 4: 1.0 - 1.1
// 5: 1.2 - 1.3
// 6: 1.4 - 1.5
// 7: 1.6 - 1.7

// 0: 0.0 - 0.1 - 0.2 - 0.3
// 1: 0.4 - 0.5 - 0.6 - 0.7
// 2: 1.0 - 1.1 - 1.2 - 1.3
// 3: 1.4 - 1.5 - 1.6 - 1.7
// 4: 2.0 - 2.1 - 2.2 - 2.3
// 5: 2.4 - 2.5 - 2.6 - 2.7
// 6: 3.0 - 3.1 - 3.2 - 3.3
// 7: 3.4 - 3.5 - 3.6 - 3.7
@public
val readBusPort: Vec[RingPort[ReadBusData]] = IO(Vec(2, new RingPort(new ReadBusData(parameter))))
val readBusPort4: Option[Vec[RingPort[ReadBusData]]] = Option.when(parameter.zvkEnable)(IO(Vec(4, new RingPort(new ReadBusData(parameter)))))

/** VRF Write Interface.
* only used for `narrow` an `widen`
Expand All @@ -220,6 +240,7 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[
*/
@public
val writeBusPort: Vec[RingPort[WriteBusData]] = IO(Vec(2, new RingPort(new WriteBusData(parameter))))
val writeBusPort4: Option[Vec[RingPort[WriteBusData]]] = Option.when(parameter.zvkEnable)(IO(Vec(4, new RingPort(new WriteBusData(parameter)))))

/** request from [[T1.decode]] to [[Lane]]. */
@public
Expand Down Expand Up @@ -320,6 +341,9 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[

// TODO: remove
dontTouch(writeBusPort)
if(parameter.zvkEnable) {
dontTouch(writeBusPort4.get)
}

/** VRF instantces. */
val vrf: Instance[VRF] = Instantiate(new VRF(parameter.vrfParam))
Expand Down Expand Up @@ -440,8 +464,12 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[
val readCheckRequestVec: Vec[VRFReadRequest] = Wire(Vec(parameter.chainingSize * 3 + 2,
new VRFReadRequest(parameter.vrfParam.regNumBits, parameter.vrfOffsetBits, parameter.instructionIndexBits)
))
val zvkReadCheckRequestVec: Vec[VRFReadRequest] = Wire(Vec(parameter.chainingSize * 3 + 4,
new VRFReadRequest(parameter.vrfParam.regNumBits, parameter.vrfOffsetBits, parameter.instructionIndexBits)
))

val readCheckResult: Vec[Bool] = Wire(Vec(parameter.chainingSize * 3 + 2, Bool()))
val zvkReadCheckResult: Vec[Bool] = Wire(Vec(parameter.chainingSize * 3 + 4, Bool()))

/** signal used for prohibiting slots to access VRF.
* a slot will become inactive when:
Expand All @@ -465,7 +493,7 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[
val slotCanShift: Vec[Bool] = Wire(Vec(parameter.chainingSize, Bool()))

/** Which data group is waiting for the result of the cross-lane read */
val readBusDequeueGroup: UInt = Wire(UInt(parameter.groupNumberBits.W))
val readBusDequeueGroup: UInt = Wire(UInt(parameter.groupNumberBits.W)) // TODO: readBusDequeueGroup is currently unused

/** enqueue valid for execution unit */
val executeEnqueueValid: Vec[Bool] = Wire(Vec(parameter.chainingSize, Bool()))
Expand Down Expand Up @@ -514,6 +542,18 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[
pipe = true
)
))
val crossLaneWriteQueue4: Seq[Queue[VRFWriteRequest]] = Seq.tabulate(4)(i => Module(
new Queue(
new VRFWriteRequest(
parameter.vrfParam.regNumBits,
parameter.vrfOffsetBits,
parameter.instructionIndexBits,
parameter.datapathWidth
),
parameter.crossLaneVRFWriteEscapeZvkQueueSize,
pipe = true
)
))
val maskedWriteUnit: Instance[MaskedWrite] = Instantiate(new MaskedWrite(parameter))
val tokenManager: Instance[SlotTokenManager] = Instantiate(new SlotTokenManager(parameter))
slotControl.zipWithIndex.foreach {
Expand Down Expand Up @@ -661,9 +701,17 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[
readCheckRequestVec((parameter.chainingSize - index - 1) * 3 + portIndex) := stage1.vrfCheckRequest(portIndex)
stage1.checkResult(portIndex) := readCheckResult((parameter.chainingSize - index - 1) * 3 + portIndex)
}
val zvkCheckSize = if (isLastSlot && parameter.zvkEnable) 7 else 5
if(parameter.zvkEnable) {
Seq.tabulate(zvkCheckSize){ portIndex =>
zvkReadCheckRequestVec((parameter.chainingSize - index - 1) * 3 + portIndex) := stage1.zvkVrfCheckRequest(portIndex)
stage1.zvkCheckResult(portIndex) := zvkReadCheckResult((parameter.chainingSize - index - 1) * 3 + portIndex)
}
}
// connect cross read bus
if(isLastSlot) {
val tokenSize = parameter.crossLaneVRFWriteEscapeQueueSize
val zvKTokenSize = parameter.crossLaneVRFWriteEscapeZvkQueueSize
readBusPort.zipWithIndex.foreach {case (readPort, portIndex) =>
// tx
val tokenReg = RegInit(0.U(log2Ceil(tokenSize + 1).W))
Expand All @@ -685,6 +733,27 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[
// dequeue to cross read unit
stage1.readBusDequeue.get(portIndex) <> queue.io.deq
}
readBusPort4.get.zipWithIndex.foreach {case (readPort, portIndex) =>
// tx
val tokenReg = RegInit(0.U(log2Ceil(zvKTokenSize + 1).W))
val tokenReady: Bool = tokenReg =/= zvKTokenSize.U
stage1.readBusRequest4.get(portIndex).ready := tokenReady
readPort.deq.valid := stage1.readBusRequest4.get(portIndex).valid && tokenReady
readPort.deq.bits := stage1.readBusRequest4.get(portIndex).bits
val tokenUpdate = Mux(readPort.deq.valid, 1.U, -1.S(tokenReg.getWidth.W).asUInt)
when(readPort.deq.valid ^ readPort.deqRelease) {
tokenReg := tokenReg + tokenUpdate
}
// rx
// rx queue
val queue = Module(new Queue(chiselTypeOf(readPort.deq.bits), zvKTokenSize, pipe=true))
queue.io.enq.valid := readPort.enq.valid
queue.io.enq.bits := readPort.enq.bits
readPort.enqRelease := queue.io.deq.fire
assert(queue.io.enq.ready || !readPort.enq.valid)
// dequeue to cross read unit
stage1.readBusDequeue4.get(portIndex) <> queue.io.deq
}

// cross write
writeBusPort.zipWithIndex.foreach {case (writePort, portIndex) =>
Expand All @@ -694,6 +763,19 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[
writePort.deq.bits := stage3.crossWritePort.get(portIndex).bits
stage3.crossWritePort.get(portIndex).ready := tokenReady

// update token
val tokenUpdate = Mux(writePort.deq.valid, 1.U, -1.S(tokenReg.getWidth.W).asUInt)
when(writePort.deq.valid ^ writePort.deqRelease) {
tokenReg := tokenReg + tokenUpdate
}
}
writeBusPort4.get.zipWithIndex.foreach {case (writePort, portIndex) =>
val tokenReg = RegInit(0.U(log2Ceil(zvKTokenSize + 1).W))
val tokenReady: Bool = tokenReg =/= zvKTokenSize.U
writePort.deq.valid := stage3.crossWritePort4.get(portIndex).valid && tokenReady
writePort.deq.bits := stage3.crossWritePort4.get(portIndex).bits
stage3.crossWritePort4.get(portIndex).ready := tokenReady

// update token
val tokenUpdate = Mux(writePort.deq.valid, 1.U, -1.S(tokenReg.getWidth.W).asUInt)
when(writePort.deq.valid ^ writePort.deqRelease) {
Expand Down Expand Up @@ -892,7 +974,9 @@ class Lane(val parameter: LaneParameter) extends Module with SerializableModule[
}

vrf.readCheck.zip(readCheckRequestVec).foreach{case (sink, source) => sink := source}
vrf.zvkReadCheck.zip(zvkReadCheckRequestVec).foreach{case (sink, source) => sink := source}
readCheckResult.zip(vrf.readCheckResult).foreach{case (sink, source) => sink := source}
zvkReadCheckResult.zip(vrf.zvkReadCheckResult).foreach{case (sink, source) => sink := source}

allVrfWriteAfterCheck.zipWithIndex.foreach { case (req, i) =>
val check = vrf.writeAllow(i)
Expand Down
47 changes: 47 additions & 0 deletions t1/src/LaneZvk.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2022 Jiuyang Liu <[email protected]>

package org.chipsalliance.t1.rtl

import chisel3.experimental.hierarchy.instantiable
import chisel3._
import chisel3.experimental.{SerializableModule, SerializableModuleParameter}
import chisel3.util._
import org.chipsalliance.t1.rtl.decoder.{BoolField, Decoder}

object LaneZvkParam {
implicit def rw: upickle.default.ReadWriter[LaneZvkParam] = upickle.default.macroRW
}

case class LaneZvkParam(datapathWidth: Int, latency: Int) extends VFUParameter with SerializableModuleParameter {
val inputBundle = new LaneZvkRequest(datapathWidth)
val decodeField: BoolField = Decoder.zvbb
val outputBundle = new LaneZvkResponse(datapathWidth)
override val NeedSplit: Boolean = false
}

class LaneZvkRequest(datapathWidth: Int) extends VFUPipeBundle {
val src = Vec(3, UInt(datapathWidth.W))
val opcode = UInt(4.W)
val vSew = UInt(2.W)
val shifterSize = UInt(log2Ceil(datapathWidth).W)
}

class LaneZvkResponse(datapathWidth: Int) extends VFUPipeBundle {
val data = UInt(datapathWidth.W)
}

@instantiable
class LaneZvk(val parameter: LaneZvkParam)
extends VFUModule(parameter) with SerializableModule[LaneZvkParam]{
val response: LaneZvkResponse = Wire(new LaneZvkResponse(parameter.datapathWidth))
val request : LaneZvkRequest = connectIO(response).asTypeOf(parameter.inputBundle)

val zvbbSrc: UInt = request.src(1) // vs2
val zvbbRs: UInt = request.src(0) // vs1 or rs1
val vSew: UInt = UIntToOH(request.vSew) // sew = 0, 1, 2

response.data := Mux1H(UIntToOH(request.opcode), Seq(
))
}

Loading

0 comments on commit cadd091

Please sign in to comment.