《RISC-V on T-Core》学习笔记

近几年来,在ARM和Intel所垄断的处理器架构格局中,一种新的免费开源指令集架构RISC-V突然声名鹊起,成为处理器领域的新秀。目前正值中美芯片之争,国内对RISC-V的关注度也很火热,前景被无限看好。那么RISC-V到底与其他架构有什么不同,又会带来哪些机遇与挑战呢面我将对RISC-V进行简单的介绍:

一、指令集简介

一般来讲,先有指令集,才会有芯片来支持指令集。指令集类似一种标准,定义了芯片支持的功能。简单来说,指令集就是定义了一种计算机识别的编码,负责告诉计算机一编码的含义是什么。指令集的强弱是CPU的重要指标,是提高微处理器效率的最有效工具之一。一个好的指令集设计可以让CPU的设计更加方便,让编译器能够对这一架构生成效率更高的代码。

众所周知,处理器领域有两大指令集架构纵横天下,复杂指令集(Complex Intruction Set Computer, CISC)的代表英特尔x86在PC市场无出其右,精简指令集(Reduced Intruction Set Computer, RISC)的代表ARM则在移动终端独领风骚。两类指令集都“集”如其名:CISC指令集靠设计出尽可能复杂的指令来完成任务。约有20%的指令会被反复使用,占全程序代码的80%。特点是任务处理能力强,但高性能就会引入高功耗的问题;RISC则只包含处理器常用的指令,不常用的操作则通过执行多条常用指令方式来达到同样的效果。

指令集

全称

特点

行业代表

RISC

Reduced Intruction Set Computer

低功耗,低性能

ARM

CISC

Complex Intruction Set Computer

高功耗,高性能

Intel

二、RISC-V的诞生

RISC-V (英文读作”risk-five”),是一种全新的精简指令集架构。它出自美国UC Berkeley大学的一个研究团队。因为传统商业闭源指令集授权费高昂且专有利保护,像伯克利大学这样的研究团队竟选不出合适的指令集架构来使用。最终他们决定从零开始,设计一套全新的、开源的指令集。于是RISC-V指令集的雏形诞生了。

秉承“大道至简”的设计哲学,RISC-V基础指令集只有40多条,加上其他的模块化扩展指令总共几十条指令。RISC-V的规范文档仅有145页,而“特权架构文档”的篇幅也仅为91页。相比传言要上千万美元的ARM指令集架构的许可证,RISC-V以其完全开源、短小精悍的模块化设计、没有过时定义的束缚、没有严重的指令冗余、没有专利问题等优势开始吸引全球初创公司和研究机构的目光。大批公司开始加入对RISC-V的研究和二次开发之中。现在,围绕RISC-V的生态环境逐渐完善,并涌现了众多开源处理器及SoC采用RISC-V架构。

RISC-V的出现打破了沉闷的行业气氛,举起了反垄断的大旗,可以看成是一个年轻的搅局者。在科技巨头以及一大批创企对RISC-V的发展和生态建设的推动之下,或许RISC-V能够成为AI和IoT时代足以与ARM匹敌的新一代主流架构。

三、RISC-V的优势

简单来说,RISC-V的优势可以被概括成一句话:短小精悍、扩展性强。处理器经过这么多年的发展,路上的坑已经被研究的清清楚楚,但ARM和x86的指令集一路走来,需要兼容的东西太多了,导致指令集越来越复杂。RISC-V则站在巨人的肩膀上汲取了这些经验,指令集的每个功能都被划分的清清楚楚,所以够精简。

RISC-V是一个典型三操作数、加载-存储形式的RISC架构。指令集使用模块化的方式进行组织,其不同部分能以模块化的方式串在一起。因此通过组合不同的模块,可以对于不同处理需求的加速芯片实现兼容。它包括三个基本指令集和6个扩展指令集,每一个模块使用一个英文字母来表示,如下表所示。

 

名称

指令数

说明

基本指令集

RV32I

47

整数指令,包含:算数、分支、访存。32位寻址空间,32个32位寄存器

RV32E

47

指令与RV32I一样,只是寄存器数量变为16个,用于嵌入式环境。

RV64I

59

整数指令,64位寻址空间,32个64位寄存器。

RV128I

71

整数指令,128位寻址空间,32个128位寄存器。

扩展指令集

M

8

包含4条乘法、2条除法、2条余数操作指令

A

11

包含原子操作指令。比如读-修改-写,比较-交换等

F

26

包含单精度浮点指令

D

26

包含双精度浮点指令

Q

26

包含四倍精度浮点指令

C

46

压缩指令集,其中的指令长度为16位,主要目的是减少代码的大小

RISC-V分为32bit、64bit、128bit三个版本,常用的模块有以下几个:

I: 与整数相关的指令集。RISC-V唯一必须支持的模块,仅仅有40多条指令。只要是RISC-V处理器,必定支持这个模块。包含了整数的加减以及相关的逻辑跳转等指令。

M: 整数的乘法与除法指令。

A:包含了存储相关的原子操作等。比如想实现从存储里取数据,然后计算完写回存储可以用此类指令。

F:单精度浮点指令。

D:双精度浮点指令,如果要支持D,那F显然要支持。

C:压缩指令,16bit的短指令。用来减少指令体积。

一般来讲,RV32IMAFD比较常见,所以缩写一下就叫RV32G,G为通用(General Purpose)的意思。除了上述指令,RISC-V还预留了很大的空间用于自定义指令。如果官方提供的指令没有满足需求,用户完全可以自定义一条指令放进去,然后再修改一下编译链就可以了,扩展潜力巨大。目前所有指令集均在RISC-V官方网站公开,感兴趣的读者可以自行查看。

四、RISC-V自学准备

首先准备学习环境:

·一台安装了Linux系统的虚拟机或电脑

·IC设计必备软件,包括编译,仿真以及波形查看工具

·riscv-gcc工具包,用于生成risc-v版的可执行文件

在这里为大家推荐友晶科技《RISC-Von T-Core》公开课,代码和文档都在Github上开源,对初学者会很有帮助,在文末提供链接。同时搭配胡振波的《手把手教你设计CPU—RISC-V篇》。这本书主要是介绍国产开源RISC-V架构CPU—蜂鸟E200,通用CPU的设计流程和基于Verilog的代码具体实现,可以说是理论和实践相结合的一本好书。无论是对于嵌入式开发,还是IC设计验证,都有很大的参考价值。

五、《RISC-V on T-Core》自学笔记

友晶科技《RISC-V on T-Core》公开课的前七讲都是理论教学,从第八讲到第十二讲开始进行实战演练。下面我将对前七讲的重点知识进行总结,后五讲则侧重实践过程中遇到的问题。

第一讲:

第一讲介绍了主要介绍了RISC-V指令集架构的特点,主要分为以下几点:

(1)模块化的指令集

在前面第三章中,已经简要介绍过RISC-V架构。相比其他成熟的商业架构,它最大的特点就是模块化架构。不仅短小精悍,而且其不同的部分还能以模块化的方式组织在一起,从而试图通过一套统一的架构满足各种不同的应用。这种模块化是 x86与ARM架构所不具备的。它能够使得用户能够灵活选择不同的模块组合,以满足不同的应用场景,可以说是“老少咸宜”。譬如针对于小面积低功耗嵌入式场景,用户可以选择RV32IC 组合的指令集,仅使用 Machine Mode(机器模式);而高性能应用操作系统场景则可以选择譬如 RV32IMFDC的指令集,使用Machine Mode(机器模式)与UserMode(用户模式)两种模式。而他们共同的部分则可以相互兼容。

《RISC-V on T-Core》学习笔记

(3)可配置的通用寄存器组

RISC-V架构支持32位或者64位的架构, 32位架构由RV32表示,其每个通用寄存器的宽度为32比特; 64位架构由RV64表示,其每个通用寄存器的宽度为64比特。

RISC-V架构的整数通用寄存器组,包含32个(I架构)或者16个(E架构)通用整数寄存器,其中整数寄存器0被预留为常数0,其他的31个(I架构)或者15个(E架构)为普通的通用整数寄存器。

如果使用浮点模块(F或者D),则需要另外一个独立的浮点寄存器组,包含32个通用浮点寄存器。如果仅使用F模块的浮点指令子集,则每个通用浮点寄存器的宽度为32比特;如果使用了D模块的浮点指令子集,则每个通用浮点寄存器的宽度为64比特。

(4)简洁的存储器访问指令

RISC-V架构的存储器访问指令具有如下显著特点:

·为了提高存储器读写的性能, RISC-V架构推荐使用地址对齐的存储器读写操作,但是也支持地址非对齐的存储器操作RISC-V架构。处理器既可以选择用硬件来支持,也可以选择用软件来支持。

·由于现在的主流应用是小端格式(Litte-Eendian ), RISC-V架构仅支持小端格式。有关小端格式和大端格式的定义和区别,在此不做过多介绍。若对此不太了解的初学者可以自行查阅学习。

·很多的RISC处理器都支持地址自增或者自减模式,这种自增或者自减的模式虽然能够提高处理器访问连续存储器地址区间的性能,但是也增加了设计处理器的难度。RISC-V架构的存储器读和存储器写指令不支持地址自增自减的模式。

·RISC-V架构采用松散存储器模型(Relaxed Memory Model),松散存储器模型对于访问不同地址的存储器读写指令的执行顺序不作要求,除非使用明确的存储器屏障Fence)指令加以屏蔽。有关存储器模型(MemoryModel)和存储器屏障指令的更多信息,请参见附录A13这些选择都清楚地反映了RISC-y架构力图简化基本指令集,从而简化硬件设计的哲学。

《RISC-V on T-Core》学习笔记

中断流程只要是CPU都大同小异的。对于RISC-V来讲,中断流程是这样的:

·外设发出中断信号。

·PLIC或者CLINT响应中断,RISC-V核心保存此时的CSR。

·跳转到中断处理程序(直接换PC值取指令即可)。

·关闭其他中断响应使能(RISC-V不支持嵌套,所以一个中断要屏蔽其他中断)。

·软件保存通用的寄存器。

·然后处理中断(过程中会清掉外设的中断)。

·软件恢复通用的寄存器。

·恢复CSR。

·跳转PC跳回原来位置退出异常。

一个完整流程就结束了。其他细节直接阅读RISC-V core的说明书即可。

第二讲:ALU

ALU是处理器中具体完成每条指令运算的功能模块。经过分析归纳,ALU需要支持的运算包括对操作数加1,对操作数减1,两个操作数加和减,两个数的与或及异或等按位逻辑运算,操作数按位取反,左移右移。ALU 的实现需要包括上面的所有功能。考虑到面积优化,加减1和减法可以全部由加反来实现。

蜂鸟E200 的ALU 单元,包括5 个功能子单元,各自的功能分为以下5 种情况:

·普通ALU 运算:主要负责普通的ALU 指令(逻辑运算,加减法,移位等指令)的执行。

·访存地址生成:主要负责Load、Store和“A”扩展指令的地址生成。

·分支预测解析:主要负责Branch和Jump 指令的结果解析和执行。

·CSR读写控制:主要负责CSR指令的执行。

·多周期乘除法器:主要负责乘法和除法指令的执行。

以上5个功能子单元只负责具体指令执行的控制,它们均共享一份实际的运算数据通路,因此主要数据通路的面积开销只有一份,这也是蜂鸟E200追求低功耗小面积实现的亮点。

第三讲:

本讲主要介绍了单指令周期 CPU 的设计与实现。根据指令周期的五个执行步骤:取指、译码、执行、访存、写回,分别设计 RISC-V六种类型指令的数据通路和控制器。

在MIPS五级流水线中一条指令的生命周期分为如下步骤:

(1). 取指

?指令取指(instruction Fetch)是指将指令从存储器中读取出来的过程。

(2). 译码

?指令译码(Instruction Decode)是指将从存储器中取出的指令进行翻译的过程。经过译码之后得到指令需要的操作数寄存器索引,可以使用此索引从通用寄存器组(RegisterFile)中将操作数读出。

(3). 执行

指令译码之后所需要进行的计算类型都己得知,并且己经从通用寄存器组中读取出了所需的操作数,那么接下来便进行指令执行。指令执行是指对指令进行真正运算的过程。譬如,如果指令是一条加法运算指令,则对操作数进行加法操作;如果是减法运算指令,则进行减法操作。

?在“执行”阶段的最常见部件为算术逻辑部件运算器(ArithmeticLogical Unit,ALU),作为实施具体运算的硬件功能单元。

(4). 访存

?存储器访问指令往往是指令集中最重要的指令类型之一,访存是指存储器访问指令将数据从存储器中读出,或者写入存储器的过程。

(5). 写回

?写回(Write-Back)是指将指令执行的结果写回通用寄存器组的过程。如果是普通运算指令,该结果值来自于“执行”阶段计算的结果:如果是存储器读指令,该结果来自于“访存”阶段从存储器中读取出来的数据。

第四讲:

本讲主要介绍了处理器流水线的概念与结构,并对流水线与单指令周期进行了比较分析。此外,讲师还与大家一起探讨了流水线设计带来的冒险,诸如结构冒险、数据冒险、控制冒险等,并带着大家找到其解决方法。最后,讲师对RISC-V onT-Core流水线实现的代码进行了解析。

(1). 数据冒险:

l  WAR(Write-After-Read)相关性,又称先读后写相关性:表示“后序执行的指令需要写回的结果寄存器索引”与“前序执行的指令需要读取的源操作数寄存器索引”相同造成的数据相关性。因此从理论上来讲,在流水线中“后序指令”一定不能比和它有WAR相关性的“前序指令”先执行,否则“后序指令”先写回了结果至通用寄存器组中,“前序指令”再读取操作数时,就会读到错误的数值。

l  WAW(Write-After-Write)相关性,又称先写后写相关性:表示“后序执行的指令需要写回的结果寄存器索引”与“前序执行的指令需要写回的结果寄存器索引”相同造成的数据相关性。因此从理论上来讲,在流水线中“后序指令”一定不能比和它有WAW相关性的“前序指令”先执行,否则“后序指令”先写回了结果至通用寄存器组中,“前序指令”再写回结果至通用寄存器组中就会将其覆盖。

l  RAW(Read-After-Write)相关性,又称先写后读相关性:表示“后序执行的指令需要读取的源操作数寄存器索引”与“前序执行的指令需要写回的结果寄存器索引”相同造成的数据相关性。因此从理论上来讲,在流水线中“后序指令”一定不能比和它有RAW相关性的“前序指令”先执行,否则“后序指令”便会从通用寄存器组中读回错误的源操作数。

(2). 结构冒险:

l  产生原因:

每条指令在解码阶段需从寄存器文件读取两个操作数;在写回阶段写入一个值到寄存器文件。

l  解决方法:

设计更多的独立端口,比如设计两个读端口,一个写端口来满足上面的需求。每个周期可同时进行3个端口的访问。

(3). 控制冒险:

在取指阶段的分支预测功能中,对于带条件分支指令,由于其条件的解析需要进行操作数运算(譬如大小比较操作),流水线在取指阶段无法得知该指令的条件跳转结果是跳还是不跳,只能进行预测。因此在执行阶段,通常需要使用ALU对该指令进行条件判断运算(譬如大小比较操作)。ALU进行条件判断运算的结果将用于解析该分支指令是否真的需要跳转,并且和之前预测的跳转结果进行比对。如果真实的结果和预测的结果不一致,则意味着之前的预测错误,需要进行流水线冲刷( PipelineFlush),将预测取指(Speculative Fetch)所取的指令都舍弃掉,重新按照真实的跳转方向进行取指。

由于分支预测错误造成的流水线冲刷会造成性能损失。流水线级数越深,流水线冲刷造成的性能损失越大。因此理论上来讲,分支解析如果能够发生在比较靠前端(取指)的流水线级数位置,则相对而言其带来的流水线冲刷的性能损失会相对小一些;反之,如果比较靠后,那造成的性能损失就会相对大一些。如何在功能正确且时序能够满足的情况下,尽量在比较靠前端的流水线位置进行分支解析,是处理器微架构设计经常需要考虑的问题。

第五讲:

本讲主要介绍了存储器的层次化结构。首先,从局部性原理出发,构建存储器的层次化结构;然后着重分析了Cache 的原理与改进方法、虚拟存储器的管理两大方面,比如 Cache 的三种映射机制、数据的一致性问题、虚拟存储器的两种管理方法以及 TLB的 Verilog 实现等;最后对 RISC-V onT-Core 的存储器系统的代码进行了讲解。

蜂鸟E200 处理器核的存储器子系统结构如下图中圆圈区域所示,主要包含如下4 个组件。

? AGU 主要为读和写指令,以及“ A "扩展指令生成存储器访问地址。

? LSU 主要作为存储器访问的控制模块。

? ITCM 主要作为存储器子系统的指令存储部件,但是也能够用于存储数据而被读和写指令访问。

? DTCM 作为存储器子系统的数据存储部件。

《RISC-V on T-Core》学习笔记

现在硬件上已经可以实现dot指令了。然后就需要需要编写含有dot指令的应用程序,这个应用程序在使用编译器编译后会生成二进制文件,烧录到T-Core上后,硬件就会计算出结果,最后把结果返回。所以需要修改GNU-Toolchain。首先安装编译risc-opcodes的编译环境python。但万万没想到,我在这一步折腾了一晚上。下面讲一下我的曲折经历:

首先我用了apt-get安装pip,如下所示:

sudo apt-get installpython3-pip

但出现了如下错误(引用自别人的博客,当时的错误信息没有保存),大概意思是缺少一个叫setuptools的依赖。

《RISC-V on T-Core》学习笔记

而在RTOS中,将所有事情分成各个模块,每一个模块的内容看作一个任务,任务的执行顺序是灵活的,根据相应的调度算法管理任务的运行,灵活性比上一种方法强,过程如下图所示:

《RISC-V on T-Core》学习笔记

选中master,在下拉列表中修改分支:

《RISC-V on T-Core》学习笔记

如上所示,FreeRTOS的代码层次结构分明,只需要修改三个文件名为“port*”的源代码,完成基本的中断和异常的底层移植。然后就是配置工程,新建FreeRTOSConfig.h,主要就是配置时钟频率,栈空间大小等信息,这个自行体会。剩下的过程大家应该不会遇到太大的问题,我的两个小任务也转起来了。

五、总结

最后,虽然列举了RISC-V这么多优点,但ARM和x86毕竟经过这么多年的积累,里面汇聚了一代又一代人的劳动成果,也不可能没有精髓。RISC-V作为行业的新秀,缺乏很多必要的适配,生态也不够完善,目前还不够成熟,离商用还有很长一段路要走。到底是不是风口,还要持股观望。但它的价值是值得肯定的,也许我国在这个领域里会出现下一个Intel或者ARM般强大的处理器,实现强国梦。在文末提供了一些RISC-V相关的教程和资料,感兴趣的同学可以自行查阅。

版权归原作者所有,侵删。

参考文献及相关链接:

友晶科技《RISC-V on T-Core》公开课

https://space.bilibili.com/437451814pm_id_from=333.788.b_765f7570696e666f.2

RISC-V基础资料

https://github.com/riscv

https://cnrv.io/resource

RISC-V蜂鸟E200系列源码

https://github.com/riscv-mcu/e203_hbirdv2

RISC-V中文社区

https://www.risc-v1.com/

友晶科技官网

http://www.terasic.com.cn
友晶科技MyFPGA论坛
http://www.myfpga.org/discuz/forum.php

《RISC-V on T-Core》学习笔记

NOW

《RISC-V on T-Core》学习笔记

《RISC-V on T-Core》学习笔记

《RISC-V on T-Core》学习笔记 OpenFPGA 《RISC-V on T-Core》学习笔记 微信公众号 《RISC-V on T-Core》学习笔记 FPGA新闻、技术、设计思想 ,FPGA深度学习

来源:碎碎思

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2020年11月26日
下一篇 2020年11月26日

相关推荐