bb-code-review

SkillDev tools

Adversarial code review: code quality / maintainability / timing risks / overall friendliness / MAS alignment. Defaults to ruthless mode, finding EVERY flaw. Trigger scenarios: (1) after RTL lint; (2) explicit /bb-code-review.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the bb-code-review skill

What this skill tells your AI

The instructions your AI receives, as published by amoslee2026/babel in .claude/skills/bb-code-review/SKILL.md and read by ahel’s review.

职责

读 RTL + MAS,对照设计意图做对抗评审,分维度给出 issues + severity + pass 判定。

  • 调用者:bb-rtl-coder、用户
  • 前置:bb-check-lint(lint 通过后)
  • 禁止使用:Task / Agent / Skill

Input Args

argtyperequired默认说明
rtl_dirpathtruedesigns/<name>/rtl/
file_listpathtruefile_list.f
mas_pathpathtruedesigns/<name>/mas/mas.json
roleenumfalseruthlessruthless | linus | balanced
focusstringfalsetiming,maintainability关注领域
design_namestringtrue
stampstringfalse<auto>

Output Contract

field
artifact_pathdesigns/<name>/rtl/code_review_<stamp>.md
issues_foundint
severity_summary{critical,high,medium,low}
timing_riskslist[str]
maintainability_issueslist[str]
synthesis_friendlybool
mas_alignmentfull | partial | none
passbool(critical==0 && high≤1)
validbool

角色

角色风格适用
ruthless无赞美只挑刺,找 EVERY flaw默认,重大改动前压力测试
linus直接尖锐,技术导向风格/架构决策
balanced承认优点+建议常规评审

4-Phase 执行

Phase 1 — build_review_prompt

$PROJECT_SCRIPTS/build_prompt.py

ROLE_PROMPTS = {
  "ruthless": "Ruthless reviewer. Find EVERY flaw. No compliments.",
  "linus":    "Linus Torvalds. Direct, no-nonsense, technically harsh.",
  "balanced": "Senior engineer. Constructive, acknowledge strengths.",
}

mas = json.load(open(mas_path))
rtl = {f: open(f).read() for f in cat(file_list)}
prompt = render_prompt(
    role=role,
    rtl=rtl,
    mas=mas,
    dimensions=["timing","maintainability","synthesis","mas_alignment"]
)

Phase 2 — run_review

claude --print "<prompt>" > <artifact_path> 或 agent 内部生成。

Phase 3 — parse_review

$PROJECT_SCRIPTS/parse_review.py

  • 提取 dimensions 段(## Timing Risks / ## Maintainability 等)
  • 计数 severity 标签 [CRITICAL] / [HIGH] / [MEDIUM] / [LOW]
  • pass = (critical == 0 && high <= 1)

Phase 4 — return

返回 JSON。pass=false → bb-rtl-coder 反馈重生成(≤3 iter)。

维度

维度检查
timing_risks长组合路径 / 无 pipeline / CDC 未处理
maintainability深嵌套 / 大模块 / 命名
synthesis_friendly非综合语法 / blackbox
mas_alignmentRTL ↔ MAS FSM/datapath 一致性
traceabilityREQ_ID 覆盖率 / 孤儿代码 / @requirement 注释完整性
spec_headerSpec Header 完整性 / @spec_hash 一致性 / Key Constraints 覆盖
selective_inline选择性内联合规(FSM/协议/datapath 必须标注,简单赋值不标注)
register_map寄存器定义 → 文档 + SVA 断言完整性
sdc_traceabilitySDC 约束 → REQ_ID 关联完整性

Traceability 检查

REQ_ID 覆盖率

扫描 RTL 文件中的 @requirement 注释,与 MAS §10 追踪矩阵对比:

def check_traceability(rtl_files, mas_path):
    """检查 @requirement 注释覆盖率"""
    # 1. 从 MAS §10 提取声明的 REQ_ID 列表
    declared = extract_req_ids_from_mas(mas_path)

    # 2. 从 RTL 扫描 @requirement 注释中的 REQ_ID
    implemented = set()
    for f in rtl_files:
        for line in open(f):
            if "@requirement" in line:
                implemented |= extract_req_ids(line)

    # 3. 计算覆盖率
    coverage = len(declared & implemented) / len(declared) * 100
    missing = declared - implemented
    orphans = implemented - declared  # 实现了但 MAS 未声明

    return {
        "coverage_pct": coverage,
        "missing_reqs": sorted(missing),
        "orphan_reqs": sorted(orphans),
    }

孤儿检测

@requirement 注释的代码块(排除 traceability/ignore.txt 白名单):

uv run $PROJECT_SCRIPTS/check_req_uniqueness.py

SVA @verifies 覆盖率

检查 RTL 中的 SVA 断言是否都包含 @verifies 标注:

def check_sva_verifies(rtl_files):
    """检查 SVA 断言的 @verifies 标注覆盖率"""
    sva_count = 0        # assert property 总数
    sva_with_verifies = 0  # 有 @verifies 的 assert property

    for f in rtl_files:
        lines = open(f).readlines()
        for i, line in enumerate(lines):
            if "assert property" in line or "assert(" in line:
                sva_count += 1
                # 检查前 3 行是否有 @verifies
                context = "".join(lines[max(0,i-3):i+1])
                if "@verifies" in context:
                    sva_with_verifies += 1

    coverage = (sva_with_verifies / sva_count * 100) if sva_count > 0 else 100
    return {
        "sva_total": sva_count,
        "sva_with_verifies": sva_with_verifies,
        "coverage_pct": coverage,
    }

输出格式

在评审报告中增加章节:

## Traceability

- REQ_ID 覆盖率: 95% (19/20)
- SVA @verifies 覆盖率: 100% (15/15)
- 缺失 REQ_ID: REQ-M01-F05
- 孤儿代码: M99_Top.sv (无 @requirement)
- NEEDS_REVIEW: 无

通过标准追加

标准要求
traceability 覆盖率≥ 90%
SVA @verifies 覆盖率== 100%
孤儿 REQ_ID== 0
Spec Header 完整性== 100%(每个模块必须有 Spec Header)
@spec_hash 一致性== 100%(所有 Spec Hash 必须与 spec 文件匹配)
寄存器文档生成== 100%(每个有寄存器的模块必须有 regmap 文档)
SDC traceability≥ 90%(SDC 约束必须有 @requirement 标注)

Spec Header 检查

完整性检查

每个 RTL 文件头部必须包含 Spec Header,包含以下字段:

def check_spec_header(rtl_files):
    """检查 Spec Header 完整性"""
    required_fields = [
        "Module:", "Source:", "Version:", "Status:",
        "Spec Hash:", "REQ Coverage:", "Purpose:",
        "Key Constraints:", "Dependencies:", "Traceability:"
    ]

    results = []
    for f in rtl_files:
        content = open(f).read()

        # 检查是否包含所有必需字段
        missing = [field for field in required_fields if field not in content]

        if missing:
            results.append({
                "file": f,
                "status": "FAIL",
                "missing_fields": missing
            })
        else:
            results.append({
                "file": f,
                "status": "PASS"
            })

    return results

@spec_hash 一致性检查

def check_spec_hash_consistency(rtl_files):
    """验证 RTL 中的 @spec_hash 与 spec 文件是否一致"""
    import subprocess, re

    results = []
    for f in rtl_files:
        content = open(f).read()

        # 提取 Source 和 Spec Hash
        source_match = re.search(r'// Source:\s*(\S+)', content)
        hash_match = re.search(r'// Spec Hash:\s*(sha256:[a-f0-9]+)', content)

        if not source_match or not hash_match:
            continue  # 无 Spec Header,跳过

        spec_file = source_match.group(1)
        rtl_hash = hash_match.group(1)

        # 计算 spec 文件实际 hash
        result = subprocess.run(
            ["uv", "run", "$PROJECT_SCRIPTS/compute_spec_hash.py", spec_file],
            capture_output=True, text=True
        )
        actual_hash = result.stdout.strip()

        if rtl_hash != actual_hash:
            results.append({
                "file": f,
                "status": "FAIL",
                "rtl_hash": rtl_hash,
                "spec_hash": actual_hash,
                "fix": f"uv run $PROJECT_SCRIPTS/compute_spec_hash.py {spec_file} --inject {f}"
            })
        else:
            results.append({
                "file": f,
                "status": "PASS"
            })

    return results

输出格式

在评审报告中增加章节:

## Spec Header

- 完整性: 100% (8/8 模块)
- @spec_hash 一致性: 87.5% (7/8)
- 不一致文件:
  - M01_DataflowController.sv: RTL=sha256:abc123, spec=sha256:def456
    Fix: `uv run $PROJECT_SCRIPTS/compute_spec_hash.py spec/MAS/M01/MAS.md --inject rtl/M01.sv`

选择性内联检查

合规检查

验证 RTL 文件遵循选择性内联标准:

def check_selective_inline(rtl_files):
    """检查选择性内联合规性"""

    # 必须标注的代码块类型
    must_annotate = [
        r'always_ff.*case\s*\(',  # FSM
        r'valid\s*\|->',          # 协议握手 (SVA)
        r'always_ff.*posedge.*\b(stage|pipe)',  # pipeline stages
    ]

    # 不应标注的代码块类型
    should_not_annotate = [
        r'^\s*assign\s+\w+\s*=',  # 简单 assign
        r'^\s*parameter\s+',      # 参数定义
        r'^\s*localparam\s+',     # 本地参数
    ]

    results = []
    for f in rtl_files:
        lines = open(f).readlines()

        for i, line in enumerate(lines):
            # 检查必须标注的代码块是否有 @requirement
            for pattern in must_annotate:
                if re.search(pattern, line):
                    # 检查前 3 行是否有 @requirement
                    context = "".join(lines[max(0,i-3):i+1])
                    if "@requirement" not in context and "@verifies" not in context:
                        results.append({
                            "file": f,
                            "line": i+1,
                            "status": "MISSING",
                            "type": "must_annotate",
                            "code": line.strip()
                        })

    return results

寄存器 Traceability 检查

检查项

def check_register_traceability(design_name):
    """检查寄存器定义 → 文档 → SVA 断言完整性"""

    mas_path = f"spec/MAS/{design_name}/MAS.md"
    regmap_doc = f"doc/regmap/{design_name}.md"
    regmap_sva = f"rtl/designs/{design_name}/rtl_src/{design_name}_regmap_assertions.sv"

    # 1. 检查 MAS 中是否有寄存器定义
    mas_content = open(mas_path).read()
    has_reg_def = "## 5. 寄存器映射" in mas_content or "## 6. 寄存器定义" in mas_content

    if not has_reg_def:
        return {"status": "SKIP", "reason": "No register definition in MAS"}

    # 2. 检查是否生成了寄存器文档
    has_doc = os.path.exists(regmap_doc)

    # 3. 检查是否生成了寄存器断言
    has_sva = os.path.exists(regmap_sva)

    # 4. 检查断言中的 @verifies 覆盖率
    if has_sva:
        sva_content = open(regmap_sva).read()
        assert_count = sva_content.count("assert property")
        verifies_count = sva_content.count("@verifies")
        verifies_coverage = (verifies_count / assert_count * 100) if assert_count > 0 else 100
    else:
        verifies_coverage = 0

    return {
        "status": "PASS" if (has_doc and has_sva and verifies_coverage == 100) else "FAIL",
        "has_reg_def": has_reg_def,
        "has_doc": has_doc,
        "has_sva": has_sva,
        "verifies_coverage": verifies_coverage
    }

SDC Traceability 检查

检查项

def check_sdc_traceability(design_name):
    """检查 SDC 约束 → REQ_ID 关联完整性"""

    sdc_path = f"designs/{design_name}/constraints/{design_name}.sdc"

    if not os.path.exists(sdc_path):
        return {"status": "SKIP", "reason": "No SDC file"}

    sdc_content = open(sdc_path).read()
    lines = sdc_content.splitlines()

    # 统计 SDC 命令数量
    sdc_commands = [
        "create_clock", "set_input_delay", "set_output_delay",
        "set_false_path", "set_multicycle_path", "set_clock_groups"
    ]

    total_commands = 0
    annotated_commands = 0

    for i, line in enumerate(lines):
        for cmd in sdc_commands:
            if cmd in line:
                total_commands += 1
                # 检查前 5 行是否有 @requirement
                context = "\n".join(lines[max(0,i-5):i+1])
                if "@requirement" in context:
                    annotated_commands += 1

    coverage = (annotated_commands / total_commands * 100) if total_commands > 0 else 100

    return {
        "status": "PASS" if coverage >= 90 else "FAIL",
        "total_commands": total_commands,
        "annotated_commands": annotated_commands,
        "coverage_pct": coverage
    }

输出格式

## SDC Traceability

- SDC 命令总数: 12
- 已标注 @requirement: 11
- 覆盖率: 91.7%
- 未标注:
  - Line 45: set_false_path -from [get_pins ...]

通过标准

级别通过
critical== 0
high≤ 1

收敛 / 失败

状态行动
pass=true写 rtl_artifact.json + 进下一阶段
pass=false & iter<3反馈 bb-rtl-coder 重生成
iter≥3arch-needs-fix

Global Paths

PROJECT_SCRIPTS   = {{ PROJECT_DIR }}/scripts

资源索引

  • $PROJECT_SCRIPTS/build_prompt.py$PROJECT_SCRIPTS/run_review.py$PROJECT_SCRIPTS/parse_review.py
  • references/rtl_review_dimensions.md
  • references/role_personas.md — 三角色详细提示词

项目级 Coding Style 参考

  • wiki/codingstyle/systemverilog_styleguide.md — SystemVerilog Style Guide (systemverilog.io)
  • wiki/codingstyle/freescale_verilog_standard.md — Freescale Verilog HDL Coding Standard SRS V3.2

Signals

GitHub stars
42
Forks
10
Last commit
Aug 2026
Advanced
Catalog kind
skill
Gateway key
bb-code-review
Source
github.com/amoslee2026/babel