概述
传统fpga逻辑工程师要开始进行基于SoC的fpga设计,确实有一些难题。这一系列的文档大致记录下本人学习SoC开发的一些历程,根据设计文档跑了一些例程,记录这些参考设计学习的过程,以便随时“温故知新”。本文简单讲述如何利用System Console工具来对SoC设计硬件进行调试,这里假设FPGA硬件已经搭建完成(Altera合作伙伴的各家开发板,也包括Altera自己的开发板都有典型的Golden参考设计,即所谓的GHRD工程)。
学习简述
位于fpga内部的ARM处理器的行为,本质上来说和位于fpga外部分立的ARM芯片并无差别。工程师拿到一片SoC fpga可以将其看做一片普通的fpga,也可以将其看做一片普通的ARM芯片,当然系统工程师是将二者集成一起看待。所以对于传统的fpga工程师来说,可以认为arm不存在一样去进行fpga设计。直到软件工程师完成软件设计并将软件下载到处理器,处理器复位之后跳转到位于Flash之中的复位入口。
fpga工程师利用Qsys工具完成逻辑设计,在HPS周边添加了不同的IP单元,比如LED,拨码开关等等。在处理器运行程序之前,硬件工程师可以利用System Console工具来对这些元件进行验证。如图1所示,就是一般的SoC系统硬件架构,我们可以利用JTAG到Avalon桥(master,图中黄色设备)来访问Avalon总线上的所有元件,这时候我们可以作为一个主设备来访问总线上的所有从设备。
图1:SoC GHRD工程结构框图
如图1所示,系统中此时已经例化了HPS处理器核,只是此时我们还无法对其进行访问,因为这是还没有任何代码在处理器中运行。笔者在介绍基于Qsys的PCIe设计中就提到过,在利用Qsys进行fpga设计的时候不再需要处理器的介入,这里其实我可以将HPS看做不存在一样,只是因为我们后面还要进行HPS软件设计的学习,所以fpga硬件工程中事先例化后了HPS核。
启动SystemConsole并对FPGA进行编程
我们打开GHRD工程,并打开Qsys软件,在Qsys软件中打开之前已经例化好的系统,即soc_system.qsys。这里不再详述。
我们可以从Qsys软件的Tool菜单里启动System Console工具,如果开发板(笔者使用的是Arrow的SoCkit开发板)连接状态正常,且已上电,那么我们可以在System Console工具中看到JTAG链上的器件连接情况,如图2所示,如果看不到,可以从System Console的Tool菜单中执行“Refresh Connection”命令刷新(该命令也可以直接鼠标右击图2中的connection文件夹找到)。
图2:在System Console中查看板子连接状态
System Console是基于TCL脚本设计及操作,所以后面的很多操作、命令都将使用类似虚拟JTAG中我们使用到的命令。首先我们来看器件服务,在脚本命令输入行敲入“get_service_paths device”命令,那么随后命令行窗口会列出链路上所有的器件,这里我们只有一块板子连接在JTAG链,所以如图3所示会给出一个器件。
图3:列出JTAG链路上所有器件
下面对上述链路上的器件进行编程,在此之前我们需要定义一个变量来存放访问目标。使用的命令为:
set d_path [lindex [get_service_paths device] 0]
注意lindex会索引路径上所有的器件,这里因为只有一个器件,所以我们将索引号为“0”(即第一个器件)的器件作为目标赋值为一个变量。那么接下来我们可以直接使用程序下载命令对该变量指向的目标器件进行编程了,具体如图4所示。
图4:定义目标变量并对目标进行编程
当然,我们也可以直接使用鼠标操作来完成器件编程,如图5所示,鼠标右击device文件夹,在弹出的菜单中选择编程器件即可。
图5:直接通过鼠标操作来完成器件编程
器件编程完成后,除了我们在设计中加入的测试程序来对编程操作进行验证外,在System Console的消息窗口中会有消息提示,编程完成后会在消息窗口提示:
Auto linking 5CSEBA6(.|ES)|5CSEMA6|..@1#USB-1#CV SoCKit to soc_system.sof
器件下载程序之后,此时我们如果展开device文件夹,那么就会看到我在Qsys中添加的各个元件,如图6所示。
图6:板子下载程序后
利用SystemConsole工具检验时钟和复位
我们再次使用“get_service_paths”命令,不过这次是获取JTAG调试服务。同样该命令会反馈并列出链路上所有的JTAG调试任务,其实图6中已经在“link”文件夹中为我们显示了JTAG调试任务了。如图7所示,执行该命令后结果。
图7:获取JTAG调试任务
图7以及图6中并未完全为我们展示这些任务,其实我们可以展开发现这三个任务分别是fpga only master、hps only mster以及f2sdram only master。为了检验系统的时钟和复位,这里我们需要通过fpga only master来对时钟和复位元件进行访问,这里定义一个变量来指向fpga only master。和之前的命令一样,这里需要用到lindex索引命令,索引号为0,这里我们指向的并不是fpga only master(不过没有关系,只要打开JTAG调试即可,这里为了测试,打开了另外一个调试任务)。具体命令及其执行情况如图8所示。
图8:定义变量并指向fpga only master
为了验证JTAG链路的信号完整性,可以使用jtag_debug_loop命令向链路串入一些特定码来进行验证。如图9所示:
图9:串入特定码进入jtag链来验证其信号完整性
下面来验证系统的时钟是否正常工作,我们可以使用的命令有两个,第一个命令是jtag_debug_sense_clock $jd_path。该命令就是简单检查时钟是否还在正常的翻转,如果是,那么返回值为“1”。
第二个命令是jtag_debug_sample_clock $jd_path。这个命令会采集当前时钟信号的值,由于时钟翻转速度很快,所以我们需要执行很多次该命令才能采集到不同的值(即0和1),只要时钟还在正常翻转,那么使用这个命令我们就应该能分别采集到0和1,如图10所示。
图10:验证系统时钟
本节最后来看看如何在System Console中验证系统的复位信号。使用的命令是jtag_debug_smaple_reset $jd_path。和时钟验证的第二个命令一样,该命令采集的是复位信号的当前值,开发板的复位信号是低有效,所以在未按下复位按钮的时候,采集回来的值应该是1,如图11所示。同时,通过命令行设计者还可以给整个系统发送一个系统复位,具体格式如图11所示。
图11:验证系统的复位以及给系统发送一个复位
利用SystemConsole工具访问FPGA的外设
访问fpga的外设是通过执行master read和master write来完成的。首先,我们需要获取可以利用的master服务,如图12所示执行get_service_paths master来获取。
图12:获取fpga已实现的master服务
大家注意图12与图7的差别,这里还是先定义一个变量来指向fpga only master服务路径,注意这里的lindex索引号应该为1,因为我们要指向fpga only master,如图13所示。
图13:定义变量指向主设备服务
如果使用索引号0打开的就是如图14所示为f2sdram only master。
图14:索引0指向的主设备服务
和虚拟jtag一样,访问设备(或服务)之前都要先打开设备,这里打开主设备服务,如图15所示。
图15:打开主设备服务
设备(服务)打开后,设计者就可以对其进行操作了。这里我们只对板子上的LED以及拨码开关进行读写操作。首先操作LED,打开Qsys系统,找到LED元件的基地址,然后执行如下命令:
master_write_memory $m_path 0x10040 0xf,该命令熄灭所有LED;
master_write_memory $m_path 0x10040 0x0,该命令点亮所有LED;
master_write_memory $m_path 0x10040 0xc,该命令点亮LED 0和1,熄灭LED 2和3;
master_write_memory $m_path 0x10040 0xa,该命令点亮LED 0和2,熄灭LED 1和3。
如果不执行图15所示打开命令,那么在执行上述命令的时候会报错,如图16所示:
图16:未打开设备服务的时候不能执行读写操作
由于led_pio元件宽度是4个比特,所以我们还可以使用master_write_8、master_wirte_16或master_write_32命令来获得相同结果。
以上介绍了master write命令,我们还可以使用master read命令来读取拨码开关上的当前值。从Qsys中获取dip_sw_pio的基地址后就可以执行读取操作了,如图17所示。
图17:读取操作
注意,返回数据格式与读取命令位宽一致。
小结
最后小结一下,以上只是在使用Qsys完成逻辑设计的基础上,使用System Console工具对于ARM核外设进行初步验证。比如使用JTAG链执行了底层的验证及对FPGA进行编程(下载sof文件);对于系统的时钟和复位信号进行底层的验证;使用System Console工具执行了master读写命令。这些验证或操作都“旁路”了ARM核,但是被操作的外设又都挂在了ARM上,也即我们可以在ARM核工作起来之前利用模拟的方式对其部分外设进行验证;也就是说利用这个工具,逻辑工程师可以在软件工程师编写完软件之前就可以对处理器的外设进行验证。