中国海洋大学-蒋永国-计算机系统综合实践Ⅰ-MiniMIPS32原型系统-实验报告
MiniMIPS32_SyS原型系统的整体架构包括以下几点:1个MiniMIPS32处理器、2个存储器(分为指令存储器8KB,数据存储器8KB,均按字节编址)、1个GPIO控制器(2个LED灯和4个7 段数码管)、1个32位定时器、1个地址译码接口模块。

MiniMIPS32处理器的顶层设计图
基本的数据走向如图所示,其中黑色代表正常数据流动,紫色代表CP0相关信号,蓝色代表暂停控制,绿色代表转移指令控制。

特殊说明
因复位信号在各个阶段执行结果基本一致,均为清零信号以实现停止阶段的总体运行,故除了if_stage阶段以外的流程图,省略不画。
五段流水及流水段寄存器的模块
1.if_stage.v
(1)主要功能
根据PC的值从存储器取出指令,并确定下一条指令的地址,更新PC,以及处理跳转、暂停和异常情况。
(2)输入
时钟信号cpu_clk_50M;
复位信号cpu_rst_n;
三个跳转信号jump_addr_1/2/3和一个跳转选择信号jtsel;
流水线暂停信号stall;
清空流水线信号flush;
异常处理程序入口地址cp0_excaddr。
(3)输出
指令存储器访问使能信号ice;
当前pc值pc;
指令存储器访问地址iaddr;
pc+4的值pc_plus_4;
异常类型编码if_exccode_o ;
错误地址输出if_badvaddr_o。
(4)流程图

2.ifid_reg.v
(1)主要功能
连接if和id阶段的寄存器。暂存if信息,在下一个时钟周期传递给id。
(2)输入
时钟信号cpu_clk_50M;
复位信号cpu_rst_n;
获取的指令地址if_pc;
转移指令的地址基准if_pc_plus_4;
异常编码if_exccode;
错误地址if_badvaddr;
流水线暂停信号stall;
清空流水线信号flush
(3)输出
当前指令地址id_pc;
下一条指令地址id_pc_plus_4;
异常编码id_exccode;
错误地址id_badvaddr;
(4)流程图

3.id_stage.v
(1)主要功能
将32 位 MIPS 指令解析为exe和后续阶段所需的信号、内容,并对数据冒险、转移指令等进行判断和识别并输出对应信号、也同样支持异常识别、流水线暂停等操作。
(2)输入
复位信号cpu_rst_n;
当前pc值id_pc_i;
pc+4:pc_plus_4;
提取的32位指令id_inst_i;
寄存器数据rd1和rd2;
exe阶段的写回信号、地址、和数据exe2id_wreg、exe2id_wa、exe2id_wd;
mem阶段的写回信号、地址、和数据mem2id_wreg、mem2id_wa、mem2id_wd;
判断load-use的暂停信号exe2id_mreg、mem2id_mreg;
是否是延迟槽指令id_in_delay_i;
异常编码id_exccode_i;
错误地址id_badvaddr_i;
清空指令flush_im;
(3)输出
Alu类型和操作码id_alutype_o、id_aluop_o;
是否写HILOid_whilo_o;
是否位load id_mreg_o;
写入目标地址id_wa_o;
是否写入id_wreg_o;
store的写入数据id_din_o;
传递的源操作数id_src1_o和id_src2_o;
通用寄存器堆的使能和地址rreg1、ra1、rreg2、ra2;
转移指令地址和信号jump_addr_1、jump_addr_2、jump_addr_3、jtsel、ret_addr;
暂停信号stallreq_id;
cp0内容cp0_addr ;
pc值id_pc_o ;
当前及后续是否为延迟槽指令信号id_in_delay_o、next_delay_o;
异常编码和错误地址id_exccode_o、id_badvaddr_o
(4)流程图

4.idexe_reg.v
(1)主要功能
连接id和exe阶段的寄存器。暂存id信息,在下一个时钟周期传递给exe。
(2)输入
时钟信号cpu_clk_50M;
复位信号cpu_rst_n;
Alu类型、操作码id_alutype、id_aluop;
源操作数id_src1、id_src2:;
寄存器地址、使能id_wa、id_wreg;
内存使能id_mreg;
写入数据id_din;
HILO使能id_whilo;
跳转返回地址id_ret_addr;
CP0地址id_cp0_addr;
延迟指令id_in_delay;
Pc值id_pc;
暂停、清空信号stall、flush;
异常代码和地址id_exccode、id_badvaddr;
(3)输出
Alu类型和操作码exe_alutype:、exe_aluop;
源操作数exe_src1、exe_src2;
寄存器地址、使能exe_wa、exe_wreg;
内存使能exe_mreg;
数据exe_din;
HILO使能exe_whilo;
跳转返回地址exe_ret_addr;
CP0地址exe_cp0_addr;
Pc值exe_pc;
延迟信号exe_in_delay;
下一阶段延迟信号next_delay_o;
异常代码和地址exe_exccode:、exe_badvaddr;
(4)流程图

5.exe_stage.v
(1)主要功能
根据译码阶段给出的信息并结合HILO相关信息进行运算,得到运算结果或访存地址,并将部分信号直接转移至下一阶段。
(2)输入
时钟和复位信号cpu_clk_50M、cpu_rst_n;
ALU 类型和操作码exe_alutype_i、exe_aluop_i;
操作数exe_src1_i和exe_src2_i;
写回寄存器地址和写使能exe_wa_i、exe_wreg_i;
存储器写使能和数据exe_mreg_i、exe_din_i;
返回地址ret_addr;HILO数据hi_i和lo_i;
HILO写使能whilo_i;
从mem传来的HILO值mem2exe_whilo 和 mem2exe_hilo;
从wb传来的HILO值wb2exe_whilo 和 wb2exe_hilo;
CP0的地址与数据cp0_addr_i 和 cp0_data_i;
mem对cp0的写使能、地址、数据mem2exe_cp0_we、mem2exe_cp0_wa、mem2exe_cp0_wd;
wb对cp0的写使能、地址、数据wb2exe_cp0_we、wb2exe_cp0_wa 、wb2exe_cp0_wd;
延迟槽信号与异常代码和地址exe_in_delay_i、exe_exccode_i 、exe_badvaddr_i。
(3)输出
操作码、写地址、写使能、运算结果、访写存的数据exe_aluop_o、exe_wa_o、exe_wreg_o、exe_wd_o、exe_mreg_o、exe_din_o;
当前地址与延迟槽信号exe_pc_o、exe_in_delay_o;
HILO写使能和数据exe_whilo_o 、 exe_hilo_o;
CP0读使能、地址、写使能、地址以及数据cp0_re_o、cp0_raddr_o、cp0_we_o、cp0_waddr_o 、cp0_wdata_o;
异常地址和类型exe_exccode_o 和 exe_badvaddr_o;暂停信号stallreq_exe。
(4)流程图

6.exemem_reg.v
(1)主要功能
连接exe和mem阶段的寄存器。暂存exe信息,在下一个时钟周期传递给mem。
(2)输入
时钟信号cpu_clk_50M;
复位信号cpu_rst_n;
Alu操作码exe_aluop;
寄存器地址、写使能、数据exe_wa、exe_wreg、exe_wd;
内存写使能、数据exe_mreg、exe_din;
HILO写使能、数据exe_whilo、exe_hilo。
(3)输出
Alu操作码mem_aluop;
寄存器地址、写使能、数据mem_wa、mem_wreg、mem_wd;
内存写使能、数据mem_mreg、mem_din;
HILO写使能、数据mem_whilo、mem_hilo;
(4)流程图

7.mem_stage.v
(1)主要功能
对于访存指令,该阶段会访问存储器,以读出数据或写入数据。否则,只需将从执行阶段传递来的信息发送到写回阶段。同时,在该阶段还要判断是否有异常需要处理,如果有,则清除流水线,然后转移到异常处理程序入口继续执行。
(2)输入
复位信号cpu_rst_n;
Aluop:mem_aluop_i;
寄存器地址、写使能、数据mem_wa_i、mem_wreg_i、mem_wd_i;
内存写使能、数据mem_mreg_i、mem_din_i;
HILO写使能、数据mem_whilo_i、mem_hilo_i;
CP0写使能、地址、数据cp0_we_i、cp0_waddr_i、cp0_wdata_i;
Wb返回的CP0写使能、地址、数据wb2mem_cp0_we;wb2mem_cp0_wa、wb2mem_cp0_wd;
Pc值mem_pc_i;
延迟槽信号mem_in_delay_i;
异常编码和地址mem_exccode_i、mem_badvaddr_i;
CP0状态和原因cp0_status、cp0_cause。
(3)输出
写寄存器地址、写使能、数据mem_wa_o、mem_wreg_o、mem_dreg_o;
内存写使能mem_mreg_o;
字节选择dre;
HILO写使能、数据mem_whilo_o、mem_hilo_o;
数据存储器的送使能、地址、写使能、数据dce、daddr、we、din;
CP0写使能、地址、数据、pc值、延迟输入信号、异常码、异常地址cp0_we_o、cp0_waddr_o、cp0_wdata_o、cp0_pc 、cp0_in_delay、cp0_exccode、cp0_badvaddr。
(4)流程图

8.memwb_reg.v
(1)主要功能
连接mem和wb阶段的寄存器。暂存mem信息,在下一个时钟周期传递给wb。
(2)输入
时钟信号cpu_clk_50M;
复位信号cpu_rst_n:;
寄存器地址、写使能、数据mem_wa、mem_wreg、mem_dreg;
内存访问使能、数据读取扩展mem_mreg、mem_dre;
HILO使能、数据mem_whilo、mem_hilo
CP0写使能、地址、数据mem_cp0_we、mem_cp0_waddr、mem_cp0_wdata;
清空flush;
符号信号mem_sign;
(3)输出
寄存器地址、写使能、数据wb_wa、wb_wreg、wb_dreg;
内存使能、读取扩展wb_mreg、wb_dre;
HILO使能、数据wb_whilo、wb_hilo;
CP0写使能、地址、数据wb_cp0_we、wb_cp0_waddr、wb_cp0_wdata;
符号信号wb_sign;
(4)流程图

9.wb_stage.v
(1)主要功能
将指令运算的结果或者从数据存储器读出的数据写入到目的寄存器中。
(2)输入
复位信号cpu_rst_n;
选择内存还是alu结果wb_mreg_i;
字节顺序wb_dre_i;
寄存器的地址、写使能wb_wa_i、wb_wreg_i;
Alu和存储器数据wb_dreg_i、dm;
是否为HILO、写回数据:wb_whilo_i、wb_hilo_i;
(3)输出
寄存器地址、写使能、数据wb_wa_o;wb_wreg_o;wb_wd_o;
HILO信号、数据wb_whilo_o、wb_hilo_o;
CP0写使能、地址、数据cp0_we_o;cp0_waddr_o;cp0_wdata_o;
符号控制信号sign。
(4)流程图

10.regfile.v
(1)主要功能
实现寄存器文件的功能,包括读写操作,为指令执行提供操作数,并保存运算结果。
(2)输入
时钟和复位信号cpu_clk_50M、cpu_rst_n;
写地址、数据、写使能wa、wd、we;
读地址与读使能ra1、re1、ra2、re2;
(3)输出
读数据rd1、rd2;
(4)流程图

11. hilo.v
(1)主要功能
实现MIPS架构中的HI/LO特殊寄存器对,用以进行64位相关的运算。
(2)输入
时钟和复位信号cpu_clk_50M、cpu_rst_n;
写使能、写hi和lo的数据we、hi_i、lo_i;
(3)输出
Hi和lo的数据hi_o、lo_o;
支持定向前推
此程序设计中支持了定向前推以解决数据依赖等问题,例如当连续两条或者隔一个指令对着同一寄存器进行操作时,可以通过转发技术从先前阶段已经运算出来并保存在寄存器中的数挪到exe阶段继续使用;再比如隐式的定向前推:在寄存器regfile.v模块中,当尚未写入的数据就是要读出的数据时实际上就会直接读取尚未写入的数据来节省时间。
转移指令
程序设计中采用延迟槽和分支预测等机制优化j型和beq等转移指令的执行。延迟槽使得在转移指令后仍可进行部分指令运行,节省了当分支预测没有发生跳转还必须暂停的一个周期的浪费,从而让运行效率继续提升,减少了性能损失、运行功耗并提升指令运行速率。
支持暂停机制
主要由SCU.v和各个模块之间的接口实现,其内部代码实现运用条件运算符实现优先级编码,若要进行复位,则令输出的stall信号全为0,若为exe请求暂停则会输出4’b1111,以此暂停所有流水线,而如果是id阶段请求暂停,则是4;b0111来暂停前三个流水线阶段,否则正常情况下全为0代表正常流动。
异常处理
主要由cp0_reg.V和各个模块之间的接口实现,其内部代码通过状态寄存器和原因寄存器管理处理器状态用以检测各类异常中断;生成异常处理程序入口地址并提供异常返回机制 (ERET) 。每个阶段都有对应的exccode_i和badvaddr_i作为异常编码和地址作为输入传进,还有对应的中断输入、延迟槽信号及地址信号。检测到异常时将flush掉整段流水线,并进行检测延迟槽和分支等情况,随后保存异常代码和地址,根据异常类型生成对应异常处理程序的入口地址。

实验心得
在课上老师先总体带我们过了一遍计基和计组相关的知识,随后便带着进入MiniMIPS32的相关学习当中。其中绝大多数情况和计组学到的知识以及对应的verilog实验类似,但相比先前的verilog代码复杂好几倍,相比计组的实验额外添加了CP0、暂停、异常处理、HILO、复位等内容,就连跳转指令和数据的定向前推也与先前学到的知识有所不同。
不过好在本课主要目的在于看懂代码并能深刻理解,而这比人为手动编写代码轻松许多,对于知识的掌握速度也更快更有效率。我一步步地对每一个部分的代码进行了深入的观察和思考,清楚了解有关CP0、数据前推、异常和暂停这类需要宏观控制整个操作系统的内容,是如何在每个部分以什么样的方式编写并实现最终功能的。即使在一开始我还对MTF0、MTC0以及CP0的出现感到不解且多余,也仍会在浏览代码过程中不禁感慨,到对于一个真实的可运行的操作系统而言,这套严谨且必须要存在的模块是有多么重要,他们确保了整段代码的正确性和高效性,可见课本内容与真实实践的内容相比是有多么悬殊。
跳转指令利用了延迟槽等未曾学过的设计,而此设计也是处理器所需也在情理之中,其设计的相当巧妙,真正实现了分支预测的基础功能,加速了整段流水线的运行。数据前推等指令更是让我见识到了真实编码的时候代码的长度和壮观程度,综合了各路信号最终决定数据来源。
总体而言本次实验帮助我重新梳理了先前所学习的书本知识,以真正的代码实现方式让我理解了制作一个cpu时内部的具体实现,用真正完善且复杂的代码体系将我脑中零碎且简陋的知识点串起来并巩固起来,完善了对系统底层的相关知识,构筑起了整体的知识体系。
更多推荐
所有评论(0)