Rocketchip RISC-V Debug调试硬件相关(一)
2019年10月份,RISCV发布了一版新的硬件代码,并对Debug调试部分进行了对应的升级修改,随后一直沿用2019年的版本至今,目前版本为0.13.2版本。本文重点研究对应的升级和修改意义,以及在后续SoC集成时的处理方法。阅读本文之前,请对RISCV的Debug调试有个基础的了解,比如JTAG五线或四线连接、调试软件openOCD、RISCV调试过程和基本流程。不了解也没关系,可先参考阅读下面这篇文章:
RISCV官方Debug文档,也可以看下,不过很多细节并没有展开描述,所以要搞懂硬件实现还需要自己研究下代码,官方文档参考下面链接:
一、总体硬件架构
DM模块内部又分为dmInner模块和dmOuter模块。dmOuter模块主要完成DM内部寄存器的实现,上位机可以通过调试通路读写dmOuter内部寄存器;dmInner模块主要完成dmOuter寄存器对核的控制操作,以及将dmOuter的控制转成TileLink总线的请求。
二、调试部分硬件架构
最新版本的DM硬件架构如上图所示,JTAG通过DTM模块进入,DTM和dmOuter通过一组io_dmi_*的DMI接口通信,dmOuter又通过auto_asource_out_*和io_innerCtrl_bits_*两组信号和dmInner通信。dmInner则通过auto_dmInner_tl_*的TileLink总线和控制总线Control Bus通信。图中黄颜色标注的是在TCK时钟域,绿色标注的是在内核时钟域或内核同步时钟域,第三小节再介绍。
dmOuter模块内部又分成五个部分:
图中DMI只是一个接口,并不是单独的模块。除此以外,dmInner实现了Program Buffer的功能,该功能虽然不是必须的,但是最好实现该功能,否则访问CSR和memory可能存在问题。
三、DM时钟复位
最新版的DM时钟复位关系如上图所示,JTAG TRST可以不接,但需要注意该复位控制DTM和DM模块的dmOuter部分,如果是四线JTAG,需要考虑dmOuter的复位由谁提供。图中黄色部分为TCK的时钟域,绿色部分为core clock时钟域。TCK时钟域下,JTAG调试通路可以一直访问到DM的dmOuter内部寄存器,但无法继续访问dmInner部分,原因是该部分时钟和内核时钟同步。
最新版的dmInner的时钟由外部提供,debug_clock和debug_reset组成一对,该时钟虽然官方将其作为输入由user logic处理,但官方对该时钟的要求是和内核时钟同步,同时复位保持和debug_clock 1:1的关系。
对于新版的改动,官方的原话为:
也就是说最新版的改动基于时钟复位1:1的关系实现,dmOuter使用dmi_clock和dmi_reset,这两个时钟和复位在内部连接到了TCK和TRST的对外输入引脚,一组新的debug_clock和debug_reset用于给dmInner提供时钟和复位。
四、新版本修改的地方说明
新版本的修改,官方对其进行了解释和说明,参考下面链接可以了解详细的说明:
其中有几个较为重要的修改,将在后续文章中进行深入研究,这里对该原文内容翻译一下,不一定都对,有疑问可评论留言,一起探讨。
debug_clock
must be synchronous toclock
. The clock gate formerly in dmInnerAsync now resides outside the debug module in customer logic. Customer logic can callconnectDebugClockAndReset
to achieve the same functionality as before.debug_clock和core clock必须同步,clock gate之前在dmInner内部实现,现在需要外围 wrapper逻辑customer logic实现该功能。Customer logic可以调用
connectDebugClockAndReset
o achieve 来实现和之前版本一致的功能(但clock gate的std cell还是需要根据不同工艺库进行替换)。
- A new input
dmactiveAck
is returned from customer logic and is used to indicate when dmInner is able to accept DMI transactions (i.e.debug_clock
is running anddebug_reset
is negated). WhendmactiveAck
is negated, a bus blocker returnsdenied
for transactions to dmInner. The current version of OpenOCD is tolerant of this blocker, but other software may need to be updated.一个新的输入信号dmactiveAck需要customer logic处理,该信号用来指示dmInner是否有能力接受DMI传输请求(也就是说debug_clock有效,且debug_reset释放复位)。当dmactiveAck无效时(1’b0),总线blocker会返回“拒绝”请求dmInner命令。当前版本的OpenOCD能够兼容该blocker的行为,但其他的软件需要升级更新。
dmi_reset
must be asynchronous.debug_reset
may be either synchronous or asynchronous but its deassertion must always occur either whendebug_clock
is stopped or synchronously todebug_clock
.dmi_reset必须要是异步的,debug_reset可以异步或者同步,但其复位释放必须总是在debug_clock无效的时候(异步),或者和debug_clock同步的时候(同步)。
- hart-reset and halt-on-reset functions have been changed to simple I/O and require customer logic involvement. The two signals are grouped in a new
ResetCtrlIO
bundle.hartIsInReset
is a logical equivalent ofcore_reset
and is synchronous tocore_clock
. For debug module halt-on-reset function, this signal must remain asserted for at least 4debug_clock
cycles for the DM to assert debug interrupt plus 3core_clock
cycles for the debug interrupt to reach the core prior to thecore_reset
signal being deasserted. Halt-on-reset will not work if eitherclock
orcore_clock
is not running.hart-reset和halt-on-reset功能现在移到了输入引脚,并且要求custom logic处理该引脚信号。该信号由ResetCtrlIO前缀组成一组,hartIsInReset信号在逻辑上等同于core reset,并且和core clock同步。该信号影响DM halt-on-reset功能,如果需要使用该功能,必须在core reset复位释放之前,保持该信号至少4个debug_clock周期(为了DM有效拉起debug中断)+3个core_clock周期(为了让debug中断得到内核的响应)有效。如果core clock不工作,那么halt-on-reset也不会工作。该功能也非常重要,将在后续章节介绍。
除此之外,还有ndreset和dmactive信号,在SoC集成时需要注意信号的连接和实现。有相关问题和疑问,可以留言一起讨论,有不懂的也可以留言一起解决。
因篇幅问题不能全部显示,请点此查看更多更全内容