基于Verilog实现通过JTAG接口对zynqPS和PL程序重构 ------理论部分

概述

        本文档描述了基于JTAG协议的Zynq SoC重构加载控制逻辑。该控制器使用Verilog语言实现,可部署于CPLD或FPGA平台,负责加载Zynq器件的PL端和PS端程序。当前实现中,PL端支持全局配置比特流文件的加载;PS端支持加载并运行Zynq FSBL(First Stage Bootloader)和u-boot启动程序,并且在FSBL加载完成后,能够加载并执行任意的ELF格式可执行文件映像。

完整工程文件下载:Verilog实现JTAG加载重构PS PL源码 (点击蓝色字体获取)

取件码:6qhr


一、介绍

        Zynq SoC的常规启动模式包括QSPI、SD卡等,其中JTAG启动模式通常用于与调试主机的连接,配合Vivado和SDK软件加载需要调试的程序。本文介绍的控制器能够实现JTAG启动模式下的无外部干预加载运行,适用于Zynq硬件设备的备份启动、量产测试等场景。

        理解本文内容要求读者具备对JTAG协议时序及其状态机的基本了解,并熟悉Zynq SoC的功能架构及PL/PS之间的关系。此外,读者还应了解Zynq BootROM、FSBL和u-boot的功能及其启动流程。这些内容在我之前的文章也都进行过讲解,不懂的可以去翻阅一下之前的文章。

        用户需自行准备适用于PL配置的bitstream文件,以及FSBL和u-boot的ELF文件。不同硬件电路的映像文件不可互换。

二、基本原理

        Zynq器件中的调试接口为JTAG,按照协议,共串联了两个JTAG控制器,其一为Xilinx TAP控制器,用于对PL部分进行操作;其二为ARM DAP控制器,用于对PS部分进行操作。两者除底层JTAG协议外,工作方式完全独立,需要按照各自的控制协议进行访问。

        Xilinx TAP是第一个设备,其IR长度为6bit,IDCODE为0x23727093(XC7Z045,其他设备会不同)。TAP的主要参考资料为:

  1. 《UG470 - 7 Series FPGAs Configuration User Guide

ARM DAP是第二个设备,其IR长度为4bit。IDCODE为0x4ba00477。DAP的主要参考资料为:

  1. 《ARM Debug Interface Architecture Specification ADIv5.0 to ADIv5.2
  2. 《ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition

        Zynq的JTAG内部连接关系如下,正常模式下使用的是PL JTAG接口,MIO PJTAG和EMIO PJTAG都是未选通的。由于JTAG的IR和DR是LSB First的移位寄存器,TDI上先输出的比特进入到TAP,后输出的进入到DAP。

2.1 JTAG接口

JTAG的基本时序逻辑如下:

Xilinx TAP和ARM DAP均符合上述时序。

在之前的文章也有所介绍,在这里就不在进行讲解,可以翻阅一下之前的文章

Xilinx FPGA通过JTAG接口在线重构

2.2 TAP控制器

Xilinx TAP的实现相对简单,严格按照UG470 Table-10-4的操作序列执行即可。

在之前的文章也有所讲解,大家可以去看一下,本文章主要讲解DAP控制器的原理和实现。

2.3 DAP控制器

        ARM的DAP控制器相对复杂。首先DAP是一个通用规范,所有ARM结构处理器都采用这个接口作为调试用途。但每个ARM核心架构的调试寄存器接口均不同,需要参照各自的手册。就Zynq而言,应参照ARMv7-A。

2.3.1 DAP接口

        DAP接口对应ARM Debug Interface中的JTAG-DP。DAP接口包括一个DP和若干个AP。Zynq的实现提供了两个AP,其中AP0可以访问AHB系统总线,AP1通过APB接口访问Cortex-A的Debug接口。理论上AP0可以对整个地址空间进行操作,但缺少官方说明,目前所有的编程器都是采用通用方式,通过AP1接口间接访问所有资源。

DAP上实现的指令清单:

表 1 DAP JTAG IR指令清单

IR指令

二进制值

DR位宽

用途

ABORT

1000

35

中止指令

DPACC

1010

35

访问DP

APACC

1011

35

访问AP

IDCODE

1110

32

读取IDCODE

BYPASS

1111

1

BYPASS模式

主要操作通过DPACC和APACC指令进行。DAP的主要访问数据位宽是35位,其中前3位是操作码,后32位是数据。所有读写都是以32bit为单位。

表 2 DPACC和APACC指令的DR数据格式

DATA[34:3]

DATA[2:1]

DATA[0]

32位数据

访问地址,需要*4作为实际地址

0 - 读操作

1 - 写操作

MSB后传输

LSB先传输

根据DPACC或者DPACC指令,DATA[2:1]*4表示的地址对应寄存器定义为:

表 3 DP和AP的寄存器清单

DPACC

地址

寄存器

功能

0x4

CTRL/STAT

控制/状态

0x8

SELECT

选择AP通道

0xC

RDBUFF

读取前一次读操作的结果

APACC

地址

寄存器

功能

0x0

CSW

访问控制

0x4

TAR

目标地址

0x8

RSV

0xC

DRW

读写数据

DPACC指令对应的寄存器主要进行DAP接口的功能控制如使能和禁用等。SELECT寄存器选择访问哪个AP及AP的哪个bank。

APACC指令用于访问SELECT选定的AP,其中TAR用于设定APB总线地址,DRW则为读写的数据。CSW控制访问属性如地址自增等。

通过DPACC+APACC配合使用,可以间接访问APB上按地址映射的资源,也就是Cortex-A的Debug接口。

DP和AP的详细定义参见ARM Debug Interface Architecture Specification ADIv5.0 to ADIv5.2》。关于AP的实现信息参见《UG585 - Zynq 7000 SoC Technical Reference Manual》Chapter 27 JTAG and DAP Subsystem

2.3.2 ARM Debug接口

大部分ARM处理器都提供了Debug接口,其中包括一定数量的寄存器可以进行调试相关的操作。具体到Zynq,其实现了Cortex-A的Debug Interface Registers。Debug接口的具体定义参见ARM Architecture Reference Manual ARMv7-A and ARMv7-R edition》 Chapter C6 Debug Register Interfaces.

表 4 ARM Debug接口主要寄存器清单

地址偏移量

寄存器

功能

0x80

DTRRX

用于配合指令进行Host到CPU的数据传递

0x84

ITR

用于写入要执行的指令机器码

0x88

DSCR

调试状态和控制寄存器

0x8C

DTRTX

用于配合指令进行CPU到Host的数据传递

0x90

DRCR

调试运行控制寄存器,控制Halt和Restart

zynq包括两个Cortex-A核心,每个核心有一套独立的Debug寄存器接口,可以单独控制。Zynq的两个核心的Debug接口APB地址分配未在官方文档提及,但通过解析源码得到以下信息:

表 5 Zynq Debug接口APB地址映射

CPU

Debug接口基地址

功能

CPU.0

0x80090000

CPU0 Debug接口

CPU.1

0x80092000

CPU1 Debug接口

由于启动阶段仅使用CPU0运行fsbl和u-boot,所以基本上只使用位于0x80090000的CPU0 Debug接口。例如:APACC的TAR寄存器写入0x80090080是访问CPU0.DTRRX;写入0x80090090是访问CPU0.DRCR。

利用上述Debug接口寄存器可以对CPU的运行/挂起进行控制,并通过数据传递寄存器和指令寄存器执行任意CPU指令。

2.3.3 C14协处理器

        利用ITR寄存器可以执行任意ARM指令。对于调试功能来说最常用的是CP14指令。CP14指ARM第14号协处理器,该协处理器用于Debug功能,主要是在Host和CPU之间传递数据。利用CP14指令,可以在DTRRX和CPU通用寄存器(R0~R15)之间传递数据。

CP14指令一共有5条:

表 6 CP14指令集概要

指令

功能

CDP

协处理器寄存器到协处理器寄存器的数据操作

LDC

将源寄存器内容所指的存储器数据读取到目标寄存器

STC

将源寄存器内容写入到目标寄存器内容所指的存储器地址

MCR

将ARM处理器源寄存器内容传送到协处理器目标寄存器

MRC

将协处理器源寄存器内容传送到ARM处理器目标寄存器

加载功能主要实现的是将程序区段(segment)写入到其对应的内存地址。这个目标可以利用STC指令实现。ARM为了方便调试加载操作,在DSCR寄存器设置中,提供了FAST_MODE,在该模式下起始地址首先写入R0寄存器,然后STC指令写入ITR,之后的每次DTRRX写入都会自动执行STC指令并自增地址,从而顺序写入程序数据。

完成程序写入内存后,再将程序入口地址写入R0寄存器,并执行一条通用指令“B0”,表示跳转到R0寄存器指向的地址运行。然后设置DRCR为Restart,程序将从设定的入口地址开始执行。

三、总结     

        本篇文章详细介绍了基于JTAG接口的zynq重构加载的理论部分,重点讲解了DAP接口、ARM Debug接口及C14协处理器指令的工作原理,并阐述了如何通过JTAG进行Zynq的程序加载和调试控制。通过深入分析Zynq的调试寄存器及其操作方式,本文为开发者提供了理解Zynq调试架构和调试流程的理论框架。

        下一篇将发布关于Verilog代码实现的文章,详细介绍如何基于本文所述的理论内容,使用Verilog语言实现相关的Zynq控制器。这一实现部分将深入探讨Verilog代码的具体设计和应用,帮助读者进一步掌握如何在硬件层面上实现JTAG启动和调试控制。

敬请期待下一篇文章,进一步了解Verilog代码实现的技术细节。

如有兴趣进一步深入了解FPGA和Zynq设计方面的应用,欢迎关注相关技术分享和实际项目案例,涵盖多种规模的设计实践。通过分享实际设计经验,帮助开发者更高效地实现各种定制化的硬件解决方案


Verilog代码实现文章已经更新!! 下面为快捷链接

基于Verilog实现通过JTAG接口对zynqPS和PL程序重构 ------代码实现部分-优快云博客

完整工程文件下载:Verilog实现JTAG加载重构PS PL源码 (点击蓝色字体获取)

取件码:6qhr

如果感觉文章对您有用,麻烦三连支持一下,方便下次用到的时候,就可以快速找到我,非常感谢您的支持!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值