1.lw,sw指令格式及功能

指令 [31:26] [25:21] [20:16] [15:0] 意义
lw 100011 rs rt offset 从数存(数据存储器)中取数据写进寄存器
sw 101011 rs rt offset 将寄存器中的值写入数存

2.所需模块框图及指令执行过程


       lw指令和sw指令需要DataMem(数据存储器)来取数据或存数据。

执行过程:
       lw:
       从数存中取数据写入寄存器,rega提供数存单元地址(源),regc提供寄存器地址(目的)。
       ①IF模块将指令地址pc和片选信号romCe送入指存InstMem,从InstMem中取出数据由data脚送入ID模块的inst脚。
       ②ID将送入的inst进行译码,对于lw指令,将指令中的rs为送入regaAddr,连同regaRd读信号送入寄存器堆RegFile,读出regaData,送入ID模块的regaData_i。regaData_i里的数据加上指令中(经符号位扩展的)offset位,即regaData_i+offset,regaData_i+offset表示的就是要取的数据(在数存中)的地址。将regaData_i+offset送入ID的regaData,将指令中的rt位送入regcAddr。将ID中的regaData,regcAddr和regcWr分别送入EX模块的regaData,regcAddr_i和regcWr_i。
       ③EX模块的regaData作为memAddr送入内存MEM,regcAddr_i和regcWr_i作为regcAddr和regcWr送入MEM。
       ④MEM将送入的memAddr给要送出的memAddr(这里纠正框图中的一个错误,送入的memAddr应改为memAddr_i,modelsim中不能有命名相同的参数或变量。所以在这里将memAddr_i和memAddr分别称为要送入的memAddr和要送出的memAddr,下文也是一样,不再说明),将要取的数据地址memAddr和片选信号memCe送入数存DataMem,读取数据,从rdData送入MEM。
       ⑤MEM将rdData作为regData,将regcAddr作为regAddr,将regcWr作为regWr,然后将regData,regAddr和regWr送入regFile,将数据regData写进地址为regAddr的寄存器中。lw指令执行完毕。

sw:
       将寄存器中的数据写入数存,rega提供数存单元地址(目的),regb提供寄存器地址(源)。
       ①IF模块将指令地址pc和片选信号romCe送入指存InstMem,存InstMem中取出数据由data脚送入ID模块的inst脚。
       ②ID将送入的inst进行译码,对于sw指令,将指令中的rs位送入regaAddr。指令中的rt位送入regbAddr,将regbAddr、regaAddr、regaRd,regbRd送入RegFile,找到regbData和regaData送入ID的regbData_i和regaData_i。将regaData_i加上(经符号位扩展)的offset,并送入regaData。此时regaData中保存的就是要写入的数据在数存中的地址,regbData保存的就是要写入数存中的数据。将regaData和regbData分别送入EX的regaData和regbData。
       ③EX中,将regaData作为memAddr,regbData作为memData,分别送入MEM中的memAddr和memData。
       ④MEM将memData作为wtData,连通memAddr,memWr和memCe分别送入DataMem中的wtData、addr、we和ce,将数据写进DataMem,sw指令执行完毕。

3.代码

①define.v


`define RstEnable        1'b0
`define RstDisable       1'b1`define RomDisable       1'b0
`define RomEnable        1'b1`define RamWrite         1'b1
`define RamUnWrite       1'b0
`define RamEnable        1'b1
`define RamDisable       1'b0`define Valid            1'b1
`define Invalid          1'b0`define Zero             32'h00000000
`define nop              6'b001101`define Inst_lw          6'b100011
`define Inst_sw          6'b101011`define Lw              6'b001100
`define Sw              6'b001101

②IF.v


`include "define.v"module IF(input wire clk,input wire rst,output reg [31:0] pc,output reg romCe,input wire [31:0] jAddr,input wire jCe);always@(*)if(rst == `RstEnable)romCe = `RomDisable;elseromCe = `RomEnable;always@(posedge clk)if(romCe == `RomDisable)pc = `Zero;else if(jCe == `Valid)pc = jAddr;elsepc = pc+4;endmodule

③InstMem.v


`include "define.v"module InstMem(input wire ce,input wire [31:0] addr,output reg [31:0] data
);reg [31:0] instmem [1023:0];always@(*)if(ce == `RomDisable)data = `Zero;elsedata = instmem[addr[11:2]];initialbegininstmem[0] = 32'h8E1F0001;  //lwinstmem[1] = 32'hAC890000;  //swendendmodule

④ID.v


`include "define.v"module ID(input wire rst,input wire [31:0] inst,input wire [31:0] regaData_i,input wire [31:0] regbData_i,input wire [31:0] pc_i,output reg [5:0] op,output reg [31:0] regaData,output reg [31:0] regbData,output reg regcWr,output reg [31:0] regcAddr,output reg regaRd,output reg [31:0] regaAddr,output reg regbRd,output reg [31:0] regbAddr,output reg [31:0] jAddr,output reg jCe,output wire [31:0] pc
);wire [31:0] npc = pc + 4;wire [5:0] Inst_op = inst[31:26];wire [5:0] func = inst[5:0];reg [31:0] imm;//    assign pc = pc_i;always@(*)if(rst == `RstEnable)beginop = `nop;regaRd = `Invalid;regbRd = `Invalid;regcWr = `Invalid;regaAddr = `Zero;regbAddr = `Zero;regcAddr = `Zero;imm = `Zero;jCe = `Invalid;jAddr = `Zero;endelsebeginjCe = `Invalid;jAddr = `Zero;case(Inst_op)`Inst_lw:beginop = `Lw;regaRd = `Valid;regbRd = `Invalid;regcWr = `Valid;regaAddr = inst[25:21];regbAddr = `Zero;regcAddr = inst[20:16];imm = {{16{inst[15]}},inst[15:0]};end`Inst_sw:beginop = `Sw;regaRd = `Valid;regbRd = `Valid;regcWr = `Invalid;regaAddr = inst[25:21];regbAddr = inst[20:16];regcAddr = `Zero;imm = {{16{inst[15]}},inst[15:0]};endendcaseendalways@(*)if(rst == `RstEnable)regaData = `Zero;else if(op == `Lw || op == `Sw)regaData = regaData_i + imm;else if(regaRd == `Valid)regaData = regaData_i;elseregaData = imm;always@(*)if(rst == `RstEnable)regbData = `Zero;else if(regbRd == `Valid)regbData = regbData_i;elseregbData = imm;
endmodule

⑤EX.v

`include "define.v"module EX(input rst,input wire [5:0] op_out,input wire [5:0] op_i,//    input wire [31:0] pc_i,input wire [31:0] regaData,input wire [31:0] regbData,output reg [31:0] regcData,input wire regcWr_i,input wire [4:0] regcAddr_i,output wire regcWr,output wire [4:0] regcAddr,output wire [31:0] memAddr,output wire [31:0] memData,//HiLooutput reg [31:0] wHiData, //lw,swoutput reg [31:0] wLoData,output wire [31:0] rHiData,output wire [31:0] rLoData,output reg whi,output reg wlo);assign op_out = op_i;assign memAddr = regaData;assign memData = regbData;assign regcWr = regcWr_i;assign regcAddr = regcAddr_i;
endmodule

⑥MEM.v

`include "define.v"module MEM(input wire rst,input wire [5:0] op,input wire [31:0] regcData,input wire [4:0] regcAddr,input wire regcWr,input wire [31:0] memAddr_i,input wire [31:0] memData,input wire [31:0] rdData,output wire [31:0] regData,output wire [4:0] regAddr,output wire regWr,output wire [31:0] memAddr,output reg [31:0] wtData,output reg memWr,output reg memCe
);assign regData = (op == `Lw) ? rdData : regcData;assign regAddr = regcAddr;assign regWr = regcWr;assign memAddr = memAddr_i;always@(*)if(rst == `RstEnable)beginwtData = `Zero;memWr = `RamUnWrite;memCe = `RamDisable;endelsecase(op)`Lw:beginwtData = `Zero;memWr = `RamUnWrite;//readmemCe = `RamEnable;end`Sw:beginwtData = memData;memWr = `RamWrite;//writememCe = `RamEnable;enddefault:beginwtData = `Zero;memWr = `RamUnWrite;memCe = `RamDisable;endendcase
endmodule

⑦DataMem.v


`include "define.v"
module DataMem(input wire clk,input wire ce,input wire we,input wire [31:0] wtData,input wire [31:0] memAddr,output reg [31:0] rdData
);reg [31:0] data [31:0];  always@(*)if(ce == `RamDisable)rdData = `Zero;else rdData = data[memAddr[11:2]];always@(posedge clk)if(ce == `RamEnable && we == `RamWrite)data[memAddr[11:2]] = wtData;else ;initialbegindata [1] = 32'h0000001A; //lwend
endmodule

⑧RegFile.v


`include "define.v"module RegFile(input wire clk,input wire rst,input wire we,input wire [4:0] wAddr,input wire [31:0] wData,input wire regaRd,input wire regbRd,input wire [4:0] regaAddr,input wire [4:0] regbAddr,output reg [31:0] regaData,output reg [31:0] regbData
);reg [31:0] reg32 [31 : 0];    always@(*)if(rst == `RstEnable)regaData = `Zero;else if(regaAddr == `Zero)regaData = `Zero;elseregaData = reg32[regaAddr];always@(*)if(rst == `RstEnable)          regbData = `Zero;else if(regbAddr == `Zero)regbData = `Zero;elseregbData = reg32[regbAddr];always@(posedge clk)if(rst != `RstEnable)if((we == `Valid) && (wAddr != `Zero))reg32[wAddr] = wData;else ;  initialbeginreg32[4] = 32'h00000010; //swreg32[9] = 32'h000000FF; //sw   reg32[16] = 32'h00000004; //lwendendmodule

⑨MIPS.v

`include "define.v"
module MIPS(input wire clk,input wire rst,input wire [31:0] instruction,output wire romCe,output wire [31:0] instAddr
);wire [31:0] regaData_regFile, regbData_regFile;wire [31:0] regaData_id, regbData_id; wire [31:0] regcData_ex;wire [5:0] op;    wire regaRd, regbRd;wire [4:0] regaAddr, regbAddr;wire regcWr_id, regcWr_ex;wire [4:0] regcAddr_id, regcAddr_ex;wire [31:0] jAddr;wire jCe;wire [5:0] op_ex;wire [31:0] memAddr_ex,memData_ex;//lw and swwire [31:0] rdData,wtData;wire [31:0] memAddr;wire [4:0] regAddr_mem;wire [31:0] regData_mem;wire memWr,memCe;wire regWr_mem;wire wlo,whi;//hilowire [31:0] wLoData,wHiData;wire [31:0] rLoData,rHiData;IF if0(.clk(clk),.rst(rst),.jAddr(jAddr),.jCe(jCe),.romCe(romCe), .pc(instAddr));ID id0(.rst(rst),        .inst(instruction),.regaData_i(regaData_regFile),.regbData_i(regbData_regFile),.pc(instAddr),.op(op),.regaData(regaData_id),.regbData(regbData_id),.regaRd(regaRd),.regbRd(regbRd),.regaAddr(regaAddr),.regbAddr(regbAddr),.regcWr(regcWr_id),.regcAddr(regcAddr_id),.jAddr(jAddr),.jCe(jCe));EX ex0(.rst(rst),.op_i(op),        .regaData(regaData_id),.regbData(regbData_id),.regcWr_i(regcWr_id),.regcAddr_i(regcAddr_id),.rHiData(rHiData),.rLoData(rLoData),.regcData(regcData_ex),//out.regcWr(regcWr_ex),.regcAddr(regcAddr_ex),.op_out(op_ex),//lw and sw.memAddr(memAddr_ex),.memData(memData_ex),.whi(whi),.wlo(wlo),.wHiData(wHiData),.wLoData(wLoData));    MEM mem0(.rst(rst),.op(op_ex),.regcData(regcData_ex),.regcAddr(regcAddr_ex),.regcWr(regcWr_ex),.memAddr_i(memAddr_ex),.memData(memData_ex),.rdData(rdData),.regData(regData_mem),.regAddr(regAddr_mem),.regWr(regWr_mem),.memAddr(memAddr),.wtData(wtData),.memWr(memWr),.memCe(memCe));DataMem datamem0(.clk(clk),.ce(memCe),.we(memWr),.wtData(wtData),.memAddr(memAddr),.rdData(rdData));RegFile regfile0(.clk(clk),.rst(rst),.we(regWr_mem),.wAddr(regAddr_mem),.wData(regData_mem),.regaRd(regaRd),.regbRd(regbRd),.regaAddr(regaAddr),.regbAddr(regbAddr),.regaData(regaData_regFile),.regbData(regbData_regFile));
endmodule

⑩SoC.v

module SoC(input wire clk,input wire rst
);wire [31:0] instAddr;wire [31:0] instruction;wire romCe;    MIPS mips0(.clk(clk),.rst(rst),.instruction(instruction),.instAddr(instAddr),.romCe(romCe));    InstMem instrom0(.ce(romCe),.addr(instAddr),.data(instruction));
endmodule

11. soc_tb.v

`include "define.v"
module soc_tb;reg clk;reg rst;initialbeginclk = 0;rst = `RstEnable;#100rst = `RstDisable;#10000 $stop;      //run to 10000,simulate stop(Zan ting)       endalways #10 clk = ~ clk;SoC soc0(.clk(clk), .rst(rst));
endmodule

4.仿真图

RegFile里的数据:

            reg32[4] = 32'h00000010; //swreg32[9] = 32'h000000FF; //sw   reg32[16] = 32'h00000004; //lw

DataMem里的数据:

            data [1] = 32'h0000001A; //lw

我的lw指令和sw指令:
       lw:8E1F0001,其二进制为100011 10000 11111 0000 0000 0000 0001。
       sw:AC890000,其二进制为101011 00100 01001 0000000000000000。
       lw指令将数存地址为32’h00000004(reg32[16])中的数据32’h0000001A(data[1])写入到RegFile中地址为5’b11111的寄存器中(即r31寄存器)。

sw指令将RegFile中的数据32’h000000FF(reg32[9])写到数存的data[4]中,之所以是data[4],是因为RegFile的reg32[4]中的数据是32’h00000010,即写入到数存的第16个字节中,而data是宽度为32位的寄存器,一个字节8位,data的每位都是4个字节,数存的第16个字节刚好是data的第4位,即data[4]。仿真图如下:

       因为读出是组合逻辑,任意时间都能看到数据,写入是时序逻辑只有时钟上升沿才能写入到寄存器,所以数存中的数据32’h0000001a在lw指令的下一周期才被写入RegFile的31号寄存器reg32[31]。和lw一样,需要在sw的下一个周期才能从RegFile读出写入的数据32’b000000FF,写入的地址就是data[4]。

MIPS单周期CPU设计——lw和sw指令的设计相关推荐

  1. MIPS单周期CPU设计(24条指令)

    MIPS单周期可执行24条指令CPU 实验要求 本实训项目帮助学生构建支持 24 条指令的 MIPS 单周期 CPU ,最终实现的处理器能运行 benchmark 测试程序.另外希望学有余力的同学能为 ...

  2. 计算机公共基础知识实验报告,MIPS单周期CPU实验报告总结.doc

    <计算机组成原理实验> 实验报告 (实验二) 学 院 名 称 : 专业(班级) : 学 生 姓 名 : 学号 : 时间:2017年11月25日 成 绩 : 实 验 二 : 单周期 CPU设 ...

  3. (Verilog)单周期CPU设计

    (Verilog)单周期CPU设计 首先是基础资料部分(借用学校资料): 一.实验内容 设计一个单周期CPU,该CPU至少能实现以下指令功能操作.需设计的指令与格式如下: ==> 算术运算指令 ...

  4. 计算机组成原理实验单周期处理,计算机组成原理实验实验报告-单周期cpu设计...

    计算机组成原理实验实验报告-单周期cpu设计 (16页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 19.90 积分 计算机组成原理实验计算机组成原理实验 ...

  5. 合肥工业大学宣城校区计算机组成原理实验 单周期 CPU 设计与实现

    本实验使用的是Verilog,离谱的是CSDN居然找不到Verilog的代码块,只能使用c语言的代码块了. 一.实验目的: 通过设计并实现支持 10 条指令的CPU,进一步理解和掌握CPU 设计的基本 ...

  6. 【Computer Organization笔记10】单周期CPU设计:基于7条MIPS指令的数据通路

    本次笔记内容: P19 计算机组成原理(19) P20 计算机组成原理(20) 本节课对应幻灯片: 组成原理24 singlecycle.pptx 基于上节课的7条MIPS指令的数据通路,分别针对7条 ...

  7. 单周期CPU设计【Verilog】

    第一章 单周期CPU的设计原理 1.1 单周期CPU概述 1.2 CPU工作原理 第二章 单周期CPU的设计内容 2.1 指令系统的设计 2.1.1 概述 2.1.2 运算类指令的设计 2.1.3 传 ...

  8. 【中山大学计算机组成原理实验】单周期CPU设计与实现

    实验一 : 单周期CPU设计与实现 一. 实验目的 (1) 掌握单周期CPU数据通路图的构成.原理及其设计方法: (2) 掌握单周期CPU的实现方法,代码实现方法: (3) 认识和掌握指令与CPU的关 ...

  9. 单周期CPU设计与实现原理分析

    文章目录 单周期CPU设计与实现原理分析 一.单周期CPU的设计思路 二.单周期CPU的模块实现 ① Instruction Memory指令存储器的设计 ② ALU算术逻辑单元的设计 ③ PC程序计 ...

  10. 31条指令单周期cpu设计(Verilog)-(二)总体设计

    目录 31条指令单周期cpu设计(Verilog)-(一)相关软件 31条指令单周期cpu设计(Verilog)-(二)总体设计 31条指令单周期cpu设计(Verilog)-(三)指令分析      ...

最新文章

  1. mysql导入导出.sql数据
  2. 华硕笔记本,宽带连上,可以上网, 但收到不无线
  3. Ubuntu 16.04使用timedatectl进行管理时间(UTC/CST)(服务器/桌面)
  4. “凡尔赛”式晒校园生活?移动云 9.9 风暴手把手教你!
  5. android 信鸽 自动重启,Android简单集成信鸽推送
  6. exxi6.7如何传文件到win7_Win7文件误删如何恢复?这三种方法请收好
  7. python接球游戏
  8. boot入门思想 spring_SpringBoot基础入门
  9. android遍历文件夹里的文件,Android 遍历文件夹中所有文件
  10. UEstudio 注册机使用教程
  11. Altium Designer快捷键,布线技巧
  12. 搜索计算机硬盘的索引恢复,如何修复Windows 10搜索索引 | MOS86
  13. MATLAB与信号处理课程手册
  14. 走,去出海,一起“Copy to World” | 36氪出海行业报告
  15. java集成easyExcel动态生成表头并在浏览器下载excel
  16. 联盛德 HLK-W806 (三): 免按键自动下载和复位
  17. wordpress模板WP主题安装失败的解决办法
  18. AE 动画的分层与组合
  19. 什么原因导致了儿童自闭症?跟父母养育有关吗?
  20. python时间戳是什么意思_python时间戳是什么

热门文章

  1. sim800a指令_SIM900A 各功能指令 详细版
  2. pandas求协方差、相关系数、显著性检验
  3. 微信 8.0 「裂开」「炸弹」的特效代码
  4. linux glibc升级
  5. 好用的网络拓扑绘制软件亿图图示安装以及使用
  6. 100套计算机毕设源码+论文 免费分享 【2020最新版】
  7. C语言图形库函数easyx下载
  8. 单个圆孔菲涅耳衍射的matlab模拟,矩孔和圆孔菲涅耳衍射的计算机模拟
  9. 基于ssm的酒店管理系统
  10. AdapterView详解