Skip to content

Commit

Permalink
[svsim] Escape '$' in defines for VCS only
Browse files Browse the repository at this point in the history
Add an abstract function to `svsim.Backend` which can be used to control
how define key and values will be escaped.  Add escaping for '$' for VCS
only.

This is done to work around what I think is a difference in how VCS and
Verilator handle the `+define+key=value` command line argument.  In svsim,
we call both like the following (this is a key only, no value):

    <tool> '+define+Foo$Bar'

While Verilator will accept this, VCS will not and instead wants:

    <tool> '+define+Foo\$Bar'

As far as I can tell, the problem seems to be the single quotes not being
respected by VCS.  This is _likely_ due to the fact that the VCS
entrypoint is shell and may have some oddities in how it is handling
command line options.  (This is speculation.)

I expect that this could have manifested for anything that was using a
Verilog system function, e.g.., `+define+RANDOM+$random`.  For that
specific case, we were already escaping it internally.

The immediate need for this is to get inline layers and their `$`-ridden
ABI (that I wrote...) working with VCS.  They are already working with
Verilator.

Signed-off-by: Schuyler Eldridge <[email protected]>
  • Loading branch information
seldridge committed Dec 12, 2024
1 parent 33b6b2d commit 877b9fa
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 5 deletions.
12 changes: 9 additions & 3 deletions svsim/src/main/scala/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@ object CommonCompilationSettings {
def apply(name: String) = new VerilogPreprocessorDefine(name, None)
}
case class VerilogPreprocessorDefine private (name: String, value: Option[String]) {
private[svsim] def toCommandlineArgument: String = {
private[svsim] def toCommandlineArgument(backend: Backend): String = {
value match {
case Some(v) => s"+define+${name}=${v}"
case None => s"+define+${name}"
case Some(v) => s"+define+${backend.escapeDefine(name)}=${backend.escapeDefine(v)}"
case None => s"+define+${backend.escapeDefine(name)}"
}
}
}
Expand Down Expand Up @@ -75,6 +75,12 @@ trait Backend {
commonSettings: CommonCompilationSettings,
backendSpecificSettings: CompilationSettings
): Backend.Parameters

/** This function will be applied to all defines (both the keys and the values).
* This can be used to workaround subtleties in how different simulators
* parse defines and require different escaping.
*/
def escapeDefine(string: String): String
}

final object Backend {
Expand Down
7 changes: 6 additions & 1 deletion svsim/src/main/scala/vcs/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ final class Backend(
VerilogPreprocessorDefine(svsim.Backend.HarnessCompilationFlags.supportsDelayInPublicFunctions)
),
backendSpecificSettings.traceSettings.verilogPreprocessorDefines
).flatten.map(_.toCommandlineArgument),
).flatten.map(_.toCommandlineArgument(this)),
).flatten,
environment = environment ++ Seq(
"VCS_HOME" -> vcsHome,
Expand All @@ -212,4 +212,9 @@ final class Backend(
)
//format: on
}

/** VCS seems to require that dollar signs in arguments are escaped. This is
* different from Verilator.
*/
override def escapeDefine(string: String): String = string.replace("$", "\\$")
}
4 changes: 3 additions & 1 deletion svsim/src/main/scala/verilator/Backend.scala
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,14 @@ final class Backend(
VerilogPreprocessorDefine(svsim.Backend.HarnessCompilationFlags.enableVcdTracingSupport)
)
},
).flatten.map(_.toCommandlineArgument),
).flatten.map(_.toCommandlineArgument(this)),
).flatten,
environment = Seq()
),
simulationInvocation = svsim.Backend.Parameters.Invocation(Seq(), Seq())
)
//format: on
}

override def escapeDefine(string: String): String = string
}
2 changes: 2 additions & 0 deletions svsim/src/test/scala/BackendSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ case class CustomVerilatorBackend(actualBackend: verilator.Backend) extends Back
backendSpecificSettings
)
}

override def escapeDefine(string: String): String = string
}

class VerilatorSpec extends BackendSpec {
Expand Down

0 comments on commit 877b9fa

Please sign in to comment.