From 1d54224fb9f1fef2b946bd40c4cd286f15dee28a Mon Sep 17 00:00:00 2001 From: Damien Pretet Date: Mon, 26 Sep 2022 16:01:35 +0200 Subject: [PATCH] Merge develop-verilator branch Update CI to run also verilator --- .github/workflows/ci.yaml | 13 ++++- README.md | 5 +- example/fsm.sv | 12 ++++- example/fsm_example_testbench.sv | 29 ++++++---- example/runme.sh | 93 +++++++++++++++++++++++++++++++- example/sim_main.cpp | 85 +++++++++++++++++++++++++++++ 6 files changed, 219 insertions(+), 18 deletions(-) create mode 100644 example/sim_main.cpp diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 1c0d32c..1f38ecc 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -6,12 +6,21 @@ jobs: steps: - uses: actions/checkout@v2 - run: brew install verilator + - run: verilator -V - run: verilator --lint-only svlogger.sv - Example: + Example-Icarus: runs-on: macos-latest steps: - uses: actions/checkout@v2 - run: brew install icarus-verilog - run: iverilog -V - - run: cd example && ./runme.sh + - run: cd example && ./runme.sh -s icarus + + Example-Verilator: + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - run: brew install verilator + - run: verilator -V + - run: cd example && ./runme.sh -s verilator diff --git a/README.md b/README.md index 93a0499..7c61359 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,9 @@ and into the fileset: +incdir+SVLOGGER_PATH ``` -Please notice this project has been developed and tested with Icarus Verilog 11 and can't work -with oldest version. +Please notice this project has been developed and tested with Icarus Verilog 11 and Verilator 5. +It can't work with oldest version of these software. SVlogger could probably work with other +(commercial) simulators but it never has been tested oustide iverilog and verilator scope. ## How to diff --git a/example/fsm.sv b/example/fsm.sv index 744022e..9469852 100644 --- a/example/fsm.sv +++ b/example/fsm.sv @@ -6,7 +6,7 @@ module fsm #( - parameter NAME = 0 + parameter NAME = "FSMExample" )( input logic aclk, input logic aresetn @@ -55,7 +55,15 @@ module fsm end FOUR: begin mylog.error("Moving in FOUR state"); - fsm <= IDLE; + fsm <= FIVE; + end + FIVE: begin + mylog.info("Moving in FIVE state"); + fsm <= SIX; + end + SIX: begin + mylog.info("End of simulation"); + $finish(); end endcase end diff --git a/example/fsm_example_testbench.sv b/example/fsm_example_testbench.sv index 250ebef..0c7727d 100644 --- a/example/fsm_example_testbench.sv +++ b/example/fsm_example_testbench.sv @@ -3,25 +3,30 @@ `timescale 1 ns / 100 ps -module fsm_example_testbench(); - - `SVUT_SETUP - - parameter NAME = 0; - - logic aclk; - logic aresetn; +module fsm_example_testbench( + `ifdef VERILATOR + input wire aclk, + input wire aresetn + `endif +); fsm #( - NAME + "fsm_example" ) dut ( - aclk, - aresetn + aclk, + aresetn ); + `ifndef VERILATOR + + `SVUT_SETUP + + logic aclk; + logic aresetn; + // To create a clock: initial aclk = 0; always #2 aclk = ~aclk; @@ -84,4 +89,6 @@ module fsm_example_testbench(); `TEST_SUITE_END + `endif + endmodule diff --git a/example/runme.sh b/example/runme.sh index dc03ce6..eb5f7e3 100755 --- a/example/runme.sh +++ b/example/runme.sh @@ -1,3 +1,94 @@ #!/usr/bin/env bash +set -e -iverilog -g2012 -Wall -o icarus.out -f files.f fsm_example_testbench.sv ; vvp icarus.out +#------------------------------------------------------------------------------ +# Variables and setup +#------------------------------------------------------------------------------ + +test_ret=0 +do_clean=0 + +# Use Icarus Verilog simulator +[[ -z $SIM ]] && SIM="icarus" + +#------------------------------------------------------------------------------ +# Grab arguments and values +#------------------------------------------------------------------------------ + +get_args() { + + while [ "$1" != "" ]; do + case $1 in + -s | --simulator ) + shift + SIM=$1 + ;; + -c | --clean ) + do_clean=1 + ;; + -h | --help ) + usage + exit 0 + ;; + * ) + usage + exit 1 + ;; + esac + shift + done +} + + +#------------------------------------------------------------------------------ +# Cleaner +#------------------------------------------------------------------------------ +clean() { + echo "Clean-up" + rm -f "*.txt" + rm -f icarus.out + rm -fr build +} + +#------------------------------------------------------------------------------ +# Helper +#------------------------------------------------------------------------------ +usage() { +cat << EOF +usage: bash ./run.sh ... +-c | --clean Clean-up and exit +-s | --simulator Choose between icarus or verilator (icarus is default) +-h | --help Brings up this menu + --simulator Choose between icarus or verilator (icarus is default) +EOF +} + +compile() { + if [ "$SIM" == "icarus" ]; then + iverilog -g2012 -Wall -o icarus.out -f files.f fsm_example_testbench.sv ; vvp icarus.out + else + verilator -Wall --trace --Mdir build +1800-2017ext+sv \ + +1800-2005ext+v -Wno-STMTDLY -Wno-UNUSED -Wno-UNDRIVEN -Wno-PINCONNECTEMPTY \ + -Wpedantic -Wno-VARHIDDEN -Wno-lint \ + +incdir+. -f files.f \ + -cc --exe --build -j --top-module fsm_example_testbench \ + fsm_example_testbench.sv sim_main.cpp + + ./build/Vfsm_example_testbench + fi +} +#------------------------------------------------------------------------------ +# Main +#------------------------------------------------------------------------------ + +main() { + get_args "$@" + + if [ $do_clean -eq 1 ]; then + clean + else + compile + fi +} + +main "$@" diff --git a/example/sim_main.cpp b/example/sim_main.cpp new file mode 100644 index 0000000..d3c60f3 --- /dev/null +++ b/example/sim_main.cpp @@ -0,0 +1,85 @@ +// distributed under the mit license +// https://opensource.org/licenses/mit-license.php + +#include "build/Vfsm_example_testbench.h" +// For std::unique_ptr +#include +// Include common routines +#include + +// Legacy function required only so linking works on Cygwin and MSVC++ +double sc_time_stamp() { return 0; } + +int main(int argc, char** argv, char** env) { + + int ret = 0; + + // Prevent unused variable warnings + if (false && argc && argv && env) {} + + // Construct a VerilatedContext to hold simulation time, etc. + // Multiple modules (made later below with Vtop) may share the same + // context to share time, or modules may have different contexts if + // they should be independent from each other. + // Using unique_ptr is similar to + // "VerilatedContext* contextp = new VerilatedContext" then deleting at end. + const std::unique_ptr contextp{new VerilatedContext}; + // Set debug level, 0 is off, 9 is highest presently used + // May be overridden by commandArgs argument parsing + contextp->debug(0); + // Randomization reset policy + // May be overridden by commandArgs argument parsing + contextp->randReset(1); + // Verilator must compute traced signals + contextp->traceEverOn(true); + // Pass arguments so Verilated code can see them, e.g. $value$plusargs + // This needs to be called before you create any model + contextp->commandArgs(argc, argv); + // Construct the Verilated model, from Vtop.h generated from Verilating "top.v". + // Using unique_ptr is similar to "Vtop* top = new Vtop" then deleting at end. + // "TOP" will be the hierarchical name of the module. + const std::unique_ptr top{new Vfsm_example_testbench{contextp.get(), "fsm_example_testbench"}}; + + + top->aclk = 0; + top->aresetn = 0; + + // Simulate until $finish + while (!contextp->gotFinish()) { + + contextp->timeInc(1); // 1 timeprecision period passes... + // Historical note, before Verilator 4.200 a sc_time_stamp() + // function was required instead of using timeInc. Once timeInc() + // is called (with non-zero), the Verilated libraries assume the + // new API, and sc_time_stamp() will no longer work. + + // Toggle a fast (time/2 period) clock + top->aclk = !top->aclk; + + // Toggle control signals on an edge that doesn't correspond + // to where the controls are sampled; in this example we do + // this only on a negedge of clk, because we know + // reset is not sampled there. + if (!top->aclk) { + if (contextp->time() > 1 && contextp->time() < 10) { + top->aresetn = 0; + } else { + top->aresetn = 1; + } + } + + // Evaluate model + // (If you have multiple models being simulated in the same + // timestep then instead of eval(), call eval_step() on each, then + // eval_end_step() on each. See the manual.) + top->eval(); + + } + + // Final model cleanup + top->final(); + + if (!ret) VL_PRINTF("INFO: Verilator executed successfully\n"); + + return ret; +}