Skip to content

Commit 43a308e

Browse files
authored
feat(difftest): support DiffPhyRegState and DiffArchRenameTable (#714)
This commit introduces DiffPhyRegState and DiffArchRenameTable as new Difftest interfaces. A new option softArchUpdate is also added (disabled by default). By default, Difftest replaces PhyReg and RenameTable with ArchReg and CommitData (WriteBack results) on the hardware side to keep backward compatibility. When softArchUpdate is enabled, this substitution is deferred to the software side, reducing hardware area overhead by avoiding extra read ports in the register files. Also we clarify `get_commit_data()` func to `get_int_data()` and `get_fp_data()` for better readability.
1 parent 5d01bec commit 43a308e

File tree

6 files changed

+192
-157
lines changed

6 files changed

+192
-157
lines changed

src/main/scala/Bundles.scala

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ class TriggerCSRState extends DifftestBaseBundle {
175175
val tinfo = UInt(64.W)
176176
}
177177

178+
class ArchRenameTable(numRegs: Int, numPhyRegs: Int) extends DifftestBaseBundle {
179+
val value = Vec(numRegs, UInt(log2Ceil(numPhyRegs).W))
180+
}
181+
182+
class PhyRegState(numPhyRegs: Int) extends DifftestBaseBundle {
183+
val value = Vec(numPhyRegs, UInt(64.W))
184+
}
185+
178186
class DataWriteback(val numElements: Int) extends DifftestBaseBundle with HasValid with HasAddress {
179187
val data = UInt(64.W)
180188
}
@@ -183,36 +191,36 @@ class VecDataWriteback(val numElements: Int) extends DifftestBaseBundle with Has
183191
val data = Vec(2, UInt(64.W))
184192
}
185193

186-
class ArchIntRegState extends DifftestBaseBundle {
187-
val value = Vec(32, UInt(64.W))
194+
class ArchRegState(numRegs: Int) extends DifftestBaseBundle {
195+
val value = Vec(numRegs, UInt(64.W))
188196

189-
def apply(i: UInt): UInt = value(i(4, 0))
197+
def apply(i: UInt): UInt = value(i(log2Ceil(numRegs), 0))
190198
def apply(i: Int): UInt = value(i)
191-
192199
def toSeq: Seq[UInt] = value
193-
def names: Seq[String] = Seq(
194-
"$0", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2",
195-
"s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6",
196-
)
197200

198-
def ===(that: ArchIntRegState): Bool = {
201+
def ===(that: ArchRegState): Bool = {
199202
VecInit(value.zip(that.value).map(v => v._1 === v._2)).asUInt.andR
200203
}
201-
def =/=(that: ArchIntRegState): Bool = {
204+
def =/=(that: ArchRegState): Bool = {
202205
VecInit(value.zip(that.value).map(v => v._1 =/= v._2)).asUInt.orR
203206
}
204207
}
205208

209+
class ArchIntRegState extends ArchRegState(32) {
210+
def names: Seq[String] = Seq(
211+
"$0", "ra", "sp", "gp", "tp", "t0", "t1", "t2", "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7", "s2",
212+
"s3", "s4", "s5", "s6", "s7", "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6",
213+
)
214+
}
215+
206216
class ArchFpRegState extends ArchIntRegState {
207217
override def names: Seq[String] = Seq(
208218
"ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
209219
"fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11",
210220
)
211221
}
212222

213-
class ArchVecRegState extends DifftestBaseBundle {
214-
val value = Vec(64, UInt(64.W))
215-
}
223+
class ArchVecRegState extends ArchRegState(64)
216224

217225
class ArchDelayedUpdate(val numElements: Int) extends DifftestBaseBundle with HasValid with HasAddress {
218226
val data = UInt(64.W)

src/main/scala/Difftest.scala

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,7 @@ class DiffArchFpDelayedUpdate extends DiffArchDelayedUpdate(32) {
351351
override val desiredCppName: String = "regs_fp_delayed"
352352
}
353353

354-
class DiffArchFpRegState extends ArchIntRegState with DifftestBundle {
354+
class DiffArchFpRegState extends DiffArchIntRegState {
355355
override val desiredCppName: String = "regs_fp"
356356
override val desiredOffset: Int = 2
357357
override val updateDependency: Seq[String] = Seq("commit", "event")
@@ -365,6 +365,43 @@ class DiffArchVecRegState extends ArchVecRegState with DifftestBundle {
365365
override val supportsDelta: Boolean = true
366366
}
367367

368+
abstract class DiffArchRenameTable(numRegs: Int, val numPhyRegs: Int)
369+
extends ArchRenameTable(numRegs, numPhyRegs)
370+
with DifftestBundle {
371+
override val updateDependency: Seq[String] = Seq("commit", "event")
372+
override val supportsDelta: Boolean = true
373+
override def classArgs: Map[String, Any] = Map("numPhyRegs" -> numPhyRegs)
374+
}
375+
376+
class DiffArchIntRenameTable(numPhyRegs: Int) extends DiffArchRenameTable(32, numPhyRegs) {
377+
override val desiredCppName: String = "rat_int"
378+
}
379+
380+
class DiffArchFpRenameTable(numPhyRegs: Int) extends DiffArchRenameTable(32, numPhyRegs) {
381+
override val desiredCppName: String = "rat_fp"
382+
}
383+
384+
class DiffArchVecRenameTable(numPhyRegs: Int) extends DiffArchRenameTable(64, numPhyRegs) {
385+
override val desiredCppName: String = "rat_vec"
386+
}
387+
388+
abstract class DiffPhyRegState(val numPhyRegs: Int) extends PhyRegState(numPhyRegs) with DifftestBundle {
389+
override val supportsDelta: Boolean = true
390+
override def classArgs: Map[String, Any] = Map("numPhyRegs" -> numPhyRegs)
391+
}
392+
393+
class DiffPhyIntRegState(numPhyRegs: Int) extends DiffPhyRegState(numPhyRegs) {
394+
override val desiredCppName: String = "pregs_int"
395+
}
396+
397+
class DiffPhyFpRegState(numPhyRegs: Int) extends DiffPhyRegState(numPhyRegs) {
398+
override val desiredCppName: String = "pregs_fp"
399+
}
400+
401+
class DiffPhyVecRegState(numPhyRegs: Int) extends DiffPhyRegState(numPhyRegs) {
402+
override val desiredCppName: String = "pregs_vec"
403+
}
404+
368405
class DiffVecCSRState extends VecCSRState with DifftestBundle {
369406
override val desiredCppName: String = "vcsr"
370407
override val desiredOffset: Int = 5

src/main/scala/Gateway.scala

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ case class GatewayConfig(
4747
traceDump: Boolean = false,
4848
traceLoad: Boolean = false,
4949
hierarchicalWiring: Boolean = false,
50+
softArchUpdate: Boolean = false,
5051
isFPGA: Boolean = false,
5152
isGSIM: Boolean = false,
5253
) {
@@ -62,8 +63,8 @@ case class GatewayConfig(
6263
def hasDeferredResult: Boolean = isNonBlock || hasInternalStep
6364
def needTraceInfo: Boolean = hasReplay
6465
def needEndpoint: Boolean =
65-
hasGlobalEnable || hasDutZone || isBatch || isSquash || hierarchicalWiring || traceDump || traceLoad
66-
def needPreprocess: Boolean = hasDutZone || isBatch || isSquash || needTraceInfo
66+
hasGlobalEnable || hasDutZone || isBatch || isSquash || hierarchicalWiring || traceDump || traceLoad || needPreprocess
67+
def needPreprocess: Boolean = hasDutZone || isBatch || isSquash || needTraceInfo || !softArchUpdate
6768
def useDPICtype: Boolean = !isFPGA && !isGSIM
6869
// Macros Generation for Cpp and Verilog
6970
def cppMacros: Seq[String] = {
@@ -161,6 +162,7 @@ object Gateway {
161162
case 'H' => config = config.copy(hierarchicalWiring = true)
162163
case 'F' => config = config.copy(isFPGA = true)
163164
case 'G' => config = config.copy(isGSIM = true)
165+
case 'U' => config = config.copy(softArchUpdate = true)
164166
case x => println(s"Unknown Gateway Config $x")
165167
}
166168
config.check()
@@ -182,6 +184,15 @@ object Gateway {
182184
bundle
183185
}
184186

187+
def getInstance(bundles: Seq[DifftestBundle]): Seq[DifftestBundle] = {
188+
val archRegs = if (!bundles.exists(_.desiredCppName == "regs_int")) {
189+
Preprocess.getArchRegs(bundles, false)
190+
} else {
191+
Seq.empty
192+
}
193+
bundles ++ archRegs
194+
}
195+
185196
def collect(): GatewayResult = {
186197
val instances = instanceWithDelay.map(_._1).toSeq
187198
val sink = if (config.needEndpoint) {
@@ -197,14 +208,14 @@ object Gateway {
197208
val endpoint = Module(new GatewayEndpoint(instanceWithDelay.toSeq, config))
198209
endpoint.in := gatewayIn
199210
GatewayResult(
200-
instances = endpoint.instances,
211+
instances = getInstance(endpoint.instances),
201212
structPacked = Some(config.isBatch),
202213
structAligned = Some(config.isDelta),
203214
step = Some(endpoint.step),
204215
fpgaIO = endpoint.fpgaIO,
205216
)
206217
} else {
207-
GatewayResult(instances = instances) + GatewaySink.collect(config)
218+
GatewayResult(instances = getInstance(instances)) + GatewaySink.collect(config)
208219
}
209220
sink + GatewayResult(
210221
cppMacros = config.cppMacros,
@@ -229,7 +240,7 @@ class GatewayEndpoint(instanceWithDelay: Seq[(DifftestBundle, Int)], config: Gat
229240
}
230241

231242
val preprocessed = if (config.needPreprocess) {
232-
WireInit(Preprocess(bundle))
243+
WireInit(Preprocess(bundle, config))
233244
} else {
234245
WireInit(bundle)
235246
}

0 commit comments

Comments
 (0)