MIPS单周期CPU设计(24条指令+差异化指令 OR 45条指令) 详细实现

        本实验来自于谭志虎老师的《计算机组成原理实验指导与习题解析》5.3 节的全部内容,目的是向读者朋友提供一个实现参考,因为个人认为这节内容还是很不错的,实现了 MIPS 45条指令,已经绰绰有余了。

目录

1. 实验要求

2. 具体实现

2.1 指令编码规律 

2.2 C 类指令实现

        2.2.1新增控制信号

       2.2.2 指令实现

2.3 B类指令实现

​编辑

信号控制信号

地址位宽注意点

指令实现

2.4 M类指令实现

        大坑

地址位宽注意点 CS3410 MIPS RAM

新增信号

指令实现

MenByteSel

3. 测试说明

4. 资源下载(免费)

5. 向我留言


1. 实验要求

        实现 45 条指令的单周期 MIPS CPU。

        在 24条指令的基础上随机增加表 5.13 中的扩展指令,应包括两种C类指令、一种 M 类指令、一条B类指令,简称 CCMB 系列指令。最终实现的MIPS处理器能正确运行标准测试程序 benchmark.asm,以及新增的扩展指令的测试程序。读者需要单独测新增试扩展指令的标准测试程序(详见实验资源包),并修改 syscall系统调用的功能。当系统调用号不等于34(十进制)时,一律是暂停当前程序的执行,而不是停机;系统调用号等于34(十进制)将数据输出到数码管;暂停后等待用户按下电路中的Go按钮才能继续运行后续测试程序。

  

2. 具体实现

        使用 Logisim,采用单周期、硬布线控制器实现,下图是最终的 Logisim 电路图、真值表、内存控制器真值表。

        由于是总体性,看不懂很正常,不懂可以大致看看,然后深入具体电路中会好懂一些。

最终Logisim电路图​​​​

最终 控制信号真值表

      

内存控制器控制信号真值表

2.1 指令编码规律 

        注意:以下结论适合大部分指令,但不是绝对的,具体细节参考资源下载中的《MIPS32指令手册.pdf》

        R型指令,rd 为目标寄存器编号,rs 第一源操作数、rt 第二源操作数

        I型指令,rt 为目标寄存器编号,rs 第一源操作数、Imm(16) 为第二源操作数

        R、I型指令,rs 第一源操作数

  

2.2 C 类指令实现

          实现 C 类指令要注意的点,已经用红色加粗标识出来了。而且“硬布线控制器”的输出端,新增了 HiToReg、LoToReg、ResToLoHiWrite、LoExt、RegShamt 这几个输出控制信号。

        2.2.1新增控制信号


        1. HiToReg、LoToReg 控制信号

        用于 mfhi 指令,将寄存器内容传送到 HI 寄存器中,同理 LoToReg 用于 mflo 指令,将寄存器内容传送到 LO 寄存器中。

        2. ResToLoHiWrite

         用于 mult、div 乘法,除法指令,将低32bit结果写入 Lo 寄存器,高32bit结果写入 Hi 寄存器。我觉得这个信号名称不太好,换成 LoHiWrite 比较好。

        3. LoExt

        用于 LUI 指令,将立即数写回寄存器时控制低位零扩展,形成32bit数据,写入 $rt 目标寄存器中。

lui $rt, imm

R[$rt] <-  { (imm)[15:0],   16x0}      低位零扩展

        4. RegShamt

        用可变位移指令,注意,该类指令第一源操作数是 $rt,位移量由 $rs 提供,这3条指令的信号都是一样的,运算类型有 ALUOP 指定。

       2.2.2 指令实现

  • SLLV、SRLV、SRAV
    需要注意第一操作数是 $rt、位移量是 $rs。
     
  • SUBU、XOR 
    标准R型指令,和 add 的控制信号一样,注意:subu,这里的“u”是运算溢出后不触发中断,不是进行无符号减法,减法和加法本质上是不区分符号的。乘法、除法才需区分有符号和无符号。
  • XORI

        标准I型指令,和 andi 逻辑运算类指令信号一样。

  • LUI
lui $rt, imm

R[$rt] <-  { (imm)[15:0],   16x0}      低位零扩展

        在我的实现中是:新增一个控制信号,用于控制低位零扩展,然后再将扩展后的32bit数据,写入到寄存器中。       

  • SLTIU

        和 24 条基础指令总的 SLTI 的控制信号一样,除了 ALUOP 不一样,因为本指令是无符号比较,而 SLTI 是有符号比较

  • MULTU、DIVU
multu $rs, $rt
{Hi, Lo} <-  R[$rs] * R[$rt]                       无符号乘法 


divu $rs, $rt
Lo  <- R[$rs] / R[$rt],Hi <- R[$rs] % R[$rt]      无符号除法

        无符号乘、除。数据通路的控制有些特殊,只需将 ALU 的 Res1 写入 Lo,Res2 写入 Hi 即可,因此需要 RestoLoHiWrite=1。

  •  MFLO、MFHI
mflo $rd
R[$rd] <- Lo

mfhi $rd
R[$rd] <- Hi

        将通用寄存器内容写入 Hi、Lo 寄存器,故 HiToReg、LoToReg 都为1。

2.3 B类指令实现

        包括下面4条指令,和 beq、bne 类似,但又有不同。不同点:下面4条指令是和0左比较,而 beq、bne 是判断是否相等,而寄存器文件中 31号寄存器是常零值,就可以利用它来实现 

信号控制信号

        新增了 LEZ(小于或等于零则跳转)、GTZ(大于零则跳转)、LTZ(小于零则跳转)、GEZ(大于等于零则跳转)。

        注意:BLTZ、BGEZ OpCode都为1(十进制),需要再根据指令字的 20:16 位来判断具体是那个,详细细节在资源文件的《MIPS32指令集完整.pdf》中。

        在实现电路时需要再进行一次判断,判断当前指令是 BLTZ还是BGEZ。 

地址位宽注意点

        可以看到指令存储器地址输入端是32位的2-11位信号组成的10bit,作为地址输入信号,为什么是10bit,这好理解,因为我们的指令并没有那么多,重点是为什么是2:11位,为什么不是0:9组成的10位?因为 MIPS 32 每个指令固定占 4Byte,所以是4Byte对齐,也就是说低两位恒零,所以低2位就不需要了。

        另外当前的指令存储器是按字(4Byte)寻址的,每个地址对应的存储单元占4Byte。

指令实现

blez $rs, imm	if( R[$rs] <= 0 ) PC <- PC+4 + SignExt(imm)<<2	    有符号比较
bgtz $rs, imm	if( R[rs] > 0 )     PC <- PC+4 + SignExt(imm)<<2	有符号比较
bltz $rs, imm	if( R[rs] < 0 )     PC <- PC+4 + SignExt(imm)<<2	有符号比较
bgez $rs, imm	if( R[rs] >= 0 )     PC <- PC+4 + SignExt(imm)<<2	有符号比较

        下图中的 Res1 隧道标签就是 ALU 运算的结果,我们封装的 ALU 有“有符号比较”运算,x<y ? 1:0,利用下面的逻辑表示,就可以判断出是哪条跳转指令是否满足。

2.4 M类指令实现

        大坑

        CS3410  MIPS RAM 有个很大的坑,输入数据总,即便是不写入存储器中,存在高阻态信号,也会导致写入出错。

        要像这样才行,不写入的数据不能是高阻态。

地址位宽注意点 CS3410 MIPS RAM

        数据存储器使用的是 CS3410 MIPS RAM,地址位宽10bit,数据位宽32bit,是按字(4Byte)寻址的,所以字节地址0x000、 0x001、0x002、0x003都对应字地址0x000;字节地址 0x004(0b100)对应字地址0x001,以此类推。

        切记:CS3410 MIPS RAM 的地址输入端一定要是字地址(4Byte)寻址,即字节地址的低两位忽略。

        若想读取1字节的字节地址 0x001(0b01),那么字地址等于0x000,Sel=0010。Sel就是选择4Byte中的那一个字节的。

        若想读取2字节的字地址0x000,那么字地址等于0x000,Sel=0011。

新增信号

        M类指令是访存类指令,原有的控制信号和 LW、SW 是一样的。新增了如下的控制信号(由内存控制器生成)        根据指令来生成访问内存位宽,来生成是操作连续的4Byte,还是连续2Byte,还是1Byte。

        以及 MenOutSignExt,从内存中读取1Byte或2Byte数据传送到32Bit的寄存器中,必然要涉及到扩展,因为位宽不够。LB/LH进行符号扩展,LBU/LHU 进行零扩展。写入内存的数据不涉及位扩展。

指令实现

        M类指令相对比 SW、lW 复杂了不少,主要是支持了字节、半字(2Byte)、字(4Byte)的数据写入和读出。

        节选部分内存输入地址、输入数据,输出数据控制电路。

        其中 8 输入扩展,输入1是8位数据,输入2是SignExt,是否进行符号扩展,输出是32位扩展后的数据。16位输入扩展同理。

MenByteSel

        下图是内存控制器,输出的 MenByteSel 逻辑如下。

内存控制器

        上图的电路逻辑,用C语言描述,大概是:

if (1Byte) {
    switch (Addr[1:0]) {
        case 0b00: 
            MenByteSel = 0b0001;
            break;
        
        case 0b01:
            MenByteSel = 0b0010;
            break;

        case 0b10:
            MenByteSel = 0b0100;
            break;

        case 0b11:
            MenByteSel = 0b1000;
            break;
    }
}

if (2Byte) {
    switch (Addr[1:0]) {
        case 0b00: 
            MenByteSel = 0b0011;
            break;
        
        case 0b01:
            MenByteSel = 0b0110;
            break;

        case 0b10:
        case 0b11:
            MenByteSel = 0b1100;
            break;
    }
}

if (4Byte) {
    MenByteSel = 0b1111
}

3. 测试说明

        所有的测试程序都在资源文件下的“汇编工具及测试用例4.4”中,如果有想自定义测试的,可以手动写 mips 汇编,再使用 MARS 软件手动生成机器码。

        注意:下面只是列出部分用于参考,具体请下载资源,自行查看。

        测试程序的输出请看下图中的“CCMB输出汇总.docx”。

       C类指令测试程序:

      

         B类指令测试程序:

       

        M类指令测试程序:

    

        最终支持 45 条指令的 MIPS CPU,能够正确运行 CCMB、benchmark 这两个测试程序。

4. 资源下载(免费)

        此压缩包包含了 Logisim电路、Excel 自动生成逻辑表达式(真正表输入输出均已正确填写)、以及详尽的测试用例。

5. 向我留言

        如有任何疑问,可发表评论,我会及时处理! 

        若有讲解不清楚的地方,也欢迎留言,我都会及时处理!希望大家能够一起交流!

  • 27
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: MIPS周期CPU设计需要考虑以下几个方面: 1. 指令集的设计MIPS指令集包含24条指令,需要根据指令集的特点设计CPU指令集。 2. 数据通路的设计CPU的数据通路需要包含寄存器、ALU、控制元等模块,以实现指令的执行。 3. 控制元的设计:控制元需要根据指令的不同,控制数据通路中各个模块的工作,以实现指令的执行。 4. 存储器的设计CPU需要包含指令存储器和数据存储器,以存储指令和数据。 5. 中断处理的设计CPU需要支持中断处理,以响应外部事件。 6. 性能优设计CPU的性能需要优,可以采用流水线等技术提高CPU的执行效率。 以上是MIPS周期CPU设计需要考虑的几个方面,需要综合考虑各个方面的因素,才能设计出高效、稳定的CPU。 ### 回答2: MIPS是一种基于RISC (Reduced Instruction Set Computing)的指令集架构,具有精简指令集、快速响应、高效率等特点,被广泛用于微控制器和嵌入式系统中。在MIPS体系结构中,CPU通常采用周期设计,其指令集包括24条指令,这些指令可以被划分为6类,分别是:算术运算指令、逻辑运算指令、转移指令、访存指令、加载指令和存储指令。 在周期CPU设计中,每一条指令在执行过程中都需要占用一个时钟周期,因此这种CPU的时钟周期时间需要较长。在MIPS周期CPU设计中,CPU需要包括五个模块:指令存储器、指令译码器、执行元、数据存储器和控制元。 指令存储器模块主要是用于存储指令代码,执行译码器模块会对指令进行解码,并从其中提取出指令码、操作码、立即数、寄存器编号等信息。执行元则包括算术逻辑元(ALU)和移位元,它们主要用于进行各种数值计算。数据存储器是用于存储数据的,包括 CPU 中的寄存器和主存储器,控制元则是用于控制CPU中各个功能元的工作状态。 在设计MIPS周期CPU时,需要根据指令的不同来分配不同的控制信号,使CPU能够正确地执行指令。在指令序列中,访存指令和转移指令的执行过程较为复杂,需要特别考虑其执行过程中所需的控制信号,以确保CPU能够正确地执行指令。 为了进一步优MIPS周期CPU的性能,通常还需要引入流水线技术。在流水线的设计中,CPU的各个模块可以并行工作,从而实现指令的并行执行,大大提高了CPU的工作效率。不过在引入流水线的同时,也需要考虑各个模块之间的数据冲突和控制冲突等问题,以确保CPU的工作正常、稳定。 ### 回答3: MIPS 周期 CPU 设计是一种基于 MIPS 体系结构的 CPU 设计,它实现了 24 条指令的功能,包括数据传输、逻辑运算、跳转等基本操作。它的架构非常简,由五个主要部件构成,分别是取指元、执行元、数据存储器、寄存器堆以及控制元。 首先,取指元主要负责从程序存储器中读取指令,并将其送到执行元。执行元则将指令进行解码、分析和执行。数据存储器负责存储数据,供指令读取和写入。寄存器堆用于存储 CPU 内部的寄存器,包括通用寄存器和特殊寄存器。最后,控制元用于控制整个 CPU 的运行流程和时序。 在 MIPS 周期 CPU 设计中,指令流程非常简,取指、解码和执行都在同一个周期内完成。每条指令需要多个时钟周期才能完成,所以指令周期较长。但是由于 CPU 周期固定,逻辑电路简,因此响应速度比较快。 该设计包括以下 24 条指令: 1. 加载字(LW) 2. 存储字(SW) 3. 加(ADD) 4. 加立即数(ADDI) 5. 减(SUB) 6. 位与(AND) 7. 位或(OR) 8. 移位(SLL) 9. 移位立即数(SLLI) 10. 移位右(SRL) 11. 移位右立即数(SRLI) 12. 逻辑运算左移(SLT) 13. 逻辑运算左移立即数(SLTI) 14. 分支等于零(BEQZ) 15. 分支不等于零(BNEZ) 16. 跳转(J) 17. 跳转和链接(JAL) 18. 加载地址(LA) 19. 加载字节(LB) 20. 存储字节(SB) 21. 移位右算术(SRA) 22. 移位右算术立即数(SRAI) 23. 乘(MUL) 24. 除(DIV) 总的来说,MIPS 周期 CPU 设计是一种较为简,响应速度较快的 CPU 设计,但由于指令周期固定,每条指令都需要多个时钟周期才能完成,因此效率相对较低。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值