Skip to content

Commit

Permalink
squash: allow enabling/disabling during simulation (OpenXiangShan#199)
Browse files Browse the repository at this point in the history
We add a Blackbox with an exported C/C++ task and a Verilog argument
parser to control the enable bit for Squash.

For now, the Verilog argument can only specify a cycle counter to
disable the Squash after exceeding specific clock cycles.
  • Loading branch information
poemonsense authored Oct 21, 2023
1 parent 00996fa commit f3b5197
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 1 deletion.
59 changes: 58 additions & 1 deletion src/main/scala/Squash.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package difftest.squash

import chisel3._
import chisel3.experimental.ExtModule
import chisel3.util._
import chisel3.util.experimental.BoringUtils
import difftest._
Expand Down Expand Up @@ -79,8 +80,12 @@ class SquashEndpoint(bundles: Seq[DifftestBundle]) extends Module {
val supportsSquashBaseVec = VecInit(state.map(_.supportsSquashBase).toSeq)
val supportsSquashBase = supportsSquashBaseVec.asUInt.andR

val control = Module(new SquashControl)
control.clock := clock
control.reset := reset

// Submit the pending non-squashable events immediately.
val should_tick = !supportsSquash || !supportsSquashBase || tick_first_commit
val should_tick = !control.enable || !supportsSquash || !supportsSquashBase || tick_first_commit
out := Mux(should_tick, state, 0.U.asTypeOf(MixedVec(bundles)))

// Sometimes, the bundle may have squash dependencies.
Expand Down Expand Up @@ -126,3 +131,55 @@ class SquashEndpoint(bundles: Seq[DifftestBundle]) extends Module {
}
}
}

class SquashControl extends ExtModule with HasExtModuleInline {
val clock = IO(Input(Clock()))
val reset = IO(Input(Reset()))
val enable = IO(Output(Bool()))

setInline("SquashControl.v",
"""
|module SquashControl(
| input clock,
| input reset,
| output reg enable
|);
|
|initial begin
| enable = 1'b1;
|end
|
|// For the C/C++ interface
|export "DPI-C" task set_squash_enable;
|task set_squash_enable(int en);
| enable = en;
|endtask
|
|// For the simulation argument +squash_cycles=N
|reg [63:0] squash_cycles;
|initial begin
| squash_cycles = 0;
| if ($test$plusargs("squash-cycles")) begin
| $value$plusargs("squash-cycles=%d", squash_cycles);
| $display("set squash cycles: %d", squash_cycles);
| end
|end
|
|reg [63:0] n_cycles;
|always @(posedge clock) begin
| if (reset) begin
| n_cycles <= 64'h0;
| end
| else begin
| n_cycles <= n_cycles + 64'h1;
| if (squash_cycles > 0 && n_cycles >= squash_cycles) begin
| enable = 0;
| end
| end
|end
|
|
|endmodule;
|""".stripMargin
)
}
16 changes: 16 additions & 0 deletions src/test/csrc/difftest/difftest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include "ram.h"
#include "flash.h"
#include "spikedasm.h"
#ifdef CONFIG_DIFFTEST_SQUASH
#include "svdpi.h"
#endif // CONFIG_DIFFTEST_SQUASH

Difftest **difftest = NULL;

Expand Down Expand Up @@ -72,6 +75,19 @@ void difftest_finish() {
difftest = NULL;
}

#ifdef CONFIG_DIFFTEST_SQUASH
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());
}
#endif // CONFIG_DIFFTEST_SQUASH

Difftest::Difftest(int coreid) : id(coreid) {
state = new DiffState();

Expand Down
4 changes: 4 additions & 0 deletions src/test/csrc/difftest/difftest.h
Original file line number Diff line number Diff line change
Expand Up @@ -355,4 +355,8 @@ void difftest_finish();
void difftest_trace();
int init_nemuproxy(size_t);

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

#endif

0 comments on commit f3b5197

Please sign in to comment.