Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Squash: move into Gateway, get Scope from initial #222

Merged
merged 1 commit into from
Dec 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ jobs:
source ./env.sh
make clean
sed -i 's/hasGlobalEnable: Boolean = false/hasGlobalEnable: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/isEffective: Boolean = false/isEffective: Boolean = true/' difftest/src/main/scala/Squash.scala
sed -i 's/isSquash : Boolean = false/isSquash : Boolean = true/' difftest/src/main/scala/Gateway.scala
make emu
./build/emu -b 0 -e 0 -i ./ready-to-run/microbench.bin --diff ./ready-to-run/riscv64-nemu-interpreter-so
cd difftest && git restore src
Expand All @@ -195,7 +195,7 @@ jobs:
cd $GITHUB_WORKSPACE/../xs-env/NutShell
source ./env.sh
make clean
sed -i 's/isEffective: Boolean = false/isEffective: Boolean = true/' difftest/src/main/scala/Squash.scala
sed -i 's/isSquash : Boolean = false/isSquash : Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/isBatch : Boolean = false/isBatch : Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/hasGlobalEnable: Boolean = false/hasGlobalEnable: Boolean = true/' difftest/src/main/scala/Gateway.scala
make emu
Expand Down Expand Up @@ -265,7 +265,7 @@ jobs:
cd $GITHUB_WORKSPACE/../xs-env/NutShell
source ./env.sh
make clean
sed -i 's/isEffective: Boolean = false/isEffective: Boolean = true/' difftest/src/main/scala/Squash.scala
sed -i 's/isSquash : Boolean = false/isSquash : Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/isBatch : Boolean = false/isBatch : Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/hasGlobalEnable: Boolean = false/hasGlobalEnable: Boolean = true/' difftest/src/main/scala/Gateway.scala
make simv VCS=verilator
Expand Down
4 changes: 1 addition & 3 deletions src/main/scala/Difftest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package difftest

import chisel3._
import difftest.gateway.Gateway
import difftest.squash.Squash

import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Paths}
Expand Down Expand Up @@ -287,7 +286,7 @@ object DifftestModule {
if (enabled) {
val id = register(gen, style)
val sink = Gateway(gen, style)
sink := Squash(Delayer(difftest, delay))
sink := Delayer(difftest, delay)
sink.coreid := difftest.coreid
}
if (dontCare) {
Expand All @@ -312,7 +311,6 @@ object DifftestModule {
macros ++= gateway_tuple._1
difftest.step := gateway_tuple._2

macros ++= Squash.collect()
if (cppHeader.isDefined) {
generateCppHeader(cpu, cppHeader.get)
}
Expand Down
40 changes: 26 additions & 14 deletions src/main/scala/Gateway.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ import chisel3.util._
import chisel3.util.experimental.BoringUtils
import difftest._
import difftest.dpic.DPIC
import difftest.squash.Squash

import scala.collection.mutable.ListBuffer

case class GatewayConfig(
style : String = "dpic",
hasGlobalEnable: Boolean = false,
isSquash : Boolean = false,
diffStateSelect: Boolean = false,
isBatch : Boolean = false,
batchSize : Int = 32
Expand Down Expand Up @@ -80,10 +82,9 @@ class GatewayEndpoint(signals: Seq[DifftestBundle], config: GatewayConfig) exten
BoringUtils.addSink(data, s"gateway_$id")
in(id) := data.asTypeOf(in(id).cloneType)
}
val out = WireInit(in)
val out_pack = WireInit(in_pack)

if (config.hasDutPos) {
val share_wbint = WireInit(in)
if (config.hasDutPos || config.isSquash) {
// Special fix for int writeback. Work for single-core only
if (in.exists(_.desiredCppName == "wb_int")) {
require(in.count(_.isUniqueIdentifier) == 1, "only single-core is supported yet")
Expand All @@ -99,7 +100,7 @@ class GatewayEndpoint(signals: Seq[DifftestBundle], config: GatewayConfig) exten
val commits = in.filter(_.desiredCppName == "commit").map(_.asInstanceOf[DiffInstrCommit])
val num_skip = PopCount(commits.map(c => c.valid && c.skip))
assert(num_skip <= 1.U, p"num_skip $num_skip is larger than one. Squash not supported yet")
val wb_for_skip = out.filter(_.desiredCppName == "wb_int").head.asInstanceOf[DiffIntWriteback]
val wb_for_skip = share_wbint.filter(_.desiredCppName == "wb_int").head.asInstanceOf[DiffIntWriteback]
for (c <- commits) {
when(c.valid && c.skip) {
wb_for_skip.valid := true.B
Expand All @@ -112,22 +113,30 @@ class GatewayEndpoint(signals: Seq[DifftestBundle], config: GatewayConfig) exten
}
}
}

for ((data, id) <- out_pack.zipWithIndex) {
data := out(id).asUInt
}
}
}

val out = WireInit(share_wbint)
if (config.isSquash) {
val squash = Squash(share_wbint.toSeq.map(_.cloneType))
squash.in := share_wbint
out := squash.out
}

val out_pack = WireInit(in_pack)
for ((data, id) <- out_pack.zipWithIndex) {
data := out(id).asUInt
}

val port_num = if (config.isBatch) config.batchSize else 1
val ports = Seq.fill(port_num)(Wire(new GatewayBundle(config)))

val global_enable = WireInit(true.B)
if(config.hasGlobalEnable) {
global_enable := VecInit(in.filter(_.needUpdate.isDefined).map(_.needUpdate.get).toSeq).asUInt.orR
global_enable := VecInit(out.filter(_.needUpdate.isDefined).map(_.needUpdate.get).toSeq).asUInt.orR
}

val batch_data = Option.when(config.isBatch)(Mem(config.batchSize, in_pack.cloneType))
val batch_data = Option.when(config.isBatch)(Mem(config.batchSize, out_pack.cloneType))
val enable = WireInit(false.B)
if(config.isBatch) {
val batch_ptr = RegInit(0.U(log2Ceil(config.batchSize).W))
Expand Down Expand Up @@ -162,21 +171,24 @@ class GatewayEndpoint(signals: Seq[DifftestBundle], config: GatewayConfig) exten
if (config.isBatch) {
for (ptr <- 0 until config.batchSize) {
ports(ptr).dut_pos.get := ptr.asUInt
for(id <- 0 until in.length) {
GatewaySink(in(id).cloneType, config, ports(ptr)) := batch_data.get(ptr)(id)
for(id <- 0 until out.length) {
GatewaySink(out(id).cloneType, config, ports(ptr)) := batch_data.get(ptr)(id)
}
}
}
else {
for(id <- 0 until in.length){
GatewaySink(in(id).cloneType, config, ports.head) := out_pack(id)
for(id <- 0 until out.length){
GatewaySink(out(id).cloneType, config, ports.head) := out_pack(id)
}
}

var macros = GatewaySink.collect(config)
if (config.isBatch) {
macros ++= Seq("CONFIG_DIFFTEST_BATCH", s"DIFFTEST_BATCH_SIZE ${config.batchSize}")
}
if (config.isSquash) {
macros ++= Squash.collect()
}
}


Expand Down
61 changes: 9 additions & 52 deletions src/main/scala/Squash.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,21 @@ import difftest._
import scala.collection.mutable.ListBuffer

object Squash {
private val isEffective: Boolean = false
private val instances = ListBuffer.empty[DifftestBundle]

def apply[T <: DifftestBundle](gen: T): T = {
if (isEffective) register(gen, WireInit(0.U.asTypeOf(gen))) else gen
}

def register[T <: DifftestBundle](original: T, squashed: T): T = {
// There seems to be a bug in WiringUtils when original is some IO of Module.
// We manually add a Wire for the source to avoid the WiringException.
BoringUtils.addSource(WireInit(original), s"squash_in_${instances.length}")
BoringUtils.addSink(squashed, s"squash_out_${instances.length}")
instances += original.cloneType
squashed
def apply[T <: Seq[DifftestBundle]](bundles: T): SquashEndpoint = {
val module = Module(new SquashEndpoint(bundles))
module
}

def collect(): Seq[String] = {
if (isEffective) {
Module(new SquashEndpoint(instances.toSeq))
Seq("CONFIG_DIFFTEST_SQUASH")
}
else {
Seq()
}
Seq("CONFIG_DIFFTEST_SQUASH")
}
}

class SquashEndpoint(bundles: Seq[DifftestBundle]) extends Module {
val in = WireInit(0.U.asTypeOf(MixedVec(bundles)))
for ((data, i) <- in.zipWithIndex) {
BoringUtils.addSink(data, s"squash_in_$i")
}

val out = Wire(MixedVec(bundles))
for ((data, i) <- out.zipWithIndex) {
BoringUtils.addSource(data, s"squash_out_$i")
}
val in = IO(Input(MixedVec(bundles)))
val out = IO(Output(MixedVec(bundles)))

val state = RegInit(0.U.asTypeOf(MixedVec(bundles)))

Expand Down Expand Up @@ -106,30 +84,6 @@ class SquashEndpoint(bundles: Seq[DifftestBundle]) extends Module {
s := i.squash(s)
}
}

// Special fix for int writeback. Work for single-core only.
if (bundles.exists(_.desiredCppName == "wb_int")) {
require(bundles.count(_.isUniqueIdentifier) == 1, "only single-core is supported yet")
val writebacks = in.filter(_.desiredCppName == "wb_int").map(_.asInstanceOf[DiffIntWriteback])
val numPhyRegs = writebacks.head.numElements
val wb_int = Reg(Vec(numPhyRegs, UInt(64.W)))
for (wb <- writebacks) {
when (wb.valid) {
wb_int(wb.address) := wb.data
}
}
val commits = out.filter(_.desiredCppName == "commit").map(_.asInstanceOf[DiffInstrCommit])
val num_skip = PopCount(commits.map(c => c.valid && c.skip))
assert(num_skip <= 1.U, p"num_skip $num_skip is larger than one. Squash not supported yet")
val wb_for_skip = out.filter(_.desiredCppName == "wb_int").head.asInstanceOf[DiffIntWriteback]
for (c <- commits) {
when (c.valid && c.skip) {
wb_for_skip.valid := true.B
wb_for_skip.address := c.wpdest
wb_for_skip.data := wb_int(c.wpdest)
}
}
}
}

class SquashControl extends ExtModule with HasExtModuleInline {
Expand All @@ -145,7 +99,10 @@ class SquashControl extends ExtModule with HasExtModuleInline {
| output reg enable
|);
|
|import "DPI-C" context function void set_squash_scope();
|
|initial begin
| set_squash_scope();
| enable = 1'b1;
|end
|
Expand Down
20 changes: 12 additions & 8 deletions src/test/csrc/difftest/difftest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,19 @@ void difftest_finish() {
}

#ifdef CONFIG_DIFFTEST_SQUASH
svScope squashScope;
void set_squash_scope() {
squashScope = svGetScope();
}

extern "C" void set_squash_enable(int enable);
void difftest_squash_set(int enable, const char *scope_name = "TOP.SimTop.SquashEndpoint.control") {
auto scope = svGetScopeFromName(scope_name);
if (scope == NULL) {
printf("Error: Could not retrieve scope with name '%s'\n", scope_name);
assert(scope);
}
svSetScope(scope);
set_squash_enable(rand());
void difftest_squash_enable(int enable) {
if (squashScope == NULL) {
printf("Error: Could not retrieve squash scope, set first\n");
assert(squashScope);
}
svSetScope(squashScope);
set_squash_enable(enable);
}
#endif // CONFIG_DIFFTEST_SQUASH

Expand Down
3 changes: 2 additions & 1 deletion src/test/csrc/difftest/difftest.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ void difftest_trace_write(int step);
int init_nemuproxy(size_t);

#ifdef CONFIG_DIFFTEST_SQUASH
extern "C" void difftest_squash_set(int enable, const char *scope_name);
extern "C" void set_squash_scope();
extern "C" void difftest_squash_enable(int enable);
#endif // CONFIG_DIFFTEST_SQUASH

#endif
Loading