FPGA作为一种非常底层的硬件可编程逻辑芯片,实现数字逻辑电路可谓非常灵活,但是对于习惯了C语言和MCU编程的同学来说,从底层电路写到上层应用还是要费一番工夫的。
那么既想在FPGA里面灵活地设计底层电路,又希望像Arduino一样快速地开发应用程序,鱼与熊掌,可否兼得呢?
我们知道在MCU(Microcontroller Unit)中运行的是CPU硬核,比如Intel的8051核,ARM的Cortex-M核,Arduino板上用的AVR核等,各大半导体厂商在CPU Core的基础上集成了各种各样的外设模块,以适用于不同的应用需求。用户需要关心的就是这款MCU有哪些资源,寄存器如何配置。如果我想根据自己的应用需求来定制一款MCU,但是半导体厂商又不理我怎么办呢?办法总是有的,那就回到MCU出生之前的状态。通过将处理器内核移植到FPGA中,使用FPGA内部的逻辑资源和存储资源来构建一个软MCU,再通过内部总线挂载需要的外设电路就构成了一个定制化的MCU,我们称之为软核。
目前,在FPGA中移植软核已经是一种常见的做法,但是大多数MCU软核都是FPGA厂商定制的,比如Altera的Nios II、Xilinx的MicroBlaze和Lattice的MICO32/MICO8,这些软核并不完全开源并且对用户做了诸多限制。国外有一家名叫PulseRain Technology的公司开发并开源了一款高性能的MCU软核FP51-1T,该软核虽然基于8位的8051体系,但是它巧妙地实现了RISC架构,并且优化了指令集,大部分指令都可以单时钟周期实现,主频可以飙到100MHz以上,以二战时彪悍的野马战斗机P51来命名这款软核再合适不过了。
为方便调试,在软核内部集成了OCD(On Chip Debugger-片上调试)模块,PC主机只要通过RS232接口就可以实现程序下载、单步执行、断点调试等功能。这款软核最大的灵活性在于通过Wishbone总线挂载了Timer、SPI/I2C、UART、PWM、voice CODEC、microSD、 Serial SRAM等外设接口,为方便软件开发,PulseRain Technology提供了兼容Arduino的板卡支持包和软件开发库,将该软核移植到FPGA就可以使用Arduino来开发FPGA了。
FP51-1T结构图
FP51-1T软核采用最小资源配置及移植到Altera MAX10系列FPGA资源占用情况:
PulseRain FP51-1T 提供两种授权方式,一种开源授权(GPL v3),另一种商业授权,所有开源的代码已放在GitHub的仓库,但是如果要应用于商业目的的话还是要获得commercial license
FP51-1T MCU Core详细介绍☞FP51-1T MCU Core: A Mustang in FPGA
PulseRain推出的M10开发板使用Arduino开发详细介绍☞PulseRain M10: Play FPGA like Arduino
现在FP51-1T已经成功移植到STEP-MAX10开发板并且提供了Arduino板卡支持包。
下面我们使用STEP FPGA开发板来体验一下这个神奇的操作吧!
STEP-MAX10是小脚丫FPGA系列中基于Intel/Altera公司的FPGA芯片MAX10M08的FPGA开发板,它同样也采用了DIP40封装,小巧、携带方便,板载资源也是十分丰富,包含:
此外,板卡集成了下载器,用一根通用的MicroUSB数据线即可实现开发板的供电与下载。该开发板上使用的MAX1008芯片有8000个LE资源、最大172KB的用户闪存、378Kbit RAM,丰富的逻辑和存储资源保证了在移植完成软核后还有足够的余量来设计其它外设电路。
小脚丫STEP-MAX10实物图片
Quartus Prime是Altera被Intel收购之后推出的免费、强大的设计软件,包括了从设计输入到综合直至优化、验证以及仿真等各个阶段所需的一切功能。Quartus Prime Lite是大批量器件系列的理想设计工具,可以免费下载使用。
Quartus Prime下载安装、使用☞: Quartus Prime
Arduino是一款便捷灵活、方便上手的开源电子原型平台,包含硬件(各种型号的Arduino板)和软件(Arduino IDE)两大核心部分。Arduino IDE基于processing IDE开发,对于初学者来说极易掌握,同时有足够的灵活性。Arduino语言是基于wiring语言开发的,是对 avr-gcc库的二次封装,不需要太多的单片机基础和编程基础,只需简单学习后,你就可以快速的进行开发。
Arduino IDE的下载安装
Arduino IDE下载
使用Arduino IDE开发STEP-MAX10 FPGA的操作流程图如下:
M10 BSP for Arduino IDE(Copy from PulseRain)
FP51-1T的工程源代码已经开源在Github上,你可用如下的命令得到代码
git clone -b stepfpga https://github.com/PulseRain/Mustang.git stepfpga
这个操作会在本地目录建立一个stepfpga 目录
也可以直接点击链接https://github.com/PulseRain/Mustang.git ,注意在该Repository下有两个Branch,选择Branch:stepfpga
在网页的Clone or download选项中Download ZIP文件
cd step_fpga
进入该目录
git submodule update - - init - - recursive 注意init和recursive前面是两个 -
更新所有的submodules
该项目是用 Quartus prime 16.1 Lite Edition 编译的,项目文件在 Synth/Mustang_fast.qpf
(注意转发源码时请保留源码开头的版权声明)
FP51-1T是一个兼容8051体系的高性能8位MCU,通过巧妙地RISC架构实现,大部分指令都可以单周期实现,主频可以跑到96MHz。为方便调试,在软核内部集成了OCD(On Chip Debugger - 片上调试)模块,PC主机只要通过RS232接口就可以实现程序的下载、单步执行、设置断点等调试功能。另外,该软核通过Wishbone总线挂载了多个外设模块,如Timer、UART、SPI/I2C、PWM、Voice CODEC、microSD socket、 SRAM、onchip ADC等,用户可以裁剪和添加这些外设。
FP51-1T MCU结构图
使用Quartus prime 打开工程文件 Mustang_fast.qpf。
该工程包含了FP51-1T CORE及常用的外设模块,这些外设模块适用于STEP-MAX10 和 STEP FPGA Baseboard开发板,包括旋转编码器、七段数码管、PS/2键盘接口、PWM背光控制、LED显示、LCD显示。
如果需要连接其他外设,我们也可以修改软核,但是需要同时修改编译器的文件,这里我们默认现有的外设不做修改。
STEP-MAX10 FPGA开发板上面默认板载资源有:
底板外设模块如下图所示:
直接从GitHub上clone的项目已默认编译,使用Micro USB数据线连接PC和开发板后,使用Quartus Prime软件可以直接下载到STEP-MAX10芯片。
如果不熟悉Quartus prime的使用可以先学习这里的上手教程quartus_prime的使用。
如果不熟悉FPGA的开发可以先学习入门教程step-max10入门教程。
Arduino IDE可以支持第三方板子的开发,但是需要安装第三方板卡的支持包。
打开Arduino IDE,打开 文件——首选项——附加开发板管理器网址,添加如下链接:
https://raw.githubusercontent.com/PulseRain/Arduino_M10_IDE/step_fpga/package_M10_index.json
Arduino中添加板卡支持包链接
确定后,打开 工具——开发板——开发板管理器,在搜索框中输入“STEPFPGA”会出现名为StepFPGA_M10的板卡支持包,点击安装
Arduino中安装板卡支持包
下载安装完成后在板卡管理器中有StepFPGA M10这个选项。 该BSP主要包括三部分:FP51 Core、SDCC Compiler和Target Downloade Tools
Arduino之所以开发简单快速,是因为Arduino官方和众多的开源硬件爱好者贡献了大量的应用软件库,对于常见外设接口或模块的软件库都可以从网上下载到,而且能非常方便的嵌入到我们的程序中。
PulseRain 为FT51-1T MCU提供了常用外设接口的软件库如I2C,microSD,CODEC,PWM,ESP8266等,而且有详细的文档说明 ☞https://www.pulserain.com/m10。
我们在Arduino IDE中打开 项目——加载库——管理库,在库管理器窗口搜索框中输入“M10”,会有M10LCD,M10PWM等外设库。
点击 安装 需要的库文件。这里我们安装M10LCD,M10PWMM,10SevenSeg三个库文件。
Arduino中安装库文件
用户在程序中如果需要用到某个库,只需要在项目——加载库,选择相应的库,即可将该库的头文件包含到应用程序中。
在Arduino IDE 工具一栏,选择 开发板为StepFPGA M10, 搭建好软硬件环境,我们可以开始开发自己的应用程序了,这里我们编写一段应用程序实现以下功能:
应用程序☛ Play FPGA like Arduino step_test APP
在该程序中除了我们的应用程序之外,还包括了Arduino.h软件库,FP51 Core lib,另外用到了两个外设库M10PWM和M10SevenSeg。
点击Arduino IDE的验证✔选项开始编译,程序编译结果会在下面的信息栏中给出。
这里建议用户在Preferences对话框 (菜单File / Preferences) 中打开“Show Verbose Output”选项,这样信息栏中会给出详细的编译结果。
Arduino开发板之所以能够使用串口实现一键下载,是因为在主控制器内部有Bootloader,而在我们的软核内部没有使用软件bootloader,而是在软核中嵌入了OCD (onchip debugger)模块,相当于MCU内部的硬件BOOT模块,通过外接串口同样可以实现串口一键下载。只不过程序下载到FPGA内部的SRAM区,掉电数据会丢失,如果想程序掉电不丢失还是需要将Arduino IDE 生成的.hex文件通过Quatus prime烧录到MAX10内部的Flash区。
STEP FPGA Baseboard板载了一片USB转串口芯片CP2102,通过Micro USB数据线连接到PC USB口,在设备管理器中会出现一个端口号,如COM5
在Arduino IDE中选择工具——端口,选择对应的端口号。在工具——编程器一栏选择编程器为USBasp。
点击上传按钮⇒,软件会对程序编译后下载到板子。
演示效果
Arduino中开发STEP-MAX10 FPGA演示效果
Step FPGA M10采用Single Compressed Image设置, 在该设置下, 其片上闪存的地址如下图所示:
在上图所示的4个分区中, 分区1和2一共有32KB, 被用来存放代码。 PulseRain FP51-1T MCU的缺省配置有32KB Instruction RAM和8KB Data RAM. 分区1和2 正好和FP51-1T MCU的 Instruction RAM 大小相对应.在上电启动时,source / codemempoweronloader.sv 会把用户的代码从闪存分区1和2载入到Instruction RAM 中并执行。
闪存分区3目前被用来存放LOGO图片,该图片可以在LCD上显示。STEP Base Board自带的LCD有132 x 162的分辨率。这里建议用户存放一个大小为128 x 154的真彩图片在这个分区。
在 synth / outputfiles下有一个叫pic2hex.py的Python Script,可以把图片转换为 .hex 文件。该目录下的 bitmap.hex 就是由同一目录下的pulsestep.png生成的。
当用户用Arduino IDE 编译Sketch以后,可以把Arduino生成的.hex 文件的最后一行删除,并与bitmap.hex合并,并将合并后的文件命名为synth/output_files/ufm.hex。
这样在生成FPGA Image时,ufm.hex 会被自动包含在最后生成的Image里面。
用户可以用Intel Quartus Prime打开synth / Mustangfast.qpf , 并点击“Start a new compilation”,
Mustang project 内含一个叫postflow.tcl的script.这个script会自动做文件合成与转换.
转换结束后,在synth/outputfiles/flashimages/fullimage.pof就是最后需要的FPGA Image. 如果用户需要把数据放入UFM的话,只需把对应的.hex文件命名成ufm.hex,
并放到synth/outputfiles/之下, post_flow.tcl 会自动将其包含到最终的FPGA Image里面.
使用Quartus Prime下载.pof文件到FPGA内部Flash中。
如果用户需要增加新的外设的话, 具体步骤如下(以LCD为例)
1. 编写RTL模块, 并且simulate, 比如
GitHub\stepfpga\submodules\PulseRainFP51MCU\submodules\PulseRainrtllib\LCD下面的那些文件
2. 给新增加的外设分配SFR 地址, 地址分配见
GitHub\stepfpga\submodules\PulseRainFP51MCU\common\SFR.svh
parameter unsigned [DATAWIDTH - 1 : 0] LCDCSRADDR = 8'hC1;
parameter unsigned [DATAWIDTH - 1 : 0] LCDDATAADDR = 8'hC2;
3. 更改 GitHub\stepfpga\submodules\PulseRainFP51MCU\peripherals\peripherals.sv
把新外设增加到Peripheral bus上. 由于新的外设增加了新的管脚, 所以除了peripherals.sv 之外,
GitHub\stepfpga\submodules\PulseRainFP51MCU\source\PulseRainFP51MCU.sv 和
GitHub\stepfpga\source\Mustangfast.sv 也要相应修改, 在port list 中增加管脚. 比如
output wire LCDBL,
output wire LCDDATCMD,
output wire LCDRES,
inout wire LCDSDA,
inout wire LCDSCL,
4. 对新增的管脚做Constrain, 比如Pin assignment, voltage level 等
5. 由于新增加了SFR, Arduino 编译器的SFR定义也要相应修改. 编译器的SFR头文件通常被安装在
C:\Users...\AppData\Local\Arduino15\packages\StepFPGAM10\tools\M10compiler...\SDCC\include\mcs51\8051.h