10、自动操作(改进版)

在初级版的自动操作,从控制面板在RAM列输入要计算的所有数,然后断开清零开关,则会自动的累计所有数值,并且显示到控制面板的灯泡上。

假如,我们需要对50对数分别求和,这就不是一个好办法了。因此,我们想到把运算结果存回到RAM阵列中去,这样的话,在适当的时候用RAM阵列的控制面板来检查运算结果。

这意味着,我们需要去掉锁存器连接的灯泡,取而代之的是把锁存器的输出端连接到RAM阵列的数据输入端,这样就可以把计算结果写回到RAM阵列去。电路图如下所示:

要解决上诉的问题,我们就要考虑,如何配置一个自动加法器,使它不仅仅可以对一组数字做累加运算,还希望它能够自主地确定要累加多少个数字,而且还能记住RAM中存放了多少计算结果,这样子就可以简化工作。

 

例如,我们要先对三个数进行求和,然后对两个数求和,最后再对三个数求和。想象一下,我们可以把这些数保存在RAM阵列中以0x0000开始的存储空间中,具体形式如下所示:

我们希望该加法器可以做这么四件事情:首先它要把第一个字节从存储器传送到累加器中,这个操作称之为加载(Load)。第二个操作把存储器中的一个字节加(Add)到累加器的内容中去。第三个操作把累加器中的计算结果取出并存放(Store)到存储器中。另外我们需要一个方法令自动加法器停(Halt)下来。

我们就借助上面的例子,详细介绍一下这个过程。

[1] 把0x0000地址处的内容加载到累加器。

[2] 把0x0001地址处的内容到累加器中。

[3] 把0x0002地址处的内容到累加器中。

[4] 把累加器中的内容存储到0x0003地址处。

[5] 把0x0004地址处的内容加载到累加器。

[6] 把0x0005地址处的内容到累加器。

[7] 把累加器中的内容存储到0x0006地址处。

[8] 把0x0007地址处的内容加载到累加器。

[9] 把0x0008地址处的内容到累加器。

[10] 把0x0009地址处的内容到累加器。

[11] 把累加器中的内容存储到0x000A地址处。

[12] 令自动加法器停止工作。

最初的加法器只是简单地把存储器指定地址的内容和累加器中的内容相加,在某些情况下需要这样子做。但是有时我们需要把存储器中的某个值直接加载到累加器,或者把累加器中值直接保存到存储器。

该如何完成这个工作呢?对于RAM阵列中的每一个数,我们需要一些数字代码来标识加法器要做的每一项工作:加载、相加、保存和停止。

也许存放这些代码的最简单方法[但肯定不是最小代价]是把它们存放在一个独立的RAM阵列中。这个RAM应该和第一个RAM同时访问。但是这个RAM中存放的不是需要求和的数,而是一些数字代码,用来标识自动加法器对第一个RAM中指定地址要做的一种操作。这两个RAM可以分别被标记为“数据”和“代码”。结构图如下所示:

此外,我们需要四个代码来标识新的自动加法器需要的四个操作,这些代码可以任意指定。如下是一种方案。

为了实现上面例子三组数字的相加,需要通过控制面板把如下值输入到代码RAM阵列,同时给出数据RAM的内容。

                          

比较一下代码RAM与数据RAM的内容,你会发现,代码RAM阵列存放的每一个代码都对应着数据RAM中被加载或者加到累加器中的数,或者对应需要存回到数据RAM中的某个数。

改进后的加法器如下图所示:

图中省略了一些组件,但是仍然可以清晰的描述各个组件之间的8位数据通路。16位的计数器为两个RAM阵列提供了地址输入。通常,数据RAM阵列的输出传入到8位加法器执行加操作。8位锁存器的输入可以是数据RAM阵列的输出(执行Load指令时),也可以是加法器的输出(当执行Add指令时),这种情况下需要一个2-1选择器。通常,锁存器电路的输出又回流到加法器中,但是当执行Store指令时,它就成为了数据RAM阵列的输入数据。

上图缺少的是控制所有这些组件的信号,它们统称为控制信号,包括16位计数器的“时钟”输入和“清零”输入,8位锁存器的
“时钟”输入和“清零输入”,数据RAM阵列的“写”输入,2-1选择器的“选择”输入。其中一些信号很明显是基于代码RAM阵列的输出,例如,如果代码RAM阵列输出Load指令,那么2-1选择器的“选择”输入必须是0(即选择数据RAM输出)。只有当操作码是指令Store时,数据RAM阵列的“写”输入必须是1。这些控制信号可以通过逻辑门来各种组合来实现。

 

此外,我们是否可以改进自动加法器的电路,使它可以进行16位数的加法操作呢?

答案是肯定的,我们需要做的仅仅是在第一步运算时保存低字节运算的进位输出,并把它作为下一步高字节运算的进位输入。如何保存1位呢?1位锁存器就是最好的选择了,该锁存器应该被称之为进位锁存器(Carry latch)。

为了使用进位锁存器,还需要另外一个操作码,我们称之为“进位加法”(Add with Carry)。当进行8位数字加法时,使用的是常规的Add指令。加法器的进位输入是0,它的进位输出将会保存到进位锁存器。

如果要对两个16位的数进行加法计算,我们仍然使用常规的Add指令对两个低位字节数进行加法运算。加法器的进位输入总是为0,而其进位输出被锁存进进位锁存器中。当把两个高位字节数相加时,使用新的Add with Carry指令。在这种情况下,两个数相加时要用进位锁存器的输出作为加法器的进位输入。

下面给出例子,假如需要计算0x2CAB + 0x2376,那么需要分别在代码RAM和数据RAM保存下面内容:

计算结果低位保存在0x0002地址处,高位保存在0x0005地址处。

通过这种方法,我们可以方便的进行16位数、24位数、32位数、40位数,甚至更多位的数字进行加法运算。下面再给出一个32位数字相加的运算例子,0x7A892BCD和0x65A872FF相加,我们需要一条Add指令,3条Add with Carry指令。

到此,我们改进版的自动计算电路比初版做了相当大的改变。一个是引入了指令,用来指示不同的动作,此外还添加了代码RAM。对于初版来说,我们已经做到了很多优化的点,比如所它可以停止了,比如说它比之前版本更加的智能了,比如说它可以计算超过8位的数值加法了。

不过它仍然还有一些缺点,通过控制面板输入的计算的数的存储单元不是连续的,并且保存计算的结果也不是连续的,像前面的例子[两个16位数字相加],计算结果低位保存在0x0002,而高位保存在0x0005。

除此之外,当前设计的自动加法器不允许在随后的计算中重复使用前面的计算结果。产生这个问题的原因就在于我们构造的自动加法器具有如下特性:它的代码存储器和数据存储器是同步的、顺序的,并且都从0x0000开始寻址。代码存储器的每一条指令对应数据存储器中相同地址的存储单元。一旦执行了一条Store指令,相应的,就会有一个数保存到数据存储器,而这个数将不能重新加载到累加器。

后面,我们会在继续优化自动加法器,它会变的更加灵活的。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值