简易CPU的设计和实现
一.CPU的简介:
此CPU为冯·诺伊曼架构的,顾名思义程序存储器和数据存储器共用了一组数据和地址总线,当然有兴趣的人可以在此基础上实现下哈佛架构的CPU。
本CPU内部主要由五大部件组成,每个部件的相互配合,实现了每条指令的有序执行。
二.CPU设计准备:
所采用软件为QuartusII 9.0,所使用语言为Verilog HDL。
三.CPU架构的设计:
四.CPU各个部件的功能简述:
1.程序计数器(PC):包含当前正在执行的指令的地址,当指令被获取之后,一般情况下,指向下一条指令。
2.存储器(Memory):主要有三个作用:
a.存储CPU运行的指令
b.保存指令运行过程中的临时变量
c.在指令执行前存放初始化数据
在本示例中,即是指令存放的地方又是操作数所存放的地方
3.指令解码器(Idec):
a.将从指令存储器(本示例中即是从memory中读出)中读出的指令进行翻译,CPU根据翻译后的代码执行不同的操作
b.将所读取到的指令分为指令码和操作码(本示例中实现6条计算机指令,故指令码采取3位)
4.算术逻辑单元(ALU):实现数据的二进制运算及判断标志位(负数标志,溢出标志等)的输出。
5.控制单元(Control): 此部件是本CPU的核心模块,控制着整个CPU有条不紊地运行,它控制着每个部件何时使能工作,ALU何时进行什么样的运算,这个功能在CPU的顶层原理图体现的淋漓尽致。
五.各个部件的代码实现
1.PC部件的代码实现
module pc (clock,reset,en,pc);
input clock, reset, en;
output reg [4:0] pc;wire [4:0] pc_next; //欲寻址的下一条指令//always过程快
always@ (posedge clock or posedge reset)
beginif(reset) //系统复位,pc清0pc <= 0;elseif(en) //如果使能pc模块,则将下一条指令付给pc端口输出pc <= pc_next;elsepc <= pc; //否则,pc保持即不工作
end//assign持续赋值语句
assign pc_next = pc + 1; //本处理器中下一条指令的地址为当前地址加1
endmodule
2.存储器(Memory)的代码实现
module memory (clock,reset,addr,din,dout,wr,rd);input clock; //时钟信号线
input reset; //复位信号,高电平有效
input [4:0] addr; //存储器地址
input [7:0] din; //数据线输入
output reg [7:0] dout; //数据线输出
input wr; //写使能端,高电平有效
input rd; //读使能端,高电平有效reg [7:0] mem [0:31]; //内部的存储空间always @(posedge clock or posedge reset) beginif (reset) beginmem [0] <= 'b00001011; //LDA 01011mem [1] <= 'b01001100; //ADD 01100mem [2] <= 'b00101101; //STA 01101mem [3] <= 'b00001011; //LDA 01011mem [4] <= 'b10001100; //AND 01100mem [5] <= 'b00101110; //STA 01110mem [6] <= 'b00001011; //LDA 01011mem [7] <= 'b01101100; //SUB 01100mem [8] <= 'b00101111; //STA 01111mem [9] <= 'b10100000; //HLTmem [10] <= 'b00000000;mem [11] <= 'b10010101;mem [12] <= 'b01100101;mem [13] <= 'b00000000;mem [14] <= 'b00000000;mem [15] <= 'b00000000;mem [16] <= 'b00000000;mem [17] <= 'b00000000;mem [18] <= 'b00000000;mem [19] <= 'b00000000;mem [20] <= 'b00000000;mem [21] <= 'b00000000;mem [22] <= 'b00000000;mem [23] <= 'b00000000;mem [24] <= 'b00000000;mem [25] <= 'b00000000;mem [26] <= 'b00000000;mem [27] <= 'b00000000;mem [28] <= 'b00000000;mem [29] <= 'b00000000;mem [30] <= 'b00000000;mem [31] <= 'b00000000;endelse beginif (wr)mem [addr] <= din;if (rd)dout <= mem [addr]; end
end
endmodule
3.指令解码器(Idec)的代码实现
module idec (clock, //时钟端口reset, //复位端口en, //译码使能端口instruction, //指令输入端口opcode, //操作吗输入端口addr, //存储器地址输入端口);input clock,reset,en;
input [7:0] instruction;
output reg [2:0] opcode;
output reg [4:0] addr;always @(posedge clock or posedge reset) beginif (reset) beginopcode <= 0;addr <= 0;// reset endelse if (en) beginopcode <= instruction [7:5];addr <= instruction [4:0];end
end
endmodule
4.算术逻辑单元(ALU)的代码生成:
module alu (clock, //时钟端口reset, //复位端口en, //alu使能端口a, //累加器输出寄存器din, //操作数1输入 n, //负标志z, //0标志c, //输出进位标志v, //输出溢出标志add_en, //加法使能运算sub_en, //减法使能运算and_en, //与运算pass_en, //使din直通累加器A,不做运算(部分运算需要));input clock,reset,en,add_en,sub_en,and_en,pass_en;
input [7:0] din;
output n,z,c,v;
output reg [7:0] a;
reg c;always @(posedge clock or posedge reset) if (reset) begina <= 0; //复位累加器清0,c <= 0;// reset endelse beginif(en) beginif(add_en){c,a} <= a [7:0] + din;else if(sub_en){c,a} <= a [7:0] - din;else if(and_en)a <= a & din;else if(pass_en)a <= din; endendassign z = (a == 8'b0) ? 1: 0 ; //0标志,如果累加器为0,z=1
assign n = (c == 1) ? 1: 0 ; //负数标志,如果借位为1,则n=1
assign v = ((a>127) || (a<-128) ? 1:0 ); //溢出标志endmodule
5.控制单元(Control)的代码实现:
module control (input clock,input reset, //异步复位端端口output reg s0, //分别作用各阶段的使能信号个端口output reg s1,output reg s2,output reg s3,output reg s4,output reg s5,output reg addrsel, //选择程序的地址或者选择数据的地址output reg instr_add, //加法端口使能信号,以下类似output reg instr_sub,output reg instr_and,output reg instr_pass,input [2:0] opcode //解码器解码后将指令码传给控制器);parameter [2:0] LDA = 3'b000, STA = 3'b001, ADD = 3'b010, SUB = 3'b011, AND = 3'b100 , HLT = 3'b101;reg [2:0] cnt; //指令执行需要6个阶段,用cnt计数来表示不同的阶段always @(posedge clock or posedge reset) if (reset) // resetcnt <= 0;elseif (cnt==5)cnt <= 0;else cnt <= cnt+1;always@ *begincase(cnt)0: begin //取指s0<=1; s1<=0; s2<=0; s3<=0; s4<=0; s5<=0;addrsel<=0;end1:begin //解码s0<=0; s1<=1; s2<=0; s3<=0; s4<=0; s5<=0;addrsel<=0;end2:begin //根据操作码决定是否从存储器中读取数据s0<=0; s1<=0; s2<=1; s3<=0; s4<=0; s5<=0;addrsel<=1;if( (opcode==LDA) ||(opcode==ADD) ||(opcode==SUB) ||(opcode==AND) )s2<=1;elses2<=0;end3:begin //确定ALU的运算s0<=0; s1<=0; s2<=0; s3<=1; s4<=0; s5<=0;addrsel<=1;if (opcode==LDA) begininstr_add<=0;instr_sub<=0;instr_and<=0;instr_pass<=1;endelse if(opcode==ADD) begininstr_add<=1;instr_sub<=0;instr_and<=0;instr_pass<=0;endelse if(opcode==SUB) begininstr_add<=0;instr_sub<=1;instr_and<=0;instr_pass<=0;endelse if(opcode==AND) begininstr_add<=0;instr_sub<=0;instr_and<=1;instr_pass<=0;endelse if(opcode==STA) begininstr_add<=0;instr_sub<=0;instr_and<=0;instr_pass<=0;endelse begininstr_add<=0;instr_sub<=0;instr_and<=0;instr_pass<=0;endend4:begin //必要时往存储器中写数据s0<=0; s1<=0; s2<=0; s3<=0; s4<=1; s5<=0;addrsel<=1;if(opcode==STA)s4<=1;elses4<=0;end5:begin //使能PC准备开始读取下一条指令s0<=0; s1<=0; s2<=0; s3<=0; s4<=0; s5<=1;addrsel<=1;endendcaseend
endmodule
六.CPU的顶层原理图:
七.CPU顶层原理图的功能仿真结果:
八.总结:
1.从对顶层原理图的功能仿真结果来看,我们已经实现相应的功能,结果也以在图中标出
2.此CPU中每条指令的执行包括六个阶段:取指令、指令解码、根据操作码决定是否从存储器中读取数据、确定ALU的运算、必要时往存储器中写数据、使能PC准备开始读取下一条指令。从结果图中可以看出,使用cnt来标记指令所处于的哪一个阶段,故可以在图中清楚的分辨出第几条指令的执行结果。
简易CPU的设计和实现相关推荐
- 简易cpu设计_为简单而设计
简易cpu设计 Before we get started, it's worth me spending a brief moment introducing myself to you. My n ...
- 基于modelsim软件进行仿真简易CPU指令的实现
文章目录 基于modelsim软件进行仿真简易CPU指令的实现 一. 任务.要求.目的 二. 指令实现原理 2.1 Verilog HDL基础 2.2 MIPS架构简介 2.2.1 指令基础 2.2. ...
- 简易灯箱画廊设计html,原生Js实现的画廊功能
原生Js实现画廊功能,点击图片,在下方出现相应放大图片.给a标签绑定onclick点击事件.这里上方的小图和下方将要展示大图,都是同一张图片,只是上下两个img的style中设置了不同的width和h ...
- 简单计算器的设计java_(基于java的简易计算器的设计.doc
(基于java的简易计算器的设计 基于java的简易计算器的设计 摘要 自从java语言诞生以来,java语言就以不可抵挡的趋势很快成为国际上广泛流行的面向对象编程语言,它既具有高级语言的特点,又少了 ...
- java简单计算器课程设计_java仿windows简易计算器课程设计 源码+报告
[实例简介] java仿windows简易计算器课程设计 源码+报告 课直接运行. [实例截图] [核心代码] Java课设-简易计算器 └── Java课设-简易计算器 ├── Java课程设计.d ...
- 基于stm32简易计算机电路图,基于STM32的简易电子计算器设计与实现(DOC).doc
嵌入式系统设计实验综合设计报告 PAGE 四川师范大学成都学院通信工程学院 基于STM32的简易电子计算器设计与实现 实验综合设计报告 学生姓名 陶龑 学 号 2016301033 所在学院 通信工程 ...
- 单片机多功能电子琴课设_基于单片机的简易电子琴课程设计.doc
基于单片机的简易电子琴课程设计.doc 还剩 16页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,喜欢就下载吧,价低环保! 内容要点: 15 14可在实际的应用时这些是不能被忽略的,我们不 ...
- web浮动框架 简易灯箱画廊设计
<!-- prj_3_1.html --> <!doctype html> <html lang="en"><head><me ...
- RISC-V CPU课程设计报告【计算机组成原理课设】
博主在ujs大二完成的计算机组成原理课设,内容是RISC-V CPU设计.(当时也是做的快吐血了~~) 完成情况(写在前面) 在本次计算机组成原理课程设计中,我完成一个基于RISC-V指令集架构的模型 ...
最新文章
- 计算机图形学在数学中的应用,计算机图形学的数学工具与C#实现:数学C
- mininet在哪编写python脚本_1 mininet 简介及同时支持python2和python3
- this表示当前对象简单实例
- CCF - 201703-1 - 分蛋糕
- 在mac上用文本编辑器写python_Mac系统Python解释器、PyCharm编辑器安装及使用方法详解...
- jQuery UI.Layout
- /dev/tty和/dev/console
- HTML 内容居中方式总结
- Linux 下使用Postgre中的命令,要使用postgres这个用户
- Hadoop Hive与Hbase关系 整合
- 【概率论基础】机器学习领域必知必会的12种概率分布(附Python代码实现)
- 数据库的三种状态RESTRICT、QUIESCE和SUSPEND
- 使用.NET Core搭建分布式音频效果处理服务(一)需求、问题和解决方案的几个坑...
- 抖音被“逼”出个“视频朋友圈”
- 在Android上模拟登录广工正方教务系统查询成绩
- SpringBoot项目yml文件 不显示绿色小树叶的问题
- SEVERE: Could not contact [localhost:8005] (base port [8005] and offset [0]). Tomcat may not be runn
- [经验教程]iPhone苹果手机电池健康度怎么查询及如何更换苹果iPhone手机电池恢复健康度到100%?
- 【Java进阶营】阿里架构师加持,十分钟入门RocketMQ,就是这么简单
- icinga用NSCA监控远程Linux服务器