1.JTAG简介
JTAG调试工具:
在调试时需要用到一个工具,比如JLink或者CMSIS-DAP,对于这个工具,在这里称为JTAG主机(JTAG host),而嵌入在芯片内部的JTAG称为JTAG从机(JTAG slave),需要注意的是上面这些信号的输入输出方向是对于JTAG从机来说的。下文中如无特别说明,JTAG都是指JTAG从机。
箭头上的0或1表示的是TMS信号的电平。JTAG在每一个TCK信号的上升沿采样TMS信号和TDI信号,决定状态机的状态是否发生变化,在每一个TCK信号的下降沿输出TDO信号。可以看到,无论TAP目前处于哪一个状态,只要TMS保持高电平并持续5个TCK时钟,则TAP一定会回到Test-Logic-Reset状态。
JTAG内部有一个IR(instruction register)寄存器和多个DR(data register)寄存器,IR寄存器决定要访问的是哪一个DR寄存器。DR寄存器有IDCODE、BYPASS等。在Test-Logic-Reset状态下IR寄存器默认选择的是IDCODE这个DR寄存器。
JTAG主机通过IR SCAN设置IR寄存器的值,然后通过DR SCAN来读、写相应的DR寄存器
2.RISC-V调试Spec
调试模块在CPU芯片设计里是最为不起眼的,但又是最为复杂的模块之一,大部分开源的处理器IP都没有调试模块。
下面的内容基于RISC-V debug spec 0.13版本。
目前RISC-V的官方调试上位机是openocd,调试工具可以是JLink或者CMSIS-DAP,RISC-V调试系统框架如图3所示。
可以看到主要分为3个部分,(1)分别是Debug Host,可以理解为PC;(2)Debug Hardware,可以理解为JLink或者CMSIS-DAP这样的调试工具;(3)第三部分就是嵌入在芯片内部的调试模块。在调试模块内部,与调试工具直接交互的是DTM模块,DTM模块通过DMI接口与DM模块交互。
2.1DTM模块
在DTM模块里实现了一个TAP控制器(状态机),其中IR寄存器的长度最少为5位,当TAP控制器复位时,IR的值默认为5’b00001,即选择的是IDCODE寄存器。DTM模块的寄存器(DR寄存器)定义如图4所示。其中红色框起来的寄存器是必须要实现的。下面简单介绍一下这几个寄存器。
1. IDCODE寄存器(0x01)
当TAP状态机复位时,IR寄存器的值默认为0x01,即选择的是IDCODE寄存器。IDCODE寄存器的每一位含义如图5所示。IDCODE是只读寄存器。
-
Version:只读,版本号,可为任意值。
-
PartNumber:只读,可为任意值。
-
Manufld:只读,厂商号,遵循JEP106标准分配,实际中可为任意值,只要不与已分配的厂商号冲突即可
2 DTM控制和状态寄存器(dtmcs,0x10)
dtmcs寄存器的每一位含义如图6所示。
-
dmihardreset:DTM模块硬复位,写1有效。
-
dmireset:清除出错,写1有效。
-
idle:只读,JTAG 主机在Run-Test-Idle状态停留的时钟周期数,0表示不需要进入Run-Test-Idle状态,1表示进入Run-Test-Idle状态后可以马上进入下一个状态,以此类推。
-
dmistat:只读,上一次操作的状态。0表示无出错,1或者2表示操作出错,3表示操作还未完成。
-
abits:只读,dmi寄存器中address域的大小(位数)。
-
version:只读,实现所对应的spec版本,0表示0.11版本,1表示0.13版本。
3. DM模块接口访问寄存器(dmi,0x11)
dmi寄存器的每一位含义如图7所示
-
address:可读可写,DM寄存器的长度(位数)。
-
data:可读可写,往DM寄存器读、写的数据,固定为32位。
-
op:可读可写,读或者写这个域时有不同的含义。当写这个域时,写0表示忽略address和data的值,相当于nop操作;写1表示从address指定的寄存器读数据;写2表示把data的数据写到address指定的寄存器。写3为保留值。当读这个域时,0表示上一个操作正确完成;1为保留值;2表示上一个操作失败,这个状态是会被记住的,因此需要往dtmcs寄存器的dmireset域写1才能清除这个状态。3表示上一个操作还未完成。
-
在Update-DR状态时,DTM开始执行op指定的操作。在Capture-DR状态时,DTM更新data域。
4. BYPASS寄存器(0x1f)
只读,长度为1,值固定为0。