基于ECP5的RISC-V移植
本设计旨在将RISC-V软核PulseRain Reindeer设计移植到ECP5 FPGA上,并通过一个流水灯以及串口打印应用程序来验证软核的正确性。
标签
RISC-V
FPGA
ECP5
Daggal
更新2023-08-30
成都信息工程大学
1207

一、概述

对于ECP5的RISC-V移植采用了PulseRain Reindeer设计。PulseRain Reindeer是冯·诺依曼架构的软CPU。它支持RISC-V RV32I[M]指令集,并具有2 x 2流水线。它在速度和面积之间取得平衡,并为所有FPGA平台上的软CPU提供了灵活的选择。

亮点2x2流水线

PulseRain Reindeer的流水线由4个阶段组成:

  • 指令提取(Instruction Fetch)
  • 指令解码(Instruction Decode)
  • 指令执行(Instruction Execution)
  • 寄存器回写和内存访问(Reg and Mem access)

但是,与传统流水线不同,PulseRain Reindeer的流水线映射到 2 x 2 布局,如下Scheme-it绘制的框图所示:

FqLLrqhb5f8eZ-Tj1_RRVvyWMxQV

在 2 x 2 布局中,每个级每隔一个时钟周期处于活动状态。对于偶数周期,只有Instruction Fetch和Instruction Execution阶段处于活动状态,而对于奇数周期,只有Instruction Decode和Reg and Mem access阶段处于活动状态。这样,指令提取和内存访问总是发生在不同的时钟周期上,从而避免了单端口存储器造成的结构危险。

亮点 保持和加载

引导软 CPU 往往令人头疼。传统方法或多或少类似于以下内容:

  1. 在软件中制作引导加载程序
  2. 将引导加载程序存储在 ROM 中
  3. 开机复位后,引导加载程序应该首先执行,为此它将其余代码/数据移动到RAM中。之后,PC将设置为新映像的_start地址。

上述方法的缺点是:

  1. 引导加载程序或多或少会侵入性,因为它占用内存空间。
  2. ROM 的实现在所有 FPGA 平台上并不一致。对于某些 FPGA,如英特尔 Cyclone 或 Xilinx Artix,存储器初始数据可以存储在 FPGA 比特流中,但其他平台可能会选择使用外部闪存来存储 ROM 数据。引导加载程序本身可以就地执行,也可以加载一个在FPGA结构中实现的小型预加载器。当涉及到SoC + FPGA时,就像Microsemi Smartfusion2一样,硬核处理器也可能参与引导加载。换句话说,软CPU可能需要对应更改才能在各种平台上工作。

为了打破现状,PulseRain Reindeer采用了一种称为“保持和加载”的不同方法,该方法将基于硬件的OCD(片上调试器)带到了前台,如下图所示:Fm3kgCpmdkv6rTlTbHj25VvfOj3Q

软 CPU 和 OCD 可以共享同一个 UART 端口,如上图所示。RX 信号同时进入软 CPU 和 OCD,而 TX 信号必须通过多路复用器。而那个多路复用器是由强制控制的。

重置后,软CPU将进入保持状态,默认情况下可以访问UART TX端口。但是从主机PC发送的有效调试帧可以让OCD重新配置多路复用器并将UART TX切换到OCD端,可以访问内存,并且可以交换控制。在 CPU 保持状态期间,可以将新的软件映像加载到内存中,这会产生“保持和加载”的名称。

在内存加载新映像后,OCD可以设置软CPU的起始地址,并发送启动脉冲使软CPU处于活动状态。此时,OCD可以将UART TX切换回CPU端以进行CPU输出。

由于保持和加载从外部主机获取软件映像,因此它不需要任何 ROM。这使得它在所有FPGA平台上的可移植性更高。如果使用闪存来存储软件映像,则可以稍微修改OCD,以便从闪存而不是外部主机读取。

 

二、使用比特流对硬件进行编程

本次设计采用了Reindeer_MachXO3D的工程,将工程文件中MachXO3D的IP核、存储以及管脚等对应替换为ECP5。

Reindeer_MachXO3D的github工程文件:PulseRain/Reindeer_MachXO3D:Port Reindeer to Lattice MachXO3D 分线板 (github.com)

克隆 GitHub 存储库

$ git clone https://github.com/PulseRain/Reindeer_MachXO3D.git

$ cd Reindeer_MachXO3D

$ git submodule update --init --recursive

移植工程

1、通过Reindeer_MachXO3D\build\lattice\MachXO3D_Breakout目录下的MachXO3D.ldf打开Lattice Diamond工程。

Fn6DYVRj9YsNOFl_f6Tjj8tQL4Mu

2、打开project->Device。

Fja2d6xfc0PJFMtFlbiLugCGK49l

3、将配置改为如下图所示。

FsnpWnw679T0QXz4N63COK-1t8KK

4、根据ECP5 MINI板更改对应的IP核。例如将MachXO3D的PLL改为ECP5的PLL,并将时钟输入改为16MHZ。如下图所示:

FjYxafDoUPhaEj0VnZRJHLJcobf2

5、更改完对应的IP核后,编译工程。

Fq3EmjrtXOBM6AtWQOnx1V8YRhES

6、将所有报错和IP核更改完成后,出现completed successfully表示成功。

FvuLliVw7f-HhhemvcyWQKHi_EfL

7、打开Tools->Spreadsheet View。

FqZBfFDyzunkySoFkLHS2M_3atBJ

8、根据ECP5 MINI的原理图配置对应的引脚,如下图所示。

Frlbgcd4-QpmPJX5ixnJWKZ89MGn

9、然后依次编译工程剩下的部分,直到所有部分都打上绿色的√。

FpjjNX_UwuvltP9z2qQyWG4amDr-

10、打开Tools->Programmer。

Fo3s0Lo4oedkj6yJR_F2e1kd9f1J

11、配置programmer。

FvwXVnVD0_vnzLbPMPdtgr1JW7Ni

12、点击Program进行烧写。

FjapaQpJEw2mYV6TmYzm8VslxnNc

 

三、在软 CPU 上运行软件

Fk_-cbLqCS0r9Wa2qkFeB4dsKkBx

 

如上图所示,提供了一个名为reindeer_config.py的python脚本,用于将软件(.elf文件)加载到软CPU中并执行。此时,此脚本仅在 Windows 平台上进行测试。在使用此脚本之前,应执行以下操作以在 Windows 上设置环境:

  1. 在Windows上安装RISC-V工具链

    建议使用 the RISC-V Embedded GCC,它的 v7.2.0-1-20171109 release 可以从这里下载

  2. 安装后,将RISC-V工具链添加到系统的$PATH

    如果使用默认安装路径,则很可能需要将以下路径添加到系统$PATH:

    C:\Program Files\GNU MCU Eclipse\RISC-V Embedded GCC\7.2.0-1-20171109-1926\bin
  3. 在 Windows 上安装 python3

    最新的 python for Windows 可以从 https://www.python.org/downloads/windows/ 下载

  4. 安装完成后,将python二进制和pip3二进制添加到系统的$PATH

    例如,如果用户 XYZ 在默认路径中安装了 python 3.7.1,则可能会将以下两个文件夹添加到$PATH:

    C:\Users\XYZ\AppData\Local\Programs\Python\Python37
    ​
    C:\Users\XYZ\AppData\Local\Programs\Python\Python37\Scripts
  5. 打开命令提示符(您可能需要以管理员身份运行),然后安装 python 的 pyserial 包:

    pip3 install pyserial
  6. 克隆PulseRain Reindeer软 CPU 的 GitHub 存储库

    git clone https://github.com/PulseRain/Reindeer.git
  7. cd Reindeer/scripts ,然后输入“python reindeer_config.py -h”寻求帮助。有效的命令行选项是

-r, --reset          : reset the CPU
-P, --port=          : the name of the COM port, such as COM7
-d, --baud=          : the baud rate, default to be 115200
-t, --toolchain=     : setup the toolchain. By default,  riscv-none-embed-  is used
-e, --elf=           : path and name to the elf image file
-d, --dump_addr      : start address for memory dumping
-l, --dump_length    : length of the memory dump
-c, --console_enable : switch to observe the CPU UART after image is loaded.

执行以下操作以在 Windows 上烧写程序:

  1. 将硬件板连接到主机 PC。

  2. 在使用 python 脚本之前,请确保使用正确的比特流对电路板进行编程。

    如果电路板首次使用比特流编程,请拔下并重新插入 USB 电缆,以确保电路板已正确重新初始化。

  3. 硬件正确连接到主机 PC 后,打开设备管理器以确定硬件使用的 COM 端口。

  4. 假设硬件使用 COM9,假设用户想要运行 zephyr hello_world,可以使用以下命令:

    python reindeer_config.py --port=COM9 --reset --elf=C:\GitHub\Reindeer\bitstream_and_binary\zephyr\hello_world.elf --console_enable --run

如果一切正确,屏幕输出应如下所示:

==============================================================================
# Copyright (c) 2018, PulseRain Technology LLC
# Reindeer Configuration Utility, Version 1.0
==============================================================================
baud_rate  =  115200
com_port   =  COM9
toolchain  =  riscv-none-embed-
==============================================================================
Reseting CPU ...
Loading  C:\GitHub\Reindeer\bitstream_and_binary\zephyr\hello_world.elf
__start 80000000
​
//================================================================
//== Section  vector
//================================================================
         addr = 0x80000000, length = 1044 (0x414)
​
//================================================================
//== Section  reset
//================================================================
        addr = 0x80004000, length = 4 (0x4)
​
//================================================================
//== Section  exceptions
//================================================================
         addr = 0x80004004, length = 620 (0x26c)
​
//================================================================
//== Section  text
//================================================================
         addr = 0x80004270, length = 7172 (0x1c04)
​
//================================================================
//== Section  devconfig
//================================================================
         addr = 0x80005e74, length = 36 (0x24)
​
//================================================================
//== Section  rodata
//================================================================
         addr = 0x80005e98, length = 1216 (0x4c0)
​
//================================================================
//== Section  datas
//================================================================
         addr = 0x80006358, length = 28 (0x1c)
​
//================================================================
//== Section  initlevel
//================================================================
         addr = 0x80006374, length = 36 (0x24)
​
===================> start the CPU, entry point = 0x80000000
***** Booting Zephyr OS zephyr-v1.13.0-2-gefde7b1e4a *****
Hello World! riscv32

 

四、Arduino IDE配置

1、安装 Arudino IDE。版本为1.8.9,对于Windows 10,也可以通过Microsoft商店安装。

2、启动 Arudino IDE。在“File / Preferences”中,将“ Additional Boards Manager URLs”设置为“https://raw.githubusercontent.com/PulseRain/Arduino_RISCV_IDE/master/package_pulserain.com_index.json”,如下所示:

FsNVIH48YGXt6fdHQSDRDJDLxLIH

3、在菜单Tools/ Boards / Boards Manager...中,搜索Reindder,然后安装PulseRain Reindeer 1.3.7或更高版本,如下所示:

Fvdxo1kY2xYhDevwMsoay9YafN87

4、安装主板包后,选择菜单中 Boards / PulseRain RISC-V (Reindeer)/MachXO3D Breakout。

5、插入开发板后,配置串口Tools / Port acoordingly。

6、现在就可以随意进行编程了。

 

五、展示

当ECP5 MINI核心板通电后,USER指示灯亮起。

FiNKaNc5A8g9WUJ_yV9WeeD3DLkf

 

按下复位键后,四个RGB灯显绿色常亮一段时间。

Frq6-0g3ONJ0OGnuoBUklRu1Vkgy

RGB灯短暂常亮后,8个RGB灯进行流水。

FpfputJ0sIAtRdrnpevhmrH9o2qB

 

串口数据打印

将ECP5 MINI核心板设定的串口引脚接到USB-TTL上,打开电脑串口会循环打印以下的信息。以下信息会根据按键引脚高低电平的变化而改变。

Fuez19QdjPCJBzdRcpIEvNsgktQl

 

六、其他配置

UART 配置

UART应配置为115200波特率,8位数据,无奇偶校验,1停止位

软 CPU 的配置

默认情况下, PulseRain软CPU仅支持RV32I。要使其支持硬件 mul/div (RV32IM),请在 config.h 中将“定义ENABLE_HW_MUL_DIV”转换为 1,然后重建以生成新的比特流。

 

七、参考资料

ECP5核心板资料:基于ECP5 FPGA的核心板 - 电子森林 (eetree.cn)

RISC-V指令集资料:riscv-spec-20191213.pdf

tinyriscv参考资料(简单、易懂的RISC-V处理器设计):从零开始写RISC-V处理器 | liangkangnan的博客 (gitee.io)

PulseRain Reindeer - RISCV RV32I[M] Soft CPU:PulseRain/Reindeer: PulseRain Reindeer - RISCV RV32I[M] Soft CPU (github.com)

 

 

 

附件下载
Reindeer_MachXO3D.rar
工程代码
团队介绍
个人
评论
0 / 100
查看更多
目录
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2023 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号