揭秘 DC_SHELL 核心引擎:RTL Parser 的底层魔法与完整解析!

目录

RTL Parser 的主要工作

RTL Parser 的底层实现机制

1. Lexical Analyzer(词法分析器)

2. Syntax Analyzer(语法分析器)

3. Pre-Semantic Analyzer(预语义检查器)

4. Behavioral Description Collection(行为表达式采集)

✨ 总结一下(一张表清晰看)

小细节分享(很多人不知道)

小结一句话


RTL Parser 在整个 Design Compiler(DC_SHELL)流程中是第一个把源代码转换成内部可操作数据的模块,它直接决定了后续 Elaboration、HLO、Datapath 优化的基础结构。
你问得非常到位,不仅要知道它做了什么,还要知道它是怎么实现的——下面我就从功能底层实现机制给你全面讲一遍。


RTL Parser 的主要工作

在 Design Compiler 里,RTL Parser负责把输入的 HDL(比如 Verilog、VHDL)源代码转成内部的语法树(AST, Abstract Syntax Tree)初步的数据对象(Symbol Table)

主要包括:

阶段 具体内容
1. 词法分析(Lexical Analysis) 把源代码分割成一个个有意义的 Token(关键词、变量名、符号、数字等)
2. 语法分析(Syntax Analysis) 把 Token 按语言语法规则组合成 AST(树形结构,描述代码结构)
3. 初步语义检查(Pre-Semantic Check) 检查类型定义、端口声明、参数合法性,收集 symbol 表(名字和对象的映射)
4. 构建设计单元(Design Units) 把 module、entity、architecture 等转化为 design_unit 结构
5. 保留行为描述 对 always、assign、process 等保留为行为表达式,供 HLO 后续展开

注意:在这一步 不会做任何 elaboration,比如 module instantiation、位宽调整、时序分析,这些都是后面阶段做的。


RTL Parser 的底层实现机制

DC_SHELL 的 RTL Parser,底层大致可以分为四大模块:


1. Lexical Analyzer(词法分析器)

  • 手写的 DFA(Deterministic Finite Automaton)或者Lex 工具生成的扫描器。

  • 把源码一行行读入,切分成:

    • 关键字(如 module, input, wire, always

    • 标识符(变量名)

    • 运算符(+, -, *, ?, :

    • 常量(比如 8'd255)

实现细节:

  • 内部是状态机(Finite State Machine)

  • 读取字符并跳转状态,最终输出 Token

  • 有 Error Recovery 机制(比如漏掉分号时,尽量找出后续 Token)


2. Syntax Analyzer(语法分析器)

  • 典型使用LALR(1)LR(1) Parser(Shift-Reduce Parser)

  • 基于 Verilog/VHDL 的 BNF(巴科斯范式)描述的语法规则构建解析树。

  • 遇到规则匹配时进行 Reduce,构建 AST(Abstract Syntax Tree)节点。

例如,看到:

assign y = a + b;

构建 AST 大概是:

assign_stmt
  ├── lhs: identifier (y)
  ├── rhs: add_expr
        ├── operand1: identifier (a)
        ├── operand2: identifier (b)

内部数据结构一般是:

  • ast_node:带有 node_type(如 assign、always、module_decl)和 child pointers

  • 每个节点还记录位置信息(行号、列号)方便报错和后续映射回源代码。


3. Pre-Semantic Analyzer(预语义检查器)

  • 在 Parser 阶段直接做简单检查,提高错误检测的早期性:

    • 检查端口定义是否重复

    • 参数定义是否符合语法

    • 端口 direction 是否合规(input/output/inout)

    • wire/reg 类型约束基本检查

这一步不会检查类型匹配,比如说一个加法的左右是否都是 logic 型,这要等 elaboration 以后。

同时,这一步会收集:

  • Symbol Table(符号表):模块名、变量名、端口名、参数名 → 地址

  • Module List(模块列表)

  • Early Netlist Skeleton(粗略连线信息)


4. Behavioral Description Collection(行为表达式采集)

  • 把所有 combinational 和 sequential 逻辑块保存在 AST 中。

  • always 块、assign 语句、initial 块都被记录为抽象节点,供后续 HLO 调度。

比如:

always @(posedge clk) begin
   if (reset) 
       q <= 0;
   else 
       q <= d;
end

会被记录成:

  • always node

  • sensitivity list(posedge clk)

  • if-else structure

  • non-blocking assignment (<=) expression

而不是一开始就直接建成 Flip-Flop!

这一阶段不做硬件推导,只是保留逻辑描述。


✨ 总结一下(一张表清晰看)

步骤 作用 是否生成硬件?
词法分析 把代码分成 Token
语法分析 解析成 AST 树
预语义分析 检查基本语义错误,生成 Symbol Table
行为收集 保存 always/assign 等逻辑块描述

注意:

  • 到这里为止,DC 还没有生成任何硬件电路!

  • 只有到了 Elaboration/HLO 后才会把这些 AST 转成硬件表示(dataflow, FSM, datapath node)


小细节分享(很多人不知道)

  • DC 的 Verilog Parser 是支持不规范代码的,比如多余逗号、端口顺序不严格。

  • 有隐藏参数 verilog_standard 可以设定为 1995, 2001, 2005, SystemVerilog,影响 Parser 行为。

  • 其实 DC 里 Verilog 和 VHDL 是分别独立实现的两个 Parser 引擎,但中间 IR 是统一的。

  • Parser 在内部会加一个 invisible "root" node,把所有 module/architecture 挂在下面,方便 traversal。


小结一句话

RTL Parser 把 HDL 源代码解析成 AST 和 Symbol Table,并保留行为描述,为后续 elaboration、调度、绑定打下基础,它本身不做电路生成,只是构建中间表示。

你可能感兴趣的:(EDA,DC_SHELL,Synopsys,EDA,Synopsys)