本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录前一修订版后一修订版 | 前一修订版 | ||
cs:comp_n_arch:courses:fnti_i:week_2 [2025/04/04 14:48] – [实例:Hack ALU] codinghare | cs:comp_n_arch:courses:fnti_i:week_2 [2025/04/08 14:28] (当前版本) – [其他实现上的一些细节] codinghare | ||
---|---|---|---|
行 125: | 行 125: | ||
本课例子(HACK ALU): | 本课例子(HACK ALU): | ||
* 接收两个 16 bits 的输入 | * 接收两个 16 bits 的输入 | ||
- | * 得到一个16 bits 的输出和两个 1 bits 的输出。 | + | * 得到一个 16 bits 的输出和两个 1 bits 的输出。 |
* 实现了一系列的(总共18个)**基础**函数 | * 实现了一系列的(总共18个)**基础**函数 | ||
* 调用哪个函数通过结构图正上方的 6 个 1 bit 的输入来决定。 | * 调用哪个函数通过结构图正上方的 6 个 1 bit 的输入来决定。 | ||
行 132: | 行 132: | ||
{{ : | {{ : | ||
\\ | \\ | ||
+ | ==控制位与 16bits 输出位的真值表== | ||
+ | Hack ALU 常用的 18 种运算的真值表如下: | ||
+ | \\ \\ | ||
+ | {{ : | ||
+ | \\ | ||
+ | 上面 6 个控制位均在 0 和 1 时代表了两种不同的运算: | ||
+ | \\ \\ | ||
+ | {{ : | ||
+ | \\ \\ | ||
+ | 整个计算过程从左到右进行运算,前面的运算结果会作为下一次的算子参与新的运算。比如下面的例子: | ||
+ | |||
+ | <code CIL> | ||
+ | // input | ||
+ | x = 0010 | ||
+ | y = 1011 | ||
+ | |||
+ | // calculation: | ||
+ | // control bits sequence from the turth table | ||
+ | 0 0 0 1 1 1 | ||
+ | |||
+ | // compute process | ||
+ | |||
+ | zx = 0 // do nothing | ||
+ | x = 0010 | ||
+ | y = 1011 | ||
+ | |||
+ | zy = 0 // do nothing | ||
+ | x = 0010 | ||
+ | y = 1011 | ||
+ | |||
+ | zy = 0 // do nothing | ||
+ | x = 0010 | ||
+ | y = 1011 | ||
+ | |||
+ | ny = 1 // y = !y | ||
+ | x = 0010 | ||
+ | y = 0100 | ||
+ | |||
+ | f = 1 // out = x + y | ||
+ | x = 0010 | ||
+ | y = 0100 | ||
+ | out = 0110 | ||
+ | no = 1 // out = !out | ||
+ | out = 1001 | ||
+ | </ | ||
+ | ==Add16:串行实现== | ||
+ | * '' | ||
+ | * 之后只需要将前一位计算的 carry 交给下一个Full adder 即可 | ||
+ | ==Add16:Carry-ahead== | ||
+ | 之前的方法非常慢,必须等到前一个 adder 的结果出来之后才能下一步。我们可以通过 Carry-ahead 的方法进行 carry 位的并行计算。 | ||
+ | 可以观察到的是,当前 adder 中送到下一个 carry 位是可以根据如下的情况来判断的: | ||
+ | * 如果参与计算的 bits '' | ||
+ | * 如果参与计算的 bits 中存在一个 1,且前一位的 carry bit '' | ||
+ | 这里的第一部分('' | ||
+ | $$C_{i+1} = G_{i}∨(P_{i} ∧C_{i})$$ | ||
+ | 利用这个公式,我们可以对每一位的 $C_i$ 进行展开。也就是说,只要已知所有的 '' | ||
+ | 比如第二位的 carry 公式就可以展开为: | ||
+ | $$C_2=G_1∨(P_1∧G_0)∨(P_1∧P_0∧C_0))$$ | ||
+ | ==其他实现上的一些细节== | ||
+ | * '' | ||
+ | * 验证某个输出是否小于 0 只需验证其最高位,比如 '' | ||
+ | * 验证某个输出是否等于 0 需要使用 '' | ||
+ | * 如果有任意 bit 为 1,那么 Or 的结果都为 1。此时输出是不等于 0 的,如果再将其翻转(// | ||
+ | * 反之,按位 Or 全为 0,翻转后结果为 1,说明相等。 |