单指令周期CPU——移动操作指令的实现

代码放在github上
在之前实现的基础上继续增加了移动操作指令(增加了特殊寄存器HI和LO,以及对他们的操作)
之前操作的传送门:
单指令周期ori指令的实现
单指令周期CPU—–逻辑、移位操作和空指令

指令简介

MIPS指令集架构中定义6条移动操作指令:movn、movz、mfhi、mthi、mflo、mtlo

后4条指令涉及对特殊寄存器HI、LO的读写操作

HI、LO寄存器用于保存乘法、除法结果

6条移动操作指令格式:
这里写图片描述
由指令格式可以看出指令码都是6’b000000(bit26\~31),由功能码(0\~5bit)判断是哪个指令,并且指令6~10bit都是0
- movn(功能码是6’b001011):用法:movn rd, rs, rt;作用:if rt != 0 then rd <- rs(如果rt通用寄存器里的值不为0,则将地址为rs的通用寄存器的值赋值给地址为rd的通用寄存器)
- movz(功能码是6’b001010):用法:movn rd, rs, rt;作用:if rt == 0 then rd <- rs(如果rt通用寄存器里的值为0,则将地址为rs的通用寄存器的值赋值给地址为rd的通用寄存器)
- mfhi(功能码是6’b010010):用法:mflo rd 作用:rd <- lo将特殊寄存器HI的值赋给地址为rd的通用寄存器
- mflo(功能码是6’b010000):用法 mflo rd 作用:rd <- lo将特殊寄存器LO的值赋给地址为rd的通用寄存器
- mthi(功能码是6‘b010001):用法:mthi rs 作用:hi <- rs将地址为rs的通用寄存器的值赋给特殊寄存器HI
- mtlo(功能码是6’b010011):用法:mtlo rs 作用:lo <- rs,将地址为rs的通用寄存器的值赋给特殊寄存器LO

修改系统结构

对之前的结构进行改变
1. 增加HILO模块,实现HI、LO寄存器
2. 增加执行模块EX的输入接口,接收从HILO模块传来的HI、LO寄存器的值;输出到WB模块是否要写HILO、写入HI寄存器的值、写入LO寄存器的值
3. 增加回写模块WB的输入输出接口
这里写图片描述

添加HILO模块,实现HI、LO寄存器

module hilo_reg(
    input wire clk,
    input wire rst,

    //写端口
    input wire we,
    input wire[`RegBus] hi_i,
    input wire[`RegBus] lo_i,

    //读端口
    output reg[`RegBus] hi_o,
    output reg[`RegBus] lo_o
);
always @(posedge clk)begin
  if(rst==`RstEnable) begin
    hi_o <= `ZeroWord;
    lo_o <= `ZeroWord;
  end else if(we == `WriteEnable) begin
    hi_o<=
  end
end

修改译码阶段的ID模块

首先把移动操作这令的这六条指令的功能码和操作码以及操作类型的宏定义添加到defines.v文件中去:

`define EXE_MOVZ  6'b001010     //指令MOVZ的功能码
`define EXE_MOVN  6'b001011     //指令MOVN的功能码
`define EXE_MFHI  6'b010000     //指令MFHI的功能码
`define EXE_MTHI  6'b010001     //指令MTHI的功能码
`define EXE_MFLO  6'b010010     //指令MFLO的功能码
`define EXE_MTLO  6'b010011     //指令MTLO的功能码
`define EXE_MOVZ_OP  8'b00001010
`define EXE_MOVN_OP  8'b00001011
`define EXE_MFHI_OP  8'b00010000
`define EXE_MTHI_OP  8'b00010001
`define EXE_MFLO_OP  8'b00010010
`define EXE_MTLO_OP  8'b00010011
`define EXE_RES_MOVE 3'b011 

其次在译码模块ID中根据六条指令的功能码判断是那一条指令:
这里写图片描述
- MFLO和MFHI:将特殊寄存器LO和HI赋给通用寄存器,则可以知道肯定是要修改寄存器的即wreg_o为WriteEnable,而且不需要读取寄存器的值即reg1_read_o和reg2_read_o都为0,另外运算类型为EXE_RES_MOVE
- MTHI和MTLO:将通用寄存器的值赋值给特殊寄存器LO和HI,则可知不需要修改通用寄存器的值即wreg_o为WriteDisable,需要读取端口1的寄存器的值,也就是指令中rs的值即reg1_read_o 为1,另外运算类型为EXE_RES_NOP
- MOVN和MOVZ:需要读取rs,rt寄存器的值即reg1_read_o和reg2_read_o都为1,从端口1中读取rs寄存器(指令的21\~25b

一、 设计目标 设计目的: 设计一个含有36条指令MIPS单周期处理器,并能将指令准确的执行并烧写到试验箱上来验证 设计初衷 1、理解MIPS指令结构,理解MIPS指令集中常用指令的功能编码,学会对这些指令进行归纳分类。 2、了解熟悉MIPS体系中的处理器结构 3、熟悉并掌握单周期处理器CPU的原理设计 4、进一步加强Verilog语言进行电路设计的能力 二、实验设备 1、装有xilinx ISE的计算机一台 2、LS-CPU-EXB-002教学系统实验箱一台 三、实验任务 1.、学习 MIPS 指令集,深入理解常用指令的功能编码,并进行归纳确定处理器各部件的控制码,比如使用何种 ALU 运算,是否写寄存器堆等。 2、单周期 CPU 是指一条指令的所有操作在一个时钟周期内执行完。设计中所有寄存器存储器都是异步读同步写的,即读出数据不需要时钟控制,但写入数据需时钟控制。 故单周期 CPU 的运作即:在一个时钟周期内,根据 PC 值从指令 ROM 中读出相应的指令,将指令译码后从寄存器堆中读出需要的操作数,送往 ALU 模块,ALU 模块运算得到结果。 如果是 store 指令,则 ALU 运算结果为数据存储的地址,就向数据 RAM 发出写请求,在下一个时钟上升沿真正写入到数据存储器。 如果是 load 指令,则 ALU 运算结果为数据存储的地址,根据该值从数据存 RAM 中读出数据,送往寄存器堆根据目的寄存器发出写请求,在下一个时钟上升沿真正写入到寄存器堆中。 如果非 load/store 操作,若有写寄存器堆的操作,则直接将 ALU 运算结果送往寄存器堆根据目的寄存器发出写请求,在下一个时钟上升沿真正写入到寄存器堆中。 如果是分支跳转指令,则是需要将结果写入到 pc 寄存器中的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值