简单CPU系统设计与实现.docx
《简单CPU系统设计与实现.docx》由会员分享,可在线阅读,更多相关《简单CPU系统设计与实现.docx(24页珍藏版)》请在冰豆网上搜索。
简单CPU系统设计与实现
数字电路综合实验报告
简单CPU系统设计与实现
1设计课题的任务要求
设计一个简单的CPU及其外部模块,能够完成机器代码的输入、存储、执行和结果显示。
基本要求:
指令要求至少有空指令,跳转指令,加法指令,存取数据指令。
利用自己设计的指令系统编写一段机器语言,可以完成求两个小于256的数的最大公约数。
机器语言通过拨码开关和按键逐条输入,通过程序执行开关控制程序执行,最后在数码管或LED灯上显示结果。
提高要求:
设计并实现其它指令。
2系统设计
2.1设计思路
设计的简易CPU系统主要由指令存储器(可以通过拨码和按键读入指令)、控制器、内部寄存器、内存以及ALU构成。
设计过程重点考虑如下事项:
读/写寄存器,读/写存储器以及执行指令。
通过执行读入的指令以及编写好的求两个数的最大公约数的程序来测试该系统的功能。
2.2总体框图
2.2.1系统总体框图
由设计思路,可绘制如下的简单CPU系统总体框图:
最终在quartusII中连接好的CPU系统图如下所示(其中的ACC属于ALU部件):
2.2.2系统状态转移图
如上图,系统共有3个状态:
S0、S1、S2。
分别为S0:
在这一状态,通过拨码和按键录入要执行的指令。
S1:
在这一状态,CPU执行程序,即S0录入的指令。
S2:
在这一状态,CPU执行完全部程序,等待再次执行或等待录入指令。
2.2.3求解最大公约数的程序框图
设a,b为给定的两个整数,用辗转相减法求解他们的最大公约数:
2.3分块设计
2.3.1DIV(分频器)
DIV将电路板所提供的时钟分频,产生CPU工作所需要的时钟以及数码管扫描所需要的时钟。
2.3.2MCU(控制器)
MCU用来产生系统内部所有寄存器、运算单元所需的控制信号,以及执行各条指令所需要的微操作。
它是整个系统设计的核心所在。
2.3.3ALU(算术逻辑运算单元)
ALU完成数据的算术和逻辑运算。
ALU有5个输入端和2个输出端,其中一个操作数固定来自累加器acc(具体编程时可用变量或信号表示),另一个操作数来自端口mbr_in(通过数据总线接到寄存器MBR)。
参加运算的操作数在ALU中进行规定的操作运算,运算结束后,一方面将结果送至累加器,同时将操作结果的特征状态送标志寄存器。
2.3.4MAR(地址寄存器)
MAR存放着要被读取或写入的内存单元地址。
其中,读操作时,CPU从内存读。
而写操作时,CPU把数据写入内存。
2.3.5MBR(缓冲寄存器)
MBR存放了将要存储到内存的数据或者从内存中读取的最新数据。
MBR连接到系统总线中的地址总线。
2.3.6RAM(随机存取存储器)
RAM有着相对独立的输入输出管脚,在本系统设计中它作为内存使用。
它不是CPU内部的寄存器,不属于CPU的一部分。
但要测试所设计的CPU的性能,需要把RAM加进系统设计中。
2.3.7SMG(数码管显示)
SMG负责将运算结果转化为BCD码形式,然后用数码馆显示。
3仿真波形及波形分析
根据波形图可以看出状态机的运行,其中一个状态占两个时钟周期。
该仿真相当于CPU执行指令的时序图,反映了程序运行情况。
还包括了辗转相减法的仿真,和rst的清零仿真。
可以看出该CPU系统的仿真结果正确,达到下载的要求。
4源程序(含注释)
各个部件对应的源程序如下(最后的连接是用图形连接完成的):
4.1DIV(分频器)
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityDIVis
port
(
clk_in:
instd_logic;
clk_out1:
outstd_logic;
clk_out2:
outstd_logic
);
endDIV;
architecturebehaveofDIVis
signaltmp:
std_logic_vector(15downto0);
begin
process(clk_in,tmp)
begin
if(clk_in'eventandclk_in='1')then
tmp<=tmp+1;
endif;
clk_out1<=tmp(0);
clk_out2<=tmp
(1);
endprocess;
endbehave;
4.2MCU(控制器)
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityMCUis
port
(
clk:
instd_logic;
start:
instd_logic;
opcode:
instd_logic_vector(3downto0);
cmp:
instd_logic;
ctr:
outstd_logic_vector(10downto0)
);
endMCU;
architecturebehaveofMCUis
begin
process(clk,start)
variablestatus:
std_logic_vector(4downto0):
="00000";
begin
if(start='1')then
status:
="00001";
elsif(clk'eventandclk='1')then
casestatusis
when"00001"=>ctr<="00010000000";status:
=status+1;--MBR<-RAM
when"00010"=>ctr<="00001000000";status:
=status+1;--MAR<-MBR
when"00011"=>--DECODING
caseopcodeis
when"0001"=>status:
="00100";ctr<="00100000000";--Store--MBR<-ACC
when"0010"=>status:
="00101";ctr<="00010000000";--Load--MBR<-RAM
when"0011"=>status:
="00111";ctr<="00010000000";--Add--MBR<-RAM
when"0100"=>status:
="01001";ctr<="00010000000";--Sub--MBR<-RAM
when"0101"=>status:
="11111";ctr<="00000000011";--SHL--ACC<-ACC<<1
when"0110"=>status:
="11111";ctr<="00000000100";--SHR--ACC<-ACC>>1
when"0111"=>status:
="01011";ctr<="00010000000";--And--MBR<-RAM
when"1000"=>status:
="01101";ctr<="00010000000";--Or--MBR<-RAM
when"1001"=>status:
="11111";ctr<="00000000111";--Not--ACC<-NOTACC
when"1010"=>status:
="00001";ctr<="00000000000";--Jump
when"1011"=>if(cmp='0')then--JumpZ
status:
="00001";ctr<="00000100000";
else
status:
="00001";ctr<="00000000000";
endif;
when"1100"=>status:
="11111";ctr<="10000000000";--Smg
when"1111"=>status:
="00000";ctr<="00000000000";--Halt
whenothers=>ctr<="00000000000";status:
="11111";
endcase;
when"00100"=>ctr<="01000000000";status:
="11111";--Store--RAM<-MBR
when"00101"=>ctr<="00000011111";status:
=status+1;--Load--BR<-MBR;ACC<-0
when"00110"=>ctr<="00000000001";status:
="11111";--ACC<-ACC+BR
when"00111"=>ctr<="00000010000";status:
=status+1;--Add--BR<-MBR
when"01000"=>ctr<="00000000001";status:
="11111";--ACC<-ACC+BR
when"01001"=>ctr<="00000010000";status:
=status+1;--Sub--BR<-MBR
when"01010"=>ctr<="00000000010";status:
="11111";--ACC<-ACC-BR
when"01011"=>ctr<="00000010000";status:
=status+1;--And--BR<-MBR
when"01100"=>ctr<="00000000101";status:
="11111";--ACC<-ACCANDBR
when"01101"=>ctr<="00000010000";status:
=status+1;--Or--BR<-MBR
when"01110"=>ctr<="00000000110";status:
="11111";--ACC<-ACCORBR
when"01111"=>ctr<="00000010000";status:
=status+1;--Mutiply--BR<-MBR
when"10000"=>ctr<="00000001000";status:
="11111";--ACC<-ACC*BR
when"11111"=>ctr<="00000100000";status:
="00001";--PC<-PC+1;MAR<-PC
when"00000"=>ctr<="00000000000";status:
="00000";
whenothers=>ctr<="00000000000";status:
="00001";
endcase;
endif;
endprocess;
endbehave;
4.3ALU(算术逻辑运算单元)
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
entityALUis
port
(
clk:
instd_logic;
rst:
instd_logic;
mbr_in:
instd_logic_vector(11downto0);
mbr_e:
instd_logic;