《CPU设计实验报告》word版.docx

上传人:b****5 文档编号:7444547 上传时间:2023-01-24 格式:DOCX 页数:12 大小:561.93KB
下载 相关 举报
《CPU设计实验报告》word版.docx_第1页
第1页 / 共12页
《CPU设计实验报告》word版.docx_第2页
第2页 / 共12页
《CPU设计实验报告》word版.docx_第3页
第3页 / 共12页
《CPU设计实验报告》word版.docx_第4页
第4页 / 共12页
《CPU设计实验报告》word版.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

《CPU设计实验报告》word版.docx

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

《CPU设计实验报告》word版.docx

《CPU设计实验报告》word版

CPU设计实验报告

姓名:

学号:

邮箱:

一、实验目的:

1、掌握硬件描述语言VHDL和EDA工具QuartusII;利用VHDL设计16位串行CPU,实现算术和逻辑运算指令、转移指令、访存指令、堆栈指令和控制指令;

2、掌握CPU的调试和测试方法。

二、实验内容:

1、运用硬件描述语言VHDL实现寄存器堆和算数逻辑单元设计、指令集和指令格式、时序设计和整体结构设计、指令译码器的设计、访存单元的设计、调试单元的设计;

2、上机调试。

三、实验步骤:

1、寄存器堆的设计

寄存器堆由16个16位寄存器组成。

其中reset是异步清0端,reset=0时将所有寄存器清0。

dr_sel和sr_sel是目标寄存器和源寄存器编号,dr_out和sr_out输出目标寄存器和源寄存器的内容。

reg_sel指定一个寄存器编号,将该寄存器内容送给reg_out,这两个端口用于调试时观察每个寄存器的值。

reg_en是写允许端。

reg_en=“01”时,在clk的上升沿将from_alu写入dr_sel指定的寄存器;reg_en=“10”时,在clk的上升沿将from_mem写入dr_sel指定的寄存器。

reg_en取其他值时不改变寄存器堆的值。

设计方法:

subtypeWORDisstd_logic_vector(15downto0);

typeREGISTERARRAYisarray(0to15)ofWORD;

signalreg_bank:

REGISTERARRAY

则reg_bank就是我们所需要的寄存器堆。

写寄存器堆的方法:

reg_bank(conv_integer(dr_sel))<=from_alu;

读寄存器堆的方法:

dr_out<=reg_bank(conv_integer(dr_sel));

其中,conv_integer是STD_LOGIC_UNSINGED程序包提供的函数,将标准逻辑矢量转换成整数,作为reg_bank的下标。

2、算数逻辑单元设计

ALU可以实现16种运算。

alu_func是运算功能选择,alu_a和alu_b是两个操作数,c_in是进位标志输入,用于实现ADC和SBB。

alu_o是运算结果,c、s、z、o分别是进位标志,符号标志,零标志和溢出标志。

ALU功能如下图所示:

设计方法:

7条算术运算指令可以调用Quartus提供的模块lpm_add_sub实现。

在库使用说明中增加:

LIBRARYLPM;

USELPM.LPM_COMPONENTS.ALL;

在构造体的ARCHITECTURE和BEGIN关键字之间,用COMPONENT语句声明该模块:

COMPONENTlpm_add_sub

GENERIC(lpm_width:

NATURAL;

lpm_direction:

STRING;

lpm_type:

STRING;

lpm_hint:

STRING);

PORT(dataa:

INSTD_LOGIC_VECTOR(lpm_width-1DOWNTO0);

datab:

INSTD_LOGIC_VECTOR(lpm_width-1DOWNTO0);

cin:

INSTD_LOGIC;

result:

OUTSTD_LOGIC_VECTOR(lpm_width-1DOWNTO0);

cout:

OUTSTD_LOGIC;

overflow:

OUTSTD_LOGIC);

ENDCOMPONENT;

并定义几个信号:

SIGNALaddsub_cin:

STD_LOGIC;

SIGNALaddsub_c:

STD_LOGIC;

SIGNALaddsub_o:

STD_LOGIC;

SIGNALaddsub_a:

STD_LOGIC_VECTOR(15DOWNTO0);

SIGNALaddsub_b:

STD_LOGIC_VECTOR(15DOWNTO0);

SIGNALaddsub_r:

STD_LOGIC_VECTOR(15DOWNTO0);

在构造体中,用GENERICMAP和PORTMAP语句说明lpm_add_sub的连接方式:

ALU_ADDSUB:

lpm_add_sub

GENERICMAP(lpm_width=>16,

lpm_direction=>"ADD",

lpm_type=>"LPM_ADD_SUB",

lpm_hint=>"ONE_INPUT_IS_CONSTANT=NO,CIN_USED=YES")

PORTMAP(dataa=>addsub_a,

datab=>addsub_b,

cin=>addsub_cin,

result=>addsub_r,

cout=>addsub_c,

overflow=>addsub_o);

实现7条算术运算指令时,addsub_a、addsub_b、addsub_cin的取值如下:

按照上述取值方法,addsub_r和addsub_o就是这7条指令的运算结果和溢出标志。

对于ADD和ADC指令,addsub_c就是进位标志,对于SUB、CMP和SBB,应将addsub_c取反后作为进位标志,而INC和DEC不影响进位标志,应将c_in作为进位标志。

三条移位指令的实现方法:

即:

将被移出的位作为进位标志,将移位前后最高位的异或作为溢出标志。

3、标志寄存器的设计

标志寄存器用来保存c,s,z,o四个标志位。

flag_en=“00”时不改变四个标志位;flag_en=“01”时同时保存四个标志位;flag_en=“10”时将进位标志清零,用于实现CLC指令;flag_en=“11”时将进位标志置1,用于实现STC指令。

4、执行单元的设计

将寄存器堆,ALU和标志寄存器连接在一起,构成执行单元。

编译后,为执行单元生成一个图形符号。

5、指令译码单元的设计

指令集共35条指令,其中单字长(16位)指令33条,双字长(32位)指令2条。

双字长指令:

指令编码采用定长操作码,所有指令的操作码都是8位。

为了将汇编指令转换为二进制形式的机器指令,需要编写一个规则文件。

规则文件是一个纯文本文件,以行为单位,每行指定一条汇编指令的机器码。

注释:

以/开头的行是注释。

常量定义:

R0IS0定义了一个常量R0,其值为0

指令格式定义:

包括三个字段,第一字段是指令名,第二字段是操作数声明,第三字段说明如何生成该指令的机器码。

指令译码单元共产生9个控制信号。

dr_sel<=ir(7DOWNTO4);

sr_sel<=ir(3DOWNTO0);

alu_func<=ir(11DOWNTO8);

mem_wr:

为1表示写存储器,为0表示读存储器。

SIGNALOP:

STD_LOGIC_VECTOR(7DOWNTO0);

OP<=ir(15DOWNTO8);

mem_wr<=‘1’WHENS=‘0’ANDOP=“10010000”ELSE--STR指令

‘1’WHENS=‘0’ANDOP=“10100000”ELSE--PUSH指令

'0';

类似地写出以下5个控制信号的代码:

reg_en:

寄存器堆的写允许信号。

flag_en:

标志寄存器的写允许信号。

jmp_relv:

类型为STD_LOGIC

为‘1’表示进行相对转移,为‘0’表示不进行相对转移。

sp_en:

类型为STD_LOGIC_VECTOR(1DOWNTO0)

为“01”表示堆栈指针SP加1,为“10”表示堆栈指针SP减1.

addr_sel:

类型为STD_LOGIC_VECTOR(2DOWNTO0)

用于确定S=0时地址总线上的值。

“000”表示SP,“001”表示SP-1,“010”表示DR,“011”表示SR,“100”表示PC。

6、节拍发生器

节拍发生器用来产生节拍信号S。

reset=0时将S清0;

clk出现上升沿时,若S=0且ir中保存的是HLT指令,则S继续为0,CPU进入死锁状态;否则对S取反。

7、访存单元的设计

data_bus连接数据总线,端口方向为INOUT;wr连接存储器的读写控制端;addr_bus连接地址总线。

访存单元的内部结构:

 

IR:

指令寄存器。

取指时将数据总线上传来的指令锁存进IR。

初始化时可以向IR存入NOP指令。

SP:

堆栈指针。

执行堆栈指令后根据sp_en的值对SP进行修改。

初始化时向SP存入0280H。

PC:

程序计数器

SIGNALOP:

STD_LOGIC_VECTOR(7DOWNTO0);

SIGNALoffset:

STD_LOGIC_VECTOR(15DOWNTO0);

OP<=ir(15DOWNTO8);

offset<=“11111111”&ir(7DOWNTO0)WHENir(7)='1'ELSE

“00000000”&ir(7DOWNTO0);--将偏移量扩展为16位

PROCESS(reset,clk)

VARIABLEtmp:

STD_LOGIC_VECTOR(15DOWNTO0);

BEGIN

IFreset='0'THEN

tmp:

=x“0000”;

ELSIFclk'EVENTANDclk='1'THEN

IFS='1'THEN--取指令之后PC加1

tmp:

=tmp+1;

ELSIFjmp_relv='1'THEN--进行相对转移

tmp:

=tmp+offset;

ELSIFOP=“11000000”THEN--JMPA指令

tmp:

=data_bus;

ELSIFOP=“11010000”THEN--MVRD指令

tmp:

=tmp+1;

ENDIF;

ENDIF;

pc<=tmp;

ENDPROCESS;

存储器地址选择:

PROCESS(reset,S,addr_sel,sp,dr,sr,pc)

VARIABLEtmp:

STD_LOGIC_VECTOR(15DOWNTO0);

BEGIN

IFreset='0'THEN

tmp:

=x“0000”;

ELSIFS='1'THEN--取指令

tmp:

=pc;

ELSE

IFaddr_sel=“000”THEN--PUSH

tmp:

=sp;

ELSIFaddr_sel=“001”THEN--POP

tmp:

=sp-1;

ELSIFaddr_sel=“010”THEN--STR

tmp:

=dr;

ELSIFaddr_sel=“011”THEN--LDR

tmp:

=sr;

ELSIFaddr_sel=“100”THEN--双字长指令

tmp:

=pc;

ELSE

tmp:

=“XXXXXXXXXXXXXXXX”;

ENDIF;

ENDIF;

addr_bus<=tmp;

ENDPROCESS;

存储器读写控制:

--mem_wr=‘1’:

wr<=clk,写存储器

--mem_wr=‘0’:

wr<=‘1’读存储器

PROCESS(clk,mem_wr,data_bus,sr)

BEGIN

IFmem_wr=‘1’THEN--写存储器(STR指令,PUSH指令)

data_bus<=sr;

wr<=clk;

ELSE--读存储器

data_bus<=“ZZZZZZZZZZZZZZZZ”;

wr<='1';

mem_data<=data_bus;

ENDIF;

ENDPROCESS;

8、调试单元的设计

调试单元是一个多路选择器,用于在调试过程中观察CPU内部主要寄存器的值。

reg_sel是数据选择端。

取63时将ir送到输出;取62时将pc送到输出;取16时将sp送到输出;取0~15时,将来自寄存器堆的reg送到输出。

调试过程中,调试程序debugcontroller会在reg_sel输入端循环地输入0~63,并将调试单元的输出在程序界面上进行显示。

寄存器堆和调试单元的连接关系:

将reg_sel[5..0]的最低四位reg_sel[3..0]送给寄存器堆的寄存器选择端,将寄存器堆的输出端reg_out作为调试单元的输入端reg。

当reg_sel[5..0]的最高两位为“00”,而最低四位在0到15之间变化时,debug_out输出的恰好是寄存器R0到R15。

 

9、上机调试

上机调试步骤:

将exe_unit,id_unit,mem_unit,timer,debug_unit连接成完整的CPU:

CPU外部端口包括:

输入端:

reset,clk,reg_sel[5..0]

输出端:

addr_bus[15..0],debug_out[15..0],wr,c_flag,z_flag,s_flag,o_flag

输入输出端:

data_bus[15..0]

共61个引脚。

芯片类型:

Cyclone家族的EP1C6Q240C8

引脚分配:

reset:

240clk:

29wr:

75

c_flag:

86z_flag:

85s_flag:

83o_flag:

84

reg_sel[5..0]:

17,16,15,14,13,12

addr_bus[15..0]:

64,63,62,61,60,59,58,57,48,47,46,45,44,43,42,41

data_bus[15..0]:

237,236,235,234,226,225,224,223,217,216,215,214,203,202,201,200

debug_out[15..0]:

181,180,179,178,177,175,174,173,165,164,163,162,161,160,159,158

然后将以上程序下载到实验箱芯片中;

设置实验箱:

SW22接USB,REGSEL接1,CLKSEL接0,FDSEL接1

调试步骤:

1.打开规则文件

2.打开汇编源文件

3.CompileCode

4.UploadBIN

5.CPU复位

6.BeginDebug

7.运行程序,可以选择半时钟周期运行、单时钟周期运行或运行至断点(双击某一行可以设置断点)。

运行过程中通过RegWindow观察CPU内部各寄存器的值。

8.EndDebug

四、实验心得:

通过对本门课程的学习,复习巩固了硬件描述语言VHDL;掌握了工具QuartusII的使用;深入了解了CPU的基本结构和原理;掌握了测试和调试的步骤。

非常感谢在实验过程中给予帮助的老师和同学,是我能顺利完成实验。

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

当前位置:首页 > IT计算机 > 计算机硬件及网络

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

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