├── .bazelversion ├── .gitignore ├── BUILD ├── .bazelrc ├── test └── alu │ ├── .bazelrc │ ├── alu.cpp │ ├── alu.sv │ └── BUILD ├── verilator ├── BUILD ├── toolchains │ └── BUILD ├── internal │ ├── BUILD │ ├── versions.bzl │ ├── toolchain.bzl │ ├── cc_actions.bzl │ └── verilator.BUILD ├── repositories.bzl └── defs.bzl ├── WORKSPACE ├── .github └── workflows │ └── ci_bazel.yml ├── README.md └── LICENSE /.bazelversion: -------------------------------------------------------------------------------- 1 | 5.2.0 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bazel-* 2 | -------------------------------------------------------------------------------- /BUILD: -------------------------------------------------------------------------------- 1 | exports_files(["LICENSE"]) 2 | -------------------------------------------------------------------------------- /.bazelrc: -------------------------------------------------------------------------------- 1 | build --incompatible_strict_action_env=true 2 | -------------------------------------------------------------------------------- /test/alu/.bazelrc: -------------------------------------------------------------------------------- 1 | build --experimental_cc_skylark_api_enabled_packages=@rules_verilator//verilator 2 | -------------------------------------------------------------------------------- /test/alu/alu.cpp: -------------------------------------------------------------------------------- 1 | #include "Valu.h" 2 | 3 | int main() { 4 | Valu alu; 5 | 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /test/alu/alu.sv: -------------------------------------------------------------------------------- 1 | module alu #(parameter int W = 16) ( 2 | input logic [W-1:0] x, 3 | input logic [W-1:0] y, 4 | output logic [W-1:0] z 5 | ); 6 | assign z = x * y; 7 | endmodule 8 | -------------------------------------------------------------------------------- /verilator/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_verilator//verilator/internal:toolchain.bzl", "verilator_toolchain_alias") 2 | 3 | toolchain_type( 4 | name = "toolchain_type", 5 | visibility = ["//visibility:public"], 6 | ) 7 | 8 | verilator_toolchain_alias( 9 | name = "toolchain", 10 | visibility = ["//visibility:public"], 11 | ) 12 | -------------------------------------------------------------------------------- /verilator/toolchains/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_verilator//verilator/internal:toolchain.bzl", "TOOLCHAIN_TYPE") 2 | load("@rules_verilator//verilator/internal:versions.bzl", "VERSION_INFO") 3 | 4 | [toolchain( 5 | name = "v{}".format(version), 6 | toolchain = "@rules_verilator//verilator/internal:toolchain_v{}".format(version), 7 | toolchain_type = TOOLCHAIN_TYPE, 8 | ) for version in VERSION_INFO.keys()] 9 | -------------------------------------------------------------------------------- /verilator/internal/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_verilator//verilator/internal:toolchain.bzl", "verilator_toolchain_info") 2 | load("@rules_verilator//verilator/internal:versions.bzl", "VERSION_INFO") 3 | 4 | [verilator_toolchain_info( 5 | name = "toolchain_v{}".format(version), 6 | libs = [ 7 | "@verilator_v{}//:libverilator".format(version), 8 | "@verilator_v{}//:svdpi".format(version), 9 | ], 10 | verilator = "@verilator_v{}//:verilator_executable".format(version), 11 | visibility = ["//visibility:public"], 12 | ) for version in VERSION_INFO.keys()] 13 | -------------------------------------------------------------------------------- /test/alu/BUILD: -------------------------------------------------------------------------------- 1 | load("@rules_verilog//verilog:defs.bzl", "verilog_module") 2 | load("@rules_verilator//verilator:defs.bzl", "sv_library", "verilator_cc_library") 3 | 4 | sv_library( 5 | name = "alu_lib", 6 | srcs = ["alu.sv"], 7 | ) 8 | 9 | verilator_cc_library( 10 | name = "alu", 11 | mtop = "alu", 12 | deps = [":alu_lib"], 13 | ) 14 | 15 | cc_binary( 16 | name = "alu_bin", 17 | srcs = ["alu.cpp"], 18 | deps = [":alu"], 19 | ) 20 | 21 | verilog_module( 22 | name = "alu_module", 23 | srcs = ["alu.sv"], 24 | top = "alu", 25 | ) 26 | 27 | verilator_cc_library( 28 | name = "alu_with_module", 29 | module = ":alu_module", 30 | ) 31 | 32 | cc_binary( 33 | name = "alu_bin_with_module", 34 | srcs = ["alu.cpp"], 35 | deps = [":alu_with_module"], 36 | ) 37 | -------------------------------------------------------------------------------- /verilator/internal/versions.bzl: -------------------------------------------------------------------------------- 1 | """Helpers for finding the repository information for a specific version""" 2 | 3 | _MIRROR_URLS = [ 4 | "https://github.com/verilator/verilator/archive/{}.tar.gz", 5 | ] 6 | 7 | def _urls(version): 8 | if version != "master": 9 | version = "v" + version 10 | return [m.format(version) for m in _MIRROR_URLS] 11 | 12 | def _info(version, sha256): 13 | return (version, struct( 14 | sha256 = sha256, 15 | strip_prefix = "verilator-{}".format(version), 16 | urls = _urls(version), 17 | )) 18 | 19 | VERSION_INFO = dict([ 20 | _info("4.224", "010ff2b5c76d4dbc2ed4a3278a5599ba35c8ed4c05690e57296d6b281591367b"), 21 | _info("master", ""), # Hash omitted. Use at your own risk. 22 | ]) 23 | 24 | DEFAULT_VERSION = "4.224" 25 | 26 | def version_info(version): 27 | if version not in VERSION_INFO: 28 | fail("Verilator version {} not supported by rules_verilator.".format(repr(version))) 29 | return VERSION_INFO[version] 30 | -------------------------------------------------------------------------------- /WORKSPACE: -------------------------------------------------------------------------------- 1 | workspace(name = "rules_verilator") 2 | 3 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 4 | load( 5 | "@rules_verilator//verilator:repositories.bzl", 6 | "rules_verilator_dependencies", 7 | "rules_verilator_toolchains", 8 | ) 9 | 10 | rules_verilator_dependencies() 11 | 12 | # This defines a toolchain for all supported versions to the repo for testing 13 | # purposes. Most project should simply use the default toochain, i.e.: 14 | # 15 | # rules_verilator_toolchains() 16 | load("@rules_verilator//verilator/internal:versions.bzl", "VERSION_INFO") 17 | 18 | [rules_verilator_toolchains(version) for version in VERSION_INFO.keys()] 19 | 20 | # Register dependency toolchains 21 | load("@rules_m4//m4:m4.bzl", "m4_register_toolchains") 22 | 23 | m4_register_toolchains() 24 | 25 | load("@rules_flex//flex:flex.bzl", "flex_register_toolchains") 26 | 27 | flex_register_toolchains() 28 | 29 | load("@rules_bison//bison:bison.bzl", "bison_register_toolchains") 30 | 31 | bison_register_toolchains() 32 | -------------------------------------------------------------------------------- /.github/workflows/ci_bazel.yml: -------------------------------------------------------------------------------- 1 | name: Bazel Tests 2 | on: 3 | push: 4 | branches: 5 | - main 6 | paths: 7 | - '**.cc' 8 | - '**.h' 9 | - '**.cpp' 10 | - '**.hpp' 11 | - '**.sv' 12 | - '**.v' 13 | 14 | pull_request: 15 | branches: 16 | - main 17 | paths: 18 | - '**.cc' 19 | - '**.h' 20 | - '**.cpp' 21 | - '**.hpp' 22 | - '**.sv' 23 | - '**.v' 24 | 25 | jobs: 26 | test: 27 | runs-on: ubuntu-latest 28 | steps: 29 | # Checkout our repo. 30 | - uses: actions/checkout@v2 31 | # Download bazel 32 | - uses: bazelbuild/setup-bazelisk@v1 33 | # Cache previous bazel builds 34 | - name: Cache bazel 35 | uses: actions/cache@v2 36 | env: 37 | cache-name: bazel-cache 38 | with: 39 | path: | 40 | ~/.cache/bazelisk 41 | ~/.cache/bazel 42 | key: ${{ runner.os }}-${{ env.cache-name }} 43 | # Build everything 44 | - name: Build the code 45 | run: bazel build //... 46 | # Test everything 47 | - name: Test the code 48 | run: bazel test //... 49 | -------------------------------------------------------------------------------- /verilator/internal/toolchain.bzl: -------------------------------------------------------------------------------- 1 | TOOLCHAIN_TYPE = "@rules_verilator//verilator:toolchain_type" 2 | 3 | ToolchainInfo = provider(fields = ["files", "libs", "vars", "verilator_executable"]) 4 | 5 | def _verilator_toolchain_info(ctx): 6 | runfiles = ctx.attr.verilator[DefaultInfo].default_runfiles.files 7 | toolchain = ToolchainInfo( 8 | files = depset( 9 | direct = [ctx.executable.verilator], 10 | transitive = [runfiles], 11 | ), 12 | libs = ctx.attr.libs, 13 | vars = {}, 14 | verilator_executable = ctx.executable.verilator, 15 | ) 16 | 17 | return [ 18 | platform_common.ToolchainInfo(verilator_toolchain = toolchain), 19 | platform_common.TemplateVariableInfo(toolchain.vars), 20 | ] 21 | 22 | verilator_toolchain_info = rule( 23 | _verilator_toolchain_info, 24 | attrs = { 25 | "verilator": attr.label( 26 | doc = "Verilator binary", 27 | mandatory = True, 28 | executable = True, 29 | cfg = "host", 30 | ), 31 | "libs": attr.label_list( 32 | doc = "List of runtime libraries required for Verilator programs", 33 | mandatory = True, 34 | allow_empty = False, 35 | providers = [CcInfo], 36 | cfg = "target", 37 | ), 38 | }, 39 | provides = [ 40 | platform_common.ToolchainInfo, 41 | platform_common.TemplateVariableInfo, 42 | ], 43 | ) 44 | 45 | def _verilator_toolchain_alias(ctx): 46 | toolchain = ctx.toolchains[TOOLCHAIN_TYPE].verilator_toolchain 47 | return [ 48 | DefaultInfo(files = toolchain.files), 49 | toolchain, 50 | platform_common.TemplateVariableInfo(toolchain.vars), 51 | ] 52 | 53 | verilator_toolchain_alias = rule( 54 | _verilator_toolchain_alias, 55 | toolchains = [TOOLCHAIN_TYPE], 56 | provides = [ 57 | DefaultInfo, 58 | ToolchainInfo, 59 | platform_common.TemplateVariableInfo, 60 | ], 61 | ) 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Bazel build rules for Verilator 2 | 3 | [![Bazel Tests](../../actions/workflows/ci_bazel.yml/badge.svg)](../../actions/workflows/ci_bazel.yml) 4 | 5 | ## Overview 6 | 7 | Add the following to your `WORKSPACE` file 8 | 9 | ```python 10 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 11 | 12 | # Verilator 13 | http_archive( 14 | name = "rules_verilator", 15 | # See release page for latest urls + sha 16 | ) 17 | 18 | load( 19 | "@rules_verilator//verilator:repositories.bzl", 20 | "rules_verilator_dependencies", 21 | "rules_verilator_toolchains" 22 | ) 23 | rules_verilator_dependencies() 24 | rules_verilator_toolchains() 25 | 26 | # Register toolchain dependencies 27 | load("@rules_m4//m4:m4.bzl", "m4_register_toolchains") 28 | m4_register_toolchains() 29 | 30 | load("@rules_flex//flex:flex.bzl", "flex_register_toolchains") 31 | flex_register_toolchains() 32 | 33 | load("@rules_bison//bison:bison.bzl", "bison_register_toolchains") 34 | bison_register_toolchains() 35 | ``` 36 | 37 | ### Supported Bazel Versions 38 | 39 | These rules are under active development and the minimum supported Bazel version may change. 40 | Currently, the `master` branch requires [Bazel >= 5.2.0](https://blog.bazel.build/2021/01/19/bazel-5-2.html). 41 | 42 | ## Build rules 43 | 44 | ```python 45 | load("@rules_verilator//verilator:defs.bzl", "verilator_cc_library") 46 | 47 | verilator_cc_library( 48 | name = "alu", 49 | mtop = "alu", # defaults to name if not specified 50 | srcs = ["alu.sv"], 51 | ) 52 | 53 | cc_binary( 54 | name = "alu_bin", 55 | srcs = ["alu.cpp"], 56 | deps = [":alu"], 57 | ) 58 | ``` 59 | 60 | The details of a verilog module (sources, top name, etc.) can also be specified by a `verilog_module` 61 | which can be reused in other rules. 62 | 63 | ```python 64 | load("@rules_verilog//verilog:defs.bzl", "verilog_module") 65 | 66 | load("@rules_verilator//verilator:defs.bzl", "verilator_cc_library") 67 | 68 | verilog_module( 69 | name = "alu_module", 70 | top = "alu", 71 | srcs = ["alu.sv"], 72 | ) 73 | 74 | verilator_cc_library( 75 | name = "alu", 76 | module = ":alu_module", 77 | ) 78 | ``` 79 | 80 | See [test/alu/BUILD](test/alu/BUILD) for working examples. 81 | 82 | ## License 83 | 84 | Released under Apache 2.0. 85 | -------------------------------------------------------------------------------- /verilator/internal/cc_actions.bzl: -------------------------------------------------------------------------------- 1 | """Rules for compiling Verilog files to C++ using Verilator""" 2 | 3 | load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain") 4 | 5 | def cc_compile_and_link_static_library(ctx, srcs, hdrs, deps, includes = [], defines = [], 6 | user_compile_flags = [], user_link_flags = []): 7 | """Compile and link C++ source into a static library""" 8 | cc_toolchain = find_cpp_toolchain(ctx) 9 | feature_configuration = cc_common.configure_features( 10 | ctx = ctx, 11 | cc_toolchain = cc_toolchain, 12 | requested_features = ctx.features, 13 | unsupported_features = ctx.disabled_features, 14 | ) 15 | 16 | compilation_contexts = [dep[CcInfo].compilation_context for dep in deps] 17 | compilation_context, compilation_outputs = cc_common.compile( 18 | name = ctx.label.name, 19 | actions = ctx.actions, 20 | feature_configuration = feature_configuration, 21 | cc_toolchain = cc_toolchain, 22 | srcs = srcs, 23 | includes = includes, 24 | defines = defines, 25 | public_hdrs = hdrs, 26 | compilation_contexts = compilation_contexts, 27 | user_compile_flags = user_compile_flags, 28 | ) 29 | 30 | linking_contexts = [dep[CcInfo].linking_context for dep in deps] 31 | linking_context, linking_output = cc_common.create_linking_context_from_compilation_outputs( 32 | actions = ctx.actions, 33 | feature_configuration = feature_configuration, 34 | cc_toolchain = cc_toolchain, 35 | compilation_outputs = compilation_outputs, 36 | linking_contexts = linking_contexts, 37 | name = ctx.label.name, 38 | user_link_flags = user_link_flags, 39 | ) 40 | 41 | output_files = [] 42 | if linking_output.library_to_link.static_library != None: 43 | output_files.append(linking_output.library_to_link.static_library) 44 | if linking_output.library_to_link.dynamic_library != None: 45 | output_files.append(linking_output.library_to_link.dynamic_library) 46 | 47 | return [ 48 | DefaultInfo(files = depset(output_files)), 49 | CcInfo( 50 | compilation_context = compilation_context, 51 | linking_context = linking_context, 52 | ), 53 | ] 54 | -------------------------------------------------------------------------------- /verilator/repositories.bzl: -------------------------------------------------------------------------------- 1 | load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") 2 | load( 3 | "@rules_verilator//verilator/internal:versions.bzl", 4 | _DEFAULT_VERSION = "DEFAULT_VERSION", 5 | _version_info = "version_info", 6 | ) 7 | 8 | def _verilator_repository(ctx): 9 | info = _version_info(ctx.attr.version) 10 | ctx.download_and_extract( 11 | url = info.urls, 12 | sha256 = info.sha256, 13 | stripPrefix = info.strip_prefix, 14 | ) 15 | 16 | ctx.file("WORKSPACE", "workspace(name = {name})\n".format(name = repr(ctx.name))) 17 | ctx.symlink(ctx.attr._buildfile, "BUILD") 18 | 19 | # Generate files usually produced / modified by autotools. 20 | replace = { 21 | "#define PACKAGE_STRING \"\"": "#define PACKAGE_STRING \"Verilator v{}\"".format( 22 | ctx.attr.version, 23 | ), 24 | } 25 | ctx.template("src/config_build.h", "src/config_build.h.in", replace, executable = False) 26 | 27 | ctx.file( 28 | "src/config_rev.h", 29 | "static const char* const DTVERSION_rev = \"v{}\";\n".format(ctx.attr.version), 30 | ) 31 | 32 | replace = { 33 | "@PACKAGE_NAME@": "Verilator", 34 | "@PACKAGE_VERSION@": ctx.attr.version, 35 | } 36 | ctx.template( 37 | "include/verilated_config.h", 38 | "include/verilated_config.h.in", 39 | replace, 40 | executable = False, 41 | ) 42 | 43 | verilator_repository = repository_rule( 44 | _verilator_repository, 45 | attrs = { 46 | "version": attr.string(mandatory = True), 47 | "_buildfile": attr.label( 48 | default = Label("@rules_verilator//verilator/internal:verilator.BUILD"), 49 | ), 50 | }, 51 | ) 52 | 53 | def rules_verilator_dependencies(version = _DEFAULT_VERSION): 54 | _maybe( 55 | http_archive, 56 | name = "rules_m4", 57 | urls = ["https://github.com/jmillikin/rules_m4/releases/download/v0.2.2/rules_m4-v0.2.2.tar.xz"], 58 | sha256 = "b0309baacfd1b736ed82dc2bb27b0ec38455a31a3d5d20f8d05e831ebeef1a8e", 59 | ) 60 | _maybe( 61 | http_archive, 62 | name = "rules_flex", 63 | urls = ["https://github.com/jmillikin/rules_flex/releases/download/v0.2/rules_flex-v0.2.tar.xz"], 64 | sha256 = "f1685512937c2e33a7ebc4d5c6cf38ed282c2ce3b7a9c7c0b542db7e5db59d52", 65 | ) 66 | _maybe( 67 | http_archive, 68 | name = "rules_bison", 69 | urls = ["https://github.com/jmillikin/rules_bison/releases/download/v0.2.1/rules_bison-v0.2.1.tar.xz"], 70 | sha256 = "9577455967bfcf52f9167274063ebb74696cb0fd576e4226e14ed23c5d67a693", 71 | ) 72 | _maybe( 73 | http_archive, 74 | name = "rules_verilog", 75 | urls = ["https://github.com/agoessling/rules_verilog/archive/v0.1.0.zip"], 76 | strip_prefix = "rules_verilog-0.1.0", 77 | sha256 = "401b3f591f296f6fd2f6656f01afc1f93111e10b81b9a9d291f9c04b3e4a3e8b", 78 | ) 79 | 80 | def rules_verilator_toolchains(version = _DEFAULT_VERSION): 81 | repo_name = "verilator_v{version}".format(version = version) 82 | _maybe(verilator_repository, name = repo_name, version = version) 83 | native.register_toolchains("@rules_verilator//verilator/toolchains:v{}".format(version)) 84 | 85 | def _maybe(repo_rule, **kwargs): 86 | if kwargs["name"] not in native.existing_rules(): 87 | repo_rule(**kwargs) 88 | -------------------------------------------------------------------------------- /verilator/internal/verilator.BUILD: -------------------------------------------------------------------------------- 1 | package(default_visibility = ["//visibility:private"]) 2 | 3 | licenses(["notice"]) 4 | 5 | exports_files([ 6 | "Artistic", 7 | "COPYING", 8 | "COPYING.LESSER", 9 | ]) 10 | 11 | sh_binary( 12 | name = "flexfix", 13 | srcs = ["src/flexfix"], 14 | ) 15 | 16 | sh_binary( 17 | name = "bisonpre", 18 | srcs = ["src/bisonpre"], 19 | ) 20 | 21 | genrule( 22 | name = "verilator_astgen", 23 | srcs = [ 24 | "src/V3Ast.h", 25 | "src/V3AstNodes.h", 26 | "src/Verilator.cpp", 27 | "src/astgen", 28 | ], 29 | outs = [ 30 | "V3Ast__gen_classes.h", 31 | "V3Ast__gen_impl.h", 32 | "V3Ast__gen_report.txt", 33 | "V3Ast__gen_types.h", 34 | "V3Ast__gen_visitor.h", 35 | "V3Ast__gen_yystype.h", 36 | "V3AstNodes__gen_macros.h", 37 | ], 38 | cmd = """ 39 | python3 $(location src/astgen) -I$$(dirname $(location src/V3Ast.h)) --classes 40 | cp V3Ast__gen_classes.h $(@D) 41 | cp V3Ast__gen_impl.h $(@D) 42 | cp V3Ast__gen_report.txt $(@D) 43 | cp V3Ast__gen_types.h $(@D) 44 | cp V3Ast__gen_visitor.h $(@D) 45 | cp V3Ast__gen_yystype.h $(@D) 46 | cp V3AstNodes__gen_macros.h $(@D) 47 | """, 48 | ) 49 | 50 | genrule( 51 | name = "verilator_astgen_const", 52 | srcs = [ 53 | "src/V3Ast.h", 54 | "src/V3AstNodes.h", 55 | "src/V3Const.cpp", 56 | "src/Verilator.cpp", 57 | "src/astgen", 58 | ], 59 | outs = ["V3Const__gen.cpp"], 60 | cmd = """ 61 | python3 $(location src/astgen) -I$$(dirname $(location src/V3Const.cpp)) V3Const.cpp 62 | cp V3Const__gen.cpp $(@D) 63 | """, 64 | ) 65 | 66 | genrule( 67 | name = "verilator_lex_pregen", 68 | srcs = ["src/verilog.l"], 69 | outs = ["V3Lexer_pregen.yy.cpp"], 70 | cmd = "M4=$(M4) $(FLEX) -d --outfile=$(@) $(<)", 71 | toolchains = [ 72 | "@rules_flex//flex:current_flex_toolchain", 73 | "@rules_m4//m4:current_m4_toolchain", 74 | ], 75 | ) 76 | 77 | genrule( 78 | name = "verilator_lex_flexfix", 79 | srcs = [":V3Lexer_pregen.yy.cpp"], 80 | outs = ["V3Lexer.yy.cpp"], 81 | cmd = "./$(location :flexfix) V3Lexer < $(<) > $(@)", 82 | tools = [":flexfix"], 83 | ) 84 | 85 | genrule( 86 | name = "verilator_prelex_pregen", 87 | srcs = ["src/V3PreLex.l"], 88 | outs = ["V3PreLex_pregen.yy.cpp"], 89 | cmd = "M4=$(M4) $(FLEX) -d --outfile=$(@) $(<)", 90 | toolchains = [ 91 | "@rules_flex//flex:current_flex_toolchain", 92 | "@rules_m4//m4:current_m4_toolchain", 93 | ], 94 | ) 95 | 96 | genrule( 97 | name = "verilator_prelex_flexfix", 98 | srcs = [":V3PreLex_pregen.yy.cpp"], 99 | outs = ["V3PreLex.yy.cpp"], 100 | cmd = "./$(location :flexfix) V3PreLex < $(<) > $(@)", 101 | tools = [":flexfix"], 102 | ) 103 | 104 | genrule( 105 | name = "verilator_bison", 106 | srcs = ["src/verilog.y"], 107 | outs = [ 108 | "V3ParseBison.c", 109 | "V3ParseBison.h", 110 | ], 111 | cmd = "M4=$(M4) ./$(location :bisonpre) --yacc $(BISON) -d -v -o $(location V3ParseBison.c) $(<)", 112 | toolchains = [ 113 | "@rules_bison//bison:current_bison_toolchain", 114 | "@rules_m4//m4:current_m4_toolchain", 115 | ], 116 | tools = [":bisonpre"], 117 | ) 118 | 119 | cc_library( 120 | name = "verilatedos", 121 | hdrs = ["include/verilatedos.h"], 122 | strip_include_prefix = "include/", 123 | ) 124 | 125 | # Helper lib to break dependency between V3 and libverilated 126 | cc_library( 127 | name = "verilated_trace_defs", 128 | hdrs = ["include/verilated_trace_defs.h"], 129 | strip_include_prefix = "include/", 130 | ) 131 | 132 | # TODO(kkiningh): Verilator also supports multithreading, should we enable it? 133 | cc_library( 134 | name = "verilator_libV3", 135 | srcs = glob( 136 | ["src/V3*.cpp"], 137 | exclude = [ 138 | "src/V3*_test.cpp", 139 | "src/V3Const.cpp", 140 | ], 141 | ) + [ 142 | ":V3Ast__gen_classes.h", 143 | ":V3Ast__gen_impl.h", 144 | ":V3Ast__gen_types.h", 145 | ":V3Ast__gen_visitor.h", 146 | ":V3AstNodes__gen_macros.h", 147 | ":V3Ast__gen_yystype.h", 148 | ":V3Const__gen.cpp", 149 | ":V3ParseBison.h", 150 | ], 151 | hdrs = glob(["src/V3*.h"]) + [ 152 | "src/config_build.h", 153 | "src/config_rev.h", 154 | ], 155 | copts = [ 156 | # TODO: We should probably set this later 157 | "-DDEFENV_SYSTEMC_INCLUDE=\\\"@invalid@\\\"", 158 | "-DDEFENV_SYSTEMC_LIBDIR=\\\"@invalid@\\\"", 159 | "-DDEFENV_VERILATOR_ROOT=\\\"@invalid@\\\"", 160 | # TODO: Remove these once upstream fixes these warnings 161 | "-Wno-unneeded-internal-declaration", 162 | ], 163 | defines = ["YYDEBUG"], 164 | strip_include_prefix = "src/", 165 | textual_hdrs = [ 166 | # These are included directly by other C++ files 167 | # See https://github.com/bazelbuild/bazel/issues/680 168 | ":V3Lexer.yy.cpp", 169 | ":V3PreLex.yy.cpp", 170 | ":V3ParseBison.c", 171 | ], 172 | deps = [ 173 | ":verilated_trace_defs", # Needed for V3TraceDecl.cpp 174 | ":verilatedos", 175 | "@rules_flex//flex:current_flex_toolchain", 176 | ], 177 | ) 178 | 179 | cc_library( 180 | name = "libverilator", 181 | srcs = [ 182 | "include/gtkwave/fastlz.h", 183 | "include/gtkwave/fst_config.h", 184 | "include/gtkwave/fstapi.h", 185 | "include/gtkwave/lz4.h", 186 | "include/gtkwave/wavealloca.h", 187 | "include/verilated.cpp", 188 | "include/verilated_fst_c.cpp", 189 | "include/verilated_imp.h", 190 | "include/verilated_syms.h", 191 | "include/verilated_vcd_c.cpp", 192 | ], 193 | hdrs = [ 194 | "include/verilated.h", 195 | "include/verilated_config.h", 196 | "include/verilated_dpi.h", 197 | "include/verilated_fst_c.h", 198 | "include/verilated_heavy.h", 199 | "include/verilated_intrinsics.h", 200 | "include/verilated_sc.h", 201 | "include/verilated_sym_props.h", 202 | "include/verilated_trace.h", 203 | "include/verilated_trace_defs.h", 204 | # Needed for verilated_vcd_c.cpp and verilated_fst_c.cpp 205 | "include/verilated_trace_imp.h", 206 | "include/verilated_vcd_c.h", 207 | "include/verilatedos.h", 208 | "include/verilated_types.h", 209 | "include/verilated_funcs.h", 210 | ], 211 | includes = ["include"], 212 | strip_include_prefix = "include/", 213 | textual_hdrs = [ 214 | "include/gtkwave/fastlz.c", 215 | "include/gtkwave/fstapi.c", 216 | "include/gtkwave/lz4.c", 217 | ], 218 | visibility = ["//visibility:public"], 219 | # TODO: Remove these once upstream fixes these warnings 220 | copts = [ 221 | "-Wno-unused-const-variable", 222 | "-Wno-deprecated-declarations", 223 | "-Wno-unused-but-set-variable", 224 | ], 225 | ) 226 | 227 | cc_library( 228 | name = "svdpi", 229 | hdrs = [ 230 | "include/vltstd/svdpi.h", 231 | ], 232 | strip_include_prefix = "include/vltstd", 233 | visibility = ["//visibility:public"], 234 | ) 235 | 236 | cc_binary( 237 | name = "verilator_executable", 238 | srcs = ["src/Verilator.cpp"], 239 | visibility = ["//visibility:public"], 240 | deps = [":verilator_libV3"], 241 | ) 242 | -------------------------------------------------------------------------------- /verilator/defs.bzl: -------------------------------------------------------------------------------- 1 | load("@rules_verilog//verilog:defs.bzl", "VerilogModuleInfo") 2 | load( 3 | "@rules_verilator//verilator/internal:cc_actions.bzl", 4 | "cc_compile_and_link_static_library", 5 | ) 6 | load( 7 | "@rules_verilator//verilator/internal:toolchain.bzl", 8 | _TOOLCHAIN_TYPE = "TOOLCHAIN_TYPE", 9 | ) 10 | 11 | # Provider for verilog libraries 12 | VerilogInfo = provider(fields = ["transitive_sources"]) 13 | 14 | def get_transitive_sources(srcs, deps): 15 | """Obtain the underlying source files for a target and it's transitive 16 | dependencies. 17 | 18 | Args: 19 | srcs: a list of source files 20 | deps: a list of targets that are the direct dependencies 21 | Returns: 22 | a collection of the transitive sources 23 | """ 24 | return depset( 25 | direct = srcs, 26 | transitive = [dep[VerilogInfo].transitive_sources for dep in deps], 27 | ) 28 | 29 | def _sv_library(ctx): 30 | transitive_sources = get_transitive_sources(ctx.files.srcs, ctx.attr.deps) 31 | return [VerilogInfo(transitive_sources = transitive_sources)] 32 | 33 | sv_library = rule( 34 | attrs = { 35 | "srcs": attr.label_list( 36 | allow_files = [".v", ".sv"], 37 | ), 38 | "deps": attr.label_list(providers = [VerilogInfo]), 39 | }, 40 | implementation = _sv_library, 41 | ) 42 | 43 | _CPP_SRC = ["cc", "cpp", "cxx", "c++"] 44 | _HPP_SRC = ["h", "hh", "hpp"] 45 | 46 | def _only_cpp(f): 47 | """Filter for just C++ source/headers""" 48 | if f.extension in _CPP_SRC + _HPP_SRC: 49 | return f.path 50 | return None 51 | 52 | def _only_hpp(f): 53 | """Filter for just C++ headers""" 54 | if f.extension in _HPP_SRC: 55 | return f.path 56 | return None 57 | 58 | _COPY_TREE_SH = """ 59 | OUT=$1; shift && mkdir -p "$OUT" && cp $* "$OUT" 60 | """ 61 | 62 | def _copy_tree(ctx, idir, odir, map_each = None, progress_message = None): 63 | """Copy files from a TreeArtifact to a new directory""" 64 | args = ctx.actions.args() 65 | args.add(odir.path) 66 | args.add_all([idir], map_each = map_each) 67 | ctx.actions.run_shell( 68 | arguments = [args], 69 | command = _COPY_TREE_SH, 70 | inputs = [idir], 71 | outputs = [odir], 72 | progress_message = progress_message, 73 | ) 74 | 75 | return odir 76 | 77 | def _verilator_cc_library(ctx): 78 | """Produce a static library and C++ header files from a Verilog library""" 79 | 80 | # Get the verilator toolchain 81 | verilator_toolchain = ctx.toolchains[_TOOLCHAIN_TYPE].verilator_toolchain 82 | 83 | # Get the depset correspond to all the Verilog source files 84 | srcs = ctx.attr.module[VerilogModuleInfo].files if ctx.attr.module else depset() 85 | 86 | # Merge with the files from srcs, hdrs, and deps, plus transitive dependencies 87 | # Code taken from https://github.com/bazelbuild/bazel/issues/5817#issuecomment-496910826 88 | # TODO: This call can be removed when srcs/hdrs/deps are removed 89 | srcs = depset(transitive = [ 90 | srcs, 91 | get_transitive_sources( 92 | srcs = ctx.files.srcs + ctx.files.hdrs, 93 | deps = ctx.attr.deps, 94 | ), 95 | ]) 96 | 97 | # Default Verilator output prefix (e.g. "Vtop") 98 | if ctx.attr.module: 99 | mtop = ctx.attr.module[VerilogModuleInfo].top 100 | else: 101 | mtop = ctx.label.name if not ctx.attr.mtop else ctx.attr.mtop 102 | prefix = ctx.attr.prefix + mtop 103 | 104 | # Output directories/files 105 | verilator_output = ctx.actions.declare_directory(ctx.label.name + "-gen") 106 | verilator_output_cpp = ctx.actions.declare_directory(ctx.label.name + ".cpp") 107 | verilator_output_hpp = ctx.actions.declare_directory(ctx.label.name + ".h") 108 | 109 | # Run Verilator 110 | args = ctx.actions.args() 111 | if ctx.attr.sysc: 112 | args.add("--sc") 113 | else: 114 | args.add("--cc") 115 | args.add("--Mdir", verilator_output.path) 116 | args.add("--prefix", prefix) 117 | args.add("--top-module", mtop) 118 | if ctx.attr.trace: 119 | args.add("--trace") 120 | args.add_all(srcs) 121 | args.add_all(ctx.attr.vopts, expand_directories = False) 122 | ctx.actions.run( 123 | arguments = [args], 124 | executable = verilator_toolchain.verilator_executable, 125 | inputs = srcs, 126 | outputs = [verilator_output], 127 | progress_message = "[Verilator] Compiling {}".format(ctx.label), 128 | ) 129 | 130 | # Extract out just C++ files 131 | # Work around for https://github.com/bazelbuild/bazel/pull/8269 132 | _copy_tree( 133 | ctx, 134 | verilator_output, 135 | verilator_output_cpp, 136 | map_each = _only_cpp, 137 | progress_message = "[Verilator] Extracting C++ source files", 138 | ) 139 | _copy_tree( 140 | ctx, 141 | verilator_output, 142 | verilator_output_hpp, 143 | map_each = _only_hpp, 144 | progress_message = "[Verilator] Extracting C++ header files", 145 | ) 146 | 147 | # Collect the verilator ouput and, if needed, generate a driver program 148 | srcs = [verilator_output_cpp] 149 | hdrs = [verilator_output_hpp] 150 | 151 | # Do actual compile 152 | defines = ["VM_TRACE"] if ctx.attr.trace else [] 153 | deps = list(verilator_toolchain.libs) 154 | #if ctx.attr.sysc: 155 | # deps.append(ctx.attr._systemc) 156 | return cc_compile_and_link_static_library( 157 | ctx, 158 | srcs = srcs, 159 | hdrs = hdrs, 160 | defines = defines, 161 | includes = [verilator_output_hpp.path], 162 | deps = deps, 163 | user_compile_flags=ctx.attr.user_compile_flags, 164 | user_link_flags=ctx.attr.user_link_flags, 165 | ) 166 | 167 | verilator_cc_library = rule( 168 | _verilator_cc_library, 169 | attrs = { 170 | "srcs": attr.label_list( 171 | doc = "[Deprecated] List of verilog source files", 172 | mandatory = False, 173 | allow_files = [".v", ".sv"], 174 | ), 175 | "hdrs": attr.label_list( 176 | doc = "[Deprecated] List of verilog header files", 177 | allow_files = [".v", ".sv", ".vh", ".svh"], 178 | ), 179 | "deps": attr.label_list( 180 | doc = "[Deprectated] List of verilog dependencies", 181 | ), 182 | "mtop": attr.string( 183 | doc = "[Deprecated] Top level module. Defaults to the rule name if not specified", 184 | mandatory = False, 185 | ), 186 | "module": attr.label( 187 | doc = "Label of verilog_module to verilate", 188 | providers = [VerilogModuleInfo], 189 | ), 190 | "trace": attr.bool( 191 | doc = "Enable tracing for Verilator", 192 | default = False, 193 | ), 194 | "prefix": attr.string( 195 | doc = "Prefix for generated C++ headers and classes", 196 | default = "V", 197 | ), 198 | "sysc": attr.bool( 199 | doc = "Generate SystemC using the --sc Verilator option", 200 | default = False, 201 | ), 202 | "vopts": attr.string_list( 203 | doc = "Additional command line options to pass to Verilator", 204 | default = ["-Wall"], 205 | ), 206 | "user_compile_flags": attr.string_list( 207 | doc = "Additional command line options to pass to C++ compiler", 208 | default = [], 209 | ), 210 | "user_link_flags": attr.string_list( 211 | doc = "Additional command line options to pass to Linker", 212 | default = [], 213 | ), 214 | "_cc_toolchain": attr.label( 215 | default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"), 216 | ), 217 | }, 218 | provides = [ 219 | CcInfo, 220 | DefaultInfo, 221 | ], 222 | toolchains = [ 223 | "@bazel_tools//tools/cpp:toolchain_type", 224 | "@rules_verilator//verilator:toolchain_type", 225 | ], 226 | fragments = ["cpp"], 227 | ) 228 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | --------------------------------------------------------------------------------