计算机组成原理 实验五 单周期CPU设计与实现——十条指令CPU

2023-11-04 22:59

本文主要是介绍计算机组成原理 实验五 单周期CPU设计与实现——十条指令CPU,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

实验二三(CPU部件实现之ALU、寄存器堆、PC、RAM)

系统硬件综合设计-多周期CPU的设计与实现

一、实验目的

通过设计并实现支持 10 条指令的 CPU,进一步理解和掌握 CPU设计的基本原理和过程。

二、实验内容

设计和实现一个支持如下十条指令的单周期CPU。

非访存指令
 清除累加器指令CLA
 累加器取反指令COM
 算术右移一位指令SHR:将累加器ACC中的数右移一位,结果放回ACC
 循环左移一位指令CSL:对累加器中的数据进行操作
 停机指令STP

访存指令
 加法指令ADD X:[X] + [ACC] –〉ACC,X为存储器地址,直接寻址
 存数指令STA X,采用直接寻址方式
 取数指令LDA X,采用直接寻址

转移类指令
 无条件转移指令JMP imm:signExt(imm) -> PC
 有条件转移(负则转)指令BAN X: ACC最高位为1则(PC)+ X -> PC,否则不变

三、实验原理

单周期 CPU 是指所有指令均在一个时钟周期内完成的 CPU。CPU 由数据通路及其控制部件两部分构成,因而要完成一个支持若干条指令 CPU 的设计, 需要依次完成以下两件事:

  1. 根据指令功能和格式设计 CPU 的数据通路;

  2. 根据指令功能和数据通路设计控制部件。
    在这里插入图片描述

四、实验步骤

1. CPU各模块Verilog实现

PC 模块

PC 模块功能描述

输入时钟信号 clk、重置信号 rst
输出指令地址 pc(8 位)
功能每个时钟上升沿 PC 的值自动加 1,并输出

源码:

module PC(
input stop,
input clk,
input rst,
input pcJMP,
input banEBL,
input ban,
input wire [7:0] data_in,
output reg [7:0] PC
);
always @(posedge clk )begin
if(rst==1) begin PC = 0;end
if(stop!=1)begin
PC = PC +1;
if(banEBL == 1) begin
if(ban == 1) begin
PC = PC + data_in;
end
end
if(pcJMP == 1 ) begin PC = data_in;end
end
end
endmodule

指令存储器模块

指令存储器模块功能描述

输入8位指令地址Addr
输出16位指令Ins
功能存放待执行的指令(初始化),并根据地址输出指令
 源码:module ins(output reg[15:0] outins,input wire[7:0] adder,output reg[5:0] r1,output reg[7:0] r2,input wire clk);reg [15:0] storage [0:255];reg [15:0] temp;initial beginstorage [8'h00] = 16'h0000; //startstorage [8'h01] = 16'h0100; //clastorage [8'h02] = 16'h0200; //comstorage [8'h03] = 16'h0300; //shrstorage [8'h04] = 16'h0400; //cslstorage [8'h05] = 16'h0500; //add xstorage [8'h06] = 16'h0600; //sta xstorage [8'h07] = 16'h0701; //lda xstorage [8'h08] = 16'h0803; //jmpstorage [8'h09] = 16'h0902; //banstorage [8'h0a] = 16'hffff; //stopendalways @(adder)begin temp = storage[adder];r1 = {storage[adder][5:0]};r2 = {storage[adder][7:0]};outins = temp;endendmodule

寄存器堆

寄存器堆模块功能描述

输入时钟信号clk、读写控制线wr_en、读寄存器编号read_reg1和 read_reg2、写寄存器编号write_reg、写入数据write_data
输出对应两个读寄存器编号的寄存器值reg1和reg2
功能根据读寄存器编号给出对应寄存器的值;在写允许情况下,把写入端的数据在clk下降沿写到写寄存器编号对应的寄存器

源码:

 module register(RA, RB, RW, busW, clk, WE, busA, busB, RD);
input wire [2:0] RA, RB, RW;input wire [15:0] busW;input clk, WE, RD;output reg [15:0] busA, busB;reg [15:0] Reg[7:0];always @(negedge clk)begin if(WE == 1)beginReg[RW] = busW;busA = Reg[RA];busB = Reg[RB];end else if(RD == 1)begin busA = Reg[RA];busB = Reg[RB];endendendmodule

ALU

ALU 模块功能描述

输入操作数in1和in2、操作选择信号alu_op
输出ALU运算结果Z
功能根据操作选择信号计算in1和in2的运算结果Z

源码:

module alu(outalu, a, b, select);
output [15:0] outalu;
input [15:0]a, b;
input [2:0]select;
reg [15:0] outalu;
always @(\*)
case(select)
3'b000: outalu = a + b;
3'b001: outalu = a - b;
3'b010: outalu = a&b;
3'b011: outalu = a\|b;
3'b100: outalu = a\<\<b;
3'b101: outalu = a\>\>b;
3'b110: outalu = a\*b;
3'b111: outalu = a%b;
default: outalu = 16'b1111111111111111;
endcase
endmodule

CU

控制单元模块功能描述

输入指令(操作码)
输出寄存器堆的读写控制线wr_en、ALU的操作选择信号alu_op
功能根据当前指令功能对wr_en和alu_op赋值

源码:

module cu(
input wire[7:0] accout,
input wire [15:0] outins,
output reg stop,
output reg [1:0]accop,
output reg ena,
output reg [2:0] aluop,
output reg enable,
output reg pcJMP,banEBL,ban
);
always @\* begin
case(outins[15:8])
8'h00:
begin
stop = 0;
end
8'hff:
begin
stop = 1;
end
8'h01:
begin
ena = 1;
accop = 2'b00;
banEBL = 0;
pcJMP=0;
end
8'h02:
begin
ena = 1;
accop = 2'b01;
banEBL = 0;
pcJMP=0;
end
8'h03:
begin
ena = 1;
accop = 2'b10;
banEBL = 0;
pcJMP=0;
end
8'h04:
begin
ena = 1;
accop = 2'b11;
banEBL = 0;
pcJMP=0;
end
8'h05:
begin
ena = 1;
enable = 0;
aluop = 3'b000;
banEBL = 0;
pcJMP=0;
end
8'h06:
begin
ena = 1;
enable = 1;
banEBL = 0;
pcJMP=0;
end
8'h07:
begin
ena = 1;
enable = 0;
banEBL = 0;
pcJMP = 0;
end
8'h08:
begin
pcJMP = 1 ;
end
8'h09:
begin
banEBL = 1 ;
if(accout[7] == 1)
begin
ban = 1 ;
end
end
endcase
end
endmodule

2. CPU顶层文件封装实现

通过将以上定义的模块进行连接、封装就得到了目标
CPU,该CPU的输入为系统时钟信号clk和重置信号 reset。

源码:

module cpu(
input clk,
input rst,
output wire [7:0] pc
);wire [2:0] RA, RB, RW;
wire [15:0] busW;
wire WE, RD;
wire [15:0] busA, busB;
wire [15:0] accout;
wire [2:0] aluop;
wire stop, pcJMP, banEBL, ban, ena, enable;
wire [15:0] outins;
wire [1:0] accop;
wire [5:0] r1;
wire [7:0] r2;
wire [15:0] dataout, out1, out2;
alu malu(.outalu(out1),.a(accout),.b(out2),.select(aluop));pc
mpc(.stop(stop),.clk(clk),.rst(rst),.pcJMP(pcJMP),.banEBL(banEBL),.ban(ban),.data_in(r2),.pc(pc));ins mins(.outins(outins),.adder(pc),.r1(r1),.r2(r2),.clk(clk));cu
mcu(.accout(accout),.outins(outins),.stop(stop),.accop(accop),.ena(ena),.aluop(aluop),.enable(enable),.pcJMP(pcJMP),.banEBL(banEBL),.ban(ban));acc myacc(.ena(ena),.accop(accop),.accin(out1),.acc(accout));register mregister(RA, RB, RW, busW, clk, WE, busA, busB, RD);Datastorage
mDatastorage(.address(r1),.enable(enable),.clk(clk),.dataout(dataout),.datain(accout));endmodule

3. CPU模拟仿真

为了仿真验证所实现的
CPU,需要定义测试文件并在测试文件中对指令存储器和寄存器堆中的相应寄存器的值进行初始化,并通过仿真波形图查看是否指令得到了正确执行。

源码:

 module MyCPU_tb;parameter CYCLE = 32;reg clk;wire [7:0] PC;reg rst;
cpu MyCPU(clk, rst, PC);initial clk = 0;always \#(CYCLE/2) clk = \~ clk;initial beginclk = 1;rst = 0;(CYCLE\*1) clk = 1;rst = 1;
(CYCLE\*2) rst = 0;
(CYCLE\*3) rst = 0;
(CYCLE\*4) rst = 0;
(CYCLE\*5) rst = 1;
(CYCLE\*6) rst = 0;
(CYCLE\*7) rst = 0;
(CYCLE\*8) rst = 0;(CYCLE\*9) rst = 1;(CYCLE\*9)rst = 0;force MyCPU.r1 = 7'h5;force MyCPU.r2 = 8'h9;(CYCLE\*10)force MyCPU.outins = 16'h0600;force MyCPU.banEBL = 1;(CYCLE\*12)force MyCPU.accout[7] = 1;force MyCPU.r2 = 16'h2;(CYCLE\*13)force MyCPU.outins = 16'h0902;(CYCLE\*14)force MyCPU.outins = 16'hffff;(CYCLE\*20)stop;endendmodule

五、modelSim仿真结果

清除累加器指令CLA

执行指令前,如图5.1所示:

在这里插入图片描述
图5.1

执行指令后,如图5.2所示:

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t9lJ6dVt-1610787453384)(media/92d7ac9edf7775c651fc3e37eef5e4a5.png)]
图5.2

累加器取反指令COM

执行指令前,如图5.3所示:

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rB6Sh2LG-1610787453391)(media/e7af1e7dce6c71101e3f3d732c96f6e0.png)]图5.3

执行指令后,如图5.4所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zXynIFUm-1610787453392)(media/a98398c1e25747b02fa75a1d847e9b5a.png)]
图5.4

算术右移一位指令SHR:将累加器ACC中的数右移一位,结果放回ACC

执行指令前,如图5.5所示:

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eMmLaVKX-1610787453395)(media/80dbd2d5db4070c5aaec9ef846fea9ac.png)]

图5.5

执行指令后,如图5.6所示:

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xezWK3i0-1610787453397)(media/48bb809aa1ac8ce18a494fab0ce26dd6.png)]

图5.6

循环左移一位指令CSL:对累加器中的数据进行操作

执行指令前,如图5.7所示:

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AwA1n8fG-1610787453398)(media/24fa769f95bdfaa04487a1ca1b793d53.png)]
图5.7

执行指令后,如图5.8所示
### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IPfxkHRG-1610787453399)(media/03dfc2f09759be50326ef504a7c1d2d8.png)]
图5.8

停机指令STP

执行指令前后如图5.9所示

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QOViaw3g-1610787453401)(media/fc0b30d1f555eb85c23689619e2c47df.png)]

图5.9

加法指令ADD X:[X] + [ACC] –〉ACC,X为存储器地址,直接寻址

执行指令前后,如图5.10所示:

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-r9fjWOMT-1610787453403)(media/d52943c1a02bdebe3666ce493e6cfe92.png)]
图5.10

存数指令STA X,采用直接寻址方式

执行指令前,如图5.11所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q3btY2Tu-1610787453404)(media/73739c832c1bb67492779f69958795a9.png)]

图5.11

执行指令后,如图5.12所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2nW8kme6-1610787453405)(media/2c5accabe8dd4a73409e876005f3160f.png)]

图5.12

取数指令LDA X,采用直接寻址

指令执行前后如图5.13所示:

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-eTy7UvYi-1610787453407)(media/101a280351ee6fa45cc8396a5813b1e0.png)]

图5.13

无条件转移指令JMP imm:signExt(imm) -> PC

指令执行前后,如图5.14所示:

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7vpaJEMY-1610787453408)(media/f3ce653a6f09b4c16af7a0ff8e914b91.png)]

图5.14

有条件转移(负则转)指令BAN X: ACC最高位为1则(PC)+ X -> PC,否则PC不变

指令执行前后如图5.15所示:

### [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y8ZZOr53-1610787453411)(media/4f354793d0725ed393c53efcd8f4a7e8.png)]

图5.15

六、实验结果分析

清除累加器指令 CLA:执行清除累加器指令 CLA 前,程序计数寄存器ACC为不确定状态,ACC 处于待机状态;执行 CLA 后,0000 被送入ACC 中,CPU可以开始执行程序。如图 5.1 与图 5.2 所示。

累加器取反指令 COM:执行累加器取反指令 COM 前,ACC 的输出accout 为 0000H;执行后COM 后,accout 跳变为 FFFFH,ACC 的内容被成功取反输出。如图 5.3 与图 5.4 所示。

算术右移一位指令 SHR:执行算术右移一位指令 SHR 前,ACC 的输出accout 为FFFFH;执行 SHR 后,accout 跳变为 7FFFH,ACC 的内容被成功右移一位。如图 5.5 与图5.6所示。

循环左移一位指令 CSL:执行循环左移一位指令 CSL 前,ACC 的输出accout 为7FFFH;执行 CLS 后,accout 跳变为 FFFEH,ACC 的内容被成功循环左移一位。如图 5.7与图 5.8 所示。

停机指令STP:执行停机指令STP后,PC停止工作,outins赋值为FFFFH。如图 5.9所示。

加法指令 ADD X:执行加法指令 ADD X 前,程序计数器寄存器 ACC 的值为 9H,r1 为5H,r2 为 9H;执行 ADD X 后,ACC 的值为 13H,即(r2)+(ACC)->ACC,ACC+1->ACC。如图 5.10所示。

存数指令 STA X:执行存数指令 STA X 前,存储器 dataout 为不确定状态;执行 STA X后,因 ACC=06H,传送給 ALU 的指令为 0B,因此ACC 中的数据 FFFEH在下一个时钟下降沿传送給 dataout。如图 5.11与图 5.12 所示。

取数指令 LDA X:执行取数指令 LDA X 前,程序计数器寄存器 ACC的值为 06H;执行 LDAX 后,因 accop=3H,所以依然执行(ACC)+1->ACC,因此 ACC的值在下一个时钟下降沿变为 07H。如图5.13 所示。

无条件转移指令 JMP imm:执行无条件转移指令 JMP imm 前,程序计数器寄存器 ACC的值为 07H,pcJMP=1H,允许无条件跳转;执行JMP imm后outins=0803H,ins=03H,所以在下一个时钟上升沿,ACC 跳变到 03H。如图 5.14所示。

有条件转移(负则转)指令 BAN X:执行有条件转移(负则转)指令BAN X前,程序计数器寄存器 ACC 的值为04H,r2=02H,ban=1,允许有条件跳转,;执行有条件转移(负则转)指令 BAN X 后,(ACC)+(r2)->ACC,(ACC)+1->ACC,所以在下一个时钟上升沿,ACC 跳变为 07H。如图5.15所示。

七、后记

实验二三(CPU部件实现之ALU、寄存器堆、PC、RAM)

既来之 则赞之
若有疑问,欢迎评论
本文仅供参考,务必独立思考

完整项目baidu网盘链接
链接:https://pan.baidu.com/s/1B9eXsySMq_MvHXM_PQtemw
提取码:ehu4

这篇关于计算机组成原理 实验五 单周期CPU设计与实现——十条指令CPU的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/345746

相关文章

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

深入探索协同过滤:从原理到推荐模块案例

文章目录 前言一、协同过滤1. 基于用户的协同过滤(UserCF)2. 基于物品的协同过滤(ItemCF)3. 相似度计算方法 二、相似度计算方法1. 欧氏距离2. 皮尔逊相关系数3. 杰卡德相似系数4. 余弦相似度 三、推荐模块案例1.基于文章的协同过滤推荐功能2.基于用户的协同过滤推荐功能 前言     在信息过载的时代,推荐系统成为连接用户与内容的桥梁。本文聚焦于

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

hdu4407(容斥原理)

题意:给一串数字1,2,......n,两个操作:1、修改第k个数字,2、查询区间[l,r]中与n互质的数之和。 解题思路:咱一看,像线段树,但是如果用线段树做,那么每个区间一定要记录所有的素因子,这样会超内存。然后我就做不来了。后来看了题解,原来是用容斥原理来做的。还记得这道题目吗?求区间[1,r]中与p互质的数的个数,如果不会的话就先去做那题吧。现在这题是求区间[l,r]中与n互质的数的和

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount