第9章:加载存储指令的实现

9.1 加载存储指令说明

MIPS32指令集架构中定义的了8条加载指令、6条存储指令

9.1.1 加载指令lb、lbu、lh、lhu、lw说明

在这里插入图片描述

9.1.2 存储指令sb、sh、sw说明

在这里插入图片描述

9.1.3 加载存储指令用法示例

OpenMIPS处理器是按照字节寻址,并且是大端模式,在这种模式下,数据的高位保存在存储器的低地址中,而数据的低位保存在存储器的高地址中。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

9.2 加载存储指令实现思路

在这里插入图片描述

9.2.1 数据流图的修改

在这里插入图片描述

9.2.2 系统结构的修改

在这里插入图片描述

9.3 修改OpenMIPS以实现加载存储指令

9.3.1 修改译码阶段

  1. 修改ID模块
    在这里插入图片描述
  2. 修改ID/EX模块
    在这里插入图片描述

9.3.2 修改执行阶段

  1. 修改EX模块
    在这里插入图片描述
  2. 修改EX/MEM模块
    在这里插入图片描述

9.3.3修改访存阶段

在这里插入图片描述
在这里插入图片描述

9.3.4 修改OpenMIPS顶层模块

在这里插入图片描述
在这里插入图片描述

9.4 修改最小SOPC

为了验证加载存储指令是否实现正确,需要修改在第4章中设计的最小SOPC,为其添加数据存储器RAM。

9.4.1 添加数据存储器RAM

在这里插入图片描述
在这里插入图片描述

9.4.2 修改最小SOPC

在这里插入图片描述

9.5 测试程序

9.6 链接加载指令II、条件存储指令sc说明

  • II、sc是MIPS32指令集架构中比较特殊的加载存储指令,用来实现信号量机制。
  • 在多线程系统中,需要RMW(Read-Modify-write)操作序列保证对某个资源的独占性,RMW操作序列的含义是,读取内存某个地址的数据,读取的数据经过修改然后保存回内存原地址,在这个过程中不能有任何打扰,因此需要建立一个临街区域,临街区域中完成的操作通常称为原子操作,原子操作不被打扰。操作系统建立临街区域的方式通常是信号量机制,如下:
    在这里插入图片描述
    semaphore是一个信号量,为1表示信号量使用中,为0 表示信号量空闲。进行原子操作前,使用wait函数查询semaphore的值,如果为1,则等待,否则将其置为1,开始执行原子操作。操作结束后,signal函数将semaphore置为0,这样其他线程就可以执行原子操作了。

9.7 II、sc指令实现思路

9.7.1 II、sc指令的实现

两条指令都设计访问链接状态位LLbit,可以将LLbit当做寄存器处理,II指令需要写该寄存器,sc指令需要读该寄存器,同时,与对通用寄存器的访问都一样,对LLbit寄存器的写操作也放在回写阶段进行。

9.7.2 数据流图的修改

在这里插入图片描述

9.7.3 系统结构的修改

在这里插入图片描述

9.8 修改OpenMIPS以实现II、sc指令

9.8.1 LLbit寄存器的实现

在这里插入图片描述

9.8.2 修改译码阶段的ID模块

在这里插入图片描述

9.8.3 修改访存阶段

  1. 修改MEM模块
    2.
  2. 修改MEM/WB模块
    在这里插入图片描述

9.8.4 修改OpenMIPS模块

9.9 测试II、sc指令实现效果

9.10 load相关问题

9.10.1 load相关问题介绍

在这里插入图片描述
在这里插入图片描述
由于数据加载时,beq指令已经处于执行阶段,已经进行了比较判断,这种情况称为load相关,数据前推也解决不了问题。

9.10.2 解决方法

OpenMIPS解决load相关的方法是:在译码阶段检查当前指令与上一条指令是否存在load相关,如果存在load相关,那么就让流水线的译码、取指阶段暂停,而执行,访存,回写阶段继续,相当于插入一条空指令,这样处于执行阶段的加载指令会继续运行,不受影响,当其运行到访存阶段时,将加载得到的数据前推到译码阶段,然后流水线可以继续运行。
在这里插入图片描述
在这里插入图片描述

9.11 修改OpenMIPS以解决load相关问题

9.11.1 修改译码阶段的ID模块

在这里插入图片描述

9.11.2 修改OpenMIPS模块

9.12 测试load相关问题的解决效果

9.13 小结

猜你喜欢

转载自blog.csdn.net/tanfuz/article/details/113815181
今日推荐