Circuitjs 创建自定义逻辑(Custom Logic)器件
您可以使用 自定义逻辑芯片 来实现自己的简单逻辑器件.
位于“菜单--绘制--数字芯片--添加自定义逻辑”下, 或者是"右键--数字芯片--添加自定义逻辑".
一个具体示例
来看一个具体的示例, 通过它来讲述 自定义逻辑 是什么, 为什么以及怎么去做.
这个示例如下, 两个输入 A1 和 A0, 两个输出 S1 和 S0, 两者间的关系也很简单, 就是对输入简单取反, 因此使用了两个 非门 就达到了目的.
输出与输入间的关系就是:
S1=!A1
S0=!A0
其中感叹号 ! 表示取反.
上述的逻辑是用电路直接实现, 现在假设要使用自定义逻辑的方式去做一个等价实现, 从而取代上述 非门 构成的电路, 要怎么去做呢?
至于为什么引入自定义逻辑, 放在后面再解释.
第一步是添加一个自定义逻辑器件, 在菜单或右键中选择 添加自定义逻辑
, 然后拖动生成一个缺省的自定义逻辑器件:
默认情况, 它包含两个输入 A 和 B, 两个输出 C 和 D, 但这只是缺省情况, 可以进一步调整, 输入和输出均可以是一个或多个, 而不是限于两个.
下一步是双击(或"右键--编辑")组件编辑其属性:
首先给它一个名称, 比如 "two-bit-invert":
接着点击 编辑模型
, 在弹出窗口中, 有四个属性可以编辑, 分别为 输入
, 输出
, 信息文本
, 定义
, 下面将一一说明:
- 输入
改为
A1,A0
, 与原型一致, 以(英文)逗号分隔. 当然, 这里实际叫什么并不是特别重要, 根据你自己需要去定义即可, 但建议尽可能简短.视具体情况不同, 输入端可以有更多或更少. 比如
X,Y,Z
就表示有三个输入端, 名称分别被设为 X, Y 和 Z. - 输出
改为
S1,S0
, 与原型一致(同理, 这里实际叫什么也不是特别重要)同样的, 输出端也不限于两个, 可以更多或更少.
- 信息文本
这里可以填入对功能的一个具体描述, 比如 "对各位取反"
- 定义
这是最重要的, 它定义了输入输出间的逻辑关系.
怎么定义呢? 最简单方式就是枚举所有输入的组合情况, 并给出对应输出的值.
如果你有数字电路基础, 很明显这跟所谓的 真值表(True Table) 就是一回事.
那么对于前述取反逻辑, 最终的定义如下:
00=11
01=10
10=01
11=00
最终如下:
等号左边对应输入, 右边对应输出.
第一行, 左边 00 分别表示 A1=0, A0=0, 右边 11 表示 S1=1, S0=1;
第二行, 左边 01 分别表示 A1=0, A0=1, 右边 10 表示 S1=1, S0=0;
第三行, 左边 10 分别表示 A1=1, A0=0, 右边 01 表示 S1=0, S0=1;
第四行, 左边 11 分别表示 A1=1, A0=1, 右边 00 表示 S1=0, S0=0;
很显然, 以上通过枚举所有输入(及对应的输出)情况, 表达了前述的取反逻辑:
S1=!A1
S0=!A0
如果创建另一个自定义逻辑, 并有如下定义:
00=0
01=1
10=1
11=1
那么就是定义了一个具有两个输入端, 一个输出端的逻辑组件.
显然, 上述定义实际上就是一个 或门.
同样的, 还可以定义更复杂的如异或门, 半加器, 全加器, 译码器以及其它你想要的逻辑组件等等.
确定之后, 组件按我们定义的输入, 输出名称显示如下, 当鼠标移上去后, 画布的右下角还将显示对应名称及信息文本:
自定义逻辑示例在线交互电路
接下来可以测试其是否满足相应逻辑, 如果不能满足, 则可能需要仔细检查 定义
里的规则是否有误; 如果一切 OK, 则可以用它取代两个非门构成的电路.
自然, 对于简单的, 容易实现的逻辑来说, 自定义逻辑并没有什么优势;
但对于更复杂一些, 更多输入, 输出的情况, 你可能一下子想不出用电路怎么去实现, 又或者能用电路实现, 但非常庞杂, 各种组件, 连线非常多, 这时自定义逻辑就有优势了.
最终, 所有的逻辑还是要落到具体的电路实现上, 自定义逻辑有时更像是一种"投机取巧", 但用得好, 它还是可以辅助你在整体设计期间, 先忽略部分模块的具体实现, 不至于迷失在过多的细节里, 你可以假设这些子部件是已经实现的, 然后测试整体的逻辑是否 OK.
当大的框架及交互没有问题时, 你可以回过头来再一一去实现那些自定义逻辑, 所以, 它也可以帮你推迟某些实现, 但又不影响整体的功能.
小结
每个自定义逻辑器件都有一个模型名称, 该名称指向描述其工作方式的模型.
您可以创建具有相同型号的任意数量的器件.
编辑模型会更改使用该模型的所有器件的行为.
编辑模型时, 可以指定输入, 输出, 一些信息文本(将鼠标悬停在器件上时显示在右下角)和定义.
输入(和输出)是(英文)逗号分隔的短引脚标签列表(最多一个或两个字符).
您还可以指定 取反标签, 像 /Q
对应 Q.
示例:A,B,/C,/D
定义是形式为多行的 输入=输出.
与输入引脚匹配的第一个输入模式将被选中, 并将输出引脚设置为与输出模式匹配.
模式可以包含比特值(0
, 1
), 过渡(+
, -
), 通配符/任意值(?
), 和模式字母(A
, B
, 等等).
输入必须不少于输入引脚的数量.
如果更长, 则会将额外的模式字符与输出引脚进行匹配;这使您可以创建带有状态的器件.
输出模式还可包含 _
, 以指示高阻抗状态.
更多示例
前面举的具体示例代表了最基本, 最常用的情况, 但自定义逻辑还支持更复杂的表达方式, 比如通配之类的; 甚至, 除了组合逻辑外, 你还可以定义时序逻辑组件.
下面是一些具体示例及说明.
3输入与非门
输入: A,B,C
输出: X
定义:
111=0
???=1
如果所有三个输入均为 1, 则输出为 0. 否则为 1.
全加器
输入: A,B,C
输出: S,C
定义:
111=11
110=10
011=10
101=10
100=01
010=01
001=01
000=00
SR 锁存器
输入: S,R
输出: Q,/Q
定义:
?? 00=10
10 ??=10
01 ??=01
?? AB=AB
输入模式(等号的左侧)按顺序匹配 S, R, Q 和 Q.
等号右侧指定对应的 Q 和 Q 结果值.
第一行, 如果两个输入均为低电平, 则将 Q 输出置位(复位电路时需要此设置).
第二行, 如果 置位端(set) 为高, 则将输出设置为 1,0.
第三行, 如果 复位端(reset) 为高, 则将输出设置为 0,1.
第四行, 除以上情况外, 将使输出保持不变.
前两个字母与输入引脚匹配, 后两个字母与输出引脚匹配.
空格会被忽略, 此处添加空格仅为清晰起见.
D 触发器
输入: D,Clk
输出: Q,/Q
定义:
?? 00=10
0+ ??=01
1+ ??=10
?? AB=AB
如果两个输入均为低电平, 则第一行将 Q 输出置位(复位电路时需要此设置).
接下来的两行在时钟的上升沿时将 Q 输出设置为与 D 输入匹配.
除以上情况外, 最后一行使输出保持不变.
JK 触发器
输入: J,K,Clk
输出: Q,/Q
定义:
??? 00=10
00- AB=AB
10- ??=10
01- ??=01
11- AB=BA
??? AB=AB
如果两个输入均为低电平, 则第一行将 Q 输出置位(复位电路时需要此设置).
接下来的四行在时钟的负跳变上实现JK触发器逻辑.
除以上情况外, 最后一行使输出保持不变.
数字比较器
输入: A2,A1,A0,B2,B1,B0
输出: Eq,A>,A<
定义:
ABC ABC=100
1?? 0??=010
A1? A0?=010
AB1 AB0=010
??? ???=001
第一行检查两个输入是否相等. 接下来的三行测试 A 是否更大. 否则, B 更大.
3位计数器
输入: Clk
输出: A,B,C
定义:
+ AB0=AB1
+ A01=A10
+ 011=100
+ 111=000
? ABC=ABC
该计数器在 Clk 输入的正跳变时递增计数.
第一行处理从 000、010、100 或 110 开始的计数.
第二行处理从 001 或 101 开始的计数.
接下来的两行处理 011 和 111.
最后一行确保除非时钟产生正跳变, 否则输出不会改变.
具有 使能功能 的 3 输入与非门
输入: A,B,C,En
输出: X
定义:
1111=0
???1=1
???0=_
与上面的 3 输入与非门相同, 不同之处在于如果 使能引脚 为低电平, 则输出进入高阻抗状态.
三态缓冲器
输入: A,En
输出: X
定义:
A1=A
?0=_
如果 使能位 为高, 则输出与A相同;否则, 如果 使能引脚 为低, 则输出进入高阻状态.