如何使用CISC模型微处理器?
如何使用CISC模型微处理器?
(1) 实验题目
设计一台CISC模型机,要求具有以下验证程序所要求的功能:输入包含10个整数(无符号数)的数组M,按从小到大的顺序输出这10个数。( A类)
(2) 嵌入式CISC模型机数据通路框图
图1 模型机数据通路框图
(3) 操作控制器的逻辑框图
图2 操作控制器逻辑框图
(4) 模型机的指令系统和指令格式
1 指令系统
本系统设计了10条指令:IN1(输入到目的寄存器),MOV(将一个数送入目的寄存器),MOV1(将源寄存器中的数据存储到目的寄存器所指向的地址单元),MOV2(将源寄存器所指向的地址单元中的数送入目的寄存器), OUT1(输出),CMP(将目的寄存器和源寄存器所指向的地址单元中的数据进行比较),DEC(将目的寄存器中的数据自减一),INC(将目的寄存器中的数据自加一),JMP(无条件跳转),JB(小于跳转),下表列出了每条指令的格式、汇编符号和指令功能。
助记符号 |
指令格式 |
功 能 |
||||||
IN1 Rd |
|
(SW)->Rd |
||||||
MOV im Rd |
|
(im)->Rd |
||||||
MOV1 Rs [Rd] |
|
(Rs)->[Rd] |
||||||
MOV2 [Rs] Rd |
|
([Rs])->Rd |
||||||
OUT1 Rd |
|
(Rs)->LED |
||||||
CMP Rs Rd |
|
(Rs)-(Rd),锁存CY和ZI |
||||||
DEC Rd |
|
(Rd)-1->Rd |
||||||
INC Rd |
|
(Rd)+1->Rd |
||||||
JMP addr
|
|
addr->PC |
||||||
JB addr
|
|
若小于,则addr->PC |
表1 指令系统格式表
2 指令格式
下面时系统中采用的10条指令及其格式,其中Rs为源寄存器,Rd为目的寄存器,im为立即数,addr为形式地址。
(1) 输入指令
输入(IN1)指令采用单字节指令,其格式如下:
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × |
Rs |
(2) MOV指令
MOV指令采用双字节指令,其格式如下:
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × |
Rd |
im |
(3) MOV1指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
Rs |
Rd |
“Rs”为源寄存器,存放的是源操作数
“Rd”为目的寄存器,存放的是目的操作数所在的地址
(4) MOV2指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
Rs |
Rd |
“Rs”为源寄存器,存放的是源操作数所在的地址
“Rd”为目的寄存器,存放的是目的操作数
(5) 输出(OUT1)指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
Rs |
× × |
(6) 比较(CMP)指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
Rs |
Rd |
“Rs”为源寄存器,存放的是源操作数
“Rd”为目的寄存器,存放的是目的操作数
(7) 自增一(INC)指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × |
Rd |
(8) 自减一(DEC)指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × |
Rd |
(9) 条件转移转移指令(JB) 指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × × × |
|
addr |
“addr”中的值就是要转移的地址值。
(10) 无条件转移指令(JMP)指令
7 6 5 4 |
3 2 |
1 0 |
操作码 |
× × × × |
|
addr |
“addr”中的值就是要转移的地址值。
其中对Rs和Rd的规定如下:
Rs Rd |
选定的寄存器 |
0 0 |
R0 |
0 1 |
R1 |
1 0 |
R2 |
1 1 |
R3 |
3 数据格式
模型机规定数据的为无符号整数,且字长为8位,其格式如下:
7 6 5 4 3 2 1 0 |
数据 |
(5) 微程序流程图
机器指令的CPU操作流程图是根据模型机的硬件设计、指令系统、所有指令的解释过程和控制信号的时序设计出来的,如图2所示。图中每一个方框执行的时间为一个时钟周期(包含T1-T4共4个节拍脉冲周期),对应一条微指令。框中上面的八进制数表示的是当前微指令在控制存储器中的微地址,框中下面的八进制表示的是当前微指令的后继微地址。图中的菱形框从属于它上面的方框。
图2 微程序流程图
(6) 微指令代码表
1 指令格式
本模型机使用的微指令采用全水平型微指令,字长为29位,其中微命令字段为21位,P字段为2位,后继微地址为6位,其格式如图3所示:
图3 微指令格式
2 指令代码表
表2 微指令代码
(7) 顶层电路图
1 模型机的顶层电路图
图4 顶层电路图
2 模型机微地址寄存器单元aa的内部结构
图5 地址寄存器单元aa的电路图
3模型机微程序控制器的内部结构
图6 微程序控制器的电路图
(8) 汇编语言源程序
冒泡排序:两两比较待排序记录的关键字,发现两个记录的次序相反时即进行交换,直到没有反序的记录为止。
算法思想: 1 输入10个数
2 用R0存放最外层的循环次数,R1存放地址,R2和R3存放比较的两个数,从对应的R1的地址读入.R3存放大的数.如果有更大的数,则交换.最后下沉的就为一个最大的数.然后自减R0.进入下次循环.到循环结束.
3 输出结果
/*
* 冒泡程序: 每次将最大的数下沉。
* 输入10个数,从小到大输出。
* 作者:longronglin
* 时间:2006-5-10
*/
//* 输入10个数 */
Mov 0AH R0 //设置循环值10
Mov 00H R1 //设置RAM的初始地址00
L1: In1 R2 //从开关输入任意一个整数到R2
Mov1 R2 [R1] //将R2存入地址为R1的RAM单元中
Inc R1 //自增R1
Cmp R1, R0 //比较R1,R0的大小,R1<R0跳转L1
JB L1
//* 冒泡排序 */
Mov 0AH R0 //设置外循环值为10
Mov 00H R1 //设置RAM的初始地址00
L2: Mov2 [R1] R2 //取地址为R1的RAM内容到R2
Inc R1 //自增R1
Cmp R0 R1 //比较R0,R1的大小,R0<R1跳转L4
JB L4
Mov2 [R1] R3 //取地址为R1的RAM内容到R3
Cmp R3 R2 //比较R3,R2的大小,R3<R2跳转L3
JB L3
JMP L2 //无条件跳转L2
//* 交换两个数 */
L3: Mov1 R2 [R1] //将R2存入地址为R1的RAM单元中
Dec R1 //自减R1
Mov1 R3 [R1] //将R3存入地址为R1的RAM单元中
Inc R1 //自增R1
JMP L2 //无条件跳转L2
L4: Dec R0 //循环值自减1
Mov 00H R1 //设置R1的值为0
Cmp R1 R0 //比较R1和R0的大小,R1<R0跳转L2
JB L2
//* 输出 */
Mov 0AH R0 //设置循环值10
Mov 00H R1 //设置RAM的初始地址00
L5: Mov2 [R1] R2 //取地址为R1的RAM内容到R2
Inc R1 //自增R1
Out1 R2 //输出R2到LED
Cmp R1 R0 /比较R1和R0的大小,R1<R0跳转L5
JB L5
L6: Out1 R2 //输出R2到LED
JMP L6 //持续输出
(9) 机器语言源程序
根据指令格式将汇编语言源程序手工汇编成机器代码如下表:
助记符 |
地址(十六进制) |
机器代码 |
功能 |
MOV 0AH R0 |
00 01 |
10010000 00001010 |
0AH->R0 |
MOV 00H R1 |
02 03 |
10010001 00000000 |
00H->R1 |
L1: IN1 R2 |
04 |
10000010 |
(SW)->R2 |
MOV1 R2 [R1] |
05 |
10101001 |
(R2)->[R1] R2的值存入地址为R1的存储单元中 |
INC R1 |
06 |
11110001 |
(R1)+1->R1 |
CMP R1 RO |
07 |
11010100 |
([R1])-([R0]),锁存FC和FZ |
JB L1 |
08 09 |
01110000 00000100 |
小于,则跳转到L1处执行 |
MOV 09H R0 |
0A 0B |
10010000 00001001 |
09H->R0 外循环次数 |
MOV 00H R1 |
0C 0D |
10010001 00000000 |
00H->R1 |
L2: MOV2 [R1] R2 |
0E |
10110110 |
([R1])->R2 从地址为R1的存储单元里取数到R2 |
INC R1 |
0F |
11110001 |
(R1)+1->R1 |
CMP R0 R1 |
10 |
11010001 |
([R0])-([R1]),锁存FC和FZ |
JB L4 |
11 12 |
01110000 00011111 |
小于,则跳转到L4处执行 |
MOV2 [R1] R3 |
13 |
10110111 |
([R1])->R3 从地址为R1的存储单元里取数到R3 |
CMP R3 R2 |
14 |
11011110 |
([R3])-([R2]),锁存FC和FZ |
JB L3 |
15 16 |
01110000 00011001 |
小于,则跳转到L3处执行 |
JMP L2 |
17 18 |
01100000 00001110 |
跳转到L2处执行 |
L3: MOV1 R2 [R1] |
19 |
10101001 |
(R2)->[R1] R2的值存入地址为R1的存储单元中 |
DEC R1 |
1A |
11100001 |
(R1)-1->R1 |
MOV1 R3 [R1] |
1B |
10101101 |
(R3)->[R1] R3的值存入地址为R1的存储单元中 |
INC R1 |
1C |
11110001 |
(R1)+1->R1 |
JMP L2 |
1D 1E |
01100000 00001110 |
跳转到L2处执行 |
L4:DEC R0 |
1F |
11100000 |
(R0)-1->R0 |
MOV 00H R1 |
20 21 |
10010001 00000000 |
00H->R1 |
CMP R1 R0 |
22 |
11010100 |
([R1])-([R0]),锁存FC和FZ |
JB L2 |
23 24 |
01110000 00001110 |
小于,则跳转到L2处执行 |
MOV 0AH R0 |
25 26 |
10010000 00001010 |
0AH->R1 |
MOV 00H R1 |
27 28 |
10010001 00000000 |
00H->R1 |
L5:MOV2 [R1] R2 |
29 |
10110110 |
([R1])->R2 从地址为R1的存储单元里取数到R2 |
INC R1 |
2A |
11110001 |
(R1)+1->R1 |
OUT1 R2 |
2B |
11001000 |
(R2)->LED |
CMP R1 R0 |
2C |
11010100 |
([R1])-([R0]),锁存FC和FZ |
JB L5 |
2D 2E |
01110000 00101001 |
小于,则跳转到L5处执行 |
L6:OUT1 R2 |
2F |
11001000 |
(R2)->LED |
JMP L6 |
30 31 |
01100000 00101111 |
跳转到L6处执行 |
表3 将汇编语言手工解释的机器代码
(10) 功能仿真波形图及结果分析
以下仿真波形图的测试输入为(34,15,25,92,17,06,83,68,72,87)。
1 程序开始及输入10个数据. 图7中的R0控制循环, R1与用自增, R2用于保存输入的数并送到与R1对应地址的RAM中.
图7 程序开始及输入
2 数的比较。如图8,R0存放外循环的比较次数,R1存放内循环的指针。R2存放每次比较的大数,R3存放与R2比较的下一个数。如果R3>R2则跳转到交换,否则顺序执行。
图8 比较
3 交换两个数。如图9,由于R3种的数25大于R2中的数15,则进行交换。使R2每次存入最大的值后,R3继续读入R1地址的值继续进行比较。
图9 交换两个数
4 结果输出(从小到大),图10中的R0控制循环, R1与用自增, R2用于输出寄存器.结果从QD输出。图中刚好从最小的数06开始输出。
图10 结果输出
其他输入测试
1 有两个相同的数。
输入为(34,15,25,92,83,06,83,68,72,87) 输出正确
2 有零的一组数。
输入为(34,00,25,92,83,06,83,68,72,87) 输出正确
(11) 芯片的引脚分配及操作演示结果分析
1 引脚分配
(12) 故障现象和故障分析
① 数据和地址发送不正确:问题是微指令写错了。
② 写RAM时不能正确写入,在不需要的时候写入了,反而在需要写的时候没有正确输入:问题是控制信号按照书上的写,其实不符合实际情况。才开始以为也是微指令的问题,通过调试,可以看到问题是边沿信号不对。在去掉边沿信号后,变得正常。
③ 仿真时发现数据出错:汇编语言的问题,发现居然有0BH出现。在设计时就知道是不应该出现的。对着指令执行流程图可以发现是设定的外循环错误。只要9次就可以。到10次就会边沿溢出。而程序却要去读0AH中的数而0AH中并没有数,所以出错,程序就无法继续。
④ 警告的去除:原来的程序有很多警告,在多添加控制信号后发现可以消除警告。
⑤ 仿真时到1ms程序停止的问题:由于在开始测试时,为了运行速度,设定的ENDTIME为1ms所致。到1ms后就没有时钟信号了,仿真程序停止运行。而我的程序1ms内并没有运行结束。所以需要延长,而在延长时间后并没有修改时钟信号。同时修改时钟信号后程序正常运行。
⑥ 在最后验收前突然发现两个数不交换了(原来是正常的):对照波形图,发现跳转时地址出错。查看ROM里的源程序,发现跳转代码少了一句(WHEN "00011000" => ROMOUT <= "00001110";)。修改后正确。可能在制作Word文档拷贝源程序或添加注释时不小心删除了。
⑦ 验收时添加一条输出结果,不需要重新编译,只需要重新仿真。当时说重新编译是口误,其实在我的操作过程就是正确的。并没有编译也就是重新仿真。编译只有在改动源代码的时候才需要。
(13) 软件清单
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(
AC, DR: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
S1, S0: IN STD_LOGIC;
BCDOUT: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
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
IF(S1='0' AND S0='0') THEN
BCDOUT <= AC + DR;
AA<='0'&AC;
BB<='0'&DR;
TEMP <= AA + BB;
CY<=TEMP(8);
IF( TEMP ="100000000") THEN
ZI <= '1';
ELSE
ZI <= '0';
END IF;
ELSIF(S1='0' AND S0='1') THEN
BCDOUT <= AC - DR;
AA<='0'&AC;
BB<='0'&DR;
TEMP <= AA - BB;
CY<=TEMP(8);
IF( TEMP ="000000000") THEN
ZI <= '1';
ELSE
ZI <= '0';
END IF;
ELSIF(S1='1' AND S0='0') THEN
AA<='0'&AC;
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
AA<='0'&AC;
TEMP<=AA-1;
BCDOUT<=TEMP(7 DOWNTO 0);
CY<=TEMP(8);
IF( TEMP ="000000000") THEN
ZI <= '1';
ELSE
ZI <= '0';
END IF;
ELSE
BCDOUT <= "00000000";
CY <= '0';
ZI <= '0';
END IF;
END PROCESS;
END A;
2状态条件寄存器子模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY LS74 IS
PORT(
LDFR:IN STD_LOGIC;
CY,ZI:IN STD_LOGIC;
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;
END IF;
END PROCESS;
END A;
3暂存器、通用寄存器、地址寄存器、指令寄存器子模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY LS273 IS
PORT(
D_IN:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
CLK:IN STD_LOGIC;
D_OUT: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
D_OUT<=D_IN;
END IF;
END PROCESS;
END A;
4 时序产生器子模块
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;
5 程序计数器子模块
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;
BUS_IN:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
PCOUT: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<=BUS_IN; --BUS->PC
ELSE
QOUT<= QOUT+1; --PC+1
END IF;
END IF;
END PROCESS;
PCOUT<= QOUT;
END A;
6 选择从PC或BUS中读入数据到AR的选择器子模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY MUX2_1 IS
PORT(
I_D:IN STD_LOGIC;
PC_IN,BUS_IN:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
MUX2_1OUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END MUX2_1;
ARCHITECTURE A OF MUX2_1 IS
BEGIN
PROCESS(I_D,PC_IN,BUS_IN)
BEGIN
IF(I_D='0')THEN
MUX2_1OUT<=BUS_IN;
ELSE
MUX2_1OUT<=PC_IN;
END IF;
END PROCESS;
END A;
7 ROM子模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY ROM16 IS
PORT(
ROMOUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
ADDR:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
RE,CS_I: IN STD_LOGIC
);
END ROM16;
ARCHITECTURE A OF ROM16 IS
BEGIN
PROCESS(RE,CS_I)
BEGIN
IF (RE='0' AND CS_I='0') THEN
CASE ADDR IS
WHEN "00000000" => ROMOUT <= "10010000"; --MOV 0AH R0
WHEN "00000001" => ROMOUT <= "00001010";
WHEN "00000010" => ROMOUT <= "10010001"; --MOV 00H R1
WHEN "00000011" => ROMOUT <= "00000000";
WHEN "00000100" => ROMOUT <= "10000010"; --L1: IN1 R2
WHEN "00000101" => ROMOUT <= "10101001"; --MOV1 R2 [R1]
WHEN "00000110" => ROMOUT <= "11110001"; --INC R1
WHEN "00000111" => ROMOUT <= "11010100"; --CMP R1 RO
WHEN "00001000" => ROMOUT <= "01110000"; --JB L1
WHEN "00001001" => ROMOUT <= "00000100";
WHEN "00001010" => ROMOUT <= "10010000"; --MOV 09H R0
WHEN "00001011" => ROMOUT <= "00001001";
WHEN "00001100" => ROMOUT <= "10010001"; --MOV 00H R1
WHEN "00001101" => ROMOUT <= "00000000";
WHEN "00001110" => ROMOUT <= "10110110"; --L2: MOV2 [R1] R2
WHEN "00001111" => ROMOUT <= "11110001"; --INC R1
WHEN "00010000" => ROMOUT <= "11010001"; --CMP R0 R1
WHEN "00010001" => ROMOUT <= "01110000"; --JB L4
WHEN "00010010" => ROMOUT <= "00011111";
WHEN "00010011" => ROMOUT <= "10110111"; --MOV2 [R1] R3
WHEN "00010100" => ROMOUT <= "11011110"; --CMP R3 R2
WHEN "00010101" => ROMOUT <= "01110000"; --JB L3
WHEN "00010110" => ROMOUT <= "00011001";
WHEN "00010111" => ROMOUT <= "01100000"; --JMP L2 WHEN "00011000" => ROMOUT <= "00001110";
WHEN "00011001" => ROMOUT <= "10101001"; --L3: MOV1 R2 [R1]
WHEN "00011010" => ROMOUT <= "11100001"; --DEC R1
WHEN "00011011" => ROMOUT <= "10101101"; --MOV1 R3 [R1]
WHEN "00011100" => ROMOUT <= "11110001"; --INC R1
WHEN "00011101" => ROMOUT <= "01100000"; --JMP L2
WHEN "00011110" => ROMOUT <= "00001110";
WHEN "00011111" => ROMOUT <= "11100000"; --L4: DEC R0
WHEN "00100000" => ROMOUT <= "10010001"; --MOV 00H R1
WHEN "00100001" => ROMOUT <= "00000000";
WHEN "00100010" => ROMOUT <= "11010100"; --CMP R1 R0
WHEN "00100011" => ROMOUT <= "01110000"; --JB L2
WHEN "00100100" => ROMOUT <= "00001110";
WHEN "00100101" => ROMOUT <= "10010000"; --MOV 0AH R0
WHEN "00100110" => ROMOUT <= "00001010";
WHEN "00100111" => ROMOUT <= "10010001"; --MOV 00H R1
WHEN "00101000" => ROMOUT <= "00000000";
WHEN "00101001" => ROMOUT <= "10110110"; --L5: MOV2 [R1] R2
WHEN "00101010" => ROMOUT <= "11110001"; --INC R1
WHEN "00101011" => ROMOUT <= "11001000"; --OUT1 R2
WHEN "00101100" => ROMOUT <= "11010100"; --CMP R1 R0
WHEN "00101101" => ROMOUT <= "01110000"; --JB L5
WHEN "00101110" => ROMOUT <= "00101001";
WHEN "00101111" => ROMOUT <= "11001000"; --L6: OUT1 R2
WHEN "00110000" => ROMOUT <= "01100000"; --JMP L6
WHEN "00110001" => ROMOUT <= "00101111";
WHEN OTHERS => NULL;
END CASE;
END IF;
END PROCESS;
END A;
8 RAM子模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY RAM IS
PORT(
WR,CS:IN STD_LOGIC;
DIN:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
DOUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
ADDR:IN STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END RAM;
ARCHITECTURE A OF RAM IS
TYPE MEMORY IS ARRAY(0 TO 31) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
PROCESS(CS,WR)
VARIABLE MEM: MEMORY;
BEGIN
IF (CS='0') THEN
IF (WR='0') THEN
MEM(CONV_INTEGER(ADDR(4 DOWNTO 0))):=DIN;
ELSIF(WR='1') THEN
DOUT <= MEM(CONV_INTEGER(ADDR(4 DOWNTO 0)));
END IF;
END IF;
END PROCESS;
END A;
9 选择对ROM或者RAM进行操作的二选一选择器子模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY MUX2_2 IS
PORT(
R_R:IN STD_LOGIC;
ROM_IN,RAM_IN:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
MUX2_2OUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END MUX2_2;
ARCHITECTURE A OF MUX2_2 IS
BEGIN
PROCESS(R_R,ROM_IN,RAM_IN)
BEGIN
IF(R_R='0')THEN
MUX2_2OUT<=ROM_IN;
ELSE
MUX2_2OUT<=RAM_IN;
END IF;
END PROCESS;
END A;
10 五选一选择器子模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY MUX5 IS
PORT(
R0_B,R1_B,R2_B,R3_B,ALU_B:IN STD_LOGIC;
R0_IN,R1_IN,R2_IN,R3_IN,ALU_IN:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
MUX5OUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END MUX5;
ARCHITECTURE A OF MUX5 IS
BEGIN
PROCESS(ALU_B,R3_B,R2_B,R1_B,R0_B)
BEGIN
IF(ALU_B='1' AND R3_B='1' AND R2_B='1' AND R1_B='1' AND R0_B='0') THEN
MUX5OUT<=R0_IN;
ELSIF(ALU_B='1' AND R3_B='1' AND R2_B='1' AND R1_B='0' AND R0_B='1') THEN
MUX5OUT<=R1_IN;
ELSIF(ALU_B='1' AND R3_B='1' AND R2_B='0' AND R1_B='1' AND R0_B='1') THEN
MUX5OUT<=R2_IN;
ELSIF(ALU_B='1' AND R3_B='0' AND R2_B='1' AND R1_B='1' AND R0_B='1') THEN
MUX5OUT<=R3_IN;
ELSIF(ALU_B='0' AND R3_B='1' AND R2_B='1' AND R1_B='1' AND R0_B='1') THEN
MUX5OUT<=ALU_IN;
ELSE MUX5OUT<=ALU_IN;
END IF;
END PROCESS;
END A;
11 一分二分配器子模块源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY FEN2 IS
PORT(
MUX5_IN:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
LED_B,WR: IN STD_LOGIC;
OUT_MUX3,OUT_PUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END FEN2;
ARCHITECTURE A OF FEN2 IS
BEGIN
PROCESS(LED_B)
BEGIN
IF(LED_B='0' AND WR='0') THEN
OUT_PUT<=MUX5_IN;
OUT_MUX3<="00000000";
ELSE
OUT_MUX3<=MUX5_IN;
END IF;
END PROCESS;
END A;
12 三选一选择器子模块
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY MUX3 IS
PORT(
SW_B,CS:IN STD_LOGIC;
FEN2_IN,MUX2_2IN,SW_IN:IN STD_LOGIC_VECTOR(7 DOWNTO 0);
MUX3OUT:OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
);
END MUX3;
ARCHITECTURE A OF MUX3 IS
BEGIN
PROCESS(SW_B,CS)
BEGIN
IF(SW_B='0' AND CS='1') THEN
MUX3OUT<=SW_IN;
ELSIF(SW_B='1' AND CS='0') THEN
MUX3OUT<=MUX2_2IN;
ELSIF(SW_B='0' AND CS='0') THEN
MUX3OUT<=FEN2_IN;
ELSE
MUX3OUT<="11101110";
END IF;
END PROCESS;
END A;
13 CENTER_CONTROL微程序控制单元
1 地址转移逻辑电路ADDR源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY ADDR IS
PORT(
I7,I6,I5,I4:IN STD_LOGIC;
FZ,FC,T4,P1,P2:IN STD_LOGIC;
SE6,SE5,SE4,SE3,SE2,SE1:OUT STD_LOGIC
);
END ADDR;
ARCHITECTURE A OF ADDR IS
BEGIN
SE6<='1';
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源程序
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 控制存储器CONTROM源程序
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(22 DOWNTO 0)
);
END CONTROM;
ARCHITECTURE A OF CONTROM IS
SIGNAL DATAOUT:STD_LOGIC_VECTOR(28 DOWNTO 0);
BEGIN
PROCESS(ADDR)
BEGIN
CASE ADDR IS
WHEN "000000"=>DATAOUT<="11011110011001001111000000010";
WHEN "000010"=>DATAOUT<="00011001011001001011010010000";
WHEN "000011"=>DATAOUT<="11111000010001000001000000000";
WHEN "000100"=>DATAOUT<="11111000111001001011000000000";
WHEN "000101"=>DATAOUT<="11111000001001011001000000110";
WHEN "000110"=>DATAOUT<="11111000011011001111100000000";
WHEN "000111"=>DATAOUT<="11111000111110001001100000000";
WHEN "001000"=>DATAOUT<="11111000111100001001000000000";
WHEN "001001"=>DATAOUT<="00010100011001001011000000000";
WHEN "010000"=>DATAOUT<="00011000111001001011000000000";
WHEN "010110"=>DATAOUT<="11111110011001001111000001001";
WHEN "010111"=>DATAOUT<="11011110011001001111001100000";
WHEN "011000"=>DATAOUT<="11111000111001001101000000000";
WHEN "011001"=>DATAOUT<="11111110011001001111000010000";
WHEN "011010"=>DATAOUT<="11101010001001001001000000011";
WHEN "011011"=>DATAOUT<="11101010010001001001000000100";
WHEN "011100"=>DATAOUT<="11011000010001000110000000000";
WHEN "011101"=>DATAOUT<="11111000010001101001000000101";
WHEN "011110"=>DATAOUT<="11111000001001101001000000111";
WHEN "011111"=>DATAOUT<="11111000001001101001000001000";
WHEN "100000"=>DATAOUT<="00010100011001001011000000000";
WHEN "110000"=>DATAOUT<="11111000011001001111000000000";
WHEN OTHERS =>DATAOUT<="11111000011001001111000000000";
END CASE;
UA(5 DOWNTO 0)<=DATAOUT(5 DOWNTO 0);
D(22 DOWNTO 0)<=DATAOUT(28 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;
DIN:IN STD_LOGIC_VECTOR(22 DOWNTO 0);
P1 , P2, 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, CS_I, I_D, R_R, RE : OUT STD_LOGIC
);
END MCOMMAND;
ARCHITECTURE A OF MCOMMAND IS
SIGNAL DATAOUT:STD_LOGIC_VECTOR(22 DOWNTO 0);
BEGIN
PROCESS(T2)
BEGIN
IF(T2'EVENT AND T2='1') THEN
DATAOUT(22 DOWNTO 0)<=DIN(22 DOWNTO 0);
END IF;
P2<=DATAOUT(0);
P1<=DATAOUT(1);
LDFR<=DATAOUT(2)AND T4;
LED_B<=DATAOUT(3);
SW_B<=DATAOUT(4);
CS<=DATAOUT(5);
WR<=NOT(NOT DATAOUT(6)AND T3);
LDDR<=DATAOUT(7)AND T4;
LDAC<=DATAOUT(8)AND T4;
ALU_B<=DATAOUT(9);
S0<=DATAOUT(10);
S1<=DATAOUT(11);
R3_B<=(DATAOUT(13)OR(NOT I1)OR (NOT I0))AND(DATAOUT(12)OR(NOT I3)OR (NOT I2));
R2_B<=(DATAOUT(13)OR(NOT I1)OR I0)AND(DATAOUT(12)OR(NOT I3)OR I2);
R1_B<=(DATAOUT(13)OR I1 OR(NOT I0))AND(DATAOUT(12)OR I3 OR(NOT I2));
R0_B<=(DATAOUT(13)OR I1 OR I0)AND(DATAOUT(12)OR I3 OR I2);
LDR3<=T4 AND DATAOUT(14)AND I1 AND I0;
LDR2<=T4 AND DATAOUT(14)AND I1 AND (NOT I0);
LDR1<=T4 AND DATAOUT(14)AND (NOT I1) AND I0;
LDR0<=T4 AND DATAOUT(14)AND (NOT I1) AND (NOT I0);
LDIR<=DATAOUT(15)AND T3;
LDAR<=DATAOUT(16)AND T3;
LDPC<=DATAOUT(17)AND T4;
LOAD<=DATAOUT(18);
I_D<=DATAOUT(19);
R_R<=DATAOUT(20);
CS_I<=DATAOUT(21);
RE<=DATAOUT(22);
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(
DIN_IR: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<=DIN_IR(7);
UA6<=DIN_IR(6);
UA5<=DIN_IR(5);
UA4<=DIN_IR(4);
UA3<=DIN_IR(3);
UA2<=DIN_IR(2);
UA1<=DIN_IR(1);
UA0<=DIN_IR(0);
END A;
(14) 总结
在为期4个星期的实验时间里,我在老师的细心指导和同学们的耐心帮助之下成功完成了本次实验,并能得到预期的实验结果。在这段时间内,我努力学习了计算机系统结构,VHDL等相关的各项知识,也查阅不少资料,掌握了设计软件MAX+plus II的使用。通过本次实验的设计,使我对计算机系统结构的有了进一步的了解,也对CISC模型微处理器的设计以及其内部运作有了一个初步的理解,能够将课堂上所学的知识运用于实际的设计中,能够很好的进行理论联系实际进行开发。最后,我对曾经给予我帮助的同学和给予我细心指导的老师表示衷心的感谢。
补充说明:
文中的指令编码和控制器中的地址编码有对应关系的。通过指令寄存器及译码器获得控制器中微地址。参看地址转移逻辑电路ADDR源程序