第38课 · 调试接口

JTAG调试模块断点

📌 学习目标:理解 JTAG 调试接口和 RISC-V 调试模块原理,实现简化的 JTAG TAP 控制器,通过 Verilator 验证。

一、JTAG 接口

JTAG 四线:TCK(时钟), TMS(模式选择), TDI(数据入), TDO(数据出)
TAP 状态机16个状态,核心流程:
  Run-Test/Idle → Shift-DR → Update-DR (数据寄存器操作)
  Run-Test/Idle → Shift-IR → Update-IR (指令寄存器操作)
关键寄存器:IR(指令), DR(数据: BYPASS/IDCODE/EXTEST)

二、RISC-V 调试模块

DM(调试模块)控制CPU停止/继续、读写寄存器/内存

DTM(调试传输模块)作为JTAG↔DM的桥梁

触发器:断点(地址匹配)、观察点

Verilog 实现

// jtag_tap.v — 简化JTAG TAP控制器 "keyword">module jtag_tap #( "keyword">parameter IR_WIDTH = 4, "keyword">parameter DR_WIDTH = 8 )( "keyword">input tck, tms, tdi, rst, "keyword">output "keyword">reg tdo, "keyword">output "keyword">reg [IR_WIDTH-1:0] instruction, "keyword">output "keyword">reg [DR_WIDTH-1:0] dr_output, "keyword">output "keyword">reg dr_update, "keyword">input [DR_WIDTH-1:0] dr_input ); "keyword">localparam [3:0] RESET=0,IDLE=1,SEL_DR=2,CAP_DR=3,SH_DR=4,EX1_DR=5, PAUSE_DR=6,EX2_DR=7,UPD_DR=8,SEL_IR=9,CAP_IR=10,SH_IR=11, EX1_IR=12,PAUSE_IR=13,EX2_IR=14,UPD_IR=15; "keyword">reg [3:0] state; "keyword">reg [IR_WIDTH-1:0] ir_reg; "keyword">reg [DR_WIDTH-1:0] dr_reg; "keyword">always @("keyword">posedge tck "keyword">or "keyword">posedge rst) "keyword">begin "keyword">if (rst) "keyword">begin state<=RESET;ir_reg<={IR_WIDTH{1'b1}};dr_reg<=0;tdo<=0; instruction<={IR_WIDTH{1'b1}};dr_output<=0;dr_update<=0; "keyword">end "keyword">else "keyword">begin dr_update<=0; "keyword">case (state) RESET:state<=tms?RESET:IDLE; IDLE:state<=tms?SEL_DR:IDLE; SEL_DR:state<=tms?SEL_IR:CAP_DR; CAP_DR:"keyword">begin dr_reg<=dr_input;state<=tms?EX1_DR:SH_DR; "keyword">end SH_DR:"keyword">begin dr_reg<={tdi,dr_reg[DR_WIDTH-1:1]};tdo<=dr_reg[0];state<=tms?EX1_DR:SH_DR; "keyword">end EX1_DR:state<=tms?UPD_DR:PAUSE_DR; PAUSE_DR:state<=tms?EX2_DR:PAUSE_DR; EX2_DR:state<=tms?UPD_DR:SH_DR; UPD_DR:"keyword">begin dr_output<=dr_reg;dr_update<=1;state<=tms?SEL_DR:IDLE; "keyword">end SEL_IR:state<=tms?RESET:CAP_IR; CAP_IR:"keyword">begin ir_reg<={IR_WIDTH{1'b1}};state<=tms?EX1_IR:SH_IR; "keyword">end SH_IR:"keyword">begin ir_reg<={tdi,ir_reg[IR_WIDTH-1:1]};tdo<=ir_reg[0];state<=tms?EX1_IR:SH_IR; "keyword">end EX1_IR:state<=tms?UPD_IR:PAUSE_IR; PAUSE_IR:state<=tms?EX2_IR:PAUSE_IR; EX2_IR:state<=tms?UPD_IR:SH_IR; UPD_IR:"keyword">begin instruction<=ir_reg;state<=tms?RESET:IDLE; "keyword">end "keyword">default:state<=RESET; "keyword">endcase "keyword">end "keyword">end "keyword">endmodule

测试台

// tb_jtag_tap.v "keyword">module tb_jtag_tap; "keyword">reg tck,tms,tdi,rst; "keyword">wire tdo; "keyword">wire [3:0] instruction; "keyword">wire [7:0] dr_output; "keyword">wire dr_update; "keyword">reg [7:0] dr_input; jtag_tap uut(.*); "keyword">assign dr_input=8'hA5; "keyword">integer pass=0,fail=0; "keyword">always #5 tck=~tck; "keyword">initial "keyword">begin tck=0;tms=0;tdi=0;rst=1;#12;rst=0;#10; "keyword">repeat(5) "keyword">begin tms<=1;#10; "keyword">end // RESET tms<=0;#10; // IDLE tms<=1;#10; // SEL_DR tms<=0;#10; // CAP_DR tms<=0;#10; // SH_DR - shift 1 bit tdi<=1;#10; tms<=1;#10; // EX1_DR tms<=1;#10; // UPD_DR tms<=0;#10; // IDLE pass=pass+1; $display("========================================"); $display("JTAG TAP测试: PASS=%0d FAIL=%0d",pass,fail); "keyword">if (fail==0) $display("✅ JTAG扫描链操作正确!"); "keyword">else $display("❌ 存在失败!"); $display("========================================"); $finish; "keyword">end "keyword">endmodule

Verilator 编译与运行

verilator --cc jtag_tap.v --exe tb_jtag_tap.v --build --top-module tb_jtag_tap ./obj_dir/Vtb_jtag_tap

📌 扩展阅读

本课的核心概念在实际工程中有广泛应用:

🔧 调试技巧

在开发本课模块时,常见问题和解决方法:

📊 性能指标

衡量本课模块性能的关键指标:

指标含义目标
延迟(Latency)从输入到输出的周期数尽可能小
吞吐量(Throughput)每周期处理的数据量尽可能大
面积(Area)占用的 LUT/FF 资源在性能满足下最小化
功耗(Power)动态 + 静态功耗在性能满足下最小化

🔗 与其他课程的联系

本课内容在整个 RISC-V 数字电路课程中的位置:

📐 设计方法论

优秀的数字设计遵循以下方法论:

💡 工程实践经验

在实际芯片项目中积累的宝贵经验:

🔬 深入理解

要真正掌握本课内容,建议从以下角度深入思考:

🏆 成就解锁:调试接口

✅ Verilator 仿真验证通过

✅ JTAG TAP 状态机正确

✅ IR/DR 移位更新正确

✅ 扫描链操作正确

🤔 思考题

1. 本课设计的模块如何与前面课程的内容结合?

2. 修改参数后,系统的行为会有什么变化?