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 没有逻辑值,它表示"没有驱动"。而 strong1pull0 等都有明确的逻辑值。

四、强度竞争规则

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

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

示例分析:

复制代码
// 场景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(电源强度更高,胜出)

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

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

语法:

复制代码
<门类型> ( <强度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 分别是 wandwor 的三态版本。

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

1. trireg 的特殊之处

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

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

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

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

2. trireg 的默认值
线网类型 默认值(无驱动时)
wiretri 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

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

五、电源线网(supply0supply1

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

复制代码
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
相关推荐
minglie114 小时前
j2b描述smp协议
fpga开发
FPGA开源工坊18 小时前
FPGA开发技巧–BRAM资源优化
fpga开发
泛联新安1 天前
InfinitPro多FPGA原型验证系统|提升芯片设计验证效率10-100倍
fpga开发
hahaha60162 天前
HLS高层次综合设计技巧--数组
开发语言·嵌入式硬件·算法·fpga开发
NamoAmitabha1282 天前
直接上手 UVM 例子
fpga开发
cmc10282 天前
301.modelsim自动仿真
fpga开发
Riwuarua3 天前
从近似0基础开始FPGA开发 -- part.10 verilog-ethernet开源UDP协议栈工程学习
fpga开发·udp·开源
my_daling3 天前
紫光FPGA远程升级注意事项(关于GTP_CFGCLK原语使用问题)
笔记·学习·fpga开发
Riwuarua4 天前
从近似0基础开始FPGA开发 -- part.11 AXI总线协议与工程应用
fpga开发