组成原理8位模型机的设计精编版.docx
《组成原理8位模型机的设计精编版.docx》由会员分享,可在线阅读,更多相关《组成原理8位模型机的设计精编版.docx(26页珍藏版)》请在冰豆网上搜索。
组成原理8位模型机的设计精编版
计算机组成原理课程设计报告
题目8位模型计算机的设计
姓名
学号
班号
指导老师
成绩
1.课程设计目的3
2.开发工具选择3
3.方案选择3
4.指令系统设计4
5.模型机框图设计5
6.指令流程图6
7.微指令格式(微程序控制器)设计7
8.微程序(微程序控制器)设计7
9.VHDL实现9
10.调试仿真16
11.课程设计回顾总结19
参考文献19
附录………………………………………………………………………………………………19
1.课程设计目的
(1)、计算机组成原理课程设计的主要任务是让学生通过动脑和动手解决计算机设计中的实际问题。
综合运用所学计算机组成原理知识,在掌握部件单元电路实验的基础上,进一步将其组成系统构造一台基本的模型计算机,掌握整机概念,并设计机器指令系统,编写程序,在所设计的模型计算机上调试运行。
(2)、通过一台模型机的设计过程,明确计算机的控制原理与控制过程,巩固和灵活应用所学的理论知识,掌握计算机组成的一般设计方法,提高学生设计能力和实践操作技能,为从事计算机研制与设计打下基础。
2.开发工具选择
以TEC-CA教学实验系统为平台,采用硬件描述语言VHDL为设计工具,应用QUARTUSⅡ5.1环境进行大规模集成电路的功能设计仿真。
3.方案选择
实习的内容为八位模型计算机的设计,为单总线,微程序控制方式,设置两种寻址方式:
直接寻址(“0”)和寄存器寻址(“1”)。
微程序控制方式由微指令译码产生。
微程序中一条机器指令往往分成几步执行,将每一步操作所需的若干为命令以代码编写在一条微指令中,若干条微指令组成一段微程序,对应一条机器指令。
然后根据系统的需要,事先编制各段微程序,将它存入控制存储器(CM)中。
微程序执行过程:
(1)从控存中逐条取出“取指令操作”,执行取指令公共操作。
(2)根据指令的操作码,经过微地址形成部件,得到这条指令的入口地址,并送入微地址寄存器中。
(3)从控存中逐条的取出对应的微指令并执行。
(4)执行完一条机器指令对应的微程序后又回到取指微程序的入口地址,继续第
(1)步,以完成取下一条机器指令的公共操作。
微程序控制基本框图:
4.指令系统设计
所要设计的微程序控制器是由七条指令来完成的,即:
sta,add,sub,and1,jmp,shl,nop。
实现功能分别如下:
sta指令实现存操作;
add指令实现加法操作;
sub指令实现减法操作;
and1指令实现与操作;
jmp指令实现无条件跳转操作;
shl指令实现逻辑左移操作;
nop指令实现空操作。
75410
操作码
寻址方式
标志位
模拟机采用了定长的指令格式,每条指令字长为8位。
采用的寻址方式为直接寻址和寄存器寻址,标志位为“0”时为直接寻址,为“1”时为寄存器寻址。
操作码类型及编码方式如下:
操作码
sta
add
sub
and1
jmp
shl
nop
编码方式
000
001
010
011
100
101
110
含义
传送
加
减
与
跳转
逻辑左移
空
5.模型机框图设计
模拟机数据通路如下图所示,模型机采用单总线结构,主要包括运部件ALU,以及程序计数器PC、累加器ACC、指令寄存器IR、数据寄存器MDR、地址寄存器MAR和通用寄存器R,RAM为内存。
控制信号
ALU
图2模拟机数据通路
(1)寄存器的位数
所有的寄存器都均为8位:
1 通用寄存器R。
该模拟机有1个通用寄存器,用于寄存器寻址时存放结果,提供操作数。
2 指令寄存器IR。
为了提高取指令的速度,将指令从内存中读出,经数据总线直接置入IR。
3
数据寄存器MDR、地址寄存器MAR。
地址寄存器MAR提供访问主存的地址;数据寄存器MDR,把从内存取出的数据暂存于MDR中,在用到该数据进行运算时,再从MDR中取出数据进行运算。
4 程序计数器PC。
用于存放下一条指令的内存地址。
(2)总线宽度:
该模拟机只有一条总线,且总线宽度为8位。
(3)ALU位数及运算功能
ALU可以实现8位操作数的运算,即ALU的位数为8位。
ALU运算功能为:
加(001:
add)、减(010:
sub)、逻辑与(011:
and)、左移(101:
shl)、跳转(100:
jmp)、空(110:
nop)。
(4)微命令的设置(各标识的含义)
6.指令流程图
指令的流程图如图3所示,共有8条指令,每条指令都要经过取指令、分析指令和执行指令3个步骤。
在取指令阶段,8条指令是一样的,首先程序计数器PC的内容通过总线送入地址寄存器MAR,存储信息,PC+1传送给PC,把读出的内容传送给指令寄存器IR。
再接下来的操作中,根据不同的指令,执行顺序也不同。
7.微指令格式(微程序控制器)设计
微指令格式设计如表1:
控制信号
描述
ACC_bus
用ACC的内容驱动总线
load_ACC
将总线上的数据载入ACC
PC_bus
用PC的内容驱动总线
load_IR
将总线上的数据装载至IR
load_MAR
将总线上的数据装载至MAR
MDR_bus
用MDR的内容驱动总线
ALU_ACC
用ALU的结果装载ACC
INC_PC
PC+1并将结果存至PC中
Addr_bus
用IR指令中的地址部分驱动总线
CS
片选。
用MAR的内容设置存储器地址
R_NW
读取,不可写。
当R_NW无效且CS有效时,MBR的内容存储于存储器中
Reg_bus
用寄存器R的内容驱动总线
load_Reg
将总线上的数据装载至R
ALU_ADD
在ALU中执行逻辑加操作
ALU_SUB
在ALU中执行减操作
ALU_AND
在ALU中执行与操作
ALU_SHL
在ALU中执行左移操作
表2微指令格式
8.微程序(微程序控制器)设计
根据微处理器的数据通路和指令系统,可得出微程序的流程图如图4所示。
微程序的编码采用直接编码方法,每一个控制信号对应一位,共有17个控制信号,根据微指令格式把相关的控制信号整合到一起进行编码。
微程序流程图的下地址,可知共有25条微指令,表2给出了该模拟机微程序的编码。
地址3的下地址,应该根据指令操作码来和寻址方式形成,所以将其下地址设为11111,表示如果下地址为11111时,且寻址方式标志位为0(即立即寻址),则下地址应为01&指令的操作码,若寻址方式标志位为1(即寄存器寻址),则下地址应为10&指令的操作码。
该模拟机微程序的编码如下
0=>0000010100010000000001
1=>0000000000000110000010
2=>0000001010000000000011
3=>0000000100001000011111
4=>0000000000000110000110
5=>0000000000000110000111
6=>0000100010000000000000
7=>0001000010000000000000
8=>0000000000000000011011
9=>0000000000000000011100
10=>0000000000000000010010
11=>0000000000000000010100
12=>0000000000000000010110
13=>0000000000000000011001
14=>0000000000000110000000
15=>0000000000000110010001
16=>0000000010100001000000
010*********
18=>0000000000000110010011
19=>0000000010100000100000
20=>0000000000000110010101
21=>0000000011100000000000
22=>0000000000000110011101
23=>0010000010000000000000
24=>0000000000000000000000
25=>1000000000100000000000
9.VHDL实现
头文件cpu_defs.vhd如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
PACKAGEcpu_defsIS
TYPEopcodeIS(sta,add,sub,and1,jmp,shl,nop);
CONSTANTword_w:
NATURAL:
=8;
CONSTANTop_w:
NATURAL:
=3;
CONSTANTrfill:
STD_LOGIC_VECTOR(op_w-1downto0):
=(others=>'0');
--FUNCTIOnslv2op(slv:
INSTD_LOGIC_VECTOR)RETURNopcode;
FUNCTIONop2slv(op:
inopcode)RETURNSTD_LOGIC_VECTOR;
ENDPACKAGEcpu_defs;
PACKAGEBODYcpu_defsIS
TYPEoptableISARRAY(opcode)OFSTD_LOGIC_VECTOR(op_w-1DOWNTO0);
CONSTANTtrans_table:
optable:
=("000","001","010","011","100","101","110");
FUNCTIONop2slv(op:
INopcode)RETURNSTD_LOGIC_VECTORIS
BEGIN
RETURNtrans_table(op);
ENDFUNCTIONop2slv;
--functionslv2op(slv:
instd_logic_vector)returnopcodeis
--variabletransop:
opcode;
--begin
--foriinopcodeloop
--ifslv=trans_table(i)then
--transop:
=i;
--endif;
--endloop;
--returntransop;
--endfunctionslv2op;
ENDPACKAGEBODYcpu_defs;
源程序cpu.vhd如下:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL,IEEE.NUMERIC_STD.ALL;
USEWORK.CPU_DEFS.ALL;
ENTITYCPUIS
PORT(clock:
INSTD_LOGIC;
reset:
INSTD_LOGIC;
mode:
INSTD_LOGIC_VECTOR(2DOWNTO0);
mem_addr:
INUNSIGNED(word_w-op_w-1DOWNTO0);
output:
OUTSTD_LOGIC_VECTOR(word_w-1DOWNTO0);
data_r_out:
OUTSTD_LOGIC_VECTOR(21DOWNTO0);
op_out:
OUTSTD_LOGIC_VECTOR(op_w-1DOWNTO0);
add_r_out:
OUTUNSIGNED(4DOWNTO0)
);
ENDENTITY;
ARCHITECTURErtlOFCPUIS
TYPEmem_arrayISARRAY(0TO2**(word_w-op_w)-1)OFSTD_LOGIC_VECTOR(word_w-1DOWNTO0);
SIGNALmem:
mem_array;
CONSTANTprog:
mem_array:
=(
0=>op2slv(sta)&STD_LOGIC_VECTOR(TO_UNSIGNED(9,word_w-op_w-1))&'0',
1=>op2slv(sta)&STD_LOGIC_VECTOR(TO_UNSIGNED(10,word_w-op_w-1))&'1',
2=>op2slv(add)&STD_LOGIC_VECTOR(TO_UNSIGNED(9,word_w-op_w-1))&'1',
3=>op2slv(sub)&STD_LOGIC_VECTOR(TO_UNSIGNED(10,word_w-op_w-1))&'0',
4=>op2slv(and1)&STD_LOGIC_VECTOR(TO_UNSIGNED(10,word_w-op_w-1))&'0',
5=>op2slv(shl)&STD_LOGIC_VECTOR(TO_UNSIGNED(10,word_w-op_w-1))&'0',
6=>op2slv(nop)&STD_LOGIC_VECTOR(TO_UNSIGNED(9,word_w-op_w-1))&'0',
7=>op2slv(sta)&STD_LOGIC_VECTOR(TO_UNSIGNED(11,word_w-op_w-1))&'0',
8=>op2slv(jmp)&STD_LOGIC_VECTOR(TO_UNSIGNED(12,word_w-op_w-1))&'0',
9=>STD_LOGIC_VECTOR(TO_UNSIGNED(2,word_w)),
10=>STD_LOGIC_VECTOR(TO_UNSIGNED(3,word_w)),
OTHERS=>(OTHERS=>'0'));
TYPEmicrocode_arrayISARRAY(0TO25)OFSTD_LOGIC_VECTOR(21DOWNTO0);
CONSTANTcode:
microcode_array:
=(
0=>"0000010100010000000001",
1=>"0000000000000110000010",
2=>"0000001010000000000011",
3=>"0000000100001000011111",
4=>"0000000000000110000110",
5=>"0000000000000110000111",
6=>"0000100010000000000000",
7=>"0001000010000000000000",
8=>"0000000000000000011011",
9=>"0000000000000000011100",
10=>"0000000000000000010010",
11=>"0000000000000000010100",
12=>"0000000000000000010110",
13=>"0000000000000000011001",
14=>"0000000000000110000000",
15=>"0000000000000110010001",
16=>"0000000010100001000000",
17=>"0100000000100001000000",
18=>"0000000000000110010011",
19=>"0000000010100000100000",
20=>"0000000000000110010101",
21=>"0000000011100000000000",
22=>"0000000000000110011101",
23=>"0010000010000000000000",
24=>"0000000000000000000000",
25=>"1000000000100000000000");
SIGNALcount:
UNSIGNED(word_w-op_w-1DOWNTO0);
SIGNALop:
STD_LOGIC_VECTOR(op_w-1DOWNTO0);
SIGNALz_flag:
STD_LOGIC;
SIGNALmdr_out:
STD_LOGIC_VECTOR(word_w-1DOWNTO0);
SIGNALmar_out:
UNSIGNED(word_w-op_w-1DOWNTO0);
SIGNALIR_out:
STD_LOGIC_VECTOR(word_w-1DOWNTO0);
SIGNALacc_out:
UNSIGNED(word_w-1DOWNTO0);
SIGNALsysbus_out:
STD_LOGIC_VECTOR(word_w-1DOWNTO0);
BEGIN
PROCESS(reset,clock)
VARIABLEinstr_reg:
STD_LOGIC_VECTOR(word_w-1DOWNTO0);
VARIABLEacc:
UNSIGNED(word_w-1DOWNTO0);
CONSTANTzero:
UNSIGNED(word_w-1DOWNTO0):
=(OTHERS=>'0');
VARIABLEmdr:
STD_LOGIC_VECTOR(word_w-1DOWNTO0);
VARIABLEreg:
STD_LOGIC_VECTOR(word_w-1DOWNTO0);
VARIABLEmar:
UNSIGNED(word_w-op_w-1DOWNTO0);
VARIABLEsysbus:
STD_LOGIC_VECTOR(word_w-1DOWNTO0);
VARIABLEmicrocode:
microcode_array;
VARIABLEadd_r:
UNSIGNED(4DOWNTO0);
VARIABLEdata_r:
STD_LOGIC_VECTOR(21DOWNTO0);
VARIABLEtemp:
STD_LOGIC_VECTOR(4DOWNTO0);
BEGIN
IFreset='0'THEN
add_r:
=(OTHERS=>'0');
count<=(OTHERS=>'0');
instr_reg:
=(OTHERS=>'0');
acc:
=(OTHERS=>'0');
mdr:
=(OTHERS=>'0');
reg:
=(OTHERS=>'0');
mar:
=(OTHERS=>'0');
z_flag<='0';
mem<=prog;
sysbus:
=(OTHERS=>'0');
ELSIFRISING_EDGE(clock)THEN
--microprogramcontroller
data_r:
=code(TO_INTEGER(add_r));
IFdata_r(4DOWNTO0)="11111"THEN--判断下地址
temp:
="01"&op(2DOWNTO0);
add_r:
=UNSIGNED(temp);
ELSIFdata_r(4DOWNTO0)="11011"THEN
IFIR_out(0)='1'THEN
add_r:
="00101";
ELSE
add_r:
="00100";
ENDIF;
ELSIFdata_r(4DOWNTO0)="11100"THEN
IFIR_out(0)='1'THEN
add_r:
="10001";
ELSE
add_r:
="01111";
ENDIF;
ELSIFdata_r(4DOWNTO0)="11101"THEN
IFz_flag='1'THEN
add_r:
="10111";
ELSE
add_r:
="11000";
ENDIF;
ELSE
add_r:
=UNSIGNED(data_r(4DOWNTO0));
ENDIF;
data_r_out<=data_r;
add_r_out<=add_r;
--PC
IFdata_r(16)='1'THEN--PC_bus='1'
sysbus:
=rfill&STD_LOGIC_VECTOR(count);
ENDIF;
IFdata_r(19)='1'THEN--load_PC='1'
count<=UNSIGNED(mdr(word_w-op_w-1DOWNTO0));
ELSIFdata_r(10)='1'THEN--INC_PC='1'
count<=count+1;
ELSE
count<=count;
ENDIF;
--IR
IFdata_r(15)='1'THEN--load_IR
instr_reg:
=mdr;
ENDIF;
IFdata_r(9)='1'THEN--Addr_bus='1'
sysbus:
='0'&rfill&instr_reg(word_w-op_w-1DOWNTO1);
ENDIF;
op<=instr_reg(word_w-1DOWNTOword_w-op_w);
IR_out