网络知识 娱乐 MIPS单周期CPU

MIPS单周期CPU

一、单周期CPU介绍

单周期CPU顾名思义就是一个指令周期内只执行一条指令的CPU。

比如下面的指令

在单周期CPU中执行的过程,体现为:

 在每一个周期(时钟上升沿),就执行完一条指令。

二、CPU设计

CPU是由一个指令存储器(IM,instruction Memory)和数据存储器(DM,DataMemory)还有CPU组成。其架构如下:

模块

功能描述

CPU

信号

描述

clock(clock)

时钟信号

reset(rst)

复位信号

instruction(Instruction)

执行的指令

ReadMemData(ReadMemData)

从内存中读出的数据

InstAddress(PC)

指令地址

AluResult(MemDataAddr)

从内存中读数据的地址

MemWrite(MemWrite)

是否写内存

WriteMemData(WriteMemData)

写入内存的数据

WriteMemDataLength(WriteMemDataLength)

表示写入内存的数据的位置,长度

模块

功能描述

InstructionMemory

指令存储器

信号

描述

PC[8:2]

指令地址

Instruction

指令

模块

功能描述

DataMemory

数据存储器

信号

描述

clock

时钟信号

MemDataAddr[8:2]

写入/读出内存数据的地址

MemWrite

是否写入内存

WriteMemData

写入内存的数据

WriteMemDataLength

表示写入内存的数据的位置,长度

ReadMemData

从内存中读出的数据

首先,CPU向指令存储器传入指令地址,也就是PC中存储的值,指令存储器就将对应的指令地址传给CPU。CPU开始执行指令 ,有的指令涉及到和数据存储器,比如LW,LB,LBU,LH,LHU指令需要读取数据存储器中的数据,SW,SH,SB指令需要将运算结果写入数据存储器中。就涉及到了CPU将数据和数据要存放的地址传给DM,也涉及到CPU将要读取的地址传给DM,DM将对应数据传回CPU。这就是CPU运作的大致流程,在单周期或者流水线CPU中基本没有什么变化。

而指令如何执行,CPU内部如何实现就是单周期和流水线CPU的差别所在。

CPU内部架构如图所示(看不清没办法了),大致描述一下过程,PC将指令地址传给IM,IM将指令送到控制器,控制器根据指令解析出指令的信号  (指令是否需要写入内存,指令是否需要写入寄存器,指令是否要进行符号扩展,指令的运算符是什么,下一个指令地址是什么等等)  之后,将信号传到各自的模块运算。

模块

功能描述

PC

负责PC更新,仅在 clk 或者 rst 为 posedge 时更新 PC。

信号

描述

NextPC(NextInstAddress)

从NextPC模块送来的下一条指令地址

PC(InstAddress)

指令地址

clock(clock)

时钟信号

reset(reset)

复位信号

模块

功能描述

NextPC

计算下一条指令地址

信号

描述

NextPC(NextInstAddress)

计算出的PC

PC(InstAddress)

当前正在处理的指令的PC值

NextPCSignal(NextPCSignal)

控制信号,选择哪一个作为下一个PC值

JumpAddr(JumpAddr)

J/JAL指令中的25位立即数作为跳转地址

JumpReg(RegSourceData)

JR/JARL指令跳转地址

模块

功能描述

CU

控制器模块,产生控制信号

信号

描述

Opcode

指令中的opcode字段

Func

指令中的function字段

RegTarget

指令中的rt字段,(用于区分bltz,bltzal...)

AluZeroSignal

用于判断分支指令是否跳转

RegWrite

是否写寄存器

MemWrite

是否写内存

SignExt

是否扩展立即数

RegimmSignal

表示是否是(BLTZ,BLTZAL...)

AluOpcode

ALU的操作符

NextPCSignal

下一条指令地址选择信号

AluSrcASignal

操作数A选择信号

AluSrcBSignal

操作数B选择信号

WriteRegDataSignal

写入寄存器数据的选择信号

WriteRegSignal

写入寄存器地址的选择信号

MemRead

是否读内存

模块

功能描述

Register

通用寄存器组,

信号

描述

clock(clock)

时钟信号

reset(reset)

复位信号

RegWrite(RegWrite)

是否写寄存器

ReadRegAddr1(RegSource)

读rs的地址

ReadRegAddr2(RegTarget)

读rt的地址

WriteRegAddr(WriteRegAddr)

写寄存器的地址

WriteRegData(WriteRegData)

写寄存器的数据

ReadRegData1(RegSourceData)

读出rs数据

ReadRegData2(WriteMemData)

读出rt数据

模块

功能描述

SRC_A

选择ALU的操作数A

信号

描述

DataIn0(RegSourceData)

读出rs数据

DataIn1(Shamt)

移位指令的位移量

Signal(AluSrcASignal)

ALU的操作数A选择信号

DataOut(AluOperandA)

操作数A

模块

功能描述

SRC_B

选择ALU的操作数B

信号

描述

DataIn0(WriteMemData)

读出rt数据

DataIn1(Imm32)

扩展后的32位立即数

Signal(AluSrcBSignal)

ALU的操作数B选择信号

DataOut(AluOperandB)

操作数B

模块

功能描述

ALU

运算器模块

信号

描述

AluOperandA(AluOperandA)

操作数A

AluOperandB(AluOperandB)

操作数B

AluOpcode(AluOpcode)

ALU的操作符

MemRead(MemRead)

是否读内存

MemWrite(MemWrite)

是否写内存

AluResult(AluResult)

运算结果

AluZeroSignal(AluZeroSignal)

判断运算结果与0的关系

AluOverflowSignal(AluOverflowSignal)

判断运算结果是否溢出

WriteMemDataLength(WriteMemDataLength)

表示写入内存的数据的位置,长度

ReadMemExtSignal(ReadMemExtSignal)

表示从内存读出的数据如何拓展

RegimmSignal(RegimmSignal)

表示操作数B是否是0,针对(BLTZ等指令)

模块

功能描述

WR_REG_ADDR

选择写寄存器的地址

信号

描述

DataIn0(RegDst)

写入rd寄存器

DataIn1(RegTarget)

写入rt寄存器

.DataIn2(5'b11111)

31号寄存器

Signal(WriteRegSignal)

选择信号

DataOut(WriteRegAddr)

写寄存器的地址

模块

功能描述

WR_REG_DATA

选择写寄存器的数据

信号

描述

DataIn0(AluResult)

运算器运算结果

DataIn1(MemDataExt)

从内存读出并扩展后的数据

DataIn2(InstAddress + 4)

当前指令的下一条指令地址,(JALR,JAL,BLTZAL...)

Signal(WriteRegDataSignal)

选择信号

DataOut(WriteRegData)

写寄存器的数据

模块

功能描述

SignExtension

扩展立即数

信号

描述

Imm16

指令中的16位立即数

SignExt

扩展信号,表示零扩展还是符号扩展

Imm32

扩展后的32位立即数

模块

功能描述

MemDataExtension

扩展从内存中读出的数据

信号

描述

ReadMemData

读出的数据

ReadMemExtSignal

扩展信号

MemDataExt

扩展后的数据

 

 这里带大家模拟执行一条指令,便于大家理解。

就比如第一条指令

首先,PC将00400000传给IM,IM读取到指令,2402ff9d(就是addiu $2,$0,-99的二进制码,表示将0号寄存器中的值加上-99,存储到2号寄存器中)传给CPU的控制器, 控制器解析指令,得到这条指令需要写入寄存器,需要对立即数进行负号扩展,运算器运算符是00001(定义为加法),下一个指令地址(NextPC)是顺序执行,在当前指令地址上加4。第一个运算数是寄存器R0(AluSrc1Signal是0表示读寄存器),第二个运算数是立即数(AluSrc2Signal是1),写入寄存器的数据不需要扩展,不需要读内存。这些信号传到各自模块中后,ALUSRC1会根据指令中的对应字段确认是几号寄存器,去寄存器中读取值,ALUSRC2会从立即数扩展器中得到扩展后的立即数,ALU得到ALUSRC1和ALUSRC2的两个运算符,得到AluCode是加法,计算之后,将结果传给寄存器,寄存器写入对应寄存器。这条指令就执行完成了。

详细资源:

Chris_William/BIT-MINI-MIPS-Single-Cycle-CPU - 码云 - 开源中国 (gitee.com)