这个学期陆陆续续做了好多课设,软硬件、跑模型的都有,看看后面有没有时间都写成博客发出来,github上也把源码传上去~
首先是计算机组成原理的课程设计,是我这个学期做的第一个课设,浅浅分享一下:
一、实验内容
- 设计并实现一套完整的指令系统;
- 设计并实现完整的计算机(采用上述指令系统);
- 利用该计算机实现 二分查找 ,即利用二分查找的原理,确定一个目标数是否存在于一个有序数组中,若存在则输出该数地址,不存在则输出EF。
二、实验原理
1.指令设计
模型机指令分为3大类:运算类指令、控制转移类指令和数据传送类指令。运算类指令包含3种运算,算术运算、逻辑运算和移位运算。在本复杂模型机中,修改后的运算类指令共有6条,分别为ADD、DEC、INC、SUB、OR、SHR,所有运算类指令都为单字节指令,其寻址方式采用直接寻址。控制转移类指令有3条:HLT、JMP、BZC,用以控制程序的分支和转移,其中HLT为单字节指令,JMP和BZC为双字节指令。数据传送类指令有6条:IN、OUT、MOV、LDI、LAD、STA,用以完成寄存器和寄存器、寄存器和I/O设备、寄存器和存储器之间的数据交换,除了MOV指令为单字节指令以外,其余指令均为双字节指令。
2.指令格式
所有单字节指令(ADD、DEC、INC、SUB、OR、SHR、HLT和MOV)的格式:
I7 | I6 | I5 | I4 | I3 | I2 | I1 | I0 |
OP-CODE | RS | RD |
RS或RD选定的寄存器:
RS或RD | 选定的寄存器 |
00 | R0 |
01 | R1 |
10 | R2 |
11 | R3 |
双字节指令格式
指令 | I7 - I4 | I3 - I2 | I1 I0 | I7 - I0 |
IN/OUT | OP-CODE | RS | RD | P(I/O端口号) |
LDI | OP-CODE | RS | RD | data |
LAD/STA/JMP/BZC | OP-CODE | M | RD | D |
用到的寻址模式:
寻址模式M | 有效地址E | 说明 |
00 | E=D | 直接寻址 |
01 | E=(D) | 间接寻址 |
3.指令描述
(标红的为修改后的指令)
汇编符号 | 指令格式 | 指令功能 |
MOV RD, RS ADD RD, RS SUB RD, RS DEC RD SHR RD, RS INC RD | 0100 RS RD 0000 RS RD 1000 RS RD 0001 ** RD 1010 RS RD 0111 ** RD | RS→RD RD + RS→RD RD – RS→RD RD – 1→RD RS逻辑右移1位→RD RD + 1→RD |
LAD M D, RD STA M D, RS JMP N D BZC M D | 1100 M RD D 1101 M RD D 1110 M ** D 1111 M ** D | E→RD RD→E E→PC 当FC=1或FZ=1时, E→PC |
IN RD, P OUT P, RS | 0010 ** RD P 0011 RS ** P | [P]→RD RS→[P] |
LDI RD, D | 0110 ** RD D | D→RD |
HALT | 0101 ** ** | 停机 |
4.微程序流程图
(平板改的 有点丑hhh)
5.微指令格式
1.每条微指令的格式:
23 | 22 | 21 | 20 | 19 | 18-15 | 14-12 | 11-9 | 8-6 | 5-0 |
M23 | CN | WR | RD | IOM | S3-S0 | A字段 | B字段 | C字段 | UA5-UA0 |
A字段 | B字段 | C字段 | |||||||||
14 | 13 | 12 | 选择 | 11 | 10 | 9 | 选择 | 8 | 7 | 6 | 选择 |
0 | 0 | 0 | NOP | 0 | 0 | 0 | NOP | 0 | 0 | 0 | NOP |
0 | 0 | 1 | LDA | 0 | 0 | 1 | ALU_B | 0 | 0 | 1 | P<1> |
0 | 1 | 0 | LDB | 0 | 1 | 0 | RS_B | 0 | 1 | 0 | P<2> |
0 | 1 | 1 | LDRi | 0 | 1 | 1 | RD_B | 0 | 1 | 1 | P<3> |
1 | 0 | 0 | 保留 | 1 | 0 | 0 | RI_B | 1 | 0 | 0 | 保留 |
1 | 0 | 1 | LOAD | 1 | 0 | 1 | 保留 | 1 | 0 | 1 | LDPC |
1 | 1 | 0 | LDAR | 1 | 1 | 0 | PC_B | 1 | 1 | 0 | 保留 |
1 | 1 | 1 | LDIR | 1 | 1 | 1 | 保留 | 1 | 1 | 1 | 保留 |
2.微指令二进制代码(标红的为修改后的微指令)
地址 | 十六进制表示 | 高五位 | S3-S0 | A 字段 | B 字段 | C 字段 | UA5-UA0 |
00 | 00 00 01 | 00000 | 0000 | 000 | 000 | 000 | 000001 |
01 | 00 6D 43 | 00000 | 0000 | 110 | 110 | 101 | 000011 |
03 | 10 70 70 | 00010 | 0000 | 111 | 000 | 001 | 110000 |
04 | 00 24 05 | 00000 | 0000 | 010 | 011 | 000 | 000101 |
05 | 04 B2 01 | 00000 | 1001 | 011 | 001 | 000 | 000001 |
06 | 06 32 01 | 00000 | 1100 | 011 | 001 | 000 | 000001 |
07 | 01 32 01 | 00000 | 0010 | 011 | 001 | 000 | 000001 |
08 | 10 60 09 | 00010 | 0000 | 110 | 000 | 000 | 001001 |
09 | 18 30 01 | 00011 | 0000 | 011 | 000 | 000 | 000001 |
0A | 10 60 10 | 00010 | 0000 | 110 | 000 | 000 | 010000 |
0B | 00 00 01 | 00000 | 0000 | 000 | 000 | 000 | 000001 |
0C | 10 30 01 | 00010 | 0000 | 011 | 000 | 000 | 000001 |
0D | 20 06 01 | 00100 | 0000 | 000 | 001 | 100 | 000001 |
0E | 00 53 41 | 00000 | 0000 | 101 | 001 | 101 | 000001 |
0F | 00 00 CB | 00000 | 0000 | 000 | 000 | 011 | 001011 |
10 | 28 04 01 | 00101 | 0000 | 000 | 010 | 000 | 000001 |
11 | 10 30 01 | 00010 | 0000 | 011 | 000 | 000 | 000001 |
12 | 06 B2 01 | 00000 | 1101 | 011 | 001 | 000 | 000001 |
13 | 00 24 14 | 00000 | 0000 | 010 | 011 | 000 | 010100 |
14 | 05 B2 01 | 00000 | 1011 | 011 | 001 | 000 | 000001 |
15 | 00 24 16 | 00000 | 0000 | 010 | 011 | 000 | 010110 |
16 | 01 B2 01 | 00000 | 0011 | 011 | 001 | 000 | 000001 |
17 | 00 24 18 | 00000 | 0000 | 010 | 011 | 000 | 011000 |
18 | 03 32 01 | 00000 | 0110 | 011 | 001 | 000 | 000001 |
1B | 00 53 41 | 00000 | 0000 | 101 | 001 | 101 | 000001 |
1C | 10 10 1D | 00010 | 0000 | 001 | 000 | 000 | 011101 |
1D | 10 60 8C | 00010 | 0000 | 110 | 000 | 010 | 001100 |
1E | 10 60 1F | 00010 | 0000 | 110 | 000 | 000 | 011111 |
1F | 10 10 20 | 00010 | 0000 | 001 | 000 | 000 | 100000 |
20 | 10 60 8C | 00010 | 0000 | 110 | 000 | 010 | 001100 |
28 | 10 10 29 | 00010 | 0000 | 001 | 000 | 000 | 101001 |
29 | 00 28 2A | 00000 | 0000 | 010 | 100 | 000 | 101010 |
2A | 04 E2 2B | 00000 | 1001 | 110 | 001 | 000 | 101011 |
2B | 04 92 8C | 00000 | 1001 | 001 | 001 | 010 | 001100 |
2C | 10 10 2D | 00010 | 0000 | 001 | 000 | 000 | 101101 |
2D | 00 2C 2E | 00000 | 0000 | 010 | 110 | 000 | 101110 |
2E | 04 E2 2F | 00000 | 1001 | 110 | 001 | 000 | 101111 |
2F | 04 92 8C | 00000 | 1001 | 001 | 001 | 010 | 001100 |
30 | 00 16 04 | 00000 | 0000 | 001 | 011 | 000 | 000100 |
31 | 00 16 06 | 00000 | 0000 | 001 | 011 | 000 | 000110 |
32 | 00 6D 48 | 00000 | 0000 | 110 | 110 | 101 | 001000 |
33 | 00 6D 4A | 00000 | 0000 | 110 | 110 | 101 | 001010 |
34 | 00 34 01 | 00000 | 0000 | 011 | 010 | 000 | 000001 |
35 | 00 00 35 | 00000 | 0000 | 000 | 000 | 000 | 110101 |
36 | 00 6D 51 | 00000 | 0000 | 110 | 110 | 101 | 010001 |
37 | 00 16 12 | 00000 | 0000 | 001 | 011 | 000 | 010010 |
38 | 00 16 13 | 00000 | 0000 | 001 | 011 | 000 | 010011 |
39 | 00 16 15 | 00000 | 0000 | 001 | 011 | 000 | 010101 |
3A | 00 16 17 | 00000 | 0000 | 001 | 011 | 000 | 010111 |
3B | 00 00 01 | 00000 | 0000 | 000 | 000 | 000 | 000001 |
3C | 00 6D 5C | 00000 | 0000 | 110 | 110 | 101 | 011100 |
3D | 00 6D 5E | 00000 | 0000 | 110 | 110 | 101 | 011110 |
3E | 00 6D 68 | 00000 | 0000 | 110 | 110 | 101 | 101000 |
3F | 00 6D 6C | 00000 | 0000 | 110 | 110 | 101 | 101100 |
3.微指令修改分析
由于利用该计算机实现折半查找并不需要用到AND和RR这两条机器指令,因此我将AND的与功能改为DEC的自减功能,将RR的右环移功能改为SHR的逻辑右移一位功能。具体的微指令修改如下:
微指令一:06,将此条微指令的功能改为自减。
高五位不变;S3-S0部分根据运算器逻辑功能表改为功能F=A-1对应的1100;A字段改为LDRi的011,B字段改为ALU_B的001,C字段不变;UA5-UA0改为000001。
微指令二:18,将此条微指令的功能改为逻辑右移一位。
高五位不变;S3-S0部分根据运算器逻辑功能表改为逻辑右移一位对应的0110;ABC字段都不变;UA5-UA0不变;。
三、源代码
机器程序
;init
$P 00 20 ;IN R0 00H 从IN单元输入要查找的数到R0
$P 01 00
$P 02 D0 ;STA 6FH,R0 将目标数存入6FH中
$P 03 6F
$P 04 61 ;LDI R1,60H 将首地址60H存入R1
$P 05 60
$P 06 62 ;LDI R2,6EH 将尾地址6EH存入R2(都是立即寻址)
$P 07 6E
;comparing
$P 08 44 ;MOV R0,R1
$P 09 89 ;SUB R1,R2 R1-R2
$P 0A F0 ;BZC为有条件跳转 若R1-R2<=0, 跳转继续查找
$P 0B 0E ;跳转到countmid
$P 0C E0 ;JMP无条件跳转R1-R2>0,找不到目标数跳转结束
$P 0D 31 ;跳转到notfind
;countmid
$P 0E 41 ;MOV R1 R0 将R0中的首地址存入R1
$P 0F 09 ;ADD R1,R2 将首地址和尾地址相加并存入R1
$P 10 47 ;MOV R3,R1 将R1中的首尾地址和存入R3
$P 11 AD ;SHR R1,R3 将R3中的地址和除以2得到折中地址并存入R1
$P 12 D1 ;STA 70,R1 将R1中的折中地址存入地址70中
$P 13 70
$P 14 C5 ;LAD R1 (70) 通过间接寻址把地址70H中的折中地址对应的中间数存入R1
$P 15 70
$P 16 C3 ;LAD R3,6F 通过直接寻址将地址6F中存放的目标数放R3
$P 17 6F
$P 18 87 ;SUB R3,R1 R3-R1
$P 19 F0 ;BZC R3-R1<=0向左继续查找(包含找到的情况)
$P 1A 20 ;跳转到leftsearch
;rightsearch 否则为R3-R1>0的情况 向右继续查找
$P 1B C1 ;LAD R1,70 把地址70中的折中地址存入R1
$P 1C 70
$P 1D 71 ;INC R1 A+1 把R1中的折中地址右移一位作为新的左边界
$P 1E E0 ;JMP
$P 1F 08 ;返回Comparing重新比较
;leftsearch
$P 20 C3 ;LAD R3,6F
$P 21 6F
$P 22 8D ;SUB R1,R3
$P 23 F0 ;BZC 若R1-R3=0说明找到该数,跳转结果
$P 24 2C ;跳转到find
$P 25 C1 ;LAD R1,70 不相等则继续往左找
$P 26 70
$P 27 11 ;DEC R1 A-1 把R1中的折中地址左移一位作为新的右边界
$P 28 46 ;MOV R2,R1
$P 29 41 ;MOV R1,R0
$P 2A E0 ;JMP
$P 2B 08 ;返回Comparing重新比较
;find
$P 2C C0 ;LAD R0,70 将查找到的目标数地址存入R0
$P 2D 70
$P 2E 30 ;OUT 40H,R0 在out单元显示
$P 2F 40
$P 30 50 ;HLT 停机
;notfind
$P 31 60 ;LDI R0,EF 立即寻址 直接将EF存入R0
$P 32 EF
$P 33 30 ;OUT 40H,R0 在out单元显示
$P 34 40
$P 35 50
; 地址60H-6EH中存放15个升序的非连续整数
$P 60 10 ; 初始首地址
$P 61 15
$P 62 17
$P 63 25
$P 64 28
$P 65 33
$P 66 36
$P 67 40
$P 68 43
$P 69 46
$P 6A 51
$P 6B 56
$P 6C 58
$P 6D 60
$P 6E 62 ; 初始尾地址
最后的结果就不展示了,可以在软件与硬件显示器中显示~