一、课程设计的题目
二、嵌入式CISC模型机数据通路框图
三、微程序控制器(CISC模型机)的逻辑结构框图
四、模型机的指令系统和指令格式
五、机器指令的微程序流程图
六、嵌入式CISC模型机的顶层电路图
七、汇编语言源程序
八、机器语言源程序
九、微命令格式和微指令代码表
十、仿真波形图及其分析
十一、故障现象和分析以及心得体会
十二、软件清单
1.运算器和状态条件寄存器单元
2.通用寄存器单元LS273
3.地址寄存器单元LS273
4.指令寄存器单元LS273
5.1:2分配器FEN2
6.4选1数据选择器单元MUX4
7.5选1数据选择器单元MUX5
8.程序计数器单元PC
9.主存储器单元ROM
10.时序产生器单元COUNTER
11.操作控制单元CROM
A类:输入包含10个整数(8位二进制补码表示)的数组M(采用RAM),输出最小的负数。
说明:
在T4内形成微指令的微地址,并访问控制存储器,在T2的上边沿到来时,将读出的微指令打入微指令寄存器,即图中的微命令寄存器和微地址寄存器。
(1)I/O指令
输入(IN1)指令采用单字节指令,其格式如下:
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × |
Rd |
输出(OUT1)
7 6 5 4 |
3 2 |
1 0 |
操作码 |
Rs |
× × |
Rs指源寄存器,Rd指目的寄存器。
(2)自增指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × |
Rd |
(3)转移指令
条件转移指令(JB、JN)和无条件转移指令(JMP)采用单字节指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × × × |
|
地 址 |
说明:“地址”中的值就是要转移的地址值
(4)比较指令(CMP)和MOV指令
比较指令(CMP)和MOV1采用单字节指令,格式如下:
7 6 5 4 |
3 2 |
1 0 |
操作码 |
Rs |
Rd |
MOV采用双字节指令,格式如下:
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × |
Rd |
地 址 |
(5)寄存器间传送指令
MOV3采用单字节指令,格式如下:
7 6 5 4 |
3 2 |
1 0 |
操作码 |
Rs |
Rd |
MOV采用双字节指令,格式如下:
(6)寄存器间址寻址送指令
MOV1采用单字节指令,格式如下:
7 6 5 4 |
3 2 |
1 0 |
操作码 |
[Rs] |
Rd |
MOV2采用单字节指令,格式如下:
7 6 5 4 |
3 2 |
1 0 |
操作码 |
Rs |
[Rd] |
(7)负数测试指令
TEST采用单字节指令,格式如下:
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × |
Rd |
由此可见,共有12条基本指令,下表列出了每条指令的格式、汇编符号和指令功能。
助记符号 |
指令格式 |
功能 |
||||||
TEST Rd |
|
测试 Rd 寄存器中的值是否为负数 |
||||||
MOV3 Rs ,Rd |
|
(Rs)→(Rd) |
||||||
IN1 Rd |
|
将数据存到 Rd 寄存器 |
||||||
MOV Rd, data |
|
data→Rd |
||||||
MOV1 [Rs], Rd |
|
[Rs]→(Rd) |
||||||
MOV2 Rs, [Rd] |
|
(Rs)→[Rd] |
||||||
CMP Rs, Rd |
|
(Rs) – (Rd),锁存 CY 和 ZI |
||||||
JB addr |
|
若小于,则 addr→PC |
||||||
JN addr |
|
若为负,则 addr→PC |
||||||
INC Rd |
|
(Rd) + 1→Rd |
||||||
JMP addr |
|
addr→PC |
||||||
OUT Rs |
|
(Rs)→LED |
说明:
①对Rs和Rd的规定:
Rs或Rd |
选定的寄存器 |
0 0 |
R0 |
0 1 |
R1 |
1 0 |
R2 |
1 1 |
R3 |
②模型机规定数据的表示采用定点整数补码表示,单字长为8位,其格式如下:
7 |
6 5 4 3 2 1 0 |
符号位 |
尾数 |
同给出的题目编写汇编语言源程序。算法思想为:R0寄存器初始化为1,R1寄存器初始化为11,R3寄存器存入输入的数据,然后将R3中的数存入以R0寄存器中的数为地址的RAM中,R0寄存器自增一,再和R1寄存器中的数进行比较,如果小于则再输入下一个数,如此循环十次,把输入的十个数存入RAM中。当R0寄存器中数和R1中相等时,则进入负数判定和负数间的比较。
R0寄存器初始化为1,R1寄存器初始化为11,R2寄存器初始化为FF(即-1)。把RAM中以R0中的数为地址的的数取出来放在R3中,然后R0自增一,为取下一个数做准备,同时判断是否已经取完了十个数。接下来测试R3中的数时候为负数,如果不是则跳到L1处从RAM中取下一个数。如果是负数,则和R2中的数进行比较。如果R3中的数比R2中的数大,则跳到L1处从RAM中取下一个数,否则将R2中的数替换为R3中的数。即,每次比较完后R2中都保存的是最小的负数。如此循环十次,最后输出R2中的数,即最小的负数。
MOV R0,1 /将立即数1→R0 MOV R1,11 /将立即数11→R1(R2用于计数) L1: IN1 R3 /R3保存输入的数据 MOV2 R3,[R0] /写RAM,地址保存在R0中 INC R0 /R0自加一 CMP R0,R1 /将R1中的数与R0中的数进行比较,锁存CY/FC和ZI/FZ JB L1 /小于,则转到L1处执行 MOV R0,1 /将立即数1→R0 MOV R1,11 /将立即数11→R0 MOV R2,FFH /将立即数FFH→R0 L2: MOV1 [R0],R3 /读RAM,地址保存在R0中 INC R0 /R0中的数自加一 CMP R1,R0 /将R1中的数与R0中的数进行比较,锁存CY/FC和ZI/FZ JB L5 /小于,则转到L5处执行 TEST R3 /测试R3中的数是否为负数 JN L3 /R3中的数是负数时,则跳到L3执行 JMP L2 /无条件转到L2处执行,继续从RAM中取下一个数 L3: CMP R3,R2 /将R3中的数与R1中的数进行比较,锁存CY/FC和ZI/FZ JB L4 /小于,则转到L4处执行 JMP L2 /无条件转到L2处执行,继续从RAM中取下一个数 L4: MOV3 R3,R2 /把R3中的数保存到R2中,R2一直保存的是最小的负数 JMP L2 /无条件转到L2处执行 L5: OUT1 R2 /输出R2中的最小负数 JMP L5 /循环输出
根据设计的指令格式,将汇编语言源程序手工转换成机器语言源程序,并将其设计到模型机中的ROM中去。汇编语言源程序对应的机器语言源程序如下:
//助记符 地址(十六进制) 机器代码 机器代码十六进制 功能 MOV R0,1 00 01110000 70 1→R0 01 00000001 01 MOV R1,11 02 01110001 71 11→R1 03 00001011 0B L1: IN1 R3 04 01100011 63 (SW)→R3 MOV2 R3,[R0] 05 10011100 9C R3→[R0] INC R0 06 11010000 D0 (R0)+1→R0 CMP R0,R1 07 10100001 A1 (R0)-(R1) JB L1 08 10110000 B0 L1→PC 09 00000100 04 MOV R0,1 0A 01110000 70 1→R0 0B 00000001 01 MOV R1,11 0C 01110001 71 11→R1 0D 00001011 0B MOV R2,FFH 0E 01110010 72 FF→R2 0F 11111111 FF L2: MOV1 [R0],R3 10 10000011 83 [R0]→R3 INC R0 11 11010000 D0 (R0)+1→R0 CMP R1,R0 12 10100100 A4 (R1)-(R0) JB L5 13 10110000 B0 L5→PC 14 00100010 22 TEST R3 15 01000011 43 80H<=(R3) JN L3 16 11000000 C0 L3→PC 17 00011010 1A JMP L2 18 11100000 E0 L2→PC 19 00010000 10 L3: CMP R3,R2 1A 10101110 AE (R3)-(R2) JB L4 1B 10110000 B0 L4→PC 1C 00011111 1F JMP L2 1D 11100000 E0 L2→PC 1E 00010000 10 L4: MOV3 R3,R2 1F 01011110 5E (R3) →R2 JMP L2 20 11100000 E0 L2→PC 21 00010000 10 L5: OUT1 R2 22 11111000 F8 (R2) →LED JMP L5 23 11100000 E0 L5→PC 24 00100010 22
(1)设计微指令格式和微指令代码表
CISC模型机系统使用的微指令采用全水平型微指令,字长为31位,其中微命令字段为25位,P字段为3位,后继微地址为6位,其格式如下:
由微指令格式和微程序流程图编写的微指令代码表如下所示,在微指令的代码表中微命令字段从左边到右代表的微命令信号依次为:LOAD、LDPC、LDAR、LDIR、LDRi、RD_B、RS_B、S1、S0、ALU_B、LDAC、LDDR、WR、CS、SW_B、LED_B、LDFR。
微地址 |
微命令字段 |
P1 P2 P3 |
后继 微地址 |
||||||||||||||||||||||||
00 |
000000 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000001 |
01 |
000001 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
1 |
0 |
0 |
010000 |
02 |
000010 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
03 |
000011 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
04 |
000100 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
05 |
000101 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000110 |
06 |
000110 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
000000 |
07 |
010111 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
08 |
011000 |
1 |
1 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
11 |
010001 |
1 |
1 |
0 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
13 |
010011 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
000000 |
14 |
010100 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
010011 |
15 |
010101 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
16 |
010110 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
0 |
0 |
0 |
000000 |
17 |
010111 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000010 |
18 |
011000 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000011 |
19 |
011001 |
1 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000100 |
1A |
011010 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000101 |
1B |
011011 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
0 |
100000 |
1C |
011100 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
1 |
010001 |
1D |
011101 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000111 |
1E |
011110 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
001000 |
1F |
011111 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
000000 |
20 |
100000 |
1 |
0 |
1 |
0 |
1 |
0 |
1 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
30 |
110000 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
31 |
110001 |
1 |
1 |
0 |
0 |
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
000000 |
(2)设计地址转移逻辑电路
地址转移逻辑电路是根据微程序流程图中的棱形框部分及多个分支微地址,利用微地址寄存器的异步置“1”端,实现微地址的多路转移。
由于微地址寄存器中的触发器异步置“1”端低电平有效,与µA4~µA0对应的异步置“1”控制信号SE5~SE1的逻辑表达式为:(µA5的异步置“1”端SE6实际未使用)
SE6<=NOT(NOT FS AND P3 AND T4);
SE5<=NOT((NOT FC OR FZ)AND P2 AND T4);
SE4<=NOT(I7 AND P1 AND T4);
SE3<=NOT(I6 AND P1 AND T4);
SE2<=NOT(I5 AND P1 AND T4);
SE1<=NOT(I4 AND P1 AND T4);
说明:
①上述逻辑表达式的含义:在进行P(1)测试时,根据指令操作码I7、I6、I5、I4进行16路分支;在进行P(2)测试时,根据状态标志FC和FZ进行2路分支。在进行P(3)测试时,根据状态标志FS进行2路分支。
②地址转移逻辑电路中异步置“1”信号SE6~SE1表达式的确定与P字段测试时转移微地址的确定密切相关;
图A 在CISC模型机上的仿真波形图1
图B 在CISC模型机上的仿真波形图2
图C 在CISC模型机上的仿真波形图3
图D 在CISC模型机上的仿真波形图4
图E 在CISC模型机上的仿真波形图5
图F 在CISC模型机上的仿真波形图6
图G 在CISC模型机上的仿真波形图7
通过这次课程设计,我们对计算机组成有了一个理性的认识,使我对计算机的工作原理和流程有了更加深刻的认识。同时也巩固了我以前所学的汇编语言;以及对嵌入式硬件(ARM)的学习提供了很大的帮助,可以让我真正理解硬件的工作原理,多了一种看待问题的角度;我也发现了我所学知识的许多漏洞,需要我在经后的学习中不断弥补。
在老师讲完理论后,我就开始学习VHDL语言。在网上看了一些入门教程后就开始看实验课本。首先把书上各个器件的例子都实现了,对各个器件的结构、及整个嵌入式CISC模型机的结构以及MAX+plus II 10.2 BASELINE有了个大概的了解。为实现更复杂的功能打下来了基础。在调试书上的例子时对嵌入式CISC模型机的工作原理有了进一步的理解。五一放假期间,对地址转移逻辑、控制信号和微程序设计又有了更深的理解,为P(3)测试做好了理论基础。
在接下来的一个星期里,在课本上的例子的基础上进行改动,增加了一个P(3)测试、一个寄存器和RAM。首先画顶层电路图并写好汇编程序,这样就知道要用到哪些指令。然后设计指令、画微程序流程图、微指令代码表。最后是进行仿真和调试。在整个过程中,仿真和调试花了最多的时间。根据波形图,找出出现错误的地方,最初调试时觉得是最困难的事情了,随着一个个错误的解决和积极帮助同学调试程序,慢慢的积累了一套调试程序的方法:检查一下图形连线有没有连对,汇编程序有没有错,机器码是否写对,机器指令是否正确,微命令对不对,按照这个顺序下来,基本上都能把问题解决。
其实想想,这些错误大部分都是一些很低级的错误,比如将P(1)和P(2))的连线结反了,看仿真波形图时,微指令流程全乱了;RAM无法写入和读出数据或者读出的数据不是预期的数据,仿真波形图时,RAM的数据输入端和地址输入端的数据都是正确的,数据应该写入了RAM,在读RAM时,RAM的地址输入端的数据正确,但读出的数据却不正确,后来一分析,原来是RAM的读写时序不对,RAM是时序器件;仿真波形图显示微指令执行了,但不是想要的结果,这可能是微指令代码写的不对等。这些错误其实在设计时认真一些,多检查一遍,这样就可以减少大量得调试时间。而且,在设计好微指令时,一定要先测试一下每一个汇编指令是否正确,这样我们在调试汇编程序时就可以轻松很多,汇编程序的结果不对的原因大部分是部分指令设计的不对,比如跳转指令的跳转不对,还有一部分原因是机器码写的不对,尤其是源寄存器和目的寄存器的编码写反了。宁愿在设计时多花半小时,这样可以减少数小时甚至几天的调试时间。最后,要多和老师和同学交流,也许让你焦头烂额的问题,在别人眼里其实是一个很简单的问题或者换一个思路就豁然开朗。
经过近一个月的努力,终于将此次设计成功完成,实现了A类题目预期所要求的所有功能。 在实践的过程中,我对计算机体系结构有了一定的理解,尤其是加深了我对计算机硬件的理解,为嵌入式的学习提供了很大的帮助,但是也使得我更加深刻的发现了自己的不足,还要更加努力的学习,比如:对程序计数器PC的功能理解不透侧等(PC的值送到AR后,PC会加1指向下一条指令)。
本程序虽然完成了预期所要求的基本功能,但还有很多需要完善的地方,比如RAM的片选信号可以和ROM共用,由于ROM和RAM共用一根地址线,在读写RAM的时候会读取ROM,但是通过控制4选1数据选择器可以只输出RAM或ROM中的数据,这样就可以少一个控制信号。还有,RAM的读写控制信号也不必单独设计,可和原有的WR控制信号共用。可是由于时间的仓促和一开始总体设计方面的不足,使得系统设计的不够精简,控制信号冗余。这使我认识到了自己在软件设计、开发上的不足。软件的前期设计不充分和顶层电路图不合理的布局让我在后期修改代码和扩展功能时遇到了意想不到的困难。
虽然本次课程设计还有如此种种的不足,但是我仍然受益匪浅。我深刻的认识到了掌握EDA技术及CISC CPU的设计原理具有重要意义。
运算器由算术逻辑运算单元ALU、两个暂存寄存器和状态条件寄存器组成。算术逻辑运算单元可执行满足题目要求的三种运算,如下面的表中所示;暂存寄存器由累加器AC和数据寄存器DR组成;状态条件寄存器用来在进行比较运算时锁存借位标志(FC/CY)和零标志(FZ/ZI)。
ALU单元的功能表
S1 |
S0 |
功能 |
0 |
0 |
(AC)+(DR),锁存FC和FZ |
0 |
1 |
(AC)-(DR),锁存FC和FZ |
1 |
0 |
(AC)-1,锁存FC和FZ |
1 |
1 |
80H<=(AC),锁存FS |
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY ALU IS PORT( A:IN STD_LOGIC_VECTOR(7 DOWNTO 0); B:IN STD_LOGIC_VECTOR(7 DOWNTO 0); S1,S0:IN STD_LOGIC; BCDOUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); SF,CY,ZI:OUT STD_LOGIC ); END ALU; ARCHITECTURE A OF ALU IS SIGNAL AA,BB,TEMP:STD_LOGIC_VECTOR(8 DOWNTO 0); BEGIN PROCESS(S1,S0) BEGIN --VARIABLE TEMP1:STD_LOGIC_VECTOR(7 DOWNTO 0); IF(S1='0' AND S0='0')THEN AA<='0'&A; BB<='0'&B; TEMP<=AA+BB; BCDOUT<=TEMP(7 DOWNTO 0); CY<=TEMP(8); IF(TEMP="100000000")THEN ZI<='1'; ELSE ZI<='0'; END IF; ELSIF(S1='0' AND S0='1')THEN BCDOUT<=A-B; IF(A<B)THEN CY<='1'; ZI<='0'; ELSIF(A=B)THEN CY<='0'; ZI<='1'; ELSE CY<='0'; ZI<='0'; END IF; ELSIF(S1='1' AND S0='0')THEN AA<='0'&A; TEMP<=AA+1; BCDOUT<=TEMP(7 DOWNTO 0); CY<=TEMP(8); IF(TEMP="100000000")THEN ZI<='1'; ELSE ZI<='0'; END IF; ELSIF(S1='1' AND S0='1')THEN --TEMP1="10000000"; BCDOUT<="10000000"-A; IF("10000000"<=A)THEN SF<='1'; ELSE SF<='0'; END IF; ELSE BCDOUT<="00000000"; CY<='0'; ZI<='0'; END IF; END PROCESS; END A;
(2)状态条件寄存单元LS74
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY LS74 IS PORT( LDFR:IN STD_LOGIC; SF,CY,ZI:IN STD_LOGIC; FS,FC,FZ:OUT STD_LOGIC ); END LS74; ARCHITECTURE A OF LS74 IS BEGIN PROCESS(LDFR) BEGIN IF(LDFR'EVENT AND LDFR='1')THEN FC<=CY; FZ<=ZI; FS<=SF; END IF; END PROCESS; END A;
(3)暂存寄存器单元LS273
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY LS273 IS PORT( D:IN STD_LOGIC_VECTOR(7 DOWNTO 0); CLK:IN STD_LOGIC; O:OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END LS273; ARCHITECTURE A OF LS273 IS BEGIN PROCESS(CLK) BEGIN IF(CLK'EVENT AND CLK='1')THEN O<=D; END IF; END PROCESS; END A;2.通用寄存器单元LS273
4个通用寄存器(R0、R1、R2、R3)以及ALU输出的外部控制信号如下表中所示:
R0_B |
R1_B |
R2_B |
R3_B |
ALU_B |
功能 |
1 |
1 |
1 |
1 |
0 |
输出ALU的结果 |
0 |
1 |
1 |
1 |
1 |
输出(R0) |
1 |
0 |
1 |
1 |
1 |
输出(R1) |
1 |
1 |
0 |
1 |
1 |
输出(R2) |
1 |
1 |
1 |
0 |
1 |
输出(R3) |
VHDL源程序同暂存寄存器单元LS273
VHDL源程序同暂存寄存器单元LS273
VHDL源程序同暂存寄存器单元LS273
1:2分配器用来将ALU的运算结果或通用寄存器的内容经3选1多路选择器送到数据总线,或者将ALU的运算结果或通用寄存器的内容送往输出设备显示。功能如下表所示。
输入 |
输出 |
|||
WR |
LED_B |
X[7..0] |
W1[7..0] |
W2[7..0] |
0 |
0 |
× |
X[7..0] |
|
其它取值 |
× |
X[7..0] |
VHDL源程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY FEN2 IS PORT( WR,LED_B:IN STD_LOGIC; X:IN STD_LOGIC_VECTOR(7 DOWNTO 0); W1,W2:OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END FEN2; ARCHITECTURE A OF FEN2 IS BEGIN PROCESS(LED_B,WR) BEGIN IF(LED_B='0' AND WR='0')THEN W2<=X; ELSE W1<=X; END IF; END PROCESS; END A;
4选1数据选择器单元用来从外部输入数据端ID[7..0]、5选1多路选择器的输出端N1[7..0]、只读存储器ROM的输出端ROM[7..0]和RAM的输出端RAM [7..0]选择一个8位数进入内部数据总线。功能表如下面表中所示。
输入 |
输出 |
|||||||
SW_B |
RAM_B |
ROM_B |
ID[7..0] |
ROM [7..0] |
N2[7..0] |
EW[7..0] |
||
0 |
× |
× |
× |
× |
× |
ID[7..0] |
||
1 |
× |
0 |
× |
× |
× |
ROM[7..0] |
||
1 |
1 |
1 |
× |
× |
× |
N1[7..0] |
||
1 |
0 |
1 |
× |
× |
× |
RAM[7..0] |
MUX4的VHDL源程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY MUX4 IS PORT( ID:IN STD_LOGIC_VECTOR(7 DOWNTO 0); RAM_B,SW_B,ROM_B:IN STD_LOGIC; N1,ROM,RAM:IN STD_LOGIC_VECTOR(7 DOWNTO 0); EW:OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END MUX4; ARCHITECTURE A OF MUX4 IS BEGIN PROCESS(SW_B,RAM_B,ROM_B) BEGIN IF(SW_B='0')THEN EW<=ID; ELSIF(RAM_B='0')THEN EW<=RAM; ELSIF(ROM_B='0')THEN EW<=ROM; ELSE EW<=N1; END IF; END PROCESS; END A;
MUX5用来从四个通用寄存器的数据输出端和ALU的数据输出端选择一个8位的数据进入1:2分配器的数据输入端。功能表如下表中所示。
输入控制信号 |
输出 |
||||
C |
D |
E |
F |
G |
W[7..0] |
0 |
1 |
1 |
1 |
1 |
X1[7..0] |
1 |
0 |
1 |
1 |
1 |
X2[7..0] |
1 |
1 |
0 |
1 |
1 |
X3[7..0] |
1 |
1 |
1 |
0 |
1 |
X4[7..0] |
1 |
1 |
1 |
1 |
0 |
X5[7..0] |
MUX5的VHDL源程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY MUX5 IS PORT( C,D,E,F,G:IN STD_LOGIC; X1,X2,X3,X4,X5:IN STD_LOGIC_VECTOR(7 DOWNTO 0); W:OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END MUX5; ARCHITECTURE A OF MUX5 IS SIGNAL SEL:STD_LOGIC_VECTOR(4 DOWNTO 0); BEGIN SEL<=G&F&E&D&C; PROCESS(SEL) BEGIN IF(SEL="11110")THEN W<=X1; ELSIF(SEL="11101")THEN W<=X2; ELSIF(SEL="11011")THEN W<=X3; ELSIF(SEL="10111")THEN W<=X4; ELSIF(SEL="01111")THEN W<=X5; ELSE NULL; END IF; END PROCESS; END A;
程序计数器单元,在控制信号的控制下具有清“0”、置计数初值和加1的功能,作用是保证程序的顺序执行,在执行跳转指令时,通过修改PC值以达到程序转移分支的目的。功能表如下面表中所示。
PC(程序计数器单元)功能表
CLR |
LOAD |
LDPC |
功能 |
0 |
× |
× |
将PC清0 |
1 |
0 |
↑ |
BUS-->PC |
1 |
1 |
0 |
不装入也不计数 |
1 |
1 |
↑ |
PC+1 |
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY PC IS PORT( LOAD,LDPC,CLR:IN STD_LOGIC; D:IN STD_LOGIC_VECTOR(7 DOWNTO 0); O:OUT STD_LOGIC_VECTOR(7 DOWNTO 0) ); END PC; ARCHITECTURE A OF PC IS SIGNAL QOUT:STD_LOGIC_VECTOR(7 DOWNTO 0); BEGIN PROCESS(LDPC,CLR,LOAD) BEGIN IF(CLR='0')THEN QOUT<="00000000"; ELSIF(LDPC'EVENT AND LDPC='1')THEN IF(LOAD='0')THEN QOUT<=D;--BUS->PC ELSE QOUT<=QOUT+1;--PC=PC+1 END IF; END IF; END PROCESS; O<=QOUT; END A;
主存储器单元用来存放CPU要运行的程序和数据,是计算机系统中必不可少的重要组成部分。其功能表如下面的表中所示。
主存储器ROM功能表
CS |
功能 |
1 |
不选择 |
0 |
读 |
ROM的VHDL源程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY ROM IS PORT( CS:IN STD_LOGIC; DOUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0); ADDR:IN STD_LOGIC_VECTOR(7 DOWNTO 0) ); END ROM; ARCHITECTURE A OF ROM IS BEGIN PROCESS(CS) BEGIN IF (CS'EVENT AND CS='0')THEN CASE ADDR IS WHEN "00000000" => DOUT<="01110000";-- MOV R0,1 WHEN "00000001" => DOUT<="00000001"; WHEN "00000010" => DOUT<="01110001";-- MOV R1,11 WHEN "00000011" => DOUT<="00001011"; WHEN "00000100" => DOUT<="01100011";--L1:IN1 R3 WHEN "00000101" => DOUT<="10011100";-- MOV2 R3,[R0] WHEN "00000110" => DOUT<="11010000";-- INC R0 WHEN "00000111" => DOUT<="10100001";-- CMP R0,R1 WHEN "00001000" => DOUT<="10110000";-- JB L1 WHEN "00001001" => DOUT<="00000100"; WHEN "00001010" => DOUT<="01110000";-- MOV R0,1 WHEN "00001011" => DOUT<="00000001"; WHEN "00001100" => DOUT<="01110001";-- MOV R1,11 WHEN "00001101" => DOUT<="00001011"; WHEN "00001110" => DOUT<="01110010";-- MOV R2,FF WHEN "00001111" => DOUT<="11111111"; WHEN "00010000" => DOUT<="10000011";--L2:MOV1 [R0],R3 WHEN "00010001" => DOUT<="11010000";-- INC R0 WHEN "00010010" => DOUT<="10100100";-- CMP R1,R0 WHEN "00010011" => DOUT<="10110000";-- JB L5 WHEN "00010100" => DOUT<="00100010"; WHEN "00010101" => DOUT<="01000011";-- TEST R3 WHEN "00010110" => DOUT<="11000000";-- JN L3 WHEN "00010111" => DOUT<="00011010"; WHEN "00011000" => DOUT<="11100000";-- JMP L2 WHEN "00011001" => DOUT<="00010000"; WHEN "00011010" => DOUT<="10101110";--L3:CMP R3,R2 WHEN "00011011" => DOUT<="10110000";-- JB L4 WHEN "00011100" => DOUT<="00011111"; WHEN "00011101" => DOUT<="11100000";-- JMP L2 WHEN "00011110" => DOUT<="00010000"; WHEN "00011111" => DOUT<="01011110";--L4:MOV3 R3,R2 WHEN "00100000" => DOUT<="11100000";-- JMP L2 WHEN "00100001" => DOUT<="00010000"; WHEN "00100010" => DOUT<="11111000";--L5:OUT1 R2 WHEN "00100011" => DOUT<="11100000";-- JMP L5 WHEN "00100100" => DOUT<="00100010"; WHEN OTHERS => NULL; END CASE; END IF; END PROCESS; END A;
COUNTER用来产生节拍脉冲信号(T1、T2、T3、T4),对各种控制信号实施时间上的控制。其功能表如下面的表中所示。
输入 |
输出 |
备注 |
||||
Q |
CLR |
T1 |
T2 |
T3 |
T4 |
当CLR变为1且Q的上边沿到来时,T1为“1”,T2~T4为“0” |
× |
0 |
0 |
0 |
0 |
0 |
|
↑ |
1 |
循环右移1次 |
COUNTER的VHDL源程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY COUNTER IS PORT( Q,CLR:IN STD_LOGIC; T2,T3,T4:OUT STD_LOGIC ); END COUNTER; ARCHITECTURE A OF COUNTER IS SIGNAL X:STD_LOGIC_VECTOR(1 DOWNTO 0); BEGIN PROCESS(Q,CLR) BEGIN IF(CLR='0')THEN T2<='0'; T3<='0'; T4<='0'; X<="00"; ELSIF(Q'EVENT AND Q='1')THEN X<=X+1; T2<=(NOT X(1)) AND X(0); T3<=X(1) AND (NOT X(0)); T4<=X(1) AND X(0); END IF; END PROCESS; END A;
微程序控制器主要由地址转移逻辑电路ADDR、微地址寄存器aa、控制存储器CONTEROM和微命令寄存器MCOMMAND等几部分组成。为方便电路的设计与连线,在进行设计时,增加了F1、F2和F3共三个用于多根单线与总线之间转换的器件。各部件的VHDL源程序如下:
(1)地址转移逻辑电路ADDR
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY ADDR IS PORT( I7,I6,I5,I4:IN STD_LOGIC; FS,FZ,FC,T4,P1,P2,P3:IN STD_LOGIC; SE6,SE5,SE4,SE3,SE2,SE1:OUT STD_LOGIC ); END ADDR; ARCHITECTURE A OF ADDR IS BEGIN SE6<=NOT(NOT FS AND P3 AND T4); SE5<=NOT((NOT FC OR FZ)AND P2 AND T4); SE4<=NOT(I7 AND P1 AND T4); SE3<=NOT(I6 AND P1 AND T4); SE2<=NOT(I5 AND P1 AND T4); SE1<=NOT(I4 AND P1 AND T4); END A;
(2)微地址寄存器aa
微地址寄存器内部主要由6个MMM部件组成,再接入相应的输入、输出信号,VHDL源程序如下:
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY MMM IS PORT( SE:IN STD_LOGIC; T2:IN STD_LOGIC; D:IN STD_LOGIC; CLR:IN STD_LOGIC; UA:OUT STD_LOGIC ); END MMM; ARCHITECTURE A OF MMM IS BEGIN PROCESS(CLR,SE,T2) BEGIN IF(CLR='0')THEN UA<='0'; ELSIF(SE='0')THEN UA<='1'; ELSIF(T2'EVENT AND T2='1')THEN UA<=D; END IF; END PROCESS; END A;
(3)微地址转换器F1
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY F1 IS PORT( UA5,UA4,UA3,UA2,UA1,UA0:IN STD_LOGIC; D:OUT STD_LOGIC_VECTOR(5 DOWNTO 0) ); END F1; ARCHITECTURE A OF F1 IS BEGIN D(5)<=UA5; D(4)<=UA4; D(3)<=UA3; D(2)<=UA2; D(1)<=UA1; D(0)<=UA0; END A;
(4)控制存储器CONTEROM
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY CONTROM IS PORT( ADDR:IN STD_LOGIC_VECTOR(5 DOWNTO 0); UA:OUT STD_LOGIC_VECTOR(5 DOWNTO 0); D:OUT STD_LOGIC_VECTOR(24 DOWNTO 0) ); END CONTROM; ARCHITECTURE A OF CONTROM IS SIGNAL DATAOUT:STD_LOGIC_VECTOR(30 DOWNTO 0); BEGIN PROCESS(ADDR) BEGIN CASE ADDR IS WHEN "000000"=>DATAOUT<="1100111100110010011110000000001"; WHEN "000001"=>DATAOUT<="1100110010110010010110100010000"; WHEN "000010"=>DATAOUT<="1100110001110010010110000000000"; WHEN "000011"=>DATAOUT<="0010110001110010011110000000000"; WHEN "000100"=>DATAOUT<="1000110000100010011110000000000"; WHEN "000101"=>DATAOUT<="1100110000010010111110000000110"; WHEN "000110"=>DATAOUT<="1100110000110110011111000000000"; WHEN "000111"=>DATAOUT<="1100110001111000011110000000000"; WHEN "001000"=>DATAOUT<="1100101000110010010110000000000"; WHEN "001001"=>DATAOUT<="1000110000110010011110000000000";--9 WHEN "010001"=>DATAOUT<="1010101000110010010110000000000";--11 WHEN "010010"=>DATAOUT<="1100110000110010011110000000011";--12 WHEN "010011"=>DATAOUT<="1100110000111110011111000000000";--13 WHEN "010100"=>DATAOUT<="1100110000010011011110000010011";--14TEST Rd WHEN "010101"=>DATAOUT<="1100110001100010011110000000000";--15 MOV3 Rs>Rd WHEN "010110"=>DATAOUT<="1100110001110010011010000000000";--16 IN1 RD WHEN "010111"=>DATAOUT<="1100111100110010011110000000010";--17 MOV RD #DATA WHEN "011000"=>DATAOUT<="1101010100100010011110000000011";--18 MOV1 [Rs]>Rd WHEN "011001"=>DATAOUT<="1101010100010010011110000000100";--19 MOV2 [Rs]<Rd WHEN "011010"=>DATAOUT<="1100110000100011011110000000101";--1A CMP Rs Rd WHEN "011011"=>DATAOUT<="1100111100110010011110010100000";--1B JB WHEN "011100"=>DATAOUT<="1100111100110010011110011010001";--1C JN WHEN "011101"=>DATAOUT<="1100110000010011011110000000111";--1D INC Rd WHEN "011110"=>DATAOUT<="1100111100110010011110000001000";--1E JMP WHEN "011111"=>DATAOUT<="1100110000100010001100000000000";--1F OUT Rs WHEN "100000"=>DATAOUT<="1010101000110010010110000000000"; WHEN "110000"=>DATAOUT<="1100110000110010011110000000000"; WHEN "110001"=>DATAOUT<="1100110000110010011110000000000"; WHEN OTHERS =>DATAOUT<="1100110000110010011110000000000"; END CASE; UA(5 DOWNTO 0)<=DATAOUT(5 DOWNTO 0); D(24 DOWNTO 0)<=DATAOUT(30 DOWNTO 6); END PROCESS; END A;
(5)微命令寄存器MCOMMAND
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.STD_LOGIC_UNSIGNED.ALL; ENTITY MCOMMAND IS PORT( T2,T3,T4,I3,I2,I1,I0:IN STD_LOGIC; O:IN STD_LOGIC_VECTOR(24 DOWNTO 0); P1,P2,P3,RAM_B,WR1,CS1,PC,ADDR,LOAD,LDPC,LDAR,LDIR,LDR0,LDR1,LDR2,LDR3,R0_B,R1_B,R2_B,R3_B,S1,S0,ALU_B,LDAC,LDDR,WR,CS,SW_B,LED_B,LDFR:OUT STD_LOGIC ); END MCOMMAND ; ARCHITECTURE A OF MCOMMAND IS SIGNAL DATAOUT:STD_LOGIC_VECTOR(24 DOWNTO 0); BEGIN PROCESS(T2) BEGIN IF(T2'EVENT AND T2='1')THEN DATAOUT(24 DOWNTO 0)<=O(24 DOWNTO 0); END IF; P3<=DATAOUT(0); P2<=DATAOUT(1); P1<=DATAOUT(2); LDFR<=DATAOUT(3) AND T4; LED_B<=DATAOUT(4); SW_B<=DATAOUT(5); CS<=DATAOUT(6); WR<=DATAOUT(7)OR(NOT T3); LDDR<=DATAOUT(8) AND T4; LDAC<=DATAOUT(9) AND T4; ALU_B<=DATAOUT(10); S0<=DATAOUT(11); S1<=DATAOUT(12); R3_B<=(DATAOUT(14) OR (NOT I1) OR (NOT I0))AND (DATAOUT(13) OR (NOT I3 ) OR (NOT I2)); R2_B<=(DATAOUT(14) OR (NOT I1) OR I0)AND (DATAOUT(13) OR (NOT I3 ) OR I2); R1_B<=(DATAOUT(14) OR I1 OR (NOT I0))AND (DATAOUT(13) OR I3 OR (NOT I2)); R0_B<=(DATAOUT(14) OR I1 OR I0)AND (DATAOUT(13) OR I3 OR I2); LDR3<=T4 AND DATAOUT(15) AND I1 AND I0; LDR2<=T4 AND DATAOUT(15) AND I1 AND (NOT I0); LDR1<=T4 AND DATAOUT(15) AND (NOT I1) AND I0; LDR0<=T4 AND DATAOUT(15) AND (NOT I1) AND (NOT I0); LDIR<=DATAOUT(16) AND T3; LDAR<=DATAOUT(17) AND T3; LDPC<=DATAOUT(18) AND T4; LOAD<=DATAOUT(19); PC<=DATAOUT(20); ADDR<=DATAOUT(21); WR1<=DATAOUT(22)OR (NOT(T2 OR T3)); CS1<=DATAOUT(23)OR (NOT T3); RAM_B<=DATAOUT(24); END PROCESS; END A;
(6)微地址转换器F2
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY F2 IS PORT( D:IN STD_LOGIC_VECTOR(5 DOWNTO 0); UA5,UA4,UA3,UA2,UA1,UA0:OUT STD_LOGIC ); END F2; ARCHITECTURE A OF F2 IS BEGIN UA5<=D(5); UA4<=D(4); UA3<=D(3); UA2<=D(2); UA1<=D(1); UA0<=D(0); END A;
(7)指令代码转换器F3
LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; ENTITY F3 IS PORT( D:IN STD_LOGIC_VECTOR(7 DOWNTO 0); UA7,UA6,UA5,UA4,UA3,UA2,UA1,UA0:OUT STD_LOGIC ); END F3; ARCHITECTURE A OF F3 IS BEGIN UA7<=D(7); UA6<=D(6); UA5<=D(5); UA4<=D(4); UA3<=D(3); UA2<=D(2); UA1<=D(1); UA0<=D(0); END A;