用telnet+openocd+jtag_dpi+vcs仿真调试RISCV的cpu
目录
背景:
需要了解的基础知识,此处不做介绍:
如何连结和调试
一些中间过程需要关心,记录
背景:
- Server :tcl+telnet
- SW :openocd+JTAG_DPI+VCS仿真(riscv base+1core+multi_harts)
用tcl,通过telnet连接openocd,与JTAG_DPI连接,JTAG_DPI的verilog model 例化在testbench中,DUT是riscv的core,具有JTAG的调试接口,遵循riscv-debug-spec
这个文章的介绍只是我操作过程中的一些理解和整理,也有很多不涉及的或者有偏差的地方,如果大家又发现问题,可以随时私信沟通交流,多谢。
需要了解的基础知识,此处不做介绍:
- Riscv-spec
- Riscv-spec-privileged
- Riscv-debug-stable
- JTAG spec
- Openocd user guide
- Openocd如何通过JTAG_DPI和VCS 仿真连接,网络有教程
我是用的下边的JTAG_DPI
GitHub - yaozhaosh/e200_opensource: The Ultra-Low Power RISC Core
About (OpenOCD User’s Guide)
如何连结和调试
配置target.cfg 文件
##配置interface,bitbang和jtag_dpi相连,telnet_port是telnet和openocd相连
interface remote_bitbang
##注意,bitbang的host和port要和jtag_dpi设置为相同的配置
remote_bitbang_port 44853
remote_bitbang_host t01n70
tcl_port 6667 #自行更改
telnet_port 44441 #自行更改,如果是window界面,可以在windows打开telnet服务
##以下是配置chipname和tap_ID
if { [info exists CHIPNAME] } {
set _CHIPNAME $CHIPNAME
} else {
set _CHIPNAME riscv
}
if { [info exists CPUTAPID ] } {
set _CPUTAPID $CPUTAPID
} else {
## 以下设置jtag tap的IDCODE
set _CPUTAPID 0x****
}
## 设置jtag的new_tap
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id $_CPUTAPID
set _TARGETNAME $_CHIPNAME.cpu
## 根据该core的harts的情况配置target,认为每一个hart 都是一个target
## 为何除了hart5,其他都是defer-examine,因为本方案每次调试只会启动一个hart,其他的都是sleep状态,所以不需要其他core 做examine;
target create $_TARGETNAME.hart0 riscv -chain-position $_TARGETNAME -coreid 0 -rtos hwthread -defer-examine
target create $_TARGETNAME.hart1 riscv -chain-position $_TARGETNAME -coreid 1 -rtos hwthread -defer-examine
target create $_TARGETNAME.hart2 riscv -chain-position $_TARGETNAME -coreid 2 -rtos hwthread -defer-examine
target create $_TARGETNAME.hart3 riscv -chain-position $_TARGETNAME -coreid 3 -rtos hwthread -defer-examine
target create $_TARGETNAME.hart4 riscv -chain-position $_TARGETNAME -coreid 4 -rtos hwthread -defer-examine
target create $_TARGETNAME.hart5 riscv -chain-position $_TARGETNAME -coreid 5 -rtos hwthread -defer-examine
target create $_TARGETNAME.hart6 riscv -chain-position $_TARGETNAME -coreid 6 -rtos hwthread -defer-examine
target create $_TARGETNAME.hart7 riscv -chain-position $_TARGETNAME -coreid 7 -rtos hwthread -defer-examine
## 一些其他配置
gdb_report_data_abort enable
gdb_report_register_access_error enable
riscv set_command_timeout_sec 120
## 当hart5 examine结束之后,立刻halt该hart
$_TARGETNAME.hart5 configure -event examine-end {
halt
}
############ target.cfg 配置完成。
跑起vcs仿真,(仿真截止时间一定要长,应为jtag 输入实在太慢了)
## -d 可以打出很多debug的信息,感觉非常有用,打出log文件,可以不用trace屏幕了
openocd -f target.cfg -d -l my.log
## 用telnet连接
telnet host port_number
## 连接成功之后,可以在命令行调试;
我做的调试命令是
##打印出当前的targets都有哪些
targets
##选中要调试的hart,不然会处于hart7
targets riscv.cpu.hart5
##可以看到current target是不是hart5,如果是可以做后续调试
target current
##查看hart5是不是处于halted状态,或者,当前是处于什么状态;
riscv.cpu.hart5 curstate
## 可以做hartreset,这个需要根据自己的需求自定义
## 这个proc是设置起始地址和hartreset,haltreq,hartreset之后会进入到debug mode ## 该proc完成后,可以做step,或者是设置硬件断点 proc halted_hartreset_halt {target data0 data1 dmcontrol} { set CurS [$target curstate] if { $CurS eq "halted" } { set dmctrl_ori [riscv dmi_read 0x10] set dmctrl_new [ expr $dmctrl_ori | $dmcontrol ] riscv dmi_write 0x05 $data1 riscv dmi_write 0x04 $data0 riscv dmi_write 0x10 $dmctrl_new riscv dmi_read 0x11 riscv dmi_read 0x10 } } |
##hartreset之后
## 设置单步执行,该命令会设置dcsr的step位域,然后resume,执行一条指令,理论上会再次进入debug mode
step
## 查看该hart 的状态,一般是halted
riscv.cpu.hart5 curstate
## reg 可以通过abstract command的register access的方式读取hart内部的寄存器
## 读取dcsr
reg dcsr
## 给x1 写入0x20 (一般不会这么用)我的工程主要是read
reg x1 0x20
## 设置硬件断点,地址,asid,字节数,hw,4个option
bp 0x000000000010001c 0 4 hw
## 断点设置成功之后,resume,然后再断点进入debug mode
resume
## 如果想要设置第二个断点,先要remove所有的断点,然后再设置
## remove bp,不会对tdata2 清零,要注意;
rbp all
## exit,调试结束
exit
一些中间过程需要关心,记录
调试之前会做target examine,只有完成target examine之后,后续的调试命令才能被识别,否则openocd会报告当前的target还没有被examine
通常target的examine主要做的流程是:(假如只启动某一个调试hart的examine)
- 读取dtmcs这个DR,获取DM集成的一些信息;
- Allocate new DM,deassert dmactive,然后assert dmactive
- 枚举hartsel,写入hasel和hartse*,hartse*为最大值,检查当前DM支持的最大hart个数;如果写入的hartse*不支持,会汇报 noexistense的dmstatus,随后读取dmcontrol,观察真实写入的hartse*是多少;
- 随后分别读取hartinfo,sbcs,abstractcs这些DMR,看是否支持,如果支持,获取这些DMR的各个域段的值;以观察DM支持的feature;
- 如果发现有havereset位域置位,则通过ackhavereset,进行握手;
- 从0开始一直遍历到最大的hartsel*,看当前的DM支持的hart的范围;
- 因为当前启动的是某个线程,所以后续针对这个线程开始做后续步骤;
- 如果当前hart 是running状态,设置haltreq,挂起该hart;
- Polling该hart的dmstatus,直到有anyhalted的状态,可以认为hart已经进入debug_mode;如果已经进入,则deassert haltreq;
- 然后通过abstract command的方式读取GPR x8,
- 通过abstract command的方式读取CSR_misa,观察当前支持的ISA如何;
- Create register cache;
- 根据misa不同可能后续还会有其他的操作,我的调试支持的只有64I,之后不需要读取其他信息了;
- 发送resume,等polling dmstatus,收集到anyrunning和anyresumeack之后认为resume成功,deassert resume,完成examine的过程;
Step这个操作会
- 如果还未设置过硬件断点,step首先会检测trigger情况,通过遍历tselect,看写入的和读出的是否一致,如过不一致,可以列举出支持的trigger的个数;
- 随后读取tdata1,看当前tdata1支持的control type,决定后续如何加断点trigger的控制
- 随后读取dcsr看当前的状态
- 如果step位域不是1,则设置该位域;
- 发送resume,唤起hart
- 通常执行完一条指令,则会再次进入到debug mode
bp 这个命令
通过访问tselect,tdata1和tdata2 做相关的trigger的配置
我的方案是支持1个硬件指令断点,tdata1的type位域是2;
resume
该操作会清除dcsr的step位域,解除单步的设置,直到响应了断点,或者haltreq
rbp all
清除所有的trigger设置,对tdata1 清零,但不会改变tdata2的值
用telnet+openocd+jtag_dpi+vcs仿真调试RISCV的cpu相关推荐
- 用telnet+openocd+jtag_dpi+vcs仿真调试RISCV的cpu(二,不同cpu的TAP菊花链连接,2TAP)
背景: 在之前相关文章的基础上,有两个多线程(hart)的cpu,每个cpu都有一个jtag(TAP)的debug module(DM),通过菊花链相连(测试了一共有2个TAP的情况),再用下risc ...
- Linux 运行vcs仿真命令,VCS使用以及命令行调试
最近在学习VCS,现将VCS的一些使用心得记录下来. VCS是synopsys的仿真verilog的仿真器.基于linux系统.有命令行模式和图形化模式.图形化模式是用的dve. 以串口verilog ...
- ise仿真添加信号_「干货」推荐一款FPGA仿真调试鸟枪换炮的工具
俗话说,隔行如隔山.非微电子专业没有做过芯片的同学,是不知道这个世界上还有效率更高的用来对Verilog/VHDL代码进行仿真的工具的.具体来讲,对于做FPGA开发的同学而言,需要知道除了ModelS ...
- RV-LINK:GDB 使用 RV-LINK 仿真器调试 RISC-V 程序
RV-LINK:GDB 使用 RV-LINK 仿真器调试 RISC-V 程序 https://blog.csdn.net/zoomdy/article/details/101456186 zoomdy ...
- Synopsys VCS仿真编译选项
VCS仿真编译选项 1. 扩展选项 2. 自带编译选项 1. 扩展选项 1. +vcs+line+wait:一直等待license. 2. +maxdelays/+mindelays:使用SDF文件中 ...
- gdb 调试 RISC-V
优秀的产品需要有高效的调试手段,RISC-V的工具链中提供GDB. 使得切换到RISCV后,底软和内核工程师的工作效率不受损害. 我们使用一个有趣的程序来尝试gdb调试的效果.源文件 rot13.c ...
- Keil5的仿真调试
Keil5基本的仿真调试操作: 首先点击魔法棒 然后输入你板子上所用的晶振,然后进入debug: 然后选择 Use Simulator,然后点击OK: 然后点击调试按钮: 然后就会出现调试页面: 我这 ...
- Apollo星火计划学习笔记——参考线平滑算法解析及实现(以U型弯道场景仿真调试为例)
文章目录 1. Apollo参考线介绍 1.1 参考线的作用 1.2 导航规划的路线 1.3 为什么需要重新生成参考线 1.4 ReferenceLine数据结构 1.5 ReferencePoint ...
- 使用VCS 仿真后,通过DVE 观察波形,多维数据显示not load问题及解决方案
版权声明:本文为CSDN博主「Silent_Majority」的原创文章,遵循CC 4.0 by-sa版权协议,转载请附上原文出处链接及本声明. 原文链接:https://blog.csdn.net/ ...
最新文章
- Linux 下的动态库、静态库与环境变量
- Oracle 9i 升级至Oracle10g数据库最好的方法
- Java中栈、堆和常量池
- Node.js 开发指南笔记
- 130242014076+陈旭+第3次实验
- ML之NB:利用NB朴素贝叶斯算法(CountVectorizer/TfidfVectorizer+去除停用词)进行分类预测、评估
- 微信小程序学习笔记(四)
- wstring 截取_StringUtils截取字符substringBefore等方法使用
- ipv6转换成ipv4_IPv6协议及其安全浅析
- 在VMware 14中安装Centos7
- VMware vSphere 6.7主机与虚拟机高级管理
- C++中-运算符与.运算符的具体使用
- VSCode 上竟然也能约会,谈对象了???
- 天平应什么放置_电子天平,你不得不知道的那些事!
- 可变车道怎么走不违章_还记得这种车道怎么走吗?
- 第三次修正打坐的姿势
- python微信定时发送消息
- 解决Spark数据倾斜(Data Skew)的 N 种姿势 与 问题定位
- Python爬虫:(亲测,已解决!)解决在使用谷歌浏览器的开发者工具时,没有Referer防盗链缺失问题。
- 指针详讲(一阶指针和二阶指针等指针各种用法详解)