Bump rocket, make possible to use published deps (#47)
* Use published rocketchip * Simulator works! * Gitignore was masking csrc * Fix broken submodules * Update gitignore * Fix things up * Some more cleanup * Clean up so that using maven works * Incorporate feedback * Oops * Add workaround for some of csrc * Forgot dtm and jtag * Make name better and add comment * Extraneous comment * Fix includes. After running a clean build, I realized old build state was masking this problem. verisim/csrc needs to be in the include path until we find a more permanent solution to our problem. * Add target to generate verilator-specific files. * Ignore DS_Store * Generate bootrom from testchipip * Oops * Add extraneous rocket-dsptools reference
This commit is contained in:
8
.gitignore
vendored
8
.gitignore
vendored
@@ -1,6 +1,12 @@
|
|||||||
|
bootrom
|
||||||
/Makefrag.pkgs
|
/Makefrag.pkgs
|
||||||
target
|
target
|
||||||
*.jar
|
*.jar
|
||||||
*.stamp
|
*.stamp
|
||||||
/vsim
|
/vsim
|
||||||
/verisim
|
/verisim/generated-src*
|
||||||
|
/verisim/simulator-*
|
||||||
|
/verisim/verilator
|
||||||
|
simv*
|
||||||
|
*.vcd
|
||||||
|
.DS_Store
|
||||||
|
|||||||
32
Makefrag
32
Makefrag
@@ -1,4 +1,5 @@
|
|||||||
ROCKETCHIP_DIR=$(base_dir)/rocket-chip
|
ROCKETCHIP_DIR=$(base_dir)/rocket-chip
|
||||||
|
TESTCHIP_DIR = $(base_dir)/testchipip
|
||||||
|
|
||||||
SCALA_VERSION=2.12.4
|
SCALA_VERSION=2.12.4
|
||||||
SCALA_VERSION_MAJOR=$(basename $(SCALA_VERSION))
|
SCALA_VERSION_MAJOR=$(basename $(SCALA_VERSION))
|
||||||
@@ -11,8 +12,8 @@ PACKAGES=rocket-chip testchipip
|
|||||||
SCALA_SOURCES=$(foreach pkg,$(PACKAGES),$(call lookup_scala_srcs,$(base_dir)/$(pkg)/src/main/scala)) $(call lookup_scala_srcs,$(base_dir)/src/main/scala)
|
SCALA_SOURCES=$(foreach pkg,$(PACKAGES),$(call lookup_scala_srcs,$(base_dir)/$(pkg)/src/main/scala)) $(call lookup_scala_srcs,$(base_dir)/src/main/scala)
|
||||||
|
|
||||||
ROCKET_CLASSES ?= "$(ROCKETCHIP_DIR)/target/scala-$(SCALA_VERSION_MAJOR)/classes:$(ROCKETCHIP_DIR)/chisel3/target/scala-$(SCALA_VERSION_MAJOR)/*"
|
ROCKET_CLASSES ?= "$(ROCKETCHIP_DIR)/target/scala-$(SCALA_VERSION_MAJOR)/classes:$(ROCKETCHIP_DIR)/chisel3/target/scala-$(SCALA_VERSION_MAJOR)/*"
|
||||||
|
TESTCHIPIP_CLASSES ?= "$(TESTCHIP_DIR)/target/scala-$(SCALA_VERSION_MAJOR)/classes"
|
||||||
FIRRTL_JAR ?= $(ROCKETCHIP_DIR)/lib/firrtl.jar
|
FIRRTL_JAR ?= $(ROCKETCHIP_DIR)/lib/firrtl.jar
|
||||||
FIRRTL ?= java -Xmx2G -Xss8M -XX:MaxPermSize=256M -cp $(ROCKET_CLASSES):$(FIRRTL_JAR) firrtl.Driver
|
|
||||||
|
|
||||||
$(FIRRTL_JAR): $(call lookup_scala_srcs, $(ROCKETCHIP_DIR)/firrtl/src/main/scala)
|
$(FIRRTL_JAR): $(call lookup_scala_srcs, $(ROCKETCHIP_DIR)/firrtl/src/main/scala)
|
||||||
$(MAKE) -C $(ROCKETCHIP_DIR)/firrtl SBT="$(SBT)" root_dir=$(ROCKETCHIP_DIR)/firrtl build-scala
|
$(MAKE) -C $(ROCKETCHIP_DIR)/firrtl SBT="$(SBT)" root_dir=$(ROCKETCHIP_DIR)/firrtl build-scala
|
||||||
@@ -21,9 +22,6 @@ $(FIRRTL_JAR): $(call lookup_scala_srcs, $(ROCKETCHIP_DIR)/firrtl/src/main/scala
|
|||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
build_dir=$(sim_dir)/generated-src
|
build_dir=$(sim_dir)/generated-src
|
||||||
testchip_dir = $(base_dir)/testchipip
|
|
||||||
|
|
||||||
include $(testchip_dir)/Makefrag
|
|
||||||
|
|
||||||
CHISEL_ARGS ?=
|
CHISEL_ARGS ?=
|
||||||
|
|
||||||
@@ -35,35 +33,39 @@ VERILOG_FILE ?=$(build_dir)/$(long_name).top.v
|
|||||||
HARNESS_FILE ?=$(build_dir)/$(long_name).harness.v
|
HARNESS_FILE ?=$(build_dir)/$(long_name).harness.v
|
||||||
SMEMS_FILE ?=$(build_dir)/$(long_name).mems.v
|
SMEMS_FILE ?=$(build_dir)/$(long_name).mems.v
|
||||||
SMEMS_CONF ?=$(build_dir)/$(long_name).mems.conf
|
SMEMS_CONF ?=$(build_dir)/$(long_name).mems.conf
|
||||||
|
verilator_dotf ?= $(build_dir)/verilator_files.f
|
||||||
|
|
||||||
REPL_SEQ_MEM = --repl-seq-mem -c:$(MODEL):-o:$(SMEMS_CONF)
|
REPL_SEQ_MEM = --repl-seq-mem -c:$(MODEL):-o:$(SMEMS_CONF)
|
||||||
|
|
||||||
# This should match whatever the commonSettings version is in build.sbt
|
# This should match whatever the commonSettings version is in build.sbt
|
||||||
BARSTOOLS_VER=1.0
|
BARSTOOLS_VER=1.0
|
||||||
TAPEOUT_JAR=$(base_dir)/barstools/tapeout/target/scala-$(SCALA_VERSION_MAJOR)/tapeout_$(SCALA_VERSION_MAJOR)-$(BARSTOOLS_VER).jar
|
TAPEOUT_JAR=$(base_dir)/barstools/tapeout/target/scala-$(SCALA_VERSION_MAJOR)/tapeout-assembly-$(BARSTOOLS_VER).jar
|
||||||
MACROCOMPILER_JAR=$(base_dir)/barstools/macros/target/scala-$(SCALA_VERSION_MAJOR)/barstools-macros-assembly-$(BARSTOOLS_VER).jar
|
MACROCOMPILER_JAR=$(base_dir)/barstools/macros/target/scala-$(SCALA_VERSION_MAJOR)/barstools-macros-assembly-$(BARSTOOLS_VER).jar
|
||||||
|
|
||||||
TAPEOUT ?= java -Xmx8G -Xss8M -cp $(ROCKET_CLASSES):$(FIRRTL_JAR):$(TAPEOUT_JAR)
|
TAPEOUT ?= java -Xmx8G -Xss8M -cp $(ROCKET_CLASSES):$(TESTCHIPIP_CLASSES):$(TAPEOUT_JAR)
|
||||||
MACROCOMPILER ?= java -Xmx8G -Xss8M -cp $(ROCKET_CLASSES):$(FIRRTL_JAR):$(MACROCOMPILER_JAR)
|
MACROCOMPILER ?= java -Xmx8G -Xss8M -cp $(ROCKET_CLASSES):$(TESTCHIPIP_CLASSES):$(MACROCOMPILER_JAR)
|
||||||
|
|
||||||
$(TAPEOUT_JAR): $(call lookup_scala_srcs, $(base_dir)/barstools/tapeout/src/main/scala) $(FIRRTL_JAR)
|
$(TAPEOUT_JAR): $(call lookup_scala_srcs, $(base_dir)/barstools/tapeout/src/main/scala)
|
||||||
cd $(base_dir) && $(SBT) "tapeout/package"
|
cd $(base_dir) && $(SBT) "tapeout/assembly"
|
||||||
|
|
||||||
$(MACROCOMPILER_JAR): $(call lookup_scala_srcs, $(base_dir)/barstools/macros/src/main/scala) $(call lookup_scala_srcs, $(base_dir)/barstools/mdf/scalalib/src/main/scala) $(FIRRTL_JAR)
|
$(MACROCOMPILER_JAR): $(call lookup_scala_srcs, $(base_dir)/barstools/macros/src/main/scala) $(call lookup_scala_srcs, $(base_dir)/barstools/mdf/scalalib/src/main/scala)
|
||||||
cd $(base_dir) && $(SBT) "barstools-macros/assembly"
|
cd $(base_dir) && $(SBT) "barstools-macros/assembly"
|
||||||
|
|
||||||
.PHONY: jars
|
.PHONY: jars
|
||||||
jars: $(MACROCOMPILER_JAR) $(TAPEOUT_JAR)
|
jars: $(MACROCOMPILER_JAR) $(TAPEOUT_JAR)
|
||||||
|
|
||||||
$(FIRRTL_FILE) $(ANNO_FILE): $(SCALA_SOURCES) $(bootrom_img) $(FIRRTL_JAR)
|
$(verilator_dotf): $(SCALA_SOURCES)
|
||||||
|
cd $(base_dir) && $(SBT) "runMain example.GenerateSimFiles -td $(build_dir)"
|
||||||
|
|
||||||
|
$(FIRRTL_FILE) $(ANNO_FILE): $(SCALA_SOURCES) $(verilator_dotf)
|
||||||
mkdir -p $(build_dir)
|
mkdir -p $(build_dir)
|
||||||
cd $(base_dir) && $(SBT) "runMain $(PROJECT).Generator $(CHISEL_ARGS) $(build_dir) $(PROJECT) $(MODEL) $(CFG_PROJECT) $(CONFIG)"
|
cd $(base_dir) && $(SBT) "runMain $(PROJECT).Generator $(CHISEL_ARGS) $(build_dir) $(PROJECT) $(MODEL) $(CFG_PROJECT) $(CONFIG)"
|
||||||
|
|
||||||
$(VERILOG_FILE) $(SMEMS_CONF): $(FIRRTL_FILE) $(ANNO_FILE) $(TAPEOUT_JAR)
|
$(VERILOG_FILE) $(SMEMS_CONF): $(FIRRTL_FILE) $(ANNO_FILE) $(TAPEOUT_JAR)
|
||||||
$(TAPEOUT) barstools.tapeout.transforms.GenerateTop -o $(VERILOG_FILE) -i $(FIRRTL_FILE) --syn-top $(TOP) --harness-top $(MODEL) -faf $(ANNO_FILE) $(REPL_SEQ_MEM)
|
$(TAPEOUT) barstools.tapeout.transforms.GenerateTop -o $(VERILOG_FILE) -i $(FIRRTL_FILE) --syn-top $(TOP) --harness-top $(MODEL) -faf $(ANNO_FILE) $(REPL_SEQ_MEM) -td $(build_dir)
|
||||||
|
|
||||||
$(HARNESS_FILE): $(FIRRTL_FILE) $(ANNO_FILE) $(TAPEOUT_JAR)
|
$(HARNESS_FILE): $(FIRRTL_FILE) $(ANNO_FILE) $(TAPEOUT_JAR)
|
||||||
$(TAPEOUT) barstools.tapeout.transforms.GenerateHarness -o $(HARNESS_FILE) -i $(FIRRTL_FILE) --syn-top $(TOP) --harness-top $(MODEL) -faf $(ANNO_FILE)
|
$(TAPEOUT) barstools.tapeout.transforms.GenerateHarness -o $(HARNESS_FILE) -i $(FIRRTL_FILE) --syn-top $(TOP) --harness-top $(MODEL) -faf $(ANNO_FILE) -td $(build_dir)
|
||||||
|
|
||||||
# This file is for simulation only. VLSI flows should replace this file with one containing hard SRAMs
|
# This file is for simulation only. VLSI flows should replace this file with one containing hard SRAMs
|
||||||
$(SMEMS_FILE): $(SMEMS_CONF) $(MACROCOMPILER_JAR)
|
$(SMEMS_FILE): $(SMEMS_CONF) $(MACROCOMPILER_JAR)
|
||||||
@@ -102,3 +104,7 @@ $(output_dir)/%: $(RISCV)/riscv64-unknown-elf/share/riscv-tests/isa/%
|
|||||||
mkdir -p $(output_dir)
|
mkdir -p $(output_dir)
|
||||||
ln -sf $< $@
|
ln -sf $< $@
|
||||||
|
|
||||||
|
.PHONY: clean-scala
|
||||||
|
clean-scala:
|
||||||
|
rm -rf $(MACROCOMPILER_JAR) $(TAPEOUT_JAR)
|
||||||
|
|
||||||
|
|||||||
23
build.sbt
23
build.sbt
@@ -12,6 +12,7 @@ lazy val commonSettings = Seq(
|
|||||||
libraryDependencies += "org.json4s" %% "json4s-native" % "3.5.3",
|
libraryDependencies += "org.json4s" %% "json4s-native" % "3.5.3",
|
||||||
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
|
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
|
||||||
libraryDependencies += "edu.berkeley.cs" %% "firrtl-interpreter" % "1.2-SNAPSHOT",
|
libraryDependencies += "edu.berkeley.cs" %% "firrtl-interpreter" % "1.2-SNAPSHOT",
|
||||||
|
libraryDependencies += "com.github.scopt" %% "scopt" % "3.7.1",
|
||||||
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),
|
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),
|
||||||
resolvers ++= Seq(
|
resolvers ++= Seq(
|
||||||
Resolver.sonatypeRepo("snapshots"),
|
Resolver.sonatypeRepo("snapshots"),
|
||||||
@@ -23,18 +24,28 @@ lazy val rocketchip = RootProject(file("rocket-chip"))
|
|||||||
lazy val testchipip = project.settings(commonSettings)
|
lazy val testchipip = project.settings(commonSettings)
|
||||||
.dependsOn(rocketchip)
|
.dependsOn(rocketchip)
|
||||||
|
|
||||||
lazy val example = (project in file("."))
|
// Checks for -DROCKET_USE_MAVEN.
|
||||||
|
// If it's there, use a maven dependency.
|
||||||
|
// Else, depend on subprojects in git submodules.
|
||||||
|
def conditionalDependsOn(prj: Project): Project = {
|
||||||
|
if (sys.props.contains("ROCKET_USE_MAVEN")) {
|
||||||
|
prj.settings(Seq(
|
||||||
|
libraryDependencies += "edu.berkeley.cs" %% "testchipip" % "1.0-020719-SNAPSHOT",
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
prj.dependsOn(testchipip)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lazy val example = conditionalDependsOn(project in file("."))
|
||||||
.settings(commonSettings)
|
.settings(commonSettings)
|
||||||
.dependsOn(testchipip)
|
|
||||||
|
|
||||||
lazy val tapeout = (project in file("./barstools/tapeout/"))
|
lazy val tapeout = conditionalDependsOn(project in file("./barstools/tapeout/"))
|
||||||
.settings(commonSettings)
|
.settings(commonSettings)
|
||||||
.dependsOn(rocketchip)
|
|
||||||
|
|
||||||
lazy val mdf = (project in file("./barstools/mdf/scalalib/"))
|
lazy val mdf = (project in file("./barstools/mdf/scalalib/"))
|
||||||
|
|
||||||
lazy val `barstools-macros` = (project in file("./barstools/macros/"))
|
lazy val `barstools-macros` = conditionalDependsOn(project in file("./barstools/macros/"))
|
||||||
.enablePlugins(sbtassembly.AssemblyPlugin)
|
.enablePlugins(sbtassembly.AssemblyPlugin)
|
||||||
.settings(commonSettings)
|
.settings(commonSettings)
|
||||||
.dependsOn(rocketchip, mdf)
|
.dependsOn(mdf)
|
||||||
|
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
sbt.version=1.2.7
|
sbt.version=1.2.8
|
||||||
|
|||||||
Submodule rocket-chip updated: 50bb13d788...a05728c4fa
356
src/main/resources/project-template/csrc/emulator.cc
Normal file
356
src/main/resources/project-template/csrc/emulator.cc
Normal file
@@ -0,0 +1,356 @@
|
|||||||
|
// See LICENSE.SiFive for license details.
|
||||||
|
// See LICENSE.Berkeley for license details.
|
||||||
|
|
||||||
|
#include "verilated.h"
|
||||||
|
#if VM_TRACE
|
||||||
|
#include <memory>
|
||||||
|
#include "verilated_vcd_c.h"
|
||||||
|
#endif
|
||||||
|
#include <fesvr/dtm.h>
|
||||||
|
#include <fesvr/tsi.h>
|
||||||
|
#include "remote_bitbang.h"
|
||||||
|
#include <iostream>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
// For option parsing, which is split across this file, Verilog, and
|
||||||
|
// FESVR's HTIF, a few external files must be pulled in. The list of
|
||||||
|
// files and what they provide is enumerated:
|
||||||
|
//
|
||||||
|
// $RISCV/include/fesvr/htif.h:
|
||||||
|
// defines:
|
||||||
|
// - HTIF_USAGE_OPTIONS
|
||||||
|
// - HTIF_LONG_OPTIONS_OPTIND
|
||||||
|
// - HTIF_LONG_OPTIONS
|
||||||
|
// $(ROCKETCHIP_DIR)/generated-src(-debug)?/$(CONFIG).plusArgs:
|
||||||
|
// defines:
|
||||||
|
// - PLUSARG_USAGE_OPTIONS
|
||||||
|
// variables:
|
||||||
|
// - static const char * verilog_plusargs
|
||||||
|
|
||||||
|
extern tsi_t* tsi;
|
||||||
|
extern dtm_t* dtm;
|
||||||
|
extern remote_bitbang_t * jtag;
|
||||||
|
|
||||||
|
static uint64_t trace_count = 0;
|
||||||
|
bool verbose;
|
||||||
|
bool done_reset;
|
||||||
|
|
||||||
|
void handle_sigterm(int sig)
|
||||||
|
{
|
||||||
|
dtm->stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
double sc_time_stamp()
|
||||||
|
{
|
||||||
|
return trace_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C" int vpi_get_vlog_info(void* arg)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usage(const char * program_name)
|
||||||
|
{
|
||||||
|
printf("Usage: %s [EMULATOR OPTION]... [VERILOG PLUSARG]... [HOST OPTION]... BINARY [TARGET OPTION]...\n",
|
||||||
|
program_name);
|
||||||
|
fputs("\
|
||||||
|
Run a BINARY on the Rocket Chip emulator.\n\
|
||||||
|
\n\
|
||||||
|
Mandatory arguments to long options are mandatory for short options too.\n\
|
||||||
|
\n\
|
||||||
|
EMULATOR OPTIONS\n\
|
||||||
|
-c, --cycle-count Print the cycle count before exiting\n\
|
||||||
|
+cycle-count\n\
|
||||||
|
-h, --help Display this help and exit\n\
|
||||||
|
-m, --max-cycles=CYCLES Kill the emulation after CYCLES\n\
|
||||||
|
+max-cycles=CYCLES\n\
|
||||||
|
-s, --seed=SEED Use random number seed SEED\n\
|
||||||
|
-r, --rbb-port=PORT Use PORT for remote bit bang (with OpenOCD and GDB) \n\
|
||||||
|
If not specified, a random port will be chosen\n\
|
||||||
|
automatically.\n\
|
||||||
|
-V, --verbose Enable all Chisel printfs (cycle-by-cycle info)\n\
|
||||||
|
+verbose\n\
|
||||||
|
", stdout);
|
||||||
|
#if VM_TRACE == 0
|
||||||
|
fputs("\
|
||||||
|
\n\
|
||||||
|
EMULATOR DEBUG OPTIONS (only supported in debug build -- try `make debug`)\n",
|
||||||
|
stdout);
|
||||||
|
#endif
|
||||||
|
fputs("\
|
||||||
|
-v, --vcd=FILE, Write vcd trace to FILE (or '-' for stdout)\n\
|
||||||
|
-x, --dump-start=CYCLE Start VCD tracing at CYCLE\n\
|
||||||
|
+dump-start\n\
|
||||||
|
", stdout);
|
||||||
|
fputs("\n" PLUSARG_USAGE_OPTIONS, stdout);
|
||||||
|
fputs("\n" HTIF_USAGE_OPTIONS, stdout);
|
||||||
|
printf("\n"
|
||||||
|
"EXAMPLES\n"
|
||||||
|
" - run a bare metal test:\n"
|
||||||
|
" %s $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add\n"
|
||||||
|
" - run a bare metal test showing cycle-by-cycle information:\n"
|
||||||
|
" %s +verbose $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add 2>&1 | spike-dasm\n"
|
||||||
|
#if VM_TRACE
|
||||||
|
" - run a bare metal test to generate a VCD waveform:\n"
|
||||||
|
" %s -v rv64ui-p-add.vcd $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add\n"
|
||||||
|
#endif
|
||||||
|
" - run an ELF (you wrote, called 'hello') using the proxy kernel:\n"
|
||||||
|
" %s pk hello\n",
|
||||||
|
program_name, program_name, program_name
|
||||||
|
#if VM_TRACE
|
||||||
|
, program_name
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
unsigned random_seed = (unsigned)time(NULL) ^ (unsigned)getpid();
|
||||||
|
uint64_t max_cycles = -1;
|
||||||
|
int ret = 0;
|
||||||
|
bool print_cycles = false;
|
||||||
|
// Port numbers are 16 bit unsigned integers.
|
||||||
|
uint16_t rbb_port = 0;
|
||||||
|
#if VM_TRACE
|
||||||
|
FILE * vcdfile = NULL;
|
||||||
|
uint64_t start = 0;
|
||||||
|
#endif
|
||||||
|
char ** htif_argv = NULL;
|
||||||
|
int verilog_plusargs_legal = 1;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"cycle-count", no_argument, 0, 'c' },
|
||||||
|
{"help", no_argument, 0, 'h' },
|
||||||
|
{"max-cycles", required_argument, 0, 'm' },
|
||||||
|
{"seed", required_argument, 0, 's' },
|
||||||
|
{"rbb-port", required_argument, 0, 'r' },
|
||||||
|
{"verbose", no_argument, 0, 'V' },
|
||||||
|
#if VM_TRACE
|
||||||
|
{"vcd", required_argument, 0, 'v' },
|
||||||
|
{"dump-start", required_argument, 0, 'x' },
|
||||||
|
#endif
|
||||||
|
HTIF_LONG_OPTIONS
|
||||||
|
};
|
||||||
|
int option_index = 0;
|
||||||
|
#if VM_TRACE
|
||||||
|
int c = getopt_long(argc, argv, "-chm:s:r:v:Vx:", long_options, &option_index);
|
||||||
|
#else
|
||||||
|
int c = getopt_long(argc, argv, "-chm:s:r:V", long_options, &option_index);
|
||||||
|
#endif
|
||||||
|
if (c == -1) break;
|
||||||
|
retry:
|
||||||
|
switch (c) {
|
||||||
|
// Process long and short EMULATOR options
|
||||||
|
case '?': usage(argv[0]); return 1;
|
||||||
|
case 'c': print_cycles = true; break;
|
||||||
|
case 'h': usage(argv[0]); return 0;
|
||||||
|
case 'm': max_cycles = atoll(optarg); break;
|
||||||
|
case 's': random_seed = atoi(optarg); break;
|
||||||
|
case 'r': rbb_port = atoi(optarg); break;
|
||||||
|
case 'V': verbose = true; break;
|
||||||
|
#if VM_TRACE
|
||||||
|
case 'v': {
|
||||||
|
vcdfile = strcmp(optarg, "-") == 0 ? stdout : fopen(optarg, "w");
|
||||||
|
if (!vcdfile) {
|
||||||
|
std::cerr << "Unable to open " << optarg << " for VCD write\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'x': start = atoll(optarg); break;
|
||||||
|
#endif
|
||||||
|
// Process legacy '+' EMULATOR arguments by replacing them with
|
||||||
|
// their getopt equivalents
|
||||||
|
case 1: {
|
||||||
|
std::string arg = optarg;
|
||||||
|
if (arg.substr(0, 1) != "+") {
|
||||||
|
optind--;
|
||||||
|
goto done_processing;
|
||||||
|
}
|
||||||
|
if (arg == "+verbose")
|
||||||
|
c = 'V';
|
||||||
|
else if (arg.substr(0, 12) == "+max-cycles=") {
|
||||||
|
c = 'm';
|
||||||
|
optarg = optarg+12;
|
||||||
|
}
|
||||||
|
#if VM_TRACE
|
||||||
|
else if (arg.substr(0, 12) == "+dump-start=") {
|
||||||
|
c = 'x';
|
||||||
|
optarg = optarg+12;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else if (arg.substr(0, 12) == "+cycle-count")
|
||||||
|
c = 'c';
|
||||||
|
// If we don't find a legacy '+' EMULATOR argument, it still could be
|
||||||
|
// a VERILOG_PLUSARG and not an error.
|
||||||
|
else if (verilog_plusargs_legal) {
|
||||||
|
const char ** plusarg = &verilog_plusargs[0];
|
||||||
|
int legal_verilog_plusarg = 0;
|
||||||
|
while (*plusarg && (legal_verilog_plusarg == 0)){
|
||||||
|
if (arg.substr(1, strlen(*plusarg)) == *plusarg) {
|
||||||
|
legal_verilog_plusarg = 1;
|
||||||
|
}
|
||||||
|
plusarg ++;
|
||||||
|
}
|
||||||
|
if (!legal_verilog_plusarg) {
|
||||||
|
verilog_plusargs_legal = 0;
|
||||||
|
} else {
|
||||||
|
c = 'P';
|
||||||
|
}
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
// If we STILL don't find a legacy '+' argument, it still could be
|
||||||
|
// an HTIF (HOST) argument and not an error. If this is the case, then
|
||||||
|
// we're done processing EMULATOR and VERILOG arguments.
|
||||||
|
else {
|
||||||
|
static struct option htif_long_options [] = { HTIF_LONG_OPTIONS };
|
||||||
|
struct option * htif_option = &htif_long_options[0];
|
||||||
|
while (htif_option->name) {
|
||||||
|
if (arg.substr(1, strlen(htif_option->name)) == htif_option->name) {
|
||||||
|
optind--;
|
||||||
|
goto done_processing;
|
||||||
|
}
|
||||||
|
htif_option++;
|
||||||
|
}
|
||||||
|
std::cerr << argv[0] << ": invalid plus-arg (Verilog or HTIF) \""
|
||||||
|
<< arg << "\"\n";
|
||||||
|
c = '?';
|
||||||
|
}
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
case 'P': break; // Nothing to do here, Verilog PlusArg
|
||||||
|
// Realize that we've hit HTIF (HOST) arguments or error out
|
||||||
|
default:
|
||||||
|
if (c >= HTIF_LONG_OPTIONS_OPTIND) {
|
||||||
|
optind--;
|
||||||
|
goto done_processing;
|
||||||
|
}
|
||||||
|
c = '?';
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
done_processing:
|
||||||
|
if (optind == argc) {
|
||||||
|
std::cerr << "No binary specified for emulator\n";
|
||||||
|
usage(argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int htif_argc = 1 + argc - optind;
|
||||||
|
htif_argv = (char **) malloc((htif_argc) * sizeof (char *));
|
||||||
|
htif_argv[0] = argv[0];
|
||||||
|
for (int i = 1; optind < argc;) htif_argv[i++] = argv[optind++];
|
||||||
|
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, "using random seed %u\n", random_seed);
|
||||||
|
|
||||||
|
srand(random_seed);
|
||||||
|
srand48(random_seed);
|
||||||
|
|
||||||
|
Verilated::randReset(2);
|
||||||
|
Verilated::commandArgs(argc, argv);
|
||||||
|
TEST_HARNESS *tile = new TEST_HARNESS;
|
||||||
|
|
||||||
|
#if VM_TRACE
|
||||||
|
Verilated::traceEverOn(true); // Verilator must compute traced signals
|
||||||
|
std::unique_ptr<VerilatedVcdFILE> vcdfd(new VerilatedVcdFILE(vcdfile));
|
||||||
|
std::unique_ptr<VerilatedVcdC> tfp(new VerilatedVcdC(vcdfd.get()));
|
||||||
|
if (vcdfile) {
|
||||||
|
tile->trace(tfp.get(), 99); // Trace 99 levels of hierarchy
|
||||||
|
tfp->open("");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
jtag = new remote_bitbang_t(rbb_port);
|
||||||
|
dtm = new dtm_t(htif_argc, htif_argv);
|
||||||
|
tsi = new tsi_t(htif_argc, htif_argv);
|
||||||
|
|
||||||
|
signal(SIGTERM, handle_sigterm);
|
||||||
|
|
||||||
|
bool dump;
|
||||||
|
// reset for several cycles to handle pipelined reset
|
||||||
|
for (int i = 0; i < 10; i++) {
|
||||||
|
tile->reset = 1;
|
||||||
|
tile->clock = 0;
|
||||||
|
tile->eval();
|
||||||
|
#if VM_TRACE
|
||||||
|
dump = tfp && trace_count >= start;
|
||||||
|
if (dump)
|
||||||
|
tfp->dump(static_cast<vluint64_t>(trace_count * 2));
|
||||||
|
#endif
|
||||||
|
tile->clock = 1;
|
||||||
|
tile->eval();
|
||||||
|
#if VM_TRACE
|
||||||
|
if (dump)
|
||||||
|
tfp->dump(static_cast<vluint64_t>(trace_count * 2 + 1));
|
||||||
|
#endif
|
||||||
|
trace_count ++;
|
||||||
|
}
|
||||||
|
tile->reset = 0;
|
||||||
|
done_reset = true;
|
||||||
|
|
||||||
|
while (!dtm->done() && !jtag->done() && !tsi->done() &&
|
||||||
|
!tile->io_success && trace_count < max_cycles) {
|
||||||
|
tile->clock = 0;
|
||||||
|
tile->eval();
|
||||||
|
#if VM_TRACE
|
||||||
|
dump = tfp && trace_count >= start;
|
||||||
|
if (dump)
|
||||||
|
tfp->dump(static_cast<vluint64_t>(trace_count * 2));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
tile->clock = 1;
|
||||||
|
tile->eval();
|
||||||
|
#if VM_TRACE
|
||||||
|
if (dump)
|
||||||
|
tfp->dump(static_cast<vluint64_t>(trace_count * 2 + 1));
|
||||||
|
#endif
|
||||||
|
trace_count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if VM_TRACE
|
||||||
|
if (tfp)
|
||||||
|
tfp->close();
|
||||||
|
if (vcdfile)
|
||||||
|
fclose(vcdfile);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (dtm->exit_code())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "*** FAILED *** via dtm (code = %d, seed %d) after %ld cycles\n", dtm->exit_code(), random_seed, trace_count);
|
||||||
|
ret = dtm->exit_code();
|
||||||
|
}
|
||||||
|
else if (tsi->exit_code())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", tsi->exit_code(), random_seed, trace_count);
|
||||||
|
ret = tsi->exit_code();
|
||||||
|
}
|
||||||
|
else if (jtag->exit_code())
|
||||||
|
{
|
||||||
|
fprintf(stderr, "*** FAILED *** via jtag (code = %d, seed %d) after %ld cycles\n", jtag->exit_code(), random_seed, trace_count);
|
||||||
|
ret = jtag->exit_code();
|
||||||
|
}
|
||||||
|
else if (trace_count == max_cycles)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "*** FAILED *** via trace_count (timeout, seed %d) after %ld cycles\n", random_seed, trace_count);
|
||||||
|
ret = 2;
|
||||||
|
}
|
||||||
|
else if (verbose || print_cycles)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "*** PASSED *** Completed after %ld cycles\n", trace_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dtm) delete dtm;
|
||||||
|
if (tsi) delete tsi;
|
||||||
|
if (jtag) delete jtag;
|
||||||
|
if (tile) delete tile;
|
||||||
|
if (htif_argv) free(htif_argv);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import testchipip._
|
|||||||
|
|
||||||
class WithBootROM extends Config((site, here, up) => {
|
class WithBootROM extends Config((site, here, up) => {
|
||||||
case BootROMParams => BootROMParams(
|
case BootROMParams => BootROMParams(
|
||||||
contentFileName = s"./testchipip/bootrom/bootrom.rv${site(XLen)}.img")
|
contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img")
|
||||||
})
|
})
|
||||||
|
|
||||||
object ConfigValName {
|
object ConfigValName {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package example
|
package example
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
|
import chisel3.experimental._
|
||||||
|
import firrtl.transforms.{BlackBoxResourceAnno, BlackBoxSourceHelper}
|
||||||
import freechips.rocketchip.diplomacy.LazyModule
|
import freechips.rocketchip.diplomacy.LazyModule
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.util.GeneratorApp
|
import freechips.rocketchip.util.GeneratorApp
|
||||||
@@ -15,8 +17,21 @@ class TestHarness(implicit val p: Parameters) extends Module {
|
|||||||
val dut = p(BuildTop)(clock, reset.toBool, p)
|
val dut = p(BuildTop)(clock, reset.toBool, p)
|
||||||
dut.debug := DontCare
|
dut.debug := DontCare
|
||||||
dut.connectSimAXIMem()
|
dut.connectSimAXIMem()
|
||||||
|
dut.connectSimAXIMMIO()
|
||||||
dut.dontTouchPorts()
|
dut.dontTouchPorts()
|
||||||
dut.tieOffInterrupts()
|
dut.tieOffInterrupts()
|
||||||
|
dut.l2_frontend_bus_axi4.foreach(axi => {
|
||||||
|
axi.tieoff()
|
||||||
|
experimental.DataMirror.directionOf(axi.ar.ready) match {
|
||||||
|
case core.ActualDirection.Input =>
|
||||||
|
axi.r.bits := DontCare
|
||||||
|
axi.b.bits := DontCare
|
||||||
|
case core.ActualDirection.Output =>
|
||||||
|
axi.aw.bits := DontCare
|
||||||
|
axi.ar.bits := DontCare
|
||||||
|
axi.w.bits := DontCare
|
||||||
|
}
|
||||||
|
})
|
||||||
io.success := dut.connectSimSerial()
|
io.success := dut.connectSimSerial()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -24,4 +39,5 @@ object Generator extends GeneratorApp {
|
|||||||
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
|
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
|
||||||
generateFirrtl
|
generateFirrtl
|
||||||
generateAnno
|
generateAnno
|
||||||
|
generateArtefacts
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,26 +2,27 @@ package example
|
|||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import freechips.rocketchip.subsystem._
|
import freechips.rocketchip.subsystem._
|
||||||
|
import freechips.rocketchip.system._
|
||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.devices.tilelink._
|
import freechips.rocketchip.devices.tilelink._
|
||||||
import freechips.rocketchip.util.DontTouch
|
import freechips.rocketchip.util.DontTouch
|
||||||
import testchipip._
|
import testchipip._
|
||||||
|
|
||||||
class ExampleTop(implicit p: Parameters) extends RocketSubsystem
|
class ExampleTop(implicit p: Parameters) extends ExampleRocketSystem //RocketSubsystem
|
||||||
with CanHaveMasterAXI4MemPort
|
with CanHaveMasterAXI4MemPort
|
||||||
with HasPeripheryBootROM
|
with HasPeripheryBootROM
|
||||||
// with HasSystemErrorSlave
|
// with HasSystemErrorSlave
|
||||||
with HasSyncExtInterrupts
|
// with HasSyncExtInterrupts
|
||||||
with HasNoDebug
|
with HasNoDebug
|
||||||
with HasPeripherySerial {
|
with HasPeripherySerial {
|
||||||
override lazy val module = new ExampleTopModule(this)
|
override lazy val module = new ExampleTopModule(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class ExampleTopModule[+L <: ExampleTop](l: L) extends RocketSubsystemModuleImp(l)
|
class ExampleTopModule[+L <: ExampleTop](l: L) extends ExampleRocketSystemModuleImp(l) // RocketSubsystemModuleImp(l)
|
||||||
with HasRTCModuleImp
|
with HasRTCModuleImp
|
||||||
with CanHaveMasterAXI4MemPortModuleImp
|
with CanHaveMasterAXI4MemPortModuleImp
|
||||||
with HasPeripheryBootROMModuleImp
|
with HasPeripheryBootROMModuleImp
|
||||||
with HasExtInterruptsModuleImp
|
// with HasExtInterruptsModuleImp
|
||||||
with HasNoDebugModuleImp
|
with HasNoDebugModuleImp
|
||||||
with HasPeripherySerialModuleImp
|
with HasPeripherySerialModuleImp
|
||||||
with DontTouch
|
with DontTouch
|
||||||
|
|||||||
92
src/main/scala/example/Verilator.scala
Normal file
92
src/main/scala/example/Verilator.scala
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
package example
|
||||||
|
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
case class GenerateSimConfig(
|
||||||
|
targetDir: String = ".",
|
||||||
|
dotFName: String = "verilator_files.f",
|
||||||
|
)
|
||||||
|
|
||||||
|
trait HasGenerateSimConfig {
|
||||||
|
val parser = new scopt.OptionParser[GenerateSimConfig]("GenerateSimFiles") {
|
||||||
|
head("GenerateSimFiles", "0.1")
|
||||||
|
|
||||||
|
opt[String]("target-dir")
|
||||||
|
.abbr("td")
|
||||||
|
.valueName("<target-directory>")
|
||||||
|
.action((x, c) => c.copy(targetDir = x))
|
||||||
|
.text("Target director to put files")
|
||||||
|
|
||||||
|
opt[String]("dotFName")
|
||||||
|
.abbr("df")
|
||||||
|
.valueName("<dot-f filename>")
|
||||||
|
.action((x, c) => c.copy(dotFName = x))
|
||||||
|
.text("Name of generated dot-f file")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
object GenerateSimFiles extends App with HasGenerateSimConfig {
|
||||||
|
def addOption(file: File): String = {
|
||||||
|
val fname = file.getCanonicalPath
|
||||||
|
// add -FI flag for header files
|
||||||
|
if (fname.takeRight(2) == ".h") {
|
||||||
|
s"-FI ${fname}"
|
||||||
|
} else { // do nothing otherwise
|
||||||
|
fname
|
||||||
|
}
|
||||||
|
}
|
||||||
|
def writeDotF(lines: Seq[String], cfg: GenerateSimConfig): Unit = {
|
||||||
|
writeTextToFile(lines.mkString("\n"), new File(cfg.targetDir, cfg.dotFName))
|
||||||
|
}
|
||||||
|
// From FIRRTL
|
||||||
|
def safeFile[A](fileName: String)(code: => A) = try { code } catch {
|
||||||
|
case e@ (_: java.io.FileNotFoundException | _: NullPointerException) => throw new Exception(fileName, e)
|
||||||
|
case t: Throwable => throw t
|
||||||
|
}
|
||||||
|
// From FIRRTL
|
||||||
|
def writeResource(name: String, targetDir: String): File = {
|
||||||
|
val in = getClass.getResourceAsStream(name)
|
||||||
|
val p = java.nio.file.Paths.get(name)
|
||||||
|
val fname = p.getFileName().toString();
|
||||||
|
|
||||||
|
val f = new File(targetDir, fname)
|
||||||
|
val out = new java.io.FileOutputStream(f)
|
||||||
|
safeFile(name)(Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.write))
|
||||||
|
out.close()
|
||||||
|
f
|
||||||
|
}
|
||||||
|
// From FIRRTL
|
||||||
|
def writeTextToFile(text: String, file: File) {
|
||||||
|
val out = new java.io.PrintWriter(file)
|
||||||
|
out.write(text)
|
||||||
|
out.close()
|
||||||
|
}
|
||||||
|
val resources = Seq(
|
||||||
|
// TODO(rigge): make conditional on if we are using verilator
|
||||||
|
"/project-template/csrc/emulator.cc",
|
||||||
|
"/csrc/SimDTM.cc",
|
||||||
|
"/csrc/SimJTAG.cc",
|
||||||
|
"/csrc/remote_bitbang.h",
|
||||||
|
"/csrc/remote_bitbang.cc",
|
||||||
|
"/csrc/verilator.h",
|
||||||
|
"/vsrc/EICG_wrapper.v",
|
||||||
|
"/testchipip/bootrom/bootrom.rv64.img",
|
||||||
|
)
|
||||||
|
|
||||||
|
def writeBootrom(): Unit = {
|
||||||
|
firrtl.FileUtils.makeDirectory("./bootrom/")
|
||||||
|
writeResource("/testchipip/bootrom/bootrom.rv64.img", "./bootrom/")
|
||||||
|
}
|
||||||
|
|
||||||
|
def writeFiles(cfg: GenerateSimConfig): Unit = {
|
||||||
|
writeBootrom()
|
||||||
|
firrtl.FileUtils.makeDirectory(cfg.targetDir)
|
||||||
|
val files = resources.map { writeResource(_, cfg.targetDir) }
|
||||||
|
writeDotF(files.map(addOption), cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
parser.parse(args, GenerateSimConfig()) match {
|
||||||
|
case Some(cfg) => writeFiles(cfg)
|
||||||
|
case _ => // error message already shown
|
||||||
|
}
|
||||||
|
}
|
||||||
Submodule testchipip updated: 4775caf9f2...b30b72615a
@@ -21,19 +21,15 @@ LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(sim_dir) -lfesv
|
|||||||
include $(base_dir)/Makefrag
|
include $(base_dir)/Makefrag
|
||||||
include $(sim_dir)/Makefrag-verilator
|
include $(sim_dir)/Makefrag-verilator
|
||||||
|
|
||||||
|
sim_blackboxes = \
|
||||||
|
$(build_dir)/firrtl_black_box_resource_files.f
|
||||||
|
|
||||||
rocketchip_vsrc_dir = $(ROCKETCHIP_DIR)/src/main/resources/vsrc
|
rocketchip_vsrc_dir = $(ROCKETCHIP_DIR)/src/main/resources/vsrc
|
||||||
|
|
||||||
sim_vsrcs = \
|
sim_vsrcs = \
|
||||||
$(VERILOG_FILE) \
|
$(VERILOG_FILE) \
|
||||||
$(HARNESS_FILE) \
|
$(HARNESS_FILE) \
|
||||||
$(SMEMS_FILE) \
|
$(SMEMS_FILE)
|
||||||
$(rocketchip_vsrc_dir)/AsyncResetReg.v \
|
|
||||||
$(rocketchip_vsrc_dir)/plusarg_reader.v \
|
|
||||||
$(testchip_vsrcs)
|
|
||||||
|
|
||||||
sim_csrcs = \
|
|
||||||
$(sim_dir)/csrc/verilator-harness.cc \
|
|
||||||
$(testchip_csrcs)
|
|
||||||
|
|
||||||
model_dir = $(build_dir)/$(long_name)
|
model_dir = $(build_dir)/$(long_name)
|
||||||
model_dir_debug = $(build_dir)/$(long_name).debug
|
model_dir_debug = $(build_dir)/$(long_name).debug
|
||||||
@@ -44,26 +40,27 @@ model_header_debug = $(model_dir_debug)/V$(MODEL).h
|
|||||||
model_mk = $(model_dir)/V$(MODEL).mk
|
model_mk = $(model_dir)/V$(MODEL).mk
|
||||||
model_mk_debug = $(model_dir_debug)/V$(MODEL).mk
|
model_mk_debug = $(model_dir_debug)/V$(MODEL).mk
|
||||||
|
|
||||||
$(model_mk): $(sim_vsrcs) $(INSTALLED_VERILATOR)
|
$(model_mk): $(sim_vsrcs) $(verilator_dotf) $(INSTALLED_VERILATOR)
|
||||||
rm -rf $(build_dir)/$(long_name)
|
rm -rf $(build_dir)/$(long_name)
|
||||||
mkdir -p $(build_dir)/$(long_name)
|
mkdir -p $(build_dir)/$(long_name)
|
||||||
$(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(build_dir)/$(long_name) \
|
$(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(build_dir)/$(long_name) \
|
||||||
-o $(sim) $(sim_vsrcs) $(sim_csrcs) -LDFLAGS "$(LDFLAGS)" \
|
-o $(sim) $(sim_vsrcs) -f $(verilator_dotf) -f $(sim_blackboxes) -LDFLAGS "$(LDFLAGS)" \
|
||||||
-CFLAGS "-I$(build_dir) -include $(model_header)"
|
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(model_header)"
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
$(sim): $(model_mk) $(sim_csrcs)
|
$(sim): $(model_mk)
|
||||||
$(MAKE) VM_PARALLEL_BUILDS=1 -C $(build_dir)/$(long_name) -f V$(MODEL).mk
|
$(MAKE) VM_PARALLEL_BUILDS=1 -C $(build_dir)/$(long_name) -f V$(MODEL).mk
|
||||||
|
|
||||||
|
|
||||||
$(model_mk_debug): $(sim_vsrcs) $(INSTALLED_VERILATOR)
|
$(model_mk_debug): $(sim_vsrcs) $(verilator_dotf) $(INSTALLED_VERILATOR)
|
||||||
|
rm -rf $(build_dir)/$(long_name)
|
||||||
mkdir -p $(build_dir)/$(long_name).debug
|
mkdir -p $(build_dir)/$(long_name).debug
|
||||||
$(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(build_dir)/$(long_name).debug --trace \
|
$(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(build_dir)/$(long_name).debug --trace \
|
||||||
-o $(sim_debug) $(sim_vsrcs) $(sim_csrcs) -LDFLAGS "$(LDFLAGS)" \
|
-o $(sim_debug) $(sim_vsrcs) -f $(verilator_dotf) -f $(sim_blackboxes) -LDFLAGS "$(LDFLAGS)" \
|
||||||
-CFLAGS "-I$(build_dir) -include $(model_header_debug)"
|
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(model_header_debug)"
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
$(sim_debug): $(model_mk_debug) $(sim_csrcs)
|
$(sim_debug): $(model_mk_debug)
|
||||||
$(MAKE) VM_PARALLEL_BUILDS=1 -C $(build_dir)/$(long_name).debug -f V$(MODEL).mk
|
$(MAKE) VM_PARALLEL_BUILDS=1 -C $(build_dir)/$(long_name).debug -f V$(MODEL).mk
|
||||||
|
|
||||||
$(output_dir)/%.out: $(output_dir)/% $(sim)
|
$(output_dir)/%.out: $(output_dir)/% $(sim)
|
||||||
@@ -83,5 +80,5 @@ run-regression-tests-fast: $(addprefix $(output_dir)/,$(addsuffix .run,$(regress
|
|||||||
|
|
||||||
run-regression-tests-debug: $(addprefix $(output_dir)/,$(addsuffix .vpd,$(regression-tests)))
|
run-regression-tests-debug: $(addprefix $(output_dir)/,$(addsuffix .vpd,$(regression-tests)))
|
||||||
|
|
||||||
clean:
|
clean: clean-scala
|
||||||
rm -rf generated-src ./simulator-*
|
rm -rf generated-src ./simulator-*
|
||||||
|
|||||||
@@ -24,8 +24,6 @@ verilator/verilator-$(VERILATOR_VERSION).tar.gz:
|
|||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
wget http://www.veripool.org/ftp/verilator-$(VERILATOR_VERSION).tgz -O $@
|
wget http://www.veripool.org/ftp/verilator-$(VERILATOR_VERSION).tgz -O $@
|
||||||
|
|
||||||
rocketchip_csrc_dir = $(ROCKETCHIP_DIR)/src/main/resources/csrc
|
|
||||||
|
|
||||||
# Run Verilator to produce a fast binary to emulate this circuit.
|
# Run Verilator to produce a fast binary to emulate this circuit.
|
||||||
VERILATOR := $(INSTALLED_VERILATOR) --cc --exe
|
VERILATOR := $(INSTALLED_VERILATOR) --cc --exe
|
||||||
VERILATOR_FLAGS := --top-module $(MODEL) \
|
VERILATOR_FLAGS := --top-module $(MODEL) \
|
||||||
@@ -33,4 +31,4 @@ VERILATOR_FLAGS := --top-module $(MODEL) \
|
|||||||
+define+STOP_COND=\$$c\(\"done_reset\"\) --assert \
|
+define+STOP_COND=\$$c\(\"done_reset\"\) --assert \
|
||||||
--output-split 20000 \
|
--output-split 20000 \
|
||||||
-Wno-STMTDLY --x-assign unique \
|
-Wno-STMTDLY --x-assign unique \
|
||||||
-O3 -CFLAGS "$(CXXFLAGS) -DVERILATOR -include $(rocketchip_csrc_dir)/verilator.h"
|
-O3 -CFLAGS "$(CXXFLAGS) -DTEST_HARNESS=V$(MODEL) -DVERILATOR"
|
||||||
|
|||||||
@@ -1,167 +0,0 @@
|
|||||||
// See LICENSE for license details.
|
|
||||||
|
|
||||||
#include "verilated.h"
|
|
||||||
#if VM_TRACE
|
|
||||||
#include "verilated_vcd_c.h"
|
|
||||||
#endif
|
|
||||||
#include <fesvr/tsi.h>
|
|
||||||
#include <iostream>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <signal.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
extern tsi_t* tsi;
|
|
||||||
static uint64_t trace_count = 0;
|
|
||||||
bool verbose;
|
|
||||||
bool done_reset;
|
|
||||||
|
|
||||||
void handle_sigterm(int sig)
|
|
||||||
{
|
|
||||||
tsi->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
double sc_time_stamp()
|
|
||||||
{
|
|
||||||
return trace_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" int vpi_get_vlog_info(void* arg)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int copy_argv(int argc, char **argv, char **new_argv)
|
|
||||||
{
|
|
||||||
int optind = 1;
|
|
||||||
int new_argc = argc;
|
|
||||||
|
|
||||||
new_argv[0] = argv[0];
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
if (argv[i][0] != '+' && argv[i][0] != '-') {
|
|
||||||
optind = i - 1;
|
|
||||||
new_argc = argc - i + 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 1; i < new_argc; i++)
|
|
||||||
new_argv[i] = argv[i + optind];
|
|
||||||
|
|
||||||
return new_argc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
unsigned random_seed = (unsigned)time(NULL) ^ (unsigned)getpid();
|
|
||||||
uint64_t max_cycles = -1;
|
|
||||||
uint64_t start = 0;
|
|
||||||
int ret = 0;
|
|
||||||
FILE *vcdfile = NULL;
|
|
||||||
bool print_cycles = false;
|
|
||||||
char *new_argv[argc];
|
|
||||||
int new_argc;
|
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++) {
|
|
||||||
std::string arg = argv[i];
|
|
||||||
if (arg.substr(0, 2) == "-v") {
|
|
||||||
const char* filename = argv[i]+2;
|
|
||||||
vcdfile = strcmp(filename, "-") == 0 ? stdout : fopen(filename, "w");
|
|
||||||
if (!vcdfile)
|
|
||||||
abort();
|
|
||||||
} else if (arg.substr(0, 2) == "-s")
|
|
||||||
random_seed = atoi(argv[i]+2);
|
|
||||||
else if (arg == "+verbose")
|
|
||||||
verbose = true;
|
|
||||||
else if (arg.substr(0, 12) == "+max-cycles=")
|
|
||||||
max_cycles = atoll(argv[i]+12);
|
|
||||||
else if (arg.substr(0, 7) == "+start=")
|
|
||||||
start = atoll(argv[i]+7);
|
|
||||||
else if (arg.substr(0, 12) == "+cycle-count")
|
|
||||||
print_cycles = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (verbose)
|
|
||||||
fprintf(stderr, "using random seed %u\n", random_seed);
|
|
||||||
|
|
||||||
srand(random_seed);
|
|
||||||
srand48(random_seed);
|
|
||||||
|
|
||||||
Verilated::randReset(2);
|
|
||||||
Verilated::commandArgs(argc, argv);
|
|
||||||
VTestHarness *tile = new VTestHarness;
|
|
||||||
|
|
||||||
#if VM_TRACE
|
|
||||||
Verilated::traceEverOn(true); // Verilator must compute traced signals
|
|
||||||
std::unique_ptr<VerilatedVcdFILE> vcdfd(new VerilatedVcdFILE(vcdfile));
|
|
||||||
std::unique_ptr<VerilatedVcdC> tfp(new VerilatedVcdC(vcdfd.get()));
|
|
||||||
if (vcdfile) {
|
|
||||||
tile->trace(tfp.get(), 99); // Trace 99 levels of hierarchy
|
|
||||||
tfp->open("");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
new_argc = copy_argv(argc, argv, new_argv);
|
|
||||||
tsi = new tsi_t(new_argc, new_argv);
|
|
||||||
|
|
||||||
signal(SIGTERM, handle_sigterm);
|
|
||||||
|
|
||||||
// reset for several cycles to handle pipelined reset
|
|
||||||
for (int i = 0; i < 10; i++) {
|
|
||||||
tile->reset = 1;
|
|
||||||
tile->clock = 0;
|
|
||||||
tile->eval();
|
|
||||||
tile->clock = 1;
|
|
||||||
tile->eval();
|
|
||||||
tile->reset = 0;
|
|
||||||
}
|
|
||||||
done_reset = true;
|
|
||||||
|
|
||||||
while (!tsi->done() && !tile->io_success && trace_count < max_cycles) {
|
|
||||||
tile->clock = 0;
|
|
||||||
tile->eval();
|
|
||||||
#if VM_TRACE
|
|
||||||
bool dump = tfp && trace_count >= start;
|
|
||||||
if (dump)
|
|
||||||
tfp->dump(static_cast<vluint64_t>(trace_count * 2));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
tile->clock = 1;
|
|
||||||
tile->eval();
|
|
||||||
#if VM_TRACE
|
|
||||||
if (dump)
|
|
||||||
tfp->dump(static_cast<vluint64_t>(trace_count * 2 + 1));
|
|
||||||
#endif
|
|
||||||
trace_count++;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if VM_TRACE
|
|
||||||
if (tfp)
|
|
||||||
tfp->close();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (vcdfile)
|
|
||||||
fclose(vcdfile);
|
|
||||||
|
|
||||||
if (tsi->exit_code())
|
|
||||||
{
|
|
||||||
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", tsi->exit_code(), random_seed, trace_count);
|
|
||||||
ret = tsi->exit_code();
|
|
||||||
}
|
|
||||||
else if (trace_count == max_cycles)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "*** FAILED *** (timeout, seed %d) after %ld cycles\n", random_seed, trace_count);
|
|
||||||
ret = 2;
|
|
||||||
}
|
|
||||||
else if (verbose || print_cycles)
|
|
||||||
{
|
|
||||||
fprintf(stderr, "Completed after %ld cycles\n", trace_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete tsi;
|
|
||||||
delete tile;
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user