#### 使用Arduino玩转FPGA
---
#### 鱼与熊掌,不可兼得?
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,我们称之为软核。 \\
#### 软核中的野马战斗机——FP51-1T
目前,在FPGA中移植软核已经是一种常见的做法,但是大多数MCU软核都是FPGA厂商定制的,比如Altera的Nios II、Xilinx的MicroBlaze和Lattice的MICO32/MICO8,这些软核并不完全开源并且对用户做了诸多限制。国外有一家名叫PulseRain Technology的公司开发并开源了一款高性能的MCU软核[[https://www.pulserain.com/fp51|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结构图.png?500 |}}
**FP51-1T结构图**
\\
FP51-1T软核采用最小资源配置及移植到Altera MAX10系列FPGA资源占用情况:
* 8051 1T MCU Core
* 16KB Code Memory,16KB Data Memory
* 2 Timer
* 1 Watchdog Timer / LED Controller
* 1 RS-232 UART,1 JTAG UART
* OCD
{{::fp51-1t资源.png?400|}} \\
\\
PulseRain FP51-1T 提供两种授权方式,一种开源授权(GPL v3),另一种商业授权,所有开源的代码已放在[[https://github.com/PulseRain|GitHub的仓库]],但是如果要应用于商业目的的话还是要获得commercial license \\
FP51-1T MCU Core详细介绍☞[[https://www.pulserain.com/fp51|FP51-1T MCU Core: A Mustang in FPGA]] \\
PulseRain推出的M10开发板使用Arduino开发详细介绍☞[[https://www.pulserain.com/m10|PulseRain M10: Play FPGA like Arduino]] \\
\\
现在FP51-1T已经成功移植到STEP-MAX10开发板并且提供了Arduino板卡支持包。 \\
下面我们使用STEP FPGA开发板来体验一下这个神奇的操作吧!
#### 使用Arduino开发STEP-MAX10 FPGA
##### 准备工作
* 小脚丫FPGA开发板 STEP-MAX10 08系列
* Intel Quantus Prime软件
* Arduino IDE
###### 准备1:STEP-MAX10 FPGA开发板 — FPGA型号Intel MAX10-08系列
STEP-MAX10是小脚丫FPGA系列中基于Intel/Altera公司的FPGA芯片MAX10M08的FPGA开发板,它同样也采用了DIP40封装,小巧、携带方便,板载资源也是十分丰富,包含:
* 4路轻触按键
* 4路拨码开关
* 8路用户LED
* 2路RGB_LED三色灯
此外,板卡集成了下载器,用一根通用的MicroUSB数据线即可实现开发板的供电与下载。该开发板上使用的MAX1008芯片有8000个LE资源、最大172KB的用户闪存、378Kbit RAM,丰富的逻辑和存储资源保证了在移植完成软核后还有足够的余量来设计其它外设电路。
{{ ::zhege2.png?500 |}}
**小脚丫STEP-MAX10实物图片**
###### 准备2:Intel Quantus Prime软件
Quartus Prime是Altera被Intel收购之后推出的免费、强大的设计软件,包括了从设计输入到综合直至优化、验证以及仿真等各个阶段所需的一切功能。Quartus Prime Lite是大批量器件系列的理想设计工具,可以免费下载使用。
Quartus Prime下载安装、使用☞: [[Quartus Prime]]
###### 准备3:Arduino IDE软件
Arduino是一款便捷灵活、方便上手的开源电子原型平台,包含硬件(各种型号的Arduino板)和软件(Arduino IDE)两大核心部分。Arduino IDE基于processing IDE开发,对于初学者来说极易掌握,同时有足够的灵活性。Arduino语言是基于wiring语言开发的,是对 avr-gcc库的二次封装,不需要太多的单片机基础和编程基础,只需简单学习后,你就可以快速的进行开发。 \\
Arduino IDE的下载安装
[[https://www.arduino.cc/en/Main/Software|Arduino IDE下载]]
----
#### 操作步骤
- 获取PulseRain FP51-1T MCU软核
- Arduino IDE安装板卡和软件支持包
- 在Arduino IDE中开发应用程序
- 配置软核到STEP-MAX10 FPGA开发板
- 定制自己的硬件外设
使用Arduino IDE开发STEP-MAX10 FPGA的操作流程图如下:
{{ ::m10_bsp_for_arduino_ide.png?700 |m10_bsp_for_arduino_ide}}
**M10 BSP for Arduino IDE(Copy from PulseRain) **
##### 步骤1:获取PulseRain FP51-1T MCU软核
###### 1.Clone 软核源代码
FP51-1T的工程源代码已经开源在Github上,你可用如下的命令得到代码 \\
**git clone -b step_fpga https://github.com/PulseRain/Mustang.git step_fpga** \\
这个操作会在本地目录建立一个step_fpga 目录 \\
也可以直接点击链接https://github.com/PulseRain/Mustang.git ,注意在该Repository下有两个Branch,选择Branch:step_fpga \\
在网页的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 \\
(**注意转发源码时请保留源码开头的版权声明**) \\
###### 2.软核外设介绍
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结构图.png?800 |FP51-1T MCU结构图}}
**FP51-1T MCU结构图**
使用Quartus prime 打开工程文件 Mustang_fast.qpf。\\
该工程包含了FP51-1T CORE及常用的外设模块,这些外设模块适用于STEP-MAX10 和 [[step-baseboard|STEP FPGA Baseboard]]开发板,包括旋转编码器、七段数码管、PS/2键盘接口、PWM背光控制、LED显示、LCD显示。\\
如果需要连接其他外设,我们也可以修改软核,但是需要同时修改编译器的文件,这里我们默认现有的外设不做修改。\\
STEP-MAX10 FPGA开发板上面默认板载资源有:
* 2位七段数码管;
* 2个RGB三色LED;
* 4路拨码开关;
* 4路按键;
* 36个用户可扩展I/O,这36个可扩展I/O可以与底板外设连接
底板外设模块如下图所示: \\
{{:: 底板外设接口图.png?360 |底板外设接口}}
{{:db.png?650|}}
\\
直接从GitHub上clone的项目已默认编译,使用Micro USB数据线连接PC和开发板后,使用Quartus Prime软件可以直接下载到STEP-MAX10芯片。 \\
{{ ::stepmax10编译结果.png?440 |}} \\
如果不熟悉Quartus prime的使用可以先学习这里的上手教程[[quartus_prime的使用]]。 \\
如果不熟悉FPGA的开发可以先学习入门教程[[step-max10入门教程]]。 \\
##### 步骤2:Arduino IDE安装板卡支持包和软件库
###### 1.安装板卡支持包
Arduino IDE可以支持第三方板子的开发,但是需要安装第三方板卡的支持包。 \\
打开Arduino IDE,打开 **文件**——**首选项**——**附加开发板管理器网址**,添加如下链接: \\
**https://raw.githubusercontent.com/PulseRain/Arduino_M10_IDE/step_fpga/package_M10_index.json** \\
{{ :arduino添加板卡支持包链接.png?400 |}}
**Arduino中添加板卡支持包链接**
确定后,打开 **工具**——**开发板**——**开发板管理器**,在搜索框中输入“STEPFPGA”会出现名为StepFPGA_M10的板卡支持包,点击**安装**
{{ ::arduino安装板卡支持包2.png?500 |}}
**Arduino中安装板卡支持包**
下载安装完成后在板卡管理器中有StepFPGA M10这个选项。
该BSP主要包括三部分:FP51 Core、[[http://sdcc.sourceforge.net/|SDCC]] Compiler和Target Downloade Tools
###### 2.安装软件库
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加载库.png?500 |}}
**Arduino中安装库文件**
用户在程序中如果需要用到某个库,只需要在**项目**——**加载库**,选择相应的库,即可将该库的头文件包含到应用程序中。
##### 步骤3:在Arduino IDE中开发应用程序
在Arduino IDE **工具**一栏,选择 **开发板**为**StepFPGA M10**, 搭建好软硬件环境,我们可以开始开发自己的应用程序了,这里我们编写一段应用程序实现以下功能:
*在串口以115200 bps 输出 Hello World!然后输出PS2键盘的Scancode
*在7段管上显示旋转编码器的数字。转动旋转编码器数字会加减,LED也会随旋转编码器相应变化,1.8'LCD亮度也会变化。
*LCD显示一张带有小脚丫和PulseRain LOGO的图片
*按键1设置为MCU的复位键
应用程序☛ [[Play FPGA like Arduino step_test APP]] \\
\\
在该程序中除了我们的应用程序之外,还包括了Arduino.h软件库,FP51 Core lib,另外用到了两个外设库M10PWM和M10SevenSeg。 \\
{{::fp51_bsp.png?400|}} \\
\\
点击Arduino IDE的**验证****✔**选项开始编译,程序编译结果会在下面的信息栏中给出。 \\
这里建议用户在Preferences对话框 (菜单File / Preferences) 中打开"Show Verbose Output"选项,这样信息栏中会给出详细的编译结果。 \\
{{::fp51arduino编译结果.png?500|}}
##### 步骤4:配置软核到STEP-MAX10 FPGA开发板
###### 1.串口一键下载
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_fp51_底板程序1.jpg?500 |}}
**Arduino中开发STEP-MAX10 FPGA演示效果**
\\
###### 2.片上闪存的配置(Onchip Flash Memory)
Step FPGA M10采用Single Compressed Image设置, 在该设置下, 其片上闪存的地址如下图所示:
{{ :max10闪存配置.png |}} \\
在上图所示的4个分区中, 分区1和2一共有32KB, 被用来存放代码。 PulseRain FP51-1T MCU的缺省配置有32KB Instruction RAM和8KB Data RAM. 分区1和2 正好和FP51-1T MCU的 Instruction RAM 大小相对应.在上电启动时,source / code_mem_power_on_loader.sv 会把用户的代码从闪存分区1和2载入到Instruction RAM 中并执行。 \\
闪存分区3目前被用来存放LOGO图片,该图片可以在LCD上显示。STEP Base Board自带的LCD有132 x 162的分辨率。这里建议用户存放一个大小为128 x 154的真彩图片在这个分区。 \\
在 synth / output_files下有一个叫pic2hex.py的Python Script,可以把图片转换为 .hex 文件。该目录下的 bitmap.hex 就是由同一目录下的pulse_step.png生成的。 \\
当用户用Arduino IDE 编译Sketch以后,可以把Arduino生成的.hex 文件的最后一行删除,并与bitmap.hex合并,并将合并后的文件命名为synth/output_files/ufm.hex。 \\
这样在生成FPGA Image时,ufm.hex 会被自动包含在最后生成的Image里面。
###### 3.烧录程序到MAX10 FPGA内部Flash
用户可以用Intel Quartus Prime打开synth / Mustang_fast.qpf , 并点击"Start a new compilation", \\
Mustang project 内含一个叫post_flow.tcl的script.这个script会自动做文件合成与转换. \\
转换结束后,在synth/output_files/flash_images/full_image.pof就是最后需要的FPGA Image. 如果用户需要把数据放入UFM的话,只需把对应的.hex文件命名成ufm.hex, \\
并放到synth/output_files/之下, post_flow.tcl 会自动将其包含到最终的FPGA Image里面. \\
使用Quartus Prime下载.pof文件到FPGA内部Flash中。 \\
##### 步骤5:定制自己的硬件外设
如果用户需要增加新的外设的话, 具体步骤如下(以LCD为例) \\
1. 编写RTL模块, 并且simulate, 比如 \\
GitHub\step_fpga\submodules\PulseRain_FP51_MCU\submodules\PulseRain_rtl_lib\LCD下面的那些文件 \\
2. 给新增加的外设分配SFR 地址, 地址分配见 \\
GitHub\step_fpga\submodules\PulseRain_FP51_MCU\common\SFR.svh \\
parameter unsigned [DATA_WIDTH - 1 : 0] LCD_CSR_ADDR = 8'hC1; \\
parameter unsigned [DATA_WIDTH - 1 : 0] LCD_DATA_ADDR = 8'hC2; \\
3. 更改 GitHub\step_fpga\submodules\PulseRain_FP51_MCU\peripherals\peripherals.sv \\
把新外设增加到Peripheral bus上. 由于新的外设增加了新的管脚, 所以除了peripherals.sv 之外, \\
GitHub\step_fpga\submodules\PulseRain_FP51_MCU\source\PulseRain_FP51_MCU.sv 和 \\
GitHub\step_fpga\source\Mustang_fast.sv 也要相应修改, 在port list 中增加管脚. 比如 \\
output wire LCD_BL, \\
output wire LCD_DAT_CMD, \\
output wire LCD_RES, \\
inout wire LCD_SDA, \\
inout wire LCD_SCL, \\
4. 对新增的管脚做Constrain, 比如Pin assignment, voltage level 等 \\
5. 由于新增加了SFR, Arduino 编译器的SFR定义也要相应修改. 编译器的SFR头文件通常被安装在 \\
C:\Users\...\AppData\Local\Arduino15\packages\StepFPGA_M10\tools\M10_compiler\...\SDCC\include\mcs51\8051.h \\
#### 相关设计资源
* {{::step_fpga_m10_user_guide_cn.pdf|STEP FPGA FP51-1T MCU中文用户手册 }} \\
* {{::datasheet_fp8051_1t.pdf|FP51-1T Datasheet}} \\
* {{::pulserain_8_bit_mcu_trm.pdf|FP51-1T Technical Reference Manual}} \\
* [[https://github.com/PulseRain/Mustang/tree/step_fpga|Repository for FPGA]] \\
* [[https://github.com/PulseRain/Arduino_M10_IDE/tree/step_fpga|Repository for Arduino IDE package]] \\
* [[https://github.com/PulseRain/M10_high_speed_config_rtl|TRM for M10 High Speed Configuration]] \\
* [[https://github.com/PulseRain|Repository for Peripherals]] \\