What & How & Why

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录前一修订版
后一修订版
前一修订版
cs:comp_n_arch:courses:fnti_i:week_2 [2025/04/05 12:33] – [控制位与 16bits 输出位的真值表] codingharecs:comp_n_arch:courses:fnti_i:week_2 [2025/04/08 14:28] (当前版本) – [其他实现上的一些细节] codinghare
行 141: 行 141:
 {{ :cs:comp_n_arch:courses:fnti_i:contorl_bits_alu.svg?300 |}} {{ :cs:comp_n_arch:courses:fnti_i:contorl_bits_alu.svg?300 |}}
 \\ \\  \\ \\ 
-整个计算过程从左到右以此进行,比如下面的例子:+整个计算过程从左到右进行运算前面的运算结果会作为下一次的算子参与新的运算。比如下面的例子:
  
 <code CIL> <code CIL>
行 178: 行 178:
 out = 1001 out = 1001
 </code> </code>
 +==Add16:串行实现==
 +  * ''0'' bit 使用 half adder 计算
 +  * 之后只需要将前一位计算的 carry 交给下一个Full adder 即可
 +==Add16:Carry-ahead==
 +之前的方法非常慢,必须等到前一个 adder 的结果出来之后才能下一步。我们可以通过 Carry-ahead 的方法进行 carry 位的并行计算。
 +可以观察到的是,当前 adder 中送到下一个 carry 位是可以根据如下的情况来判断的:
 +  * 如果参与计算的 bits ''a'', ''b'' 都是 1,那么无论前一个 adder 传递来的 carry 位是什么,当前 adder 的 carry 位一定是 1,也就是 ''a and b''
 +  * 如果参与计算的 bits 中存在一个 1,且前一位的 carry bit ''ci'' 是 1,那么当前 adder 的 carry 位是 1。判断条件为 ''(a or b) and ci''
 +这里的第一部分(''a and b'')被称为 //Generate// 位(//G//),第二部分(''a or b'')被称为 //Propagate// 位(P)。也就是说当前 carry 位的值实际上取决于以下的表达式:
 +$$C_{i+1} = G_{i}∨(P_{i} ∧C_{i})$$
 +利用这个公式,我们可以对每一位的 $C_i$ 进行展开。也就是说,只要已知所有的 ''a'', ''b'',以及 ''0'' 位的 carry,那么所有的 adder 都可以直接对本位的 carry 进行计算,
 +比如第二位的 carry 公式就可以展开为:
 +$$C_2=G_1​∨(P_1∧G_0)​∨(P_1∧P_0​∧C_0))$$
 +==其他实现上的一些细节==
 +  * ''Mux16'' 是 ''if / else'' 的硬件实现,使用 ''sel'' 位来作为条件输入
 +  * 验证某个输出是否小于 0 只需验证其最高位,比如 ''out[15]'' 为 1 则该数为负
 +  * 验证某个输出是否等于 0 需要使用 ''OrNWay'' 对所有 bits 进行按位 ''Or''。这样计算后:
 +    * 如果有任意 bit 为 1,那么 Or 的结果都为 1。此时输出是不等于 0 的,如果再将其翻转(//Not//)再输出至是否相等的 bit,此时为 0,也就是不相等。
 +    * 反之,按位 Or 全为 0,翻转后结果为 1,说明相等。