2026/8/8 16:09:38

JK触发器原理深度解析:从SR缺陷到Verilog仿真实践

JK触发器原理深度解析:从SR缺陷到Verilog仿真实践 最近在整理数字电路学习笔记时发现很多朋友对JK触发器的理解停留在“功能表”和“波形图”上一到实际电路搭建和时序分析就容易卡壳。Ben Eater的经典视频教程虽然直观但缺少中文语境下的系统性梳理和代码仿真验证。本文将结合Ben Eater的硬件演示思路为你拆解JK触发器的核心原理、真值表背后的“为什么”、从零搭建的完整步骤并提供可运行的Verilog仿真代码。无论你是电子专业学生、FPGA初学者还是想夯实数电基础的开发者都能通过本文获得一套从理论到实践、从硬件到仿真的闭环学习方案。1. JK触发器的核心概念与为什么需要它在数字逻辑的世界里触发器Flip-Flop是构成时序电路的基本记忆单元。我们最先接触的往往是SR锁存器Set-Reset Latch它简单直接但有一个致命的缺陷禁止状态S1, R1。当两个输入端同时有效时其输出状态是不确定的这在实际电路中是必须避免的。JK触发器正是为了解决SR触发器的“禁止状态”而诞生的。它巧妙地对SR触发器的功能进行了改进和扩展。1.1 JK触发器是什么JK触发器是一种具有时钟边沿触发、保持、置位、复位和翻转功能的双稳态存储器件。它有两个数据输入端J和K一个时钟输入端CLK通常是边沿触发以及输出端Q和其反相输出端Q’。它的核心价值在于当J和K同时为高电平1时输出状态会在每个有效时钟沿发生翻转Toggle。这个特性使得JK触发器功能上变得“完备”消除了不确定状态并为其在计数器、分频器等电路中的应用奠定了基础。1.2 JK触发器与SR、D触发器的关系理解JK触发器最好将其放在触发器家族的进化链中来看SR锁存器基础异步操作有禁止状态SR1。钟控SR触发器引入了时钟控制但禁止状态问题依然存在。JK触发器进化在钟控SR触发器的基础上通过内部反馈逻辑将“禁止状态”重新定义为“翻转状态”。你可以粗略地理解为J对应S置位K对应R复位但当 JK1 时电路不会冲突而是让输出取反。D触发器简化可以看作是JK触发器在 JK’即J和K始终相反条件下的一个特例或者一个更简单的结构主要用于数据存储。因此掌握JK触发器就等于掌握了最通用、功能最完整的触发器类型D触发器和T触发器翻转触发器都可以看作是它的子集或变体。2. 环境准备与学习工具说明学习JK触发器我们推荐“理论仿真硬件”三位一体的方法。以下是所需的“环境”和工具2.1 理论分析工具笔和纸用于绘制真值表、状态转换图状态图和时序波形图。这是理解内部逻辑关系不可替代的一步。逻辑代数基础需要了解与、或、非等基本逻辑运算。2.2 硬件仿真环境跟随Ben Eater思路如果你想像Ben Eater那样在面包板上搭建需要准备集成电路74LS73N双JK触发器带清零端。这是最经典的教学芯片。面包板、跳线、电源提供5V直流电源。逻辑开关用于手动控制J、K和CLK输入。LED与电阻用于观察输出Q和Q’的状态。单脉冲发生器/按键用于产生干净的手动时钟信号避免机械抖动。2.3 数字电路仿真软件强烈推荐对于绝大多数学习者先用软件仿真可以极大降低门槛快速验证逻辑Logisim开源、图形化适合入门级逻辑电路仿真可以直观地搭建门级电路。Digital或类似工具功能更强大的数字电路仿真器。FPGA开发工具 Verilog/VHDL用于进行寄存器传输级RTL仿真和综合是工业级的学习方式。我们将使用Verilog进行行为级仿真。本文将以74LS73的功能为基准同时使用Verilog进行仿真验证确保你能从抽象逻辑和具体实现两个层面都掌握它。3. JK触发器的功能真值表与深度解析真值表是理解触发器功能的钥匙但死记硬背没有意义。我们结合时钟边沿和内部逻辑来解读。3.1 功能真值表以上升沿触发为例时钟CLKJKQ(n)Q(n1)功能描述↑0000保持输出状态不变↑0011保持输出状态不变↑0100复位输出置0↑0110复位输出置0↑1001置位输出置1↑1011置位输出置1↑1101翻转输出状态取反↑1110翻转输出状态取反0 或 1xxxQ(n)无效时钟无效时忽略J、K输入说明CLK ↑表示时钟的上升沿从0跳变到1的瞬间是有效触发时刻。Q(n)表示当前状态时钟沿之前的状态。Q(n1)表示下一个状态时钟沿之后的状态。x表示“无关项”可以是0或1。3.2 真值表背后的逻辑方程从真值表可以推导出JK触发器的特征方程它描述了下一个状态Q(n1)与当前状态Q(n)以及输入J、K之间的关系Q(n1) J · Q(n) K · Q(n)这个方程如何理解J · Q(n)当Q(n)0即Q(n)1时若J1则Q(n1)被置为1。这实现了置位功能。K · Q(n)当Q(n)1时若K0即K1则Q(n1)保持为1。这实现了保持功能当J0K0时两项都为0由第二项保持。 更关键的是当K1即K0时这一项为0如果此时J0则方程结果为0实现了复位。翻转功能的体现当J1, K1时方程变为Q(n1) 1·Q(n) 0·Q(n) Q(n)正好是当前状态的反码即翻转。这个方程是理解JK触发器所有行为的数学核心也是我们后续用逻辑门搭建它的理论基础。4. 从门级电路到集成电路JK触发器的内部构造Ben Eater的视频精彩之处在于他用最基础的门电路与非门一步步搭建出了JK触发器。我们来还原这个构建过程理解其内部工作原理。4.1 基础SR锁存器与非门实现一切始于两个交叉耦合的与非门NAND Gate。// 这是一个用Verilog描述的门级SR锁存器低电平有效 module sr_latch ( input wire S_n, // 低电平有效的置位端 input wire R_n, // 低电平有效的复位端 output reg Q, output wire Q_n ); assign Q_n ~Q; // Q_n是Q的反相 always (*) begin // 注意这是组合逻辑描述实际锁存器有反馈这里为简化示意 // 真实的门级实现是交叉连接会产生锁存器 if (!S_n R_n) Q 1‘b1; // S有效置位 else if (S_n !R_n) Q 1’b0; // R有效复位 // 当 S_n1, R_n1 时Q保持原值通过反馈实现 // 当 S_n0, R_n0 时是禁止状态Q和Q_n都输出1 end endmodule关键点当两个输入都为高电平时电路保持同时为低电平时输出无效Q和Q_n都为1。4.2 升级钟控SR触发器在SR锁存器前增加两个与非门用时钟CLK来控制信号何时能传入。// 钟控SR触发器高电平有效时钟高电平期间透明 module clocked_sr_ff ( input wire CLK, input wire S, input wire R, output reg Q, output wire Q_n ); wire S_gated, R_gated; // 时钟门控逻辑 assign S_gated ~(S CLK); // 输入与非门低电平有效 assign R_gated ~(R CLK); // 将门控后的信号接入SR锁存器低电平有效 // 这里调用上面定义的sr_latch模块需稍作修改以适应接口 // 简化描述其行为 always (posedge CLK) begin // 注意这已经是边沿触发行为的描述 if (S !R) Q 1‘b1; else if (!S R) Q 1’b0; // SR1 会导致问题 end assign Q_n ~Q; endmodule问题当CLK1期间如果S1且R1则S_gated和R_gated同时为0会使底层SR锁存器进入禁止状态。4.3 终极形态主从JK触发器为了解决上述问题JK触发器引入了反馈。经典的主从JK触发器结构包含两个级联的钟控SR触发器一个主触发器一个从触发器并将从触发器的输出Q和Q’反馈到主触发器的输入门。核心改进逻辑将输出Q反馈回来与K和CLK相与后作为主触发器复位信号的一部分。将输出Q_n反馈回来与J和CLK相与后作为主触发器置位信号的一部分。这样做的神奇效果当Q1时Q_n0。这会阻塞J端通往主触发器置位端的路径因为与0相与得0同时为K端打开通往复位端的路径。这意味着即使JK1也只有复位通路可能被激活。当Q0时Q_n1。这会阻塞K端通往主触发器复位端的路径同时为J端打开通往置位端的路径。因此J和K永远不会同时有效地作用于主触发器的SR输入端从而彻底消除了禁止状态。当JK1时电路会根据当前状态自动选择置位或复位最终效果就是翻转。这种结构就是74LS73等芯片内部采用的经典主从结构。它在时钟高电平期间采样输入在时钟下降沿改变最终输出。5. 完整实战使用Verilog仿真JK触发器理解了原理我们通过代码来仿真验证其功能。我们将实现一个行为级模型和一个简单的测试平台。5.1 JK触发器的Verilog行为级描述// 文件名jk_ff_behav.v // 功能上升沿触发的JK触发器带异步低电平清零端如同74LS73 module jk_ff_behav ( input wire clk, // 时钟信号 input wire j, // J输入 input wire k, // K输入 input wire clr_n, // 异步清零低电平有效 (Clear) output reg q, // 输出 output wire q_n // 反相输出 ); assign q_n ~q; // 反相输出 // 异步清零的优先级最高 // 时钟上升沿触发 always (posedge clk or negedge clr_n) begin if (!clr_n) begin // 清零信号有效无条件清零 q 1b0; end else begin // 根据JK真值表进行状态转换 case ({j, k}) 2b00: q q; // 保持 2b01: q 1b0; // 复位 2b10: q 1b1; // 置位 2b11: q ~q; // 翻转 default: q q; // 默认保持 endcase end end endmodule5.2 编写测试平台Testbench// 文件名tb_jk_ff.v // 功能测试JK触发器模块 timescale 1ns / 1ps // 定义仿真时间单位/精度 module tb_jk_ff(); // 定义测试信号 reg clk; reg j; reg k; reg clr_n; wire q; wire q_n; // 实例化被测试单元DUT jk_ff_behav dut ( .clk(clk), .j(j), .k(k), .clr_n(clr_n), .q(q), .q_n(q_n) ); // 生成时钟信号周期20ns频率50MHz initial begin clk 0; forever #10 clk ~clk; // 每10ns翻转一次周期20ns end // 施加测试激励 initial begin // 初始化信号 j 0; k 0; clr_n 1; // 初始不清零 // 等待一个时钟周期让电路稳定 #20; // 测试用例1异步清零优先级最高 $display([%0t] Test 1: Async Clear, $time); clr_n 0; // 激活清零 #15; clr_n 1; // 释放清零 #20; // 测试用例2保持功能 (J0, K0) $display([%0t] Test 2: Hold (J0, K0), $time); j 0; k 0; #40; // 观察两个时钟沿q应保持不变 // 测试用例3置位功能 (J1, K0) $display([%0t] Test 3: Set (J1, K0), $time); j 1; k 0; #40; // 第一个上升沿置位之后保持 // 测试用例4复位功能 (J0, K1) $display([%0t] Test 4: Reset (J0, K1), $time); j 0; k 1; #40; // 第一个上升沿复位之后保持 // 测试用例5翻转功能 (J1, K1) - 最核心的特性 $display([%0t] Test 5: Toggle (J1, K1), $time); j 1; k 1; #80; // 观察四个时钟沿q应每个周期翻转一次 // 测试用例6组合测试 $display([%0t] Test 6: Mixed Inputs, $time); j 0; k 1; #40; // 复位 j 1; k 0; #40; // 置位 j 1; k 1; #40; // 翻转应变为0 j 0; k 0; #40; // 保持保持0 $display([%0t] All tests completed., $time); #20 $finish; // 结束仿真 end // 监控信号变化打印到控制台 initial begin $monitor(Time%0tns: clk%b, j%b, k%b, clr_n%b - q%b, q_n%b, $time, clk, j, k, clr_n, q, q_n); end endmodule5.3 运行仿真与结果分析使用ModelSim、Vivado Simulator或任何支持Verilog的仿真工具运行上述测试平台。预期关键波形与输出异步清零clr_n变低的瞬间q应立即变为0无需等待时钟沿。保持在JK0期间q的值在时钟上升沿前后不变。置位/复位在J1,K0的时钟上升沿后q变为1在J0,K1的时钟上升沿后q变为0。翻转在JK1期间每个时钟上升沿q的值都会翻转一次1-0-1-0...。这是JK触发器最标志性的行为。通过仿真波形你可以直观地验证真值表中的所有情况深刻理解边沿触发和异步清零的含义。6. 常见问题与硬件搭建排错指南在实际硬件搭建如使用74LS73芯片或仿真中你可能会遇到以下问题6.1 问题排查表问题现象可能原因排查思路与解决方案输出无变化始终为高或低1. 电源未接通或电压不对。2. 时钟信号未连接或频率太高。3. 清零端(CLR)被意外置为有效电平。1. 用万用表检查Vcc5V和GND。2. 用示波器或LED检查时钟信号是否存在。改用低频1Hz或手动单脉冲时钟。3. 检查74LS73的CLR引脚是否已接高电平无效。输出状态不稳定随机跳动1. 输入信号存在毛刺或抖动。2. 面包板接触不良。3. 未使用去耦电容。1. 对机械开关产生的时钟或输入使用RC滤波电路或专用防抖芯片如施密特触发器。2. 重新插拔芯片和导线确保接触牢固。3. 在芯片Vcc和GND引脚间就近并联一个0.1uF的瓷片电容。翻转功能(JK1)不正常1. 芯片损坏。2. 反馈逻辑理解有误对于分立门电路搭建。3. 主从触发器的“一次变化”问题。1. 更换芯片测试。2. 仔细检查从输出反馈到输入的连接是否正确。3.注意经典主从JK触发器在CLK1期间主触发器可能因输入变化而只改变一次状态。确保在CLK1期间J、K保持稳定。仿真结果与预期不符1. 测试平台时钟与激励的时序不对齐。2. Verilog代码中敏感列表或赋值方式错误。3. 对异步/同步复位理解有误。1. 确保激励信号在时钟上升沿之前足够长时间建立时间保持稳定。2. 检查是否该用非阻塞赋值的地方误用了阻塞赋值。时序逻辑统一用。3. 确认清零信号的优先级和有效边沿描述是否正确。6.2 硬件搭建核心技巧Ben Eater风格单步时钟一开始不要用信号发生器用一个按键通过RC防抖电路产生单脉冲作为CLK按一下观察一次状态变化便于调试。先静态后动态先断开CLK手动设置J、K检查输出是否符合锁存特性对于某些电路。然后接上时钟。善用LED不仅用LED看输出Q也可以用LED串联电阻接在关键的中间节点如主触发器输出帮助理解内部状态变化。阅读数据手册务必查阅74LS73的数据手册确认引脚图、最大时钟频率、建立保持时间等参数。7. 最佳实践与工程应用建议掌握了基础后如何在更复杂的数字系统和现代FPGA/ASIC设计中用好JK触发器呢7.1 何时选用JK触发器尽管JK触发器功能全面但在现代同步数字设计中D触发器因其结构简单、数据路径清晰而成为绝对主流。JK触发器通常用于教学场景理解触发器原理和状态机基础。特定计数器设计某些异步计数器或环形计数器用JK实现可能更简洁。将现有TTL/CMOS逻辑如74系列移植到FPGA需要理解其行为以进行等效替换。在FPGA/ASIC中优先使用D触发器。JK触发器的功能可以通过D触发器加组合逻辑轻松实现// 用D触发器和组合逻辑实现JK触发器功能 module jk_using_d_ff ( input wire clk, input wire j, input wire k, input wire clr_n, output reg q ); wire d_input; // 根据JK功能表推导出D输入端的逻辑 // Q(n1) J ~Q(n) | ~K Q(n) assign d_input (j ~q) | (~k q); always (posedge clk or negedge clr_n) begin if (!clr_n) q 1b0; else q d_input; // D触发器核心 end endmodule7.2 同步设计与时序约束无论使用哪种触发器都必须遵守同步设计原则全局时钟使用单一的全局时钟网络驱动所有触发器。避免异步反馈像主从JK触发器内部那种异步反馈在现代设计中应转化为同步逻辑。关注时序理解建立时间Setup Time和保持时间Hold Time。在仿真中激励信号要在时钟沿前稳定足够长时间。7.3 从JK触发器到有限状态机FSMJK触发器是构建状态机尤其是摩尔机的理想元件。每个触发器存储状态位的一位。设计步骤状态编码为每个状态分配二进制码。绘制状态转移图。列出状态转移表包含当前状态、输入、下一状态。利用JK触发器激励表根据当前状态和下一状态反推出每个JK触发器所需的J、K输入值。化简J、K的逻辑方程使用卡诺图或逻辑化简工具。绘制电路图或编写RTL代码。这个过程是数字逻辑设计的精髓虽然现在多用HDL直接描述状态机但理解其底层硬件实现由触发器构成至关重要。本文从SR触发器的缺陷出发揭示了JK触发器如何通过巧妙的反馈逻辑消除禁止状态并实现翻转功能。我们不仅深入分析了其真值表和特征方程还沿着Ben Eater的硬件思路理解了主从结构的内在机理。通过可运行的Verilog行为模型和测试平台我们能够在仿真环境中直观验证其所有功能。最后我们探讨了硬件搭建的常见陷阱并给出了在现代数字设计中应用JK触发器的最佳实践。理解JK触发器不仅仅是记住一个芯片的功能更是打通组合逻辑与时序逻辑、理解状态存储与转移的关键一步。建议你亲手运行一遍仿真代码如果有条件不妨在面包板上搭一遍74LS73电路那种“灯随心动”的体验会让你对数字电路的理解更加深刻。