如何在mc里打造一个计算器[3] -- 乘法器

在 二进制里如何实现乘法呢? 首先来回顾一下小学学的乘法:

把4567称作A, 1023称作B, 那么可以看到步骤有:
1. A与B的每一位相乘, 2. 根据B的位置把相乘后的数字移动到相应的位置, 3. 把移动后的数字按位加起来
但是我们不考虑硬件部分有两个以上的内存器, 所以每计算好一位的乘法应该马上加起来, 那么稍微调整顺序变为:
1. 假设原本输出C为0, 2. A与B的其中一位相乘, 3. 根据B的位置移动相乘后的数字, 4. 把移动后的数字加起来得到新的C, 返回2
把这个顺序按照小学方式写出来就是:

那么对于二进制, 一位的乘法过于简单: Ax0=0, Ax1=A, 那么乘法可以用与门代替
假设 B 逐位写成 [B3, B2, B1, B0], 那么4bits乘法可以写为:
A*B = (A<<0)&B0 + (A<<1)&B1 + (A<<2)&B2 + (A<<3)&B3

观察A*B这条式子, 可以看到A的位移是每执行一次加法就左移多一位, 那么设计部件时可以把这种位移特性考虑进去, 那么可以设计出一个部件:

此处应该有以下规则: A = A`<<1; C = C`+A`&B_i
那么一堆这样的部件堆在一起就是乘法器了

这种结构的乘法器叫做矩阵式乘法器 (好像是叫行列式乘法器?, 不管了)
不过可以看到输入是4bits, 而输出变为7bits, 一般考虑溢出整形的话, 乘法器只拿右边的6个全加器组成的部分, 而左边6个则直接扔掉 (是哪6个自己想想吧)
而对于负号的处理, 直接把两个负号位做xor就是输出的负号位了

与上篇专栏说的加减法器一样, 这个乘法器的输出只由此时的输入确定, 输入改变了输出也会改变, 同样也有一种只有"开始运算"信号输入才会开始计算的触发型乘法器, 而那种乘法器有很大的化简空间, 专栏第一张图就是一个32bits的触发型乘法器, 读者可以思考一下如何化简乘法器至最简
下一篇先跳过除法器说一下BCD转BIN和BIN转BCD

为了庆祝300粉(虽然可能马上就掉下去了), 就来说一下7段数字显示屏的ROM吧
把7段显示分别标上序号

那么数字4就可以表示在显示屏上的信号为: 0011110 (1234号位的显像管亮起来), 同理, 数字3的信号为 1011011
可以观察到, 0011和1011011, 0100和0011110并不存在必然的运算关系, 所以这时候只能够使用ROM(只读储存器),
以3为例: 假设输入为A, rom在3的部分为: if(A3==0, A2==0, A1==1, A0==1): Out=1011011; else: Out=0000000, 添加else部分是避免3的输出与其他数字的输出混淆
稍微使脑细胞减少一些就可以得到: if (not ((A3) or (A2) or (not A1) or (not A0)) == True): Out = 1011011; else: Out=0000000
如果将1011011与条件部分作and操作就可以免去条件操作, 于是得到: Out_3 = (not ((A3) or (A2) or (not A1) or (not A0))) and (1011011)
tips: A and B = not ((not A) or (not B)), A = not (not A))
于是可以设计出3的ROM结构:


在这个结构中, 只有输入恰好为0011才会输出1011011, 否则为000000
同理设计出0123456789的rom并把输出结果全部作or操作就得到了7段数字显示屏的rom部分了
整个rom都可以写成一条算式: (水字数)
Out = not(((A3)or(A2)or(A1)or(A0))or(not1110111))or not(((A3)or(A2)or(A1)or(notA0))or(not0010010))or not(((A3)or(A2)or(notA1)or(A0))or(not1101011))or not(((A3)or(A2)or(notA1)or(not A0))or(not1011011))or not(((A3)or(notA2)or(A1)or(A0))or(not0011110))or not(((A3)or(notA2)or(A1)or(not A0))or(not1011101))or not(((A3)or(notA2)or(notA1)or(A0))or(not1111101))or not(((A3)or(notA2)or(notA1)or(not A0))or(not0010011))or not(((notA3)or(A2)or(A1)or(A0))or(not1111111))or not(((notA3)or(A2)or(A1)or(not A0))or(not1011111))
事实上, 任何不含环状电路的结构, 其输出都可以用一条只包含or和not运算的式子表示出来, 包括加减法器, 乘法器, BCD转BIN, BIN转BCD和除法器, 写出来后可以直接化简式子来达到化简电路的效果, 但是真的太长了