2022年结束了,过去一年确实发生了很多事情,开心的、伤心的、激动的、平凡的…这些都已经成为过去了,只希望在新的一年里,能够多一些开心,少一些emo,做一些自己喜欢的事情。
其实说实话,感觉我的2022年挺不尽人意的,很多事情明明可以坚持下去,最后都以放弃结束了;明明可以努力争取,却还是以摆烂结束…这些不尽人意就随着2022一起走吧!这些在2023年会改变的。
啊哈哈哈哈,大家一起加油哇!!!
MIPS指令 | 格式 |
---|---|
add r d , rd, rd,rs,$rt | R[ r d ] ← R [ rd]←R[ rd]←R[rs]+R[ r t ] 溢出时产生异常,且不修改 R [ rt] 溢出时产生异常,且不修改R[ rt]溢出时产生异常,且不修改R[rd] |
slt r d , rd, rd,rs,$rt | R[ r d ] ← R [ rd]←R[ rd]←R[rs] |
addi r t , rt, rt,rs,imm | R[ r t ] ← R [ rt]←R[ rt]←R[rs]+SignExt16b(imm) 溢出产生异常 |
lw r t , i m m ( rt,imm( rt,imm(rs) | R[ r t ] ← M e m 4 B ( R [ rt]←Mem4B(R[ rt]←Mem4B(R[rs]+SignExt16b(imm)) |
sw r t , i m m ( rt,imm( rt,imm(rs) | Mem4B(R[ r s ] + S i g n E x t 16 b ( i m m ) ) ← R [ rs]+SignExt16b(imm))←R[ rs]+SignExt16b(imm))←R[rt] |
beq r s , rs, rs,rt,imm | if(R[ r s ] = R [ rs] = R[ rs]=R[rt]) PC ← PC + SignExt18b({imm, 00}) |
bne r s , rs, rs,rt,imm | if(R[ r s ] ! = R [ rs] != R[ rs]!=R[rt]) PC ← PC + SignExt18b({imm, 00}) |
syscall | 系统调用,这里用于停机 |
(1)根据课程设计指导书的要求,制定出设计方案;
(2)分析指令系统格式,指令系统功能;
(3)根据指令系统构建基本功能部件,主要数据通路;
指令 | 格式 |
---|---|
Add | add $rd, $rs, $rt |
Add Immediate | addi $rt, $rs, immediate |
Add Immediate Unsigned | addiu $rt, $rs, immediate |
Add Unsigned | addu $rd, $rs, $rt |
And | and $rd, $rs, $rt |
And Immediate | andi $rt, $rs, immediate |
Shift Right Arithmetic | sra $rd, $rt, shamt |
Shift Right Logical | srl $rd, $rt, shamt |
Sub | sub $rd, $rs, $rt |
Or | or $rd, $rs, $rt |
Or Immediate | ori $rt, $rs, immediate |
Nor | nor $rd, $rs, $rt |
Load Word | lw r t , o f f s e t ( rt, offset( rt,offset(rs) |
Store Word | sw r t , o f f s e t ( rt, offset( rt,offset(rs) |
Branch on Equal | beq $rs, $rt, label |
Branch on Not Equal | bne $rs, $rt, label |
Set Less Than | slt $rd, $rs, $rt |
指令 | 格式 |
---|---|
Set Less Than Immediate | slti $rt, $rs, immediate |
Set Less Than Unsigned | sltu $rd, $rs, $rt |
Jump | j label |
Jump and Link | jal label |
Jump Register | jr $rs |
指令 | 格式 |
---|---|
syscall(display or exit) | Syscall |
(1)支持表 1.1 中8 条基本 32 位 MIPS 指令;
(2)能运行由自己所设计的指令系统构成的一段测试程序,测试程序应能涵盖;
(3)所有指令,程序执行功能正确;
(4)能运行教师提供的标准测试程序,并自动统计执行周期数。
1、程序计数器:在时钟沿到来时,用NPC的值更新PC。
2、指令存储器:将PC输入的地址对应的指令输出。
3、ALU:将A,B,C输入的操作数按照ALUOp信号进行相应的算术运算、逻辑运算或移位操作,输出为D。
4、寄存器组:本系统的寄存器组,可以读出指令中指定rs,rt对应的寄存器的数据,也能在时钟沿到来时将WDSel指定数据源的数据写入WRSel指定的寄存器之一。
5、数据存储器:按照ALUOUT给出的地址,将从RF读出的数据在时钟沿到来时写入存储器;或从存储器中读出对应地址的数据。
6、单周期硬布线控制器:按照OP和Func的值输出对应的控制信号。
单周期MIPS CPU数据通路要将运算和功能部件进行连接,组成一个能个执行取值、译码、执行、进一步可能包含中断的数据连接,能够让指令从PC开始,流向各运算和功能部件,并成功指令相应的功能,给出相应的返回,并且数据通路要具备基本的CPU要求,能够形成相应的数据流和状态转移。
因为是单周期CPU,所有指令均在一个时钟周期内完成操作,所以指令与数据分别采用ROM及RAM存储。一个指令周期包含取指周期和执行周期,因此实验的数据通路架构应该分为两块,即取指和执行。
RAM是一种可读/可写存储器,其特点是存储器的任何一个存储单元的内容都可以随机存储。ROM是只能对其存储的内容读出,而不能对其重新写入的存储器。
取址阶段完成取指令和分析指令的操作,称为取指周期。执行阶段完成指令的操作,成为执行周期。取指(包含跳转和分支指令,跳转和分支指令可改变程序的控制流)和PC相对寻址指令(地址计算依赖于PC值)称为“分支”,绝对地址指令(地址计算不依赖于PC值)成为“跳转”。具有跳转功能的指令有JR、J、JAL以及分支指令BEQ、BNE。
PC默认输入为PC+4(无跳转时下一条指令地址),跳转发生时根据不同的指令会指向不一样的地址,所以使用了三个二路选择器来实现跳转。一般情况下指令是顺序执行,控制信号为PC+4,我们用加法器来实现。输入端为当前指令地址和32位整数00000004,输出即为PC+4。
BEQ和BNE是根据比较的结果改变控制流,ifequal或者ifnotequal,所以可以合并为一条指令Branch。Branch、JMP、JR均为低电平时输入PC+4,否则就输入高电平的信号对应的那一地址。如果Branch为高电平而JR、JMP为低电平时输入PC+4+(SignExtImm<<2),即图中的PC+imm16<<2。
根据地址从指令寄存器中读出指令,再通过分线器读出指令的各个部分,硬布线控制器通过opcode和funct分析出指令将要执行的操作并产生控制信号。取指部分结束。
执行部分分为以下6个部分:
1.首先需要从数据寄存器进行输入。
2.再到运算器输入。
3.将数值存入存储器中。
4.当JAL信号为高电平时,把PC+4的值写回数据寄存器。(存放返回的地址)
5.Syscall指令与Led显示屏的输出:
6.总周期数的计算:为了方便平台测评,实验还要提供计算总周期数的功能,未停机时即为一个周期。执行部分到此结束。
CPU数据通路图如下:
根据给出的单周期硬布线控制器的线路,实现其中的运算器控制器和控制信号生成。使用logisim的组合逻辑电路分析功能,获取了相应量的表达式就可以自动生成对应的电路。
1.运算器控制器
运算器控制器设计的基本思想是通过24条MIPS指令的运算指令,进行组合逻辑分析,将运算指令送入到ALU_OP中。首先要对24条MIPS指令具体的执行过程进行分析,然后对每条MIPS指令,结合运算器ALU单元的运算规格,给出每条MIPS指令的运算类型,填入到自动生成表格中,进行ALU_OP值的生成,然后利用分析电路功能,自动生成电路。
2.控制信号生成器
控制信号生成器的基本思想与运算器部分类似,但这次不是对于24条MIPS指令的运算执行部分进行分析,而是对于24条MIPS指令具体所需要的控制信号进行分析,对每一条MIPS所需的控制信号分析,通过组合逻辑分析,得到控制信号的组合逻辑。
保存当前运行的指令的地址的寄存器数据通路合并的,把各种功能的数据路径合并,使得每个时钟周期执行一条指令基本方法:使用多路选择器与控制信号。通过一条指令来说明:(clk上升)使用当前PC寄存器的值取出一条指令。(clk高电平)指令送到IR寄存器,分段直接送往译码单元和寄存器堆,获得ALU_OP和Write_Reg信号。ALU接收到ALU_OP对两个读出的数据进行运算,同时计算标志寄存器的值。(clk下降沿)同时激活PC自增、目标寄存器的写入、标志寄存器的更新,根据高电平生成的控制信号来确定是否写入。
最左侧多路选择器,当执行有条件跳转指令时,选择跳转地址,跳转地址由15位的立即数运算得到;下一层为无条件跳转指令选择,当执行JAL(函数调用指令)或J(无条件跳转指令)选择由26位立即数运算得到的地址;第三层选择为JR指令(跳转到寄存器记录地址,一般用于在JAL调用退出时使用),一般选择寄存器保存JAL执行时PC的值,函数调用后,再读取寄存器的值进行返回。
指令控制逻辑,通过OP判断指令,根据指令输出对应的控制信号。ALU控制逻辑通过判断是加法还是比较指令并输出为ALUOP。
“纸上得来终觉浅,绝知此事要躬行”,通过指导书的帮助、自己的不断摸索以及与同学老师的探讨,我一步一个脚印,从单周期到多周期,从数据通路与控制信号表格,到模块的逐个编写,从模块单独测试到系统整体测试,我不断努力,最终取得实践的成功。当然,由于时间所限,设计的 CPU 并非完美无缺,还有一些地方可以进一步优化。例如:①可以改变 PC 更新的时机,调整 debug 信号逻辑;②可以尝试不使用双符号位而使用更简易的方法实现 SLTU 指令;③可以从原理上进一步分析,尝试继续优化指令实现的周期安排,尝试更合理地划分数据通路等等。
希望这篇文章会对大家有帮助,也希望大家在编程的道路上越走越远,早日成为IT届大佬!!!
后续将持续更新,大家的支持就是我创作的动力!!!