精华内容
下载资源
问答
  •  目前实现加载的方法通常有两种:一种是用专用Cable通过JTAG口进行数据加载,另一种是外挂与该FPGA厂商配套的PROM芯片。前者需要在PC机上运行专用的加载软件,直接下载到FPGA片内,所以掉电数据仍然会丢失,只适用...

          基于SRAM结构的FPGA容量大,可重复操作,应用相当广泛;但其结构类似于SRAM,掉电后数据丢失,因此每次上电时都需重新加载。

          目前实现加载的方法通常有两种:一种是用专用Cable通过JTAG口进行数据加载,另一种是外挂与该FPGA厂商配套的PROM芯片。前者需要在PC机上运行专用的加载软件,直接下载到FPGA片内,所以掉电数据仍然会丢失,只适用于FPGA调试阶段而不能应用于工业现场的数据加载。

          后者虽然可以解决数据丢失问题,但这种专用芯片成本较高,供货周期也较长(一般大于2个月),使FPGA产品的开发时间受到很大约束。因此希望找到一种更简便实用的FPGA芯片数据加载方法。根据FPGA芯片加载时序分析,本文提出了采用通过市面上常见的Flash ROM芯片替代专用PROM的方式,通过DSP的外部高速总线进行FPGA加载;既节约了系统成本,也能达到FPGA上电迅速加载的目的;特别适用于在FPGA调试后期,待固化程序的阶段。下面以两片Xilinx公司Virtex-4系列XC4VLX60芯片为例,详细介绍采用TI公司的TMS320C61416 DSP控制FPGA芯片数据加载的软硬件设计。

          1 Xilinx FPGA配置原理

          Virtex-4系列的FPGA芯片外部配置引脚MODE PIN(M0、M1、M2),有5种配置模式,如表1所列。

          FPGA在Slave SelectMAP方式下,共用了表2所列的15个配置引脚。

          1.1 配置流程

          FPGA加载时序如图1所示。各配置信号必须满足其时序关系,否则配置工作无法正常完成。





           图1中,Slave SelelctMAP加载主要包括以下3个步骤:

          ①启动和初始化。FPGA上电正常后,通过PROG_B引脚低脉冲进行FPGA异步复位,使得FPGA内部逻辑清零。其次PROG_B上拉高,停止外部复位,INIT_B引脚会在TPOR时间段内自动产生一个由低到高的跳变,指示FPGA内部初始化完成,可以进行数据下载;同时FPGA在INIT_B的上升沿采样其模式引脚MODE PIN,决定其模式配置。

          ②比特流加载。INIT_B信号变高后,不需要额外的等待时间,Virtex器件就可以立即开始数据的配置。比特流数据在外部CCLK信号上升沿按字节方式置入。该过程包括同步初始化字、器件ID号校验、加载配置数据帧、CRC校验4个部分。

          ③STARTUP启动。在成功校验CRC码位后,比特流命令使得FPGA进入STARTUP状态。它是由8相状态机实现的。中间包括等待DCM锁相、DCI匹配等几个状态,最后FPGA释放外部DONE引脚,对外输出高阻态,由外部上拉高,指示FPGA加载成功。

          1.2 文件生成

          ISE生成数据文件主要有3种:BIT文件,由二进制格式进行表征逻辑设计,包括文件头和配置数据,主要用于JTAG下载电缆模式;MCS文件,为外部PROM烧写生成的下载文件,ASCII码,与前者不同的是它含有在PROM中的数据地址和校验值;BIN文件格式,由二进制表示,完全由配置数据组成,不需要作其他的提取和进制转换,只是配置前的Byte-Swapped是在CPLD中实现的。本设计采用的是BIN文件格式。

          2 硬件实现

          系统采用2片Xilinx Virtex-4系列的600万门的FPGA XC4VLX60。主MCU是TI公司高性能定点处理器TMS320C6416,对外有2个EMIF总线接口,分别是64位宽EMIFA和16位宽EMIFB。EMIFB上挂有8位8MB的Flash和16位CPLD:Flash做2片FPGA的BIN文件保存,之前由仿真器烧写;CPLD用于2片FPGA地址译码和DSP与FPGA配置部分的逻辑接口。整个数据流程是在DSP上电启动后,Bootloader自行引导用户程序运行。该程序负责由EMIFB总线搬移Flash空间中BIN文件,通过CPLD分别对2片FPGA进行配置加载。硬件系统拓扑图如图2所示。

          3 软件设计

          软件包括3部分:引导Bootloader代码,加载FPGA用户程序以及接口部分的CPLD Verilog代码。

          3.1 DSP Bootloader

          本系统中目标板处于FPGA调试后期,需要固化其加载程序。整板上电后,要求脱离仿真器自行加载FPGA,因此这里采用DSP的EMIF BooT方式。它是由DSP上电复位后,以默认ROM时序通过EDMA自行搬移BCE1的ROM空间前1 KB内容到片内,在其0x0地址开始运行。

          一般由C编写的程序代码长度都远大于1 KB,如果只是纯粹由DSP搬移Flash前1 KB空间,这样便会丢失数据,程序无法正常运行。这里采用由汇编语言写的一个两次搬移的Bootloader程序,来引导较大的用户程序。使用汇编语言是因为其代码效率高,代码长度短(本系统中只有256字节)。两次搬移是因为第一次DSP自行搬移后的Bootloader会占用片内的0x0地址前1 KB空间,与下一步的用户程序0x0地址拷贝冲突(中断向量表必须放在0x0地址,否则会丢失中断跳转的绝对地址),且运行中的Bootloader不能覆盖自身。所以把拷贝用户程序的那部分代码放在片内较底端运行,腾出了用户空间的0x0地址。最后整体拷贝结束后,Bootloader再跳转到用户程序入口地址c_int00运行。

          3.2 用户程序和CPLD程序

          本系统中2片FPGA加载的原理一样。为避免繁琐,这里以1片FPGA_A为例来作介绍。

          CPLD在系统中负责2项工作。

          ①映射DSP端Flash分页寄存器:控制Flash的高3位地址线,分8页,每页1 MB空间。
          ②映射DSP端2片FPGA的加载寄存器:

          a.配置寄存器FpgaA(B)_config_Reg[8:O]。负责配置数据和时钟,高8位为Byte-Swapped前的数据位,输出到配置引脚时进行字节交换,最低位为CCLK位。
          b.控制寄存器FpgaA(B)_Prog_Reg[2:O]。负责外部控制引脚,分别为CS_B、RDWR_B和PROG_B。
          c.状态寄存器FpgaA(B)_State_Reg[2:0]。负责回读配置中的握手信号,分别为BUSY、DONE和INIT_B。  
     
          由Bootloader引导的用户程序由C语言开发,在CCS下调试通过。它主要实现Flash翻页,把之前烧写在Flash中的BIN文件,通过上述CPLD中3个加载寄存器对FPGA进行上电配置。具体流程如图3所示。

     

          当前FPGA配置时钟CCLK是在用户程序中通过DSP写命令产生的,即写FpgaA(B)_Config_Reg的CCLK位高低电平;同时8位配置数据也连续写2次,由CPLD锁存到FPGA总线上,便能充分保证图1中该有效数据在CCLK上升沿上被锁。

          以下是CPLD中动态加载部分的Verilog代码:

          //FPGA控制寄存器(DSP只写)

     



          结 语

          该系统已成功用于某公司一款软件无线电平台中,通过反复软硬件调试,现已投放市场。此外,由于该系统中的DSP芯片TMS320C6416自带PCI桥,因此该平台设计有与主机通信的CPCI接口,支持32位的PCI总线带宽,最大数据吞吐率能达到133 MB/s。所以,此平台不仅可以实现上述提到的上电Flash自行加载FPGA的目的,还可在其配置完以后通过主机端对FPGA实现动态加载,充分满足了软件无线电中可重构化、实时灵活的指导思想

    展开全文
  • 作者:左颢睿 李焱 马艳 来源:单片机与嵌入式系统应用 摘 要:以TMS320VC5410为例,介绍对Am29LV200B Flash存储器进行程序分页烧写以及上电后多页用户程序并行自举的方法。对多页Flash存储器的烧写,须在烧写...
      
    

    作者:左颢睿 李焱 马艳 来源:单片机与嵌入式系统应用 
     
     

     
     
    摘 要:以TMS320VC5410为例,介绍对Am29LV200B Flash存储器进行程序分页烧写以及上电后多页用户程序并行自举的方法。对多页Flash存储器的烧写,须在烧写过程中对已烧写的数据长度进行动态判断,当达到预定烧写长度后对Flash进行换页,然后继续烧写,重复上述换页过程,直到程序烧写完为止。对多页程序的并行自举,在系统上电后,利用TI提供的自举程序,将一个用户自己编写的前导程序载入DSP,利用该前导程序将多页程序载入DSP来实现程序的自举。此方法适用于多种FIash芯片和 C5000系列DSP。
    关键词:TMS320VC5410 Am29LV200B DSP 多页并行自举


      TI公司的DSP芯片TMS320Vc5410(简称5410)是性能卓越的低功耗定点DSP,在嵌入式系统中有着广泛的应用。5410没有自带的片上非易失性存储器,因此需要外部的非易失性存储介质,如EPROM或Flash,来存储程序和数据。5410片内有64 K字RAM,由于在片内RAM运行程序比片外运行有高速度低功耗等显著优点,通常上电后都需要从片外EPROM或Flash上加载程序到片内RAM,但是芯片自带的自举程序(简称Bootloader)只支持32 K字以内的外部程序加载,因此程序设计往往局限于32 K字空间内,限制了编程的灵活性,不能充分发挥5410的性能。当程序空问大于32 K字时,就需要自己编写程序来实现自举。下面首先介绍使用5410对Am29LV200BFlash存储器进行程序分页烧写的方法,然后重点介绍利用 Bootloader来编程实现多页并行自举引导的方法。

    1 Am29LV200B Flash 存储器的分页烧写
    1.1 FIash 存储器简介
      Am29LV200B(简称Flash)是AMD公司生产的Flash存储器,主要特点有:3 V单电源供电,可内部产生高电压进行编程和擦除操作;支持JEDEC单电源Flash存储器标准;只需向其命令寄存器写人标准的微处理器指令,具体编程、擦除操作由内部嵌入的算法实现,并且可以通过查询特定的引脚或数据线监控操作是否完成;可以对任一扇区进行读、写或擦除操作,而不影响其他部分的数据。文中128K×16位Am29LV200B Flash映射为5410的片外数据存储空间,地址为:0x8000~0xFFFF,数据总线16位,用于16位方式的并行引导装载。128K的 Flash被分为7页进行访问。本文通过DSP的I/O端口向FPGA写控制字,由FPGA控制Flash的换页引脚对各个分页进行访问;以烧写2个页面为例,使用Flash的第1、2页,初始化时选中第l页。

    1.2 Flash 存储器的分页烧写
      Flash的页面分配和相应的引脚控制如表1所列。关于Am29LV200B的擦除、写、校验等详细操作,请见参考文献[1]、[2]。

     


      从表1可以看到,通过对A16、A15等地址引脚的控制,可以实现Flash的页面切换。在烧写过程中,只要在指定页面烧写完预定空间后就对Flash进行换页,然后将烧写指针指向新的一页的首地址,就可以继续进行烧写,当程序烧写完成后需要将页面换回到第1页,在第1页的FFFFH地址写入8000H,这样Bootloader可以从这一页开始自举。整个烧写程序流程如图1所示。


      这里会出现一个问题:程序烧写好后,虽然Bootloader可以自动加载程序,但是Bootloader怎样在加载过程中自动换页?下面详细介绍利用片上Bootloader编程实现多页程序并行加载的方法。

    2 多页并行加载的实现
      实现多页加载,关键问题是要让Bootloader知道什么时候可以换页;但是Bootloader是固化在5410片上ROM内的,无法对其进行编程。解决的方法是通过自己编写一段“前导”加载程序(简称Loader)来实现加载中的换页:首先将Loader和用户程序都烧写到Flash中,当系统上电后,Bootloader将Loader加载到片上并运行,然后Loader将Flash中的用户程序加载到目标RAM空间。这个加载过程是用户编程可控的,因此在需要换页时,可以控制Flash进行换页,加载完成后,Loader跳转到用户程序的人口地址处运行用户程序。

    2.1 Bootloader的并行自举表结构和编程后的自举表结构
      5410的并行加载过程以及生成并行自举表的详细方法请见参考文献[1]、[3]。Bootloader使用图2所示的并行自举表来加载程序。 Bootloader从表头开始依次读取自举表,然后将相应的程序段加载到目标RAM,最后以程序段大小为0来结束自举表的读取,跳转到用户程序入口地址执行用户程序。从图2可以看到,Bootloader是以自举表中的程序长度为0来结束自举的,于是就可以利用这个特性,给Bootloader制造一个 “假象”,让Bootloader在加载完Loader程序后,认为程序已经加载完毕,然后开始运行Loader程序,继续加载用户程序。按照这个思路,可以建立图3所示的自举表。



      图3中的黑体字部分,是嵌入了Loader程序的自举表,有了图3这样形式的并行自举表,系统就可以实现多页程序的并行自举。建立这样的自举表很简单,只需要将hex500格式转换工具生成的Loader的并行自举表和用户程序的并行自举表按图3给定的格式,通过简单的文件操作合并在一起就可以了。注意: Loader程序要占用一部分RAM空间,用户程序空间不能和Loader的RAM空间重叠在一起。

    2.2 Loader程序的具体实现
      下面以分布在2个Flash页面的程序为例,给出5410并行自举的示例程序。程序中,当I/O端口5写人数据O时,选中Flash第1页;写1时选中第 2页。程序里用黑体字标出的注释部分,是Loader程序设计的重点或难点。(具体程序见本刊网站www.mesnet.com.cn——编者注)

      示例程序中,DSP上电后,Bootloader将Loader程序加载到RAM中,然后执行Loader程序:Loadelr程序从Flash第1页的 8080H开始读取用户程序自举表,当Flash读取计数值超过31 K时,将Flash切换到页面2,继续加载,自举完成后,跳转到用户程序入口地址执行用户程序。在编写自举程序过程中,有这样几个问题需要注意:

      ①在换页时,一般情况下程序段都会跨越两个页面,因此在确定需要换页时要计算出第1页和第2页分别要加载的段长度。
      ②整个用户程序段开始时有2个字的入口信息,每一个程序段都有3个字的段信息,因此需要在Flash读取计数时给予修正,才能正确加载数据。
      ③在确定需要换页时要将换页标志置为1,换页后要将换页标志置为0,而且换页后要将数据读取指针指向第2页的开头地址。

      如果要使用本文的示例程序,一定要将Loader程序烧写到Flash第1页8000H的位置,用户程序段烧写到8080H以后的位置。再次提醒, Loader程序加载到RAM中的地址,不能和用户程序段加载到RAM中的地址重叠。例如Loader使用了RAM中的7F80H~8000H这段空间,则用户程序不能使用这段空间,否则会出现错误。Loader的自举流程如图4所示。


    3 总 结
      要实现5410的多页程序并行自举,有如下几个步骤:
      ①根据用户程序的需求以及实际使用Flash的分页设置,参考第2部分提供的思路和例子编写Loader程序;
      ②使用hex500代码转化工具分别生成Loader程序和用户程序的自举表;
      ③将两个自举表按图2的格式生成一个新的自举表,再使用第1部分介绍的方法将新的自举表分页烧写到Flash上。

      使用本文介绍的方法,通过多次试验,系统上电后,能够很好地实现2个页面程序的并行自举。虽然是以2个页面为例介绍Flash烧写和并行自举的方法,但是对于2页以上的程序烧写和并行自举同样适用,只需要进行一些细微的改动即可。本文提供的方法以不到128字的RAM空间代价,在5410上实现了将大于 32 K字的程序并行自举到片上RAM,大大提高了编程的自由度和程序的运行速度,降低了系统功耗。这个方法有很强的通用性,可以在很多存在类似问题的DSP芯片(5409、5416等)上进行应用,具有较高的实用价值。

    展开全文
  • DriverStudio开发PCI设备DMA数据传输

    千次阅读 2016-07-05 11:03:18
    在驱动程序的调试过程中,经常出现系统“死机”、“蓝屏”等现象,这些情况可能由于内存访问分页错误、寄存器非法操作等因素造成。   加载存储板的操作都是经过PCI9054的配置,但是在驱动程序设计过程中,一般会...

    DriverWizard向导可以创建基本的wDM驱动程序框架,包括总线类型,地址空间,中断源,DMA资源,以及IOCTL(i/o控制代码)的定义等等。详细情况可参看DriverStudio的帮助文档,以下主要介绍如何用DriverWorks编写DMA方式的驱动程序。

     

        DriverWorks关于DMA操作。封装了三个类:KDmaAdapter, KDmaTransfer和KCommonCmaBuffer。KDmaAdapter类用于建立一个DMA适配器。说明DMA通道的特

    性; KDmaTransfer类用于控制DMA传输: KCommonCmaBuffer类用于申请公共缓冲区。

     

        DriverWorks中很少涉及到映射寄存器。只是提到KDmaTransfer类“由于硬件或者缓冲区大小的限制。将一个DMA请求分段进行。为每个段提供了一个传输段描述符数组,当设备不支持分散/集中时,这个数组中的描述符只有一个。每个描述符包含一个物理地址和相应的字节数。其结构如下:

    typedef struct TRANSFERDESCRIPTOR

    {

    展开全文
  • 使用Vivado HLS可以实现真正意义上基于C语言的IP,通过HLS,我们可以把用户的C/C++以及System C算法以VHDL或Verilog的形式输出,然后通过Vivado IPI或SysGen等Xilinx的工具,整合到FPGA设计工程中去。使用Vivado HLS...

    基于SDSoC的软硬件协同设计

    一 基于SDSoC的软硬件协同设计流程简介

    Software Define 的概念

    近年来“Software Define”软件定义这个词持续火热,全球知名技术研究和咨询公司Gartner早在对2014年最有战略意义的十大技术与趋势做出预测时,便提出了软件定义一切(Software Defined Anything)的概念,他们预测这类技术会在未来三年里拥有巨大潜力,并在同行业中产生重大影响。两年后的今天回顾这一概念和技术的发展,不难看出,Software Define的确成为了行业风向标,其应用可谓无处不在。
    一直关注Xilinx技术动向的工程师们对SDx这个词并不陌生,概括来讲,Xilinx的SDx指的是一系列新工具,专为系统和软件工程师而设计,可以使那些只有很少或根本没有FPGA设计经验的研发人员直接使用高级编程语言在强大的可编程硬件上进行设计,并且与那些嵌入芯片内部的或是在片外连接的业界标准处理器例如ARM或x86一起协同工作。 可以看到SDx系列目前有三个主要成员,包括SDSoC、SDAccel和SDNet。
    SDSoC开发环境允许嵌入式和应用软件开发人员更广泛的利用Zynq® SoC和MPSoCs的性能,提供超过100倍的软件性能加速。SDAccel™ 开发环境针对的是OpenCL,C和C++的设计应用,与那些CPU和GPU在数据中心和医疗影像等领域的实现方案相比,利用FPGA进行加速可获得高达25倍的性能功耗比提升。SDNet是“软”定义网络的解决方案。具体来说就是SDNet结合Xilinx的全面可编程器件,打造出了“软”定义网络这样的交叉技术,从而将可编程能力和智能化功能从控制层扩展至数据层,不仅支持SDN,而且还可以突破性地支持任何软件定义网络架构。
    从以上简要的介绍可以看出SDx系列的三个工具所针对的器件与市场各有侧重,但总体上都是面向软件和系统工程师的全面可编程抽象化设计工具,是Xilinx业界领先技术实力的进一步体现。其中,专门用作提高Xilinx异构Zynq SoC以及MPSoC的设计生产力而生的SDSoC开发环境就是这篇短文将要介绍的重点,在以下的篇幅中,我们会为大家分析SDSoC主要针对的市场和应用,SDSoC的各种创新,应用SDSoC的好处和优势等。

    Vivado HLS简介

    本章主要内容是介绍SDSoC,但在开始之前需要重复介绍一下Vivado HLS这个在高级抽象语言与底层硬件描述语言之间架起了一座桥梁的高阶综合工具。经过了三四年的上市推广,Vivado HLS早已不再是一个全新的工具,Xilinx已经有超过1000家成功的客户。HLS的灵活性和生产力优势是显而易见的,甚至Xilinx的IP开发部门在交付Vivado 2015.1版本及以后的部分视频IP时也都是使用HLS从C/C++语言开始设计。
    Vivado HLS可以在很短的时间内生成与手工编码质量相当的RTL代码,并且允许用户将同样在C测试平台生成的测试向量用在C仿真和RTL验证中,从而大幅加速验证过程。对那些使用C / C ++描述规范的算法设计类客户来说,这是理想的解决方案,可以将其已有的各类浮点或定点算法无缝实现到FPGA硬件中,比较典型的应用就是各类视频运算、加解密等DSP算法等等。最近非常火热的FPGA+深度学习的应用,就有很多开发者使用HLS进行开发,并且取得了非常高的性能。
    使用Vivado HLS可以实现真正意义上基于C语言的IP,通过HLS,我们可以把用户的C/C++以及System C算法以VHDL或Verilog的形式输出,然后通过Vivado IPI或SysGen等Xilinx的工具,整合到FPGA设计工程中去。使用Vivado HLS可以更便捷高效地完成从高阶抽象语言C/C++到Xilinx FPGA可编程逻辑硬件的设计实现过程。
    Vivado HLS不仅是简单的翻译工具或是综合工具,更为重要的是,我们可以将其产生的RTL以IP的形式导出到Vivado IPI中,或者直接调用HLS生成的RTL文件到另一个RTL项目,甚至是输出到DSP设计的SysGen工程中。

    Zynq SoC 开发流程
    之所以要花几页篇幅来介绍Vivado HLS的作用与Zynq的架构,就是为了更清楚地描述全面可编程Zynq SoC的开发流程。对于以C/C++等高阶语言为起点来进行SoC开发的用户来说,由C/C++算法开始,首先需要对软硬件进行划分,选择哪些部分放入PL进行加速,哪些部分仍然在PS用软件实现。对那些被指定放入上PL用于硬件加速的部分,还需要完成C代码到RTL IP的转换。接下来,就是完成软/硬件之间的连接,包括使用怎样的DataMover、PS与PL之间的接口如何配置等,接下来还要完成配套的软件驱动程序。所有这些往往牵扯到数个不同团队和专业人员的通力合作,需要通过数次迭代来探索最佳的实现方案和系统架构。这个流程图很清晰地描绘了SoC的开发流程,每一步都是耗时耗力的工作。

    不使用SDSoC的开发流程

     不使用SDSoC的开发流程
    具体到每一步的工作来看,传统的Zynq 设计流程大致分为五个步骤:
    首先,系统架构师来决定将哪些部分用于软件实现,哪些部分放入硬件加速,即所谓的软硬件分区。划分为硬件实现的功能将需要使用RTL 代码来开发,或是使用HLS 将C/C++代码综合成Vivado 中可实现的IP。然后,要在Vivado IPI 中搭建DataMover 和接口。后是应用软件和驱动程序的开发。这无疑是一个十分耗时的过程,需要多个部门和团队之间的设计切换。有时候,即便这样完成后的设计可以正常工作,却可能无法满足你在吞吐量、延迟或面积等方面的设计性能要求。此时就可能需要通过修改系统连接来重新搭建硬件架构来对系统性能进一步优化。但这么做,又将导致软件应用程序和驱动程序的变化。因此,你往往需要与多个软件和硬件团队紧密合作,通过多次迭代设计来试着满足最终需求。
    在某些情况下,设计不能满足你的性能要求的原因在于软件性能不够,或是硬件的占用率太高。这时候你就需要返回到最初的设计,重新修改软/硬件分区方案,然后前面所说的硬件实现,系统连接,软件驱动等所有步骤都要重新再来一边,这势必要求更多的团队一起配合,改变设计来探索另一种架构,而且可能面临更多次的设计迭代,进一步拉长设计周期。毫无疑问,用在系统优化上的时间对time-to-market 的影响巨大。此外,我们也注意到在Zynq SoC 的设计中,用户最关注的部分往往是算法的最终实现和算法模块的优化,包括IP 或是软件功能块。

    使用SDSoC 的开发流程

    使用SDSoC 的开发流程
    SDSoC工具可以自动搭建软硬件之间的通讯部分,包括DataMover、软件驱动程序和硬件连接接口。工具还可以将整个开发过程抽象到C/C++的应用层面,以C/C++为起点来进行算法开发,当然,工具也可以调用以传统的IP方法开发的算法模块,包括已经由Vivado HLS转换后的RTL IP,也包括那些本身就由Verilog或VHDL硬件描述语言编写的IP。在调用这类IP时,只需将其封装为C可调用库的形式即可。在SDSoC中,我们能够轻松进行软件/硬件的划分,用户仅需在图形化界面中用鼠标单击指定那些需要进行硬件加速的模块即可。
    相比较传统SoC设计流程,SDSoC通过自动生成硬件连接和软件驱动程序大大简化了Zynq SoC和MPSoC的开发过程。它会自动调用Vivado HLS来将那些用C/C++开发的算法模块转化为Vivado可综合的RTL IP,它也可以将那些已经优化过的HDL IP模块通过C可调用库的方式进行重用。用户可以在软件中通过简单点击某个功能块将其应用到PL上进行加速来迅速修改软/硬件的分区,因此,它也有助于系统架构设计人员运行快速假设性分析来评估系统的性能和面积。在应用SDSoC之后,我们可以非常迅速地将你的设计应用在Zynq系统上,即使第一遍实现后的性能不达标,也可以使用SDSoC快速选择不同的用于硬件加速的功能块,探索不同的硬件/软件分区方案,或是通过pragma等手段来指导工具产生不同的系统配置等方法来进一步优化设计。统计显示,使用SDSoC开发Zynq系统,可以将整体开发时间从原本的数周缩短至数日甚至数个小时。
    现在我们稍作总结就会发现,SDSoC开发环境提供了一个大大简化的C/C++编程体验,用户现在可以在嵌入式开发人员所熟悉的基于Eclips的IDE上完成整个Zynq SoC的开发。SDSoC带来了业界首个C/C ++的全系统优化编译器,提供系统级的Profiling特征分析,自动将软件代码放入可编程逻辑中加速,自动产生系统连接和相关的库以加速开发。SDSoC也为用户和第三方平台开发者提供了流程支持,通过提供平台描述文件的手段,可以使他们自己设计的包含有Zynq SoC的开发板在SDSoC开发环境中使用。
    应用SDSoC,开发人员可以从整个设计的C/C++代码开始系统级特征分析,从而找出系统设计的瓶颈。然后用户只需选择将那些性能瓶颈的功能块放入PL中加速。SDSoC的全系统优化编译器会使用Vivado HLS自动创建RTL IP,生成最优的系统连接,配置软件驱动程序。最终的结果是FPGA比特流文件,可执行elf文件和软件的引导映像。所有这些,完全由一个基于Eclipse的嵌入式开发环境生成。

    SDSoC开发环境的优势

    SDSoC提供给用户的是一个可以用来完成整个Zynq SoC和MPSoC开发的基于Eclipse的软件环境,这个环境对那些已经在使用DSP芯片、视频SoC 和CPU处理器的嵌入式开发人员来说是在熟悉不过的。在IDE中,用户可以简单地选择用来放入PL中加速的功能块,无需手动创建用于硬件实现的Vivado工程或是软件驱动程序。另外,已经有很多针对FPGA硬件优化过的IP库可以经由Vivado HLS导出,除了Xilinx和ARM,我们也有很多合作伙伴提供更多特定的算法库,包括视频类,加解密,OpenCV等等,帮助用户进一步提高生产力。
    关于操作系统,目前的SDSoC版本中已经支持的目标平台Platform大都支持多种OS,包括Linux,FreeRTOS和Standalone,如果用户需要其他操作系统的支持,只要将所需OS打包到所用的目标平台中即可。具体做法涉及SDSoC目标平台的创建,稍后会在其他章节中做详细介绍。
    Xilinx提供了很多关于SDSoC的开发文档,非常详细地介绍了SDSoC所有的内容,是学习SDSoC工具最好的资料。但是这些开发文档动辄上百页,想完整地看完需要耗费很长时间,而且并不是所有内容都经常被用到,因此本章挑选了使用SDSoC过程中较常见的操作并且给出了应用SDSoC的一些案例以便读者能够快速入门。本章不仅希望能够使读者快速掌握SDSoC,还希望读者通过查阅Xilinx的开发文档进一步学习SDSoC。

    二 SDSoC使用

    初次使用SDSoC

    尽管SDSoC支持在Windows主机上开发Linux应用,但是创建SDSoC Platform需要一台Linux主机,本书会在其他部分介绍如何在Ubuntu系统上安装SDSoC。在Windows上安装SDSoC比较简单,因此不做介绍。指定SDSoC工作区
    第一次打开SDSoC后会弹出一个界面要求指定工作区,SDx工作区是一个文件夹,用于存储项目,源文件和编译时产生的中间结果。您可以为每个项目定义单独的工作区,或者为不同类型的项目分配工作区。勾选Use this as the default and do not ask again指定当前的文件夹为SDSoC的默认工作区,日后可以在File ->Switch Workspace中更改

    新建SDSoC工程

    新建SDSoC工程
    在Project Explorer的空白处右键New->SDx Project即可新建工程,SDx有三种工程类型:

    • Application Project:一个Software Application,可以将部分函数放进PL部分加速。
    • System Project:包含了多个Application Project以支持不同的应用和硬件加速器。
    • Platform Project:定义SDSoC的软硬件平台。

    在这里我们选择Application Project点击Next,然后指定一个工程名称,在这里我们暂定为lab1,点击Next。下面我们就进入选择Platform的对话框。
    选择SDSoC Platform
    将我们提供的PYNQ的board_file文件夹复制到XILINX_VIVADO/data/boards/board_files路径下,PYNQ的SDSoC Platform复制到XILINX_SDX/platforms/路径下。一个SDSoC Platform包含DSA(Device Support Archive)文件,定义了硬件平台的设计、接口,以及软件平台,包括OS的boot文件以及runtime文件。在编译过程中SDSoC会调用Vivado从dsa文件读取平台信息复现硬件平台,因此需要提供板卡的board_file,后面会介绍如何自己搭建Platform。在这里我们选择PYNQ platform然后点击Next。
    然后进入System Configuration对话框,下面有三个选项。

    • Software Platform:用来选择应用运行在什么操作系统上,是Linux,FreeRTOS还是standalone(裸机),工程使用的是什么类型的代码(C/C++还是OpenCL)。
    • Domain用来选择系统运行在哪个核心上,我们提供的PYNQ Platform搭载了Linux系统,运行在两颗Cortex-A9核心上。有些板卡可能有其他核心,比如ZCU102上搭载的ZU9CG上除了四颗Cortex-A53核心,还有两颗Cortex-R5核心,ZCU102的FreeRTOS系统就运行在两颗R5核心上。
    • Additional Settings:有两个选项,一个是Linux Root File System,后面会讲到这个选项的作用。另一个是Output Type,选择Executable,项目最终会生成一个可执行文件,需要代码中有一个main函数,而选择shared library,项目最终会生成一个.so文件,具体如何使用后面会详细介绍。这里我们选择Executable,点击Next。
      现在进入了Templates对话框,目前PYNQ的Platform并没有提供Example,点击Next,进入默认界面。项目被安排在一系列不同的窗口和编辑器视图中,也称为IDE中的界面。打开SDx工具,如图所示,默认界面上半部分从左至右,分别是项目资源管理器、项目编辑器、大纲,下半部分从左至右,分别是报告,控制台以及目标连接,相信熟悉Eclipse的读者看到这个界面并不陌生。
      SDSoC默认界面

    导入源代码

    在SDSoC中打开工程后,可以将源代码导入到工程中,右键src文件夹,点击Import。Import对话框允许您指定获取文件的来源,包括从压缩包,已经存在的工程,文件系统以及Git文件夹。我们在这里选择从文件系统中导入,点击File System,在From directory一栏输入$XILINX_SDX /samples/mmultadd,注意不要导入description.json和Makefile文件,这两个文件工具可以自动生成。
    从文件系统中导入源代码

    Profiling

    在选择硬件加速函数之前,我们需要大致了解整个算法各部分消耗多少时间,SDSoC工具提供了Profiling工具,可以自动分析算法各部分消耗了多少时间。首先新建一个Application工程命名为profiling,将我们提供的代码导入到src文件夹下,在Debug模式下编译代码。
    将PYNQ与电脑连接在同一个路由器下,并将PYNQ的MicroUSB接口连接到电脑。点击SDx界面右下角的Target Connection->Linux TCF Agent-> Linux Agent [default],弹出Target Connection对话框,Host一栏输入PYNQ的IP地址,点击Test Connection,如果看到Connection Successful对话框则说明连接成功。
    配置Linux TCF
    右键小蜘蛛,选择System Debugger using Debug_Profiling.elf on Linux Agent,点击OK进入Debug模式。
    启动Debug
    使能TCF Profiler,Windows->Show View->Other->Debug->TCF Profiler
    使能TCF Profiler
    点击TCF下绿色三角箭头,弹出TCF Profiler启动界面,勾选Enable stack tracing,点击OK,按F8启动程序
    启动TCF Profiler
    等待程序运行一段时间,可以看到Profiler显示各函数运行的时间:
    TCF Profiler显示各程序运行时间

    选择硬件加速函数

    创建硬件加速SoC的第一项主要任务是确定应用程序的哪些部分适合在硬件中实现,即将这部分代码放在PL中运行将显著提升整体性能,在上一小节我们介绍了如何找到算法中计算量最大的部分。当您已经决定哪个函数放到硬件进行加速之后,有两种方法指定用于硬件加速函数。

    • 方法1
      双击project.sdx文件进入Application Project Settings如下图所示。点击Hardware Func-tion一栏最右侧的橙色闪电按钮,可以显示当前工程中的候选函数(可能被用来硬件加速的函数),按住ctrl键选择madd和mmult两个函数作为硬件加速函数。
      添加硬件加速函数对话框
    • 方法2
      切换硬件/软件
      点击硬件加速函数所在的.cpp文件左侧的小箭头,找到用于硬件加速的函数,右键点击Toggle HW/SW,这一步是切换某函数是放在软件中运行还是硬件中运行。指定硬件加速函数后的用户界面如上图所示。注意,用于硬件加速的函数需要特定的写法,并不是所有函数都可以被指定为硬件加速函数。硬件加速函数应该编写如何并不是本书的主要内容,会在后面简要介绍。这部分内容请参考UG871,UG902以及Xilinx大学计划翻译的HLS手册https://github.com/xupsh/pp4fpgas-cn-hls

    选择硬件加速函数的频率

    选择硬件功能后,还需要选择硬件加速函数和数据传输网络的时钟频率。硬件加速函数需要通过CPU从DDR中读取数据,这项工作由专门的硬件——DMA来完成,因此也要指定这部分的频率。每个平台都有一个或多个由SDSoC Platform开发人员定义的时钟源,在开发SDSoC Plaform的时候会指定一个默认时钟源,但是无论是硬件加速函数还是数据传输网络,都可以自由选择时钟而不是限定为默认时钟,此外硬件加速函数和数据传输网络可以使用不同的时钟频率,这部分内容会在之后介绍。
    选择硬件加速函数和数据传输网络的时钟频率选择硬件加速函数和数据传输网络的时钟频率

    编译并测试

    指定硬件加速函数和它们的运行频率之后我们就可以编译工程了。默认界面左上角可以选择当前的编译模式,Release还是Debug,二者的优化级别不同,我们这里选择Release,注意更改编译模式后要重新添加硬件加速函数。右键lab1文件夹选择build project,或点击图片中的小锤子按钮。编译过程根据电脑配置会持续二十分钟到六十分钟不定。编译的过程中SDSoC首先调用Vivado HLS工具将硬件加速函数中的代码转化成RTL代码并打包成IP核,在Release/_sds/iprepo/repo文件夹中可以看到硬件加速函数生成的HLS IP核。
    硬件加速函数生成的IP核
    然后调用Vivado IP Integrator自动添加DMA模块生成Data motion Network并生成系统的Block Diagram,可以点击Release/_sds/p0/_vpl/ipi/syn/syn.xpr打开Vivado工程,然后Open block diagram查看,不同的SDx生成的Vivado工程路径可能会不同。
    SDSoC 调用Vivado IP Integrator自动生成Block Diagram
    SDSoC会调用Vivado生成比特流,同时自动生成Data motion network的驱动程序,并将生成的bitstream与fsbl.elf,u-boot.elf打包在一起生成BOOT.bin文件。每一次编译工程SDSoC都会完整地进行一遍Vivado HLS->Vivado IPI->Vivado的流程,Vivado HLS正常情况下只要几分钟就可以完成,HLS运行时间过长说明代码编写有问题,整个流程中最费时间的是Vivado综合布局布线生成比特流的过程。
    将sd_card目录下的lab1.elf,BOOT.BIN,image.ub文件拷贝到FAT32的SD卡中。有两种方法连接到PYNQ板卡。将PYNQ的MicroUSB连接到PC,PC会自动安装驱动。然后找到SDx Terminal右侧的“+”,选择合适的端口。需要注意以上操作的顺序:先上电,然后打开串口,波特率保持默认,端口选择COM4。
    连接PYNQ板卡
    启动之后会打印内核启动信息,直到输出PYNQ login,输入用户名root,密码root。
    SDSoC自带的Terminal

    $ mount /dev/mmcblk0p1 /mnt  //进入系统后挂载SD卡
    $ cd /mnt
    $ ./lab1.elf
    
     
     
    • 1
    • 2
    • 3

    性能预测模式

    SDSoC完整地编译一次工程少则二十分钟,多则几个小时,因此Xilinx提供了性能预测模式可以让开发者快速地评估系统性能。勾选Estimate performance选项然后点击编译按钮,这个模式下SDSoC只会进行HLS的流程,并不会产生Block Diagram并调用Vivado产生比特流,整个编译过程不会持续超过10分钟。
    勾选Estimate Performance
    编译完成后会弹出一个性能评估报告,包含了资源利用情况以及预测的执行一次硬件加速函数消耗的CPU时钟周期数。
    性能预测报告
    还有一种办法可以得到在CPU上运行程序的实测周期数。设置好TCF Agent后(在10.2.4节有提到)点击上图中的Click Here就会运行lab1.elf文件,得到实测的CPU周期数,并给出性能对比。
    通过Linux TCF Agent得到的性能对比

    分析和优化

    在执行算法优化时需要考虑两个不同的方向:应用程序代码优化和硬件功能优化。大多数应用程序开发人员都熟悉针对CPU优化软件。这通常要求程序员分析算法的复杂性,总体系统性能和数据局部性。有许多方法指南和软件工具来指导开发者定位性能瓶颈,这些技能在优化针对SDSoC环境中的硬件加速函数时同样适用。
    首先,开发者应该分别优化整个工程中每一个函数的性能,在SDSoC环境下进行优化与传统软件开发的最大不同是有一些算法会被放进PL中进行加速,这要求开发者必须考虑到算法的并行性,数据传输,内存使用以及PL的存在。然后,开发者需要指定硬件加速函数,并尽可能地让硬件加速器在数据传输时保持工作,也就是说要尽可能让硬件加速器计算跟通信同时进行。
    SDSoC可以在编译过程中自动生成报告,帮助开发者详细地分析软件应用和硬件加速函数,这些报告在Report视图下可以看到,如下图所示
    报告视图
    双击Data Motion Network Report,我们可以看到Data Motion Network的报告,包含了每个硬件加速函数与PS之间的连接信息,如使用了哪种端口(S_AXI_ACP or S_AXI_HP),哪种Datamover(DMA_SIMPLE or DMA_SG),每次运算的数据搬运量,以及用来存储数据的内存是否连续,这些名词的含义会在后面介绍。
    Data Motion Network报告
    双击HLS Report,可以看到HLS的详细信息,包括资源利用率,时钟频率以及周期数等信息,开发者要根据这些信息来优化设计。需要注意的是这里估算出来的时钟周期数与HLS估算出来的时钟周期数是有差别的。CPU端的时钟周期数=PL端时钟周期数×(CPU频率/PL频率),而且HLS估算数据加载的时间与实际数据传输时间是有区别的,因此Estimate performance里预测的CPU时钟周期数与实际情况会有一些区别,但是整体来看预测结果还是比较准确的,可以作为参考。
    HLS报告

    三 SDS指令简介

    前面的章节已经介绍了利用HLS进行开发的流程,分成三步,首先在Vivado HLS工具中将C/C++转换成RTL代码并打包成IP核,然后在Vivado IPI中将HLS IP核与Zynq的PS集成在一起,最后在SDK中编写驱动完成整个设计。在这个流程中开发者需要根据应用特点选择合适的接口,合适的DMA,每一次调整都要先在HLS中调整,然后在Vivado更新IP,操作流程十分繁琐。此外,编写驱动进行调试也要花费大量的精力。

    SDSoC替开发者完成后两项工作,使开发者可以专注在最有价值的工作当中。SDSoC完成后两步的工作也需要一些约束条件,这些约束条件以SDS pragma的形式给出。SDS pragma根据是否与数据传输相关可以分成两类,第一类SDS pragma决定了算法加速IP连接到PS的哪个端口,调用哪种类型的Data mover,在DDR中的内存如何分配,包括SDS data copy/zero_copy,data access_pattern,data mem_attribute,data sys_port和data_mover,这些指令可以形成不同的组合,不同的组合最终实现的数据传输性能差距很大。第二类SDS pragma包括SDS async/wait,partition,buffer_depth,resource以及trace,这类指令的功能各异,使用频率也不是很高,本节会着重介绍第一类指令应该如何使用。

    SDS指令简介

    1. access_pattern

      语法

    `#pragma SDS data access_pattern( ArrayName:<pattern> )
    
     
    `

    其中:

    pattern:SEQUENTIAL或RANDOM,默认为RANDOM。

    如果access_pattern是SEQUENTIAL,Array会被综合成一个streaming接口,如ap_fifo;如果是RANDOM,Array会被综合成一个RAM。

    例1

    `#pragma SDS data access_pattern(A:SEQUENTIAL)
    void foo(int A[1024], int B[1024])
    
     
    `

    在这种情况下,数组A会被综合成一个FIFO,只能按照A[0], A[1],…, A[1023]的顺序被访问,而B会被综合成RAM(因为默认是RANDOM),可以按照任意顺序被访问。

    例2

    `#pragma SDS data access_pattern(A:SEQUENTIAL)
    void foo(int* A, int B[1024])
    
     
    `

    类似地,指针变量也可以用data access_pattern指令来规定它的访问次序。

    在为硬件加速函数添加SDS指令时,有些指令可以省略,但是access_pattern指令绝对不能省略,除非用到zero_copy指令。zero_copy要求在该接口上数据必须顺序传输,此时data access_pattern强制为SEQUENTIAL,是否添加pragma没有影响。

    例3

    `void mmult_accel(float A[N*N], float B[N*N], float C[N*N], int M) 
    {
         float A_tmp[N][N], B_tmp[N][N];
         for(int i=0; i<M; i++) {
              for(int j=0; j<M; j++) {
              #pragma HLS PIPELINE
                   A_tmp[i][j] = A[i*M+j];
                   B_tmp[i][j] = B[i*M+j];
              }
         }
         for (int i = 0; i < M; i++) {
              for (int j = 0; j < M; j++) {
                   float result = 0;
                   for (int k = 0; k < M; k++) {
                        #pragma HLS PIPELINE
                        result += A_tmp[i][k] * B_tmp[k][j];
                   }
                   C[i*M+j] = result;
              }
         }
    }
    
     
    `

    此外,为了提升系统性能,通常算法加速IP需要将运算时用到的数据先加载到PL上再进行计算,如例3代码所示。为了提升性能,将数据从内存搬运到PL的过程访问内存的方式是连续的,因此在本系列文章中所有SDSoC相关实验的assess pattern均设置为SEQUENTIAL。

    1. #pragma SDS data copy/zero_copy

    使用copy指令时SDSoC会综合出一个datamover完成数据传输,而使用zero_copy指令时,SDSoC会将硬件加速器的接口直接连接到PS的S_AXI端口,这部分内容在下一节中会详细分析。

    语法:

    `#pragma SDS data copy|zero_copy(ArrayName[<offset>:<length>])
    
     
    `

    其中:

    offset:编译时必须为常量,指定数据存储到数组的第几个元素中,目前offset值必须指定为0。

    length:用于告知编译器通过该接口的数据传输量,可以是数学表达式,要确保该函数执行时能够得到确定的结果。

    重要!copy指令与zero_copy指令是相互排斥的,绝对不允许在同一个数组/指针上使用。

    例1

    `#pragma SDS data copy(A[0:1024], B[0:1024])
    #pragma SDS data zero_copy(A[0:1024], B[0:1024])
    void foo(int* A, int* B);
    
     
    `

    例1的所示情况是不被允许的。

    例2

    `#pragma SDS data copy(A[0:1024])
    #pragma SDS data zero_copy(B[0:1024])
    void foo(int* A, int* B);
    
     
    `

    例2的所示情况是被允许的。

    例3

    `#pragma SDS data copy(A[0:size*size], B[0:size*size])
    void foo(int *A, int *B, int size)
    {
    ...
    }
    
     
    `

    size作为传入参数虽然在编译时不能确定,但是在执行时可以确定,因此上面的写法是被允许的。

    copy与zero_copy的区别会在后面详细介绍。

    1. pragma SDS data data_mover

    默认情况下编译器会分析代码自动选择合适的data_mover,但是开发者可以指定data_mover覆盖掉编译器的默认值。

    语法:

    `#pragma SDS data data_mover(ArrayName:DataMover[:id])
    
     
    `

    其中:

    dataMover:AXIFIFO,AXIDMA_SG或AXIDMA_SIMPLE。

    id:可选,必须是一个正整数,如果多个ArrayName指定同一个id,它们会共享同一个data_mover。

    例1

    `#pragma SDS data data_mover(A:AXIDMA_SG:1, B:AXIDMA_SG:1)
    void foo(int* A, int* B)
    
     
    `

    在这种情况下A和B会共享同一个AXIDMA_SG IP

    `pragma SDS data mem_attribute
    
     
    `

    对于像支持虚拟内存的操作系统比如Linux,用户空间分配的内存是经过Linux系统虚拟化过的,不能保证在物理上,也就是DDR中是否连续,这可能会影响系统性能。SDSoC提供了API分配物理上连续的内存空间。mem_attribute可用于告诉编译器该参数是否被分配在物理上连续的内存中。

    语法:

    `#pragma SDS data mem_attribute(ArrayName:contiguity)
    
     
    `

    其中:

    Contiguity: PHYSICAL_CONTIGUOUS或NON_PHYSICAL_CONTIGUOUS,默认是后者。

    例1

    `#pragma SDS data mem_attribute(A:PHYSICAL_CONTIGUOUS)
    void foo(int* A, int* B)
    
     
    `

    在上面的例子里,开发者告诉编译器数组A被分配到了物理上连续的内存空间,编译器会强制选择Datamover为AXIDMA_SIMPLE而不是AXIDMA_SG。

    1. pragma SDS data sys_port

    前文介绍过Zynq-7000系列处理器提供了S_AXI_HP,S_AXI_ACP接口用于数据传输。ACP接口全称Accelerator Coherency Port,也叫缓存一致接口,通过该接口PL可以直接访问PS的cache,缓存一致性由SCU保证,延时很低,适合做专用指令加速器模块接口。通过ACP接口传输的数据量有限制,不能超过8MB,如果传输数据量较大只能使用HP接口。

    语法:

    `#pragma SDS data sys_port(ArrayName:port)
    
     
    `

    其中:

    port: ACP,AFI或HPC,AFI对应的是HP接口,ACP对应Zynq-7000系列的缓存一致接口,HPC对应MPSoC系列的缓存一致接口。

    例1.

    `#pragma SDS data sys_port(A:AFI)
    void foo(int* A, int* B)
    
     
    `

    在该例中,A接口连接到S_AXI_HP端口,B接口视情况而定。

    1. pragma SDS async/wait

      ASYNC pragma必须与WAIT pragma搭配使用以手动控制硬件函数同步。在调用硬件函数之前立即指定ASYNC pragma,指示编译器不要根据数据流分析自动生成等待。 WAIT pragma必须插入到程序的适当位置以便CPU等待,直到具有相同ID的关联ASYNC函数调用完成。上面的描述可能比较难以理解,读者可以先看下面的例子。

      语法:

    `#pragma SDS async(<ID>)
    ...
    #pragma SDS wait(ID)
    
     
    `

    其中:ID是用户定义的 ID用于匹配ASYNC/WAIT,必须是正整数

    例1.

    `{
    #pragma SDS async(1)
    mmult(A, B, C);
    #pragma SDS async(2)
    mmult(D, E, F);
    ...
    #pragma SDS wait(1)
    #pragma SDS wait(2)
    }
    
     
    `

    程序运行到mmult(A, B, C)时,先启动数组A和数组B的数据传输,一旦传输完毕立刻返回到主程序中,然后程序开始将数组D和数组E送到mmult硬件加速器中然后立即返回。当程序执行到#pragma SDS wait(1)时,等待输出C就绪,当程序执行到#pragma SDS wait(2)时,等待输出F就绪。使用该指令可以将数组D,E的数据传输时间与数组C的计算时间重叠,提升系统的吞吐率。

    SDS Pragma组合

    上一小节单独介绍每一个指令,但是在实际开发时要将SDS pragma组合起来,本小节通过一个最基本的数据传输的例子,分析不同的指令组合综合出来的数据传输网络有何区别以及最终数据传输性能的差异。

    新建一个Application Project,起名为lab2,将我们提供的代码拷贝到src文件夹。这个工程实现的功能非常简单,首先生成一个随机数数组,然后把这个数组从DDR传到PL中,再从PL中传回DDR,最后验证从PL传回来的数据与最初传到PL的数据是否一致。这个例子并没有涉及如何加速在PL中的计算,只是单纯地分析数据传输。

    例1. 以下程序并不完整,为了便于说明摘取了部分片段。

    `#define N 2048
    #pragma SDS data copy(In[0:N],Out[0:N])
    #pragma SDS data data_mover(In:AXIDMA_SG, Out:AXIDMA_SG)
    #pragma SDS data access_pattern(In:SEQUENTIAL, Out:SEQUENTIAL)
    #pragma SDS data sys_port(In:AFI, Out:AFI)
    void IO(float* In, float* Out)
    {
    	float Buffer [N];
    	for(int i=0;i<N;i++)	Buffer[i]=In[i];//将数据从DDR读取到PL中
    	for(int i=0;i<N;i++)	Out[i]=Buffer[i];//将数据从PL传输回DDR中
    }
    int main(int argc, char* argv[])
    {
    	float *A, *B;
        A = (float *)malloc(N * sizeof(float));
    	B = (float *)malloc(N * sizeof(float));
    ...
    	IO(A, B);
    ...
    }
    
     
    `

    在上面这段程序里,我们用到了四个SDS pragma,分别是copy,data_mover,sys_port以及access_pattern。没有使用mem_attribute是因为编译器会自动判断分配的内存连续与否。上面这段程序使用malloc语句分配内存,那么这段内存就是分页的。类似地,我们也可以用数组来初始化一段内存。

    `float A[N];
    float B[N];
    
     
    `

    这两种方式分配的内存在物理上都是不连续的,想要分配在物理上连续的内存片段必须使用sds_alloc()语句,内存片段在物理上是否连续对数据传输性能影响很大。

    这四条指令加上内存分配语句理论上可以产生2(malloc/sds_alloc) * 2(copy/zero_copy) * 3(DMA_SG/DMA_SIMPLE/FIFO) * 2(RANDOM/ SEQUENTIAL) * 2(AFI/ACP)=48种组合方式,但是各个pragma之间是有依赖关系的,比如,zero_copy和DMA_SIMPLE都必须与sds_alloc()同时使用。此外,RANDOM的assess pattern比较罕见(前面有提到),因此实际上并没有那么多组合。下面我们会比较一下各种能够实现的SDS pragma组合的情况(比如paged +AXIDMA_SIMPLE就无法实现),包括各组合的理论性能,实测性能,资源利用等情况。

    内存端口DatamovercopySetupTransfer实测FFLUT
    1连续ACPSIMPLEzero51810890489071197
    2连续AFISIMPLEzero11222206751106231197
    3连续ACPSGzero51810890488911197
    4连续AFISGzero11222206751054111197
    5连续ACPSIMPLEcopy11201033749912130
    6连续AFISIMPLEcopy124541054680345130
    7连续ACPSGcopy52021537072418130
    8连续AFISGcopy1624215426104536130
    9分页ACPSGcopy2852417532321272130
    10分页AFISGcopy2662418636351497130
    11连续GPFIFOzero51810890489411197
    12连续GPFIFOcopy39683618636580754130
    13分页GPFIFOcopy39683618636573677130

    其中,表1的内存,端口,Datamover,copy,Setup,Transfer由Data Motion Network Report给出,实测在板上测试给出,LUT与FF的使用情况由HLS Report给出,这些内容在附件里有提供,此外我们还提供了不同指令组合对应的Block Diagram。

    连续+ACP+SIMPLE+zero_copy对应原理图

    连续+ACP+SIMPLE+zero_copy对应原理图

    在这里插入图片描述

    连续+HP+SIMPLE+zero_copy对应原理图

    在这里插入图片描述

    连续+ACP+SG+zero_copy对应原理图

    在这里插入图片描述

    连续+ACP+SIMPLE+copy对应原理图

    在这里插入图片描述

    连续+ACP+SG+copy对应原理图

    在这里插入图片描述

    分页+ACP+SG+copy

    • 通过分析表1以及各种组合的原理图,我们可以得到如下结论:
    • 通过对比7,8和9,10,可知连续内存的性能远强于分页内存性能
    • 通过比较1,3,5,7,9和2,4,6,8,10可知ACP端口性能最强,AFI(也就是HP)接口次之,GP接口最差,与前两者性能相差很大。
    • 通过对比1,3和2,4,11的Block Diagram(打开Release_sds\p0_vpl\ipi\syn\syn.xpr查看),资源利用情况,Setup时间等,发现zero_copy+SG的zero_copy+SIMPLE的组合完全一致,因此有zero_copy存在的情况下Datamover会强制设置为SIMPLE。
    • 通过对比1,2和5,6的Block Diagram,可知使用AXIDMA_SIMPLE时算法加速IP不经过DMA直接连到PS的端口,AXIDMA_SG会生成一个DMA用于数据搬运。二者性能差异不大,但是AXIDMA_SG消耗了更少的FF和LUT。

    综上,分配内存时要使用sds_alloc(),数据传输量较小(<8MB)时选择ACP接口,copy与zero_copy性能差距并不大,AXIDMA_SG与AXIDMA_SIMPLE读者可以根据自己需要选择。

    四 搭建SDSoC Platform

    SDSoC Platfrom定义了基本的硬件和软件架构以及应用程序的运行环境,本节从硬件和软件两方面,介绍SDSoC Platform如何在SDSoC中被调用然后说明如何搭建自己的SDSoC Platform。一个SDSoC Platform应该包含如下文件:

    • 硬件文件夹,里面包含Device Support Archive file,DSA文件定义了Zynq的PL部分, 在编译时SDSoC利用DSA文件包含的信息重新构建硬件工程,并以此为基础舔加算法加速器。
    • 软件文件夹,包含
    1. 系统配置和处理器域,定义了系统启动顺序以及每颗CPU上运行的操作系统
    2. 启动相关文件,如fsbl.elf,u-boot.elf,如果是linux系统还需要提供设备树,内核,ramdisk或image.ub(设备树,内核,ramdisk的集合)启动相关文件,如fsbl.elf,u-boot.elf,如果是linux系统还需要提供设备树,内核,ramdisk或image.ub(设备树,内核,ramdisk的集合)
    3. Prebuild Hardware(可选),包括了比特流,.hdf等文件,如果程序里没有硬件加速函数,SDSoC将跳过调用Vivado生成比特流的步骤直接使用预先生成的文件以加快编译速度。Prebuild Hardware(可选),包括了比特流,.hdf等文件,如果程序里没有硬件加速函数,SDSoC将跳过调用Vivado生成比特流的步骤直接使用预先生成的文件以加快编译速度。
    4. 库的头文件以及静态库(可选)库的头文件以及静态库(可选)
    5. Metadata文件,用来组织上面提到的文件Metadata文件,用来组织上面提到的文件
    6. Sample Application(可选)Sample Application(可选)

    SDSoC Hardware Platform

    在这里插入图片描述

    上图是PYNQ SDSoC Platform硬件部分的基础平台,里面只有系统复位(Processor System Reset)模块和时钟向导(Clocking Wizard)模块。在SDSoC中可以指定硬件加速器的时钟频率,如100M、142M、166M和200M,这些频率并不是凭空产生的,而是在Platform的时钟向导模块中指定的,如果想要其他频率可以在时钟向导中添加。

    在这里插入图片描述

    上图是reVISION 的案例平台zcu102_rv_ss Platform硬件部分的基础平台,除了包含系统复位模块和时钟向导模块之外,还包含了MIPI接口和HDMI接口。zcu102_rv_ss提供了一个光流算法的案例,输入是MIPI摄像头,输出是DisplayPort接口(DP接口是连接到PS上的),在SDSoC中无法编写MIPI接口的控制逻辑,所以这部分逻辑是在创建SDSoC平台时准备好的。所有用到MIPI接口的工程都可以使用该基础平台,使用SDSoC工具我们可以很容易地在该基础平台上实现不同的算法。

    在这里插入图片描述

    最终加载进PL的比特流由图3所示工程生成的(路径:Debug/sds/p0/_vpl/ipi/syn),该工程在图1的基础上添加了若干IP,包括:

    • io:调用HLS产生的算法加速IP。
    • Constant:某些IP的某些接口需要一直为1/0。
    • Adaptor:AXI接口在在direct模式下控制信号以及数据需要通过Adaptor转换再连接到算法加速IP上。
    • AXI Interconnet:Adaptor的AXI接口不能直接与PS的AXI接口相连,需要通过AXI Interconnect转接。

    创建自己的SDSoC Hardware Platform

    1. 打开Vivado IDE并创建一个工程
    • Vivado没有提供PYNQ的Board file,将我们提供的PYNQ board file拷贝到{Xilinx_Vivado}\data\boards\board_files路径下
    • 打开Vivado IDE,在 Quick Start下点击Create Project,点击Next,输入工程名PYNQ和工程路径,点击Next

    在这里插入图片描述

    • Project Type保持默认RTL Project,点击Next,跳过Add Sources和Add Constraints

    • Defualt Part界面下选择PYNQ-Z2

      在这里插入图片描述

    • 点击Next,检查后点击Finish

    1. 创建一个IP Integrator设计
    • 在Flow Navigator –> IP Integrator, 选择Create Block Design.

    • 在Create Block Design对话框中为Block Design指定一个名称,在这里设置为PYNQ

      在这里插入图片描述

    • 在Block Design画布右键选择Add IP

    • 搜索框内输入zynq找到ZYNQ7 Processing System IP

    • 在IP catalog中选择ZYNQ7 Processing System IP,按下回车将其添加到Block Design中。

    在这里插入图片描述

    • 在IP integrator界面下单机Run Block Automation,如下图所示

      在这里插入图片描述

    Run Block Automation对话框打开后如下图所示,这个对话框表示FIXED_IO和DDR接口会被创建,Apply Board Preset选项通用会被勾选。在board file文件夹PYNQ目录下有一个preset.xml文件,里面提供了PS部分的基本配置,如DDR的设置。

    在这里插入图片描述

    • 点击OK,在IP integrator diagram会出现如下的图形

      在这里插入图片描述

    • Running Block Automation 之后Zynq-7000 AP SoC Processing System,注意加载preset之后要检查TTC模块,QSPI模块,UART模块,Eth模块有没有被使能,这些模块是Petalinux正常运行所必需的。

    • 右键Add IP,输入proc sys res找到Processor System Reset,按回车将这些模块添加到Block Diagram中,重复三次该操作,最终在Block Diagram中应该有四个Processor System Reset

    • 相似地,添加Clocking Wizard和Concat IP,以上步骤执行之后Block Diagram应跟下面这张图比较相似

    在这里插入图片描述

    双击Zynq IP打开配置引导界面,在Re-customize IP对话框中执行如下操作

    • PS-PL Configuration-> AXI Non Secure Enablement-> GP Master AXI Interface取消勾选M AXI GP0 interface

      在这里插入图片描述

    • Interrupts->勾选Fabric Interrupts->PL-PS Interrupt Ports,勾选IRQ_F2P[15:0],点击OK退出

      在这里插入图片描述

    • 双击Clocking Wizard进入配置界面,选择Output Clocks选项卡,勾选clk_out2,3,4并按照下图配置频率,这些频率就是最终在SDSoC平台中可以选择的频率。

      在这里插入图片描述

    • 在该页面下向下滑动,将Reset Type设置成Active Low,点击OK关闭该界面。

    • 双击Concat IP,将Number of Ports设置为1,Re-customizing IP之后的Block Diagram应如下图所示。

      在这里插入图片描述

    下面开始手动连线

    • clk_wiz_0/ clk_in1与ZYNQ7 PS/ FCLK_CLK0,clk_wiz_0/clk_out1与proc_sys_reset_0/ slowest_sync_clk相连,以此类推连接所有PSR的slowest。

    • 将ZYNQ7 PS/FCLK_RESET0_N,Clocking Wizard/resetn,所有PSR/ext_reset_in相连

    • 将Clocking Wizard的locked与所有PSR的dcm_locked相连。

    • 将Concat的dout[0:0]与ZYNQ7 PS的IRQ_F2P[0:0]相连。

    • 点击Regenerate Layout按钮重新生成Block Diagram的布局。

      在这里插入图片描述

    • 右键bd文件,点击Generate Output Products-> Synthesis Options->Global,点击Generate

      在这里插入图片描述

      然后右键bd文件,点击Create HDL Wrapper,生成HDL Wrapper。

    1. 设置Platform属性

    完成Vivado设计套件中的硬件平台设计项目后,必须完成添加平台属性(PFM)定义平台名称并配置平台接口如时钟,中断和总线接口。这些属性被设置一次并存储在工程中。平台通常由多个时钟组成。在当前项目中,我们的设计包含四个用Clocking Wizard生成不同的时钟,用户可以在SDSoC中选择要被硬件加速的函数的时钟频率。同理,在SDSoC中被用到的AXI端口也要标注,硬件加速函数会用这些被标注的AXI端口来建立Data motion network。

    在这里插入图片描述

    上图所示的Block Diagram中S_AXI_HP0被两个VDMA占用,那么这个AXI端口就不再可以被SDSoC调用。这些AXI端口在Block Diagram中可能不可见(在该Block Diagram中只能看到S_AXI_HP0),但是只要平台属性里标注好就可以被SDSoC中的硬件加速函数使用。

    • 平台属性(PFM_NAME)必须定义Vendor, Library, Name, and Version (VLNV),在Tcl Console中输入如下指令并按回车,设置SDSoC Hardware Platform的名称。
    `set_property PFM_NAME "xilinx.com:PYNQ:PYNQ:1.0" [get_files PYNQ.bd]
    
     
    `

    PFM_NAME属性按照下面的格式

    `<vendor>:<library>:<platform>:<version>
    
     
    `
    • 用户可以导出平台内的任何时钟源,但是被导出的时钟源要搭配一个Processor System Reset IP。PFM.CLOCK属性可以设为BD cell,外部端口或者外部接口。比如在本设计中时钟源来自Clocking Wizard的四个输出,也可以选择PS的FCLK_CLK0~3作为时钟源。输入如下指令并按回车,设置SDSoC Hardware Platform的时钟。
    `set_property PFM.CLOCK {\
    clk_out1 {id "0" is_default "false" proc_sys_reset "proc_sys_reset_0"} \
    clk_out2 {id "1" is_default "true" proc_sys_reset "proc_sys_reset_1" } \
    clk_out3 {id "2" is_default "false" proc_sys_reset "proc_sys_reset_2"} \
    clk_out4 {id "3" is_default "false" proc_sys_reset "proc_sys_reset_3"} \
    } [get_bd_cells /clk_wiz_0]
    
     
    `
    • 定义AXI端口
    `set_property PFM.AXI_PORT { \
    M_AXI_GP0 {memport "M_AXI_GP"} \
    M_AXI_GP1 {memport "M_AXI_GP"} \
    S_AXI_ACP {memport "S_AXI_ACP" sptag "ACP" memory "ps7 ACP_DDR_LOWOCM"} \
    S_AXI_HP0 {memport "S_AXI_HP" sptag "HP0" memory "ps7 HP0_DDR_LOWOCM"} \
    S_AXI_HP1 {memport "S_AXI_HP" sptag "HP1" memory "ps7 HP1_DDR_LOWOCM"} \
    S_AXI_HP2 {memport "S_AXI_HP" sptag "HP2" memory "ps7 HP2_DDR_LOWOCM"} \
    S_AXI_HP3 {memport "S_AXI_HP" sptag "HP3" memory "ps7 HP3_DDR_LOWOCM"} \
    } [get_bd_cells /ps7]
    
     
    `
    • SDSoC产生的中断需要通过Concat模块转接到Zynq7000系列的F2P_irq端口
    `set intVar []
    for {set i 0} {$i < 16} {incr i} {
    lappend intVar In$i {}
    }
    set_property PFM.IRQ $intVar [get_bd_cells /xlconcat_0]
    
     
    `
    1. 生成HDL设计文件
    • File->Export->Export Hardware勾选include bitstream,点击OK,这一步的目的是生成.hdf文件,后面Petalinux会用到这个文件。
    1. 打包DSA文件
    • 将所有文件打包成DSA文件,在Tcl Console中输入下面指令
    `write_dsa –force <path_to_project>/PYNQ.dsa -include_bit
    
     
    `

    注意,SDSoC Hardware Platform的名称,即PFM_NAME下的要与Vivado工程名,block diagram名以及dsa文件名保持一致以免出现不必要的麻烦,在本教程中所有的名称都是PYNQ。

    • 验证DSA文件的正确.
    `validate_dsa <path_to_project>/PYNQ.dsa
    
     
    `

    SDSoC Software Platform

    Zynq启动时需要的文件包括kernel,device-tree,u-boot和fsbl,如果与PL部分相关,还需要.bit文件,这些文件除了.bit文件都可以由Petalinux生成,其中image.ub文件包含了kernel以及device-tree。

    Petalinux 简介

    PetaLinux 是Xilinx 提供的工具链, 用于生成Linux 内核映像, 根文件系统和ZYNQ 的内核模块, 例如带有可编程硬件的嵌入式系统(用于FPGA 部分中的不同硬件设计)。使用PetaLinux工具链, 我们可以轻松地为ZYNQ PS 构建内核和模块, 而无需使用单独的交叉编译工具。使用PetaLinux 的一个缺点是, 每个PetaLinux 版本都带有特定的Linux 内核版本。例如PetaLinux2017.4 带有4.9 的默认内核版本。赛灵思提供了一种方法来改变Petalinux 使用的默认内核版本, 读者可以通过百度搜索轻松找到它, 在此不赘述。注意:对于特定的硬件设计,PetaLinux 工具可以生成U-Boot 文件, 第一阶段启动加载程序(FSBL)和BOOT.BIN。使用Xilinx SDK 可以完成同样的事情。

    环境要求

    2017.4/2018.2 版本的工具链(包括Vivado,SDSoC,Petalinux)跟之前的版本有很大区别, 因此强烈建议版本与本文保持一致。此外,SDSoC,Vivado,Petalinux必须版本一致,本文在2017.4、2018.2均测试通过。

    • Ubuntu16.04 的PC
    • SD 卡(8GB 或更大)
    • SD 卡读卡器
    • 搭载ZYNQ 系列处理器的板卡, 本文在PYNQ 上测试通过
    • 装有Vivado2018.2的PC,Windows/Linux 均可

    安装Petalinux

    `$ sudo apt-get install gawk xvfb chrpath socat autoconf libtool git texinfo zlib1g-dev zlib1g-dev gcc-multilib libsdl1.2-dev libglib2.0-dev zlib1g-dev libncurses5-dev libssl-dev zlib1g:i386 –y
    
     
    `

    安装Petalinux 依赖的库

    `$ sudo mkdir -p /opt/pkg/petalinux
    $ cd /opt/pkg/
    $ sudo dpkg-reconfigure bash
    
     
    `

    UG1144 中提到所用到的/bin/sh 命令都需要是bash, 而Ubuntu 默认的/bin/sh 是dash, 在弹出界面选“否”来禁用dash, 选择bash

    `$ sudo chown USERNAME:users petalinux/ -R
    
     
    `

    USERNAME 替换成Ubuntu 的用户名,Petalinux 不能在root 权限下安装,,所以需要chown

    `$ cd <PATH to petalinux-v2017.4-final-installer.run>
    $ ./petalinux-v2017.4-final-installer.run /opt/pkg/petalinux
    
     
    `

    等待一段时间来到了Agreement 部分, 按Enter 进入协议文本, 按q 退出协议文本, 输入y 同意协议, 进入下一条协议, 若干次之后, 就进入安装部分, 再等待一段时间Petalinux 就安装完成了

    `$ source /opt/pkg/petalinux/settings64.sh
    
     
    `

    每次使用petalinux之前要先设置环境

    使用PetaLinux 为SDSoC Hardware Platform 生成image

    • 按照上一章介绍的方法生成PYNQ 的SDSoC Hardware Platform 的Vivado 工程, 生成bitstream。然后File->Export->Export Hardware, 勾选include bitstream, 在工程目录.sdk 文件夹下可以找到一个.hdf 文件(硬件描述文件)。
    • 创建Petalinux工程
    `$ petalinux-create –type project –template zynq –name PYNQ
    
     
    `

    新建Petalinux 工程, 命名为PYNQ,会自动生成一个名为PYNQ的文件夹

    `$ cd PYNQ/
    
     
    `

    将第一步中.hdf 文件复制到PYNQ 文件夹下

    `$ petalinux-config –get-hw-description ./
    
     
    `

    获取硬件描述文件, 然后会弹出一个图形界面

    在这里插入图片描述

    • 配置system config

      DTG Settings->Kernel Bootargs->generate boot args automatically 取消勾选该选项

      手动将bootargs 设置成

    `console=ttyPS0,115200 earlyprintk quiet
    
     
    `

    • 配置内核
    `$ petalinux-config -c kernel
    
     
    `

    Device Drivers->Generic Driver Options->Size in Mega Bytes(256)

    Device Drivers->Staging drivers (ON)->Xilinx APF Accelerator driver (ON)->Xilinx APF

    DMA engines support (ON)

    保存并退出

    • 手动添加设备树

      打开/project-spec/metauser/recipes-bsp/device-tree/files/system-user.dtsi, 添加如下几行

    `/{
    xlnk {
    compatible =“xlnx,xlnk-1.0;
    };
    };
    
     
    `

    • 编译工程
    `$ petalinux-build
    
     
    `

    编译结束后在images/linux下找到zynq_fsbl.elf, u-boot.elf, image.ub, 这些文件之后会用到。

    SDSoC Platform

    前两节我们已经准备好了搭建自己的SDSoC Platform所需要的文件,下面我们将介绍如何将这些文件组织成一个SDSoC Platform。一个典型的SDSoC Platform文件结构如下

    在这里插入图片描述

    创建自己的SDSoC Platform

    • 新建一个文件夹命名为boot,将上一节生成的zynq_fsbl.elf改名为fsbl.elf,和u-boot.elf文件放到该文件夹下,然后新建一个linux.bif文件,输入以下内容
    `/* linux */
    the_ROM_image:
    {
      [bootloader]<linux/boot/fsbl.elf>
      <bitstream>
      <linux/boot/u-boot.elf>
    }
    
     
    `
    • 打开SDSoC新建一个工程,Project type选择Platform Project,然后找到dsa文件,工程会自动命名为dsa文件的名称

    • 打开该工程

      在这里插入图片描述

      SDSoC Platform Project

    • 点击左下角Define System Configuration,添加以下内容

      在这里插入图片描述

      Define System Configuration

    boot directory里包含了u-boot.elf,fsbl.elf,这两个文件将与SDSoC生成的.bit文件打包在一起生成BOOT.BIN文件。

    • Add Processor Group/Domain

      在这里插入图片描述

      Add Processor Group/Domain

    这一步完成点击Generate Platform和Add to Custom Repositories将使该Platform可以被SDSoC工具找到。至此我们就完成了搭建最基础的SDSoC Platform的流程。

    转载自:https://blog.csdn.net/lulugay/article/details/83241716

    展开全文
  • 此外,为了提升系统性能,通常算法加速IP需要将运算时用到的数据先加载到PL上再进行计算,如例3代码所示。为了提升性能,将数据从内存搬运到PL的过程访问内存的方式是连续的,因此在本系列文章中所有SDSoC相关实验的...
  • 也可以用FPGA实现PCI接口 2. 开发驱动主要有3方面问题:硬件访问,中断处理,DMA传输  X86有两种地址空间:I/O地址(只有64KB),内存地址(4GB以上)  I/O映射:一个芯片的地址在I/O地址空间的范围,只能...
  • XPC论文总结

    2020-12-14 16:55:17
    微核是将特权模式下的功能最小化,并将大多数功能(包括分页、文件系统和设备驱动程序)放在隔离的用户模式域中,以实现细粒度的隔离、更好的可扩展性、安全性和容错。 2.当前基于微核的操作系统的实现仍然面临一个...
  • 6.1 Petalinux介绍 PetaLinux 是一种嵌入式Linux软件开发套件(SDK),主要用于XILINX FPGA基片上系统设计。由于其采用Buildroot构建系统,因此可以在简单的配置下,一步生成所需要的bootloader、kernel、rootfs镜像...
  • ,支持分页虚拟内存,所以可以移植 Linux 操作系统 具有兼容 IEEE 754-2008 标准的 FPU 具有分支预测功能,具有 BTB ( Branch Prediction Buff )、 BHT ( Branch History Table )、 RAS ...
  • BSP工程相关文件介绍

    千次阅读 2017-02-18 14:57:17
    函数的地址被链接过来,系统执行时会加载该库 INCLUDES :指定额外的要搜索的头文件的路径 SOURCES :指定要被编译的文件 ADEFINES :指定汇编器要使用的参数 CDEFINES :指定编译器要使用的参数 ...
  • S3c2410软件调试总结

    千次阅读 2009-08-13 08:38:00
     最低两位(10)是section分页的标识。  AP:Access Permission,区分只读、读写、SVC&其它模式。  Domain:每个section都属于某个Domain,一个有16个Domain,每个Domain的属性由CP15的R3寄存器控制。 在我得...
  • make xconfig详解

    千次阅读 2017-03-05 23:10:21
    3-Enable loadable module support (可加载模块支持) 4-Enable the block layer (块设备支持) 5-System Type (系统类型) 6-Bus support (总线支持) 7-Kernel Features (内核特征) 8-Boot options ...
  • 计算机组成原理

    2020-01-20 21:04:34
    FPGA:现场可编程门阵列,用存储换功能实现组合逻辑(有一张LUT表)、对于需要实现的时序逻辑电路,我们可以在 FPGA 里面直接放上 D 触发器,作为寄存器,FPGA 是通过可编程逻辑布线,来连接各个不同的 CLB,最终...
  • Quartus使用笔记

    千次阅读 2020-01-26 23:10:02
    右击分页线选择旋转可以改变分栏方向 2、更改文本的编码,在quartus中显示中文: 3、层次折叠及快捷键: 折叠快捷键推荐”ALT+2” 4、快速打开文件所在的文件夹: 5、带颜色代码粘贴功能: 先选中要粘贴的代码,再...
  • 这是 os summer of code 2020 每日记录的一部分: ...参考:RISC-V 手册 一本开源指令集的指南 第一章 为什么要有 RISC-V RISC-V的目标是成为一个通用的指令集...它应该适应所有实现技术,包括现场可编程门阵列(FPGA)、
  • 穿越时空的爱恋-Z80 CPU的前世今生

    千次阅读 2021-10-04 01:17:14
    CMOS Z80 四方封装 虽然Z80是兼容8080的,但是Z80 在 8080 基础上提供了许多改进: 增强型指令集包括: 一个更合乎逻辑、更易于理解和可读的汇编指令助记符系统 更灵活的 16 位数据移动(加载或 LD)指令,关键包括...
  • 加载modules时,又使用async.parallel,使其并行运作;当发生错误时,清理工作用到了async.eachSeries。 初始网络 我们知道,Express是Node.js重要的web开发框架,这里的网络network本质上就是以Express为基础...
  • 2 基于RISC-V的开源处理器研究现状  目前基于RISC-V架构的开源处理器有很多,既有标量处理器Rocket,也有超标量处理器BOOM,还有面向嵌入式领域的Z-scale、PicoRV32等。... 支持MMU,支持分页虚拟内存,所以可以
  • 深入浅出计算机组成原理(部分)

    千次阅读 2020-02-19 10:54:48
    25 CISC和RISC:为什么手机芯片都是ARM 26 GPU 27 FPGA和ASIC:计算机体系结构的黄金时代 28 解读TPU:设计和拆解一块ASIC芯片 29 理解虚拟机:你在云上拿到的计算机是什么样的? 原理篇:储存与I/O系统 30 存储器...
  • RISC-V架构总结1

    万次阅读 2019-03-09 19:49:03
    支持MMU,支持分页虚拟内存,所以可以移植Linux操作系统 具有兼容IEEE 754-2008标准的FPU 具有分支预测功能,具有BTB(Branch Prediction Buff)、BHT(Branch History Table)、RAS(Return Address Stack) ...
  • Linux kernel 配置选项

    千次阅读 2019-01-17 17:14:37
    General setup 常规设置 Cross-compiler tool prefix CONFIG_CROSS_COMPILE 交叉编译工具前缀(比如"arm-linux-"相当于使用"make CROSS_COMPILE=arm-linux-"进行编译)....Local version - append ...
  • 论文阅读(二)

    千次阅读 2017-01-05 10:34:42
    )仅仅在加载进行度量不能精确反应运行时的行为,比如说一些不可信的网络数据的使用 2 )这种方案效率低,即使对目标应用不相关的实体也必须要能够被度量。传统的完整性度量方案基于信息流图,所有本文设计了 PRIMA ...
  • 随笔

    2019-07-17 21:55:23
    FPGA程序加载必须把在后台运行的Reader关闭后再用 ./HD5000-Reader启动,查看下Reader自启的过程,看是否加载成功了,ddr自检是否通过。 swas702:~ # hwclock --hctosys (hc代表硬件时间,sys代表系统时间) swas...
  • ②检测系统的内存映射、③加载内核、文件系统到DDR、④设置内核的启动参数 补:单片机程序为什么禁止看门狗? 答:设置看门狗定时器的时候,必须先关闭它才能设置,否则在开启状态下设置看门狗定时器可能会出现问题...
  • Linux-4.4-x86_64 内核配置选项简介

    千次阅读 2018-11-08 21:55:23
    Enable loadable module support可加载模块支持 Enable the block layer块设备支持 Processor type and features中央处理器(CPU)类型及特性 Power management and ACPI options电源管理和ACPI选项 Bus ...
  • 另外,我们还在Bitmap计算与FPGA硬件结合方面做了技术探索,较之CPU场景,计算性能提升五倍以上。 Q: 单表可支持多大的数据量级?查询时延如何? A: 每一个Shard建议关联的Entity数量在千万级,可支持的数据量级与...
  • S3c2410软件调试总结

    2011-09-18 12:02:53
     最低两位(10)是section分页的标识。  AP:Access Permission,区分只读、读写、SVC&其它模式。  Domain:每个section都属于某个Domain,一个有16个Domain,每个Domain的属性由CP15的R3寄存器控制。 在我得...

空空如也

空空如也

1 2 3 4 5 6
收藏数 104
精华内容 41
关键字:

fpga分页加载