blob: 672e5052dc4f73ebd61bb56b69c126bd6d75e2d5 [file] [log] [blame]
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""VCStatic lint rules."""
load("@rules_hdl//verilog:providers.bzl", "VerilogInfo")
def _collect_verilog_files(dep):
transitive_srcs = depset([], transitive = [dep[VerilogInfo].dag])
all_srcs = [verilog_info_struct.srcs
for verilog_info_struct in transitive_srcs.to_list()]
all_files = [src for sub_tuple in all_srcs for src in sub_tuple]
return all_files
def _vcstatic_lint_impl(ctx):
# Create f file
f_file = ctx.actions.declare_file(ctx.attr.name + "_files.f")
verilog_files = _collect_verilog_files(ctx.attr.package)
f_file_content = ["+define+SIMULATION"]
for f in verilog_files:
f_file_content = f_file_content + [f.path]
f_file_content = "\n".join(f_file_content) + "\n"
ctx.actions.write(f_file, f_file_content)
# Generate the lint script from template
vc_static_script = ctx.actions.declare_file(
ctx.attr.name + "_vc_shell.prj")
report_violations = ctx.actions.declare_file(ctx.attr.name + "_lint.rpt")
ctx.actions.expand_template(
template=ctx.attr._lint_script.files.to_list()[0],
output=vc_static_script,
substitutions={
"{F_FILE}": f_file.path,
"{MODULE_TO_LINT}": ctx.attr.module,
"{REPORT_VIOLATIONS_FILE}": report_violations.path,
"{BLACKBOX_DESIGNS}": " ".join(ctx.attr.blackbox_designs),
"{BLACKBOX_FILES}": " ".join(ctx.attr.blackbox_files),
"{GOAL}": ctx.attr.goal,
"{LINT_TAGS}": " ".join(ctx.attr.lint_tags),
"{WAIVE_TAGS}": " ".join(ctx.attr.waive_tags),
},
)
# Run lint
command = [
"vc_static_shell",
"-file",
vc_static_script.path,
]
ctx.actions.run_shell(
outputs=[report_violations],
inputs=[vc_static_script, f_file] + verilog_files,
command = " ".join(command),
use_default_shell_env = True,
)
return [DefaultInfo(files=depset([report_violations]))]
_vcstatic_lint = rule(
_vcstatic_lint_impl,
attrs = {
"package": attr.label(
doc = "The verilog target to create a test bench for.",
providers = [VerilogInfo],
mandatory = True,
),
"module": attr.string(
doc = "The name of the verilog module to lint.",
mandatory = True,
),
"blackbox_designs": attr.string_list(
doc = "Verilog designs to mark as blackboxes.",
allow_empty = True,
),
"blackbox_files": attr.string_list(
doc = "Verilog files to mark as blackboxes.",
allow_empty = True,
),
"goal": attr.string(
doc = "Lint goal to execute.",
default = "lint_rtl_check",
),
"lint_tags": attr.string_list(
doc = "Additional lint tags to enable.",
allow_empty = True,
),
"waive_tags": attr.string_list(
doc = "Lint tags to waive.",
allow_empty = True,
),
"_lint_script": attr.label(
doc = "Template file to use to generate vc_static script",
allow_files = True,
default = Label("//rules/lint:vc_shell.prj.tpl"),
),
},
)
def vcstatic_lint(name, tags=[], **kwargs):
_vcstatic_lint(name = name, tags = ["vcs"] + tags, **kwargs)