Builds a Verilated executable by running Verilator inside Docker.
This module stages SystemVerilog source files and a generated C++ wrapper into a
host-side work directory, mounts that directory into a Docker container, and
runs the Verilator Docker image with --cc --exe --build.
The expected inputs are:
- a SystemVerilog top-module name
- one or more existing SystemVerilog source files
- an existing C++ wrapper file, typically generated by
SvPortSim.Verilator.Wrapper
During compilation, source files are copied into rtl/ under the work
directory, and the wrapper file is copied into cpp/. Verilator output is
written into obj_dir/, and the expected executable path is
obj_dir/V<top_module>.
This module depends on Docker being installed and usable by the current process.
By default, compile_executable/4 checks Docker daemon availability before
running the build.
The functions in this module do not generate RTL sources or wrapper sources. They only stage existing files and invoke Verilator through Docker.
Summary
Functions
Compiles a Verilated executable by running Verilator inside Docker.
Returns the default host-side Verilator work directory for top_module.
Types
Functions
@spec compile_executable(term(), term(), term(), keyword()) :: {:ok, build_result()} | {:error, term()}
Compiles a Verilated executable by running Verilator inside Docker.
top_module is the SystemVerilog top-module name. It must be a simple
identifier accepted by this module: the name must start with an ASCII letter or
underscore, followed by ASCII letters, digits, underscores, or dollar signs.
source_files is a non-empty list of existing SystemVerilog source file paths.
The basenames of the source files must be unique because the files are staged
under the same rtl/ directory in the Docker-mounted workspace.
wrapper_cpp is the path to an existing C++ wrapper source file. The wrapper is
staged under cpp/ in the Docker-mounted workspace.
The Docker command mounts the host-side work directory at /work in the
container and runs Verilator with:
--cc--exe--build-j <make_jobs>--Mdir obj_dir--top-module <top_module>
Extra Verilator arguments, if any, are appended after the fixed Verilator options and before the staged wrapper and source paths.
Options
:image- Docker image to use. Defaults to"verilator/verilator:latest".:work_dir- Host-side build directory. Defaults todefault_work_dir(top_module). The directory is expanded before use.:docker- Docker executable path. When omitted, the executable is resolved withDockerAvailability.executable/0.:check_docker- Whether to check Docker daemon reachability before preparing the workspace and running Verilator. Defaults totrue.:make_jobs- Value passed to Verilator's-joption. Accepts a non-negative integer or a non-empty string. Defaults to0.:extra_args- Additional Verilator arguments. Must be a list of strings. Defaults to[].:user- Docker user option. Defaults to:current, which attempts to pass the currentuid:gidto Docker. Usenilorfalseto omit--user, or pass a non-empty string such as"1000:1000".:clean- Whether to remove stagedrtl/,cpp/, andobj_dir/directories before preparing the workspace. Defaults totrue.:verify_executable- Whether to require the expected executableobj_dir/V<top_module>to exist after Docker finishes successfully. Defaults totrue.
Return value
Returns {:ok, build} on success.
The returned build map contains:
:top_module- the top-module name:image- the Docker image used for the build:docker- the Docker executable path:work_dir- the host-side work directory:obj_dir- the host-side Verilator output directory:executable- the expected host-side executable path:command- the full Docker command as a list of strings:log- combined standard output and standard error from Docker
Returns {:error, reason} when validation, staging, Docker execution, or
executable verification fails.
Common error reasons include:
{:invalid_arguments, top_module, source_files, wrapper_cpp}when the required arguments or options do not have the expected types{:invalid_top_module, top_module}when the top-module name is not accepted:empty_source_fileswhen no source files are provided{:invalid_source_files, source_files}whensource_filescontains a non-string entry{:duplicate_source_basenames, basenames}when multiple source files would collide in the stagedrtl/directory{:source_not_found, path}when a source file does not exist as a regular file{:wrapper_not_found, path}when the wrapper file does not exist as a regular file:docker_not_foundwhen the Docker executable cannot be found{:invalid_docker_executable, docker}when the:dockeroption is invalid{:docker_unavailable, status, output}when Docker daemon precheck fails{:docker_command_failed, status, output}when a Docker command cannot be executed{:invalid_image, image}when the Docker image option is invalid{:invalid_make_jobs, make_jobs}when the:make_jobsoption is invalid{:invalid_extra_args, extra_args}when:extra_argsis not a list of strings{:invalid_work_dir, work_dir}when the work directory option is invalid{:mkdir_failed, path, reason}when a workspace directory cannot be created{:clean_failed, path, reason}when workspace cleanup fails{:copy_failed, source, destination, reason}when staging a file fails{:verilator_docker_failed, status, log, command}when Docker exits with a non-zero status while running Verilator{:executable_not_found, executable, log, command}when Docker succeeds but the expected executable is missing{:docker_run_failed, message}when invoking Docker raises an Erlang error
Example
{:ok, build} =
SvPortSim.Verilator.Docker.compile_executable(
"Counter",
["_build/dev/lib/sv_port_sim/rtl/Counter.sv"],
"_build/dev/lib/sv_port_sim/cpp/Counter_wrapper.cpp",
extra_args: ["-Wall"]
)
build.executable
#=> ".../obj_dir/VCounter"
Returns the default host-side Verilator work directory for top_module.
The returned path is application-local and is currently resolved as:
Application.app_dir(:sv_port_sim, Path.join(["verilator", top_module]))For example, the default work directory for "Counter" is under the
application's verilator/Counter directory.
This function only builds the path. It does not validate the top-module name, create the directory, clean previous build artifacts, or run Docker.