上学期期末做的,这学期又要学汇编😅,这都快忘光了,复习一下。
一. 课设题目
设计并实现具有以下16条指令的指令集结构的模型计算机:
二. 检查方式
跑两个指定的测试程序,要求实验箱显示正确结果。如果题目不变的话,测试13条非转移指令的测试程序结果为:寄存器R0-R3分别显示00、11、22、33,IOH显示33。测试3条转移指令的测试程序结果为:寄存器R0-R3分别显示00、11、22、33,若显示EE则程序有误。
三. 设计思路
其实前12条指令加上最后一条HALT停机指令都没有什么难度,如果前面的计组实验是认真做过的应该很快能搞定。这里的HALT指令我是偷鸡做的,因为CMStudio里的MXJ4.IS自带这条HALT指令,并且恰好在所需要的07E0H这个位置,所以我这个课设其实是基于MXJ4这一条HALT再去做的其他15条指令的。
1.微指令起始入口(0000H~0001H)
不过也有同学是直接从头到尾自己写的微指令文件,出现了一个很神奇的问题就是:
程序入口语句0001H此处的uPC,正常来说是填的程序入口地址,即第一条汇编指令的微指令地址(0600H),如果此处是手写的,很可能出现忘了将+1改成0600H的情况。导致脱机时完全没有问题,联机微单步运行大概7、8步之后运行顺序紊乱。
经过与老师探讨,此处的问题貌似是软件硬件状态不匹配,若uPC为+1,硬件执行指令时,需要多次自增以达到指令位置(大概就是要等他慢慢+1+1一直加到比如0600H这样才行),而软件仅能以一条汇编指令为单位运行,出现了汇编指令栏运行结束、微指令还不知道在哪的问题。
2.SUB指令(0600H~0602H)
减法指令,取数、取数、相减、放回目标寄存器。这里要注意的是此处取数的总线规则。为什么同样能取R0寄存器,一个是偶送偶、一个是奇送偶呢?
如果你认真思考我这个问题那说明你还没有完全理解。此处偶送偶、奇送偶其实只是表象,SUB指令的指令码是0000RdRs,取数是从Rd取还是从Rs取其实是看XP、OP控制位的,但是这两个控制位的改变会导致总线规则的改变,于是表现出偶送偶和奇送偶的差异。
3.ADD指令、AND指令同SUB指令,不再赘述。
4.DEC指令,其实也就是从寄存器里取数送到ALU计算后送回寄存器而已,比较简单,CLR指令同理。
5.RL、RR指令。还是同上,取数计算送回。但是这里有个比较奇怪的bug就是,RL循环左移指令是完全没有问题的,但是RR循环右移指令在CMStudio脱机运行时ALU输出会直接消失,不管什么数进去,输出都是0000H。而带进位右移RRC指令则可以正常运行,原因不明,忘了当时是否有联机测试过RR指令。总之最后老师修改了课设要求,从RL、RR改成了RL、RRC,于是也不了了之。
6.MOV指令。注意控制位,直接源寄存器送目标寄存器就行,不用拿别的寄存器中转。
7.LDI指令。将指令中的立即数送入Rd。首先要注意到,这条指令的机器指令码为1000 Rd00 XXXX XXXX,为两字节的指令,即指令长度为2。同时,指令中的立即数,立即数即为指令码中XXXX XXXX这一段。要注意到的是,指令和数据(立即数),本质上都是0/1字符,都是储存在程序存储器(ROM)中的,所以此处的取立即数,需要在执行指令时,取出当前指令的下一个ROM单元内的数据,例如这条指令它存在了ROM中00H和01H号单元中,那么00H存放的即为1000 Rd00这一段指令码,而01H中即为指令所操作的立即数。需要注意的是,ROM(程序存储器)和RAM(数据存储器)每个单元均只能存放一字节数据(其实寄存器也是,R0-R7都是只能存放一字节数据,在本实验中你所能看到的AX、BX、CX、DX其实都是两个寄存器所组成的,容易给人一种错觉就是一个寄存器能存放两字节数据)。同时,由于本条指令的指令长度为2(占据两个ROM单元),需要在指令执行过程中手动将PC自增,否则会出现找不到下一条指令的情况。因为正常执行完一条指令总会回到0000H-0001H,而在0001H处PC自增是为了寻找下一条指令所存放的ROM单元,但是本条指令长度为2,自增一次时所读取到的ROM单元存放的是当前指令的操作数(立即数),将操作数当作指令执行于是出现问题。同理,若指令长度为3,则需要在执行过程中自增两次,自增位置视情况而定。
8.OUT指令。Rs送IOH,没啥好说的,注意控制位和总线规则,送IO口高位,别送到低位了。
9.LDA指令。数据存储器单元中的数据送寄存器。
此处要注意的是,首先这是一条长度为3的指令,需要在过程中自增两次。同时,要从数据存储器中取数,必须要先知道数据存放的单元地址,而数据地址长度为两字节,从程序存储器中取出数据时只能取一字节,所以还需要进行拼地址的操作。先从ROM的第一个单元(假设为00H)取出数据地址的低八位,送到AL/BL;再将PC自增,从ROM的第二个单元(01H)取出数据地址的高八位,送到AH/BH拼成两字节的数据地址(此处显示为TmpB=ROM,PC++;但实际运行顺序是PC++,TmpB=ROM)。拼完地址后由ALU送AR地址寄存器,再由该地址取出预先存放在该地址单元的数据(注意E/M控制位,此控制位决定是从ROM取数据还是从RAM取数据)。
10.STA指令。寄存器数据送数据存储器单元。其实就是把LDA指令的最后一步反一下,前面仍旧是拼地址、送AR,只是最后一步从RAM送寄存器变成了从寄存器送RAM。
11.JMP指令。跳转。其实跟上面两条差不多,也是拼地址,只是这时候不送AR地址寄存器而是直接送PC了。
12.JC/JZ指令。带控制跳转。其实就是加一个判断条件的跳转,条件成立就是普通的JMP,条件不成立则直接跳过当前指令不执行。直接在变址位置选择CY标志变址/Z标志变址,当CY标志/Z标志亮起时,视为1,此时会将这个1填入下址段ud0位置,与原本填在uPC位置的ud10~ud1组成真正的下址段进行跳转,简单来说就是,如果uPC填了0000H,那么此时最后一位(二进制位)为0,当CY/Z亮起时,最后一位被填入1,则为0001H,跳转到0001H执行;若CY/Z不亮,则正常跳转到0000H执行。倒是没有试过如果末位本来是1的情况,猜想应该是末位加上控制位而不是直接变成控制位(ud0+1/ud0+0而不是ud0=1/ud0=0)。
13.HALT指令。停机指令。其实就是一个死循环,指令过程中使得PC-1,而指令执行后跳转回0001H时又使得PC+1,循环往复一直执行HALT指令,达到停机效果。
四. 遇到的问题
软件脱机模拟的时候,AL+BL送ALU,然后再从ALU输出的过程中,若从ALU的高位输出,则AL+BL的结果也会送到FUN的高位(即总线规则若是从ALU的高位输出数据,ALU的运算结果也会送到高位),进而输出;但硬件联机时发现,若从高位输出,AL+BL仍会送到FUN的低位(即总线规则不影响运算结果,运算结果总是送到低位),导致程序出现问题。
软件脱机时,ADD/SUB指令可以使用暂存器(TmpA、TmpB)也可以使用寄存器(AX、BX)相加/减,此时发生进位/结果为0时CY/Z灯亮持续到下一次使用ALU;但硬件联机时,若使用暂存器,在离开当前指令时ALU会被清空(这恒河里,说了是暂存器,就是用完就丢的,暂存器谁给你保存状态啊,吃饱了撑的),CY/Z灯也会随之熄灭,导致JC/JZ变址不能达到理想结果。
五. 微码及检查程序源文件
https://github.com/LuHawXem/Principle-of-Computer-Composition-Course-Design---2020
https://gitee.com/LuHawXem/Principle-of-Computer-Composition-Course-Design---2020
发布时间: 2021-03-09
最后更新: 2022-01-09
本文标题: 计算机组成原理与体系结构课程设计
本文链接: https://cloudflare.luhawxem.com/2021/03/09/PrincipleOfComputerOrganizationCourseDesign/
版权声明: 本作品采用 CC BY-NC-SA 4.0 许可协议进行许可。转载请注明出处!