基于微程序设计的嵌入式CISC CPU模型的实现

长平狐 发布于 2013/06/03 14:53
阅读 513
收藏 0

基于微程序设计的嵌入式CISC CPU模型的实现

一、课程设计的题目 

二、嵌入式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),输出最小的负数。

二、嵌入式CISC模型机数据通路框图

        

三、微程序控制器(CISC模型机)的逻辑结构框图

说明:

    在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

0 1 0 0

× ×

Rd

测试 Rd 寄存器中的值是否为负数

MOV3 Rs ,Rd

0 1 0 1

Rs

Rd

(Rs)(Rd)

IN1 Rd

0 1 1 0

× ×

Rd

将数据存到 Rd 寄存器

MOV Rd, data

0 1 1 1

× ×

Rd

data

data→Rd

MOV1 [Rs], Rd

1 0 0 0

Rs

Rd

[Rs](Rd)

MOV2 Rs, [Rd]

1 0 0 1

Rs

Rd

(Rs)[Rd]

CMP Rs, Rd

1 0 1 0

Rs

Rd

(Rs) – (Rd),锁存 CY 和 ZI

JB addr

1 0 11

× ×

× ×

addr

若小于,则 addr→PC

JN addr

1 1 0 0

× ×

× ×

addr

若为负,则 addr→PC

INC Rd

1 1 0 1

× ×

Rd

(Rd) + 1→Rd

JMP addr

1 1 1 0

× ×

× ×

addr

addr→PC

OUT Rs

1 1 1 1

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

符号位

尾数

五、机器指令的微程序流程图

六、嵌入式CISC模型机的顶层电路图

七、汇编语言源程序

         同给出的题目编写汇编语言源程序。算法思想为:R0寄存器初始化为1R1寄存器初始化为11R3寄存器存入输入的数据,然后将R3中的数存入以R0寄存器中的数为地址的RAM中,R0寄存器自增一,再和R1寄存器中的数进行比较,如果小于则再输入下一个数,如此循环十次,把输入的十个数存入RAM中。当R0寄存器中数和R1中相等时,则进入负数判定和负数间的比较。

         R0寄存器初始化为1R1寄存器初始化为11R2寄存器初始化为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的设计原理具有重要意义。

十二、软件清单

1.运算器和状态条件寄存器单元

运算器由算术逻辑运算单元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



(1)ALU单元

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

3.地址寄存器单元LS273

VHDL源程序同暂存寄存器单元LS273

4.指令寄存器单元LS273

VHDL源程序同暂存寄存器单元LS273

5.1:2分配器FEN2

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;

6.41数据选择器单元MUX4

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;

7.51数据选择器单元MUX5

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;

8.程序计数器单元PC

程序计数器单元,在控制信号的控制下具有清“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;

9.主存储器单元ROM

主存储器单元用来存放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;

10.时序产生器单元COUNTER

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;


11.操作控制单元CROM



微程序控制器主要由地址转移逻辑电路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;










原文链接:http://blog.csdn.net/ce123/article/details/6989541
加载中
返回顶部
顶部