- 开发工具
- Lint
- 静态分析
- 硬件开发
【免费下载链接】verible
Verible is a suite of SystemVerilog developer tools, including a parser, style-linter, formatter and language server
verible-verilog-lint是 Verible 工具集(SystemVerilog 解析器、风格检查器、格式化器与语言服务器的统一套件)中的命令行风格检查工具,它基于完整的 SystemVerilog 词法器与解析器,对单个、未经预处理的源文件进行孤立分析,查找不符合所实现 lint 规则的代码模式。本文以 verible/verilog/tools/lint/README.md 为核心,结合 verilog-lint.cc、verilog-linter.cc、verilog-linter-configuration.cc 等源码实现,系统讲解该工具的完整命令行用法、规则开启/关闭与参数配置、诊断输出格式、内联与外置豁免机制,以及基于--autofix的自动修复与交互式修复流程。读完本文,你将能够把verible-verilog-lint直接接入自己的 SystemVerilog 项目,定制团队规则集,处理语法错误与豁免,并借助 AutoFix 一键清理琐碎违规。
工具定位:基于未预处理输入的孤立文件分析
风格检查器擅长发现可以用语法树或 token 匹配规则表达的代码模式,并且能够在匹配时引入句法上下文敏感性(例如区分某个标识符出现在模块端口声明还是 always 块内部)。由于它直接分析未经预处理的原始输入,因此具备两个独特优势:
- 可以检查注释内容(例如
endif-comment规则要求endif后附带对应注释); - 擅长检查未展开宏的使用(例如
forbidden-macro、macro-name-style等规则)。
与此同时,这也带来当前实现的明确限制(README 原文声明):
- 不做任何预处理条件分支的理解;
- 不做语义分析(如信号连通性),这类分析需要预处理、多文件分析以及完整的抽象语法树支持。
从调用链看,verilog-linter.cc 在分析前先通过VerilogAnalyzer::AnalyzeAutomaticPreprocessFallback读取文件内容并做词法/语法分析:先尝试无预处理直接解析以获取更多信息,若解析失败则自动过滤预处理分支再试——这个"自动回退"策略是--check_syntax、--parse_fatal等标志的前提。四类分析器(文本结构、行、token 流、语法树)由 VerilogLinter::Lint 依次驱动,任何一类规则产生的违规都会汇入最终诊断。
安装与快速上手
verible-verilog-lint二进制由 Bazel 构建,目标定义在 verible/verilog/tools/lint/BUILD:
bazel build //verible/verilog/tools/lint:verible-verilog-lint也可以直接使用预编译发布包中的同名可执行文件。工具支持一次传入多个文件(也支持用-从 stdin 读取),例如:
verible-verilog-lint foo.sv bar.svh cat foo.sv | verible-verilog-lint -命令行选项完整说明
运行verible-verilog-lint [options] <file> [<file>...]。完整选项如下(与 README 保持一致,并按来源分组):
通用 flag 解析(来自 Abseil flags 库)
| 选项 | 默认值 | 说明 |
|---|---|---|
--flagfile | 空 | 从逗号分隔的文件列表中加载 flags |
--fromenv | 空 | 从环境变量设置 flags(export FLAGS_flag1=value) |
--tryfromenv | 空 | 尝试从环境变量设置 flags(存在才生效) |
--undefok | 空 | 允许命令行上指定程序未定义的 flag 名 |
规则与配置(来自 verilog-linter.cc)
| 选项 | 默认值 | 说明 |
|---|---|---|
--rules | 空 | 逗号分隔的 lint 规则开关列表;无前缀或+前缀启用,-前缀禁用,规则参数放在=之后 |
--rules_config | "" | lint 规则配置文件路径;一旦设置将禁用--rules_config_search |
--rules_config_search | false | 从每个被分析文件的位置向上搜索名为.rules.verible_lint的配置文件 |
--ruleset | default | 规则基数集合,取值[default\|all\|none] |
--waiver_files | "" | 豁免配置文件路径(可逗号分隔多个),格式见下文"外部豁免文件" |
语法检查(来自 verilog 解析器)
| 选项 | 默认值 | 说明 |
|---|---|---|
--verilog_trace_parser | false | 追踪 verilog 解析器 |
工具行为(来自 verilog-lint.cc)
| 选项 | 默认值 | 说明 |
|---|---|---|
--autofix | no | 自动修复模式,取值[no\|patch-interactive\|patch\|inplace-interactive\|inplace\|generate-waiver] |
--autofix_output_file | "" | 写入补丁(patch/patch-interactive)或豁免文件(generate-waiver)的目标文件 |
--check_syntax | true | 是否检查词法与语法错误,false则忽略 |
--generate_markdown | false | 打印所有规则的 Markdown 格式描述后立即退出,用于生成文档片段 |
--help_rules | "" | 取值[all\|<rule-name>],打印某个规则或全部规则的描述后立即退出 |
--lint_fatal | true | 存在 lint 违规时以非零状态退出 |
--parse_fatal | true | 存在语法错误时以非零状态退出 |
--show_diagnostic_context | false | 在诊断行后额外打印一行源码上下文,并用^标记位置 |
此外,verilog-lint.cc 还定义了一个 README 中未列出的实用 flag:--print_rules_file,它会将当前启用的规则集合以可写入.rules.verible_lint配置文件的格式打印到 stdout 后立即退出,非常适合用于生成项目初始配置文件。
README 特别建议:每个项目都应维护自己的配置文件,以保证团队成员间的一致性。退出码语义可参考 verilog-linter.cc 与 verilog-lint.cc:0表示成功;1表示解析/语法错误或 lint 违规(受parse_fatal/lint_fatal控制);2表示文件无法读取等致命问题;3表示 autofix 输出文件无法打开(如--autofix=patch时指定了不可写的输出路径,lint_tool_test.sh 中有对应集成测试)。
诊断输出格式
语法错误与 lint 规则发现统一采用以下格式:
FILE:LINE:COL: text...官方示例:
path/to/missing-endmodule.sv:3:1: syntax error (unexpected EOF). path/to/number-as-statement.sv:2:3: syntax error, rejected "123". path/to/bad-dimensions.sv:114:43: Packed dimension range must be in decreasing order. http://your.style/guide.html#packed-ordering [packed-dimensions-range-ordering]要点:
- 每条 lint 诊断末尾方括号
[...]中的内容就是触发的规则名,这也是编写豁免时引用规则名的依据; - 诊断消息中常附注风格指南出处(每个规则的
.topic会通过 citation.cc 映射到官方风格指南章节); - 开启
--show_diagnostic_context后,会在诊断下方额外打印一行源码并用^定位,lint_tool_test.sh 验证了带/不带该 flag 的输出差异; - 语法错误(syntax error)无法被豁免,必须修复源码或改用替代解析模式(见下文)。
Lint 规则:查看、默认集合与文档生成
查看规则描述
规则的用户文档是动态生成的,你随时可以在本地查看:
# 查看某个规则 verible-verilog-lint --help_rules=no-tabs # 查看全部规则 verible-verilog-lint --help_rules=all # 生成 Markdown 文档片段 verible-verilog-lint --generate_markdown输出格式由 PrintRuleInfo 与 GetLintRuleDescriptionsMarkdown 生成:包含规则描述、参数名与默认值,以及该规则是否默认启用。例如line-length规则(line-length-rule.cc)描述为"检查所有行不超过最大允许长度",参数为length(默认值来自kDefaultLineLength);enum-name-style规则(enum-name-style-rule.cc)参数为style_regex(默认[a-z_0-9]+(_t|_e))。
README 还提供了 Bazel 文档生成目标:
# 生成文档 bazel build :lint_doc # 生成产物位于 bazel-bin/documentation_verible_lint_rules.md默认启用规则集合
--ruleset的三种取值定义在 verilog-linter-configuration.cc:
default:启用 default-rules.h 中列出的生产级规则,包括no-trailing-spaces、no-tabs、posix-eof、line-length、undersized-binary-literal、always-comb、always-comb-blocking、always-ff-non-blocking、enum-name-style、suggest-parentheses、forbid-consecutive-null-statements、case-missing-default、module-filename、package-filename、packed-dimensions-range-ordering、forbid-defparam、typedef-enums等数十条规则(文件中还标注了若干暂未默认启用、留待 TODO 的规则);all:启用全部已注册规则(含文本结构、语法树、token 流、行四类规则);none:不启用任何规则,仅做语法检查。
注意--rules是在 ruleset 基础之上的增量覆盖:先应用 ruleset,再应用--rules或配置文件中的条目。
规则配置:--rules语法详解
--rules接受逗号分隔的规则列表(规则名见规则文档),前缀语义如下:
-(减号)前缀:禁用该规则;- 无前缀或
+(加号)前缀:启用该规则; - 可选的配置参数以
=赋值跟在规则名之后。
带参数的规则配置形式如下:
--rules=[+-]rule-name="<param>:<paramvalue>;<param2>:<value>",[+-]next-rule...示例一:启用、配置与禁用
下面命令启用了enum-name-style规则,启用并配置line-length规则为 80 字符,同时禁用no-tabs规则:
verible-verilog-lint --rules=enum-name-style,+line-length=length:80,-no-tabs ...示例二:多参数规则
部分规则有多个参数,参数之间用分号分隔。由于常见 shell 会把分号当作特殊字符,必须用引号包裹参数:
verible-verilog-lint --rules="undersized-binary-literal=hex:true;lint_zero:true" ...undersized-binary-literal的全部参数定义在 undersized-binary-literal-rule.cc:bin(默认true,检查二进制字面量)、oct(默认false)、hex(默认false)、lint_zero(默认false,对32'h0这类零值也告警)、autofix(默认true,提供自动修复建议)。
配置文件:--rules_config与.rules.verible_lint
--rules_config读取的配置文件语法与命令行相同,区别在于规则之间还可以用换行符分隔,并且以#开头的行会被当作注释忽略(ParseConfiguration 中对换行分隔符的处理)。README 建议每个项目维护自己的配置文件以保持一致性。
配置文件示例:
# 项目风格规则 line-length=length:100 enum-name-style -no-tabs undersized-binary-literal=hex:true;lint_zero:true此外:
- 配置解析时会容忍末尾多余逗号并给出警告,遇到未注册的规则名会记录错误但继续解析(见 ParseConfiguration);
--rules_config_search开启后,会从每个被分析文件所在目录向上搜索.rules.verible_lint,ConfigureFromOptions 中通过UpwardFileSearch实现;一旦显式给出--rules_config,搜索自动关闭;- 配置叠加顺序为:先应用 ruleset,再应用配置文件,最后应用
--rules命令行条目,因此命令行可以覆盖配置文件中的同名规则; - 配合
--print_rules_file可以快速导出当前生效配置,作为团队配置文件的起点。
正则表达式配置
部分规则允许用户用正则表达式配置规则。Verible 使用RE2正则表达式库(并非 PCRE,注意语法差异)。例如:
verible-verilog-lint --rules="enum-name-style=style_regex:[a-z_0-9]+(_t|_e)" ...对命名风格类规则,正则可以保持简单,无需担心开头是数字——词法器/解析器已经处理了这一点。下表是常见的命名风格正则模式(来自 README 原文):
| 命名风格 | 正则表达式 |
|---|---|
| lower_snake_case | [a-z_0-9]+ |
| UPPER_SNAKE_CASE | [A-Z_0-9]+ |
| Title_Snake_Case | [A-Z]+[a-z0-9]*(_[A-Z0-9]+[a-z0-9]*)* |
| Sentence_snake_case | ([A-Z0-9]+[a-z0-9]*_?)([a-z0-9]*_*)* |
| camelCase | ([a-z0-9]+[A-Z0-9]*)+ |
| PascalCase | ([A-Z0-9]+[a-z0-9]*)+ |
规则内部通过re2::RE2编译并做全匹配(如 enum-name-style-rule.cc 用RE2::FullMatch校验标识符),从源码结构可以推断:自定义正则若含非法 RE2 语法,规则配置阶段会直接报错。
豁免 Lint 违规(Waiving)
内联豁免注释
在极少数情况下,某一行需要豁免某个具体规则,可使用如下豁免注释(README 原文示例,涵盖全部四种形态):
// This example waives the line after the waiver. // verilog_lint: waive rule-name The next non-comment line like this one is waived. // This example waives the same line as the waiver. This line is waived. // verilog_lint: waive rule-name // This example shows accumulation of waivers over multiple lines. // verilog_lint: waive rule-name-1 // verilog_lint: waive rule-name-2 // Other comments, possibly waivers for other tools. This line will be waived for both rule-name-1 and rule-name-2. // This example shows how to waive an entire range of lines. // verilog_lint: waive-start rule-X ... All lines in between will be waived for rule-X ... // verilog_lint: waive-stop rule-X语义细节(与 lint-waiver.h 中 verilog-linter-constants.h 定义的关键字verilog_lint:、waive、waive-start、waive-stop对应):
- 独立成行的豁免注释,作用于其后的下一行非注释代码;
- 与代码同行的豁免注释,仅豁免本行;
- 多条豁免注释可累积,同时豁免多个规则;
waive-start/waive-stop成对使用,豁免两者之间的整段行范围;- 豁免在 VerilogLinter::Configure 与 AppendLintRuleStatuses 中生效:先扫描收集豁免行集合,再在报告阶段按违规 token 所在行查豁免集合过滤。
外部豁免文件
如果你倾向于在源码之外管理豁免(尤其当多个 linter 并存时,内联指令可能污染源码),可使用豁免文件。--waiver_files接受单个文件或逗号分隔的多个文件;指定多个文件等价于按出现顺序拼接。默认规则应用于所有文件,但可用--location限定只对文件名匹配 location 正则的文件生效。
文件格式如下:
waive --rule=rule-name-1 --line=10 waive --rule=rule-name-2 --line=5:10 waive --rule=rule-name-3 --regex="^\s*abc$" waive --rule=rule-name-4 --line=42 --location=".*some_file.*"--line:指定单行或行范围(用:分隔,如5:10);--regex:动态匹配需要豁免该规则的行,尤其适合项目中自动生成的文件;- 要豁免的规则名位于每条诊断消息末尾的
[]中; - 解析与校验逻辑见 lint-waiver.cc 的
ApplyExternalWaivers,其单元测试覆盖了非法行号、非法正则、--line与--regex冲突、未知规则名、引号包裹等多种异常情况(lint-waiver_test.cc)。
自动生成豁免
豁免规则可以用 AutoFix 模式generate-waiver自动生成,输出到 stdout,或在--autofix_output_file指定路径时写入文件:
verible-verilog-lint --autofix=generate-waiver --autofix_output_file=violations.waiver ...生成的豁免规则格式:
waive --rule=<rule_name> --line=<number> --location=<file_name>从 lint-rule-status.cc 可以看到,生成条目由诊断的违规行范围与文件名构成,可直接作为后续--waiver_files的输入,形成"先豁免、再逐个修复"的渐进式清理工作流。
语法错误与替代解析模式
语法错误无法豁免。语法错误的常见来源是:文件不是LRM 定义意义上的独立 Verilog 程序——例如只是一个 module、class、task、function 的主体片段。此时可以让解析器按片段处理,在文件顶部附近放置类似注释的解析指令:
// verilog_syntax: parse-as-module-body该指令由 verilog-excerpt-parse.cc 识别,可用模式包括(详见 analysis/README.md):
parse-as-statements:文本只包含语句(如 function、always 内部);parse-as-expression:文本出现在表达式内部;parse-as-module-body:文本出现在模块定义内部;parse-as-class-body:文本出现在类定义内部;parse-as-package-body:文本出现在包定义内部;parse-as-library-map:Verilog 库映射子语言(LRM 第 33 章)。
注意:指令扫描会在遇到第一个非预处理控制 token时停止(ifndef之后或注释之后没问题,但遇到module之类关键字后不再生效)。工具集(风格检查器与格式化器)都理解这类指令。仓库的 BUILD 中generate-label-module-body、instance-ports-module-body等测试用例正是依赖该指令实现片段解析的。
自动修复琐碎违规(AutoFix)
部分琐碎违规(如行尾空格、连续多余分号)可以自动修复。--autofix标志控制修复的呈现或应用方式,六种取值如下(README 表格原文):
--autofix取值 | 说明 |
|---|---|
no | 不显示也不应用任何修复 |
patch-interactive | 交互式选择修复,并以 unified diff 写入--autofix_output_file |
inplace-interactive | 交互式选择修复,直接就地修改原文件(修改输入) |
patch | 将所有可用修复写成 unified diff |
inplace | 将所有可用修复直接应用到原文件(修改输入) |
generate-waiver | 为每个违规生成一条豁免规则,作为临时修复 |
若未指定--autofix_output_file,patch与generate-waiver的输出会写到 stdout。源码层面,六种模式在 verilog-lint.cc 中通过AutofixMode枚举与 ViolationHandler 的不同子类(ViolationPrinter、ViolationFixer、ViolationWaiverPrinter)实现:no模式仅打印;patch/patch-interactive/generate-waiver需要可写输出流,否则以退出码 3 报错;inplace系列则就地修改。
交互式修复按键
交互式模式(patch-interactive与inplace-interactive)为每个修复提供以下动作:
y- 应用修复n- 拒绝修复a- 应用此修复及本规则剩余全部修复d- 拒绝此修复及本规则剩余全部修复A- 应用此修复及剩余全部修复D- 拒绝此修复及剩余全部修复p- 显示修复P- 显示目前已应用的修复?- 打印本帮助并重新提示
当某个违规存在多个修复备选时(例如undersized-binary-literal既有"左侧补零"也有"转为十进制"两种方案),提示符会变为数字选项,如[1,2,y,n,a,d,A,D,p,P,?]。
交互式修复会话示例
以下是一次--autofix=inplace-interactive的完整会话(README 原文示例,含多选修复):
$ verible-verilog-lint --rules="undersized-binary-literal=hex:true" --autofix=inplace-interactive autofixtest.sv autofixtest.sv:2:30: Parenthesize condition expressions that appear in the true-clause of another condition expression. [Style: parentheses] [suggest-parentheses] [ Add parenthesis for readability ] @@ -1,3 +1,3 @@ module foo(); - assign foo = condition_a? condition_b ? condition_c ? a : b : c : d; + assign foo = condition_a? (condition_b ? condition_c ? a : b : c) : d; assign c = 32'h1; Autofix is available. Apply? [y,n,a,d,A,D,p,P,?] y autofixtest.sv:2:44: Parenthesize condition expressions that appear in the true-clause of another condition expression. [Style: parentheses] [suggest-parentheses] [ Add parenthesis for readability ] @@ -1,3 +1,3 @@ module foo(); - assign foo = condition_a? condition_b ? condition_c ? a : b : c : d; + assign foo = condition_a? condition_b ? (condition_c ? a : b) : c : d; assign c = 32'h1; Autofix is available. Apply? [y,n,a,d,A,D,p,P,?] y autofixtest.sv:3:19: Hex literal 32'h1 has less digits than expected for 32 bits. [Style: number-literals] [undersized-binary-literal] [ 1. Alternative Left-expand leading zeroes ] @@ -2,3 +2,3 @@ assign foo = condition_a? condition_b ? condition_c ? a : b : c : d; - assign c = 32'h1; + assign c = 32'h00000001; endmodule [ 2. Alternative Replace with decimal ] @@ -2,3 +2,3 @@ assign foo = condition_a? condition_b ? condition_c ? a : b : c : d; - assign c = 32'h1; + assign c = 32'd1; endmodule Autofix is available. Apply? [1,2,y,n,a,d,A,D,p,P,?] 1可以看到:suggest-parentheses连续为同一行嵌套条件表达式提出两处加括号修复;undersized-binary-literal为32'h1提供补零与十进制两种备选,用户输入1选择第一种。
非交互式批量修复
CI 或提交前检查场景更常用非交互模式:
# 生成补丁(不改动源文件) verible-verilog-lint --rules="no-trailing-spaces;forbid-consecutive-null-statements" \ --autofix=patch --autofix_output_file=fix.patch foo.sv # 就地直接修复 verible-verilog-lint --autofix=inplace foo.sv端到端测试 lint_tool_test.sh 覆盖了--autofix=inplace、patch、inplace-interactive、generate-waiver的完整行为,包括:多文件就地修复、patch 模式不修改源文件且输出可被系统patch工具应用、交互模式中A/D/y/n/a/d/p/P各种按键组合、输出文件不可写时退出码为 3 等,可作为理解 AutoFix 行为的权威参考。
将 Linter 集成进项目与 CI
为仓库固化规则集
推荐做法是在仓库根目录放置.rules.verible_lint,团队成员与 CI 均以--rules_config_search运行,即可自动从被检查文件向上找到该配置:
verible-verilog-lint --rules_config_search .所有相关工具也会遵循同一配置文件,保证一致体验。
Bazel 风格 lint 测试
仓库提供了可直接复用的 Bazel 规则verilog_style_lint(定义于 verilog_style_lint.bzl),支持两种用法:
load("//verible/verilog/tools:verilog_style_lint.bzl", "verilog_style_lint") # 扫描当前包及子包中的 .v/.sv/.vh/.svh 文件 verilog_style_lint.package_test( name = "default_style_lint_test", subpackages = ["sub/dir1", "sub/dir2", ...], ) # 或手动列出要扫描的文件 verilog_style_lint.test( name = "style_lint_test", srcs = [...], )verilog_style_lint.test内部以--noparse_fatal --nolint_fatal生成完整报告再判断空/非空(expect_fail可反转预期),并默认追加--norules_config_search保证测试隔离。该宏的等价命令行形式即:
verible-verilog-lint --noparse_fatal --nolint_fatal <files...> > report.txt自动化代码评审
对于 GitHub 上的自动代码评审,官方提供了易于集成的 GitHub Action(见 lint/README.md 中的链接说明),可将 lint 诊断直接以 review 评论形式呈现。在本地或 CI 中,最简单的接入方式是:
# 语法与风格同时把关,违规即失败 verible-verilog-lint --rules_config_search --lint_fatal --parse_fatal .规则开发入门(开发者视角)
如果你想为团队实现自定义 lint 规则,官方开发者指南位于 doc/style_lint.md。其要点可归纳为四条路径(对应 common/analysis 下的四类规则基类):
- 行级规则(
LineLintRule):逐行分析文本,例如 no-trailing-spaces-rule、no-tabs-rule; - Token 流规则(
TokenStreamLintRule):逐个 token 扫描,例如 endif-comment-rule、macro-name-style-rule; - 语法树规则(
SyntaxTreeLintRule):分析语法树节点与叶子,绝大多数 SystemVerilog lint 规则属于此类,实现于 checkers 目录,可用 CST 直接访问、SearchSyntaxTree搜索或 CST Matcher 模式匹配(受 Clang ASTMatcher 启发,支持AllOf/AnyOf/Unless组合与.Bind()符号绑定); - 文本结构规则(
TextStructureLintRule):以任意方式分析整个 TextStructureView,适合需要同时访问行、token、语法树中多种形态的规则,如 module-filename-rule、line-length-rule、posix-eof-rule。
规则通过VERILOG_REGISTER_LINT_RULE(...)宏在库加载时注册(见 lint-rule-registry.h),注册后即可被--rules按名引用。每个规则的单元测试遵循RunLintTestCases<VerilogAnalyzer, LintRuleName>模板,用带标记的字符串字面量精确断言违规位置(见 style_lint.md)。lint 工具自身的集成测试配置(规则名、测试数据文件、是否默认启用)集中在 BUILD 的_linter_test_configs中。
小结
verible-verilog-lint是一个直接构建在完整 SystemVerilog 词法器与解析器之上的风格检查工具:--ruleset决定基线规则集,--rules/--rules_config/.rules.verible_lint负责精细化启停与参数配置,内联verilog_lint:注释与外部 waiver 文件双通道处理豁免,--autofix六种模式覆盖从"只生成补丁"到"交互式就地修复"乃至"自动生成豁免"的完整清理流程,而parse-as-*指令则让代码片段也能被正确分析。建议每个项目维护自己的规则配置文件,并将 lint 检查接入 CI——配合 Verible 的格式化器与语言服务器,即可为团队建立起一套完整的 SystemVerilog 代码质量防线。
- 开发工具
- Lint
- 静态分析
- 硬件开发
【免费下载链接】verible
Verible is a suite of SystemVerilog developer tools, including a parser, style-linter, formatter and language server
相关推荐
Verible Style Linter 规则体系解析:checkers 目录的注册机制、规则分类与配置实战
Verible Style Linter 规则体系解析:checkers 目录的注册机制、规则分类与配置实战 Verible 是一套面向 SystemVeril
开发工具Lint静态分析硬件开发Verible项目中的SystemVerilog代码风格检查规则开发指南
Verible项目中的SystemVerilog代码风格检查规则开发指南 前言 Verible是一个开源的SystemVerilog语言工具集,其中的代码风格检
开发工具Lint静态分析硬件开发Verible项目中的SystemVerilog代码风格检查规则开发指南
Verible项目中的SystemVerilog代码风格检查规则开发指南 前言 在数字电路设计领域,SystemVerilog作为主流的硬件描述语言,其代码质量
开发工具Lint静态分析硬件开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考