5.1 内置门原语:把电路一比一摆上法庭


文档摘要

5.1 内置门原语:把电路一比一摆上法庭 本节摘要:内置门原语是语言自带的基本单元:and、or、not、xor、buf 与三态门家族。实例化它们就是按接线图搭电路,没有解释空间。这一节用门级全加器建立「网表阅读」的双语能力,并讲清多输入门对 x 与 z 的处理规则。 时间维度审完,本章下沉现场。第一站是内置门原语——Verilog 语言直接内置的基本单元,不用定义、直接实例化。它是结构化建模的原子设施,也是读懂综合网表的第一课。 门原语全家福 多输入门:and、nand、or、nor、xor、xnor,第一个端口是输出,其余全是输入,输入数量不限。单输入门:not、buf,一个输入可以驱动多个输出。三态门:bufif1、bufif0、notif1、notif0,带使能端,下一章 5.

5.1 内置门原语:把电路一比一摆上法庭

本节摘要:内置门原语是语言自带的基本单元:and、or、not、xor、buf 与三态门家族。实例化它们就是按接线图搭电路,没有解释空间。这一节用门级全加器建立「网表阅读」的双语能力,并讲清多输入门对 x 与 z 的处理规则。

时间维度审完,本章下沉现场。第一站是内置门原语——Verilog 语言直接内置的基本单元,不用定义、直接实例化。它是结构化建模的原子设施,也是读懂综合网表的第一课。

门原语全家福

多输入门:and、nand、or、nor、xor、xnor,第一个端口是输出,其余全是输入,输入数量不限。单输入门:not、buf,一个输入可以驱动多个输出。三态门:bufif1、bufif0、notif1、notif0,带使能端,下一章 5.3 节细审。还有 pullup、pulldown 两个无输入门,把线拉到弱 1 或弱 0。

module gate_tour( input wire a, b, c, output wire y1, y2, y3 ); and g1(y1, a, b, c); // 三输入与门:全 1 才出 1 or g2(y2, a, b); // 两输入或门 not n1(y3, y1); // 反相器:一个输入一个输出 wire drive_a, drive_b; buf b1(drive_a, drive_b, y1); // 缓冲:一入两出(信号观测副本) endmodule

实例化的第一个参数是可选的实例名——门原语匿名也合法,但命名是排错的基本功:波形窗口和网表里都靠实例名定位。门上可以挂延迟:and #2 g1(y, a, b),门级仿真与网表反标就靠它。

x 与 z 的传染规则

多输入门对未知态的处理有一张固定裁决表,核心是两条:与门见到 0 直接出 0(不管其他输入是 1 还是 x),全 1 但有一个 x 才出 x;或门见到 1 直接出 1,全 0 有 x 出 x。异或门则严格——任何一个 x 都传染输出。z 在门输入端被按 x 处理。

// 传染规则速记(注释形式) // and 门:0 是霸主 —— 有 0 出 0,无 0 有 x 出 x,全 1 出 1 // or 门:1 是霸主 —— 有 1 出 1,无 1 有 x 出 x,全 0 出 0 // xor 门:无豁免 —— 见 x 出 x

这条规则直接影响门级调试:未复位信号(x)流进与门,只要另一个输入是 0,下游就是干净的 0——x 被「屏蔽」了;流进异或门则一路传染。所以门级仿真里追 x 的传播路径,异或链和选择器是重灾区,与门拉零是避风港。

门级全加器:双语对账

用门原语搭一个全加器,再与 RTL 版本对账——这是建立「描述与结构」双语能力的经典练习:

module full_adder_gates( input wire a, b, cin, output wire sum, cout ); wire w1, w2, w3; xor x1(w1, a, b); xor x2(sum, w1, cin); // 和:a 异或 b 异或 cin and a1(w2, a, b); and a2(w3, w1, cin); or o1(cout, w2, w3); // 进位:ab 或 cin 与半加和 endmodule module full_adder_rtl( input wire a, b, cin, output wire sum, cout ); assign sum = a ^ b ^ cin; assign cout = (a & b) | (cin & (a ^ b)); endmodule

两份描述逻辑严格等价,综合器处理 RTL 版本时优化的目标结构,大致就是门级版本手写的形状。这个练习的真正价值在反方向:拿到一份综合网表,按实例化关系徒手画出电路,再对照 RTL 确认——这就是网表阅读的全部技术。

05-05-fig01

案例展开:从网表认领锁存器。 背景:某团队一段组合代码综合后的面积异常偏大,怀疑意外推断了锁存器。操作:打开综合网表(结构化 Verilog),检索锁存器单元的实例化记录,顺着其数据端与使能端往回找,锁定一段缺 else 的 if 赋值;回改 RTL 补全分支,重新综合,锁存器消失、面积回落。解读:网表是综合器「理解结果」的原文——RTL 里你以为是描述,网表里它是实打实的单元清单;面积、时序、功耗的一切异常,最终都要在这份清单上找到物证。变式:养成习惯后,可以把「综合后查锁存器、查意外寄存器复制、查被删除的逻辑」做成脚本化的检查项,接进每日构建——第九章规范一节的 Lint 思路,正是把这个检查提前到综合之前。

什么时候该下到门级

判断标准只有一条:你需要的信息 RTL 层给不出来,就下一层。功能验证用 RTL;要确认毛刺、复位释放行为、延迟相关性,跑门级仿真;要查面积时序异常,读网表与时序报告。把门级当日常设计手段是时代错误——那是原理图时代的工作方式;把门级当盲区同样是隐患——总有一天你要在网表里找答案。

网表阅读的入门指引

既然网表阅读是本节的核心产出,这里给一个上手次序。第一步,只找实例化语句:网表里99%的内容是「单元名 实例名(端口连线)」,先练习忽略其他内容,把实例化清单抽出来。第二步,按信号名分组:每个网线(wire)把若干单元的端口连在一起,以网线为线索能画出局部电路。第三步,认单元:常用库单元就那几十种——各类与或非门、选择器、加法器单元、触发器单元,遇到不认识的名字查工艺库手册的单元描述。练习材料就用自己写的模块:跑一次综合,打开网表,对照 RTL 逐块认领——你写的每个 assign、每个 always,在网表里都能找到自己的影子。

门级与 RTL 波形对不上时怎么想

门级仿真的波形与 RTL 不完全重合是正常的,差异来自延迟。RTL 里组合逻辑零延迟稳定,门级里每个门有真实延迟,输出在输入变化后要经过一段传播才稳定——这段时间里的中间值就是毛刺的来源。对账的正确姿势是「沿上对账」:只比较时钟沿稳定时刻的值,忽略沿之间的过渡。若沿上也不一致,那才是真正的功能差异,需要回 RTL 排查——多半是延迟依赖的写法(锁存器、组合反馈)在两个层级下表现不同。

本节要点回顾

  • 门原语即基本单元:实例化即可用,输出端口在前,实例名是排错的坐标;
  • x 的裁决有表可查:与门 0 霸权、或门 1 霸权、异或门无豁免,z 按同 x 处理;
  • 双语能力是核心产出:门级与 RTL 互相对账,网表阅读由此入门;
  • 网表是综合器理解结果的原文:面积时序异常的物证都在实例化清单里;
  • 下门级的唯一理由:RTL 层给不出你需要的信息——毛刺、延迟、物理验证。

基本单元清点完毕,下一节造自己的单元:用户定义原语与它的真值表。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U