计组实验-CPU设计-指令添加

一、 单周期 CPU

概述

1.单周期 CPU

CPU每个时钟周期跑一个指令

2.支持的指令:

(最后一行为按照实验要求自行添加的)

  • add/sub/and/or/slt/sltu/addu/subu

  • addi/ori/lw/sw/beq

  • j/jal

  • sll/nor/lui/slti/bne/andi/srl/sllv/srlv/jr/jalr

3.主要模块:

  1. alu.v:计算模块,负责各个指令在 EX 段的算术操作。

  2. crtl.v:译码模块,将 MIPS 汇编语言程序形成的机械指令进行译码。

  3. crtl_encode.v:编码模块,存放各种编码。

  4. dm.v :存储器操作模块,负责进行MEM操作。

  5. EXT.v:数字扩展模块,对一些立即数进行符号拓展或零拓展。

  6. im.v :指令储存模块,进行取指操作。

  7. mux.v:选择器模块,根据指令的不同,来进行各阶段相应数据的选择。

  8. NPC.v:指令地址计算模块,负责计算下一条指令的地址。

  9. PC.v:程序计数器,负责生成下一条指令的地址。

  10. sscomp_tb.v:顶层实体文件

  11. sccpu.v:主模块,负责连接各个模块进行统一操作

  12. sccomp.v:顶层模块,连接CPU和存储器。

  13. RF.v:寄存器堆,负责寄存器的写入和输出。

重要部件

PC(程序计数器)

根据当前具体的指令,决定下一条指令的地址。

接口

信号名 方向 描述
Clk Input 时钟信号
Rst Input 复位信号
NPC Input 计算下一条指令地址的模块
PC Output 输出

RF(寄存器文件)

功能描述 读出和写入寄存器

读出:不需要控制

写入:RFWr 为 1

接口:

信号名 方向 描述
Clk Input 时钟信号
Rst Input 复位信号
RFWr Input 写回信号
A1[4:0] Input 寄存器Rs的地址寻址信号
A2[4:0] Input 寄存器Rt的地址寻址信号
A3[4:0] Input 寄存器Rd的地址寻址信号
WD[32:0] Input 写回的数据
Reg_sel Input 写入信号选择(Rd or Shamt)
RD1[31:0] Output 寄存器输出
RD2[31:0] Output 寄存器输出
Reg_data[31:0] Output 根据Reg_sel选择的输出信号
  module RF(   input         clk, input         rst,input         RFWr, input  [4:0]  A1, A2, A3, input  [31:0] WD, output [31:0] RD1, RD2,input  [4:0]  reg_sel,output [31:0] reg_data);reg [31:0] rf[31:0];if (RFWr) beginrf[A3] <= WD;endassign RD1 = (A1 != 0) ? rf[A1] : 0;assign RD2 = (A2 != 0) ? rf[A2] : 0;assign reg_data = (reg_sel != 0) ? rf[reg_sel] : 0; endmodule

ALU

功能描述:执行 CPU 的各种计算

ALUOp[2:0]:决定执行何种计算

其中 A、B 取决于一些选择信号

   mux2 #(32) U_MUX_ALU_A(.d0(RD1),.d1(shamt),.s(AregSel),.y(A));// mux for ALU Bmux2 #(32) U_MUX_ALU_B (.d0(writedata), .d1(Imm32), .s(ALUSrc), .y(B));   // instantiation of alualu U_ALU ( .A(A), .B(B), .ALUOp(ALUOp), .C(aluout), .Zero(Zero));

MUX

 // mux for register data to writemux4 #(5) U_MUX4_GPR_A3 (.d0(rd), .d1(rt), .d2(5'b11111), .d3(5'b0), .s(GPRSel), .y(A3));//选择要写入数据的寄存器,A3在RF中用作RFWr,即写入寄存器的序号// mux for register address to writemux4 #(32) U_MUX4_GPR_WD (.d0(aluout), .d1(readdata), .d2(PC + 4), .d3(32'b0), .s(WDSel), .y(WD));// 这里在选择把哪个数据写回到寄存器中,可能是ALU计算的结果(移位),可能是从存储器中读出的数据(lw),可能是暂存的下一条指令地址(j型),可能什么也没有(不写入)mux2 #(32) U_MUX_ALU_A(.d0(RD1),.d1(shamt),.s(AregSel),.y(A));// 在ALU内部起作用,决定是用rd来逻辑移位,还是用shamt来逻辑移位// mux for ALU Bmux2 #(32) U_MUX_ALU_B (.d0(writedata), .d1(Imm32), .s(ALUSrc), .y(B));   // 寄存器读出的第一个数据肯定会被送进ALU,这里是在选择是把寄存器读出的第二个数据放进ALU,还是放立即数,之所以叫writedata,是因为这个数据同时也会被送到MEM中

添加指令

bne 不相等跳转分支指令 I 型

bne rs, rt, label1 形式为 6 5 5 16(offeset)

func[5:0]:000101

1.crtl.v 模块添加相应wire 信号

2.ALU 模块中添加运算

ALIOP 0010 与 sub 相同,本质上就是相减判断是否为0

`ALU_SUB:  C = A - B;                      // SUB

3.由于 bne 指令要跳转,所以要修改 npc操作码

assign NPCOp[0] = (i_beq & Zero)|(i_bne &~ Zero) | i_jr | i_jalr;

sll & srl & sllv & srlv 移位指令 R型

sll 逻辑左移 R型 funct 000000 sll rd, rt, shamt rd =rt << shamt 655556 形式

srl 逻辑右移 R型 funct 000010 srl rd, rt, shamt rd =rt >> shamt 655556 形式

sllv 逻辑左移变量 R型 funct 000100 srllv rd, rt, rs rd =rt << rs 655556

srlv 逻辑右移变量 R型 funct 000110 srlv rd, rt, rs rd =rt >> rs 65556

1.crtl.v 中需要添加多路选择器,判断选择 rs 还是 shamt

  assign AregSel    = i_sll | i_srl;

2.sccpu.v 模块绑定信号 AregSel,shamt,Alu_A

对 shamt 信号格式进行定义, 前 27 位为 0,取 6 到 10 位指令

assign shamt={27'b0,instr[10:6]};

3.补充多路选择器 mux2

4.alu.v 模块输入端口进行修改

sllv 和 srlv 在原来的基础上只需要修改译码和操作数

slti 小于立即数则置位 I 型 001010

slti rt, rs, imm 65516

1.指令译码,Crtl.v 添加对应信号

2.寄存器写信号

3.Aluop 操作码与 slt 一致

nor 异或 R型 funct100111

nor rd, rs, rt 0 rs rt rd 0 0x27(6 5 5 5 5 6)

rd = ~(rs|rt)

1.ALU 模块进行扩充

ALU_NOR:  C = ~(A | B);

2.Crtl_encode 添加相应的操作码

3.Crtl.v 添加译码

4.Aluop 操作控制码修改

assign ALUOp[3]=  i_sll | i_sllv | i_srl | i_srlv | i_nor | i_lui ;

lui 立即数高 16 位放进一个寄存器 I 型 funct001111

lui rt, imm RT={imm,16’b0} 6 5 5 16

需要 16 位立即数符号扩展,再左移 16 位

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5HCU4wc9-1647494648255)(https://raw.githubusercontent.com/Liqu1d-G/Cloud_img/master/image-20211208182354123.png)]

1.Ctrl.v 添加指令译码信号

2.寄存器写信号

3.写回 rt 寄存器

4.零扩展

5.Alu_op 操作码修改

6.ALU 运算取数据信号修改,取一个立即数

andi 立即数与 I 型 op:001100

andi rt rs imm (6 5 5 16)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BW5lxR8W-1647494648255)(https://raw.githubusercontent.com/Liqu1d-G/Cloud_img/master/image-20211208184647663.png)]

1.crtl.v 添加译码

2.零扩展信号

3.添加寄存器写信号

4.Alu 需要进行选择,添加 Alu_op

5.Alu 端口需要进行选择,修改 AluSrc

output       ALUSrc;   // ALU source for A
assign ALUSrc     = i_lw | i_sw | i_addi | i_ori | i_slti | i_lui | i_andi;
// ALU B is from instruction immediate

jr 寄存器跳转 R型 001000

jr rs(无条件跳转到由寄存器 rs 指定的指令) 0 rs 0 8(6 5 15 6)

pc=GPR[rs]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WYYiM4yH-1647494648255)(https://raw.githubusercontent.com/Liqu1d-G/Cloud_img/master/image-20211208184730702.png)]

1.Crtl.v 添加指令译码信号

2.NPCOp 修改

assign NPCOp[1] = i_j | i_jal | i_jr | i_jalr;

3.Crtl_encode 修改

4.NPC 模块修改

`NPC_JR:     NPC = PCJR;

jalr 跳转并链接到寄存器 R型 001001

jalr rs rd 0 rs 0 rd 0 9(6 5 5 5 5 6)

pc=GPR[rs]; GPR[rd]=pc+4

1.Crtl.v 添加指令译码信号

2.添加寄存器写信号

3.选择需要写的来自 PC 数据__

4.对 NPC 选择

二、 多周期 CPU

在单周期基础上的修改

1、 在单周期 CPU 模块设计上进行改进,采用类似的思路。各个模块之间相互连接,实现将一条指令的五个阶段顺序执行的过程。

2、 模块设计以功能部件为基础进行构造,进而构造顶层实体

3、 模块组成: alu.v,crtl.v,crtl_encode_def.v,dm.v,EXT.v,flopenr.v,flopr.v,mc comp.v,mmcpu.v,mux.v,RF.v

4、 多周期 CPU 特征模块介绍

Crtl部分的状态转移

与单周期控制模块不同,多周期 cpu 控制模块增加了指令的执行的状态,对于指令的五个阶段分别进行相应的操作。根据指令的特征选择指令具有的阶段。

对于状态转移的控制

   reg [2:0] nextstate;reg [2:0] state;always @(posedge clk or posedge rst) beginif ( rst )state <= sif;elsestate <= nextstate;end // end alwaysparameter  [2:0] sif  = 3'b000,                // IF  statesid  = 3'b001,                // ID  statesexe = 3'b010,                // EXE statesmem = 3'b011,                // MEM stateswb  = 3'b100;                // WB  state/*************************************************//******         Control Signal              ******/always @(*) beginRegWrite = 0;MemWrite = 0;PCWrite  = 0;IRWrite  = 0;EXTOp    = 1;           // signed extensionALUSrcA  = 1;           // 1 - ReadData1ALUSrcB  = 2'b00;       // 0 - ReadData2ALUOp    = 4'b0001;      // ALU_ADD       3'b001GPRSel   = 2'b00;       // GPRSel_RD     2'b00WDSel    = 2'b00;       // WDSel_FromALU 2'b00PCSource = 3'b000;       // PC + 4 (ALU)IorD     = 0;           // 0-memory access for instructionAregSel  = 0;case (state)sif: beginPCWrite = 1;IRWrite = 1;ALUSrcA = 0;      // PCALUSrcB = 2'b01;  // 4nextstate = sid;endsid: beginif (i_j) beginPCSource = 3'b010; // JUMP addressPCWrite = 1;nextstate = sif;end else if (i_jal) beginPCSource = 3'b010; // JUMP addressPCWrite = 1;RegWrite = 1;WDSel = 2'b10;    // WDSel_FromPC  2'b10 GPRSel = 2'b10;   // GPRSel_31     2'b10nextstate = sif;end else if (i_jr) beginPCSource = 3'b100;PCWrite = 1;nextstate = sif;end else if (i_jalr) beginPCSource = 3'b100;PCWrite = 1;RegWrite = 1;WDSel = 2'b10;    // WDSel_FromPC  2'b10 GPRSel = 2'b10;   // GPRSel_31     2'b10nextstate = sif;end else beginALUSrcA = 0;       // PCALUSrcB = 2'b11;   // branch offsetnextstate = sexe;endend// ALU_NOP   4'b0000// ALU_ADD   4'b0001// ALU_SUB   4'b0010// ALU_AND   4'b0011// ALU_OR    4'b0100// ALU_SLT   4'b0101// ALU_SLTU  4'b0110// ALU_SLL   4'b0111     // ALU_SRL   4'b1000// ALU_NOR   4'b1001// ALU_LUI   4'b1010sexe: beginALUOp[0] = i_add | i_lw | i_sw | i_addi | i_and | i_slt | i_addu | i_sll | i_sllv | i_slti | i_nor | i_andi;ALUOp[1] = i_sub | i_beq | i_and | i_sltu | i_subu | i_bne | i_sll | i_sllv | i_lui | i_andi;ALUOp[2] = i_or | i_ori | i_slt | i_sltu | i_sll | i_sllv | i_slti;ALUOp[3] = i_srl | i_srlv | i_nor | i_lui;if (i_beq) beginPCSource = 3'b001; // ALUout, branch addressPCWrite = i_beq & Zero;nextstate = sif;end else if(i_bne) beginPCSource = 3'b001;PCWrite = i_bne & ~Zero;nextstate =sif;end else if (i_lw || i_sw) beginALUSrcB = 2'b10; // select offsetnextstate = smem;end else beginif (i_addi || i_ori || i_slti || i_lui || i_andi)ALUSrcB = 2'b10; // select immediateif (i_ori || i_andi)EXTOp = 0; // zero extensionif (i_sll | i_srl)AregSel = 1;nextstate = swb;endendsmem: beginIorD = 1;  // memory address  = ALUoutif (i_lw) beginnextstate = swb;end else begin  // i_swMemWrite = 1;nextstate = sif;endendswb: beginif (i_lw)WDSel = 2'b01;     // WDSel_FromMEM 2'b01if (i_lw | i_addi | i_ori | i_slti | i_lui | i_andi) beginGPRSel = 2'b01;    // GPRSel_RT     2'b01endRegWrite = 1;nextstate = sif;enddefault: beginnextstate = sif;endendcaseend // end always

计组实验-CPU设计-指令添加相关推荐

  1. 北航2021届计组 -- 流水线CPU

    北航2021届计组流水线CPU设计 文章目录 北航2021届计组流水线CPU设计 一.设计想法 1.1 我的CPU的整体架构 1.2 从单周期到流水线 1.2.1 修改原单周期CPU 1.2.2 流水 ...

  2. 计算机组成实验六MIPS汇编器,杭电计组实验6-MIPS汇编器与模拟器实验.doc

    <杭电计组实验6-MIPS汇编器与模拟器实验.doc>由会员分享,提供在线免费全文阅读可下载,此文档格式为doc,更多相关<杭电计组实验6-MIPS汇编器与模拟器实验.doc> ...

  3. 西电计组实验一 存储器实验

    FPGA中LPM_ROM定制与读出实验 一.实验目的   1.掌握FPGA中lpm_ROM的设置,作为只读存储器ROM的工作特性和配置方法:   2.用文本编辑器编辑mif文件配置ROM,学习将程序代 ...

  4. 超前进位加法器实验报告_北科大第二次计组实验报告超前进位加法器.doc

    北科大第二次计组实验报告超前进位加法器 北京科技大学 计算机与通信工程学院 实 验 报 告 实验名称: 超前进位加法器 学生姓名: 专 业: 计算机科学与技术 班 级: 学 号: 指导教师: 实验成绩 ...

  5. 超前进位加法器实验报告_北科大第二次计组实验报告超前进位加法器

    北科大第二次计组实验报告超前进位加法器 北京科技大学 计算机与通信工程学院实 验 报 告实验名称: 超前进位加法器 学生姓名: 专 业: 计算机科学与技术 班 级: 学 号: 指导教师: 实验成绩: ...

  6. 计算机组成原理实验心得2000字,计组实验报告(共10篇).doc

    计组实验报告(共10篇) 计组实验报告(共10篇) 计组实验报告 计算机组成原理实验报告一 一.算术逻辑运算器 1. 实验目的与要求: 目的:① 掌握算术逻辑运算器单元ALU(74LS181)的工作原 ...

  7. 杭电计算机组成原理实验九R-I,杭电计组实验9-实现R-I型指令的CPU设计实验.doc

    *** *** 实验报告 2018 年 6 月 1 日 成绩: 姓名 阳光男 学号班级专业 计算机科学与技术 课程名称 <计算机组成原理与系统结构 试验> 任课老 师 张翔老师 指导老 师 ...

  8. [华中科技计组实验]logisim完成单周期5级流水MIPS CPU

    自己动手画cpu系列 建设中ing 仅供参考! 在这首推华中科技大学计算机组成原理实验课mooc连接 初衷:在mooc上看见了本课觉得超赞,本人已完成了课中所有的实验,在做实验的过程中有时候实验会没有 ...

  9. 【计组实验】P1 logisim完成单周期处理器开发 MIPS指令集

    参考教材:<计算机组成与设计 硬件/软件接口 原书第五版>第二章 第四章 ↑ 这本书写的特别好,零基础也可以看 实验报告 链接: https://pan.baidu.com/s/19YQA ...

  10. 合肥工业大学计组实验四

    实验目的 通过设计并实现支持一条指令的CPU,理解和掌握CPU设计的基本原理和过程. 实验内容 设计和实现一个支持加法指令的单周期CPU.要求该加法指令(表示为add r1,r2,r3)格式约定如下: ...

最新文章

  1. mysql删除有空格字符名称的触发器
  2. 数组中两个字符串的最小距离
  3. 导出目录结构_Selenium Webdriver 3.X源码分析之核心目录结构
  4. python3之MongoDB
  5. javascript实现面向对象的继承
  6. 如何分析堆外内存使用情况_堆上与堆外的内存使用情况
  7. 两种类型的Spark RDD task解析以及iterator解析 -- (视频笔记)
  8. leetcode214. 最短回文串
  9. Linux安装后初始优化步骤(仅适用于CentOS、RedHat)
  10. 实用常识 | HTML嵌入处理MARKDOWN合并单元格
  11. 如何判断链表有环、如何判断两个链表相交
  12. MyEclipse6.5注册码(转)
  13. 腾讯无人车开进硅谷!建团队、招人才,国内放出商务岗位
  14. win7系统iis服务器删除,Win7系统如何卸载iis 删除win7中iis的方法
  15. 北京今日限行 API数据接口
  16. wireshark抓包分析POP3协议
  17. Linux系统下启动DB2以及一些常用命令
  18. Zabbix5.0监控CenterOS(RPM版)
  19. python 跳过_python怎么跳过异常继续执行
  20. HDU_6078 Wavel Sequence

热门文章

  1. 无穷级数求和7个公式_高中数学:教你等差数列求和公式,有这7种方法
  2. 计算快递费系统(java版)
  3. android中截屏快捷键是什么,安卓手机怎么截屏?安卓手机截图快捷键功能图文详解...
  4. 【Proteus仿真】L297驱动步进电机
  5. 原生拨号盘设置电信卡呼叫转移概率失败
  6. Python中取整函数汇总
  7. openwrt路由器samba拒绝访问
  8. SPSS中的数据分析—描述性统计分析【2】
  9. centos6.5安装谷歌浏览器+谷歌浏览器flash插件安装+谷歌浏览器pdf阅读器安装
  10. 把树莓派用于YAAW离线下载的Mass Storage U盘用虚拟目录建到Vsftpd的子目录里去