中科亿海微
直播中

yuzhiwen1986

11年用户 91经验值
擅长:电源/新能源,嵌入式技术
私信 关注

【中科亿海微EQ6HL45开发平台试用体验】Tiny RISC-V 在中科亿海微EQ6HL45 FPGA 平台移植实践(1)

前言

最近两年RISC-V很火,主要原因还是因为这个处理器是开源的。目前市面上也有有很多的书籍讲RISC-V的原理和架构。我学习RISC-V 主要还是从网络上下载的资料以及视频网站的的代码可以直接用FPGA来做验证。于是我在网上便开始找一些开源代码用来学习,目前从资料的完整性来看,Tiny RISC-V 和 蜂鸟e203我个人觉得是比较好的学习参考资料。这两个RISC-V 处理器我都在XILINX FPGA 上做过一些仿真编译的工作。无奈手上没有合适的板卡实践,一直也就拖了很长时间。这次正好碰上中科亿海微有个开发板测评活动就毫不犹豫的报名了。由于EQ6HL45 的资源还是有限,在评估了该开发板资源之后,我决定在Tiny RISC-V基础上做些RAM的优化调整,并根据最近有个射频模块的小项目结合起来。做一个能够在RISC-V 处理器上完成射频卡的控制和数据采集。

本次实践主要包含4部分:

  1. Tiny RSIC 的优化和移植
  2. C代码编译和条数
  3. 射频卡设计和调试
  4. 射频驱动编译和测试

以下是整个项目的一个框图:

image.png

中科亿海微EQ6HL45 FPGA 介绍

中科亿海微电子科技有限公司是中国科学院“可编程芯片与系统”研究领域的科研与产业化团队. 这次评测的FPGA便是该公司 eHiChip 家族 FPGA 开发平台产品,开发板采用核心板加扩展板的模式,方便用户对核心板的二 次开发利用,为前期验证和后期应用提供了可能。厂家给的测试配件非常丰富。包装也很不错。装好软件编译一下测试代码,第一天点燃跑马灯过把瘾!

image.png

Tiny RISC-V 介绍

RISC-V是一种指令集架构,和ARM、MIPS这些是属于同一类东西。RISC-V诞生于2010年,最大的特点是开源,任何人都可以设计RISC-V架构的处理器并且不会有任何版权问题。

tinyriscv实现的是一个微RISC-V处理器核,用verilog语言编写,只求以最简单、最通俗易懂的方式实现RISC-V指令的功能,因此没有特意去对代码做任何的优化。

tinyriscv整体框架如图所示:

image.png

tinyriscv已经不仅仅是一个内核了,而是一个小型的SOC,包含一些简单的外设,如timer、uart_tx等。

tinyriscv SOC输入输出信号有两部分,一部分是系统时钟clk和复位信号rst,另一部分是JTAG调试信号,TCK、TMS、TDI和TDO。

上图中的小方框表示一个个模块,方框里面的文字表示模块的名字,箭头则表示模块与模块之间的的输入输出关系。

下面简单介绍每个模块的主要作用。

  • jtag_top:调试模块的顶层模块,主要有三大类型的信号,第一种是读写内存的信号,第二种是读写寄存器的信号,第三种是控制信号,比如复位MCU,暂停MCU等。
  • pc_reg:PC寄存器模块,用于产生PC寄存器的值,该值会被用作指令存储器的地址信号。
  • if_id:取指到译码之间的模块,用于将指令存储器输出的指令打一拍后送到译码模块。
  • id:译码模块,纯组合逻辑电路,根据if_id模块送进来的指令进行译码。当译码出具体的指令(比如add指令)后,产生是否写寄存器信号,读寄存器信号等。由于寄存器采用的是异步读方式,因此只要送出读寄存器信号后,会马上得到对应的寄存器数据,这个数据会和写寄存器信号一起送到id_ex模块。
  • id_ex:译码到执行之间的模块,用于将是否写寄存器的信号和寄存器数据打一拍后送到执行模块。
  • ex:执行模块,纯组合逻辑电路,根据具体的指令进行相应的操作,比如add指令就执行加法操作等。此外,如果是lw等访存指令的话,则会进行读内存操作,读内存也是采用异步读方式。最后将是否需要写寄存器、写寄存器地址,写寄存器数据信号送给regs模块,将是否需要写内存、写内存地址、写内存数据信号送给rib总线,由总线来分配访问的模块。
  • div:除法模块,采用试商法实现,因此至少需要32个时钟才能完成一次除法操作。
  • ctrl:控制模块,产生暂停流水线、跳转等控制信号。
  • clint:核心本地中断模块,对输入的中断请求信号进行总裁,产生最终的中断信号。
  • rom:程序存储器模块,用于存储程序(bin)文件。
  • ram:数据存储器模块,用于存储程序中的数据。
  • timer:定时器模块,用于计时和产生定时中断信号。目前支持RTOS时需要用到该定时器。
  • uart_tx:串口发送模块,主要用于调试打印。
  • gpio:简单的IO口模块,主要用于点灯调试。
  • spi:目前只有master角色,用于访问spi从机,比如spi norflash。在后面本次实践当中SPI主要用来控制射频模块

最后在总结一下,tinyriscv处理器核有以下特点:

  1. 实现了RV32I指令集,通过riscv的RV32I指令兼容性测试,支持以下指令:add addi and andi auipc beq bge bgeu blt bltu bne fence_i jal jalr lb lbu lh lhu lw lui or ori sb sh sw sll slli slt slti sltiu sltu sra srai srl srli sub xor xori;
  2. 支持RV32M指令集:mul mulh mulhu mulhsu div divu rem remu;
  3. 采用三级流水线,即取指,译码、访存、执行,回写;
  4. 可以运行简单的c语言程序。

移植Tiny RISC-V 到EQ6HL45 平台

接下来进入到正题环节,本节中我将详细介绍移植tiny risc-v 的过程, 整个过程都是在WIN10系统里完成。

1 准备工作

clone 代码

使用git clone命令下载,不要使用zip方式下载,否则有些文件会有格式问题。

git clone https://gitee.com/liangkangnan/tinyriscv.git

安装iverilog 工具

可以在这里http://bleyer.org/icarus/下载,安装过程中记得同意把iverilog添加到环境变量中,当然也可以在安装完成后手动进行添加。安装完成后iverilog、vvp和gtkwave等工具也就安装好了。

安装GNU工具链

可以通过百度网盘下载(链接: https://pan.baidu.com/s/1bYgslKxHMjtiZtIPsB2caQ 提取码: 9n3c),或者通过微云下载https://share.weiyun.com/5bMOsu9,下载完成后将压缩包解压到本项目的tools目录下。注意目录的层次结构,解压后的工具路径应该如下所示:

tinyriscv oolsgnu-mcu-eclipse-riscv-none-gcc-8.2.0-2.2-20190521-0004-win64in iscv-none-embed-gcc

安装make 工具

可以通过百度网盘下载(链接: https://pan.baidu.com/s/1nFaUIwv171PDXuF7TziDFg 提取码: 9ntc),或者通过微云下载https://share.weiyun.com/59xtmWR,下载完成后直接解压,然后将make所在的路径添加到环境变量里。

安装python3

python官网下载win版本的python,注意要下载python3版本的。我之前电脑上有ANACOND也是可以的。

安装Visual studio code

一个很好用代码编辑工具,强烈推荐。下载地址:

Visual Studio Code - Code Editing. Redefined

移植代码修改

在作者的readme 里面已经有了详细的仿真测试指导,本文就不重复描述了。这里主要介绍一下如何将代码移植到中科艺海微FPGA,也就是编译源码里面的RTL 文件。下面的图片是源码里的RTL文件目录:

image.png

我在FPGA目录里面创建一个新的文件命名为EQ6HL45,并把源码中的RTL放进该文件夹如图:

image.png

这里需要注意几个问题,这是我在后面遇到的,可以先提前改一下,一个是头文件可以检查一下是不是对应的位置:

image.png

另一个是把ROM/RAM的深度改小一点,(因为作者在这里RAM是用LUT构成的,好处是代码在不同的平台可以通用,不好的地方是消耗过多的LUT资源不适合小容量FPGA,在这里因为试用的FPGA容量不大,先把深度改小一点。当然整个对后面运行C程序肯定会有影响。最好的办法是使用FPGA的IP生成ROM/RAM,这个在第二部分再详细介绍)

image.png

Elinx 工程创建和编译

先认真阅读代码,理清文件的层次结构。清楚了整个逻辑框架,接下来就可以打开ELINX软件开始创建工程了

image.png

具体的创建过程,本文也不赘述了,在elinx 软件使用手册里写的非常清楚。这里没有特别的技巧,如果有问题的根据提示一般也都可以解决,如果一切顺利的话在综合之后你便可以看到整个工程的层次结构如下:

image.png

接下来便可以在layout 栏目里面选择io planning 做管脚约束:

接下来布局布线,生成bit文件就可以下载到FPGA 里面啦。

FPGA image 下载与测试

关于如果下载到FPGA RAM 还是下载到外部flash里面,在中科艺海微的用户手册里面也有详细的描述。本文不描述。建议可以直接下载到FLASH里面,断电不丢失,方便测试。另外一个比较好的建议增加一些LED调试功能,可以方便调试逻辑。

编写第一个C语言程序hello world

先跑通测试代码

C语言程序例程位于源码目录下testsexample目录里。

下面以simple程序为例进行说明。

打开CMD窗口,进入到testsexamplesimple目录,执行以下命令编译:

make

image.png

编译过程界面

编译结束之后会有bin文件,这里注意的地方是MAKE 要设置好环境变量。

image.png

编译成功之后,进入到sim目录,执行以下命令开始测试:

python .sim_new_nowave.py .. estsexamplesimplesimple.bin inst.data

可以看到PASS界面

使用串口下载编译文件

通过UART方式下载前需要先使能UART debug模块。在约束文件里指定的uart_debug_en引脚,当其输入为高电平时表示使能UART debug模块,输入为低电平时表示关闭UART debug模块。

当使能了UART debug模块后,就可以通过tools/tinyriscv_fw_downloader.py脚本来下载程序。

tinyriscv_fw_downloader.py脚本使用方法:

python tinyriscv_fw_downloader.py 串口号 bin文件

打开CMD窗口,进入到tools目录,比如输入以下命令:

下载成功界面如下:

即可下载firmwarm.bin程序到软核里。下载完后,先关闭UART debug模块,然后按板子上的复位(rst)按键即可让程序跑起来。

后续部分内容如下:

  1. 增加一个SPI接口射频模块
  2. 使用C语言编写射频模块驱动
  3. 进阶部分-移植FreeTOS

更多回帖

发帖
×
20
完善资料,
赚取积分