Skip to content

Commit

Permalink
InternalStep: pack Data transmit and Step control (#294)
Browse files Browse the repository at this point in the history
* Configurable batchByteLen:
For better performace without GFIFO. In palladium, we can pass maximum 4000 byte in Gfifo Func (enable isNonBlock), and 8000 byte in Other Func. With configurable byteLen, speed will increase from 70 K to 98 K without GFIFO.

* Interval step: pack Data transmit and Step control
Previous when batch is not supported, we use multiple DPIC func to transmit DiffState. Since the DPIC order in one beat is uncertain, we use the step to mark the transmission is finished.

With batch mode, data will be transmit at single func, so we can also pack step to reduce sync times. It can reduce DPIC calls to half. Speed will increase from 95 K to 98 K without GFIFO, 26 K to 27.5 K with GFIFO.

When IntervalStep is enable, step in TOP IO will be default 0. We hold this unused signal for fixed TOP IO interface.

By the way, when the feature is supported. DUT will only use a single port to interface with REF. This helps us to migrate Difftest for other platform.
  • Loading branch information
klin02 authored Mar 4, 2024
1 parent 1a0a0a0 commit bb991c9
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 17 deletions.
36 changes: 34 additions & 2 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -321,18 +321,50 @@ jobs:
./build/simv +workload=./ready-to-run/microbench.bin +e=0 +diff=./ready-to-run/riscv64-nemu-interpreter-so
cd difftest && git restore src
- name: Verilator Build with VCS Top (with GlobalEnable DutZone Squash SquashReplay Batch PerfCnt)
- name: Verilator Build with VCS Top (with Batch InternalStep PerfCnt)
run: |
cd $GITHUB_WORKSPACE/../xs-env
source ./env.sh
cd $GITHUB_WORKSPACE/../xs-env/NutShell
source ./env.sh
make clean
sed -i 's/isBatch: Boolean = false/isBatch: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/hasInternalStep: Boolean = false/hasInternalStep: Boolean = true/' difftest/src/main/scala/Gateway.scala
make simv DIFFTEST_PERFCNT=1 VCS=verilator -j2
./build/simv +workload=./ready-to-run/microbench.bin +e=0 +no-diff +max-cycles=100000
./build/simv +workload=./ready-to-run/microbench.bin +e=0 +diff=./ready-to-run/riscv64-nemu-interpreter-so
cd difftest && git restore src
- name: Verilator Build with VCS Top (with DutZone GlobalEnable Squash SquashReplay Batch PerfCnt)
run: |
cd $GITHUB_WORKSPACE/../xs-env
source ./env.sh
cd $GITHUB_WORKSPACE/../xs-env/NutShell
source ./env.sh
make clean
sed -i 's/isSquash: Boolean = false/isSquash: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/hasDutZone: Boolean = false/hasDutZone: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/hasGlobalEnable: Boolean = false/hasGlobalEnable: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/isSquash: Boolean = false/isSquash: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/squashReplay: Boolean = false/squashReplay: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/isBatch: Boolean = false/isBatch: Boolean = true/' difftest/src/main/scala/Gateway.scala
make simv DIFFTEST_PERFCNT=1 VCS=verilator -j2
./build/simv +workload=./ready-to-run/microbench.bin +e=0 +no-diff +max-cycles=100000
./build/simv +workload=./ready-to-run/microbench.bin +e=0 +diff=./ready-to-run/riscv64-nemu-interpreter-so
cd difftest && git restore src
- name: Verilator Build with VCS Top (with GlobalEnable Squash SquashReplay Batch InternalStep NonBlock PerfCnt)
run: |
cd $GITHUB_WORKSPACE/../xs-env
source ./env.sh
cd $GITHUB_WORKSPACE/../xs-env/NutShell
source ./env.sh
make clean
sed -i 's/hasGlobalEnable: Boolean = false/hasGlobalEnable: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/isSquash: Boolean = false/isSquash: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/squashReplay: Boolean = false/squashReplay: 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/hasInternalStep: Boolean = false/hasInternalStep: Boolean = true/' difftest/src/main/scala/Gateway.scala
sed -i 's/isNonBlock: Boolean = false/isNonBlock: Boolean = true/' difftest/src/main/scala/Gateway.scala
make simv DIFFTEST_PERFCNT=1 VCS=verilator -j2
./build/simv +workload=./ready-to-run/microbench.bin +e=0 +no-diff +max-cycles=100000
./build/simv +workload=./ready-to-run/microbench.bin +e=0 +diff=./ready-to-run/riscv64-nemu-interpreter-so
Expand Down
4 changes: 2 additions & 2 deletions src/main/scala/Batch.scala
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,12 @@ class BatchEndpoint(template: Seq[DifftestBundle], bundles: Seq[DifftestBundle],
Delayer(gen.bits.getValid & global_enable, i)
}.toSeq)

val MaxDataByteLen = 3900
val MaxDataByteLen = config.batchArgByteLen._1
val MaxDataByteWidth = log2Ceil(MaxDataByteLen)
val MaxDataBitLen = MaxDataByteLen * 8
val infoWidth = (new BatchInfo).getWidth
// Append BatchInterval and BatchFinish Info
val MaxInfoByteLen = math.min((config.batchSize * (bundleNum + 1) + 1) * (infoWidth / 8), 90)
val MaxInfoByteLen = math.min((config.batchSize * (bundleNum + 1) + 1) * (infoWidth / 8), config.batchArgByteLen._2)
val MaxInfoByteWidth = log2Ceil(MaxInfoByteLen)
val MaxInfoBitLen = MaxInfoByteLen * 8

Expand Down
15 changes: 14 additions & 1 deletion src/main/scala/DPIC.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ abstract class DPICBase(config: GatewayConfig) extends ExtModule with HasExtModu
val clock = IO(Input(Clock()))
val enable = IO(Input(Bool()))
val dut_zone = Option.when(config.hasDutZone)(IO(Input(UInt(config.dutZoneWidth.W))))
val step = Option.when(config.hasInternalStep)(IO(Input(UInt(config.stepWidth.W))))

def getDirectionString(data: Data): String = {
if (DataMirror.directionOf(data) == ActualDirection.Input) "input " else "output"
Expand Down Expand Up @@ -60,7 +61,9 @@ abstract class DPICBase(config: GatewayConfig) extends ExtModule with HasExtModu

protected val commonPorts = Seq(("clock", clock), ("enable", enable))
def modPorts: Seq[Seq[(String, Data)]] = {
val ports = if (config.hasDutZone) commonPorts ++ Seq(("dut_zone", dut_zone.get)) else commonPorts
var ports = commonPorts
if (config.hasDutZone) ports ++= Seq(("dut_zone", dut_zone.get))
if (config.hasInternalStep) ports ++= Seq(("step", step.get))
ports.map(Seq(_))
}

Expand Down Expand Up @@ -91,12 +94,20 @@ abstract class DPICBase(config: GatewayConfig) extends ExtModule with HasExtModu
|""".stripMargin
}

def internalStep: String = if (config.hasInternalStep)
"""
|extern void simv_nstep(uint8_t step);
|simv_nstep(step);
|""".stripMargin
else ""

def dpicFunc: String =
s"""
|$dpicFuncProto {
| if (!diffstate_buffer) return;
|$perfCnt
| ${dpicFuncAssigns.mkString("\n ")}
| $internalStep
|}
|""".stripMargin

Expand Down Expand Up @@ -266,6 +277,7 @@ private class DummyDPICWrapper(gen: DifftestBundle, config: GatewayConfig) exten
dpic.clock := clock
dpic.enable := io.bits.getValid && control.enable
if (config.hasDutZone) dpic.dut_zone.get := control.dut_zone.get
if (config.hasInternalStep) dpic.step.get := control.step.get
dpic.io := io
}

Expand All @@ -280,6 +292,7 @@ private class DummyDPICBatchWrapper(
dpic.clock := clock
dpic.enable := control.enable
if (config.hasDutZone) dpic.dut_zone.get := control.dut_zone.get
if (config.hasInternalStep) dpic.step.get := control.step.get
dpic.io := io
}

Expand Down
24 changes: 19 additions & 5 deletions src/main/scala/Gateway.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,18 @@ case class GatewayConfig(
hasDutZone: Boolean = false,
isBatch: Boolean = false,
batchSize: Int = 32,
hasInternalStep: Boolean = false,
isNonBlock: Boolean = false,
) {
if (squashReplay) require(isSquash)
if (hasInternalStep) require(isBatch)
def dutZoneSize: Int = if (hasDutZone) 2 else 1
def dutZoneWidth: Int = log2Ceil(dutZoneSize)
def dutBufLen: Int = if (isBatch) batchSize else 1
def maxStep: Int = if (isBatch) batchSize else 1
def stepWidth: Int = log2Ceil(maxStep + 1)
def hasDeferredResult: Boolean = isNonBlock
def batchArgByteLen: (Int, Int) = if (isNonBlock) (3904, 90) else (7800, 190)
def hasDeferredResult: Boolean = isNonBlock || hasInternalStep
def needTraceInfo: Boolean = squashReplay
def needEndpoint: Boolean = hasGlobalEnable || hasDutZone || isBatch || isSquash
def needPreprocess: Boolean = hasDutZone || isBatch || isSquash || needTraceInfo
Expand All @@ -56,13 +59,15 @@ case class GatewayConfig(
if (isSquash) macros += "CONFIG_DIFFTEST_SQUASH"
if (squashReplay) macros += "CONFIG_DIFFTEST_SQUASH_REPLAY"
if (hasDeferredResult) macros += "CONFIG_DIFFTEST_DEFERRED_RESULT"
if (hasInternalStep) macros += "CONFIG_DIFFTEST_INTERNAL_STEP"
macros.toSeq
}
def vMacros: Seq[String] = {
val macros = ListBuffer.empty[String]
macros += s"CONFIG_DIFFTEST_STEPWIDTH ${stepWidth}"
if (isNonBlock) macros += "CONFIG_DIFFTEST_NONBLOCK"
if (hasDeferredResult) macros += "CONFIG_DIFFTEST_DEFERRED_RESULT"
if (hasInternalStep) macros += "CONFIG_DIFFTEST_INTERNAL_STEP"
macros.toSeq
}
}
Expand Down Expand Up @@ -115,7 +120,7 @@ object Gateway {
GatewayResult(
instances = endpoint.instances,
structPacked = Some(config.isBatch),
step = Some(endpoint.step),
step = endpoint.step,
)
} else {
GatewaySink.collect(config)
Expand Down Expand Up @@ -149,13 +154,17 @@ class GatewayEndpoint(signals: Seq[DifftestBundle], config: GatewayConfig) exten
}

val zoneControl = Option.when(config.hasDutZone)(Module(new ZoneControl(config)))
val step = IO(Output(UInt(config.stepWidth.W)))
val step = Option.when(!config.hasInternalStep)(IO(Output(UInt(config.stepWidth.W))))
val control = Wire(new GatewaySinkControl(config))

if (config.isBatch) {
val template = Batch.getTemplate(squashed)
val batch = Batch(template, squashed, config)
step := RegNext(batch.step, 0.U)
if (config.hasInternalStep) {
control.step.get := batch.step
} else {
step.get := RegNext(batch.step, 0.U)
}
control.enable := batch.enable
if (config.hasDutZone) {
zoneControl.get.enable := batch.enable
Expand All @@ -168,7 +177,11 @@ class GatewayEndpoint(signals: Seq[DifftestBundle], config: GatewayConfig) exten
if (config.hasGlobalEnable) {
squashed_enable := VecInit(squashed.flatMap(_.bits.needUpdate).toSeq).asUInt.orR
}
step := RegNext(squashed_enable, 0.U)
if (config.hasInternalStep) {
control.step.get := squashed_enable
} else {
step.get := RegNext(squashed_enable, 0.U)
}
control.enable := squashed_enable
if (config.hasDutZone) {
zoneControl.get.enable := squashed_enable
Expand Down Expand Up @@ -210,6 +223,7 @@ object GatewaySink {
class GatewaySinkControl(config: GatewayConfig) extends Bundle {
val enable = Bool()
val dut_zone = Option.when(config.hasDutZone)(UInt(config.dutZoneWidth.W))
val step = Option.when(config.hasInternalStep)(UInt(config.stepWidth.W))
}

object Preprocess {
Expand Down
6 changes: 4 additions & 2 deletions src/test/csrc/vcs/vcs_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,15 @@ extern "C" void simv_nstep(uint8_t step) {
return;
#else
extern "C" uint8_t simv_nstep(uint8_t step) {
if (difftest == NULL)
return 0;
#endif // CONFIG_DIFFTEST_DEFERRED_RESULT
#ifdef CONFIG_DIFFTEST_PERFCNT
#ifndef CONFIG_DIFFTEST_INTERNAL_STEP
difftest_calls[perf_simv_nstep]++;
difftest_bytes[perf_simv_nstep] += 1;
#endif // CONFIG_DIFFTEST_INTERNAL_STEP
#endif // CONFIG_DIFFTEST_PERFCNT
if (difftest == NULL)
return 0;
difftest_switch_zone();
for (int i = 0; i < step; i++) {
int ret = simv_step();
Expand Down
15 changes: 10 additions & 5 deletions src/test/vsrc/vcs/DeferredControl.v
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
module DeferredControl(
input clock,
input reset,
`ifndef CONFIG_DIFFTEST_INTERNAL_STEP
input [`CONFIG_DIFFTEST_STEPWIDTH - 1:0] step,
`endif // CONFIG_DIFFTEST_INTERNAL_STEP
output reg [7:0] simv_result
);

import "DPI-C" function void simv_nstep(byte step);
import "DPI-C" context function void set_deferred_result_scope();

initial begin
Expand All @@ -20,15 +21,18 @@ function void set_deferred_result(byte result);
simv_result = result;
endfunction

`ifdef CONFIG_DIFFTEST_NONBLOCK
`ifdef PALLADIUM
initial $ixc_ctrl("gfifo", "simv_nstep");
initial $ixc_ctrl("sfifo", "set_deferred_result");
`endif // PALLADIUM
`endif // CONFIG_DIFFTEST_NONBLOCK

`ifndef CONFIG_DIFFTEST_INTERNAL_STEP
import "DPI-C" function void simv_nstep(int step);

`ifdef CONFIG_DIFFTEST_NONBLOCK
`ifdef PALLADIUM
initial $ixc_ctrl("sfifo", "set_deferred_result");
initial $ixc_ctrl("gfifo", "simv_nstep");
`endif // PALLADIUM
`endif // CONFIG_DIFFTEST_NONBLOCK

always @(posedge clock) begin
if (reset) begin
Expand All @@ -38,6 +42,7 @@ always @(posedge clock) begin
simv_nstep(step);
end
end
`endif // CONFIG_DIFFTEST_INTERNAL_STEP

endmodule;
`endif // CONFIG_DIFFTEST_DEFERRED_RESULT
2 changes: 2 additions & 0 deletions src/test/vsrc/vcs/top.v
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,9 @@ wire [7:0] simv_result;
DeferredControl deferred(
.clock(clock),
.reset(reset),
`ifndef CONFIG_DIFFTEST_INTERNAL_STEP
.step(difftest_step),
`endif // CONFIG_DIFFTEST_INTERNAL_STEP
.simv_result(simv_result)
);
`else
Expand Down

0 comments on commit bb991c9

Please sign in to comment.