APP下载

基于Cortex-A8微处理器的FPGA配置接口设计

2018-09-19张春雷赵成龙瞿佳伟

精密制造与自动化 2018年3期
关键词:存储器寄存器时钟

唐 星 张春雷 陈 龙 赵成龙 张 冀 瞿佳伟

(四川大学 制造科学与工程学院 成都610065)

在嵌入式系统中,FPGA上电时,需要从外部加载配置文件,该过程被称为程序加载。在多数应用中,FPGA通过主动读取的方式从外部存储器加载程序,该方式只能加载固定的配置,不便于升级更新,且需要额外的存储器件才能实现[1]。本文设计了一种对FPGA芯片进行程序加载的接口,通过Cortex-A8微处理器对FPGA进行配置,不需要单独的存储器,使用微处理器通用 IO模拟接口时序实现,配置灵活,不占用专用接口资源,可以在线升级FPGA固件。

1 FPGA的配置概述

本设计选用的FPGA是Spartan-6 XC6SLX16,该芯片正常工作时配置数据保存在SRAM单元中,该单元也被称为配置存储器(Configuration RAM)。由于SRAM是易失性存储器,掉电之后必须重新配置[2]。配置信息通过特定的配置方式加载到芯片里,SPARTAN6 FPGA支持多种配置方式,包括:JTAG配置模式、Master Serial主动串行(Serial/SPI)配置模式(x1、x2 and x4)、Slave Serial被动串行配置模式、Master SelectMAP主动并行模式(x8 and x16)、Slave SelectMAP被动并行模式(x8 and x16)[3]。

主动和被动的区别在于数据采样的时钟来源:由FPGA输出时钟到存储器,属于主动模式,由外部器件给 FPGA提供时钟,属于被动模式。XC6SLX16通过两个模式配置寄存器M[1:0]来确定其使用的模式,该寄存器的值在芯片初始化后通过对 M1、M0两个管脚采样进行确定。本设计采用FPGA的串行从模式进行配置,对应的M1、M0引脚均为高电平。开始配置时,微处理器把Program_B引脚电平由高拉低并持续超过 500ns,强制XC6SLX16进入配置模式,清除片内 SRAM,Program_B引脚电平变高以后,XC6SLX16将INT和 DONE引脚清零,当SRAM清除完毕且 M1,M0引脚采样完成后,XC6SLX16将INT引脚电平拉高,微控制器此时可以开始通过CCLK和D0引脚发送配置数据,XC6SLX16在每个CCLK上升沿时采样1bit配置数据并写入芯片,如果中途出现校验错误,INT脚将变低报错,当配置成功完成后,XC6SLX16将DONE信号拉高,通知微控制器配置成功。Spartan 6 FPGA串行从模式配置过程的时序如图1所示。

图1 Spartan 6 FPGA串行从模式配置接口时序

2 接口设计

2.1 接口硬件设计

本设计选用的微处理器是基于Cortex-A8内核的处理器 AM3352,工作频率为 600MHz,具有NEON/SIMD协处理器,支持Linux,WinCE操作系统,具有丰富的外设接口[4]。FPGA配置接口使用5个GPIO实现,FPGA与固件配置相关的5个引脚都接到AM3352的GPIO上,FPGA_INT信号用于标识 SRAM 清除完毕,可以开始传输数据,FPGA_PROGRAM 信号用于启动配置流程,FPGA_DONE信号用于标识配置过程成功完成,AM3352通过这个引脚的信号判断配置是否成功,FPGA_CCLK信号为AM3352输出到FPGA的时钟信号,每个上升沿时,FPGA从FPGA_D0引脚上采集1bit配置数据。接口硬件原理如图2所示。

图2 配置接口硬件原理图

2.2 接口软件设计

配置接口的软件在运行于AM3352上的Linux中实现,接口软件分为字符设备驱动和应用程序两部分。字符设备驱动程序实现配置 IO的初始化和读写以及数据写入的接口,应用程序通过调用驱动接口实现配置流程[5],软件模块构架如图3所示。

图3 软件模块构架

驱动模块的核心功能是对用来配置FPGA的5个GPIO管脚进行控制,包括引脚的初始化,IO状态的读取和控制,时钟和数据的发送。根据AM3352数据手册提供的寄存器表,利用Linux 3.2内核中提供的API函数,完成此驱动程序的编写,其中模块加载函数 fpga_config_init()使用 ioremap()函数完成GPIO置位和清位寄存器的映射,以保证在内核中能通过虚拟内存地址正确地访问到硬件寄存器,接着初始化各个IO为正确的上下拉和输入输出模式,其中 INT、DONE信号为上拉输入模式,PROGRAM_B、CCLK、D0为输出模式。通过register_chrdev()注册该接口的 file_operations结构体并返回得到驱动程序的主设备号,通过class_create()和device_create()接口创建设备,设备名称为 fpga_config,当驱动被加载后,Linux文件系统的/dev目录下就会出现该设备。fpga_config_ioctl()接口用于完成对输出引脚的操作,包括 PROGRAM_B脚、CCLK脚、D0脚。fpga_config_read()接口用于读取INT、和DONE脚的电平,通过该接口判断 FPGA当前的状态。fpga_config_write()用于AM3352向FPGA写入配置数据,其中将应用程序传入的数据按位赋予D0引脚,然后操作CCLK引脚生成时钟信号,FPGA在CCLK信号上升沿读取1bit数据,为了加快发送的速率,此处对CCLK和D0脚直接使用寄存器操作设置高低电平,gpio3SetData和 gpio3ClearData分别为GPIO3的置位寄存器和清位寄存器指针,当向gpio3SetData指向的地址写值时,该值有效位(为1)对应的引脚被置高,其余引脚保持不变,当向gpio3ClearData指向的地址写值时,该值有效位(为1)对应的引脚被置低,其余引脚保持不变[6]。写入配置数据部分的驱动示例代码如下:

//直接操作寄存器以加快速度

应用程序部分通过调用 open()函数打开配置接口设备,通过 ioctl()函数拉低 PROGRAM_B引脚1ms后再拉高来开启配置,1ms后调用read()读取引脚状态,检测INT脚是否为高电平,若为高,则开始调用write()函数,将从文件系统读取的配置数据通过配置接口写入FPGA,写入完成后,通过read()函数读取DONE信号状态,判断配置是否成功。若INT不为高或者DONE信号不为高,则认为FPGA配置失败并打印错误信息。

3 实验应用

本实验平台为一款嵌入式多轴运动控制器,该控制器基于ARM+FPGA架构,运行Linux3.2系统,具有四轴脉冲方向输出,最大输出脉冲频率为2MHz。运行Linux系统的AM3352负责实现运动控制,读取加工文件,主从USB、网络、串口等功能,FPGA负责发送脉冲控制电机驱动器以及IO口操作,AM3352通过GPMC接口和FPGA进行数据交换,使用本文设计的配置接口进行FPGA的配置,其系统框图如图4所示。

图4 实验平台系统框图

完成以上代码编写后,编写 makefile,编译内核模块为 fpga_config.ko和应用程序 fpga_loader,编译器为 arm-linux-gnueabihf-gcc,操作系统为Ubuntu 12.04.5 32位。控制器上Linux系统启动后,通过 insmod命令加载 fpga_config.ko模块,配置FPGA开发工具ISE生成二进制配置文件fpga.bin[7],使用./fpga_loader /firmware/fpga.bin命令加载配置文件,通过200MHz逻辑分析仪采集加载过程的波形如图5所示。

图5 配置过程波形

分析波形可得总配置时间为0.46s,CCLK时钟最大频率8.33MHz,本设计使用的FPGA速度等级为2C,串行从模式下该等级最大外部输入时钟为80MHz[3],该频率高于配置过程最大时钟频率。通过应用程序打印的信息,可知配置及加载成功。

4 结语

通过AM3352的GPIO模拟FPGA配置接口时序,实现了在线配置FPGA的功能,省去了常见的外接FLASH芯片的成本。这种配置方式实现灵活,不占用微控制器专用接口资源,方便对FPGA固件进行升级和更新操作,达到了设计要求。

猜你喜欢

存储器寄存器时钟
STM32和51单片机寄存器映射原理异同分析
别样的“时钟”
静态随机存储器在轨自检算法
古代的时钟
Lite寄存器模型的设计与实现
移位寄存器及算术运算应用
有趣的时钟
任意2~k点存储器结构傅里叶处理器
时钟会开“花”
存储器——安格尔(墨西哥)▲