the elements of computing systems 的读书笔记1
想转职程序猿,还真不是说懂一门语言就够的了,想要继续进步,必须懂其相关实现原理,比如这些底层的构造。最近看的就是这一本计算机入门级的书,但是对我这个纯自学的人来说真是能学到很多。
这本书从最基本的Nand门开始逐步构建电路,讲真,大学里学过数电模电,但是一直感觉很虚,不知道学完之后如何运用,直到看到了这几章,才真正发现原来是这样的,通过精心设计,把对应logic gate连接起来,构成具有实际使用意义的电路。这本书只作为入门书,对象是零基础的人,所以最底层就是Nand门和DFF门了,然后根据这两个门来构建出一个简单的CPU,话讲起来很简单,但是当实际你真正构建出CPU来的时候,成就感还是很强的。
本书的第一章是讲了布尔逻辑,这一章一开始讲了最基本的逻辑关系,感觉就是高中的知识,各种与或非,然后将这种与或非抽象的概念用logic gate来物理实现,如输入低电平,就会输出高电平。然后就是利用与或非来构建选择电路,如DMux门,Mux门,实现起来也不难,感觉就是对各个输入(或者输出)加上一个系数,使其为0或为1就能决定最终输出是什么了。最后就是构造多位逻辑门,因为单个输入输出是远远满足不了我们的需求,所以需要横向扩展,简单来讲就是将各个门这样叠起来,叠16个就是16位,叠32个就是32位,如此类推。以上所有门的实现都用了HDL语言,难度不大,具体芯片的输入输出都已经给定了,只需要补充PART中的内容就行了,也就是往PART中添加其他已经实现的芯片,构造特定的输入输出,来最终完成给定目标。
本书的第二章是讲了布尔运算,这章主要内容就是根据了第一章已实现的各种逻辑门,来构造具有运算功能的门,这里是只实现了加法。加法的具体实现就是利用了二进制的进位,一个一个门的叠加上去。然后就是讲了补码,补码就是实现了负数的表示,按照书上的讲法:补码就是对X的所有位取反,然后加上1。而我个人的简单记法就是0=-1+1,1=-2+1,2=-3+1,如此类推。补码的意义在于:利用补码可以实现减法,也就是加上一个负数。当实现完加法,减法和第一章中的逻辑操作,就可以将这些功能都封装起来到一个芯片中,就是ALU,算术逻辑单元。个人在实现ALU时的思路就是根据每个输入位进行判断,从第一位开始判断,然后将其输出当成下一个输入位的输入,一直对这一个输入(出)进行操作,直到最后输出。
本书的第三章是讲了时序逻辑,这章就是讲了内存的具体实现。以前刚接触电脑的时候,知道内存里的东西是断电就没了,而磁盘内的东西无论有没电一直都有,但是并不知道是为什么,而这章就讲了这个内存是如何实现的。这章引入了一个新的基本门DFF门,书中的解释是:DFF简单地将前一个时间周期的输入值作为当前周期的输出。DFF门能够这样做的原因是他还有一个时钟输入,但是这本书并没有再往下讲其实现原理,所以明白DFF是在下一个时间周期才输出就行了。当看书看到这点的时候,我就大概明白了内存的实现逻辑,不断输出前一周期的输出(将前一周期的输出当成输入),这样一直输出那一个输出,这不就是实现了储存功能吗。(PS:这个DFF门就是数电中学到的D触发器)单位寄存器就是基于这个DFF门实现的,只需要在输入的时候选择是输入新的输入,还是输入上一周期的输出,所以增加一个load的选择位就可以实现这个DFF门了。实现完单位寄存器后,把16个叠起来就是16bit寄存器了。RAM8其实就是简单将8个16bit寄存器叠起来,然后加入一个寻址功能来确认是选择哪个寄存器来操作。RAM64的实现也是类似,将8个RAM8叠起来,加寻址器。书里按这个方法,一直叠到16k。这一章除了实现这个内存,还实现了一个计数器。计数器与寄存器相似,但是能够实现在下一周期进行自加,所以就是在寄存器的基础上添加重置和自加这两个功能。在具体实现的时候要分清输入是在t-1周期,输出是在t周期,所以所有对输入的处理都要在DFF门之前。
前三章都是讲了很基础的东西,个人看起来很容易就接受了,但是去到第四、五章,就感觉有点吃力了,一下子构建不起来相关知识点。需要多看几遍。
第四章主要介绍了机器语言,机器语言只是一种约定形式,这一章讲了如何去运用这种底层语言来操作硬件,而将如何用硬件实现放到了第五章。这章介绍了Hack汇编语言,在刚接触的时候真心很难理解,因为他是一种较低级的,静态的语言,比如他的格式是固定的:先是一条A指令指定操作什么,然后接C指令怎么操作;预定义的符号,比如字母D是一个固定的储存数据的寄存器,他作为一个独立的存储空间,暂时存储数据。
第五章讲了如何用之前构造的芯片来组合成计算机。主要难点在如何构建CPU上,简单来讲,CPU就是由ALU,A、D寄存器和计数器组成的,在设计电路时要明白两点:1、ALU的输入X,Y是由D寄存器、A寄存器/M内存的输出;2、计数器的跳转条件要结合ALU的输出和C指令的J位来考虑。
根据给出的提示图,对标记C的部分做逻辑设计就行了。
个人思路:
先对D寄存器进行设计,因为D寄存器的输入是由ALU输出提供,所以不需要额外对输入进行判断,然后根据输入的指令,如果输入指令是C指令,且需储存在D寄存器,也就是d2位是1的话,则将D寄存器的load位置1。
然后是A寄存器是储存地址或者常数,所以要对A寄存器的输入进行判断,如果外部输入指令是A指令,则选择这个A指令更新到A寄存器中;如果外部输入是C指令,则选择执行ALU的输出,且根据C指令中的d1位看是否需要更新数据到A寄存器。确定好A寄存器的输入输出后,addressM就得到了,后面还要对C指令的a位进行判断,看是将A还是M当成ALU的输入。
writeM的判断很简单,就是判断是否是C指令,且d3位置是1就行了。
PC的输入就是A寄存器的输出,主要要对其load位逻辑进行设计。因为ALU的输出有zr,ng,所以对他们进行操作,得出一个大于零的表达式,最后用这三者去分别和C指令的J位比较,得出是否发生了跳转,如果发生了跳转就对PC的load位进行操作。
Mux16(a=instruction, b=outALU, sel=instruction[15], out=outmux1); // 判断是A指令还是C指令,如果是C指令,则使用ALU输出的地址 Not(in=instruction[15], out=nota); // A寄存器是放地址或者数据的,如果输入是A指令,则要将其更新到A寄存器
And(a=instruction[15], b=instruction[5], out=cloadA); // 如果是C指令,则要判断是否要储存到A寄存器
Or(a=nota, b=cloadA, out=outor); // outor作为A寄存器的load位,决定是否更新A寄存器
ARegister(in=outmux1, load=outor, out=outA, out[0..14]=addressM); And(a=instruction[15], b=instruction[12], out=cm); // 如果是C指令,则要确定a位
Mux16(a=outA, b=inM, sel=cm, out=outAM); And(a=instruction[15], b=instruction[4], out=cloadD); // 如果是C指令,且要储存在D寄存器,那就更新D寄存器
DRegister(in=outALU, load=cloadD, out=outD); ALU(x=outD, y=outAM, zx=instruction[11], nx=instruction[10], zy=instruction[9], ny=instruction[8],
f=instruction[7], no=instruction[6], out=outALU, out=outM, zr=zr, ng=ng); And(a=instruction[15], b=instruction[3], out=writeM); Or(a=zr, b=ng, out=zrorng); // 结合ALU输出的结果去判断J位的跳转
Not(in=zrorng, out=dayuling);
And(a=instruction[0], b=dayuling, out=j3);
And(a=instruction[1], b=zr, out=j2);
And(a=instruction[2], b=ng, out=j1);
Or8Way(in[0]=j3, in[1]=j2, in[2]=j1, in[3..7]=false, out=jjj); // 看是否出现跳转
And(a=instruction[15], b=jjj, out=pcload); // 要留意前提是C指令 PC(in=outA, load=pcload, reset=reset, inc=true, out[0..14]=pc);
the elements of computing systems 的读书笔记1的更多相关文章
- 2016/2/13 《计算机系统要素》(The Elements of Computing Systems)读书笔记(1)
过年期间一直在啃一本书,学习计算机组成原理. 这是一本很棒的书,是一个基于项目的学习过程.可以让人理解的很深刻. coursera上有这本书前半部分的教程,是由书的作者团队们开的课,个人认为很棒,可惜 ...
- the elements of computing systems 的读书笔记2
懒癌发作,本来计划是两到三天就一个unit的,没想到一直拖到今天才完成第二部分(6-8章). 第6章,介绍了hack汇编到二进制,也就是用翻译到01来表示.从课后习题来看,这一章目的就是设计一个程序( ...
- 【读书笔记】《Computer Organization and Design: The Hardware/Software Interface》(1)
笔记前言: <Computer Organization and Design: The Hardware/Software Interface>,中文译名,<计算机组成与设计:硬件 ...
- TJI读书笔记15-持有对象
TJI读书笔记15-持有对象 总览 类型安全和泛型 Collection接口 添加元素 List 迭代器 LinkedList 栈 Set Map Queue Collection和Iterator ...
- 《C#图解教程》读书笔记之六:接口和转换
本篇已收录至<C#图解教程>读书笔记目录贴,点击访问该目录可获取更多内容. 一.接口那点事儿 (1)什么是接口? 一组函数成员而未实现的引用类型.只有类和结构能实现接口. (2)从ICom ...
- 图解TCP/IP读书笔记(一)
图解TCP/IP读书笔记(一) 第一章 网络基础知识 本学期的信安概论课程中有大量的网络知识,其中TCP/IP占了相当大的比重,让我对上学期没有好好学习计算机网络这门课程深感后悔.在老师的推荐下开始阅 ...
- 【Tools】Pro Git 一二章读书笔记
记得知乎以前有个问题说:如果用一天的时间学习一门技能,选什么好?里面有个说学会Git是个很不错选择,今天就抽时间感受下Git的魅力吧. Pro Git (Scott Chacon) 读书笔记: ...
- HTML5&CSS3读书笔记
Hi All, 分享一下我学HTML5 摘抄的读书笔记(我用的还是英文,因为一些新的东西还是来自于欧美国家,希望大家习惯于看一些英文材料): 1. Difference between Section ...
- 【读书笔记与思考】《python数据分析与挖掘实战》-张良均
[读书笔记与思考]<python数据分析与挖掘实战>-张良均 最近看一些机器学习相关书籍,主要是为了拓宽视野.在阅读这本书前最吸引我的地方是实战篇,我通读全书后给我印象最深的还是实战篇.基 ...
随机推荐
- centos 安装memcache服务后memcahce本机连接Permission
自己手动在虚拟机下装了下memcache,整个过程真是充满波折,本身用php5.3安装memcache扩展就麻烦很多,无法通过yum直接安装,安装方法详见http://chenwei.me/blog/ ...
- JAVA汉字转拼音(取首字母大写)
import net.sourceforge.pinyin4j.PinyinHelper;import net.sourceforge.pinyin4j.format.HanyuPinyinCaseT ...
- 数据库-mysql中文显示问题
一:在mysql 下面查看带中文的记录显示乱码 mysql> select * from role; +----+------+ | id | name | +----+------+ | 1 ...
- python网络编程-进程锁
一:进程锁的作用 进程锁是防止多进程并发执行在屏幕打印的时候,其他进程也输出数据到屏幕,而出现混乱现象. 比如:进程池中很多进程会向同一个日志文件中打印日志 二:代码 # -*- coding:utf ...
- 题解 P1074 【靶形数独 】
这是一神题!!! 可能是因为我太弱了,题解都看不太懂QWQ 不过感谢wng老师的提醒,我写出了这个样的的代码. 分析: 这道题是一个搜索(dfs).很神奇很暴力的题 首先,你需要看懂题目.(可以先去玩 ...
- Codeforces 963A Alternating Sum(等比数列求和+逆元+快速幂)
题目链接:http://codeforces.com/problemset/problem/963/A 题目大意:就是给了你n,a,b和一段长度为k的只有'+'和‘-’字符串,保证n+1被k整除,让你 ...
- Java关于数组操作函数
数组排序及元素查找 sort()方法对Java数组进行排序. binarySearch() 方法来查找数组中的元素,返回该元素所在的位置. import java.util.*; public cla ...
- Linux下的堆off-by-one的利用
这篇稿子已经投到了360安全播报,http://bobao.360.cn/learning/detail/3113.html
- 【读书笔记】Android的Ashmem机制学习
Ashmem是安卓在linux基础上添加的驱动模块,就是说安卓有linux没有的功能. Ashmem模块在内核层面上实现,在运行时库和应用程序框架层提供了访问接口.在运行时库层提供的是C++接口,在应 ...
- Web前端开发最佳实践(10):JavaScript代码不好读,不好维护?你需要改变写代码的习惯
前言 这篇文章本应该在上一篇文章:使用更严格的JavaScript编码方式,提高代码质量之前发布,但当时觉得这篇文章太过基础,也就作罢.后来咨询了一些初级的开发者,他们觉得有必要把这篇文章也放上来.尽 ...