# Ausar龙芯个人赛2020一等奖作品 **Repository Path**: jingrongchi_admin/Loonson-personal-SimpleCPU-Rua ## Basic Information - **Project Name**: Ausar龙芯个人赛2020一等奖作品 - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: simd_two_stage - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 3 - **Created**: 2021-07-16 - **Last Updated**: 2022-07-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ## 2020年龙芯杯个人赛一等奖作品 --------------- ## 一个内置了位记数加速器,速度达到65Mhz的五级流水单发射MIPS CPU > (应该是单发射无Cache设计在个人赛环境的速度极限了) > (应该可以直接提交到个人赛的环境上) > (咕咕了一年,补写一下说明) ### 原始代码 该作品源码基于本人2019年所书写的SimpleCPU,并对大赛环境进行了适配: 原始代码可见:[SimpleCPU](http://https://gitee.com/Ausar/SimpleCPU) 原始代码跑在用超大寄存器堆做的”内存”上,显然是不可上板的,但是其余部件的原理均相同。 ### 头文件的作用 代码里面包含了一个头文件,里面添加了对UART参数(UART模块需要知道自己运行的频率,以及波特率),指令独热码定义(见后文)等参数 以及对调试时候的信息显示级别做了定义,使得可以方便地进行Debug ### 关于汇编---机器码的生成 在ASM目录中,有书写以及测试汇编用的MARS修改版,这个版本的MARS能显示汇编执行时候的运行信息,很方便进行调试 同时,个人赛中起始地址为80000,但是我们编写的小程序,是由监控程序加载到81000后再执行的。在我们仿真调试中,显然不方便运行监控程序。 因此测试的时候,需要把Makefile中的地址改成80000而非81000 同时,Makefile中调用的编译器,需要从大赛官方处获得 (不知道Makefile是怎么用的同学,可以百度一下make命令怎么用) ### 文件结构及命名规范 我把CPU的5级流水打包成了4个大的模块,每个模块的出口以reg型为主。其信号命名大致是这样的,Decode级出去的信号,都叫D_XXX,如果是直接出去,不经过流水寄存器的信号,那么叫D_XXX_Pass ### 译码设计 CPU的架构是传统的5级流水,采用了分布式译码的设计 即:译码器只负责把各个指令的独热码译出,然后将独热码打包,发送到各流水级。在某个部件需要管理操作,比如ALU要做位操作时,只需要查看当前指令对应的操作即可,这样的设计有利于把延迟平均分散到各级,同时很方便进行指令的添加或者修改 ``` verilog wire BC_Family = ((ori|Or)| (And|Andi))| ((Xor|Xori)| (Nor|lui)); wire [31:0] BC_A = A, BC_B = (ori|Andi|Xori) ? Imm32 : B; wire [31:0] BC_Ans = (Xor|Xori) ? BC_A^BC_B: (ori|Or) ? BC_A|BC_B: (And|Andi) ? BC_A&BC_B: (lui) ? Imm32: ~(BC_A|BC_B);//Nor ``` ### 流水线冒险处理 采用的是T计数法,即,在Decode阶段算出该指令需要哪些寄存器,多少个周期后需要,以及多少个周期后会生成寄存器结果 再与随后各级流水线进行比较即可知道是否需要暂停或者转发 ### 乘法器设计 在大赛中,采用了Xilinx提供的乘法IP核,使得0周期就可以产生乘法结果,十分利于Mul指令的实现 但是,代码里面也内置了手写的5周期乘法器,以及优化2~16周期的除法器 具体原理可以百度一下硬件实现乘除法(那两段代码写得忒丑了) ### 加速器设计 没什么好说的,就是针对决赛时,”统计一个32位二进制数中1的个数“,用硬件实现了一个统计器。 为了优化各级延迟,这个加速器设置为了两个周期出结果,横跨E级和M级。 ### UART接口设计 采用的是大赛提供的UART模块,但是这有个坑,大赛的UART模块似乎时延很大,如果直接接到CPU上,会导致CPU得到错误的结果。 因此,我给他接上了一个FIFO缓冲模块,优化了输入输出相关的东西 ### 内存速率上限 大赛官方提供的元器件手册上显示,开发板上SRAM的最高速率为50Mhz,但是实践表明,在设计良好的情况下(把一整级流水的空隙全给访存使用)可以达到更高的频率 具体而言,在我的CPU上,未添加加速器前最高可达65.647480Mhz