目录
计算机组成与课程设计是山东大学软件学院在大二下面向软件工程专业的同学开设的一门主要偏向实践的课程。目的是通过该课程设计的学习,运用所学的计算机原理知识,设计一台模型机,从而更加深刻理解计算机的工作原理。
上课时间1-9周,其中第9周为答疑时间。最迟不超过13周(也有可能是12周)完成所有实验。
PS: 由于疫情关系,导致2020级推迟到了14周完成。
2
首先是实验台的部分。实验台有一个实验器材和一个电脑。在电脑中,你可以对想要输入的RAM和ROM进行写入。操作过程我就不一一赘述了,但是我想给大家分享一个比较简单的方法,就是你可以通过点击写地址,加你所需要的地址和数据,按照
地址:
XXXXXX
数据:
XXXXXX
进行快速写入

//注意这里的“:”是英文的
写入完之后我们可以按红色和绿色的箭头对其写入ROM,RAM写入操作,这里请注意,一般情况下,你只能修改右侧的RAM中的数字来实现修改操作(上图的版本较老,可以参考下面的版本)

//粗略解释一下RAM中各个数字的意义:取A0 和A1(位于RAM中相应地址)内的数字,将相加的结果打入A2(RAM中的数字)中,最后的结果就是观察位于A2中的值是否和通过计算器得到的值相同:
如图

那么结果就应该亮三盏灯(位于PSW)溢出,进位,判零
我们就可以读出在A2中的值为00(最前面的1因为溢出被省略)
然后是实验器材本身,由于本次实验器材已经用了很多次,所以很有可能会导致许多实验器材在脉冲的打入上遇到问题。这里注意的是,脉冲的打入我们可以人为控制的。控制点位于实验器材的左侧,中间靠下的部分。那里有一排引脚(如图),你可以把一个类似帽子的东西拔出来,再改变插入位置,从左到右代表的是脉冲速度,从慢到快,你可以在最慢的时候进行观察,最快的时候进行实验验证。//但这里强烈建议用单脉冲调试

清零端的打入自古以来都是一个非常困难的问题,如果你遇到了第一次实验是正确的,但是第二次甚至以后全部的实验都是错误的,只能够通过完全重启实验器材(断电)来实现正确的写入的话,那很有可能是你清零做干净彻底,我的建议是将清零总线接到一个开关上,通过手动对其进行清零操作,而且在读取之前进行清零操作,这样的话就可以保证你的RAM和ROM不受影响。之后再拨回,保证下一次实验的正常进行。
所以我认为比较合理的实验步骤是(可能只对个人有用):写RAM/写ROM=>Quartus 进行programmer操作=>手动清零=>单片机和CPU复位=>打入脉冲=>完成实验操作=>拨下/拨上清零端=>读取RAM=>修改RAM中相应数据(为下一组数据做准备)=>写入RAM=>拨上/拨下清零端=>单片机和CPU复位=>打入脉冲
//下文主要依靠本模型实现

通过老师给出的抽象模型,我们可以看出,整机实验的核心是以ALU,Z寄存器和A,B选择器组成的运算单元,而且其中的核心都包括暂存器Z。这里我简略写一下需要用到暂存器Z的地方:
可以看出,Z暂存器在每一个重要环节都有参与,因此,我强烈建议在第一次实验中可以把ALU彻底搞懂。
RAM:这里主要由实验器材负责,我们只需要把PC的值给RAM就可以了,其他的不用关心。
数据总线:为最上面的连接几乎所由元器件的桥梁。
启动电路:

老师提供了两种启动电路,其实如果实验器材本身没有问题的话,选择哪种方案其实没有什么太大的差别,现在在这里简单介绍一下各个管脚的主要功能:
最上面的是连接HALT指令(停机指令),通过非门使输出为0,实现了停机操作。
中间两个是脉冲的打入,通过打入脉冲可以使实验器材按照我们的意愿进行下一步操作。
最下面是CLEAR指令,这个建议单独绑一个开关

这里可以实现指令接下来是通过uPC实现uPC+1还是直接执行无条件跳转
思路如下:
这个器件的实质是一个选择器:
如果需要作为uPC+1,则BY打入高电平,选择B端口作为输出端口,这样就可以在uPC中实现uPC+1操作。
如果需要执行无条件转移指令,那么我们只需要选AY,这样的话输出的就会因为我们通过有意的连接VCC和接地实现强制转换。例如在这里我就直接将输出结果强制转化为00000001.实现了指令的无条件转移。

这个IR指令寄存器的实质其实只是一个register-8.但是我们可以通过控制输入指令的切割实现不同的目的。
这个初学者可能理解比较困难,这里我举一个例子:
例如我输入A1操作(位于RAM),

我们关注于转换得到的2进制,也就是10100001,这样打入D1到D8的0或1我们就已经知道了,从高位到低位分别是10100001.输出时,我们可以看出有两个不同的方向,其中Y1到Y4可以控制选择那些不同的寄存器(位于寄存器组中)

而高四位的输出我们可以看出是通过和B1-4的组合形成新的值,也就是00001010,这个值会打入uPC,在执行uPC+1操作后读取我们写入ROM中的下一条指令。
即机器会读取位于ROM中A0位置的指令,之后如果没有遇到无条件转移指令,会一直读下去的。

本质上就是要实现uPC+1操作,这里就不详细介绍了,但还是要注意输出引脚的绑定,我们要绑定180-191

和MAR一致,只是目的不同。值得注意的是,实验要求上如果说要实现隔绝MDR的话,这里强烈建议将MDR,三态门,选择器打包成一个统一部件,切忌不能只打包两个!或者是干脆不打包。

三态门,作用和它的名字一样,通过控制EN来实现MDR中的数据的输出方向;
例如在老师停供的总图中:

我们可以看出,MDR有两个不同的输出方向,分别是输出到RAM和通过A选择器到ALU再到寄存器。因此控制输出方向就是否有必要了
这里给出一个一般思路:(可能有更好的)

分别接入两个三态门,中间的控制MDR和双端口相连,右边的控制和A选择器相连,这样就可以控制MDR的输出方向了。
和uPC本质上是一个元器件,它们的目的其实都是在脉冲打入的时候实现+1的操作,当然,用另一句通俗易懂的话来说,就是通过它们我们可以实现了指令向下读取
这里我就以PC为例,介绍一下PC,B选择器,ALU,MAR在宏观上的联系。也就是本实验的核心部分。

在本实验老师给出的抽象模型中,我们可以看出 ,数据流通过PC,B选择器,ALU,暂存器Z,数据总线,形成了循环,也就是说。我们通过PC加一来实现取值,LOAD,操作(也就是宏观上RAM的值的读取和分析)
这个是本实验的核心。ALU相信同学在之前的实验里已经自己组装过了。但是我还是想补充几点:
首先是74181和74182.我们对于这个是怎样内部实现的不用关心,我们是要利用它们。
其次是CVNZ的操作,这个大家可以参考后文中的详细介绍。
我们先看一下74181的功能表。我们首先要明白的是,作为ALU,在本实验中,它的作用已经被定死了,也就是要实现加法操作,也就是说,我们可以通过接入VCC或者是接地的方法来实现这一功能。

通过M,S1,S2接地,C0.S0,S3进入VCC来实现。

从老师给出的参考图我们就会知道ALU的输入十分复杂。我们可以把它抽象成首先通过A,B选择器进行预选,这样的话才可以打入ALU,并在ALU执行加法操作(也可以是作为打入R0/R1的中继站,因为存入的数+0还是原来的数字)

我就不详细介绍了,之前的实验大家肯定了解的十分详细,唯一我要补充的是CN4,也就是图中右下侧绑定非门的输出,CN4记录运算后的进位。但是和我们印象不同的是,进位它打出低电平,因此需要连接非门。
接下来我详细介绍一下CVNZ是怎样实现的
1、C→CF(进位标志位):反映无符号数的运算是否产生进位或借位。运算结果的最高有效位向更高位进位或者借位,CF置1,否则置0。
2、Z→ZF(零标志位):判断结果是否为0。运算结果0,ZF置1,否则置0。
3、N→SF(符号标志位):反映运算结果的符号。运算结果为负,SF置1,否则置0。
4、V→OF(溢出标志位):反映有符号数的运算是否溢出。运算结果超过了规定字长有符号数的表示范围,OF置1,否则置0。
这是老师的实验要求,那么我们应该怎样实现呢?
我将会从简到深的为大家介绍。
C:
首先是最简单的C,即进位:之前我们已经提到了,由CN4产生的低电平信号经过非门变成高电平,这样的话我们直接接入PSW寄存器即可。

Z:
接下来是Z,首先我们需要明白什么是Z,这里的Z是狭义上的。即RAM中的数字。我们继续举上文的栗子:

在这里,我们只需要关注于最后的00即可。因此,只要我们转化为二进制的结果所有都为零即可。

在这里我们一定要明白,不是100中的“00”是全为“0”的,而是转化为二进制的“0000,0000”全部为0的!因此,我们需要接入OR8,再接入非门。理由很简单:如果里面输入任何一个不全为0的数,就会经过或操作,再接入非门变成低电平。因此输出为低电平,也就是宏观上的灯泡不亮。
N:
N:这个也同样十分简单。反映运算结果的符号。运算结果为负,SF置1,否则置0。 我们只需要把最高位接出即可。
V:
V的实现比较复杂,因为有两种可能导致溢出的情况。
首先我们要明白,什么是溢出?
溢出就是计算出的数超过了缓冲区的范围,导致部分数值丢失的操作。
可能导致溢出的原因在本实验中只有两条:
同为正数相加和同为负数相加
我们这里可以利用同或门和异或门来实现。

逻辑如上,大家有时间可以自己思考。核心还是同或或是异或问题
大家可以参考这篇文章
实验流程主要包括取值周期,LOAD周期,ADD周期,STORE周期,HALT。



HALT停机指令,当读取到本指令时,计算机会停止下一个指令的读取,且指示灯不亮,PSW显示正确结果。具体实现如图:

通过11信号的打入,使AND3恒为非状态,阻止了CP信号的打入。进而阻止了下一步指令的形成。因此实现了停机操作。
如果同学实在没什么思路,不妨去每台电脑的D盘翻翻,里面有很多很多意料之外的小惊喜噢
:)
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳