本文为通过Verliog HDL编写简易RISC-V CPU的试验笔记,如有错误敬请指正。
电路建模
复杂电路通常使用自顶向下的设计方法,先决定电路所需的功能,划分出实现功能的各个子模块,确保顶层设计无逻辑错误后,再进行各子模块的设计。
处理器的结构总是与指令集相关,对于RISC-V指令集,处理器需要按指令集的要求对数据进行处理操作。
一. 指令行为分析
对于任意一条RISC-V指令,它在处理器中的执行步骤皆可概括如下。
获得指令
从外部或储存器获得当前需要执行的指令,如:ADD rd rs1 rs2;
分析指令
获得指令后,使可以按指令的内容进行执行,但电路中指令以二进制方式储存,电路得到的只是32位的0、1,不能直接用于执行。为使电路"理解"指令的内容,需要对指令进行"翻译"以得到电路控制讯号。
对此,处理器须加入一个译码模块,作用按指令内容为生成电路各模块的控制讯号。
如对进行分析,得知ALU执行加法操作,数据来源A的地址为Rs1,数据来源B的地址为Rs2;运算结果保存至Rd。此时应设定电路为寄存器取数据的加法模式。
实例:进行译码,从得知为R-Type类型,从得到电路执行加法操作,数据来源A的地址为,数据来源B的地址为,运算结果保存至。
附注:在实际的电路译码中,不分析Rs1,Rs2,Rd的信息,而是根据Opcode及指令中的其他信息位设置数据通路与算朮单元。
取得数据
寄存器获取
出于节省指令长度,方便数据调用等考量,指令中并不直接包含需操作的32位数据。而是记录了储存数据的5位地址数据。处理器通过5位地址对储存单元进行访问,间接得到所需的运算数据。在这一步中,处理器中需要个32位寄存器组以储存临时数据。
如:,结果储存至Rd,数据来源A的地址为Rs1,数据来源B的地址为Rs2;从Rs1,Rs2中获得寄存的32位数据。
附注:在处理器中,少量的临时数据被储存于寄存器而非内存,其特点为访问速度快,需要时可直接进行存放以获得数据,若储存于内存则至少需要占用一个指令周期以获得数据。
立即数扩展
对于立即数形式指令,其运算数据被部份地储存于指令当中,一般为12位(I-Type)或20位(J-Type)。不符合32位操作数的标准,需要对数据进行扩展以得到完整的32位操作数。在RISC-V中,大部分立即数皆按有符号数进行扩展处理。
如:,结果储存至Rd,数据来源A的地址为Rs1,数据来源B为指令中储存的99,,但输入为32位,扩展为。
附注:符号扩展,由于立即数通过补码保存,正数的补码表示为其自身的二进制值,负数的补码表示为自身的二进制值取反加一,如$7_{10} = 0111_2;-7_{10} = 1001_2$,为7的4位二进制表示,若以8位表示则有$7_{10} = 00000111_2;-7_{10} = 11111001_2$,把4位二进制扩展为8位,只需判断数据的符号位(最高位),随后随扩展每一位值与最高值相同即可。
数据处理
参考指令集中定义的几种数据处理方式,分别有算朮加法、按位与、按位或、左右移。对数据的处理一般通过算朮逻辑单元(ALU)进行处理。
数据储存
假若处理结果不被保存或不改变状态机,则数据运算显得毫无意义。对大部分指令而言,数据的处理结果需要重新写回至寄存器组中等待后续指令的调用。又或是通过Store指令储存至"大型"储存器,如内存当中。
二. 逻辑框图
下为RISC-V处理器的基础构成框图,其组成与上述提到的指令执行步骤相差不大。
三. 模块划分
数据通路
数据通路是处理器的重要构成部份,主要负责模块间的数据传递。主要的部件为受译码模块控制的数据选择器。译码器通过选择器控制各模块的输入数据,例如选择ALU运算数据从寄存器或是立即数单元进行输入。
数据通路的设计需与指令相配合,对于RISC-V指令集的指令执行流程,可以得到一种数据通路设计如上。
程序计数器
在处理器中,指令一般被顺序存放于存储器,存储器的特点时访问数据时需提供地址,随后存储器通过地址取得被储存的数据。因此,程序计数器的核心为记录当前执行的指令计数,随后通过此计数值于存储器中读出相应的32位指令码。
在RISC-V中,若不考虑跳转与分支等情况,则PC在每条指令执行完毕后自增4。对应的电路为一组32位触发器及一个32位加法器。
指令储存器
存放指令的存储区域,可以是专用的指令储存器,亦可以是内存中特定的一块区域。
译码模块
翻译指令编码为控制讯号的电路,一般需与数据通路及其他模块协同设计。作为例子,译码器需为算朮逻辑单元提供操作码,以确保算朮逻辑单元的行为正确。亦需为数据通路中的各数据选择器提供操作讯号,确保各模块的输入数据正确。
寄存器组
处理器临时存放程序数据的寄存器,寄存器组的加入使程序数据能被迅速取用而无需专门访问内存空间,减少电路的延时。
算朮逻辑单元(ALU)
算朮逻辑单元的行为与使用的指令集有重要关系。对于RV32I指令集,指令集中包含了加减法、与、或、或非、移位、比较等操作指令。对应地需为ALU设计加法器及逻辑单元,从而实现指令集规定的操作行为。
随机存储器(RAM)
随机存储单元用于大规模地保存程序中的数据,对于大型程序,32个寄存器并不足以存放所有程序数据,但增加寄存器将导致地址位宽的进一步上升,使指令体系变得臃肿。因此必须使用规模更大,代价更低的器件以储存大量的运行数据。其中随机存储单元由于成本相对较低,数据可随机存放等特点而被广泛用于数据存储中。
附注:随机存储器中随机二字不是指获取的数据随机,而是指电路可以非顺序的方式读取储存器中的数据。如磁带、CD、硬碟等存储介质需从数据起始点开始一个个数据读取,而不能直接读取某一位置的数据。而随机存储器则可直接读出存储器中指定的数据,因此称为随机存储器。