MIPS流水线CPU的verilog实现 - 图文 联系客服

发布时间 : 星期一 文章MIPS流水线CPU的verilog实现 - 图文更新完毕开始阅读c9f71522ed630b1c59eeb52e

2. MIPS指令格式

1) R型指令格式

op、funct:共同决定指令名称,都为6位; rs :指定第一操作数的寄存器地址,为5位; rt :指定第二操作数的寄存器地址,为5位; rd :指定目标寄存器地址,为5位; sa :位移运算的移动位数,为5位。

本实验要实现的R型指令有:

① 算术逻辑运算指令:ADD、ADDU、SUB、SUBU、AND、OR、NOR、XOR 、SLT、SLTU ② 移位指令:SLLV、SRLV、SRAV、SLL、SRL、SRA ③ 寄存器跳转指令:JR

2) I型指令格式

op :决定指令名称,为6位;

rs :指定第一操作数的寄存器地址,为5位; rt :储存结果的寄存器地址,为5位; Imm:立即数,为16位。

本实验要实现的I型指令有: ① 存储器访问指令:LW、SW

② 立即数算术逻辑运算指令:ADDI、ADDIU、ANDI、ORI、XORI、SLTI、SLTIU ③ 分支指令:BEQ、BNE、BGEZ、BGTZ、BLEZ、BLTZ 注:

① I型指令中立即数算术逻辑运算指令对立即数(Imm)的处理应分为两类情况考虑: ??当指令为ADDI、ADDIU、SLTI、SLTIU时,指令中的16位立即数(Imm)应做符号扩展为32位:sign-extend(Imm)。此符号扩展电路在ID级完成。

??当指令为ANDI、ORI、XORI时,Imm应做“0”扩展为32位。考虑到资源的限制,在执行ANDI、ORI、XORI指令时,“0”扩展功能放在ALU内部(即EX级)完成。

② 对于条件分支指令:不执行分支语句时,跳转地址应为下一条地址;执行分支语句时,跳转地址应为下一条地址加上跳转指令数,即为立即数。由于跳转方向有两个:向前与向后,故立即数存在正负性,应该有符号扩展为32位:sign-extend(Imm)。

如果能够将立即数的位数扩充,跳转指令的范围将大大增加。

由于CPU中指令的起始地址都是4的倍数,因此它们地址的后两位都是0,那么跳过的指令数后两位也应为2’b00,故可将16为立即数左移两位扩充为18位,寻址地址范围也

9

扩大4倍。因此分支地址可表示为{PC+4+sign-extend(Imm)<<2}.

③ 对于取字指令LW操作为:rt<=Mem[rs+sign_extend(Imm)]

对于存字指令SW操作为:Mem[rs+sign_extend(Imm)]<=rt

由于地址的变化是在内存中进行,故立即数只需进行有符号位扩展,不能位移。

3) J型指令格式

op :决定指令名称,为6位; address:跳转的地址,为26位。

本实验要实现的I型指令有: 无条件跳转指令:J

注:指令都是32位,因此我们要把26位跳转地址扩展为32位。由于CPU中指令的起始地址都是4的倍数,因此它们地址的后两位都是0,可以把26位的address扩展为28位:{26-bits address,2’b00};剩下的最高4位则直接从PC中取,即跳转地址扩展为: {PC[31:28],26-bits address,2’b00}。

3. 指令译码模块ID的设计

10

指令译码模块的主要作用是从机器码中解析出指令,并根据解析结果输出各种控制信号。ID模块主要有指令译码(Decode)、寄存器堆(Registers)、冒险监测、分支检测和加法器等组成。ID模块的接口信息如下表所示:

引脚名称 clk Instruction_id[31:0] NextPC_id[31:0] RegWrite_wb RegWriteAddr_wb[4:0] RegWriteData_wb[31:0] MemRead_ex RegWriteAddr_ex[4:0] MemtoReg_id RegWrite_id MemWrite_id MemRead_id ALUCode_id[4:0] ALUSrcA_id ALUSrcB_id RegDst_id Stall Z J JR PC_IFWrite BranchAddr[31:0] JumpAddr[31:0] Imm_id[31:0] Sa_id[31:0] RsData_id[31:0] RtData_id[31:0] RdAddr_id[4:0] RsAddr_id[4:0] RtAddr_id[4:0] 方向 说 明 系统时钟 指令机器码 指令指针 寄存器写允许信号,高电平有效 寄存器的写地址 写入寄存器的数据 冒险检测的输入 Input 决定回写的数据来源(0:ALU 1:存储器) 寄存器写允许信号,高电平有效 存储器写允许信号,高电平有效 存储器读允许信号,高电平有效 决定ALU采用何种运算 决定ALU的A操作数的来源(0:rs 1:Sa) 决定ALU的B操作数的来源(0:rt 1:Imm) 决定Register回写是采用的地址(rt/rd) ID/EX寄存器清空信号,高电平插入一个流水线气泡 分支指令的条件判断结果 跳转指令 Output 寄存器跳转指令 阻塞流水线的信号,低电平有效 条件分支地址 跳转地址 符号扩展成32位的立即数 0扩展成32位的移位立即数 Rs寄存器数据 Rt寄存器数据 Rd寄存器地址 Rs寄存器地址 Rt寄存器地址

(1) 指令译码(Decode)子模块的设计

Decode控制器的主要作用是根据指令确定各个控制信号的值,是一个组合电路。我们将指令分成八类:

11

R_type1:ADD、ADDU、SUB、SUBU、AND、OR、

NOR、XOR 、SLT、SLTU、SLLV、SRLV、SRAV R型指令

R_type2:SLL、SRL、SRA JR_type:JR

J_type:J J型指令

I_type:ADDI、ADDIU、ANDI、ORI、XORI、SLTI、SLTIU

Branch:BEQ、BNE、BGEZ、BGTZ、BLEZ、BLTZ I型指令 LW:LW SW:SW

Decode输出的九组控制信号: ① RegWrite

决定是否对寄存器(Registers)进行写操作。当RegWrite高电平有效时,将数据写入指定的寄存器中。

需要写回寄存器的指令有:LW、R_type1、R_type2和I_type,则

RegWrite_id= LW || R_type1 || R_type2 || I_type ② RegDst

决定目标寄存器是rt还是rd。当RegDst=0时,rt为目标寄存器;当RegDst=1时,rd为目标寄存器。

需要写回寄存器的指令类型有:LW、R_type1、R_type2和I_type。其中, R_type1和R_type2的目标寄存器是rd,而LW和I_type的目标寄存器是rt。所以:

RegDst_id= R_type1 || R_type2 ③ MemWrite

决定是否对数据存储器进行写操作。当MemWrite有效时,将数据写入数据存储器指定的位置。

需要对写存储器的指令只有SW,所以:

MemWrite_id= SW ④ MemRead

决定是否对数据存储器进行读操作。当MemRead有效时,读取数据存储器指定位置的数据。

需要对读存储器的指令只有LW,所以:

MemRead_id= LW ⑤ MemtoReg

决定写入寄存器(registers)的数据来自ALU还是数据存储器。?当MemtoReg=0时,数据来自ALU;当MemtoReg=1时,数据来自数据存储器。

需要写回寄存器的指令类型有:LW、R_type1、R_type2和I_type。其中,只有LW写回寄存器的数据取自存储器,所以:

MemtoReg_id= LW ⑥ ALUSrcA

决定ALU第一操作数来源。当ALUSrcA=0时,ALU第一操作数A(详见转发电路设计);当ALUSrcA=1时,ALU第一操作数来源于0扩展的用于移位指令的5位sa。

12