Verilog HDL 学习笔记(十六)| 附录A:强度建模与高级线网类型

A.1 为什么需要强度建模?

一、从实际问题说起

假设你有一个总线,多个设备连接到同一条线上:

复制代码
┌──────────┐   ┌──────────┐   ┌──────────┐
│  设备A   │   │  设备B   │   │  设备C   │
│ 输出: 1  │   │ 输出: z  │   │ 输出: 0  │
└────┬─────┘   └────┬─────┘   └────┬─────┘
     │              │              │
     └──────────────┼──────────────┘
                    │
                 总线信号

如果设备A输出1,设备C输出0,那么总线上的值是什么?

答案取决于驱动强度 ------如果设备A的驱动能力更强,总线为1;如果设备C更强,总线为0;如果两者强度相同,结果为 x(不确定)。

二、强度建模的意义

场景 需要强度建模的原因
多驱动源总线 判断哪个驱动源"赢"
上拉/下拉电阻 电阻的驱动能力比逻辑门弱
电荷存储节点 电容节点可以"记住"电荷
电源/地 最强的驱动源

A.2 逻辑值与强度的组合

一、四值逻辑回顾

Verilog 使用四种逻辑值:

值 含义
0 逻辑0(假)
1 逻辑1(真)
x 不确定值
z 高阻态(浮动)

二、八种强度等级

除了逻辑值,每个信号还有强度 。Verilog 定义了 8 种强度等级,从最强到最弱:

强度等级 类型 典型来源 优先级
supply 驱动 电源(VDD)、地(VSS) 最强 ↑
strong 驱动 逻辑门输出、连续赋值
pull 驱动 上拉/下拉电阻
large 存储 电容节点(trireg类型)
weak 驱动 弱驱动源
medium 存储 电容节点(trireg类型)
small 存储 电容节点(trireg类型)
highz 高阻 三态门关闭 最弱 ↓

记忆口诀 :S upply > S trong > P ull > L arge > W eak > M edium > S mall > Highz

三、强度与逻辑值的组合

每个信号值实际上由强度 + 逻辑值两部分组成:

复制代码
信号值 = <强度> <逻辑值>

例如:

  • supply1:电源驱动,逻辑值为1(最强)

  • strong0:逻辑门输出,逻辑值为0

  • pull1:上拉电阻,逻辑值为1

  • highz:高阻态(没有驱动源)

⚠️ 重要 :highz 没有逻辑值,它表示"没有驱动"。而 strong1、pull0 等都有明确的逻辑值。

四、强度竞争规则

当多个驱动源连接到同一个线网时,按照以下规则决定最终值:

竞争情况 结果 示例
强度不同 强度高的胜出 strong1 vs pull0 → strong1(1胜出)
强度相同,值相同 值不变 strong1 vs strong1 → strong1
强度相同,值不同 结果为 x strong1 vs strong0 → x(不确定)

示例分析:

复制代码
// 场景1:不同强度竞争
wire a;
assign (strong1, weak0) a = 1'b1;  // 强1驱动
// 结果:a = strong1(1胜出)

// 场景2:相同强度竞争
wire b;
assign (strong1, strong0) b = 1'b1;
assign (strong1, strong0) b = 1'b0;
// 结果:b = x(不确定,因为两个strong驱动冲突)

// 场景3:电源 vs 逻辑门
wire c;
supply1 vdd;
assign c = vdd;      // supply1驱动
assign c = 1'b0;     // strong0驱动
// 结果:c = supply1(电源强度更高,胜出)

五、在门级原语中指定强度

门级原语(and、or、buf等)和连续赋值都可以指定驱动强度。

语法:

复制代码
<门类型> ( <强度1>, <强度0> ) <实例名> ( <端口> );

示例:

复制代码
// 为与门指定强度:输出1时为strong1,输出0时为strong0
and (strong1, strong0) a1(out, in1, in2);

// 为缓冲器指定强度:输出1时为strong1,输出0时为pull0
buf (strong1, pull0) b1(out, in);

// 为连续赋值指定强度
assign (strong1, weak0) out = in1 & in2;

// 为三态门指定强度
bufif1 (strong1, strong0) b1(out, in, enable);

// 电源和地的强度
supply1 vdd;    // supply1强度
supply0 gnd;    // supply0强度

A.3 高级线网类型

除了最常用的 wire,Verilog 还提供了多种高级线网类型,用于特定的建模场景。

一、线网类型总览

线网类型 关键字 功能 适用场景
普通连线 wire 标准连线 最常用,90%的场景
线与 wand 多个驱动源实现与逻辑 线与逻辑
线或 wor 多个驱动源实现或逻辑 线或逻辑
三态线网 tri 同wire,但允许多驱动源 三态总线
三态线与 triand 同wand,但允许多驱动源 三态线与
三态线或 trior 同wor,但允许多驱动源 三态线或
电容线网 trireg 能存储电荷 电荷存储节点
电源线 supply0 地(逻辑0) 电源/地建模
电源线 supply1 电源(逻辑1) 电源/地建模

二、线与(wand)和线或(wor)

线与(wand)

多个驱动源连接到同一线网,结果为所有驱动源的"与"。

复制代码
wand out;
assign out = a;
assign out = b;
// out = a & b

真值表:

a b wand结果
0 0 0
0 1 0
1 0 0
1 1 1
1 z 1
0 z 0

线与的物理实现:在集电极开路(OC)或漏极开路(OD)电路中,多个输出端直接相连,通过一个上拉电阻拉到高电平。只要有一个输出为0,整条线就被拉低------这就是"线与"。

线或(wor)

多个驱动源连接到同一线网,结果为所有驱动源的"或"。

复制代码
wor out;
assign out = a;
assign out = b;
// out = a | b

真值表:

a b wor结果
0 0 0
0 1 1
1 0 1
1 1 1
0 z 0
1 z 1

三、三态线网(tri)

tri 类型在功能上等同于 wire,但它明确表示这是一个三态总线,可以有多个驱动源。

复制代码
tri [7:0] data_bus;    // 8位三态数据总线

// 多个驱动源(不同时有效)
assign data_bus = enable1 ? data1 : 8'bz;
assign data_bus = enable2 ? data2 : 8'bz;
assign data_bus = enable3 ? data3 : 8'bz;

wire vs tri :在功能上完全等价。使用 tri 只是代码风格 上的选择------当你明确知道这是三态总线时,用 tri 让代码意图更清晰。

三态线与(triand)和三态线或(trior) 分别是 wand 和 wor 的三态版本。

四、电容线网(trireg)------ 最重要的高级线网类型

1. trireg 的特殊之处

普通线网(wire)没有驱动源时值为 z,但 trireg 类型的线网可以"记住"最后的驱动值。

复制代码
trireg (large) cap_node;    // 声明一个电容节点

// 当驱动源存在时,cap_node取驱动值
// 当驱动源消失(变为z)时,cap_node保持最后的驱动值

物理意义 :trireg 建模的是有电荷存储能力的节点(如MOS管的栅极电容)。当驱动源断开时,节点上的电荷不会立即消失,而是保持一段时间。

2. trireg 的默认值
线网类型 默认值(无驱动时)
wire、tri 等 z(高阻)
trireg x(不确定)

注意 :trireg 的默认值是 x,不是 z!这是因为电容节点在上电时的初始电荷是未知的。

3. trireg 的电荷强度

trireg 可以指定电荷存储强度:

强度 关键字 说明
大电容 large 电荷保持时间最长
中电容 medium 中等保持时间
小电容 small 保持时间最短
复制代码
trireg (large) cap1;     // 大电容节点(保持时间最长)
trireg (medium) cap2;    // 中电容节点
trireg (small) cap3;     // 小电容节点

// 如果trireg的强度大于驱动源的强度,驱动源需要更长时间才能改变该节点的值
4. trireg 的应用场景
场景 说明
动态MOS电路 动态逻辑门利用电容存储电荷
电荷分享电路 电荷在电容之间重新分配
存储节点建模 需要"记住"电荷的节点

示例:动态锁存器

复制代码
module dynamic_latch(q, d, clk);
    output q;
    input d, clk;

    trireg (small) storage;    // 电荷存储节点

    // 当时钟为高时,数据存入电容节点
    // 当时钟为低时,数据保持不变
    cmos (storage, d, clk, ~clk);

    // 缓冲器输出
    buf (q, storage);
endmodule

动态电路的核心:利用电容存储电荷来"记住"数据,不需要静态触发器,因此面积更小、功耗更低。但需要周期性刷新(因为电荷会泄漏),且对噪声敏感。

五、电源线网(supply0 和 supply1)

supply0 和 supply1 是强度最高的驱动源,分别表示地和电源。

复制代码
supply1 vdd;    // 电源(逻辑1,supply强度)
supply0 gnd;    // 地(逻辑0,supply强度)

// 使用
assign a = vdd;    // a 恒为 supply1(无法被其他驱动源改变)
assign b = gnd;    // b 恒为 supply0

特点:

特点 说明
强度最高 supply强度,任何其他驱动源都无法覆盖
值恒定 始终为1(supply1)或0(supply0)
用途 建模电源和地网络

A.4 强度建模总结

一、强度等级速查表

强度 级别 类型 示例
supply 7(最强) 驱动 电源、地
strong 6 驱动 逻辑门输出、assign
pull 5 驱动 上拉/下拉电阻
large 4 存储 trireg(大电容)
weak 3 驱动 弱驱动
medium 2 存储 trireg(中电容)
small 1 存储 trireg(小电容)
highz 0(最弱) 高阻 三态门关闭

二、竞争规则速查

情况 结果
不同强度 强度高的胜出
相同强度,相同值 值不变
相同强度,不同值 x(不确定)
highz vs 任何值 任何值胜出(highz不驱动)

三、线网类型选择指南

需求 推荐类型
普通连线 wire ✅
多驱动源三态总线 tri
线与逻辑 wand
线或逻辑 wor
电荷存储节点 trireg
电源/地 supply0/supply1
相关推荐
1560820721917 小时前
JFMRFVU3P5G的bit正常,但烧录mcs程序后加载异常
fpga开发
狂奔蜗牛(bradley)17 小时前
把 EtherCAT 初始化从 FPGA 搬到 ARM:命令通道的接口设计与11个坑
arm开发·人工智能·fpga开发·架构
女神下凡2 天前
芯参谋(37):EEPROM_电路设计指南
arm开发·单片机·嵌入式硬件·fpga开发·设计规范
szxinmai主板定制专家3 天前
工业视觉新思路:FPGA图像预处理+RK NPU推理,实现高速缺陷检测
人工智能·嵌入式硬件·fpga开发·rk3576+codesys
FPGA小徐3 天前
【硬件实战】立创 EDA 绘制 TF/SD 卡模块电路|SPI 模式原理图 + 阻抗匹配 + PCB 布局布线全教程
单片机·嵌入式硬件·fpga开发
狂奔蜗牛(bradley)3 天前
EtherCAT DC 分布式时钟同步的 ModelSim 仿真:从帧模板到从站行为建模
人工智能·嵌入式硬件·fpga开发·架构
ALINX技术博客3 天前
8 通道同步采样 ADC!AN706 波形显示实验 【FPGA黑金云课堂】
fpga开发
szxinmai主板定制专家4 天前
RK3568+FPGA+CODESYS异构控制方案:赋能半导体设备与工业自动化升级
人工智能·fpga开发·自动化·rk3576·半导体设备
辰丁电子4 天前
allegro入门教程-菜单栏Logic
fpga开发·pcb设计·pcb工艺·layout·pcb layout
FPGA小徐5 天前
数字IC/FPGA设计基础_ILA原理与使用
fpga开发