XDU:零基础速通计算机组成课程设计
写在开头
这学期开头发现有一周周末课表排满了(内心OS:吓哭了),课程叫做“计算机组织与体系结构课程设计”,一周下午满的,一周周六周日满的。第一次去老师就开始沉浸在他自己的艺术里了,讲了好久下面同学玩手机的玩手机,睡觉的睡觉,然后有同学给老师反映上学期就没做过计组的实验为当前知识铺垫(老师:请输入文本),然后第一节课就草率结束了。在结束前的半小时连续两个同学来问我机器怎么开我是真没绷住(好吧,其实我也问了其他人机器怎么开),下面就来介绍我是怎么在最后两次课(周六周日)弄懂这玩意并且做出实验设计的吧。
选题
这个课程说实话还是有一些好玩的,它给了你一个CPU的实现(硬件实现和vhdl等),然后给你了一个实验箱,让你自己编一个指令集,并且完成microcode的编写,有几个题目,建议选第一个,因为大家都选的第一个(基本模型机设计与实现),简单易上手(你选其他的到时候出问题了只能找老师了)。
讲义 XidianCS/集中实验环节/计算机组织与体系结构课程设计 at master · SincereXIA/XidianCS
如何操作
本文将教会你如何不听老师说任何话来独立完成这个课程设计。我说你做,非常公式化,但是你别直接抄,因为抄指令集真的很容易被看出来(如果你自己做了一套的话),还有就是你把ADD改成SUB,如果你看得懂microcode,你随便改,但是如果你看不懂microcode,你只敢改一点点,你就凉了,所以核心是看懂microcode,好的我们先来看一下实验要求。
1.深入理解基本模型计算机的功能、组成知识;
2.深入学习计算机各类典型指令的执行流程;
3.学习微程序控制器的设计过程和相关技术,掌握LPM_ROM的配置方法。
4.在掌握部件单元电路实验的基础上,进一步将单元电路组成系统,构造一台基本模型计算机。
5.定义五条机器指令,并编写相应的微程序,上机调试,掌握计算机整机概念。掌握微程序的设计方法,学会编写二进制微指令代码表。
6.通过熟悉较完整的计算机的设计,全面了解并掌握微程序控制方式计算机的设计方法。理论上来说,你的电脑C盘下会有一个计组课设的文件夹,点进去找到CH5_Expt->DEMO51_CPU5,整个文件夹复制到D盘你自己取一个名字的文件夹,因为C盘重启就清空了,然后打开设计的软件,File->Open,选择类型选第二个(xxxx Project),然后进你文件夹你发现有个CPU5A就是了,双击即可打开Project,然后左上角双击打开View,然后你会看到一个硬件实现,找到RAM,双击它,在mem_init阶段即可选择xxx.MIF(就在你文件夹内),我们选RAM_1.MIF,这样选后可以设置RAM的初始内存,RAM里面装的是你的汇编指令代码(不是microcode),然后有个长条形状的(处理器),双击进去,会展开一个新视图,里面有个ROM,双击ROM,和上面一样,选择ROM_5.MIF,这是microcode,microcode是4个字节一组的,保存,这个RAM和ROM是原装的测试程序,和讲义上一样,然后在软件最上面一栏,你要自己找到如何刷入你的实验箱(记得先在侧面启动试验箱电源并连上USB线),刷入后即可看我们的实验箱,上面出现计组xxxx的字符串,下面一堆寄存器的名称和数字就代表你刷入成功了,之后你更改RAM和ROM,每一次都要进行刷入。
注:建议去实验带一个U盘,把你的文件拷到你U盘里面而不是放D盘,要是遇到神人给你全删了你不老实了?

整个项目 BE LIKE
接下来你要懂怎么操作实验箱,实验箱下面有很多个按钮,首先你得把左边有个LED的那个调成0(实验模式),要不然你根本弄不了。然后最左边的按钮是RST(键8),如果它开着就一直重置环境,所以要重置得先开再关,然后把3和4按钮打开,3和4按钮分别是SWA和SWB,因为原装程序是有控制台微指令的,这个很臃肿,是为了让你手动一个一个输入RAM,我们在之后的设计中需要把它去掉,因为我们刷入的话是不需要手动的。SWA和SWB设置为11代表启动程序。(注:原装程序和讲义上的一样,看讲义就行),对于microcode,讲义有很多错误,请自行理解.jpg。

然后你就可以开始调试了,按按键7,每按两次产生一个脉冲(2次单步),然后屏幕上MC(microcode,微代码)表示正在运行的微代码,然后看讲义,原装的RAM+ROM讲解的很清楚。

RAM中的指令

ROM中的指令树
这两个图很重要,我们先讲解ROM,不要把微指令和RAM中的汇编搞混,你可以理解为两套系统,微指令从00微地址开始,MC会显示当前微指令的代码,验收的时候也是看这个走哪条流程的。所以按照上面的图,微指令会先从操作台微程序开始,然后走一个P(4)的选择结构,这个选择结构会按照SWA和SWB的开关选择一个分支,如果是11(也就是正常执行程序),则会跳到运行微程序的地方,所以这就是我说的我们的课程设计完全可以去掉操作台微程序的原因。
下来的代码块我们学过计组的都知道是取指令(01和02),然后P(1)是一个非常关键的东西,他会根据IR(指令寄存器)里面的值来选择分支,如果IR里面是0x00就选10分支,如果是0x10就选11分支,以此类推,但是你要注意了,这个10,11是八进制而不是0x10的十进制。先别问为什么,我们先说完。
IN指令就是从按钮1和按钮0(最右边的俩按钮)输入一个字节到R0,很容易理解,按钮1和按钮0不是简单的开关,而是一个十六进制输入的地方,你多按几下就知道了,按钮1是高8位,按钮0是低8位。
然后我们讲一下ADD指令,ADD指令的字节码显然是0x10,然后它接下来又取址了,也就是操作数(这里不是IR而是AR),也就是代表这个指令是一个双字节指令,它会把你的操作数和R0的值相加然后放回去。
STA就是把你的R0放到它指定的内存地址。
OUT就是把指定的内存地址输出到OUT(你可以看屏幕上有,这个作为验收的展示结果我认为必须要有)。
JMP很好理解,就是直接改PC,PC指向RAM中当前运行到的指令的地址。
这些microcode经过精心编址和跳转,完美的实现了这几条指令。
下面我们说RAM中的指令,其实这个你可以设计的很简单,把这几个指令从上到下测试一下就行,最后一个JMP,可以跳回开头。
设计微指令与程序
如何设计一个非常优美的微指令呢?首先你得先想好你要做哪几个指令(课程要求不少于等于5个)。
我们首先肯定要IN,OUT,这已经两条了,然后把ADD修改一下成其他的,再来个JMP,你要闲的没事可以做一个PUSH和POP的栈操作,可以看下面这篇文章。(西电计组课设 计科 模拟栈 - Genghong Hu's Blog)甚至你可以做一个条件跳转指令,这个需要读ALU的Flag,我懒得弄了,讲义里面应该有,但是不是第一个选题讲的。
好的,假设我们选择下面几个指令

“假设”我们选择的指令集
为什么选这几个,因为经过深思熟虑我选的是这几个,上图已经非常详细的解释了这几个的作用,核心指令当然是我们的NAND(这个是一个逻辑万用门,所有的逻辑指令都可以用这个完成),你们做的时候换个其他的,别用这个了,感觉老师应该会记得。
好的,我们先看懂微指令的字节码是怎么编写的。

原装微指令指令集
我们可以看到原装指令集的微指令,微指令就是右边那些01的十六进制表示,我们只需要对照着微指令树即可学懂。
除此之外我们还要看懂ABC字段:

微指令 A B C 字段详解
我们可以对应着微指令树来解读,比如01的微指令,ABC分别是 110 110 110,意思分别是LDAR, PC-B, LDPC,再结合树里面写的PC->AR,PC+1来揣测它的意思,或者你在讲义里面搜LDAR也能看到解释。但是作为速通玩家我们不看这个ABC字段就能搞,下面我来说一下方案。
首先我们拿到原装微指令树,可以从里面找我们想要的节点,扣出来放到自己的微指令树里面就行。你只需要给它们重新编一个地址,然后把微指令的低六位(下一个地址)给改掉即可,画微指令图就选draw.io,下面是我一中午设计出来的:

笔者设计的微指令流程图
你可以看到我也忘了改05里面的IR(应该是AR)。不过注意一下,讲义的原装Microcode指令表里面有一个二进制位是错的,但是微指令的十六进制是对的,请自行观察发现。
其实我就做了两个创新(原图里面没有的),心细的读者应该可以发现是16和21,接下来我将讲解这俩是咋搞出来的。
首先是16,之前是一个加法,经过我更改改成了一个NAND,你可以注意到微指令的S3~S0其实可以有16种可能,这其实是给ALU的参数,选择ALU中的算法。打开ALU181.vhd就可以看到:
module ALU181A (S, A, B, F, M, CN, CO, FZ);
input[3:0] S; input[7:0] A,B; input M, CN;
output[7:0] F; output CO, FZ;
wire[7:0] F; wire CO;wire[8:0] A9, B9; reg FZ; reg[8:0] F9;
assign A9 = {1'b0, A} ; assign B9 = {1'b0, B} ;
always @(M or CN or A9 or B9 or S) begin
case (S)
4'b0000 : if (M==0) F9<=A9+CN ; else F9<=~A9;
4'b0001 : if (M==0) F9 <= (A9 |B9) + CN ; else F9<=~(A9 | B9) ;
4'b0010 : if (M==0) F9 <= (A9 |(~B9))+ CN; else F9<=(~A9) & B9 ;
4'b0011 : if (M==0) F9 <= 9'b000000000-CN; else F9<=9'b000000000;
4'b0100 : if (M==0) F9 <=A9+(A9 & ~B9)+CN; else F9<=~(A9 & B9) ;
4'b0101 : if (M==0) F9<=(A9|B9)+(A9& ~B9)+CN; else F9<= ~B9 ;
4'b0110 : if (M==0) F9 <= A9 - B9 - CN ; else F9<= A9 ^ B9 ;
4'b0111 : if (M==0) F9 <= (A9 & (~B9)) - CN ; else F9<= A9 & (~B9) ;
4'b1000 : if (M==0) F9 <= A9 + (A9 & B9)+CN ; else F9<= (~A9) | B9 ;
4'b1001 : if (M==0) F9 <= A9 + B9 + CN ; else F9<= ~(A9 ^ B9) ;
4'b1010 : if (M==0) F9<=(A9|(~B9))+(A9&B9)+CN; else F9<= B9 ;
4'b1011 : if (M==0) F9 <= (A9 & B9) - CN ; else F9<=A9 & B9 ;
4'b1100 : if (M==0) F9 <= A9 + A9 + CN ; else F9<=9'b000000001 ;
4'b1101 : if (M==0) F9 <= (A9 | B9)+A9+CN; else F9<= A9 | (~B9) ;
4'b1110 : if (M==0) F9 <= (A9 | (~B9))+A9+CN; else F9<= A9 | B9 ;
4'b1111 : if (M==0) F9 <= A9 - CN ; else F9<= A9 ;
default : F9 <= 9'b000000000 ;
endcase
if (A9 == B9) FZ <= 1'b0 ; else FZ <= 1'b1 ;
end
assign F = F9[7:0] ; assign CO = F9[8] ;
endmodule
M就是微指令里S后面的那个参数,M=0就是算术运算,M=1就是逻辑运算,建议选一个逻辑运算来搞,算术运算还要考虑进位,麻烦.jpg,S就是S3~S0代表的值,可以看到当S==0100, M==1的时候就是NAND,非常简单吧,当然有实力的读者可以直接改这个VHDL重新编译就可以自定义算法了。
这就是那个NAND怎么来的了,下来我解释一下DR1->R0,因为我懒得找A B C,所以我看到了当S=1111,M=1的那个地方,F9<=A9(意思是把A9直接赋值给F9),这样就爽了,因为A9就是DR1,B9就是DR2(你可以从样例的树上看到),只要这样完成一个走ALU的运算就能把我们的DR1搬到R0里面。
很好,我现在认为你已经可以自主创新了,并且可以理解指令流程,合适的借鉴原装程序的微指令树了,下来你就用画图软件建立一个差不多的树,然后编一个地址(八进制),然后列一个微指令表(记得微指令写的地址是八进制,但是最后六位是十六进制地址!!)。

笔者设计的微指令表
我强烈建议和原装程序一样,你要搞不懂P(1)的原理,你就这么理解,P(1)是指令的属性(C字段),在01(我设计的微指令树)指令的C字段有一个P(1)属性,那么它跳转的地址将会是IR里的数值的高位值+跳转地址,而且强烈建议你把第一个指令地址编在10,后面接着11,12.....,这样也方便我们进行调试。然后记得把微指令编满一点,显得你很懂,比如说01之后的02可以编到第一个指令的下面的节点啥的,可以跳着编,这几个指令的顺序也能换。编完地址后把微指令写到一个表里面,用python来转换成16进制,不要自己瞎转,错了的话调试几个小时。

最后你把这几个微指令写回去到你的微指令树,你的课程设计就已经完成78%了。
然后你把ROM_5.MIF用设计软件打开,手动修改为你的微指令,保存,然后把ROM打开mem_init重新load一下,保存,编译刷入就行。
BUT其实你还没法验证你的微指令是否正确,你下来把你设计的指令集随便编码一下,刷入到RAM,然后也是保存,重新load,编译刷入。


然后,你就可以开始调试了,哪里有错改哪里,这时候你随便问老师,老师肯定知道你懂了在认真做,就会帮你细心调试(不是)。
结尾
一般最后一天的下午开始验收,早做完的写实验报告,别想着早点验收(不过你做完了可以不动声色的走人,反正只会在早上8点半签到一次),让老师记住了给你扣印象分。
笔者的代课老师是:xx涛,对于其他老师的话不太了解,如果想要我的实验报告请不要email我,因为我已经删了,其实所有有用的信息已经放在上面了,其他都是AI生成的(我一直想问我自己:你知道你是AI生成的吗)。
评论