Skip to content

Commit

Permalink
[nix] add vsrc build support with t1 namespace optimization
Browse files Browse the repository at this point in the history
* add vsrc build support to nix
* rename innermostscope to self for more intuitive naming
* use fileset utils to filter only vsrc for emulator input
* add makeOverridable to sv-to-*emu function to reduce copy-pasting

Signed-off-by: Avimitin <[email protected]>
  • Loading branch information
FanShupei authored and Avimitin committed Nov 4, 2024
1 parent ee0bd7a commit 9142463
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 37 deletions.
15 changes: 11 additions & 4 deletions nix/t1/conversion/sv-to-vcs-simulator.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

{ mainProgram
, rtl
, vsrc
, enableTrace ? false
, vcsLinkLibs ? [ ]
, topModule ? null
}:

assert lib.assertMsg (builtins.typeOf vcsLinkLibs == "list") "vcsLinkLibs should be list of strings";
Expand All @@ -22,7 +24,7 @@ stdenv.mkDerivation rec {
dontPatchELF = true;
enableCover = true;

src = rtl;
dontUnpack = true;

vcsArgs = [
"-sverilog"
Expand All @@ -31,8 +33,13 @@ stdenv.mkDerivation rec {
"-y"
"$DWBB_DIR/sim_ver"
"+libext+.v"
"-file"
"filelist.f"
"-F"
"${rtl}/filelist.f"
]
++ lib.singleton vsrc
++ lib.optionals (topModule != null) [
"-top"
topModule
]
++ lib.optionals enableCover [
"-cm"
Expand Down Expand Up @@ -78,7 +85,7 @@ stdenv.mkDerivation rec {
cp $mainProgram $out/lib
cp -r $mainProgram.daidir $out/lib
${lib.optionalString enableCover ''
cp -r ./cm.vdb $out/lib
cp -r ./cm.vdb $out/lib
''}
# We need to carefully handle string escape here, so don't use makeWrapper
Expand Down
12 changes: 8 additions & 4 deletions nix/t1/conversion/sv-to-verilator-emulator.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@

{ mainProgram
, rtl
, vsrc
, enableTrace ? false
, extraVerilatorArgs ? [ ]
, topModule ? null
, ...
}@overrides:

Expand All @@ -19,15 +21,14 @@ rec {

__noChroot = true;

src = rtl;
dontUnpack = true;

nativeBuildInputs = [ verilator ];

# zlib is required for Rust to link against
propagatedBuildInputs = [ zlib ];

verilatorFilelist = "filelist.f";
verilatorTop = "TestBench";
verilatorFilelist = "${rtl}/filelist.f";
verilatorThreads = 8;
verilatorArgs = [
"--cc"
Expand All @@ -44,8 +45,11 @@ rec {
"-Wno-lint"
"-F"
verilatorFilelist
]
++ lib.singleton vsrc
++ lib.optionals (topModule != null) [
"--top"
verilatorTop
topModule
]
++ extraVerilatorArgs
++ lib.optionals enableTrace [
Expand Down
4 changes: 2 additions & 2 deletions nix/t1/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,13 @@ lib.makeScope newScope
# * verilatorTop: Top module of the system verilog, default using "TestBench"
# * verilatorThreads: Threads for final verilating, default using 8
# * verilatorArgs: Final arguments that pass to the verilator.
sv-to-verilator-emulator = t1Scope.callPackage ./conversion/sv-to-verilator-emulator.nix { stdenv = moldStdenv; };
sv-to-verilator-emulator = lib.makeOverridable (t1Scope.callPackage ./conversion/sv-to-verilator-emulator.nix { stdenv = moldStdenv; });

# sv-to-vcs-simulator :: { mainProgram :: String, rtl :: Derivation, enableTrace :: Bool, vcsLinkLibs :: List<String> } -> Derivation
#
# sv-to-vcs-simulator will compile the given rtl, link with path specified in vcsLinksLibs to produce a VCS emulator.
# enableTrace is false by default;
sv-to-vcs-simulator = t1Scope.callPackage ./conversion/sv-to-vcs-simulator.nix { };
sv-to-vcs-simulator = lib.makeOverridable (t1Scope.callPackage ./conversion/sv-to-vcs-simulator.nix { });
}
# Nix specification for t1 (with spike only) emulator
# We don't expect extra scope for t1 stuff, so here we merge the t1 at t1Scope level.
Expand Down
66 changes: 39 additions & 27 deletions nix/t1/t1.nix
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ let
(scopeBuilderFn topName generatorData scope)))
strippedGeneratorData;
in
forEachTop (topName: generator: innerMostScope: {
forEachTop (topName: generator: self: {
inherit configName topName;

cases = innerMostScope.callPackage ../../tests { };
cases = self.callPackage ../../tests { };

mlirbc = t1Scope.chisel-to-mlirbc {
outputName = "${generator.fullClassName}.mlirbc";
Expand All @@ -46,13 +46,13 @@ forEachTop (topName: generator: innerMostScope: {
};

lowered-mlirbc = t1Scope.finalize-mlirbc {
outputName = "lowered-" + innerMostScope.mlirbc.name;
mlirbc = innerMostScope.mlirbc;
outputName = "lowered-" + self.mlirbc.name;
mlirbc = self.mlirbc;
};

rtl = t1Scope.mlirbc-to-sv {
outputName = "${generator.fullClassName}-rtl";
mlirbc = innerMostScope.lowered-mlirbc;
mlirbc = self.lowered-mlirbc;
mfcArgs = [
"-O=release"
"--disable-all-randomization"
Expand All @@ -75,13 +75,13 @@ forEachTop (topName: generator: innerMostScope: {
exec ${t1Scope.omreader-unwrapped}/bin/omreader \
${lib.replaceStrings ["elaborator"] ["omreader"] generator.fullClassName} \
\$cmd \
--mlirbc-file ${innerMostScope.lowered-mlirbc}/${innerMostScope.lowered-mlirbc.name} \
--mlirbc-file ${self.lowered-mlirbc}/${self.lowered-mlirbc.name} \
$@
EOF
chmod +x $out/bin/omreader
'';
rtlDesignMetadataJson = runCommand "get-rtl-design-metadata-from-om" { nativeBuildInputs = [ jq innerMostScope.omreader ]; } ''
rtlDesignMetadataJson = runCommand "get-rtl-design-metadata-from-om" { nativeBuildInputs = [ jq self.omreader ]; } ''
jq --null-input \
--arg march $(omreader march) \
--arg extensions $(omreader extensions) \
Expand All @@ -94,19 +94,19 @@ forEachTop (topName: generator: innerMostScope: {
"xlen": (if ($march|startswith("rv32")) then 32 else 64 end) }' \
> $out
'';
rtlDesignMetadata = with builtins; fromJSON (readFile innerMostScope.rtlDesignMetadataJson);
rtlDesignMetadata = with builtins; fromJSON (readFile self.rtlDesignMetadataJson);

# ---------------------------------------------------------------------------------
# VERILATOR
# ---------------------------------------------------------------------------------
makeDifftest = innerMostScope.callPackage ../../difftest { };
makeDifftest = self.callPackage ../../difftest { };

verilator-dpi-lib = innerMostScope.makeDifftest {
verilator-dpi-lib = self.makeDifftest {
outputName = "${topName}-verilator-dpi-lib";
emuType = "verilator";
moduleType = "dpi_${topName}";
};
verilator-dpi-lib-trace = innerMostScope.makeDifftest {
verilator-dpi-lib-trace = self.makeDifftest {
outputName = "${topName}-verilator-trace-dpi-lib";
emuType = "verilator";
moduleType = "dpi_${topName}";
Expand All @@ -115,48 +115,60 @@ forEachTop (topName: generator: innerMostScope: {

verilator-emu = t1Scope.sv-to-verilator-emulator {
mainProgram = "${topName}-verilated-simulator";
rtl = innerMostScope.rtl;
extraVerilatorArgs = [ "${innerMostScope.verilator-dpi-lib}/lib/libdpi_${topName}.a" ];
topModule = "TestBench";
rtl = self.rtl;
# Create a new nix store root with only the ClockGen file, to avoid any source change in
# t1 source root causing emulator to rebuild.
vsrc = with lib.fileset; toSource {
root = ../../${topName}/vsrc;
fileset = unions [ ../../${topName}/vsrc/ClockGen.sv ];
};
extraVerilatorArgs = [ "${self.verilator-dpi-lib}/lib/libdpi_${topName}.a" ];
};
verilator-emu-trace = t1Scope.sv-to-verilator-emulator {
mainProgram = "${topName}-verilated-trace-simulator";
rtl = innerMostScope.rtl;
verilator-emu-trace = self.verilator-emu.override {
enableTrace = true;
extraVerilatorArgs = [ "${innerMostScope.verilator-dpi-lib-trace}/lib/libdpi_${topName}.a" ];
mainProgram = "${topName}-verilated-trace-simulator";
extraVerilatorArgs = [ "${self.verilator-dpi-lib-trace}/lib/libdpi_${topName}.a" ];
};

# ---------------------------------------------------------------------------------
# VCS
# ---------------------------------------------------------------------------------
vcs-dpi-lib = innerMostScope.makeDifftest {
vcs-dpi-lib = self.makeDifftest {
outputName = "${topName}-vcs-dpi-lib";
emuType = "vcs";
moduleType = "dpi_${topName}";
};
vcs-dpi-lib-trace = innerMostScope.makeDifftest {
vcs-dpi-lib-trace = self.makeDifftest {
outputName = "${topName}-vcs-dpi-trace-lib";
emuType = "vcs";
enableTrace = true;
moduleType = "dpi_${topName}";
};

offline-checker = innerMostScope.makeDifftest {
offline-checker = self.makeDifftest {
outputName = "${topName}-offline-checker";
moduleType = "offline_${topName}";
};

vcs-emu = t1Scope.sv-to-vcs-simulator {
mainProgram = "${topName}-vcs-simulator";
rtl = innerMostScope.rtl;
vcsLinkLibs = [ "${innerMostScope.vcs-dpi-lib}/lib/libdpi_${topName}.a" ];
topModule = "TestBench";
rtl = self.rtl;
# Create a new nix store root with only the ClockGen file, to avoid any source change in
# t1 source root causing emulator to rebuild.
vsrc = with lib.fileset; toSource {
root = ../../${topName}/vsrc;
fileset = unions [ ../../${topName}/vsrc/ClockGen.sv ];
};
vcsLinkLibs = [ "${self.vcs-dpi-lib}/lib/libdpi_${topName}.a" ];
};
vcs-emu-trace = t1Scope.sv-to-vcs-simulator {
mainProgram = "${topName}-vcs-trace-simulator";
rtl = innerMostScope.rtl;
vcs-emu-trace = self.vcs-emu.override {
enableTrace = true;
vcsLinkLibs = [ "${innerMostScope.vcs-dpi-lib-trace}/lib/libdpi_${topName}.a" ];
mainProgram = "${topName}-vcs-trace-simulator";
vcsLinkLibs = [ "${self.vcs-dpi-lib-trace}/lib/libdpi_${topName}.a" ];
};

run = innerMostScope.callPackage ./run { };
run = self.callPackage ./run { };
}) # end of forEachTop
)

0 comments on commit 9142463

Please sign in to comment.