概要: 无关项表示:当系统契约没有约束某个输入对应的输出时,允许实现自行选择输出值。在卡诺图中,只有 X 单元能扩大有用分组时才将其纳入;采用积之和(SOP)时绝不能覆盖必须为 0 的单元,采用和之积(POS)时绝不能覆盖必须为 1 的单元。只有当无关项假设在使用位置确实成立时,优化才有效。HDL
X、仿真中的未知值与综合无关项并不天然等价。
逻辑化简通常要求在每一种可能输入上保持函数不变。无关项条件会放宽这项要求:对选定的输入/输出情形,可以把输出赋为 0 或 1,从而在真正重要的情形上得到更小的实现。
这种自由可以减少文字项与逻辑门,也可能在假设错误时移除复位恢复能力、暴露无效显示模式,或造成仿真与硅片行为不一致。专业设计会同时记录三类集合:
- 必须输出 1 的导通集;
- 必须输出 0 的关断集;
- 输出任取 0 或 1 均满足系统契约的无关项集。
输出不受约束的两种原因
1. 输入不可达
环境保证某个输入向量不会在需要观察该逻辑的时刻到达。
有效 BCD 数字属于 0–9 集合,因此只有在以下条件均成立时,10–15 才能视为不可达:
- 信号源始终产生有效 BCD;
- 复位和上电过程不会暴露其他数值;
- 不会把转换过程中的中间值采样为数字;
- 破坏编码的故障不在设计要求的故障模型内。
如果一条四位总线在两个有效寄存值之间切换时会短暂变成 1100,那么“算法从不请求 12”并不足以证明该输入不可达。
2. 输入可能出现,但该输出不会被观察
当 valid=0 时,流水线级可以携带任意数据。如果所有消费者都用同一个有效状态限定数据,那么无效周期的数据输出并不重要。
这是一项可观察性条件,而不是输入不可达。只有在没有任何消费者记录、比较、转发或以其他方式使用这个名义上无关的字段时,它才始终安全。
在二值化简问题中,两种情形都会变成 X 单元,但证明方式不同,因此应在规范中保留各自的理由。
X 并不只有一种通用含义
符号 X 被赋予了多种含义:
- 在卡诺图上,X 表示“实现可以选择 0 或 1”。
- 在四态 HDL 仿真中,
X通常表示“未知、冲突或未初始化”。 - 在真值表文档中,X 可能表示该行不关心某个输入值。
- 在综合指令中,工具专用结构可能授权优化。
这些含义不能互换。
在 RTL 中赋值 'x,可能在某些流程中改善优化,也可能在仿真中传播未知值,在另一个流程中被忽略或转换,还可能掩盖真实初始化错误。不完整的组合赋值可能推断出锁存器,而不是无关项。 full_case 等工具指令还可能让综合后行为不同于仿真;Intel 文档明确警告了这种可能性。
应使用目标语言、仿真器、综合工具、代码检查规则与形式验证流程共同支持的方式表达意图,然后在相同环境假设下验证综合结果。
卡诺图规则
对于化简后的积之和:
- 把每个单元标为必须 0、必须 1 或 X。
- 只用 1 与 X 组成大小为二次幂的矩形。
- 覆盖每一个必须为 1 的单元。
- 绝不包含必须为 0 的单元。
- 某个 X 不能改善覆盖时就不使用它。
- 根据真实成本目标选择覆盖,例如文字项数、单元数、深度、共享项或其他实现指标。
对于和之积,采用对偶规则:
- 将必须为 0 的单元与可选 X 分组;
- 覆盖每一个必须为 0 的单元;
- 绝不包含必须为 1 的单元。
每个输出可以以不同方式使用同一个 X。一个数码管段函数可能把某个无效 BCD 单元选为 1,另一个则选为 0。除非接口规范规定统一的无效模式,否则没有必要为所有输出全局指定同一个无效值。
完整示例:有效 BCD 数字是否至少为 5
设 A 为 BCD 最高有效位,D 为最低有效位。要求如下:
- 数字 0–4 时 F=0;
- 数字 5–9 时 F=1;
- 编码 10–15 时为 X。
| 十进制/编码 | ABCD | F |
|---|---|---|
| 0–4 | 0000–0100 | 0 |
| 5 | 0101 | 1 |
| 6 | 0110 | 1 |
| 7 | 0111 | 1 |
| 8 | 1000 | 1 |
| 9 | 1001 | 1 |
| 10–15 | 1010–1111 | X |
采用格雷码行列顺序:
CD
00 01 11 10
AB = 00 0 0 0 0
AB = 01 0 1 1 1
AB = 11 X X X X
AB = 10 1 1 X X
借助 X 单元,可以形成三个有用分组:
- A=1 的两行组成八单元组,得到 A;
0110、0111、1110和1111得到 BC;0101、0111、1101和1111得到 BD。
因此:
因式分解后:
检查关心集:
- 数字 0–4 输出 0;
- 数字 5–7 满足 ;
- 数字 8–9 满足 A。
这个表达式恰好对所有无效编码 10–15 都输出 1。只有因为这些行已经被明确声明为不受约束,这样的结果才可以接受。
如果无效编码必须输出 0
此时它们不再是无关项。当 10–15 的 F=0 时,一个有效 SOP 为:
该版本在无效编码上保持要求的零输出。由于接口契约更严格,实现也更大。
无关项不起作用的例子
对于有效 BCD 数字,“是否为偶数”可表示为:
最低有效位已经编码了奇偶性。即使允许编码 10–15 为 X,也无法在不改变必需值的情况下删掉唯一的文字项,所以最小表达式保持不变。
无关项只会扩大优化空间,并不保证一定得到改进。
消去一个文字项的例子
定义:有效 BCD 数字为 8 或 9 时 F=1,有效数字 0–7 时 F=0。
如果无效编码 10–15 也必须输出 0:
只有 1000 和 1001 满足该表达式。
如果 10–15 是无关项,必须为 1 的单元就能与全部六个 X 单元合并:
两种实现在有效 BCD 上完全一致,但有意在部分无效输入上给出不同结果。
正确比较非常重要:一个设计不能声称“未使用无关项”,却暗中利用无效单元扩大分组。
瞬态输入与采样边界
即使源寄存器和目标寄存器都保存有效编码,组合逻辑的各位也不会同时切换。从 BCD 7(0111)到 8(1000)的转换改变四个位,并可能经过其他电气组合。
这是否重要取决于边界:
- 只在译码器稳定后采样的目标寄存器,可能永远不会捕获中间结果。
- 异步输出使能、写入选通或由化简逻辑派生的时钟,可能对瞬态作出响应。
- 多路扫描显示器可能短暂出现鬼影图案。
- 逻辑分析仪可能看到软件永远不会观察到的数值。
因此,不可达集合的证明必须说明输出在什么时刻重要,而不只是软件期望哪些稳态值。
对输入或输出进行寄存、约束时序、设计无冒险控制逻辑或增加消隐,都可以使假设成立。在卡诺图上标出 X 本身做不到这些。
状态机中的无效状态
假设五个状态编码为三位,正常运行中有三个编码未使用。如果复位有保证,而且状态损坏不在范围内,把这些编码当作无关项来优化下一状态与输出逻辑可能是合理的。
如果单粒子翻转、CDC 错误、部分复位或故障注入属于范围,这些编码就并非无关。设计可能需要:
- 检测非法状态;
- 立即抑制危险输出;
- 返回复位状态或另一个安全状态;
- 报告故障;
- 使用具备所需汉明距离的编码。
FPGA 工具提供明确的安全状态机制。例如 AMD Vivado 的 FSM_SAFE_STATE 会增加无效状态检测与恢复逻辑,同时带来面积/性能取舍。Intel Quartus 文档也区分普通综合与安全状态机选项。
不能一边把非法状态优化掉,一边声称能够保证从这些状态恢复。这是两种不同的规范。
独热输入与优先级输入
严格独热的 位接口有 n 个合法向量,以及 个其他向量。如果协议允许独热或全零,那么零向量也合法。
如果上游逻辑保证输入严格独热,普通编码器可以把多个位置位的输入当作无关项。优先编码器会有意定义多位同时有效的行,因此不能把它们视为不受约束。当没有请求有效时,如果有效输出会限定编码值,它仍可把编码视为无关。
这正是应在模块边界记录输入假设,而不是从“编码器”之类名称中推断它们的原因之一。
输出无须观察的数据
考虑:
valid = 0
data = anything
只有当每一种可观察副作用都受到门控时,才能安全优化依赖数据的下游逻辑:
write_enable = valid AND condition(data)
但即使如此,condition(data) 的物理切换仍可能耗电、产生侧信道泄漏或影响时序。“功能上无法观察”不一定意味着“电气上无关”。
为了让仿真清晰,许多团队仍会为无效数据赋一个确定值,同时通过明确约束或外围使能让综合器优化。最佳选择取决于验证与实现流程。
HDL 指南
不要把卡诺图符号直接翻译为随意的 HDL X 赋值。
一种保守的组合写法会定义每一个输出:
always_comb begin
valid = (bcd <= 4'd9);
ge_five = 1'b0;
if (valid)
ge_five = (bcd >= 4'd5);
end
这里把无效行为规定为零。如果项目希望综合器把无效输入当作无关项,应使用经过审核、由工具支持的机制,并附带相应假设。例如形式输入约束、综合属性、受约束模块接口或特定技术原语。
无论选择哪种方法,都应:
- 通过代码检查发现不完整赋值与意外锁存器;
- 在流程需要时比较 RTL 与门级行为;
- 证明关心集上的等价性;
- 验证环境假设确实成立;
- 检查关于不可达状态与 case 覆盖率的警告;
- 除非明确需要相应行为,否则避免用
casex或通配匹配隐藏未知控制位。
验证计划
无关项优化需要两类互补检查。
关心集上的功能等价性
对每个必需输入:
四变量时可以枚举完整真值表。对更大逻辑,使用带明确关心集约束的断言或形式等价验证。
假设验证
证明或测试以下条件:
- 输出重要时,无效编码不可能被采样;
- 复位与上电过程满足假设;
- CDC 路径不会产生不受支持的组合;
- 故障要求不包含所谓“不可达”集合;
- 下游有效门控覆盖每一种副作用;
- 测试和调试模式不会绕过限定信号。
如果让 X 合法的是环境,那么只测试化简后的布尔方程,就只验证了契约中错误的那一半。
在 DigiSim 中构建 BCD 示例
构建两个“数字 ≥ 5”检测器:
- 定义无效值的版本: 实现 。
- 无关项优化版本: 实现 。
- 遍历全部十六种输入。
- 确认二者在 0–9 上一致。
- 记录它们在 10–15 上有意存在的差异。
- 为 BCD 0–9 增加
valid = NOT(A AND (B OR C)),并对可观察输出进行门控。 - 同时改变多个输入位,检查仿真器是否模拟中间转换;如果采用理想的同时更新,不要据此推断模拟冒险行为。
该练习展示了正确的交换条件:用更窄的行为承诺换取更小的逻辑。
审查清单
将任何单元标为 X 前,应确认:
- 输出为何不受约束:输入不可达,还是输出不被观察?
- 该说法在什么采样或观察边界成立?
- 复位、CDC、测试模式或故障行为是否会破坏它?
- X 是卡诺图许可、HDL 未知值,还是工具指令?
- 非法状态是否必须恢复?
- 优化后的实现在每一个关心集输入上都经过验证了吗?
- 假设本身是否通过断言或证明?
无关项不是“免费的逻辑门”。它用定义好的关心集之外的行为换取实现自由。关心集明确且经过验证时,这是严谨优化;关心集只靠猜测时,它就是隐藏功能。
后续可阅读 BCD 基础了解编码契约,BCD 到七段数码管译码了解七输出应用,以及静态与动态冒险了解转换期间的行为。



