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

Introduce svsim, a low level library for simulating SystemVerilog using Verilator and VCS. #3121

Merged
merged 12 commits into from
Mar 21, 2023

Conversation

GeorgeLyon
Copy link
Contributor

I apologize in advance to not-SiFive folks for ramboing a 2K+ line PR (the SiFive folks have had a bit more of a gradual introduction to this). You can be the final judge, but I think it is quite clean an readable and I will be covering some of the implementation details at the next Chisel Dev meeting (3/27) if folks are interested or have questions that don't work well in a PR context.

Type of Improvement

This upstreams the svsim project, which is a simple, self-contained Scala library for compiling SystemVerilog simulations using Verilator and VCS, and then executing and controlling those simulations. We built svsim at SiFive to enable simulating MFC-emitted SystemVerilog in the absence of SFC. svsim is meant to be low-level and not used directly by hardware designers. As such, its documentation is mainly in the code and in svsim/README.md.

A subsequent PR will migrate the BasicTester infrastructure to use svsim, and clean up that API so that users of Chisel have a built-in mechanism for running simple tests. We can then document how to use chisel3.testers to enable simple unit testing of Chisel modules.

Relation to chiseltest

While svsim may draw comparisons to chiseltest, I think it is more accurate to consider svsim as a lower-level component that could be used to power chiseltest's simulation capabilities (svsim is specifically not a testing framework). The "Design" section of svsim/README.md discusses some of the things chiseltest does which are outside of the scope of svsim.

API Impact

This does not impact API.

Backend Code Generation Impact

This does not impact backend code generation.

Desired Merge Strategy

Squash

Release Notes

Added svsim, a new library for compiling and controlling SystemVerilog simulations in Scala using Verilator or VCS.

Reviewer Checklist (only modified by reviewer)

  • Did you add the appropriate labels?
  • Did you mark the proper milestone (Bug fix: 3.5.x or 3.6.x depending on impact, API modification or big change: 5.0.0)?
  • Did you review?
  • Did you check whether all relevant Contributor checkboxes have been checked?
  • Did you do one of the following when ready to merge:
    • Squash: You/ the contributor Enable auto-merge (squash), clean up the commit message, and label with Please Merge.
    • Merge: Ensure that contributor has cleaned up their commit history, then merge with Create a merge commit.

@@ -2,6 +2,14 @@ FROM --platform=$BUILDPLATFORM ubuntu:20.04

ARG TARGETARCH

# Initialize System
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes are PR-ed separately here: #3120. I'm expecting that PR to merge soon and then these will be removed from this PR.

build.sbt Outdated
} else {
"-Werror" :: Nil
}
if (sys.props.contains("disableFatalWarnings")) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like build.sbt was not formatted with the other sources, so VSCode decided to format it for me. I can undo these changes if folks care but I don't think it is a bad thing to have this file formatted.

@GeorgeLyon GeorgeLyon marked this pull request as ready for review March 20, 2023 23:00
svsim/README.md Outdated
* `svsim` simulations are also backend-independent, meaning that the same code launches and controls a simulation regardless of what backend it was compiled using.
* `svsim` backends are declarative. This means a backend only controls which executable is invoked for compilation, and what arguments are provided to that executable (either via command line or environment variables). Backends may also provide arguments to the simulation, but may not have any other specialized logic.
* Simulations are controlled using an ad-hoc protocol where commands are read from `stdin` and messages are written to `stdout`. This protocol is **not** meant to be an ABI, and can change freely between Chisel verisons.
* Communication with the simulation is pipelined, so the Scala driver can send multiple commands before processing responses from the simulation. This allows `svsim` to effectively eliminate the overhead of communicating with the simulation without resorting to JNA or Scala-side caching. This optimization can, of course, be defeated if the driver code waits on every command, but we consider this an antipattern.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am curious: did you benchmark this? Is it actually as fast as calling into a C-library function directly?

Copy link
Contributor Author

@GeorgeLyon GeorgeLyon Mar 20, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like to say the performance is "analogous". Across SiFive's test suite, svsim performed a bit faster than chiseltest (though I think the speedup was mostly due to not running any SFC at all, also storing all this stuff in maps for VCS is easy to outperform). There were some tests that slowed down a little, and these were tests which were repeatedly waiting on the value of a peek (and not just using expect, which pipelines nicely). Obviously a straight-up C function call is faster, but compiling and simulating even a small design dwarfs this performance cost pretty quickly. For many tests, there are less than 10 "commands" sent to the simulation (svsim implements TICK as a single command) so this overhead is negligible if you are not blocking on the IO.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. That makes sense. So I guess most of the SiFive tests are BasicTester style where they only wait for a stop or a failed assert?

Copy link
Contributor Author

@GeorgeLyon GeorgeLyon Mar 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are peek poke tests as well. As long as they don't have a data dependency (i.e. they only use expect and not peek) the performance is analogous (and maybe faster if it is VCS due to the map issue above)

@GeorgeLyon
Copy link
Contributor Author

@jackkoenig This test failure is confusing, could you provide any insight? https://github.com/chipsalliance/chisel/actions/runs/4473691082/jobs/7861373685?pr=3121#step:7:2576

It doesn't seem related to anything I changed, but I don't see anything that would cause it to flake and that Seq looks to very much not be of size 5? https://github.com/GeorgeLyon/chisel/blob/cc41b964b26bbbaa07e8c7b3655370c6b7d4caa7/src/test/scala/chiselTests/Vec.scala#L470-L478

--target install-firtool

# Use VSCode for writing commit messages
ENV GIT_EDITOR="code --wait"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this necessary for this PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, these are broken out in a separate PR I'm hoping to merge soon: #3120

@@ -25,8 +33,9 @@ RUN \
# Install GraalVM
# This downloads all relevant GraalVM architectures at once, mostly because $TARGETARCH values don't map exactly to the release URLs. Since we're optimizing for developer experience here and not image size, this is OK
# GraalVM release links can be found here: https://github.com/graalvm/graalvm-ce-builds/releases
ADD https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.3.1/graalvm-ce-java17-linux-aarch64-22.3.1.tar.gz /graalvm/tarballs/arm64.tar.gz
ADD https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.3.1/graalvm-ce-java17-linux-amd64-22.3.1.tar.gz /graalvm/tarballs/amd64.tar.gz
ENV JAVA_VERSION=java11
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why are we going from java17 to java11?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Java17 fails to compile what remains of FIRRTL. I didn't dig into this too deeply. Also worth calling out this is just for development. None of these are affecting the overall requirements of the Chisel project.

.devcontainer/Dockerfile Outdated Show resolved Hide resolved
@@ -334,98 +347,101 @@ lazy val chisel = (project in file("."))
.dependsOn(macros)
.dependsOn(core)
.dependsOn(firrtl)
.aggregate(macros, core, plugin, firrtl)
.dependsOn(svsim)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why does chisel the project depend on svsim? Shouldn't this go in the chisel test project dependencies, if anywhere today?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(also I don't really understand how this file works, so my question may be nonsensical)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm looking at chisel.testers to host the "glue svsim to Chisel code". This is part of the chisel project AFAICT, but I may be missing something about test vs non-test dependencies.

build.sbt Outdated
.settings(warningSuppression: _*)
.settings(fatalWarningsSettings: _*)
.settings(chiselSettings: _*)
.settings(usePluginSettings: _*)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we are going to format this file in this PR, can we make sure that the process is repeatable. What settings was vscode picking up? I guess I'd strongly prefer we make the "format the build.sbt file and make sure it stays formatted" in its own PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe these are the settings from the project. I would guess the issue is this file doesn't have a ".scala" file extension so its not picked up in CI?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree we should make this repeatable, looking in to how we can apply it to the build.sbt

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a command scalafmtSbt which will format *.sbt files and project/*.scala files. We should see if we can make this part of "all". I will say, we should do this as a separate PR rather than as part of this one just to keep the history more clear.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've created a PR to format the SBT files: #3125

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, @jackkoenig!

svsim/README.md Outdated

### Workspace

The `Workspace` manages all interaction with the filesystem. Its API is mutable, because the underlying representation (files on disk) is mutable. A `Workspace` is represented on the filesystem as a folder. The `reset()` method will delete any previous state and create the necessary folders. The `elaborate()` method takes a `ModuleInfo` which describes the SystemVerilog module to be simulated. The idea is that a higher-level framework will provide specialized `elaborate` methods which emit SystemVerilog to `primarySourcesPath`, similar to what we do with `elaborateGCD()` in `src/test/scala/Resources.scala`. For example, Chisel can provide an `elaborate[T <: RawModule](module: => T)` method. `generateAdditionalSources()` uses the `ModuleInfo` from `elaborate` and generates the test harness. Finally, `compile()` uses a `Backend` to compile the simulation. Because `svsim`'s test harness is backend-independent, `compile` may be called multiple times with different settings or different backends to create multiple `Simulation`s (a `workingDirectoryTag` is provided so that mutliple simulations are output to separate directories).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit can we wrap this file either at 80 characters or at punctuation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a Workspace thread-safe or should it only ever be called from a single thread?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a lint/format pass we can do to add this? My IDE just auto-wraps, but I can also do this manually.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is a Workspace thread-safe or should it only ever be called from a single thread?

It is not explicitly thread safe, though you could theoretically run multiple compile invocations on multiple threads. Not sure why you would want to do that though. Simulation could be made thread-safe but currently the simulation logs would bork each other. I'd be interested in exploring this more if we ended up with a concrete use case that we want to support.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we just have to tell the .scalafmt.conf to target files with sbt extension as well

Copy link
Contributor Author

@GeorgeLyon GeorgeLyon Mar 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think we just have to tell the .scalafmt.conf to target files with sbt extension as well

This is an md file, and I don't see anything in the conf related to file extensions. I also don't see an option to do this in VSCode (independent of scalafmt)... do folks just manually add returns? Seems onerous...

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh sorry didn't realize your question was for this thread.

I have my vscode to set the .md width to 80

svsim/README.md Outdated

### `make replay`

`svsim` by default emits an `execution-script.txt` when running a Simulation. This script captures all commands sent to the simulation, which enables `svsim` to add a second target to the `Makefile`: `make replay`. `make replay` rebuilds the simulation, picking up any changes as mentioned above, and then replays the commands that were sent by `Simulation.Controller` verbatim. This allows replaying most tests without having to re-run the Scala code, potentially with manual modifications to either the SystemVerilog or the test harness (though tests which modify their behavior based on values read from the `Simulation` may not be replayed faithfully).
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we document the format of this replay file here? If not here, where is it documented? I see that it is not an ABI but it is a thing that if you're telling people they can edit we should at least point them to what the current format is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to specifically leave it un-documented (though simulation-driver.c has some pretty explicit documentation) mostly because of the "This is not an ABI" point above, and folks shouldn't be using it across Chisel versions.

@jackkoenig
Copy link
Contributor

jackkoenig commented Mar 21, 2023

@jackkoenig This test failure is confusing, could you provide any insight? https://github.com/chipsalliance/chisel/actions/runs/4473691082/jobs/7861373685?pr=3121#step:7:2576

What looks like the failure isn't really the failure, the red there is coming from Chisel but that's an expected failure. If you scroll up on the logic you can see other similar examples. We really ought to fix Chisel's error reporting so that it doesn't show up here 😬

The real failure is in compilation of svsim above:

[info] Setting Scala version to 2.12.17 on 10 projects.
[info] Reapplying settings...
[info] set current project to chisel (in build file:/home/runner/work/chisel/chisel/)
[info] compiling 4 Scala sources to /home/runner/work/chisel/chisel/plugin/target/scala-2.12.17/classes ...
[info] Non-compiled module 'compiler-bridge_2.12' for Scala 2.12.17. Compiling...
[info] compiling 6 Scala sources to /home/runner/work/chisel/chisel/macros/target/scala-2.12/classes ...
[info]   Compilation completed in 10.646s.
[info] done compiling
[info] compiling 5 Scala sources to /home/runner/work/chisel/chisel/svsim/target/scala-2.12/classes ...
[info] done compiling
[info] compiling 60 Scala sources to /home/runner/work/chisel/chisel/firrtl/target/scala-2.12/classes ...
[info] done compiling
[info] compiling 2 Scala sources to /home/runner/work/chisel/chisel/svsim/target/scala-2.12/test-classes ...
[error] /home/runner/work/chisel/chisel/svsim/src/test/scala/BackendSpec.scala:74:23: Invalid literal number
[error]           val aVal = -0x0240_0000_0000_0000L
[error]                       ^
[error] /home/runner/work/chisel/chisel/svsim/src/test/scala/BackendSpec.scala:75:23: Invalid literal number
[error]           val bVal = +0x0180_0000_0000_0000L
[error]                       ^
[error] /home/runner/work/chisel/chisel/svsim/src/test/scala/BackendSpec.scala:81:39: Invalid literal number
[error]             assert(value.asBigInt === 0x7dc0_0000_0000_0000L)
[error]                                       ^
[error] /home/runner/work/chisel/chisel/svsim/src/test/scala/BackendSpec.scala:113:39: Invalid literal number
[error]             assert(value.asBigInt === 0x00c0_0000_0000_0000L)
[error]                                       ^
[error] four errors found

Allowing _ in literals was only added in Scala 2.13 so the Scala 2.12 compilation fails.

You can test this locally by setting the version of Scala in SBT shell with ++2.12.17, eg.

$ sbt
> ++2.12.17
> svsim / compile

@GeorgeLyon
Copy link
Contributor Author

Allowing _ in literals was only added in Scala 2.13 so the Scala 2.12 compilation fails.

Is Scala 2.12 something we care about for Chisel5? (Happy to fix the issue, but just asking)

@jackkoenig
Copy link
Contributor

Is Scala 2.12 something we care about for Chisel5? (Happy to fix the issue, but just asking)

Yes, we're deprecating it in Chisel 5 but not removing till Chisel 6.

Copy link
Contributor

@jackkoenig jackkoenig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me (having also reviewed it before 🙂)!

@GeorgeLyon
Copy link
Contributor Author

Thanks @jackkoenig! Just to be clear, are you approving this to be merged or do you want someone else to also take a look?

@jackkoenig jackkoenig merged commit 5400d1a into chipsalliance:main Mar 21, 2023
@GeorgeLyon GeorgeLyon deleted the dev/george/svsim branch March 21, 2023 22:37
Copy link
Member

@sequencer sequencer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Finally we reached a clean backend!
I just added some nitpick based on my experience. In the future we should consider these:

  1. provide svsim as a library, expose API with mainargs, and can be reused by different build system, including make, mill, wake.
  2. think about how to link the design patterns that consumes other libraries, e.g. spike, we need this for RISC-V cosim or BFM.
  3. provide a API to peek/poke/force internal signals, so that we can do fault injection and dynamic coverage.

Comment on lines +7 to +11
case class ModuleInfo(
name: String,
ports: Seq[ModuleInfo.Port]) {
private[svsim] val instanceName = "dut"
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So basically, the svsim seems only being able to use the dut ports for communication, wondering how to provide force or peek to internal circuits in the future, this is extremely useful in fault injections. like ECC.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will be an API that exposes probes/rwprobes as port-like things. This will be based on the reference types that are now in the FIRRTL 2.0.0 spec: chipsalliance/firrtl-spec#75

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@seldridge mentions the "correct" answer, but I also don't have a specific issue with adding more fields to ModuleInfo if there is specific behavior we want from the test bench. Overall (and especially in these early days) I will have a strong bias towards simplicity, preferring solutions like the one @seldridge proposed over adding functionality to the test bench itself (I'll touch on this point in a separate response about how we generate the testbench below)

object Workspace {
val testbenchModuleName: String = "svsimTestbench"
}
final class Workspace(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is possibly not a good idea to declare Workspace Here. These is kind of pitfall that we should learn from: rocket-chip did it in its tests generation, chiseltest force to use test_run_dir, and use Scalatest of cause, I think decoupling function and build system will be neat.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you take a second look, Workspace explicitly does not couple this to Scalatest or any other system / paradigm. Its main role is to manage files on the filesystem (which are a requirement for VCS and Verilator). We enforce the internal structure (primary-sources, generated-sources, etc) for consistency, but this folder can be placed anywhere on the filesystem (for example, a temporary directory).


val systemVerilogTestbenchWriter = new LineWriter(s"$generatedSourcesPath/testbench.sv")
try {
val l = systemVerilogTestbenchWriter
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the future, can we use slang to compose testbench like this?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or maybe SV dialect in MLIR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think for svsim, having less dependencies and lower complexity gives a much bigger payoff than the additional functionality of something like slang (which I haven't dug into deeply) or directly using CIRCT would. This also helps create downward pressure on the complexity of the actual generated testbench. Finally, I like that this puts a floor the amount of "magic" that is done to connect the testbench to the dut, the process is entirely controlled by a list of strings and bools.

That said, this code is entirely contained in generateAdditionalSources and there is nothing technically stopping us from having something like an alternate generateAdditionalSources(sourceGenerator: SourceGenerator) where SourceGenerator is a trait and can be implemented with whatever SystemVerilog generation mechanism the user wants.

systemVerilogTestbenchWriter.close()
}

val cDPIBridgeWriter = new LineWriter(s"$generatedSourcesPath/c-dpi-bridge.cpp")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hopefully we can have a better codegen solution, maybe LLVM IR? I'm not sure.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, I don't think the added complexity buys us anything here. Indeed, it would create a further disconnect between the actual C being generated and forces developers to start thinking "how do I get this codegen system to print the code I want?".

Comment on lines +353 to +355
/**
* Use the generated Makefile to compile the simulation, since this exercises the Makefile codepath and makes it less likely that we will break `make replay`.
*/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is kind of tricky... We can find a better solution to decouple the build system to leverage mill or wake.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what you mean here. mill or wake invoke Scala, and svsim's role is to inside of a Scala process, compile generated Verilog into a simulation and then run that simulation. Also, as the comment states, the actual thing happening here is very simple (effectively just invoking vcs or verilator with a list of arguments). The only reason we add the indirection-via-makefile is to gain added confidence that the debugging flow (modifying either the invocation or the verilog and running make replay) mirrors as accurately as possible the actual build flow.

}

final object TraceSettings {
final case class FsdbSettings(verdiHome: String)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need APIs to configure VCS, e.g. SNPSLMD_LICENSE_FILE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The backends in svsim (and specifically the VCS backend) are, at the moment, unapologetically "what happened to work for SiFive's use case". that said, because things are nicely organized it should be simple to augment these backends with whatever additional flags may be needed. My one request is that we have actual use cases when we add customization here, the VCS spec has a veritable encyclopedia of command-line arguments, some of which have almost programming-language-like logic that I don't think we need to mirror the entirety of here.

Also, I chose to upstream the VCS backend because I figured it would be helpful, but as we can't test it in the Chisel repo I'm not 100% sure that this is the best place for it. Once the dust settles, I'd be supportive of unsealing the Backend trait so folks can just implement their own backend (which is a very simple task in svsim). This could also be a good way to deal with different versions of VCS, etc. (wouldn't it be great if Synopsys just provided this!?)

Comment on lines +34 to +35
s"$verdiHome/share/PLI/VCS/LINUX64/novas.tab",
s"$verdiHome/share/PLI/VCS/LINUX64/pli.a"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't work with aarch64.
(Haha, we are considering purchase a bunch of Apple M1 with Asahi to run CI)

Copy link
Contributor Author

@GeorgeLyon GeorgeLyon Mar 22, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, as I mentioned above this was just "what works at SiFive". I'm very open to PRs cleaning this up and making it work for other environments (modulo the complexity and testability comments above). The best path forward here I see is to unseal the Backend trait, have you guys iterate on your aarch64 config out-of-tree, and then upstream the changes that actually make it work. This has the added benefit of not requiring you to PR-and-bump chisel whenever you need to tweak a flag.

archOverride: Option[String] = None)

def initializeFromProcessEnvironment() = {
(sys.env.get("VCS_HOME"), sys.env.get("LM_LICENSE_FILE")) match {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK forgive me on my previous review.
However we shouldn't use LM_LICENSE_FILE, that will introduce a huge problem in multi-EDA environment. please use SNPSLMD_LICENSE_FILE instead

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what works for us (as far as I can tell we don't use SNPSLMD_LICENSE_FILE). I think unsealing the Backend trait, iterating out-of-tree and upstreaming is the right solution here.

The one design constraint I have is that we don't do any "magic" in svsim and limit ourselves to grabbing what is in the environment and forwarding it to vcs or verilator.

disableFatalExitOnWarnings: Boolean = false)

def initializeFromProcessEnvironment() = {
val process = Runtime.getRuntime().exec(Array("which", "verilator"))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe provide verilator path in configuration will be better?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why? Our usual testing methodology is that users already have any tools (espresso, etc) on their path. I think we should be consistent here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe provide verilator path in configuration will be better?

You can create the backend directly using new verilator.Backend(executablePath = "/path/to/verilator")

@GeorgeLyon
Copy link
Contributor Author

Thanks for the detailed review @sequencer! One common thread I found was that maybe it makes sense to allow custom out-of-tree Backends sooner rather than later. I used the term unseal above, but looking at the code Backend isn't actually sealed, it's just that InvocationSettings is private. Making this public should allow you to iterate on a Backend to suit your needs (and then upstream, either by merging with the existing one or by adding an alternate formulation), and feel free to draft a PR that enables this.

@jackkoenig jackkoenig added the Feature New feature, will be included in release notes label Apr 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature New feature, will be included in release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants