作为硬件基础课,数电非常重要,所以在学习FPGA之前我们先回顾一下数电的知识
下面就开始我们第一章的学习(啊不,复习)
ps:我使用的是西安电子科技大学出版社出版的教材《数字电子技术基础》
每个课程第一章都是比较简单的基础知识。数电第一章呢硬核知识不多,主要是培养我们的二进制思维。废话不多说,下面正式进入学习。
按照惯例,学习第一章之前,我们得先了解一下数电的概念。
这门课叫做数字电子技术基础,顾名思义,我们要学习的是数字电路的基础知识。
数字电路听起来很高端,实际我们每天都在接触。
什么叫做数字电路呢?用数字信号进行算数运算和逻辑运算的电路就叫做数字电路。
上面我把几个关键词加粗了,一个一个来看。第一个“数字信号”,学习过信号的话这个概念就已经知道了,它是在时间和数值上都离散的信号。就像下面这张图,时间上不连续,幅值也有上下限,也就是0和1。
事实上呢,数字电路里0和1不是绝对的两个数,而是我们规定了阈值,大于阈值的我们视作1,小于的我们视作0。
第二个“算术运算”,这个很简单了,就是我们从小学习的加减乘除等等一系列运算。在接下来的课程中,我们会对于计算机的计算过程有更深刻的理解。
最后一个关键词“逻辑运算”,乍一听可能比较陌生,实际上就是高中学过的与或非三种运算以及其变形。
如今我们见到的数字电路已经非常集成化,体积非常小了,而这当然是经过很多年的发展的。世界上第一台通用计算机“ENIAC”于1946年在美国宾夕法尼亚大学诞生,当时使用的数字电路还是电子管。这台电脑真的是一个庞然大物,用了18000个 电子管 ,占地170平方米,重达30吨,耗电功率约150千瓦,每秒钟可进行5000次运算,美国国防部用它来进行弹道计算。
后来随着科技的不断进步,晶体管工艺得到了很好的发展,开始替代电子管在数字系统中的地位。由于晶体管的集成化特点,数字电路的集成度也越来越高,出现了SSI(小规模集成电路)、MSI(中规模)、LSI(大规模)、VLSI(超大规模)。作为一门基础课,这门课程学习的主要是SSI。现在,晶体管也逐步被场效应管取代了,这两种东东在模电中会学习得比较深入。
清楚了一些很基本的常识,现在正式进入基础课程——数制与编码。学完这些,我们就能拥有二进制思维了。
这里有一个数——101,它真的是一百零一吗?
它是,也不是。一般人眼里,这个就是一百零一。但是我们不是一般人,我们是学过数电的人。我们应该有一个思维:进制决定了这个数是多少。
如果是十进制,那这确实是一百零一。
如果是二进制,逢二进一,这就是五。
如果是八进制,逢八进一,是六十五。
如果是十六进制,这个数就是二百五十七。
为了识别到底是几进制,一般我们会在数字后面加一个下标表示。
不过可能有些同学就有点疑惑,101、5、65、257是怎么算出来的,写一下马上就清楚了。
上面这个过程也就是x进制转换成十进制的方法,如果出现小数点,那么小数点后第一位是^(-1),第二位是^(-2),以此类推。
如果是十进制要转化为x进制,有一个通用的办法就是整数部分÷x取余,小数部乘x取整,无论什么进制,兵来将挡水来土掩。同样以101为例:
再举个小数的例子:
当然,一般有通用性的方法都会丧失一定的便利性,短除法确实比较繁琐。我们也可以用按权展开法,这个方法就需要我们记住进制之间常用的权值,特别是二进制(想一想玩过的2048 o(* ̄▽ ̄*)ブ)。
至于其他进制之间的转换,主要就是二进制和八进制、十六进制的转换,只需要记住一句话:三位二进制数表示一位八进制,四位二进制数表示一位十六进制。
呼~ 终于把第一部分弄完了,接下来是第一章的第二部分——编码。
提到编码是不是很自然地想起了谍战剧里嘀嘀嘀嘀的莫尔斯电码。莫尔斯电码利用时断时续的长短信号来表示不同的含义。
和莫尔斯电码类似,数电中,用若干位二进制数码按一定规律排列起来表示给定信息的过程称为编码。
由易到难,先表示最简单的十进制数字,这就是BCD码。全称Binary-Coded Decimal,意思是二进码十进数。
BCD码用四位二进制数来表示一位十进制数,根据不同的权值又分为以下几种:
-
8421BCD
-
5421BCD
-
2421BCD
每位数字表示该二进制位上的1代表的十进制数。需要注意的是,由于BCD码只能表示十进制,也就是0——9,所以出现用四位BCD码表示一个大于等于10的数是错误的。
8421BCD码加上0011就是余3码。余3码是一种变形的8421BCD码。
那么为什么我们要给8421BCD码做这样一个变形呢?百科中余3码这个词条中出现了一个词:自补性。这个自补性指的就是余3码对9会产生一个自动的补码,例如:
这样,在做运算时就会变得相对简单很多。
BCD码表示十进制数时非常方便,但是却有一个致命缺点:容易出错。在传递信息的过程中只要有一位出错,那么这个信息就是错误的。为了解决这个问题,提出了可靠性编码。
可靠性编码有很多,最常见的是格雷码,也叫做循环码。它的构成特点是对称轴两边最高位对称取反,其余 低位对称相等。
这样,相邻两个码组就只有一位不同。在连续发送相邻码组时,如果出现错误的话就很容易检测出来并纠正了。
那如果不是发送相邻码组怎么办?这个时候有另一种编码方法:奇偶校验码。
在接受和发射的时候先规定好每一组数码1的个数都是奇数(奇校验码)或者是偶数(偶校验码),如果本来的数码不符合要求就在其前面或后面加上一个1,符合就加一个0。这就是奇偶校验码的产生过程。
原本的数码就称为信息位,加上的0或1就称为校验位。
这样,如果出现一位数码的错误时,整个数码的奇偶性就变了。两位数码同时发生错误时却不能识别到错误。
如果想继续解决这个问题,就会有更复杂的编码方式,可以在网上找找看。
上面我们说的编码方式都是只能表示数的大小,却不能表示数的正负。如果我们要表示数的正负的话,就要使用原码:符号位+数值位。0表示+,1表示-。
也可以用反码。反码构成与原码相同,都是符号位+数值位,但是负数的数值位需要取反,正数反码与原码相同。
既然有了原码,为什么又要搞一个反码呢?其实反码只是一个中间状态,为了我们得到补码的中间状态。
正数的补码、反码、原码都一样,负数的补码需要用反码+1。
补码有什么用呢?为什么要创造这样一种编码?
问题就在二进制的计算上。众所周知,计算机最基本的功能就是计算。如果我们以原码的形式储存数据并进行计算,像下面这样。
显然有问题,那再用反码试试。
出现了一个-0,理论上是没有问题的,但是这不符合人类的认知习惯(0是没有正负之分的)。所以我们引入了补码。
由此,我们可以看出,补码的出现就是为了二进制计算的正确和简便性。
补码运算具有可逆性和分配律。