So yesterday I implemented all the chips for the second NAND2Tetris project except for the big one: the arithmetic logical unit (ALU)!
Designing my first arithmetic logical unit
Thinking about what pieces I need… Definitely a 16-bit adder, which I implemented yesterday. I’ll need to negate 16-bit numbers and do bit-wise AND on 16-bit numbers, which I already took care of when I built the 16-bit AND and NOT gates.
But how do I set a 16-bit number to all zeros based on one control bit? And how do I switch the chip’s functionality from adding to AND-ing based on the control bits? Ah, I probably need a multiplexer! I remember wondering what that thing would be useful for back when I was designing one, and now it makes sense!
I guess multiplexers are the low-level hardware equivalent of the ubiquitous “if statement” from software! Cool! This should be pretty easy, then.
15 minutes later: Never mind. Maybe it’s not that easy. During my first attempt at a design, I realized I probably should be using a 4-way 16-bit multiplexer – or do I need two of those? Or… wait, no, that wouldn’t work because I still need more than one ouput. I need to sketch some more ideas. Right now I have a bunch of criss-crossed arrows pointing from one chip to another, indicating that I need a way to pipe these values through and I’m missing a big chunk of the pipeline. Maybe this would be easier if I start with the output and work my way backwards.
A few minutes later: Yes, this is much easier! I feel like I’m building a Rube Goldberg machine, passing bits through form one device to another, routing them all around. This does not feel efficient at all, but I’m pretty sure it’ll work and I’m pretty sure it’s the only way to implement this particular design using the chips I’ve already built.
Ah, I just realized that if I want to be able to set one of the inputs to the constant 1, I need to set the input to 0 before I pass it through the optional negation chip. It won’t work the other way around. So, that’s one design constraint to keep in mind…
A few minutes later: Done! (I think!) Now I’ll write it up in HDL and test it in the hardware simulator! Drum roll please! And the result is…
Comparison failure at line 2.
What?! I got it wrong?! I looked at the compare file and sure enough, I got the wrong output for the first test. Maybe I just made a typo? I refuse to accept that I need to take my design back to the drawing board!
After a little head-scratching and reviewing my HDL file, I found the problem: my pipes were crossed! I used the wrong variable name, piping a set of outputs to the wrong inputs. OK, let’s try this again. Drum roll please, once again!
Comparison failure at line 3.
Argh!!! Well, at least it passed the first test. It failed on the second. Let’s look for more typos first… Don’t see any typos…
Uh oh, this is bad. I’m looking at the compare file and I don’t understand why the expected output is what it is. Maybe I misunderstood the instructions? The truth table provided in chapter 2 of The Elements of Computing Systems (PDF) says that if all control bits are set to 1, then the output should be 1.
Well, I need stop and go to my next social engagement. This is a very social day, with three events scheduled! I hope I don’t get too burnt out… As it is, my mind is going to be chewing on this all day and I might not be able to focus on my upcoming conversations. Argh! I’ll try to put it aside and just have fun, even though I’m really not in the mood for “having fun” today. But I shall try!
Next steps
- Finish building the second project.
Time breakdown
- Study time: 1 hour 19 min
- Building project 2: 1 hour 19 min