Skip to content

Commit ab7c417

Browse files
authored
[svsim] Fix initial ordering issue (#4614)
Fix a bug in svsim where the entire simulation is run inside an `initial` block from a generated testbench. This creates undefined simulation ordering with `initial` blocks in the simulated modules. Fix this by switching to an explicit state machine inside the testbench. Fixes #3962. Signed-off-by: Schuyler Eldridge <[email protected]>
1 parent 757b9c0 commit ab7c417

File tree

4 files changed

+59
-2
lines changed

4 files changed

+59
-2
lines changed

svsim/src/main/scala/Workspace.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,14 @@ final class Workspace(
141141
}
142142
l(" // Simulation")
143143
l(" import \"DPI-C\" context task simulation_body();")
144-
l(" initial begin")
145-
l(" simulation_body();")
144+
l(" enum {INIT, RUN, DONE} simulationState = INIT;")
145+
l(" initial")
146+
l(" simulationState = RUN;")
147+
l(" always @(simulationState) begin")
148+
l(" if (simulationState == RUN) begin")
149+
l(" simulation_body();")
150+
l(" simulationState = DONE;")
151+
l(" end")
146152
l(" end")
147153
l(" `ifdef ", Backend.HarnessCompilationFlags.supportsDelayInPublicFunctions)
148154
l(" export \"DPI-C\" task run_simulation;")
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// SPDX-License-Identifier: Apache-2.0
2+
3+
module Initial(output b);
4+
5+
reg a = 1'b0;
6+
7+
assign b = a;
8+
9+
initial
10+
a = 1'b1;
11+
12+
endmodule

svsim/src/test/scala/BackendSpec.scala

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import org.scalatest.funspec.AnyFunSpec
66
import org.scalatest.matchers.must.Matchers
77
import svsim._
88
import java.io.{BufferedReader, FileReader}
9+
import svsimTests.Resources.TestWorkspace
910

1011
class VCSSpec extends BackendSpec {
1112
import vcs.Backend.CompilationSettings._
@@ -272,6 +273,29 @@ trait BackendSpec extends AnyFunSpec with Matchers {
272273
}
273274
}
274275
}
276+
277+
it("handles initial statements correctly (#3962)") {
278+
workspace.reset()
279+
workspace.elaborateInitialTest()
280+
workspace.generateAdditionalSources()
281+
simulation = workspace.compile(
282+
backend
283+
)(
284+
workingDirectoryTag = name,
285+
commonSettings = CommonCompilationSettings(),
286+
backendSpecificSettings = compilationSettings,
287+
customSimulationWorkingDirectory = None,
288+
verbose = false
289+
)
290+
simulation.run(
291+
verbose = false,
292+
executionScriptLimit = None
293+
) { controller =>
294+
controller.port("b").check(isSigned = false) { value =>
295+
assert(value.asBigInt === 1)
296+
}
297+
}
298+
}
275299
}
276300
}
277301
}

svsim/src/test/scala/Resources.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,5 +116,20 @@ object Resources {
116116
)
117117
)
118118
}
119+
def elaborateInitialTest(): Unit = {
120+
workspace.addPrimarySourceFromResource(getClass, "/Initial.sv")
121+
workspace.elaborate(
122+
ModuleInfo(
123+
name = "Initial",
124+
ports = Seq(
125+
new ModuleInfo.Port(
126+
name = "b",
127+
isSettable = false,
128+
isGettable = true
129+
)
130+
)
131+
)
132+
)
133+
}
119134
}
120135
}

0 commit comments

Comments
 (0)