计组实验-CPU设计-指令添加
计组实验-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.主要模块:
alu.v:计算模块,负责各个指令在 EX 段的算术操作。
crtl.v:译码模块,将 MIPS 汇编语言程序形成的机械指令进行译码。
crtl_encode.v:编码模块,存放各种编码。
dm.v :存储器操作模块,负责进行MEM操作。
EXT.v:数字扩展模块,对一些立即数进行符号拓展或零拓展。
im.v :指令储存模块,进行取指操作。
mux.v:选择器模块,根据指令的不同,来进行各阶段相应数据的选择。
NPC.v:指令地址计算模块,负责计算下一条指令的地址。
PC.v:程序计数器,负责生成下一条指令的地址。
sscomp_tb.v:顶层实体文件
sccpu.v:主模块,负责连接各个模块进行统一操作
sccomp.v:顶层模块,连接CPU和存储器。
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设计-指令添加相关推荐
- 北航2021届计组 -- 流水线CPU
北航2021届计组流水线CPU设计 文章目录 北航2021届计组流水线CPU设计 一.设计想法 1.1 我的CPU的整体架构 1.2 从单周期到流水线 1.2.1 修改原单周期CPU 1.2.2 流水 ...
- 计算机组成实验六MIPS汇编器,杭电计组实验6-MIPS汇编器与模拟器实验.doc
<杭电计组实验6-MIPS汇编器与模拟器实验.doc>由会员分享,提供在线免费全文阅读可下载,此文档格式为doc,更多相关<杭电计组实验6-MIPS汇编器与模拟器实验.doc> ...
- 西电计组实验一 存储器实验
FPGA中LPM_ROM定制与读出实验 一.实验目的 1.掌握FPGA中lpm_ROM的设置,作为只读存储器ROM的工作特性和配置方法: 2.用文本编辑器编辑mif文件配置ROM,学习将程序代 ...
- 超前进位加法器实验报告_北科大第二次计组实验报告超前进位加法器.doc
北科大第二次计组实验报告超前进位加法器 北京科技大学 计算机与通信工程学院 实 验 报 告 实验名称: 超前进位加法器 学生姓名: 专 业: 计算机科学与技术 班 级: 学 号: 指导教师: 实验成绩 ...
- 超前进位加法器实验报告_北科大第二次计组实验报告超前进位加法器
北科大第二次计组实验报告超前进位加法器 北京科技大学 计算机与通信工程学院实 验 报 告实验名称: 超前进位加法器 学生姓名: 专 业: 计算机科学与技术 班 级: 学 号: 指导教师: 实验成绩: ...
- 计算机组成原理实验心得2000字,计组实验报告(共10篇).doc
计组实验报告(共10篇) 计组实验报告(共10篇) 计组实验报告 计算机组成原理实验报告一 一.算术逻辑运算器 1. 实验目的与要求: 目的:① 掌握算术逻辑运算器单元ALU(74LS181)的工作原 ...
- 杭电计算机组成原理实验九R-I,杭电计组实验9-实现R-I型指令的CPU设计实验.doc
*** *** 实验报告 2018 年 6 月 1 日 成绩: 姓名 阳光男 学号班级专业 计算机科学与技术 课程名称 <计算机组成原理与系统结构 试验> 任课老 师 张翔老师 指导老 师 ...
- [华中科技计组实验]logisim完成单周期5级流水MIPS CPU
自己动手画cpu系列 建设中ing 仅供参考! 在这首推华中科技大学计算机组成原理实验课mooc连接 初衷:在mooc上看见了本课觉得超赞,本人已完成了课中所有的实验,在做实验的过程中有时候实验会没有 ...
- 【计组实验】P1 logisim完成单周期处理器开发 MIPS指令集
参考教材:<计算机组成与设计 硬件/软件接口 原书第五版>第二章 第四章 ↑ 这本书写的特别好,零基础也可以看 实验报告 链接: https://pan.baidu.com/s/19YQA ...
- 合肥工业大学计组实验四
实验目的 通过设计并实现支持一条指令的CPU,理解和掌握CPU设计的基本原理和过程. 实验内容 设计和实现一个支持加法指令的单周期CPU.要求该加法指令(表示为add r1,r2,r3)格式约定如下: ...
最新文章
- mysql删除有空格字符名称的触发器
- 数组中两个字符串的最小距离
- 导出目录结构_Selenium Webdriver 3.X源码分析之核心目录结构
- python3之MongoDB
- javascript实现面向对象的继承
- 如何分析堆外内存使用情况_堆上与堆外的内存使用情况
- 两种类型的Spark RDD task解析以及iterator解析 -- (视频笔记)
- leetcode214. 最短回文串
- Linux安装后初始优化步骤(仅适用于CentOS、RedHat)
- 实用常识 | HTML嵌入处理MARKDOWN合并单元格
- 如何判断链表有环、如何判断两个链表相交
- MyEclipse6.5注册码(转)
- 腾讯无人车开进硅谷!建团队、招人才,国内放出商务岗位
- win7系统iis服务器删除,Win7系统如何卸载iis 删除win7中iis的方法
- 北京今日限行 API数据接口
- wireshark抓包分析POP3协议
- Linux系统下启动DB2以及一些常用命令
- Zabbix5.0监控CenterOS(RPM版)
- python 跳过_python怎么跳过异常继续执行
- HDU_6078 Wavel Sequence
热门文章
- 无穷级数求和7个公式_高中数学:教你等差数列求和公式,有这7种方法
- 计算快递费系统(java版)
- android中截屏快捷键是什么,安卓手机怎么截屏?安卓手机截图快捷键功能图文详解...
- 【Proteus仿真】L297驱动步进电机
- 原生拨号盘设置电信卡呼叫转移概率失败
- Python中取整函数汇总
- openwrt路由器samba拒绝访问
- SPSS中的数据分析—描述性统计分析【2】
- centos6.5安装谷歌浏览器+谷歌浏览器flash插件安装+谷歌浏览器pdf阅读器安装
- 把树莓派用于YAAW离线下载的Mass Storage U盘用虚拟目录建到Vsftpd的子目录里去