用 逻辑电路 实现一个 开平方 算法

这篇文章 的 起因 是  《小梦 在 民科吧 发了一个 用 四则运算 开平方 的 帖》  https://www.cnblogs.com/KSongKing/p/13296121.html    。

《小梦 在 民科吧 发了一个 用 四则运算 开平方 的 帖》    也 发到了 反相吧  《小梦 在 民科吧 发了一个 用 四则运算 开平方 的 帖》  https://tieba.baidu.com/p/6811112759     。

我在 帖 里的  12 楼 说了,  小梦 的 算法 简单小巧,   适合 用在 计算器 上,   我们可以 设计一个 硬件电路 来 实现 它  。

先画 一个 逻辑电路图 :

                    

                                                

左边 的   a 、b 、c 、diff 、v1 、v2 、abs_c 、max_diff   是  存储单元,  也就是 内存,   也就是 内存单元,    假设 每个 存储单元 是 64 位 的,   可以 存储  64 位 浮点数  。

右边 的   F1 、F2 、F3 、F4 、F5 、F6   是  控制单元,   具体 的 控制 和 运算 逻辑 就在 控制单元 里 实现  。

橙色线 和 橙色箭头 是  控制信号线路 和 信号传递方向,    蓝色线 是 数据线路,     一根 线 在 实际中 可能是 多位 的  。

绿色线 和 绿色箭头 也是 控制信号线路,    表示 和 橙色 不同 的 控制分支 。

F1 、F2 、F3 、F4 、F5 、F6    都 会有 数据线 和  相关的 存储单元 相连,    图中 用 蓝线 简略 的 表示,  并没有 画出 具体 的 连接 线路  。

我们 定义 :      有电压 为 1,  无电压 为 0     。

开始运算 时,    输入端  输入 一个  1 脉冲,  就可以 触发 电路 开始 进行 开平方 运算  。    注意 是  1 脉冲,   不是 持续 的 1  。

先介绍一下 存储单元,   

a   存放 a,    a 是 中间结果,  也是 最终结果

b   存放 b,    也就是 被开方数

v1   存放  a ²  

diff   存放   b  -  a ²   

v2    存放   2 * a   

c   存放   diff / v2   

abs_diff   存放  diff 的 绝对值

max_diff   存放 精度值,   当    b  -  a ²   的 绝对值 , 也就是  abs_diff   小于  max_diff  时,  a 为 达到 精度 的 开方结果 ,  可以输出  。

开始 运算 前,     先 把 被开方数  存到  b,    同时 任取一个 正数, 比如 1 ,  存到 a  。

然后,   向 输入端 输入 一个   1 脉冲,   F1  接收 到  1 脉冲 后 接通电路,  开始工作 。   F1 的 工作 是 发信号 给 运算器,  让 运算器 计算 a ²,  运算器 计算 结束后,   F1 把 计算结果 存放到  v1 ,   同时 发出 一个  1 脉冲,  触发  F2  开始工作  。

运算器 在  这个 图 里 没有 画出来,    运算器 是 一个 公共部件,     F1 、F2 、F3 、F4 、F5 、F6  都会去调用  。

F1  的 内部电路  会 在 下文 画出来,   里面 会 画出  F1  调用  运算器 的  电路 和 逻辑  。

F1  的 内部电路  如下 :

           

                 

输入端 接收 到  1 脉冲,   这个 1 脉冲 会让  “让 寄存器 A 变成 写入状态”   电路 接通,  这个电路 会 向  寄存器 A  发出 信号,   告诉 寄存器 A 变成 写入状态,

同时,  输入端  的  1 脉冲  还会 让  “让 寄存器 B 变成 写入状态”  电路 接通,  这个电路 会 向 寄存器 B  发出 信号,   告诉 寄存器 B 变成 写入状态,

同时,  输入端  的  1 脉冲  会 触发   延时开关,    延时开关 在 一段时间 后 输出 一个  1 脉冲 ,   这个  1 脉冲 会 接通 下一个 操作 的 电路 。

这样 就可以 在 一个 操作 完成后 触发 下一个 操作 执行  。

为什么要用 延时开关 呢 ?    是 为了  确保 上一个 操作 完成 后,  才 触发 下一个 操作  。   因为  电路 的 运行 需要时间, 每一段电路 运作 需要 的 时间 也 不完全相同,  所以 需要 延时开关 在 一段时间 后 发出 1 脉冲 触发 下一个 操作,   这段时间 应该 足够 完成 当前操作,   这样 来 确保 触发 下一个 操作时,  当前 操作 已经 完成  。  

从 图上 可以看到,      “让 寄存器 A 变成 写入状态”    和    “让 寄存器 B 变成 写入状态”   是  F1  的  第一个 步骤,  这 2 个 操作 是 同时执行 的,  也可以说是 并行 执行 的  。

第 1 个 步骤 有 一个 延时开关,   当   “让 寄存器 A 变成 写入状态”    和    “让 寄存器 B 变成 写入状态”    完成 后,   延时开关 发出 1 脉冲,   触发 下一个 步骤  。

第 2 个 步骤 包含 2 个 操作,    “打开 a 和 寄存器 A 的 通路,  让 a 的 数据 写入 寄存器 A”  和  “打开 a 和 寄存器 B 的 通路,  让 a 的 数据 写入 寄存器 B”  ,

这 2 个 操作 也是 同时执行 的,    第 2 个 步骤 也 有 一个  延时开关,   这 2 个 操作 完成 后,     延时开关 发出 1 脉冲,   触发 下一个 步骤  。

到 目前为止,   每一个 操作 是 一段 电路,   这一段 电路 在 输入端 输入 1 脉冲 时 工作,   1 脉冲 结束 后 电路 停止  。

1 脉冲  是 有电压,  这个 电压 使得 电路 接通 并 工作,    1 脉冲 结束 后,   无电压,   电路不工作 。  延时开关 被 触发 后,   即使  输入端 的 1 脉冲 结束,  也会 在 设定好 的 时间 后 在 输出端  发出  1 脉冲   。

当然,  我们需要 知道 每一个 步骤 完成 的 最大时间,  以此 来 设置 这个 步骤 的 延时开关 的 延迟时间,    延迟时间 应该 比 步骤 完成 的 最大时间 更大一点,   这样 有一点 冗余,    有利于 电路 的 稳定运行  。

延时开关 的 输出端 连接 了 

猜你喜欢

转载自www.cnblogs.com/KSongKing/p/13385387.html