diff options
Diffstat (limited to 'docs/projects')
-rw-r--r-- | docs/projects/nand2tetris_1.md | 52 |
1 files changed, 25 insertions, 27 deletions
diff --git a/docs/projects/nand2tetris_1.md b/docs/projects/nand2tetris_1.md index 12a8704..865595d 100644 --- a/docs/projects/nand2tetris_1.md +++ b/docs/projects/nand2tetris_1.md @@ -61,10 +61,10 @@ And this is one of the few chips that have so few pins exposed (hence "elementary") that you can craft a truth table for it, and thus can test them manually. -<details> -<summary> - <b>How I built and optimized the XOR gate by toying with boolean - expressions (click to expand)</b> +<details markdown="1"> +<summary markdown="1"> + __How I built and optimized the XOR gate by toying with boolean + expressions (click to expand)__ </summary> Here is the truth table of XOR, and you have to implement it with chips @@ -93,7 +93,7 @@ row that outputs 1: ``` Then we tie a NOT to each 0 input (excuse the pun), thus synthesizing two -sufficient conditions so that <code>out=1</code>: +sufficient conditions so that `out=1`: ``` (NOT a) AND b => out=1 @@ -128,7 +128,7 @@ XOR | ? ``` That's 9 in total. Can we optimize it? Let's try eliminating the OR first, -based on the fact that <code>a OR b = NOT((NOT a) AND (NOT b))</code>: +based on the fact that `a OR b = NOT((NOT a) AND (NOT b))`: ``` ((NOT a) AND b) OR (a AND (NOT b)) @@ -136,7 +136,7 @@ based on the fact that <code>a OR b = NOT((NOT a) AND (NOT b))</code>: ``` At first glance this might seem more complicated, but remember, -<code>NOT(a AND b) = a NAND b</code>… which is exactly our atomic building +`NOT(a AND b) = a NAND b`… which is exactly our atomic building block! We continue our equation: ``` @@ -216,8 +216,8 @@ But wait! Didn't we just see "x-y" and "y-x"? How can an Adder possibly do that? Note that there is no "Subtractor"; to do `x-y` you simply calculate `~(~x + y)` where `~` denotes bitwise negation, thanks to 2's complement. -<details> -<summary><b>Proof that <code>x-y = ~(~x + y)</code></b></summary> +<details markdown="1"> +<summary markdown="1">__Proof that `x-y = ~(~x + y)`__</summary> We know in 2's complement, @@ -267,8 +267,8 @@ proceeds to look for builtin chips implemented in Java. No other directory is in its path, even project 01. This explains why the optimization I made in project 01 does not matter. -<details> -<summary><b>If it did matter, how many NANDs are there in this ALU?</b></summary> +<details markdown="1"> +<summary markdown="1">__If it did matter, how many NANDs are there in this ALU?__</summary> It's Python scripting time! I just need to recursively find out how many NANDs in each subchip, then add them up. The syntax of HDL is pretty @@ -353,23 +353,21 @@ HDL. While I was drawing the schematics, a question came to mind: If I set `f` to zero, will the Adder be working the same way as if `f=1`? -<details> -<summary><b>Answer</b></summary> +<details markdown="1"> +<summary markdown="1">__Answer__</summary> Yes, it will. Simply put, chips "downstream" do not directly affect those "upstream" as far as this course is concerned. The implication is that, when you give an x and a y to the ALU, it does both computations at once: boolean AND and binary addition. It is the Mux's job to select which branch to pass downstream, and which one to discard. This is, in -a stretch, called -<a href="https://en.wikipedia.org/wiki/Speculative_execution"> speculative execution</a>. +a stretch, called [speculative execution](https://en.wikipedia.org/wiki/Speculative_execution) -<img alt="Schematic of ALU. The AND, Adder, and "f" mux are -highlighted" src="../img/nand2tetris/alu_highlighted.png" /> +![Schematic of ALU. The AND, Adder, and "f" mux are highlighted](../img/nand2tetris/alu_highlighted.png) -As you see in the highlighted area, <i>both</i> of these gates are +As you see in the highlighted area, _both_ of these gates are switching internally, and both of them consume power, even when one of -them does not generate useful output. Recall the <code>if</code> statement +them does not generate useful output. Recall the `if` statement in programming: ``` @@ -380,7 +378,7 @@ if (boolean) { } ``` -Either but not both of <code>do_a</code> or <code>do_b</code> will be run. +Either but not both of `do_a` or `do_b` will be run. This is one of the major mindblowers I came into, and I think it's worth writing about it. </details> @@ -496,8 +494,8 @@ which can be realized using this line of assembly (or instruction): @42 ``` -<details> -<summary><b>Expand to learn more about the difference between A and D</b></summary> +<details markdown="1"> +<summary markdown="1">__Expand to learn more about the difference between A and D__</summary> In HACK assembly, the A register is the only one you can directly assign an value to, like we just did. In contrast, if you want to write 42 into @@ -540,7 +538,7 @@ AD=1; // set A and D to 1 simultaneously AMD=1 // set A, M and D to 1 simultaneously ``` -C-instructions can also do something really cool, which is <b>jumping</b>. +C-instructions can also do something really cool, which is __jumping__. The syntax is different from what you might find in an industrial assembly language. @@ -549,12 +547,12 @@ language. D;JEQ // this jumps to ROM[42] if D=0 ``` -The <code>JEQ</code> here is a <b>jump instruction</b>. A jump instruction +The `JEQ` here is a __jump instruction__. A jump instruction compares ALU output to zero, and jumps if it is greater/equal/not equal/etc. -<details> -<summary><b>What if I want to jump to 42 if RAM[69] is zero?</b></summary> +<details markdown="1"> +<summary markdown="1">__What if I want to jump to 42 if RAM[69] is zero?__</summary> Can I just: @@ -564,7 +562,7 @@ Can I just: M;JEQ // does this work? ``` -No. <code>@42</code> completely overwrote <code>@69</code>, so the M on +No. `@42` completely overwrote `@69`, so the M on line 3 is actually RAM[42]. To perform this maneuver, we need to make use of D. |