第三次试验报告.docx
《第三次试验报告.docx》由会员分享,可在线阅读,更多相关《第三次试验报告.docx(21页珍藏版)》请在冰豆网上搜索。
![第三次试验报告.docx](https://file1.bdocx.com/fileroot1/2022-12/14/6e205e41-22f9-416b-b175-1e1541e082e0/6e205e41-22f9-416b-b175-1e1541e082e01.gif)
第三次试验报告
课程名称数字系统EDA技术
实验题目
处理器核心电路的设计及验证
一、实验目的
1、进一步掌握AlteraDE2-115开发平台的使用;
2、掌握Quartus软件设计流程;
3、掌握一个处理器核心电路的基本结构及设计方法;
4、掌握状态机的设计方法;
5、进一步掌握如何编写testBench,并利用Modelsim进行仿真。
二、实验环境
1、预装开发环境Quartus11.0以上的版本和仿真工具软件Modelsim的计算机;
2、DE2-115开发板一套。
三、实验内容
1、利用层次化的设计方法使用VHDL语言设计一个简单的处理器;
2、设计一个应用程序用于验证所设计的处理器的功能。
四、实验原理
1、一个最基本处理器的主要部件的构成
如下图所示,一个最基本的处理器应该包括一些寄存器,一个多路选择器、一个加法/减法单元、计数器和一个控制单元。
其中,寄存器的位宽可以选择8位、16位、32位、64位。
以下均以16位为例来说明所设计的处理器的基本结构。
处理器所处理的输入数据通过多路复用器加载到不同的寄存器内,寄存器分别定义为R0、R1、R2、R3、R4、R5、R6、R7和A。
各个寄存器之间可以相互传递数据。
复用器的输出称之为总线。
该总线容许数据从一个位置传递到另一个位置。
加法/减法单元首先通过多路复用器将一个16位数加载到寄存器A中,寄存器A固定作为加法/减法单元的一个操作数。
加法/减法单元的第二个操作数将通过总线传至加法/减法单元的另一个数据输入接口,完成运算操作后的数据存入寄存器G内。
寄存器G的值可通过复用器将其搬移到需要的位置。
图1处理器内部结构图
在控制单元的控制下,每个时钟周期可完成不同的操作。
这个控制单元决定什么数据放在总线上,并且控制哪个寄存器加载总线上的数据。
例如,将寄存器R0的值加载到寄存器A内,可在两个时钟周期内完成,第一个时钟周期是将R0的值放在总线上,第二个周期则将总线上的数据加载到寄存器A内。
2、处理器的操作
处理器可通过各种指令来进行所需要的操作。
下表列出了本次实验需要完成的4条指令及相应的功能。
mvRx,Ry表示将Ry寄存器内的数据移到Rx寄存器内。
mviRx,#D表示将立即数送到Rx寄存器内。
addRx,Ry表示将Rx和Ry寄存器内的数据相加,结果存入Rx寄存器内。
subRx,Ry表示将Rx和Ry寄存器内的数据相加减,结果存入Rx寄存器内。
指令可通过编码后存入IR寄存器内。
IR寄存器可以使用9位表示。
如IIIXXXYYY。
其中III表示指令,XXX代表Rx寄存器,YYY代表Ry寄存器。
IR必须连接到16位数据输入脚上(可以是低9位或高9位)。
对于mvi指令,YYY域不用,立即数#D在mvi指令存入IR寄存器后由16位数据输入口送入。
对于加法和减法指令,由于该类操作需要多次占用总线,因此完成这类操作需要多个时钟周期。
为此可增加一个2位的计数器counter。
当RUN有效时计数器counter开始计数,即检测到开始执行加法/减法操作,当指令执行完毕后Done有效,此时清空counter计数器,可以进行下一指令的操作。
表1处理器操作指令
操作
所完成的功能
mvRx,Ry
Rx<--[Ry]
mviRx,#D
Rx<--D
addRx,Ry
Rx<--[Rx]+[Ry]
subRx,Ry
Rx<--[Rx]-[Ry]
表2指令的操作时序
T0
T1
T2
T3
mv
从IR中取指令
完成移位操作
mvi
从IR中取指令
完成移位操作
add
从IR中取指令
将Rx值存入寄存器A内
将Ry值送至总线上
完成加法操作并将G值送入Rx寄存器内
sub
从IR中取指令
将Rx值存入寄存器A内
将Ry值送至总线上
完成减法操作并将G值送入Rx寄存器内
五、源程序:
---------------FunctionDescriptions-----------
--Supportoperationinstruction
--mvRx,Ry
--mviRx,#data
--addRx,Ry
--subRx,Ry
--instructionformat
--IIIXXXYYY
--III:
000:
mv,001:
mvi,010:
add,011:
sub
--XXX:
selectRxvalue:
000:
R0->Rx,001:
R1->Rx,...,111:
R7->Rx
--YYY:
selectRyvalue:
000:
R0->Ry,001:
R1->Ry,...,111:
R7->Ry
--resources
--816-bitregisters:
R0~R7
--116-bitALU(Addorsubtract)
--Operationtiming
--123456
--clk_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_|-|_
--Run_____________|---|_____________________________
--DIn========================================
--Done_____________________|---|____________________mvormvi
--procBus=========================================Busvaliddata
--R[7:
0]==================================R[7:
0]validdata(delayaclockperiod)
--Done_____________________________|---|_____________addorsub
--procBus=============================================
--R[7:
0]=====================================R[7:
0]validdata(delayaclockperiod)
--:
ValidInstruction
--:
ValidData
--库、程序包的声明
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;--有符号的加减运算
--处理器的输入和输出口
entitysimProcis
generic(BusWidth:
integer:
=16);
port(
DIn:
instd_logic_vector(BusWidth-1downto0);--16-bitdatainputport
nARst:
instd_logic;--resetsignal,lowactive
clk:
instd_logic;--clockinput,canbeobtainedthrough50MHZfrequency
--dividerorthroughabuttonofDE2_115board
Run:
instd_logic;--highactive,Keepatleastoneclockcycle
Done:
outstd_logic;--operationover,highactive
procBus:
outstd_logic_vector(BusWidth-1downto0);--outputprocessorbus
statIndic:
outstd_logic_vector(2downto0)--stateindicators
);
endsimProc;
architecturearchofsimProcis
signalhighLevel:
std_logic;
signalupCntClr:
std_logic;
signalcntRst:
std_logic;
signalprocBusReg:
std_logic_vector(BusWidth-1downto0);--registerprocBus
--IR(2downto0):
RYregister
--IR(5downto3):
RXregister
--IR(8downto6):
resprentsInstruction
signalIR:
std_logic_vector(8downto0);--9-bitInstruction
--mv:
I=0
--mvi:
I=1
--add:
I=2
--sub:
I=3
signalI:
std_logic_vector(2downto0);--Instructionregister
signalXreg,Yreg:
std_logic_vector(7downto0);--Indicatewhichregisters(R0~R7)
--R0~R7registers
signalR0,R1,R2,R3,R4,R5,R6,R7:
std_logic_vector(BusWidth-1downto0);
--writeenablesignalsofR0~R7registers
signalRin:
std_logic_vector(7downto0);
--operandRxandRy
signalRx,Ry:
std_logic_vector(BusWidth-1downto0);
--AregisterwhichisusedtosaveRxoperandwhentoaddorsubtractoperation
signalA:
std_logic_vector(BusWidth-1downto0);
--writeenablesignalofAregister
--signalA_En:
std_logic;--Hiddenintheprogram
--saveadd/subtractresult
signalG:
std_logic_vector(BusWidth-1downto0);
--operationsteps
--signalTstep_Q:
std_logic_vector(1downto0);
typeTstepis(Tstep_Q0,Tstep_Q1,Tstep_Q2,Tstep_Q3);
signalcurrentOpState:
std_logic_vector(1downto0);
signalnextOpState:
Tstep;
componentdec3to8is
port(w:
instd_logic_vector(2downto0);
En:
instd_logic;
Y:
outstd_logic_vector(7downto0));
endcomponent;
componentregnis
generic(regWidth:
integer:
=16);
port(R:
instd_logic_vector(regWidth-1downto0);
nRst:
instd_logic;
Rin,clk:
instd_logic;
Q:
outstd_logic_vector(regWidth-1downto0));
endcomponent;
begin
--highLevel<='1';
procBus<=procBusReg;
--decodeIRregister
I<=IR(8downto6);
--usedtoselectwhichregisters
Xreg_unit:
dec3to8portmap(IR(5downto3),nARst,Xreg);
--R0~R7registers
reg_0:
regn
genericmap(regWidth=>BusWidth)
portmap(procBusReg,nARst,Rin(0),clk,R0);
reg_1:
regn
genericmap(regWidth=>BusWidth)
portmap(procBusReg,nARst,Rin
(1),clk,R1);
reg_2:
regn
genericmap(regWidth=>BusWidth)
portmap(procBusReg,nARst,Rin
(2),clk,R2);
reg_3:
regn
genericmap(regWidth=>BusWidth)
portmap(procBusReg,nARst,Rin(3),clk,R3);
reg_4:
regn
genericmap(regWidth=>BusWidth)
portmap(procBusReg,nARst,Rin(4),clk,R4);
reg_5:
regn
genericmap(regWidth=>BusWidth)
portmap(procBusReg,nARst,Rin(5),clk,R5);
reg_6:
regn
genericmap(regWidth=>BusWidth)
portmap(procBusReg,nARst,Rin(6),clk,R6);
reg_7:
regn
genericmap(regWidth=>BusWidth)
portmap(procBusReg,nARst,Rin(7),clk,R7);
--DeterminewhichregistersareusedaccordingtoIRinstructiuon
--Rx
Rx<=R0whenIR(5downto3)="000"else
R1whenIR(5downto3)="001"else
R2whenIR(5downto3)="010"else
R3whenIR(5downto3)="011"else
R4whenIR(5downto3)="100"else
R5whenIR(5downto3)="101"else
R6whenIR(5downto3)="110"else
R7;
--Ry
Ry<=R0whenIR(2downto0)="000"else
R1whenIR(2downto0)="001"else
R2whenIR(2downto0)="010"else
R3whenIR(2downto0)="011"else
R4whenIR(2downto0)="100"else
R5whenIR(2downto0)="101"else
R6whenIR(2downto0)="110"else
R7;
--instructionoperationstatemachine
process(clk,nARst)
begin
if(nARst='0')then
currentOpState<="00";
elsifclk'eventandclk='1'then
--currentOpState<=nextOpState;
--endif;
--endprocess;
--process(currentOpState,I,Run)
--begin
casecurrentOpStateis
--loadinstruction
when"00"=>--Tstep_Q:
T0
if(Run='1')then
currentOpState<="01";
endif;
--shiftorloadthefirstoperationdatatoRx
when"01"=>--Tstep_Q:
T1
if((I="010")or(I="011"))then
currentOpState<="10";
else
currentOpState<="00";
endif;
--loadthesecondoperatondata
when"10"=>--Tstep_Q:
T2
if((I="010")or(I="011"))then
currentOpState<="11";
else
currentOpState<="00";
endif;
--whenTstep_Q3=>
--nextOpState<="00";
whenothers=>--Tstep_Q:
T3
currentOpState<="00";
endcase;
endif;
endprocess;
--operation
process(clk,nARst)
begin
if(nARst='0')then
Done<='0';
Rin<=(others=>'0');
statIndic(0)<='0';
procBusReg<=(others=>'0');
IR<=(others=>'0');
G<=(others=>'0');
elsifclk'eventandclk='1'then
casecurrentOpStateis
--loadinstruction
when"00"=>--Tstep_Q:
T0
Done<='0';
Rin<=(others=>'0');
statIndic(0)<='0';
if(Run='1')then
IR<=DIn(8downto0);--loadoperationinstruction
endif;
--shiftorloadthefirstoperandRxtoAregister
when"01"=>--Tstep_Q:
T1
caseIis
when"000"=>--mvRx,Ry
procBusReg<=Ry;
Rin<=Xreg;
Done<='1';--Completemvoperation
when"001"=>--mviRx,#D
procBusReg<=DIn;
Rin<=Xreg;
Done<='1';--Completemvioperation
when"010"|"011"=>--addRx,Ry
A<=Rx;--moveRxregistertoAregister
whenothers=>--inputerror
statIndic(0)<='1';
endcase;
--loadthesecondoperand
when"10"=>--Tstep_Q:
T2
caseIis
when"000"|"001"=>
statIndic(0)<='1';
when"010"=>--addRx,Ry
G<=A+Ry;
when"011"=>--subRx,Ry
G<=A-Ry;
whenothers=>
statIndic(0)<='1';
endcase;
when"11"=>--Tstep_Q:
T3
caseIis
when"000"|"001"=>
statIndic(0)<='1';
when"010"|"011"=>--addRx,RyorsubRx,Ry
procBusReg<=G;
Rin<=Xreg;
Done<='1';--Completeaddorsuboperation
whenothers=>
statIndic(0)<='1';
endcase;
whenothers=>
statIndic(0)<='1';
endcase;
endif;
endprocess;
statIndic(2downto1)<=I(1downto0);
endarch;
38译码器:
libraryieee;
useieee.std_logic_1164.all;
entitydec3to8is
port(w:
instd_logic_vector(2downto0);
En:
instd_logic;
Y:
outstd_logic_vector(7downto0));
enddec3to8;
architecturearchofdec3to8is
begin
process(w,En)
begin
ifEn='1'then
casewis
when"000"=>Y<="00000001";
when"001"=>Y<="00000010";
when"010"=>Y<="00000100";
when"011"=>Y<="00001000";
when"100"=>Y<="00010000";
when"101"=>Y<="00100000";
when"110"=>Y<