发布时间 : 星期一 文章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