绝佳的数字电子技术实践 TD4 CPU详细教程

绝佳的数字电子技术实践 TD4 CPU详细教程

TD4 CPU原理详细教程

通过自己动手制作一个简单的CPU,可以深入理解数字电路逻辑、时序和汇编语言,加深对硬件和软件的认识,更深刻地理解计算机的本质。您可以使用13片74系列逻辑芯片来实现一个带有输入输出功能的4位CPU。相关资料和视频教程可在GitHub上获取,包括电路原理图、PCB设计和焊接测试等内容。通过制作CPU TD4,您将获得宝贵的实践经验,并深入理解计算机的工作原理。

立即购买套件:

简介

如何使用9种14个74系列芯片,自己构造一个4位CPU(中央处理)的可编程计算机系统


贴片新版视频

全插件旧版视频

CPU的核心原理其实非常简单,其实任何人都只需要非常基础的一点数字电子技术知识,就可以用14个74系列芯片,完成一个4位简单计算机的设计。这本大概在十几年前就已经在日本出版并风靡电子爱好者圈子的一本好书,既可以给对计算机工作原理好奇的青年爱好者作为制作范例,又可以成为让大学本科学完数字电子技术等相关课程后用于学生大作业或课程设计改进的雏形和范例(实话说,比交通的什么之类的例子实在是好太多,因为今天是计算机的时代,大家显然会对这样的例子兴趣更加浓厚)。我花了大概一天半的时间,就基本搞懂了这个例子的原理,写下这篇文档分享给大家,希望大家也能向我一样动手坐一坐,对数字计算机的工作原理感悟体会更深刻,共勉!


总电路图(点击可放大)

TD4全图

为什么要这么做?

虽然功能简单,但是个完整的CPU,麻雀虽小五脏俱全

采用9种小规模集成电路芯片(74系列),完成数字电路设计的基础学习,可以彻底直观理解到电路工作层的原理。


立即购买套件:

-现在可以轻松获得3GHz-5GHz的高速处理器,就连不到一美元的处理器,其工作频率也在10M左右,计算位数也在16甚至是32位,我们自己搭建一个一个意义是什么?



并非没有意义,原因如下

- 从电路层面直观了解运算过程

- 直观理解各个部分的组成原理(到数字电路层面)

- 简化的4位数,不至于眼花缭乱

- 只有12个指令,也足以完成一些编程任务


其次要制定CPU的规格

- 只操作4位数

- 仅10简单的中小规模集成电路芯片(74系列)

- 可编程指令只有16条

- 演示和改造的实用性都很强


这是一个典型的解剖模型(麻雀虽小 五脏俱全)

采用机器语言编程,可以完全直观理解并看到其运行过程,可手动也可自动操作


这个项目适合哪些人?

有初步或者想初步学习数字电路的人

想了解CPU工作和设计思路的非专业人员、正在学习电子及计算机专业的学生


经过这个项目,你会收获些什么?

中规模集成电路,如74系列芯片,该怎么应用到实际需求中去

彻底理解一个简化版本的CPU的每个运作细节


教程开始啦!

74系列芯片

什么是74系列芯片,相信学过数字电子技术的同学都不会陌生,课本里都有频繁的举例,但为了完整补充相关产业背景的知识,这里还是引用一下维基百科的说法:

7400系列是典型的中小规模数字逻辑集成电路。 在 1960 年代中期,最初的 7400 系列集成电路由德州仪器 (TI) 引入,前缀为“SN”,以创建名称 SN74xx。 由于这些零件的普及,其他制造商发布了引脚对引脚兼容的逻辑器件,并保留了 7400 序列号作为识别兼容部件的辅助工具。 但是,其他制造商在其部件号上使用不同的前缀和后缀。

二值逻辑和逻辑电平、正负逻辑电平

二进制数正好是利用二值数字逻辑中的0和1来表示的。二值数字逻辑是Binary Digital Logic的译称。本系统中,由于采用USB接口供电,用5V表示1,0V表示0。在本系统中,一般采用正逻辑(即高电平有效),如所表示的数据线上有一横杠线或者器件输入输出口处有一小圆圈,则表示负逻辑(即低电平有效)。更多专业详尽的信息和说明,请查阅数字电子技术基础课本中的相关章节
CD54HC283.pdf
522.4K
·
百度网盘
SN54HC10.pdf
1.3M
·
百度网盘
SN54HC138.pdf
1.4M
·
百度网盘
SN54HC14.pdf
1.7M
·
百度网盘
SN54HC153.pdf
1.1M
·
百度网盘
SN54HC161.pdf
1.4M
·
百度网盘
SN54HC283.pdf
125.3K
·
百度网盘
SN54HC32.pdf
1.9M
·
百度网盘
SN54HC540.pdf
1.4M
·
百度网盘
SN54HC74.pdf
2M
·
百度网盘

如何查看74系列芯片的Datasheet

规格表(Data sheet)数据表,数据表或规格表是对产品,机器,组件,材料,子系统或软件的性能和其他特性进行了足够详细的总结的文档,使买家能够了解产品的含义以及设计工程师要了解组件在整个系统中的作用。通常,数据表由制造商创建,以介绍文档其余部分的介绍性页面开头,然后列出特定特征,并提供有关设备连接的更多信息。

本项目使用了8种74系列芯片,我们都采用74HC型号,相关的规格书可以在alldatasheet.com/网站查询到,个人倾向于阅读德州仪器TI公司较新的Datasheet文档,因为其资料丰富且格式规范。德州仪器公司的SN54系列和SN74系列在功能上完全一致,规格书也是共用的,所以查找规格书时,如书上所示74LS10,网上也可以搜索SN54HC10,只是54系列芯片用于军用。

我刚上大学那会,一开始阅读英文规格书材料也非常不适应,因为从小到大的数理化教育都是非英语环境进行的,但作为电子、信息、自动化和计算机相关专业的学生和从业者,这一点将来无法避免,只好捧起英文资料一遍查资料一遍看,再借助一些中文参考书,慢慢的大家受到的困难的阻力越来越小,阅读越来越顺畅,希望读者也要尝试坚持下去,一定会受益匪浅的。


74HC/LS/HCT/F系列芯片的区别

74系列集成电路大致可分为6大类:
.74××(标准型);
.74LS××(低功耗肖特基);
.74S××(肖特基);
.74ALS××(先进低功耗肖特基);
.74AS××(先进肖特基);
.74F××(高速)。

同型号的74系列、74HC系列、74LS系列芯片,逻辑功能上是一样的。74LSxx的使用说明如果找不到的话,可参阅74xx或74HCxx的使用说明。74HC的速度比4000系列快,引脚与标准74系列兼容 4000系列的好处是有的型号可工作在+15V 。新产品最好不用LS。


74系列芯片和逻辑门电路的关系

像74这一类的所有芯片都需要电源正负供电,其余部分则往往作为信号输入输出的功能引脚,在电路设计布局时,对于简单功能的芯片,门电路符号和芯片引脚标识方式常常混用,这时需要我们查阅芯片Datasheet来确认其对应关系,以74HC10为例,我们查到规格书的地址是:pdf1.alldatasheet.com/d

通过在规格书中,下面两张示意图,即可理解在实际电路中如何使用该芯片:





什么是CPU-逐项理解冯诺依曼原理

- 程序计数器从内存中获取指令(取指令)

- 根据解码结果执行操作(执行指令)

- 存储计算结果(存储结果)

(上述三个过程可以比拟成逐页翻书,理解书中内容,并尝试拿笔记本记录下来的过程)

机器的每个 时钟脉冲周期,都会重复上述的几个过程


仿真器

接下来,我们先来看一个仿真器,此时此刻你并不需要理解这个仿真器中的所有细节,等后续讲述中,每个部分理解后,再回来重看此动态仿真程序,即可全面理解。


现在,你看此仿真程序运行图,所需要知道的事情有以下几点:

  1. 红色线代表此时该线上电平为高(5V),蓝色代表电平为低(即0V)
  2. 整个系统由CLOCK脉冲驱动进行,RESET低电平有效,即RESET被拉低后,系统里所有数据清零重启

如果你已经学过数字电路基础,那么你应该还可以尝试记住并理解以下几点,如果不能或全部理解也没关系,可以全部学完,回来再看看

  1. 四个74HC161分别为寄存器A、B、C、D,分别可用于存储4个比特的数据
  2. 第三个寄存器C的输出,用于输出4位电平,驱动LED
  3. 第四个寄存器D的输出,用作指令的译码,即作为地址总线的A0-A3(Address0-Address3)
  4. 两个74HC153组成了一个4位四路数据选择器,用于选择哪一路的4位数据给后续的四位全加器做加数A。其中,第三路的4位数据来源于4位拨码开关(即输入),第四路不连接被弃用。
  5. 74HC283是一个四路全加器,它的第一个加数来源于两个74HC153的数据选择通道,第二个加数来源于指令数据的低4位(即D3-D0),这种被包含在指令中参与运算的数据又叫立即数immediate。全加器的求和结果将输出给4位寄存器A、B、C、D均可,选择其中哪一个寄存器记忆结果,完全由每个寄存器输入端的LOAD(~LD)信号决定,请注意LOAD是低电平有效,这是后续指令译码结果中控制总线的最重要一部分。
  6. 全加器有溢出位输出Carry,但是无法记忆上一次的计算结果是否溢出,故需要一个D触发器作为溢出标记位记住上一次的求和结果是否溢出,并送给译码器指令。
  7. 图上所有用门电路表示的组合电路,是一个完整的指令解码器,它由取得指令的高4位(即D7-D4)和溢出标记位一起作为译码器的输入,由控制四个寄存器的加载(LD)和两个数据选择器的A、B作为输出,这是典型的控制总线。


TD-4 CPU规格对比-理解和现有CPU规格之间的数量级差异



复位电路

补充点基础知识

如何表达0和1

- 判断电压低还是高

- 设置0V=0,5V=1

- 低电平有效,还是高电平有效

- 注意,每个IC为每个信号引脚都设置了正逻辑和负逻辑

上拉电阻、下拉电阻的概念

我们现在开始设计,如何将开关的开关两种状态,转换成电平的高低两种状态。这个转换过程,需要理解上下拉的概念。

在数字电路中,上拉电阻(英语:Pull-up resistors)是当某输入端口未连接设备或处于高阻抗的情况下,一种用于保证输入信号为预期逻辑电平的电阻元件。他们通常在不同的逻辑器件之间工作,提供一定的电压信号。

同样的,一个下拉电阻(Pull-down resistor)以类似的方式工作,不过是与地(GND)连接。它可以使逻辑信号保持在接近0伏特的状态,即使没有活动的设备连接在其所在的引脚上。

上拉和下拉电阻概念

逻辑代数、组合逻辑电路

理解下面这些门电路的关键在于理解最关键的三个逻辑门(与、或、非)下面给出另外与非门、或非门、异或门的符号图和真值表,其是由三种基本门串接形成如果你对此毫无基础,请务必了解更多专业详尽的信息和说明,可查阅数字电子技术基础课本中的相关章节(逻辑代数、逻辑门电路、组合逻辑电路)

按键的抖动与消除

我们上面所表示的上下拉电阻方式用于将开关状态转换为电位高低电平状态的设计是理想化的,在实际电路中仍需要改善,为什么呢?让我们来观察一下实际的输出电压波形

根据电路原理基础知识,我们知道电容是电荷的蓄水池,这就像个缓存,令其两端的电压无法突变




施密特触发器、迟滞特性、消抖

在电子学中,施密特触发器(英语:Schmitt trigger)是包含正反馈的比较器电路。反相施密特触发器对于标准施密特触发器,当输入电压高于正向阈值电压,输出为高;当输入电压低于负向阈值电压,输出为低;当输入在正负向阈值电压之间,输出不改变,也就是说输出由高电准位翻转为低电准位,或是由低电准位翻转为高电准位对应的阈值电压是不同的。只有当输入电压发生足够的变化时,输出才会变化,因此将这种元件命名为触发器。这种双阈值动作被称为迟滞现象,表明施密特触发器有记忆性。从本质上来说,施密特触发器是一种双稳态多谐振荡器。反相施密特触发器的滞回曲线理解施密特触发器消除抖动在于两点:1.什么是脉冲抖动——通俗得讲,在脉冲的上升沿或者下降沿由于人手的细微抖动(人手在触碰物体时常会“哆嗦”,仅仅是幅度极小人没有觉察而已,除非受到惊吓很紧张的时候抖动的幅度大到会被人觉察)或者其它电路硬件产生的幅度较小的震荡,这些原因造成了脉冲边沿的一些或大或小的毛刺引起了脉冲波形的畸变,这些称之为脉冲抖动;2.施密特触发器的特点:输入的电平高于某一个值(比如说1.8V)触发器输出电平会向下翻转,产生一个下降沿,输入的电平低于某一个值(比如说0.8V)触发器输出电平会向上翻转,产生一个上升沿,那么当输入电平介于两个翻转阈值之间时施密特触发器的输出不会动作;从上面的描述你就应该能明白:之所以能消除抖动是因为抖动所产生的电平上下波动的范围尚在施密特触发器翻转的两个阈值之间,施密特触发器不会动作,因而能消除脉冲抖动造成的不良反应。


最终该模块电路图

由于重置(RESET)信号是低电平有效,所以默认情况下应该维持高电平,采用串联两个非门施密特触发器我们得到了最终的复位电路的设计



时钟脉冲产生电路

时钟脉冲是整套数字系统的指挥棒,就像交响乐队指挥手中的指挥棒,其时间基准完全由它决定



振荡电路(时钟发生器)

-如果你想手动操作,也可以快速按下它,模拟连续的脉冲束,原理几乎和复位电路一样,只是电平相反。


时钟脉冲Clock由于是高电平有效,手动产生时钟脉冲(Manual Clock)的按钮应该采用下拉电阻接法。但是由于采用了一个反向施密特触发器,所以改位选用上拉电阻接法。


-当然,它也可以由正反馈电路发生振荡来产生



门电路组成的多谐振荡器

振荡原理:  假设Q为低电平,则非门2的输入端为高电平,经过R对C充电,C的电压上升,直到非门1输入端的电压达到反转电压,此时非门1的输出变为低电平,Q变为高电平。  此时,Q点、C、R、非门2的输入端,极性反转,相对于之前变为放电回路,然后转为反向充电,C的电压下降,直到非门1输入的电压达到反转电压,此时非门1的输出变为高电平,Q变为低电平。  如此循环,形成振荡,在Q端输出方波。  如果非门的反转电压为电源电压的1/2。  则振荡周期:T≈2.2·R·C  Rs用于稳定振荡频率,驱使为6~10倍的R。

时钟电路电阻值在TD4教科书的电路图中,规定了1Hz为33KΩ,10Hz为3.3KΩ的电阻值,但这个值实际上慢了一点。因此,下表显示了以电阻值计算的 60 秒内的实际时钟数。


电阻值(Ω)33K30K27K28.7K (33K // 220K)28.3K (33K // 200K)
时钟数5157635960


从此表中可以看出,在 33KΩ 时,它变为 51/60 = 0.85 Hz。因此,为了获得1Hz,从表中可以看出,当使用28.3KΩ(从E24系列的电阻值中选择,33K和200K并联)时,正好60/60=1赫兹。它变成了。


对于 10Hz,使用 2.83KΩ(3.3K 和 20K 并联),1Hz 的电阻值为 1/10。


RC充放电回路


上面的图来自维基百科(后面也有图片取自维基百科)。观察上面的图,当电源通过电阻 R 向电容 C 充电的时候,电容 C 两端的电压会如何变化呢(也就是会呈现出何种规律)?这可以应用基尔霍夫电路定律来建立一个微分方程,然后解出这个微分方程就会得到电容 C 在充电时的电压变化情况(也可以用拉普拉斯变换求解,关于如何求解这个方程则需要另一篇文章 :),它是时间 t 的函数:  有了公式我们就可以画出它的曲线,如图所示。如果你对此过程有疑惑或者需要了解更多,请参考电路或电路原理相关课本中的相关内容。


最终该模块电路图



用来存储程序的-只读存储器(ROM)

ROM(Read Only Memory)只读存储器,这种存储器(Memory)的内容任何情况下都不会改变,电脑与用户只能读取保存在这里的指令,和使用存储在ROM的资料,但不能变更或存入资料。ROM被存储在一个非易失性芯片上,也就是说,即使在关机之后记忆的内容仍可以被保存,所以这种存储器多用来存储特定功能的程序。

在本项目案例中,ROM的意思并非指程序不可改变,而是CPU在运行过程中,只能从该存储器阵列中读取,而不能写入或者改变其中的内容,但我们可以通过人手波动开关来写入或修改其中的内容。


-Memory (ROM) 电路使用 16 个 8 位 DIP 开关来指定 ROM 电路中的 0/1 位(DIP 开关的使用也可2 x 8 16接头和跳线针被用作替代品)。拨码开关相对昂贵,取决于类型,最大的问题是印刷电路板上比较占用空间。TD4教科书由拨码开关和二极管阵列组成,但二极管阵列比较特殊,很难获得。因此,不可避免地要使用普通的轴向引线型二极管。


组成开关阵列,并串联二极管

--CPU无法一次从ROM中读取所有程序,按照冯诺依曼原理,逐条指令读取逐条指令执行

这个例子是4位宽度的地址总线,就是2的四次方,共可以读取存储16个8位

--只需要一点一点的将其读取。就像看书,要一页一页翻着看

我想读取一位的电位,该怎么办?



1位ROM



3*4位ROM



通过选择哪一竖电位到地为低电位,横向导线分别读取每行电位的高低



组成交错的开关阵列很不错,但是读取第二竖列开关每行电位的时候,会受到第一竖列的开关选择影响,从而导致错误。


为什么要加二极管?二极管有什么作用?



每个开关连接到地参考电位前,都用二极管串联,即可避免干扰


指令地址译码



我们需要把每一竖列开关连接到地的选择过程自动化,和输入的地址编码对应唯一的选择,这个过程叫做译码。比方说,从CPU发出的地址总线请求(A3-A0)为0110,则读取第六个ROM中的8位数据作为程序的二进制指令通过(D7-D0)传给CPU加载该指令。


TD4教科书的电路图中,74HC154一次可以解码4位,用于指定ROM电路地址,但这里使用了两个74HC138 3-8解码器。得到等效电路。这仅仅是因为74HC138在更容易购买也更便宜,经销商的库存中也比较多。


译码器 3-8译码器 4-16译码器

译码器是电子技术中的一种多输入多输出的组合逻辑电路,负责将二进制代码翻译为特定的对象(如逻辑电平等),功能与编码器相反。 译码器一般分为通用译码器和数字显示译码器两大类。 ... 输入使能信号必须接在译码器上使其正常工作,否则输出将会是一个无效的码字。大多数随机存取存储器使用n线-2n线译码器来将地址总线上已选择的地址转换为行地址选择线中的一个。引脚布局图和功能逻辑图块两个3-8译码器组成一个4-16译码器,这是数字电子技术课程中组合逻辑电路译码编码部分的经典问题,绝大部分数字电子技术书籍和课本都会举例讲述,详情请参阅相关书籍。


75HC540的作用较为简单,作为练习,请大家自行阅读Datasheet。

最终该模块电路图





此电路可以由Arduino程序完全替代,详细程序,请看本文后续讲解。


寄存器电路

4个四位寄存器,由4个74HC161芯片构成,接下来我们一步一步看看它们是怎么工作的

补充知识双稳态电路 D触发器原理

触发器(英语:Flip-flop, FF),中国大陆译作“触发器”、台湾及香港译作“正反器”,是一种具有两种稳态的用于储存的组件,可记录二进制数字信号“1”和“0”。触发器是一种双稳态多谐振荡器(bistable multivibrator)。该电路可以通过一个或多个施加在控制输入端的信号来改变自身的状态,并会有1个或2个输出。触发器是构成时序逻辑电路以及各种复杂数字系统的基本逻辑单元。D触发器有一个输入、一个输出和一个时脉输入,当时脉由0转为1时,输出的值会和输入的值相等。此类触发器可用于防止因为噪声所带来的错误,以及通过管线增加处理资料的数量。带直接复位置位端的上升沿边沿触发的D触发器真值表D触发器符号。> 是时脉输入,D是资料输入,Q是暂存资料输出,Q'则是Q的反相值,S为1时强迫Q值为1,R为1时强迫Q值为0关于从基本RS触发器出发,是怎样由两个带有反馈的与非门或者或非门逐步建立起来的,并通过各种组合添加进一步形成其它更高级的触发器和计数器等内容,内容较为冗长,但对于打好相关基础非常重要,这里只大概解释各模块的外部主要特性。如果完全不了解,请读者读者查阅《数字电子技术基础》课本进行学习。



当上升沿建立起来的时候,D的状态被记录在Q中,在下一个上升沿到来之前,Q值不受D值改变的影响。



四位同步二进制计数器

在有了D触发器基础后,我们可以通过串联D触发器,得到一种叫做计数器的器件



逻辑功能图



时序逻辑图




状态转换图


通过参考查看74HC161的Datasheet后,我们知道此芯片正是这一类器件





74HC161引脚布局图



74HC161的Datasheet中的时序逻辑图可以看出,~CLR是异步清零端,所谓异步,就是指其作用并不随时钟脉冲才发生作用,即与时钟脉冲不同步,随时有效随时即刻清零所存储的数据。~LOAD低电平时,A、B、C、D的值被装载到QA,QB,QC,QD中,当ENP和ENT置高电平时,QA,QB,QC,QD组成的4位二进制数开始对外部脉冲CLK上升沿进行计数(0-15),当计数达到15后再来一个脉冲上升沿,计数溢出归零,并在RCO端给出一个正脉冲。


用带脉冲计数功能的74HC161的D触发器阵列构成寄存器



输入/输出


A寄存器和B寄存器受同一个时钟脉冲控制



将D触发器的输出端Q的信号,重新引回给触发器的输入端D,通过选择开关,即可实现数据在不同的D触发器之间传送。


如何在A寄存器和B寄存器之间交换数据,切换选择输入给哪个寄存器并保持。



譬如指令MOV A, D,就是将D寄存器内存储的数据,转存到A

数据选择器

我们需要将上述选择数据移动过程,转换成用特定芯片处理,这个过程所需要类型的芯片叫数据选择器。同时我们需要使用4个4位D触发器存储数据,即数据总线宽度位4bit,下图用划线加4bit标识。



通过75HC153的Datasheet查真值表,我们可以确认其功能是通过B,A的值,从DATA中选择C0,C1,C2,C3其中一个传输给输出Y。



通过Datasheet里的引脚分布和介绍,我们知道74HC153是两路数据选择器。由于我们传输的数据带宽是4bit,故需要两个74HC153芯片,分别作为数据选择器1和数据选择器2,共用选择信号A、B。



局部功能完成的电路图




算术逻辑单元(ALU)

补充知识加法器、全加器

74HC283用于TD4教科书的电路图中作为ALU使用的全加器。


加法器、半加器、全加器

相信认真阅读过数字电子技术基础课本中有关加法器章节的读者对此类器件的实现过程应该都印象深刻。加法操作是几乎所有算数运算中最基本的操作,原则上其它类型的算数逻辑操作都可以由此推延产生,因此仔细研究清楚其内部原理非常有必要,请读者认真参阅课本中相关章节的讲述内容,这里不再赘叙,仅给出真值表和逻辑图仅供参考。 半加器逻辑图和真值表 一位全加器的逻辑图和真值表一位全加器示意图4个一位全加器串联组成的4位全加器


此类推如果增加更多的数字,位数增加即可



4位全加器







Datasheet中74HC283的引脚图


组合一个最小系统

现在是时候组合寄存器、数据选择器、加法器,组成一个完整的指令执行系统。

无论如何,尝试做一个完整的ALU

我们来动手吧譬如执行指令ADD, Im






这样以来,就多了很多额外的东西 所以,如何执行MOV A, B呢?



立即数Im作为ALU的第二个输入数B,加法器得以实现,当指令用于传送时,令立即数Im=0即刻。这样,通过数据选择器A、B的信号组合与立即数的配合,上图的指令执行框图基本上可以实现如下类似指令

MOV A, Im 将立即数数据传送到 A 寄存器。

MOV B, Im 将立即数传送到 B 寄存器。

MOV A, B 将 B 寄存器传送到 A 寄存器。

MOV B, A 将 A 寄存器转移到 B 寄存器。

ADD A, Im 将立即数添加到 A 寄存器。

ADD B, Im 将立即数添加到 B 寄存器。


程序计数器

- 这是一个计数器,每次遇到一个脉冲则加一

- 如果它复位,则返回到零



这样很棒,在没有遇到跳转指令的时候,每次脉冲来都自动加一,很适合做储存地址的程序存储器PC(Program Counter),我们放弃了D寄存器用于通用数据的存储,将其作为程序存储器,而在遇到指令直接跳转的指令时,其相当于将立即数或者加法结果存储到寄存器D中。


整合输入输出

此外,我们还需要一个寄存器,作为输出驱动4个LED显示的输出寄存器,那么我们也放弃第三个寄存器,即C寄存器,作为OUT寄存器,其结果直接作为输出寄存器。



此外,你很可能觉得,还需要输入寄存器IN,那么又将牺牲多一个通用寄存器或者需要再添加一个74HC161。其实细想之下,这是不必要的,因为当使用的C、D寄存器作为特殊功能的寄存器后,4路的4位数据选择器只剩下2路被通用寄存器占用,我们把其中一路作为输入,另一路全部默认置零即可。这样,立即数就通过与全为零的数相加而可以被直接传送至通用寄存器A和B了。


保持进位的触发器Flip-Flop

带有条件的跳转指令往往需要通过比较计算和查看加法器的计算结果是否溢出。但加法器的溢出位C4记录的是当下的加法结果是否溢出,而非上一条指令执行时的加法结果是否溢出,这就需要一个触发器记录上一次的溢出结果,等到下一个脉冲来到时决定条件跳转指令是否执行。



我们选用了74HC74作为正边沿触发的flip-flop触发器,可以满足这个要求,详情请自行阅读Datasheet。



最后的整合与调整




指令译码电路(取指令)

- 每个时钟周期的脉冲来临时,就进行一次取指令、译码、并执行

- 被译码后,相应的电路执行指令预设的动作进行操作



这个译码电路相当有5个输入,共2的5次方种输入可能性,6个输出,2的6次方种输出可能性。然而仔细分析之下,我们需要的有意义的操作指令和相应的输出无外乎以下这些情况。




所以,总的运行架构框图如图所示




这个指令译码电路,设计过程看起来稍显复杂,然而它只是一个与时序无关的纯组合逻辑电路。参照表格所列,将所有输出结果用采用数字电子技术课本中的最小与或表达式写下,并运用包括德摩根定律在内的逻辑代数定律适度整理后,权衡器件选择和数量,就可得出如下最终的译码电路。












最后是编程指令集


TD4 中定义了十二种类型的指令,这里汇总了所有指令的列表。下图右端所示的 SelB、SelA、Ld0、Ld1、Ld2、Ld3 表示根据操作码和标志创建的解码信号。





     将立即数数据传送到 A 寄存器。

     在运行时,它不受 C 标志的影响。执行后,C 标志变为 0。



     将立即数传送到 B 寄存器。

     在运行时,它不受 C 标志的影响。执行后,C 标志变为 0。



     将 B 寄存器传送到 A 寄存器。

     在运行时,它不受 C 标志的影响。执行后,C 标志变为 0。



     将 A 寄存器转移到 B 寄存器。

     在运行时,它不受 C 标志的影响。执行后,C 标志变为 0。



     将立即数添加到 A 寄存器。

     在运行时,它不受 C 标志的影响。执行后,当发生进位时,C 标志设置为 1。



     将立即数添加到 B 寄存器。

     在运行时,它不受 C 标志的影响。执行后,当发生进位时,C 标志设置为 1。



     将数据从输入端口传输到 A 寄存器。

     在运行时,它不受 C 标志的影响。执行后,C 标志变为 0。



     将数据从输入端口传输到 B 寄存器。

     在运行时,它不受 C 标志的影响。执行后,C 标志变为 0。



     将立即数据传输到输出端口。

     在运行时,它不受 C 标志的影响。执行后,C 标志变为 0。



     B 将寄存器转发到输出端口。

     在运行时,它不受 C 标志的影响。执行后,C 标志变为 0。



     跳转到立即数指示的地址。

     在运行时,它不受 C 标志的影响。执行后,C 标志变为 0。



     当 C 标志为 0 时,它跳转到立即数所指示的地址。当 C 标志为 1 时,什么都不做。

     在运行时,C 标志会更改行为。执行后,C 标志变为 0。


Arduino替代ROM程序

data bus from D2 to D9

address bit from D10 to D13

//// ROM emulator for TTL based 4-bit CPU

byte prog[16];

//
void setup() {
  byte i;

for(i=0;i<16;i++){
  prog[i]=0;
}//// initialize program

/////////program part of 4-bit CPU
/////////////////simple blinking///////
//prog[0b0000]=0b10110011;
//prog[0b0001]=0b10110110;
//prog[0b0010]=0b10111100;
//prog[0b0011]=0b10111000;
//prog[0b0100]=0b10111000;
//prog[0b0101]=0b10111100;
//prog[0b0110]=0b10110110;
//prog[0b0111]=0b10110011;
//prog[0b1000]=0b10110001;
//prog[0b1001]=0b11110000;
////////////////////////////////////////

////other commands
////0011abcd: MOV "abcd" to A register
////0111abcd: MOV "abcd" to B register
////00010000: MOV B register to A register
////01000000: MOV A register to B register
////0000abcd: ADD "abcd" to A register
////0101abcd: ADD "abcd" to B register
////00100000: MOV input port (DIP switch) to A register
////01110000: MOV input port (DIP switch) to B register
////1011abcd: MOV "abcd" to output port (LED)
////10010000: MOV B register to output port (LED)
////1111abcd: JMP to "abcd"
////1110abcd: IF C \neq = 0 JMP to "abcd"
//// other details can be found in the book....


prog[0b0000]=0b10110001; //OUT(1011) "0001" to LED
prog[0b0001]=0b10110010; //OUT(1011) "0010" to LED
prog[0b0010]=0b10110100; // same till 0b1110
prog[0b0011]=0b10111000;
prog[0b0100]=0b10111001;
prog[0b0101]=0b10111010;
prog[0b0110]=0b10111100;
prog[0b0111]=0b10111101;
prog[0b1000]=0b10111110;
prog[0b1001]=0b10111111;
prog[0b1010]=0b10110000;
prog[0b1011]=0b10111111;
prog[0b1100]=0b10110000;
prog[0b1101]=0b10111111;
prog[0b1110]=0b10110000;
prog[0b1111]=0b11110000; // JMP(1111) to "0000" first of program




  
    Serial.begin(9600);
//// address bit from D10 to D13 
  for(i=10; i<14; i++){
  pinMode(i, INPUT);
  }

//// data bus from D2 to D9
  for(i=2; i<10; i++){
   pinMode(i, OUTPUT);   
  }
  
}

// the loop function runs over and over again forever
void loop() {

  boolean A[5],b[8];
  byte i,command_data;
  byte temp1;

// address read
    A[0]=digitalRead(10);
    A[1]=digitalRead(11);
    A[2]=digitalRead(12);
    A[3]=digitalRead(13);
    i=A[0]+2*A[1]+4*A[2]+8*A[3];
   // Serial.println(i);
    command_data=prog[i];
    //Serial.println(command_data);

/// converting to each bit
    b[0]=command_data &  0b00000001; 
    b[1]=(command_data & 0b00000010);
    b[2]=(command_data & 0b00000100);
    b[3]=(command_data & 0b00001000);
    b[4]=(command_data & 0b00010000);
    b[5]=(command_data & 0b00100000);
    b[6]=(command_data & 0b01000000);
    b[7]=(command_data & 0b10000000);
///////     

    for(i=2;i<10;i++){
      temp1=i+1;
      digitalWrite(i,b[i-2]);
    }

}


没错,设计方案源头的书是日文的,但是不要怕,我们会有很好的中文解析,大家完全能理解它!

哈哈哈,这句话我本来打算写在开头,但是怕读者畏惧,现在你已经读完了所有的解析,简单吧? 这句话成为了废话。


参考书籍:



图书出版社收到的读者书评

用10个IC轻松介绍CPU设计!

计算机的核心是一个名为CPU的黑盒子。 被称为CPU的黑匣子是计算机的核心,以4位CPU为例,从其运作的 "超级 "基本原理到设计进行解释。 你实际上可以只用秋叶原上的零件来制作你自己的CPU! 即使你没有真正做到这一点,它肯定是有趣的阅读。

-来自 "BOOK "数据库

一个叫做CPU的黑盒子是计算机的核心。 它解释了从其运作的 "超级 "基本原则到具体的设计实例的一切。 也可以只用秋叶原上的零件来实际建造。

-来自 "MARC "数据库

计算机的核心是一个名为CPU的黑盒子。 本书解释了从其运作的 "超级 "基本原则到具体的设计实例的一切。 你甚至可以只用秋叶原上的零件来建造你自己的东西!


作者简介

Iku Watanami

电路工程师。 从一家计算机制造商退休后,他成为一名独立的工程师。


基本信息

  • 出版社 ‏ : ‎ 毎日コミュニケーションズ (2003年10月1日)
  • 出版日期 ‏ : ‎ 2003年10月1日
  • 语言 ‏ : ‎ 日语
  • 单行本-平装 ‏ : ‎ 328页
  • ISBN-10 ‏ : ‎ 4839909865
  • ISBN-13 ‏ : ‎ 978-4839909864


立即购买套件:

编辑于 2024-04-15 18:09・IP 属地广东