此次CPU实验,我应该是最早验收的,所以在此分享给大家,少走弯路。
CPU资源https://download.csdn.net/download/tian246319/14014833
一、设计目的
完整、连贯地运用《数字逻辑》所学到的知识,熟练掌握 EDA 工具基本使用方法,为
学习好后续《计算机原理》课程做铺垫。
二、设计内容
1、按照给定的数据通路、数据格式和指令系统,使用 EDA 工具设计一台用硬连线逻
辑控制的简易计算机;
2、要求灵活运用各方面知识,使得所设计的计算机具有较佳的性能;
3、对所设计计算机的性能指标进行分析,整理出设计报告。
详细设计
3.1设计的整体架构
(1)普通部件
1、指令计数器PC
2、选择器
3、RAM存储器
4、指令寄存器IR
5、指令译码器
6、(图中无标出)控制台,用于发出控制信号
7、通用寄存器组
8、函数发生器(ALU运算器)
9、移位逻辑
(2)数据通路
部件之间联系和指令执行的一般流程
取指令:
1、首先通过时钟信号对PC发出指令,将PC中的地址通过选择器传递到RAM。
2、RAM根据PC传来的地址,执行存储在RAM中的指令,将指令输入到总线。
3、总线上的指令寄存器IR在控制信号的控制下读入RAM传来的指令。
4、指令寄存器IR将指令发送到指令译码器,指令通过指令译码器和控制台输出指令所需要的所有控制信号。
执行指令:
数据传送类指令的执行过程
寄存器之间的传送
MOV R1,R2
要求完成的操作为(R2)→R1,执行过程为:
由 R2 的编码通过 RAA1、RAA0 从通用寄存器组 A 口读出 R2 的内容,在 S3~S0 和
M的控制下,经 ALU 送入总线 BUS;由/WE 控制和 R1 的编码选择 RWBA1、RWBA0,将BUS
上的数据写入通用寄存器 R1。
寄存器到内存的传送
MOV M,R2
要求完成的操作为(R2)→(C),执行过程为:
由 M 的编码 11 通过 RWBA1、RWBA0 从通用寄存器 B 口读出 C
寄存器中的地址,在MADD=2 的控制下,地址通过选择器到达存储器 RAM 的地址输入端;由
R2 的编码通过RAA1、RAA0 从通用寄存器组 A 口读出 R2 的内容,在 S3~S0 和 M
的控制下,经 ALU 送入总线 BUS,并在/CS 和 XL 控制下将 BUS 上的数据写入存储器
RAM。
内存到寄存器的传送
MOV R1,M
要求完成的操作为((C))→R1,执行过程为:
由 M 的编码 11 通过 RAA1、RAA0 从通用寄存器 A 口读出 C 寄存器中的地址,在
MADD=1 的控制下,地址通过选择器到达存储器 RAM 的地址输入端,/CS 和 DL
使数据出现在 BUS 上;由/WE 控制和 R1 的编码选择 RWBA1、RWBA0,将 BUS
上的数据写入通用寄存器 R1。
算术逻辑运算类指令的执行过程
ADD R1,R2
SUB R1,R2
OR R1,R2
这类指令的执行过程为:
由 R2 的编码通过 RAA1、RAA0 从通用寄存器组 A 口读出 R2 的内容,由 R1 的编码通过
RWBA1、RWBA0 从通用寄存器组 B 口读出 R1 的内容,在 S3~S0 和 M 的控制下,经ALU
送入总线 BUS;由/WE 控制和 R1 的编码选择 RWBA1、RWBA0,将 BUS
上的数据写入通用寄存器 R1。其中 ADD 和 SUB 指令影响状态位 Zf和 Cf。
移位指令的执行过程
RSR R1
RSL R1
这类指令的执行过程为:
由 R1 的编码通过 RWBA1、RWBA0 从通用寄存器组 B 口读出 R1 的内容,在 S3~S0和 M
的控制下通过 ALU,经移位逻辑循环右移或循环左移后送入总线 BUS;再由/WE 控制和 R1
的编码选择 RWBA1、RWBA0,将 BUS 上的数据写入通用寄存器 R1。
一条指令执行完毕,RAM读取下一条指令。
转移类指令的执行过程
JMP add
JZ add
JC add
这类指令为双字节指令,第一字节为指令码,第二字节为转移目标地址。这类指令的执
行过程为:
在 MADD=0 的控制下,程序计数器 PC 中的地址通过选择器到达存储器 RAM
的地址输入端,在/CS 和 DL 控制下转移地址从 RAM 中读出并送入
BUS;如果条件满足(IN PC=0,LDPC=1)则在 LD PC 允许下将 BUS 上的数据输入
PC,作为PC下一次的输出,否则 PC 加 1 计数,并作为下一次的输出。
3.2各模块的具体实现
(此部分必须有模块的接口设计,功能实现,功能的仿真验证等内容。)
接口设计:
(1)inc,ld两个信号输入,代表控制计数器自加一和数据输出以及读入的信号。
(2)clk时钟信号,接受外部时序控制执行操作。
(3)a[7…0]和c[8…0],前者代表数据读入,后者代表输出。
原理图
VHDL代码:
仿真波形:
功能分析:
CLK | inc | ld | 功能 |
---|---|---|---|
1 | 0 | c<=c+1(不加载输入,输出自加一) | |
0 | 1 | c<=a(加载输入) |
原理图
接口设计:
(1)madd是2位控制信号,用于选择地址来源。
(2)R1,R2,R3是三个地址来源,对应PC、寄存器A口和寄存器B口。
VHDL代码:
仿真波形:
功能分析:
madd | 功能 |
---|---|
00 | selout<=RO(选择R0输出) |
01 | selout<=R1(选择R1输出) |
10 | selout<=R2(选择R2输出) |
接口设计:
(1)使用address输入和dio输出,都是8位,输入为地址,输出为指令,指令存储在RAM中。
(2)有we、outenab控制信号,代表读写有效。
(3)有时钟控制信号,对RAM的读取写入进行流程控制。
功能分析
(1)RAM是存储各种指令的地方,可以进行指令的读写。
(2)构造RAM中的指令,需要在新建文件里面建立一个mif文件,设定好参数(256个,8位)根据指令表构造指令存入即可。
(3)RAM也有时钟信号,配合其他元件,用于控制RAM何时进行读写操作。
VHDL代码:
调用了LPM库,略
功能分析:
CLK | we | outenab | 功能 |
---|---|---|---|
0 | 0 | Dio<=高阻态Z | |
1 | 0 | Dio的数据写入address所指定的存储单元 | |
0 | 1 | address所指定的存储单元数据从dio输出 |
接口设计:
(1)input是8位的输入,output是8位的输出。
(2)ld代表将BUS总线上的数据传输入译码器,1有效。
(3)clk时钟信号接口,这个部件也需要时序控制。
功能分析:
clk | ld | 功能 |
---|---|---|
1 | output<=input |
接口设计:
(1)输入的IR是8位的指令,SM为时钟信号。
(2)输出对应的是各个指令所需要的操作,传输入控制台具体执行
VHDL代码:
**
功能分析:
指令译码器的功能就是对于输入的各种指令进行读取分析,输出一系列的控制信号。
接口设计:
包括输入的信号,以及所有指令译码器传过来的指令信号,由控制器具体执行发出信号。
波形仿真:
功能分析:
将M信号改成了,M=1时在ALU中进行操作,M=0时选择输入进行直传。
接口设计:
(1)i是8位的输入,AO,BO,AR,BR,CR是8位的输出。(AR、BR、CR输出的分别是A寄存器、B寄存器和C寄存器的值,AO、BO输出的分别根据RA和WA的值决定)
(2)we代表将BUS总线上的数据传输入寄存器组,0有效。
(3)clk时钟信号接口,这个部件也需要时序控制。
功能分析:
CLK | WE | RAA[1…0] | RWBA[1…0] | 功能 |
---|---|---|---|---|
1 | 00或01或10 | 00或01或10 | 根据RAA[1…0]的值从A,B,C中选择一个寄存器的值由AO口输出 如RAA[1…0]=00,AO<=A寄存器的值 RAA[1…0]=01,AO<=B寄存器的值 RAA[1…0]=10,AO<=C寄存器的值 根据RWBA[1…0]的值从选择A,B,C中选择一个寄存器的值由BO口输出, 如RWBA[1…0]=00,BO<=A寄存器的值 RWBA[1…0]=01,BO<=B寄存器的值 RWBA[1…0]=10,BO<=C寄存器的值 | |
0 | XX | 00或01或10 | 根据RWBA[1…0]的值,将外部输入写入A,B,C三个寄存器中的一个寄存器内。 |
接口设计:
(1)使能端信号en,为0直传,为1计算。
(2)4位控制信号S,代表ALU执行的各种操作。
(3)A,B,output三个8位接口,代表通用寄存器AO、BO口传来的数据和ALU的运算结果。
(4)C输出代表进位,Z输出代表运算结果。结果为00000000时输出1,否则为0,在跳转指令中起作用。
VHDL代码:
功能分析:
ALU的功能主要是实现加、减、或等运算,由S控制,另外ALU作为数据通路,在特定的指令下,也执行直传操作,直传的数据来源可能有两个,AO口和BO口。这里的ALU我定义了两个新的控制信号S,是“1100”和“0000”。这两个指令,在指令表中没有定义,这里额外定义不会冲突。前者表示直传B,后者表示直传A。
S | en | 功能 |
---|---|---|
1001 | 1 | output<=A+B(ADD) |
0110 | 1 | output<=A-B(SUB) |
1011 | 1 | output<=A∨B(OR) |
1110 | 1 | output<=A∧B(AND) |
0101 | 1 | output<=/A(NOT) |
0000 | 0 | output<=A(直传A) |
1100 | 0 | output<=B(直传B) |
接口设计:
(1)INPUT和OUTPUT是8位的输出和输出。
(2)三个控制信号:FBUS为1则直传,FR为1右移,FL为1左移。
(3)C代表被移除的那一位,即左移时输出原最左一位,右移时输出原最右一位。
VHDL代码:
波形仿真:
功能分析:
移位逻辑部件的功能类似于ALU,也是两方面:一方面根据信号控制进行数据的处理,左移和右移,并将移除的位输出;另一方面作为数据通路,在特殊信号控制下进行直传。
F_BUS | FL | FR | 功能 |
---|---|---|---|
1 | 0 | 0 | 直传 |
0 | 1 | 0 | 循环左移一位 |
0 | 0 | 1 | 循环右移一位 |
0 | 0 | 0 | 输出高阻态 |
接口设计:
C的来源有ALU和移位逻辑,Z的来源是ALU。
原理图:
VHDL代码:
功能分析:
clk | en | 功能 |
---|---|---|
1 | out<=in |
(1)两个输入,clk是时钟信号,HALT使能端控制信号。
(2)输出为时钟信号,受到控制信号影响。
功能分析:
这是一个停机操作,加在时钟信号传入电路之前。
HALT | 功能 |
---|---|
1 | clock<=Z |
0 | clock<=clk |
接口分析:
1个8位输入,连接总线,1个使能端,1个8位输出,使能端为1,传输总线数据至输出,灯发光,使能端为0,输出高阻态。
VHDL代码:
功能分析:
en | 功能 |
---|---|
1 | output<=input |
0 | output<=Z |
VHDL代码:
sm=0为取指令周期,sm=1为执行指令周期。
系统测试
4.1 测试环境
Quartus II 9.0 仿真类型:Functional
4.2 测试代码
测试一:
测试二:
IN指令,0.0-10.0ns取指令,10.0-20.0ns执行指令,指令编码为00100000,将总线上的输入加载入寄存器A,此时总线上的输入为11000000,故执行完这个指令后寄存器A的存储的值由初始值00000000变为11000000;
OUT指令,20.0-30.0ns取指令,30.0-40.0ns执行指令,指令编码为01000000,将寄存器A中的值输出到发光二极管,由于没有线路板原件,故只能模拟,输出到总线为寄存器A中的值11000000;
ADD指令,40.0-50.0ns取指令,50.0-60.0ns执行指令,指令编码为10010001,将寄存器A中的值11000000和寄存器B中的值00000001相加后存入寄存器A,故执行完这个指令后寄存器A中的值变为11000001;
OR指令,60.0-70.0ns取指令,70.0-80.0ns执行指令,指令编码为10110010,将寄存器A中的值11000001和寄存器C中的值00000010按位相或后存入寄存器A,故执行完这个指令后寄存器A中的值仍为11000011;
NOT指令,80.0-90.0ns取指令,90.0-100.0ns执行指令,指令编码为01010000,将寄存器A中的值11000011按位取反后存入寄存器A,故执行完这个指令后寄存器A中的值变为00111100;
MOVA指令,100.0-110.0ns取指令,110.0-120.0ns执行指令,指令编码为11110100,将寄存器A中的值存入寄存器B,故执行完这个指令后寄存器B中的由00000001变为00111100;
SUB指令,120.0-130.0ns取指令,130.0-140.0ns执行指令,指令编码为01100001,将寄存器A中的值减去寄存器B中的值后得到的结果存入寄存器A,故执行完这个指令后寄存器A的值变为00000000,此时结果为0,Z标志位为1;
JZ指令,140.0-150.0ns取指令,150.0-160.0ns执行指令,指令编码为00010001,满足跳转条件,后面跟的address编码为00011000,下一次取指令的地址将变为00011000;
MOVC指令,160.0-170.0ns取指令,170.0-180.0ns执行指令,指令编码为11110111,从寄存器C中读出地址00000010,将RAM中该地址的值10010001存入寄存器B中,故执行完这个指令后寄存器B的值由01000000变为10010001;
HALT指令,180.0-190.0ns取指令,因为是停机指令,所以不需要等到下一个下降沿,指令编码为10000000,总线数据全为高阻态,后序指令都不将读取和执行。
上述指令操作结果均符合预期。
(2)RSL指令:20.0-30.0ns取指令,30.0-40.0ns执行指令,指令编码为10101011,将寄存器C中的值循环左移一位,故执行完这个指令后寄存器C中的值由00000010变为00000100;
(3)RSR指令:40.0-50.0ns取指令,50.0-60.0ns执行指令,指令编码为10100100,将寄存器B中的值循环右移一位,故执行完这个指令后寄存器B中的值由00000001变为10000000,且C标志位变为1;
(4)JC指令:60.0-70.0ns取指令,70.0-80.0ns执行指令,指令编码为00010010,满足跳转条件,后面跟的address为00100100,故下一次取指令的地址将变为00100100;
(5)MOVB指令:80.0-90.0取指令,90.0-100.0执行指令,指令编码为11111100,读出寄存器A中的值00000000和寄存器C中的值00000100,将寄存器A的值写入RAM中地址为寄存器C中的值的单元,由下一条JMP指令检测其正确性。
(6)JMP指令:100.0-110.0取指令,110.0-120.0执行指令,指令编码为00010000,后面跟的地址为00000100,故下一次取指令的地址将变为00000100;
可观测到下一次取出的指令为00000000,而不是mif文件中00000100对应的00010010正是上次MOVB指令造成的结果。
上述指令操作结果均符合预期。
信安应怜儿和你一起努力~