您好,欢迎来到叨叨游戏网。
搜索
您的当前位置:首页位cpu实验报告

位cpu实验报告

来源:叨叨游戏网

一、实验原理

RISC即精简指令集计算机(ReducedInstructionSetComputer)的缩写。RISC-CPU与一般的CPU相比,通过简化指令系统使计算机的结构更加简单合理,从而提高了运算速度。本文对RISC-CPU的架构进行了分析,并使用VHDL语言设计了8位RISC-CPUIP软核。SAP-1CPU部分:程序计数器、MAR、指令寄存器、控制器/序列发生器、累加器、加减法器、B寄存器、输出寄存器。

1.1SAP-1CPU及计算机的组成架构简介

1.程序计数器

它是一个4Bits的计数器,计数范围由0~15。主要功用是记录下每个执行的指令地址,并把这个地址传送至MAR寄存器存放。

2.输入与MAR(MemoryAccessRegister)

这个方块应分成两个部分,一个是接受由“输入”部分输入到RAM内存的外部程序和数据,另一部分“MAR”是用来在CPU执行上述所加载的程序时,暂存下一个要执行的指令地址。

3.16_8RAM

这个RAM有16个存储单元,每个单元为1字节,即8bits。所以这个RAM的地址总线是4bit,地址编码是由0000,0001,0010…1111,这个地址内容是由上述MAR传送过来,然后通过译码将地址存放的8位数据或指令输出至Wbus。

4.指令寄存器

属于CPU内的控制单元,主要是将在RAM的8位数据,通过Wbus后读入指令寄存器,然后再把数据一分为二,较高的4位属于指令部分,送至下一级的“控制器”,而较低的4位属于数据部分,将会被送至Wbus。

5.控制器/序列发生器

这个模块也是属于CPU内控制单元的一部分,这个控制器在程序执行时,负责送出整个计算机的时序信号CLK,而且会把指令寄存器送来的4位指令,解译成12位的控制信号,由这组控制信号指挥其它的功能方块,完成该指令的运作。由于使用VHDL语言设计整个SAR-1,依照语法的使用,这部分会被省略,而且不会影响整个CPU运作。

6.累加器

累加器是个8位的缓冲寄存器,它是存放目前计算机执行的实时数据地方。不同的指令也将使它产生不同的工作方式。

7.加减法器

这个加减法器负责执行数学的加法和减法运算,而且运算的结果会放回“累加器”暂存。

8.B寄存器

这个寄存器用来配合“累加器”、“加减法器”,执行“加法”或“减法”的工作。

9.输出寄存器

这个输出寄存器的用途是,CPU执行到“输出结果”的指令时,便将“累加器”的结果传至“输出寄存器”,所以它是负责存放输出结果,当然这个存放的结果是二进制形式的。

1.2SAP-1CPU指令.寻址法.程序设计

SAP-1的CPU指令,共有5个且可分成两种类型,如表

直接寻址法(DirectAddressing)

二、实验要求

配合SAP-1指令,设计16(Word)_8(Bit)的ROM,使其能够执行如下预算:

三、实验设计与过程

3.1SAP-1CPU设计

SAP-CPU在前面所提的指令,它们执行的指令周期总长度基本上都是6个脉冲长度,这可以用下图说明

SAP-1指令周期(InstructionCycle)

时序状态S0-S2范围为取指令周期,而时序状态S3-S5为指令执行周期.下面是每个时序状态下,SAP-1CPU的工作任务:

1.取指令周期(FetchCycle)

(1)状态S0:(寻址状态,AddressState)

这个状态下,“程序计数器”负责将所要执行的指令地址值传递至MAR存放.

(2)状态S2:(增加状态,IncrementState)

这个状态下,“程序计数器”的值加1,代表计数器将指针指向下一个要执行的指令地址值.

原先在状态S0时,“程序计数器”的值是01H,它会传递01H给“MAR”,然后在这个状态S1时,将内容值加1后变成02H,这样以便记录下次要执行的指令地址值.

(3)状态S2:(记忆状态,MemoryState)

这个状态下,将把记录在“MAR”里的指令地址值,送入“RAM”里后,由“RAM”读出该地址的指令码,再将该指令放入“指令寄存器”.

有一点必须强调的是,不论是执行哪个指令,它们的状态S0-S2的动作方式都是相同的,不过状态S3-S5的动作方式就会因执行对那个指令而有所不同.

2.指令执行周期

(1)LDA指令

状态S3:

这个状态下,上述的09H数据传入MAR,以便下个状态能取出该数值所代表的地址里的值,比如20H.

状态S4:

这个状态是将存放在“MAR”里的09数据,通过RAM读出09H地址的数据,比如是数值20H数值至“累加器”

状态S5:

这个状态下的LDA指令并没有作用

(2)ADD指令

状态S3:

这个状态下,上述的AH数据将传入MAR,以便下个状态取出该数值所代表地址里的内容值,比如是数值14H

状态S4:

这个状态是将存放“MAR”里的AH数据,通过RAM读出AH地址内的数据,放到B寄存器中

状态S5:

这个状态是将存在“累加器”和“B寄存器”的数值内容存放入“加减法器”相加后,再将相加结果放回“累加器”

(3)SUB指令

状态S3:

这个状态下,上述的BH数据传入MAR,以便下个状态能取出该数值所代表地址里的值

状态S4:

这个状态是将存放在“MAR”的BH数据,通过RAM读出BH地址内的数据,并放到B寄存器中

状态S5:

这个状态是将存放在“累加器”和“B寄存器”的数值放入“加减法器”相减后,再将相减后结果放回“累加器”

(4)OUT指令

状态S3:

这个状态下,累加器的内容将经Wbus传至“输出寄存器”,然后显示在二进制显示装置.

状态S4:

这个状态OUT指令没有作用.

状态S5:

这个状态OUT指令没有作用

(5)HLT指令

状态S3:

这个状态下“控制器/序列发生器”将停止送出脉冲信号CLK,这时SAP-1CPU会停止执行工作.

状态S4:

这个状态HLT指令没有作用

状态S5:

这个状态HLT指令没有作用

3.2设计思路

使用三个IO端口,分别为时钟输入clk,复位使能rst,及结果输出端口output_data。

使用portmap语句进行了元件例化,将CPU与ROM相连接了。

XXX程序

LIBRARYIEEE;

XXX.ALL;

XXX.ALL;

XXXXXX;

ENTITYROM16_8is

PORT(

DATAOUT:OUTSTD_LOGIC_VECTOR(7DOWNTO0);--DataOutputADDR:INSTD_LOGIC_VECTOR(3DOWNTO0);--ADDRESSCE:INSTD_LOGIC--ChipEnable

ENDROM16_8;

ARCHITECTUREaOFROM16_8IS

BEGIN

DATA<=“1”WHENADDR=“0000”ANDCE=‘0’--LDA9H

“0”WHENADDR=“0001”ANDCE=‘0’ELSE--ADDAH“1”WHENADDR=“0010”ANDCE=‘0’ELSE--ADDBH“0”WHENADDR=“0011”ANDCE=‘0’ELSE--SUBCH“0”WHENADDR=“0100”ANDCE=‘0’ELSE--OUT“0”WHENADDR=“0101”ANDCE=‘0’ELSE--HLT“0”WHENADDR=“1001”ANDCE=‘0’ELSE

“0”WHENADDR=“1010”ANDCE=‘0’ELSE

“0”WHENADDR=“1011”ANDCE=‘0’ELSE

“0”WHENADDR=“1100”ANDCE=‘0’ELSE

“0”;

ENDa;

XXX程序

ARCHITECTUREaOFSAP1IS

TYPESTATEIS(SO,S1,S2,S3,S4,S5);--statetypedeclare

SIGNALPState:STATE;--presentstateSIGNALNState:STATE;--ne_tstate……

BEGIN

ChangeStateMode:PROCESS(CR,RST)--states0~s5

BEGIN

IFRST=‘1’THEN--resetcpu

PC<=“0000”;--pogram

counter=0H

ACC<=“0”;--accumulator=0H

RUN<=‘1’;--CPUrunprogramenable

PState<=S0;--Initialcpupresentstate

ELSIFCP’EVENTANDCP=‘0’THEN--clocknegativeedage

IFRUN=‘1’THEN--runprogrameanble

CASEPStateIS--checkcpupresentstate

WHENS0=>--(addressstatefetchcycle-1)

NState<=S1;--cpune_tstate

WHENS1=>--(incrementstatefetchcycle-2)

NState<=S2;--cpune_tstate

WHENS2=>--(memorystatefetchcycle-3)

NState<=S3;--cpune_tstate

WHENS3=>--STATES3(E_ecutioncycle-1)

NState<=S4;--cpune_tstate

WHENS4=>--STATES4(E_ecutioncycle-2)

NState<=S5;--cpune_tstate

WHENS5=>--STATES5(E_ecutioncycle-3)

NState<=S0;--cpune_tstate

ENDCASE;

PState<=NState;--切换状态

ENDIF;

ENDIF;

ENDPROCESSChangeStateMode;

ENDa;

3.5指令捕捉周期(fetchcycle)

Changestatemode:process(cp,rst)--states0~s5

variableflag,f1:boolean;

begin

ifrst=‘1’then

Pstate<=s0;

flag:=ture;---PC指针允许加1标志打开

elsifcp’eventandcp=‘0’then

ifrun=‘1’then

casepstateis

whenso=>

nstate<=s1;

mar<=std_logic_vector(pc);

whens1=>

nstate<=s2;

ifflag=turethen

pc<=pc+1;

flag:=false;

endif;

Whens2=>

Nastate<=s3;

Flag:ture;

Ir<=databus;

Whens3=>

Endcase;

3.6指令执行周期(fetchcycle)

在CaseWhen语句的状态S3处,加入下面粗体字命令,将“指令寄存器”

(IR)截取高4位指令至TMP里

Elsifcp’eventandcp=‘0’then

whens2=>

Whens3=>

nstate<=s4;

temp<=ir(7downto4),

whens4=>

其余指令执行周期的命令,不放入CASEWHEN语句里,而改以IF-ELSE将状态S3~S5命令出来,这么做只是不希望CASEWHEN语句太过冗长。

changestatemode:process(cp,rst)

variableflag,F1:boolean;

Begin

Ifrst=‘1’then

Elsifcp’eventandcp=‘0’then

Ifrun=‘1’then

casepstateis

whens0=>

nstate<=s1;

endcase;

pstate<=nstate;

Endif;

Ifpstate=s3then

If(tmp=“0000”)or(tmp=“0001”)or(tmp=“0010”)then

Mar<=ir(3downto0);

elsiftmp=“1110”then

outreg<=acc;

elsiftmp=“1111”then

run<=‘0’;

Endif

Elsifpstate=s4then

iftmp=“0000”then

acc<=databus;

elsiftmp=“0001”then

breg<=databus;

elsiftmp=“0010”then

breg<=databus;

endif;

Elsifpstate=s5then

iftmp=“0001”andf1=turethenNum<=unsigned(acc)+unsigend(breg);

Acc<=std_logic_vector(num);F1:=false;

Elsiftmp=“0010”andf1=truethennum<=unsigned(acc)-unsigned(breg);Acc<=std_logic_vector(num);F1:false;

Endif;

Endif;

Endif;Endprocesschangestatemode;

四、实验结果及仿真

4.1软件仿真结果

4.2硬件仿真结果

五、实验总结

如果要对程序运行的指令进行更改,需要改变s5中的计算whens5=>ne_t_state<=s0;

iftemp="0001"andf1='1'then

a_<=a_b_;--执行位与指令,将结果存入a_f1<='0';

elsiftemp="0010"andf1='1'then

a_<=a_||b_;--执行或指令,将结果存入a_f1<='0';

endif;

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- gamedaodao.net 版权所有 湘ICP备2024080961号-6

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务