CPU实验报告.docx

上传人:b****7 文档编号:10460459 上传时间:2023-02-13 格式:DOCX 页数:71 大小:494.47KB
下载 相关 举报
CPU实验报告.docx_第1页
第1页 / 共71页
CPU实验报告.docx_第2页
第2页 / 共71页
CPU实验报告.docx_第3页
第3页 / 共71页
CPU实验报告.docx_第4页
第4页 / 共71页
CPU实验报告.docx_第5页
第5页 / 共71页
点击查看更多>>
下载资源
资源描述

CPU实验报告.docx

《CPU实验报告.docx》由会员分享,可在线阅读,更多相关《CPU实验报告.docx(71页珍藏版)》请在冰豆网上搜索。

CPU实验报告.docx

CPU实验报告

武汉大学

开放式CPU设计实验报告

专  业:

物联网

姓  名:

张三同组姓名:

林文王伟

2012年5月

1.设计报告

1.1实验目的

与以往的CPU教学实验不同,这次的“开放式教学CUP设计与测试系统”中使用另

外一个成品CUP专门运行监控程序,另外还能够将各种测试程序自动转换成用实验者所设计的指令系统表示的目标代码,并且能够在实验装置上运行、调试和测试所生成的目标代码。

有了这样的改进,我们做实验就有了新的要求和任务:

学会使用先进的硬件设计工具和超大规模集成电路FPGA设计并实现一个CPU芯片。

要求采用先进的工具软件进行模拟和测试,测试通过后再下载到FPGA中制成CPU芯片。

在过程中需要掌握的主要就是CPU的设计、验证和测试方法,以及学会相关工具软件的使用方法。

1.2实验环境

软件:

QuartusII5.2,完成指令集设计、逻辑设计后,用于各个功能模块的VHDL语言程序编写、编译以及FPGA-CPU的软件模拟;

DebugController,用于软件模拟成功后的硬件调试。

硬件:

FPGA(FieldProgrammableGateArray),即现场可编程门阵列。

FPGA具有掩膜可编程门阵列的通用结构,它由逻辑功能块排成阵列组成,并由可编程互联资源连接这些逻辑功能块来实现不同的设计。

1.3实验方法

本实验要完成的工作主要包括:

指令系统的设计,FPGA-CPU的整体结构设计及其细化,逻辑设计的具体实现(VHDL语言程序的编写),软件模拟,以及硬件调试。

这几部分的工作之间是先行后续的关系,不存在并行完成的情况。

实验主要流程如下图所示:

 

其中指令系统和逻辑结构的设计主要参考了附录所列的文献。

主要的方法是先确定CPU所要实现的功能,根据寄存器等的情况划分指令格式,然后根据功能写出指令,根据不同指令的特点将它们分组并确定操作码;接下来设想每条指令的执行过程,需要哪些硬件支持,最后确定整个CPU的逻辑结构图。

在各个功能模块的实现中主要使用了自底向上的设计方法。

先实现寄存器,再实现寄存器组,等等,最后将各个器件和模块之间互连,得到顶层设计图。

但有些逻辑的设计实现方法也涉及到顶向下的方法。

要注意的是,根据各个信号所对应的管脚可以画出如下的FPGA-CPU顶视图:

可以看出在这个顶层模型中有一些信号并不是CPU本身必须的,比如寄存器选择信号,主要是为调试和检查服务的。

为此还需要在设计中加入一些译码电路以输出各个通用寄存器和指令寄存器等的内容。

从这个角度说,在设计中还使用了自顶向下的方法。

软件模拟和硬件调试并无太多方法可言,主要是仔细观察和全面考虑,把各种可能性都验证到。

1.4总体说明

1、指令系统:

计算机的指令是用户使用计算机与计算机本身运行的最小功能单位。

一台计算机支持的全部指令就构成该机的指令系统。

从计算机本身的组成看,指令系统直接与计算机系统的性能和硬件结构的复杂程度等密切相关,它是CPU设计的起始点和基本依据。

设计指令系统的核心问题是选定指令的格式和功能。

具体到我们的设计来说,指令的功能应该包括简单的算术和逻辑运算,移位操作,数据传送,跳转,读写内存,另外还可能包括一些其他功能如置条件码等。

为了指令的规整性和便于译码,我们主要采用了定长的操作码组织方案,操作码为8位。

寻址方式包括了寄存器寻址、立即数寻址、直接地址和相对寻址。

(1)指令格式分类(按指令字长和操作数不同):

单字单操作数指令

158

74

30

OPCODEDEST_REG0000

OPCODEOFFSET

包括:

DEC,INC,SHL,SHR,JR,JRC,JRNC,JRZ,JRNZ,JRS,JRNS

单字双操作数指令

158

74

30

OPCODEDEST_REGSOUR_REG

包括:

ADD,SUB,AND,CMP,XOR,TEST,OR,MVRR,ADC,SBB,LDRR,STRR

单字无操作数指令

158

74

30

OPCODE00000000

包括:

CLC,STC

双字单操作数指令

158

74

30

OPCODE00000000

ADR

包括:

JMPA

双字双操作数指令

158

74

30

OPCODEDEST_REG0000

DATA

包括:

MVRD

(2)指令的分组及节拍:

由于没有中断操作,本机指令的执行步骤可概括如下:

读取指令:

地址寄存器<-指令地址,修改PC内容使其指向下一条将要执行的指令;

读内存,指令寄存器<-读出的内容。

分析指令

执行指令:

通用寄存器之间的运算或传送,可1步完成;

读写内存,通常要两步完成。

根据指令的执行步骤不同,可以把全部指令分为A、B两组。

其中A组指令完成的是通用寄存器之间的数据运算或传送,或其他一些特殊操作,在取指之后可一步完成,包括:

ADD,SUB,AND,CMP,XOR,TEST,OR,MVRR,DEC,INC,SHL,SHR,ADC,SBB,JR,JRC,JRNC,JRZ,JRNZ,JRS,JRNS,CLC,STC;B组指令完成的是一次内存读写操作,在取指之后可两步完成,包括:

JMPA,LDRR,STRR,MVRD。

在编码的时候以指令操作码的最高位来区分A、B组指令,0为A组指令,1为B组指令。

在控制器方面我们选用了组合逻辑控制器方案。

使用节拍来标记每条指令的执行步骤。

由指令而定,在我们的系统中不同的执行步骤只有5个,故使用3位节拍就足够了。

000

 

001

B组指令

101111

A组指令

011

 

(3)指令汇总表:

指令格式

汇编语句

操作数个数

CZVS

指令类型 

功能说明

00000000DRSR

ADDDR,SR

2

****

 

DR<-DR+SR

00000001DRSR

SUBDR,SR

2

****

 

DR<-DR-SR

00000010DRSR

ANDDR,SR

2

****

 

DR<-DRandSR

00000011DRSR

CMPDR,SR

2

****

 

DR-SR

00000100DRSR

XORDR,SR

2

****

A

DR<-DRxorSR

00000101DRSR

TESTDR,SR

2

****

 

DRandSR

00000110DRSR

ORDR,SR

2

****

 

DR<-DRorSR

00000111DRSR

MVRR

2

….

DR<-SR

00001000DR0000

DECDR

1

****

 

DR<-DR-1

00001001DR0000

INCDR

1

****

 

DR<-DR+1

00001010DR0000

SHLDR

1

*…

DR,C<-DR*2

00001011DR0000

SHRDR

1

*…

 

DR,C<-DR/2

00001100DRSR

ADCDR,SR

2

****

 

DR<-DR+SR+C

00001101DRSR

SBBDR,SR

2

****

DR<-DR-SR-C

01000000OFFSET

JRADR

1

….

 

无条件跳转 

01000100OFFSET

JRCADR

1

….

 

C=1时跳转

01000101OFFSET

JRNCADR

1

….

 

C=0时跳转

01000110OFFSET

JRZADR

1

….

 

Z=1时跳转

01000111OFFSET

JRNZADR

1

….

 

Z=0时跳转

01000001OFFSET

JRSADR

1

….

 

S=1时跳转

01000011OFFSET

JRNSADR

1

….

 

S=0时跳转

011110000000000

CLC

0

0…

 

C=0

011110100000000

STC

0

1…

 

C=1

1000000000000000ADR

JMPAADR

1

….

B

无条件跳转到ADR

10000010DRSR

LDRRDR,[SR]

2

….

DR<-[SR]

10000011DRSR

STRR[DR],SR

2

….

[DR]<-SR

10000001DR0000

MVRDDR,DATA

2

….

DR<-DATA

(*表示状态位在指令执行后会被重置,.表示状态位在指令执行后不会被修改)

查看源文件

2、结构图:

查看源文件

由于没有流水和Cache,CPU的结构还是比较简单的。

主要的部件就是算逻单元ALU、控制逻辑、通用寄存器组、指令寄存器IR、地址寄存器AR、程序计数器PC、标志寄存器、节拍发生器以及一些数据选择器和译码电路。

运算器方面,由一个ALU部件完成全部算数、逻辑、移位操作,输出设置了4个标志位:

C——进位标志位,Z——是否为0标志位,V——溢出标志位,S——是否为负标志位,保存在标志寄存器内。

与之相关的还有寄存器组和数据选择器。

16个16位的通用寄存器既是参与运算的数据的来源,又是运算结果的暂存地,而数据选择器为ALU正确选择了两个输入数据。

控制器方面,使用了组合逻辑控制器,这也是当前RISC类型计算机普遍选用的控制器方案。

它的基本运行原理是,用组合逻辑门线路直接提供控制计算机各功能部件协同运行所需要的控制信号。

其优点是,形成这些控制信号所必需的线路延迟时间少,对提高系统运行速度有利,并且由于使用了大规模现场可编程器件,这些逻辑线路的设计和修改变得非常简单易行。

组合逻辑控制器主要由4个部件组成:

程序计数器PC,保存指令在内存中的地址;指令寄存器IR,保存从内存读来的指令内容,在指令执行过程中提供指令本身的主要信息;节拍发生器,用于标记出每条指令的各执行步骤的相对次序关系;控制逻辑,或称时序控制信号产生部件,它根据指令内容(由IR提供)和指令的执行步骤(由节拍发生器提供)及其他一些条件信号(标志寄存器输出),形成并提供出计算机各部件当前时刻要用到的控制信号。

1.5各部分说明

1、各个功能部件及其使用的控制信号:

(1)ALU:

组合逻辑部件,对两个16位的输入及进位输入Cin可进行由3位控制信号控制的如下操作:

I2I1I0

功能

000

A+B+Cin

001

A-B-Cin

010

A与B

011

A或B

100

A异或B

101

B左移

110

B右移

由Quartus生成的.bsf图如下:

查看源文件

其VHDL语言的行为描述如下:

查看源文件

libraryieee;

useieee.std_logic_1164.all;

useieee.std_logic_arith.all;

useieee.std_logic_unsigned.all;

entityaluis--实体描述

port(cin:

instd_logic;

alu_a,alu_b:

instd_logic_vector(15downto0);

alu_func:

instd_logic_vector(2downto0);--控制信号

alu_out:

outstd_logic_vector(15downto0);

c,z,v,s:

outstd_logic);

endalu;

architecturebehaveofaluis--ALU行为描述

begin

process(alu_a,alu_b,cin,alu_func)

variabletemp1,temp2,temp3:

std_logic_vector(15downto0);

begin

temp1:

="000000000000000"&cin;--进位扩展

casealu_funcis--翻译上表中的内容,运算结果都暂存为temp2

when"000"=>

temp2:

=alu_b+alu_a+temp1;

when"001"=>

temp2:

=alu_b-alu_a-temp1;

when"010"=>

temp2:

=alu_aandalu_b;

when"011"=>

temp2:

=alu_aoralu_b;

when"100"=>

temp2:

=alu_axoralu_b;

when"101"=>

temp2(0):

='0';

forIin15downto1loop--循环实现左移

temp2(I):

=alu_b(I-1);

endloop;

when"110"=>

temp2(15):

='0';

forIin14downto0loop--循环实现右移

temp2(I):

=alu_b(I+1);

endloop;

whenothers=>

temp2:

="0000000000000000";

endcase;

alu_out<=temp2;--将temp2赋给输出alu_out

--置标志位Z,判断运算结果是否为0

iftemp2="0000000000000000"thenz<='1';

elsez<='0';

endif;

--置标志位S,判断运算结果的符号位(最高位)

iftemp2(15)='1'thens<='1';

elses<='0';

endif;

--置标志位V,判断运算结果是否溢出

casealu_funcis

when"000"|"001"=>

if(alu_a(15)='1'andalu_b(15)='1'andtemp2(15)='0')or

(alu_a(15)='0'andalu_b(15)='0'andtemp2(15)='1')then

v<='1';

elsev<='0';

endif;

whenothers=>

v<='0';

endcase;

--置标志位C,判断运算结果是否有进位

casealu_funcis

when"000"=>

temp3:

="1111111111111111"-alu_b-temp1;

iftemp3

c<='1';

elsec<='0';

endif;

when"001"=>

ifalu_b

c<='1';

elsec<='0';

endif;

when"101"=>

c<=alu_b(15);

when"110"=>

c<=alu_b(0);

whenothers=>

c<='0';

endcase;

endprocess;

endbehave;

这部分主要要注意的地方就是标志位C和V的数值。

根据参考文献[5],溢出标志位OF:

在运算过程中,如操作数超出了机器能标似的范围称为溢出,此时OF位置1,否则置0。

进位标志CF:

记录运算时从最高有效位产生的进位值,例如,执行加法指令时,最高有效位有进位时置1,否则置0。

(page22~23)后文对此进一步解释说(page59),OF用来表示带符号数的溢出,CF用来表示无符号数的溢出。

根据这一说明,可以这样判断V和C标志位的值:

V:

如果正数(符号位为0)与正数之和为负数(符号位为1),或是负数与负数之和为正数,则发生了溢出,V置1;

C:

两数之和大于111111*********1,则产生了进位,C置1;被减数小于减数,则产生借位,C置1。

注意要使用无符号数的比较符号>、<需包含库函数ieee.std_logic_arith和ieee.std_logic_unsigned。

另外要注意的是,只有算术运算需要考虑进位和溢出标志位,逻辑运算,除非带C移位和循环,否则无需考虑这两个标志位。

(2)数据选择器BUS_MUX:

组合逻辑器件,其输入包括:

源寄存器数据,目标寄存器数据,带符号位扩展的偏移地址,PC,以及从内存读取的立即数、跳转地址等数据。

在3位控制信号的控制下它进行ALU模块A、B端输入的选择:

I5I4I3

ALU_A

ALU_B

000

SR

DR

001

SR

0

010

0

DR

011

OFFSET

PC

100

0

PC

101

0

DATA

由Quartus生成的.bsf图如下:

查看源文件

其VHDL语言的行为描述如下:

查看源文件

libraryieee;

useieee.std_logic_1164.all;

entitybus_muxis--实体描述

port(alu_in_sel:

instd_logic_vector(2downto0);--控制信号

data,pc,offset,sr,dr:

instd_logic_vector(15downto0);

alu_sr,alu_dr:

outstd_logic_vector(15downto0));

endbus_mux;

architecturebehaveofbus_muxis--行为描述

begin

process(alu_in_sel,data,pc,offset,sr,dr)

begin

casealu_in_selis--翻译上表中内容

when"000"=>

alu_sr<=sr;

alu_dr<=dr;

when"001"=>

alu_sr<=sr;

alu_dr<="0000000000000000";

when"010"=>

alu_sr<="0000000000000000";

alu_dr<=dr;

when"011"=>

alu_sr<=offset;

alu_dr<=pc;

when"100"=>

alu_sr<="0000000000000000";

alu_dr<=pc;

when"101"=>

alu_sr<="0000000000000000";

alu_dr<=data;

whenothers=>

alu_sr<="0000000000000000";

alu_dr<="0000000000000000";

endcase;

endprocess;

endbehave;

由于在我们的设计中只有ALU部件有加法器的功能,而对程序计数器的自增并没有再另设一个加法器,故ALU的输入组合情况较多。

在对全部指令的执行步骤进行了分析后,共列出了表中所示的6种情况,故使用了3位控制信号。

(3)器件T1:

组合逻辑器件,用于产生ALU的进位输入Cin,受两位控制信号SCI的选择控制,输入为标志寄存的输出FLAG_C:

SCI

Cin

00

0

01

1

10

FLAG_C

由Quartus生成的.bsf图如下:

查看源文件

其VHDL语言的行为描述如下:

查看源文件

libraryieee;

useieee.std_logic_1164.all;

entityt1is--实体描述

port(flag_c:

instd_logic;

sci:

instd_logic_vector(1downto0);--控制信号

alu_cin:

outstd_logic);

endt1;

architecturebehaveoft1is--实体行为描述

begin

process(sci,flag_c)

begin

casesciis--翻译上表中的内容

when"00"=>

alu_cin<='0';

when"01"=>

alu_cin<='1';

when"10"=>

alu_cin<=flag_c;

whenothers=>

alu_cin<='0';

endcase;

endprocess;

endbehave;

(4)标志寄存器FLAG_REG:

时序逻辑部件,带有清零端RESET,输出只在时钟正跳变时发生变化;接收ALU的标志位输出,在控制信号SST的控制下输出实际需要的标志位:

SST

C

Z

V

S

00

接受ALU的运算结果

01

0

Z

V

S

10

1

Z

V

S

11

C

Z

V

S

由Quartus生成的.bsf图如下:

查看源文件

其VHDL语言的行为描述如下:

查看源文件

libraryieee;

useieee.std_logic_1164.all;

entityflag_regis--实体描述

port(sst:

instd_logic_vector(1downto0);--控制信号

c,z,v,s,clk,reset:

instd_logic;

flag_c,flag_z,flag_v,flag_s:

outstd_logic);

endflag_reg;

architecturebehaveofflag_regis--实体的行为描述

begin

process(clk,reset)

begin

ifreset='0'then--RESET为低电平时寄存器清零

flag_c<='0';

flag_z<='0';

flag_v<='0';

flag_s<='0';

elsifclk'eventandclk='1'then--时钟正跳变来临时

casesstis--翻译上表中的内容

when"00"=>

flag_c<=c;

flag_z<=z;

flag_v<=v;

flag_s<=s;

when"01"=>

flag_c<='0';

when"10"=>

flag_c<='1';

when"11"=>

null;

endcase;

endif;

endprocess;

endbehave;

(5)T2:

组合逻辑器件,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1