在数字系统设计中,逻辑模拟、故障诊断和可测性设计是确保电路功能正确性与制造可靠性的关键环节。以下是这三个主题的系统讲解:
1. 逻辑模拟(Logic Simulation)
逻辑模拟是指通过软件工具对数字电路的行为进行建模与仿真,验证其在各种输入条件下的响应是否符合预期。
(1)模拟的目的
- 验证设计的功能正确性
- 发现时序问题(如竞争、冒险)
- 支持调试与优化
- 减少硬件迭代成本
(2)模拟层次
| 层次 | 描述 | 特点 |
|---|---|---|
| 行为级模拟 | 使用高级语言描述功能(如 Y <= A + B) | 快速,不涉及具体结构 |
| RTL级模拟 | 寄存器传输级,关注数据流动与控制信号 | 可综合,用于功能验证 |
| 门级模拟 | 基于门电路网表(由综合生成) | 包含延迟信息,支持时序验证 |
| 开关级模拟 | 模拟晶体管级行为 | 精度高、速度慢,用于低功耗分析 |
(3)模拟流程
编写源代码(VHDL/Verilog)
↓
编译 → 生成可执行模型
↓
加载测试激励(Testbench)
↓
运行模拟(功能模拟 / 时序模拟)
↓
查看波形(Waveform Viewer:如ModelSim、Vivado Simulator)
↓
分析结果,修正错误
(4)常用模拟类型
| 类型 | 说明 |
|---|---|
| 功能模拟 | 不考虑延迟,仅验证逻辑功能 |
| 时序模拟 | 加入门延迟、线延迟,验证实际工作频率下是否正常 |
| 后布局布线模拟 | 在FPGA完成布局布线后进行,最接近真实硬件行为 |
✅ 推荐使用断言(assertions)和覆盖率(coverage)提高验证完整性
2. 故障诊断(Fault Diagnosis)
故障诊断是在电路出现异常时,定位出错位置的过程,常用于芯片测试与维修。
(1)常见故障模型
| 故障类型 | 描述 | 示例 |
|---|---|---|
| 固定型故障(Stuck-at Fault) | 某节点永久为0或1 | 一根信号线短接到地(stuck-at-0) |
| 桥接故障(Bridging Fault) | 两条信号线短接,导致相互干扰 | A与B相连,输出为A·B或A+B |
| 开路故障(Open Circuit) | 连线断开,信号无法传递 | 总线上某位无响应 |
| 瞬态故障(Transient Fault) | 临时干扰引起(如宇宙射线) | 单粒子翻转(SEU),常见于航天电子 |
| 延迟故障(Delay Fault) | 信号变化太慢,违反时序要求 | 关键路径延迟超标 |
✅ Stuck-at 故障是最常用的抽象模型,便于测试向量生成
(2)故障检测方法
- 应用一组输入模式(测试向量),观察输出是否偏离预期
- 若输出不同,则该故障被“覆盖”(detected)
- 使用自动测试图样生成(ATPG)工具生成高效测试集
(3)故障字典法
- 预先建立“故障 → 输出响应”映射表
- 实际测试中比对输出,查表定位故障位置
- 适用于中小规模电路
3. 可测性设计(Design for Testability, DFT)
随着集成电路复杂度上升,直接从外部引脚观测内部节点变得困难。可测性设计就是在设计阶段加入便于测试的结构,提升测试覆盖率和效率。
(1)DFT 的目标
- 提高可观测性(Observability):能观察内部状态
- 提高可控制性(Controllability):能将内部节点置为指定值
- 缩短测试时间,降低测试成本
(2)主要技术
a. 扫描链设计(Scan Chain)
将触发器改造成可以串行移位的寄存器,在测试模式下形成一条“扫描链”。
工作模式:
- 正常模式:触发器作为普通寄存器使用
- 测试模式:串行加载测试向量 → 切换到运行模式 → 采集输出 → 串行读出结果
✅ 大幅提升内部节点的可控性与可观测性
✅ 被广泛用于ASIC和FPGA中的内建自测试(BIST)
b. 内建自测试(Built-In Self-Test, BIST)
在芯片内部集成测试电路,无需外部昂贵测试设备。
典型结构:
- 测试向量生成器(如LFSR:线性反馈移位寄存器)
- 响应压缩电路(如MISR:多输入签名寄存器)
- 比较器:判断签名是否匹配预期
优点:适合现场维护、航天等场景;缺点:增加面积开销
c. JTAG 边界扫描(IEEE 1149.1 标准)
用于测试PCB板上芯片之间的互连。
原理:
- 在每个I/O引脚前添加一个边界扫描单元
- 构成一个贯穿所有芯片的扫描链
- 可检测焊点开路、短路等问题
信号线:
- TCK(时钟)、TMS(模式选择)、TDI(数据输入)、TDO(数据输出)、TRST(复位)
广泛应用于现代主板、FPGA、处理器的调试接口
d. 测试点插入(Test Point Insertion)
- 在难控/难观节点添加额外的驱动或观测点
- 提高ATPG工具的故障覆盖率
总结对比表
| 技术 | 目的 | 典型应用 |
|---|---|---|
| 逻辑模拟 | 功能与时序验证 | 设计前期验证 |
| 故障诊断 | 定位物理缺陷 | 芯片失效分析 |
| 扫描链 | 增强内部测试能力 | ASIC量产测试 |
| BIST | 实现自主测试 | 高可靠性系统 |
| JTAG | 板级互联测试 | PCB生产与调试 |
在可测性设计(DFT)中,扫描链(Scan Chain) 是一种关键技术。通过将普通寄存器替换为可扫描的触发器,可以在测试模式下串行加载测试向量,并读出内部响应,从而提高电路的可控性和可观测性。
下面详细介绍如何使用 VHDL 实现一个带扫描链功能的 D 触发器,并构建测试平台进行可测性验证。
一、带扫描链的 D 触发器设计原理
功能要求:
- 正常工作模式:作为普通 D 触发器,同步时钟边沿锁存
D输入 - 测试模式(
Scan_Enable = '1'):进入扫描模式,串行输入SI被移位到输出Q - 输出同时提供给下一个扫描单元的
SO(串行输出)
即:该触发器具有两个数据源:
D(正常路径)和SI(扫描路径),由Scan_Enable控制多路选择器选择。
二、VHDL 实现代码
-- 文件名: scan_ff.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity SCAN_FF is
port (
CLK : in std_logic;
RST : in std_logic; -- 异步复位
D : in std_logic; -- 正常数据输入
SI : in std_logic; -- 扫描输入 (Serial In)
SE : in std_logic; -- 扫描使能 (Scan Enable)
SO : out std_logic; -- 扫描输出 (Serial Out)
Q : out std_logic -- 主输出
);
end entity SCAN_FF;
architecture RTL of SCAN_FF is
signal q_reg : std_logic := '0'; -- 内部状态寄存器
begin
-- 主寄存器行为
process(CLK, RST)
begin
if RST = '1' then
q_reg <= '0';
elsif rising_edge(CLK) then
if SE = '1' then
q_reg <= SI; -- 扫描模式:加载串行输入
else
q_reg <= D; -- 正常模式:加载功能输入
end if;
end if;
end process;
-- 输出驱动
Q <= q_reg;
SO <= q_reg; -- SO 直接连接到内部状态,用于链接下一个扫描单元
end architecture RTL;
三、扫描链构建示例(多个 SCAN_FF 级联)
假设我们构建一个 3位扫描链,用于测试三个内部节点。
-- 文件名: scan_chain_top.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity SCAN_CHAIN_TOP is
port (
CLK : in std_logic;
RST : in std_logic;
D_IN : in std_logic_vector(2 downto 0); -- 并行输入
SE : in std_logic; -- 扫描使能
SI : in std_logic; -- 初始串行输入
SO : out std_logic; -- 最终串行输出
Q_OUT : out std_logic_vector(2 downto 0) -- 并行输出观察
);
end entity;
architecture STRUCTURAL of SCAN_CHAIN_TOP is
signal S0, S1, S2 : std_logic;
begin
-- 实例化三个扫描触发器(形成链式结构)
FF0: entity work.SCAN_FF(RTL)
port map(CLK => CLK, RST => RST, D => D_IN(0), SI => SI, SE => SE, SO => S0, Q => Q_OUT(0));
FF1: entity work.SCAN_FF(RTL)
port map(CLK => CLK, RST => RST, D => D_IN(1), SI => S0, SE => SE, SO => S1, Q => Q_OUT(1));
FF2: entity work.SCAN_FF(RTL)
port map(CLK => CLK, RST => RST, D => D_IN(2), SI => S1, SE => SE, SO => S2, Q => Q_OUT(2));
SO <= S2; -- 链尾输出
end architecture STRUCTURAL;
四、测试平台(Testbench)—— 可测性验证
目标:验证扫描链能否正确加载测试向量,并在运行后捕获结果。
-- 文件名: tb_scan_chain.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TB_SCAN_CHAIN is
end entity;
architecture TEST of TB_SCAN_CHAIN is
signal CLK : std_logic := '0';
signal RST : std_logic := '0';
signal D_IN : std_logic_vector(2 downto 0) := "000";
signal SE : std_logic := '0';
signal SI : std_logic := '0';
signal SO : std_logic;
signal Q_OUT : std_logic_vector(2 downto 0);
begin
-- 被测单元实例化
UUT: entity work.SCAN_CHAIN_TOP
port map(
CLK => CLK,
RST => RST,
D_IN => D_IN,
SE => SE,
SI => SI,
SO => SO,
Q_OUT => Q_OUT
);
-- 时钟生成(50 MHz)
CLK <= not CLK after 10 ns;
-- 测试过程
process
begin
-- 初始化
RST <= '1'; wait for 20 ns;
RST <= '0'; wait for 20 ns;
-- === 第一步:正常模式写入并行数据 ===
D_IN <= "101";
wait until rising_edge(CLK);
-- 观察输出(应在下一个周期反映)
wait for 20 ns;
-- === 第二步:进入扫描模式,串行加载新值 "110" ===
SE <= '1';
SI <= '0'; wait for 20 ns; -- 移入 bit0 = 0
SI <= '1'; wait for 20 ns; -- 移入 bit1 = 1
SI <= '1'; wait for 20 ns; -- 移入 bit2 = 1 (最终链内为 "110")
-- 关闭扫描模式
SE <= '0';
wait for 20 ns;
-- === 第三步:再次进入扫描模式,读出当前状态 ===
SE <= '1';
-- 连续移出三位
wait for 20 ns; -- SO 应为 LSB = 0
wait for 20 ns; -- 中间位 = 1
wait for 20 ns; -- MSB = 1 → 整体应为 "110"
wait; -- 结束仿真
end process;
end architecture;
五、仿真波形分析(关键点)
| 时间 | 操作 | 预期结果 |
|---|---|---|
| 复位后 | 清零 | Q_OUT = “000” |
| 加载 D_IN=“101” | 下一时钟上升沿后 | Q_OUT = “101” |
| 扫描输入序列 0→1→1 | 经过3个周期 | 扫描链内容变为 “110”(先进先出) |
| 扫描输出 SO | 在后续扫描时钟中依次输出原 Q 值 | 可用于比对 |
使用 ModelSim 或 Vivado Simulator 查看波形,确认:
Q_OUT是否正确更新SO是否在扫描模式下逐位输出前一级状态
六、综合可行性说明
- ✅ 该设计是完全可综合的
- 工具(如 Vivado、Quartus)会自动识别扫描触发器结构
- 注意:不要对
SO添加组合逻辑,否则可能破坏扫描链完整性 - 建议在顶层约束中禁用优化以保留扫描链结构(如设置
set_dont_touch)
七、应用意义
此设计可用于:
- ASIC 量产测试中的 ATPG 向量加载
- FPGA 内部模块的内建自检(BIST)
- 提高故障覆盖率(可达98%以上)



被折叠的 条评论
为什么被折叠?



