How do computers work? (from scratch, no prior knowledge needed) — Transcript
Full transcript
- 0:00So, in this video, I'd like to try and
- 0:03explain just exactly how a computer
- 0:06works. And I know that sounds like an
- 0:08incredibly open-ended and difficult
- 0:10question to answer. And I'm going to go
- 0:12ahead and guess that the length of this
- 0:14video will make that self-evident that
- 0:17it's not any trivial question in itself.
- 0:19But, uh, this is something that I
- 0:22wondered a lot growing up. And, uh, even
- 0:25when I got to college, I knew I was
- 0:27going to study computer science. But it
- 0:29wasn't until halfway through my degree
- 0:30where I took the course which answered
- 0:33this question and I found everything I
- 0:36learned really interesting. Ended up
- 0:38TAing that course for a few semesters
- 0:40afterwards and uh find the really
- 0:43low-level stuff of computing to be
- 0:44fascinating. And I've been surprised at
- 0:48uh a the lack of direct resources online
- 0:51that can answer this question for just
- 0:54an average person who's curious and b
- 0:57how many uh friends I have working
- 1:01technical jobs or who studied computer
- 1:04science or related degree in college and
- 1:07are not too sure how a computer actually
- 1:09works. And I think um there's a lot of
- 1:14benefits to be held from this knowledge.
- 1:16Uh if you are just curious like I am, I
- 1:19want to cater this video to be
- 1:21completely digestible even if you have
- 1:23no mathematical or technical background.
- 1:26And I also want this video to be useful
- 1:29for someone who might already be uh
- 1:31doing an engineering relating job
- 1:33because uh a lot of these lower level
- 1:35principles might actually affect how you
- 1:37structure code or just uh lay out your
- 1:40programs at a higher level. Um so in
- 1:43this video I'd like to start with no
- 1:46assumption of what a computer work how a
- 1:49computer works. uh just basic
- 1:52mathematics will be assumed which I'm
- 1:54assuming if you clicked on this video
- 1:55you have a somewhat of an understanding
- 1:57of um we're just going to be starting
- 1:59simple with like addition, subtraction,
- 2:01multiplication, division uh and like
- 2:04exponents. I think that's probably all
- 2:06the background you need to be able to
- 2:09follow along for this entire video. So
- 2:11I'm going to answer this question by
- 2:14making a CPU from scratch. Um
- 2:18and then we're going to go ahead take
- 2:20that processor uh which can run one
- 2:23program and build an operating system or
- 2:26just explain kind of at a higher level
- 2:28how an operating system can be built for
- 2:31our processor uh and what an operating
- 2:33system actually is because that's also a
- 2:35great question in itself. Um but without
- 2:38getting into too much detail now the
- 2:40computer you're watching this on even if
- 2:42it's a phone uh is is doing multiple
- 2:44things at once. And if you're like me,
- 2:47uh you probably have this YouTube video
- 2:48open, iMessage in your background, um
- 2:51and maybe a few other tabs behind those
- 2:53two. And uh it's a really interesting
- 2:56question cuz we're going to get to a
- 2:58point in this video where you design a
- 2:59CPU and it can execute one program. And
- 3:02a really common and good follow-up
- 3:05question is how can my computer run
- 3:07multiple programs at the same time? Um,
- 3:10and so we're going to go ahead and dive
- 3:12into what that looks like as well
- 3:14because it's a it's interesting to know
- 3:15how a computer works. Um, but I also
- 3:17want to make it pragmatic and get to
- 3:19something more modern uh, which is an
- 3:22operating system. So, uh, I also would
- 3:25like this video to be useful um, even if
- 3:28you don't watch it all the way through.
- 3:30I have no idea how long this is going to
- 3:32be. I am guessing it will not be short
- 3:34though. And what I would hope is um for
- 3:39those of you who don't watch it all the
- 3:41way through, which is the vast majority,
- 3:42I'm assuming, uh the individual segments
- 3:46uh will be of value themselves. And
- 3:49maybe hopefully you learn something
- 3:51interesting along the way. Even if you
- 3:53didn't take it all the way, you learned
- 3:54something. Um and what we're actually
- 3:57going to start at is one of the most
- 4:00interesting topics I think personally uh
- 4:02that anyone can know. And if you only
- 4:05watch this first segment of the video
- 4:06and nothing else, you've at least
- 4:08learned something really interesting.
- 4:09Um, so I'm going to start by uh
- 4:14explaining how computers represent
- 4:16numbers and letters. Uh, how do we how
- 4:19can computers count? How can they add
- 4:21numbers? Um,
- 4:23and you've probably heard of something
- 4:25along the lines of computers speak in
- 4:28zeros and ones. And uh, this isn't
- 4:31nonsense. It's actually very true.
- 4:32Computers don't really recognize or
- 4:35process numbers the way we do. They only
- 4:38operate on zeros and ones. And once we
- 4:42uh understand how computers represent
- 4:44numbers, it's going to make sense why
- 4:46they do it like this. Um without getting
- 4:50into too much specifics now, but also
- 4:52without being incredibly vague, uh I'll
- 4:55say when we design computers, um they're
- 4:57built with electricity. And so we can
- 5:00represent the absence of electricity
- 5:01with a zero and the presence of
- 5:03electricity with a one. Um and with this
- 5:06it it kind of gives us a lot of
- 5:08flexibility to well if we can represent
- 5:10anything in zeros and ones and we know
- 5:12how to represent zeros and ones with
- 5:13electricity or the absence of it. Then
- 5:15we can kind of build on top of that and
- 5:17design an entire computer. Um, and you
- 5:19may be wondering, well, why don't we
- 5:21just use a little a little bit of
- 5:23electricity represents uh a one, a
- 5:26little bit more than that represents a
- 5:27two, and so on and so on until the the
- 5:30maximum of electricity we could have
- 5:31represents a 10, and then computers
- 5:33could just work with the the numbers we
- 5:35know. Um, but from an engineering
- 5:38perspective, it's not that easy to
- 5:40implement. Um, I don't want to get into
- 5:41the specifics of electricity because
- 5:43that's also uh probably a little too low
- 5:45level for what I want to accomplish in
- 5:46this video, but um, it turns out
- 5:50electricity is is very inconsistent in
- 5:52in in I guess flickers might be a better
- 5:54word for what I'm trying to say. Um, so
- 5:56we find it easier just to say have a
- 5:58certain threshold of of electricity,
- 6:00quote unquote, and anything below that
- 6:02we interpret as a zero, and anything
- 6:03above that threshold we interpret as a
- 6:05one. Um, and again, it's not going to
- 6:08make perfect sense what I'm saying. If
- 6:10you're already a little bit confused, it
- 6:12should be confusing cuz I'm kind of
- 6:14jumping jumping ahead of myself here.
- 6:17So, I just wanted to give some context
- 6:19for why we uh represent numbers with
- 6:22just zeros and ones in computers. So,
- 6:24let's go ahead and understand how
- 6:25computers represent numbers. Um, so I'm
- 6:28going to clear this screen here that
- 6:29you've been staring at for 5 minutes
- 6:31now. And let's start with uh a quick
- 6:35recap of how we represent numbers. So if
- 6:38I put the number 724 on the screen,
- 6:42intuitively you know exactly what this
- 6:44is. I mean it's a number you can
- 6:45rationalize. You can imagine say 724
- 6:49uh pencils in your hand or something
- 6:50like that. But how do we actually uh how
- 6:54did we learn this? When you were in
- 6:55elementary school and learning how to
- 6:57count, this number wasn't always easy to
- 6:59you. In fact, the first time you saw
- 7:00this, it probably made no sense to you,
- 7:02but you're older now, you're smarter,
- 7:03and you know how to interpret this. Um,
- 7:06so I'm going to redumb this back down to
- 7:08our elementary school level and uh see
- 7:11how we can build this number by looking
- 7:14at each of the digit positions. So, we
- 7:16know this right here is the ones place.
- 7:19That's probably not surprising. Um, we
- 7:22know this is called the 10's place. And
- 7:24then we know this is called the
- 7:25hundred's place.
- 7:29And uh this is something you know and
- 7:32you don't remember when you learned it,
- 7:33but you know that you learned it at some
- 7:35point. And we know that if we keep
- 7:36going, we have the thousand's place and
- 7:38then the 10,000's place, then the
- 7:40hundred thousand's place and the
- 7:42million's place, the 10 million's place,
- 7:44the 100 million's place, and so on and
- 7:46so on. Um
- 7:49and so
- 7:51what exactly do each of these places
- 7:53mean? And how can we take the values
- 7:56from each of these places and and
- 7:57generate a composite number? Um, so it
- 8:01turns out that to to get the value of a
- 8:03number, uh, we have to, and this is
- 8:06going to sound painfully obvious and
- 8:07almost a little bit confusing because of
- 8:09how obvious and true it is to you, but
- 8:11I'm saying it cuz it's going to make
- 8:12sense when we look at the computer
- 8:14version. um to get the value of a
- 8:17number, we could look at the value of
- 8:19each of the digits places and kind of
- 8:23sum them all up together. So, we know in
- 8:25the ones place, this four uh is just
- 8:29going to be whatever value is in that
- 8:31digit spot times the weight of that
- 8:33spot. So, right here we have 4 * 1,
- 8:36which equals 4. And then over here, we
- 8:41have a two and it's in the 10's place.
- 8:44So that's going to be time 10 and that's
- 8:46going to be 20. And then over here we
- 8:50have a [snorts] seven in the hundred's
- 8:52place. So we multiply it by the weight
- 8:54of that place which is a 100 and we have
- 8:57700. And then we can as I said we could
- 9:00add all these values together. So once
- 9:02we compute the weight of each digit
- 9:04position we can go ahead and add those
- 9:06uh those scaled weights together. So
- 9:09then we have 700 + 20 + 4. And I'm going
- 9:14to stack those numbers on top of each
- 9:16other because that's kind of how we
- 9:16learn how to add numbers. Um, oops, not
- 9:2024. Uh, and we know exactly that there's
- 9:23only one non-zero digit in each
- 9:25position. So it's just going to carry
- 9:27right down. Um, and so we kind of
- 9:30started with 724 and ended with 724. Um,
- 9:34and that's that's nothing too crazy. Um,
- 9:38but let's go ahead and and structure
- 9:39that out a little more. So, what we saw
- 9:41here is that 724
- 9:44is equal to 7 * 100 +
- 9:502 * 10 +
- 9:544 * 1. And where did that come from?
- 9:58Just to recap, it is for each digit
- 10:01position, we take the value that is in
- 10:04that that spot and then multiply it by
- 10:07the weight of the position. So we know
- 10:09the very first digit position is the
- 10:11one's place, so its weight is one. Then
- 10:13the next one is the 10's place, so its
- 10:14weight is 10. And then the next one's
- 10:16the hundred's place, so its weight is
- 10:18100. Um, and then if we were to expand,
- 10:22so we've kind of taken our number 724
- 10:24and written written it out in this
- 10:26expanded way. Um, and hopefully I've
- 10:29convinced you that this is true and
- 10:31correct, and it it is. Um, unless I've
- 10:33made some error, but let's look at an
- 10:36even uh more alternative way uh to to to
- 10:41write out this expanded form. And all
- 10:44I'm really going to do is uh replace the
- 10:47weights um of the position. So, let me
- 10:51write this out and then we'll kind of uh
- 10:54revisit what I'm trying to say.
- 11:00Okay, so I told you um that this is
- 11:04going to run on basic math. Uh and the
- 11:07exponent is probably as complicated as
- 11:09we need to get for you to understand
- 11:10everything about how a computer works.
- 11:13Um everything loosely put everything uh
- 11:16that I'm going to teach you in this
- 11:17video. Um so just to recall that uh 10
- 11:22uh to the 1 is is 10 10^ squared uh when
- 11:28we have a a number raised to an exponent
- 11:30it just means we multiply the number by
- 11:31itself that many times. Um so 10 by 10
- 11:36is equal to 100. And then if we had 10
- 11:39cubed we multiply 10 by itself three
- 11:42times. um and that's going to be a
- 11:45th00and.
- 11:47And then uh one caveat to that is um
- 11:51there's this rule that says anything
- 11:53raised to the zero power is equal one.
- 11:55Um and uh so that means that when we
- 11:59have 10^ the 0, it's going to equal one.
- 12:01Um, that's just something you probably
- 12:03learned in algebra 2, uh, from high
- 12:06school, which is probably so far out of
- 12:08your memory at this point, but just just
- 12:10take it to be the truth that, uh,
- 12:12anything raised to the power of zero,
- 12:14we're just going to say equals 1. Um so
- 12:19what I've done here is I've rewritten
- 12:20our expression uh in this kind of
- 12:24exponentiated form where each component
- 12:27in our sum is some number multiplied by
- 12:3110 raised to some power. Um and we also
- 12:36have it that uh the powers are
- 12:39increasing. So we start with the zero
- 12:41power then we go to power one and then
- 12:43we go to power two. Uh, and that that's
- 12:47funny enough and that that's actually uh
- 12:50not surprising or the more you think
- 12:52about it, the more unsurprising it
- 12:54should be because uh 10^ the 0 is 1 and
- 12:57so that's the one's place and then uh 10
- 13:00to the^ of 1 is 10 and that's the 10's
- 13:03place and then 10 to the^ of two is 100
- 13:05and that's what we call the hundred's
- 13:06place. Um so all we've really done here
- 13:09is is taken our number 724 and in write
- 13:13it out in this expanded form. Um and
- 13:17that is all we will recap about the
- 13:20numbers that you and I know. So now that
- 13:23we know uh or now that I've shown you
- 13:25just an alternate way to consider the
- 13:27numbers we know um we have the context
- 13:30uh to go ahead and move on and learn how
- 13:33computers count numbers. So this is how
- 13:35we count numbers. And it turns out
- 13:37computers do it very similarly. So all
- 13:39of this right here is called decimal.
- 13:43That is our human way of counting
- 13:45numbers. And it's also something that's
- 13:47called base 10.
- 13:50And what does that mean? Base 10 is
- 13:53worth uh worth probably discussing a
- 13:55little bit before I move on and and jump
- 13:56to the computer equivalent. But um one
- 14:00way to interpret base 10 is that it
- 14:02means that for any digit position in a
- 14:05number, there are 10 different values
- 14:07that could go into that digit spot. So
- 14:10uh in our 724,
- 14:13um let's say I pick this digit position
- 14:14right here. We could either have uh a
- 14:18zero, a one, a two, or all the way up to
- 14:21a nine. Um
- 14:24so we could have 10 different numbers
- 14:27could go in this spot. And if you're
- 14:28wondering why it's not nine, it's
- 14:30because uh one through nine is nine
- 14:33numbers and then the digit zero lets us
- 14:35add one and so we have 10. So we
- 14:38actually have it that in uh any digit
- 14:41position um there can be 10 different
- 14:43values in base 10. And uh let's also see
- 14:47what happens when we're counting. So for
- 14:49counting in base 10 i.e. The only way
- 14:52that you and I know how to count for
- 14:54now, um, we start with the number zero,
- 14:57it becomes one, and then two, three, and
- 15:01then we're going to go all the way up
- 15:03and we get to nine. And each time here,
- 15:06we're just adding one. So, we're just
- 15:08plus one, plus one, um, all the way
- 15:10down. We get to eight, we add + one, we
- 15:12get to nine. Um, and we've used all 10
- 15:16available values that can fit in this
- 15:18digit position. So when we want to add
- 15:20one to nine um we're stuck. We can't do
- 15:24that in one digit position. So we have
- 15:26this idea of rolling over um where we we
- 15:30reset this digit back to zero and then
- 15:33carry carry uh a one over to the next
- 15:37digit place. Um and so if we take these
- 15:40numbers and and write it out in our
- 15:42expanded form, then we know 9 is just
- 15:44equal to or let's start with 10. 10 is
- 15:47equal to 1 * 10 uh + 0 *
- 15:541. Um oops. And then if we have 9 um
- 15:58then we have zero in the 10's position
- 16:01and a nine in the ones position. Um, and
- 16:05so it's kind of curious that when we we
- 16:07get to the maximum value in a current
- 16:10digit position and we want to add one to
- 16:12that, then we roll over the current
- 16:14digit position back to a zero and then
- 16:18add one to the next digit position. This
- 16:21kind of makes sense because what we're
- 16:23doing here is we are when we have this
- 16:27nine here, um, we know that we want to
- 16:30add one more to our collective value. So
- 16:32what we could do is subtract nine from
- 16:35this spot and then add one from this
- 16:38spot and that gets us the exact
- 16:40difference. Um that that is the same as
- 16:43accomplishing uh a net just addition of
- 16:46one. We took all the value from the uh
- 16:50the digit position to the right and then
- 16:52reset it to a zero and then added one to
- 16:55the next digit position to the left and
- 16:57this is the same number. Um,
- 17:01so that's how we kind of carry over and
- 17:03and we kind of see this happen when we
- 17:04add numbers. So if I go to a quick
- 17:06example where we add numbers, let's say
- 17:08we have um 18, we want to add three.
- 17:12Then uh we have 18 + 18 + 3. We start in
- 17:17the rightmost digit position and we add
- 17:19the two numbers together. So an 8 + 3 is
- 17:21an 11. And you remember from elementary
- 17:24school that you put the one down here,
- 17:26the remainder, and then you add the
- 17:28carryover up here. And um then you do 1
- 17:31plus one is two. And that's that is the
- 17:33uh kind of exact same logic that we're
- 17:35showing in this in this uh extended
- 17:38form. But obviously when you were
- 17:40younger, there was no no reasonable way
- 17:42for you to understand this version of
- 17:44things. You kind of just learn this rule
- 17:45that you uh you kind of take what you
- 17:48have. if if you if a digit position
- 17:51exceeds 10, you put the remainder down
- 17:53below and then add one to the carryover.
- 17:57Um, and so that is uh just some more
- 18:02context that we're going to see this
- 18:03come back very shortly. So we saw that
- 18:05base 10 is this idea that we can have 10
- 18:09different values in any digit position.
- 18:12And now we're going to come and uh learn
- 18:15what base 2 is. So we said humans speak
- 18:18in base 10. Um so this decimal
- 18:23is synonymous with base 10.
- 18:26And now I'm going to make this claim
- 18:28that computers uh operate in base 2. And
- 18:33this is called binary.
- 18:37And so what does this actually mean? Um
- 18:41well we said in base 10 what that means
- 18:43is that in any digit position you can
- 18:45have 10 different values. And so what we
- 18:49can translate that to in base 2 is then
- 18:51in any digit position we can have two
- 18:53different values. And those two
- 18:55different values are zero and one. Um
- 19:00and that is just exactly where the idea
- 19:03that computers only speak in zero and
- 19:05one come from. Um but let's go ahead and
- 19:08see what that means. So, um, I'm going
- 19:12to give us a binary number. So, we're
- 19:14going to start with the binary number
- 19:161011.
- 19:17Um, and this is a binary number. This is
- 19:20this is not to be confused with the
- 19:22number 1,11.
- 19:25This is uh which is in base 10. Um, so I
- 19:28will distinguish it by subsetting it
- 19:30with this two. Um, so I will try to make
- 19:33the distinction as clear as possible. If
- 19:35we are speaking about a decimal number,
- 19:38i.e. a number that you and I are
- 19:39familiar with, um, I'll write a 10 next
- 19:42to it. So, if instead I wanted to say, I
- 19:45guess our example above, we had the
- 19:46number 724.
- 19:48So, from now on, I would say 724 base 10
- 19:52just so you uh don't get confused. But
- 19:55in general, it's for I'm not going to
- 19:57try to give you a a complicated example.
- 19:59Um, so if there's just zeros and ones,
- 20:02it's probably safe for you to assume
- 20:04that I'm talking about base 2. And if
- 20:06there's other digits, then it's the base
- 20:0810 that we're so familiar with. Um,
- 20:12and let's go ahead and I'm also going to
- 20:15rewrite our expanded form of 724. So,
- 20:19let me move this down. Um, and for 724,
- 20:23we said it was 7 * 10^ 2
- 20:27+ 2 * 10 1st power + 4 * 10 0 power.
- 20:34because we start uh with the lowest
- 20:36power of 10 and then we just keep adding
- 20:38one each time. Um and so now we're I'm
- 20:41I'm kind of we're kind of curious here.
- 20:43Uh how can we take this binary value and
- 20:46translate it back to a decimal value?
- 20:50What does 1011 mean in binary? Like what
- 20:54number is that to us? Um and it turns
- 20:58out we're just going to follow the same
- 21:00exact expansion rules. So, uh, we're
- 21:03going to sum up for each digit position,
- 21:07um, the value in that position, which is
- 21:09either a one or a zero. And then instead
- 21:12of 10 raised to some power, we're going
- 21:16to use two raised to some power because
- 21:19this was for base 10, but now we're
- 21:22going to be using base 2. So it'll be
- 21:24we're going to start with um the one
- 21:27spot is going to be two to the zero and
- 21:30then instead of the 10 spot being
- 21:32afterwards uh we're going to have the
- 21:34two spot which is a little interesting
- 21:36cuz you know in our in our current uh
- 21:39number we would have um in our in our
- 21:41binary system that we're so comfortable
- 21:42with we start with the ones position and
- 21:45then go to the 10's position and then
- 21:47the hundred's position. Um, and now
- 21:50we're going to start with the one's
- 21:51position and then go to the two's
- 21:53position cuz that's 2 to the first
- 21:55power. And then after that position, we
- 21:58have two to the second power, which is
- 21:59four. Um, and after that would be 8. And
- 22:04so if I come to our original decimal
- 22:06example, we notice that between each of
- 22:08these, we're multiplying by 10. And now
- 22:11we're in each of these, we're
- 22:13multiplying by two. Um, we're looking at
- 22:15increasing powers of two, which is is is
- 22:18pretty interesting. Um, so let me go
- 22:21ahead and erase that. And if this is
- 22:23feeling a little bit confusing, I really
- 22:25hope it it it should it shouldn't feel
- 22:27intuitive yet. Um, I've said a lot of
- 22:30random things so far in this video. Um,
- 22:33and now is where we're actually start
- 22:35tying them together. So, let me spill
- 22:38the answer for you on this one, and then
- 22:40we'll we'll walk through and see what it
- 22:41means. So,
- 22:43um, let's start with the rightmost digit
- 22:45position. Uh, cuz we start with, uh, 2
- 22:49to the^ of 0. Um, so I'm going to do 2
- 22:52to the^ 0. And what do we multiply it
- 22:54by? We multiply it by the one that's
- 22:56there. And then we have that digit
- 22:58position done. Now we come on to this
- 23:00digit position. Uh, we have uh, we're
- 23:03not on the 2 to the^ of zero. Now we're
- 23:06on 2 to the^ of one. And then we
- 23:08multiply that by whatever is in that
- 23:10digit position, which also just happens
- 23:11to be a one. Um, let me move this over
- 23:14here. Um, and then we then move on to
- 23:19this digit position, which is the 2 to
- 23:23the^ of two position. And what's there
- 23:26is multiplied by a zero. And then we
- 23:29come on to the very last digit position.
- 23:31And that one is uh the next power to
- 23:33use. We use powers 0, one, and two. So
- 23:36now we use the power of three um and we
- 23:38multiply it by whatever is there. So now
- 23:42we have this expression
- 23:44um and you might need to pause here and
- 23:46just read this out loud to yourself to
- 23:48make sure that you understand exactly
- 23:50how I derived this long form expression.
- 23:53Uh it may not be clear what exactly I'm
- 23:55doing but how I got this expression
- 23:57should be clear. Um
- 24:00and you should also be able to
- 24:02understand that uh in base 10 i.e. top
- 24:05row binary that or decimal sorry that
- 24:07we're used to. Uh each digit position is
- 24:11some increasing power of 10. That's the
- 24:13weight for each digit position. Now that
- 24:16we're in base 2, each digit position,
- 24:19the weight of that position is some
- 24:21power of two. Um and let's go ahead now.
- 24:25Uh if you need to pause and and just run
- 24:28through what I explained, do that now.
- 24:31But let's go ahead and uh expand this
- 24:34out. Um so we know that uh we have 1 and
- 24:38then 2 to the^ of 3. So 2 cubed is 2 * 2
- 24:43* 2 and 2 * 2 is 4. So * 2 is 8. So we
- 24:48have 1 * 8. And then we have 2 ^ 2 um
- 24:52which is 2 * 2 which is just equal to 4.
- 24:56And we multiply that by 0.
- 24:58Um and then we have 2 to the 1st power
- 25:01which is the easy one. And we all know
- 25:02that's just two. Any number to the first
- 25:06power is just saying multiply that
- 25:08number by by itself uh once not two not
- 25:12two times that's squared. So we just
- 25:14have it once then it's just that number
- 25:16itself. Um and then we also said earlier
- 25:19that anything to the power of zero is
- 25:21just one. So now we have this expression
- 25:25and now we're this should look pretty
- 25:27comfortable. Uh no exponents here. So 8
- 25:30* 1 is 8. Uh 0 * 4 is 0. 2 * 1 is 2. And
- 25:371 * 1 is 1. And that's just 8 + 2 which
- 25:40is 10 + 1 which is 11. So and that's
- 25:44base that's uh base 10 11. So the the
- 25:48number the 11 we're comfortable with. So
- 25:50now I can tell you that this number 1011
- 25:53in binary is just 11. Um
- 25:57and that is a totally different way of
- 26:00representing a number uh that we are
- 26:02already familiar with. Um and this is
- 26:04really interesting because we only had
- 26:07zeros and ones to work with, but we were
- 26:09able to map that back to a number that
- 26:12we know perfectly. Uh that doesn't need
- 26:14to just use zeros and ones. Um so let's
- 26:17go ahead and look at uh one more
- 26:19conversion example. Um and uh let's do
- 26:24the number um 1 0
- 26:28uh 01. Um and kind of go through the
- 26:33same process again. So uh we know that
- 26:36the weighted positions let's start with
- 26:38that actually. Um let me make this a
- 26:41little bit wider so we can write on top
- 26:43of them. 1 0 0 1 that's base 2. And we
- 26:47want to know what this equals in base
- 26:4810. Um and so if we start from the right
- 26:51we know that this is the 2 to the 0ero
- 26:53position then this is 2 to the 1 then
- 26:55this is 2^ 2ar and this is 2 ^ 3. Um and
- 26:59that's just for our reference. Um so we
- 27:02can go ahead and generate this uh this
- 27:04long form expression where we know if we
- 27:07start from the very right we know that
- 27:09that is
- 27:111 * 2 0 and then we have a 0 * 2 the 1.
- 27:17Um and the the 0ero comes from the fact
- 27:21that that's what's in this digit
- 27:23position and that's also where the one
- 27:25comes from here. And then for the next
- 27:27digit position we have a 0 * 2 ^ of two.
- 27:32And then for the very last digit
- 27:33position we have 1 * 2 ^ of 3. Um so
- 27:38then we can go ahead and combine those.
- 27:40We add those all up. Um so this 1 0 0 1
- 27:44in base 2 is equal to 1 * 2 cubed + 0 *
- 27:502^ 2 + 0 * 2 the 1st power + 1 * 2 0
- 27:59power. Um, and this time, uh, I could
- 28:04expand this all out, but there's
- 28:05something interesting to note here, and
- 28:07that's that we have two examples of us
- 28:09multiplying a number by zero. And from
- 28:13basic numbers, uh, as you also learn in
- 28:16school, anything times 0 is just zero.
- 28:18Um, so there's no point in us doing
- 28:21these expansions of converting 2 ^2 to 4
- 28:24uh, just to multiply by zero. If we see
- 28:26that it's being multiplied by a zero,
- 28:28let's just ignore it because we know
- 28:29it's not going to add any any values to
- 28:31our final sum. And that's that that
- 28:33that's going to save us some time later.
- 28:35Uh if I gave you a super long binary
- 28:37number that was like say a 100 digits
- 28:39wide and told you to convert it um
- 28:42then you know this would this would be
- 28:44kind of uh a big time saving um for all
- 28:48those zeros that you could drop out. Uh
- 28:50so then we can simplify this expression.
- 28:53Uh we dropped out those zeros. We just
- 28:55have these two terms left. And then we
- 28:58know that 2 cubed is 8. So that's 1 * 8.
- 29:02And then uh remember that anything to
- 29:03the power of 0 is just 1. So then we
- 29:05have 8 + 1 which is 9. So and that's 9
- 29:10in the decimal we know. So this 1 0 0 1
- 29:13in base 2 is equal to 9 in the number
- 29:16system that we know. And this is uh
- 29:20really cool. Um, I remember when I first
- 29:23learned this, I was kind of mind blown
- 29:26uh at the fact that we could take these
- 29:29random se this seemingly random sequence
- 29:31of zeros and ones and then map it back
- 29:33to a number that we are so familiar
- 29:35with. Um, and
- 29:40that uh should make it clear how we go
- 29:43from binary the zeros and ones to
- 29:47decimal which is a number system we
- 29:49speak. Let's look at one other example.
- 29:51What if I gave you this this big number
- 29:54right here in binary? That's not the
- 29:56number 10,000. That is 1 0 0 0 in
- 30:00binary. But I would like to know what is
- 30:03this in base 10. Um and
- 30:07uh well, we know let's just go ahead and
- 30:09count our positions and then generate
- 30:11this expression. Um so we know our digit
- 30:13positions start at 0 1 2 3 and four. So
- 30:17we have uh that it equals 1 * 2 4 and
- 30:22then + 0 * 2 3 + 0 * 2 ^ 2 + 0 * 2 ^ of
- 30:331 + 0 * 2 ^ of 0. And from the rule we
- 30:38learned in the example before, whenever
- 30:40we're multiplying something by zero, we
- 30:42can just get rid of that term cuz it's
- 30:43going to equal zero. That's exactly
- 30:45what's happening in all of this
- 30:47expression except for this one digit
- 30:49position. And then we just know that uh
- 30:512 to the 4 is equal to 2 * 2 * 2 * 2.
- 30:56And that's going to be uh 2 * 2 is 4.
- 31:00Multiply by 2 again you get 8. And then
- 31:01one more time you get 16. So this number
- 31:04right here uh 1 0 0 0 in decimal is
- 31:09actually going to be equal to 16 or
- 31:12sorry 1 0 0 0 in binary is going to be
- 31:15equal to 16 in decimal um and uh luckily
- 31:21this is a very popular concept. So if
- 31:24you're feeling a little confused here um
- 31:27on anything I've shown that's totally
- 31:29fine. Just go ahead and Google it. watch
- 31:31another YouTube video if you need to.
- 31:33Um, I do not want to do more examples
- 31:36just because this video could drag on
- 31:37forever. Okay, so now we have learned up
- 31:42to this point how to take a binary
- 31:44number and translate it back into the
- 31:48base 10, i.e. decimal number that we're
- 31:51more familiar with. So, what I'd like to
- 31:53do now is the exact opposite process. If
- 31:56I have a number like 14, how can I get
- 32:00it to binary? And we're going to almost
- 32:02take the inverse of the exact process we
- 32:05we had before. And why are we going to
- 32:08learn this? It's going to be because um
- 32:11we're going to want to program our
- 32:13computer eventually. And we're going to
- 32:14want to be able to store numbers in our
- 32:17computer. And it's going to be useful
- 32:20then, in fact imperative that we know
- 32:22how to take the number we want to put
- 32:23into our computer and convert it to
- 32:25binary so we can load it into the
- 32:26language that the computer speaks. So uh
- 32:29we've been working with this number 724.
- 32:33So let me go ahead and give us the
- 32:35expanded version one more time. So we
- 32:37said this was 7 * 10 ^ of 2 + 2 * 10 1st
- 32:43power + 4 * 10th power. [snorts]
- 32:49And
- 32:51I'm also going to go ahead and bring up
- 32:53this binary example from above. Uh where
- 32:56we had let's just say 1 0 1 1.
- 33:00And I'm going to sub subscript this with
- 33:03two because it's binary. And we said
- 33:05this is equal to 1 * 2 to the 3 + 0 * 2
- 33:12^ 2 + 1 * 2 1st power plus uh sorry 1 *
- 33:202 to the zeroth power. [snorts] And if
- 33:23we notice something here um everything
- 33:26on our right hand side is decimal
- 33:30numbers the ones we're very familiar
- 33:31with. And we know that we take this this
- 33:34left-hand side which is unfamiliar to us
- 33:36and we're able to expand it out in a
- 33:39form that is actually only containing
- 33:41decimal numbers. [snorts]
- 33:44And this is the exact kind of logic
- 33:46we're going to take to get a number from
- 33:49binary to decimal. So if I have the
- 33:52number 724 and want to convert it to to
- 33:55binary then if there's a way where I
- 33:58could write it out in this expanded form
- 34:01as uh numbers zeros and 1* 2 to some
- 34:05power then we know we can just read the
- 34:08the multiplicate the multiplicative
- 34:10coefficients left to right to know our
- 34:12number. Um in this case it's easy. we
- 34:15have we have a one and then a zero and a
- 34:17one and a one and this is exactly how we
- 34:19end up with this number over here. So
- 34:22this is a little abstract um and this is
- 34:24probably a little more complicated than
- 34:27what we just learned. Uh it's my
- 34:29personal opinion that taking a a binary
- 34:32number and converting it to decimal is
- 34:34easier than me asking you to take a
- 34:37decimal number and convert it to binary.
- 34:39But let's go ahead and do this by
- 34:42working through an example. Um so let's
- 34:46take the number 15. 15 in base 10 i.e.
- 34:50just the regular 15 we're familiar with.
- 34:53What exactly is that in decimal or in
- 34:55binary? Um so question mark base 2. What
- 35:00we want to end up with is some
- 35:02expression where we start with 2 ^ 0 and
- 35:06work up to some power of two and
- 35:09multiply each of those terms by either a
- 35:11zero or a one. uh until we have some
- 35:14equivalent value that sums up to 15. And
- 35:19as we kind of saw earlier with this
- 35:20binary conversion, we only really need
- 35:22to care about the powers of two that are
- 35:24multiplied by one. I in our example
- 35:27here, this one uh since it's multiplied
- 35:29by zero, it drops out. So we kind of
- 35:32know that uh I'm going to move this out
- 35:35the way. Uh this is really just equal to
- 35:38uh 2 ^ 3 + 2 ^ of 1 + 2 ^ of 0. Um and
- 35:45I'm gonna make this interesting claim uh
- 35:47that any number in decimal any number
- 35:50that you can think of can be expressed
- 35:53as a sum like this. And what do I mean
- 35:56this? I mean a sum of powers of two. And
- 36:00there is a exactly one way to represent
- 36:03each number accordingly. Um
- 36:06and I can show you some examples. So if
- 36:08we have the number one in decimal, then
- 36:11we know that two to the 0ero is just
- 36:13one. And then let's say we have the
- 36:15number two in decimal. Well, this is
- 36:17easy as well. We know 2 to the^ of 1 is
- 36:19just two. Uh but let's look at let's
- 36:21look at h what happens when we have
- 36:23three. Um well, we know how to represent
- 36:26one and two in binary. Uh and we can
- 36:29just add those together because they sum
- 36:31to three. So we would just add their
- 36:32binary representations together and we'd
- 36:34be left with 2 1 + 2 0 and then four is
- 36:39easy uh because we would know that 2 ^
- 36:43of 2 is 4. Um and then we'll do one more
- 36:47which is five uh and we know that uh 5
- 36:52is equal to 4 + 1. So that's 2 ^ of 2 +
- 36:562 ^ of 0. And now uh for each of these
- 37:00let's uh go ahead and convert it back to
- 37:02binary. Um so let's start with this this
- 37:05five because I think it's the most
- 37:07interesting case. And we know that the
- 37:09uh we can't skip any digit positions.
- 37:11I.e. the rightmost digit position in our
- 37:13binary number has to start at 2 to the
- 37:150. The power has to be zero. And then we
- 37:18have to keep working up from there until
- 37:19we we have all the powers that we need
- 37:21in our sum. And that's the same way when
- 37:23you're when you're building out a number
- 37:24in decimal. You can't skip the 10's
- 37:26place or the hundreds place just because
- 37:28the value in that digit position is
- 37:29zero. You have to explicitly write a
- 37:32zero to make it apparent that there is
- 37:34no value in the 10's place and then the
- 37:36next value is the hundred's place. So in
- 37:38our example here what we would need to
- 37:41do is um I'm going to bring out in this
- 37:45long form. So we we know we have this 2
- 37:46to the two. We don't have any uh thing
- 37:49multiplied by 2 to the first power. So
- 37:51we do is we just leave it as a zero. We
- 37:53make the coefficient zero because that
- 37:55means it multiplies out to nothing. And
- 37:57then we have 1 * 2 to the 0 power. And
- 38:00this is the exact form from earlier
- 38:02where it was pretty easy from there just
- 38:04to read the coefficients left to right.
- 38:061 0 1. And now we have our decimal or
- 38:09our binary number. Sorry. So we took our
- 38:11five and uh got it to a binary
- 38:15representation. And if you don't believe
- 38:17me, well, the evidence is on the screen.
- 38:19But if you want to verify for yourself,
- 38:22pose the counter question. What is the
- 38:25decimal representation of the value of
- 38:27the binary value 101? And if you expand
- 38:30it out like I've already done, you're
- 38:31just going to get five. And uh let's do
- 38:34this for the example of 42. So we have
- 38:37all we have is 2 ^2. But we know we have
- 38:40to get all the way back down to the
- 38:41power of zero. 2 to the^ of 0. we just
- 38:44add in 0 * each of those terms. So we
- 38:46have 1 * 2 ^ of 2 and then we don't want
- 38:49to add anything else. So we just do 0
- 38:51for the first power of two and zero for
- 38:54the zeroth power of two. And then we
- 38:56know we just read these coefficients
- 38:58left to right which is 1 0 0. So that's
- 39:01how we represent four in binary. And in
- 39:05our example here, we have it easy cuz we
- 39:08have every power of two uh in the entire
- 39:12range included. So we know that's 1 * 2
- 39:14^ of 1 + 1 * 2 ^ of 0. And that's just
- 39:18going to be equal to 1 1 in binary. And
- 39:21we'll just go ahead and finish out what
- 39:22we have here. Uh we know that 2 ^ of 1
- 39:26is equal to 1 * 2 ^ of 1. Then we don't
- 39:28want to add anything else. We just
- 39:30multiply the remaining terms by zero.
- 39:32And there's only one remaining term for
- 39:34us to get back to the power of zero. So,
- 39:35we're just left with one zero. Uh, and
- 39:37that's supposed to be subscripted with
- 39:39the two.
- 39:41And last but not least, uh, this one's
- 39:43trivial. Um, we've already worked our
- 39:46way back down to 2 to the^ of 0. So, we
- 39:49just have that one term and that's just
- 39:51equal to one. Um, so hopefully you
- 39:54notice a little bit of a pattern here.
- 39:55uh where I have been able to convince
- 39:57you at least that the first five numbers
- 39:59in decimal are are uh able to be
- 40:04expressed as a sum of twos raised to
- 40:09various powers. And if we can figure out
- 40:12for any number what that sum is, then
- 40:14I've shown you it's pretty easy once you
- 40:16have that to expand it out and then get
- 40:18the binary representation.
- 40:20[snorts]
- 40:21So let's try a uh a little bit more
- 40:23difficult example. Um uh let's try 13.
- 40:29And
- 40:30>> what we're going to do is we want to
- 40:32find the sums of twos to various powers
- 40:36that sum up to 13. And we're going to do
- 40:38this by starting uh with the biggest
- 40:41power of two that is that can uh
- 40:43contribute to our sum. So uh I'll go
- 40:46ahead and and write this table out over
- 40:48here. We know 2 to the^ of 0 is one. 2
- 40:52to the^ of one is two. Then 2^2 is 4. 2
- 40:57cubed is 8. 2 to the 4 is 16. 2 5th is
- 41:0232. And I'll do one more. 2 6 is equal
- 41:06to 64.
- 41:08And what we want to do is just start
- 41:11with the biggest uh x such that 2 to the
- 41:14x is less than our target value of 13.
- 41:17And that's going to happen uh right
- 41:20here. 2 ^ of 3 is 8 which is the largest
- 41:23value uh that is less than or equal to
- 41:27our target value. So we know that uh 2
- 41:30cubed is going to be in this expression
- 41:32and then when we have uh we kind of have
- 41:36um 13 on this side and we have eight on
- 41:40this side and so that means we need to
- 41:41get five with some remaining
- 41:43combinations of entries on this list. So
- 41:47we'll do the same process for five. And
- 41:49if we look at this list, uh we know that
- 41:52one is less than five, 2 is less than
- 41:54five, four is less than five, 8 is not
- 41:56less than five. So this two 2^2 is the
- 42:01biggest power of two, which is less than
- 42:04or equal to our remainder, which is
- 42:05five. Our remaining sum, should I say.
- 42:08So then I'll add our two squared in. And
- 42:10now we have a four. And so we know that
- 42:1313, we have 13 on this left side and we
- 42:15need to get 13 on the right hand side or
- 42:17else they're not equal. And we have 12
- 42:19on the right hand side. So we just need
- 42:20to get one more. And that's easy enough
- 42:23because we know that 2 to the^ of 0 is
- 42:25one. So I'll just add that in. And now
- 42:29we've uh done the exact task that we we
- 42:32we said was the difficult part, which is
- 42:34expressing our target number of 13 as a
- 42:37sum of various powers of two. So now
- 42:40let's go ahead and uh I should have
- 42:42demarcated this with a base 10. So you
- 42:44know I'm working with the decimal
- 42:45number. Let's go ahead and and bring
- 42:47this out to the expanded form where we
- 42:48add in the ones and zeros and the
- 42:50missing powers of two. So we would know
- 42:53we have 1 * 2 ^ 3 + 1 * 2 ^ of 2. We
- 42:58don't have any term with 2 ^ of 1. So we
- 43:01multiply it by zero. So it doesn't
- 43:02actually add anything. And then lastly
- 43:04we do have 2 to the^ of zero. So we will
- 43:06put a one there. And from there, it's
- 43:09pretty easy. We just read left to right
- 43:11what the coefficients are. And we have
- 43:14uh our binary equivalent. So 13, the
- 43:18decimal version of 13, the number that
- 43:19you and I know is 13 is equal to 1101 in
- 43:22binary. And you can expand this out,
- 43:25which is kind of what we have right here
- 43:27to prove that in fact uh I am not lying
- 43:29to you. It is 13. So let's try one more
- 43:33example of that just because I think
- 43:34it's a little complicated. Um,
- 43:38let's go ahead and do uh let's say 22. I
- 43:43just picked it off the top of my head.
- 43:44Hopefully it works out to be somewhat
- 43:46pretty. Um, so we have to find the uh
- 43:50the sums of powers of two again. And I'm
- 43:53going to go a little bit faster this
- 43:54time. So I'm just going to look at our
- 43:55list and I can see that 16 is the
- 43:58biggest value here that is is less than
- 44:00or equal to 22. So I know we have a two
- 44:02to the four here and let's keep things
- 44:04easy. So, I have 22 = 16 + uh we know
- 44:09we're going to need something else cuz
- 44:10the left hand side does not equal the
- 44:12right hand side. And 22 - 16 is 6. So,
- 44:16we're trying to get a six now. Um, and
- 44:19four is the next candidate here in terms
- 44:21of largest power of two that doesn't
- 44:23exceed our target of six. So, I'll add a
- 44:26two squared into our sum and that's
- 44:28going to be equal to four. And now we
- 44:31have 22 on the left hand side and 20 on
- 44:33the right hand side. So all we need is
- 44:35to get two uh to our expression. And
- 44:38that's easy. We know 2 to the^ of 1 is
- 44:40just two. And now we know that the 22 is
- 44:44equal to 22. So we've we've con we can
- 44:46convince ourselves that this uh
- 44:48left-hand expression here is equal to
- 44:51the right hand side of the expression.
- 44:53And so then what we can do is we can go
- 44:55ahead and write this out in the expanded
- 44:56form which you should be comfortable
- 44:58with now hopefully or it should at least
- 45:00be becoming apparent to you. And that's
- 45:02equal to 1 * 2 ^ 4. There's no 2 3. So
- 45:06we just write a zero as the coefficient
- 45:08because it multiplies away. Uh and
- 45:10that's because anything multiplied by
- 45:120ero is just zero. So this this term we
- 45:14just added contributes nothing to our
- 45:16sum. And then we have a 2 ^2. So we'll
- 45:19add the 2^2 in. And we have a 2 to the^
- 45:22of 1. And we do not have a 2 to the^ of
- 45:240. But we need to go all the way down
- 45:26from the largest power of two, which is
- 45:28four, all the way down to zero. So we
- 45:31stop like this. And then we can we can
- 45:35take these coefficients and just read
- 45:36them left to right. So that's 1 0 1 1 0.
- 45:41And that means that 22 in decimal is
- 45:44equal to the binary number 1 0 1 1 0.
- 45:49Cool.
- 45:50So, you've now uh gotten a pretty high
- 45:55level but also complete understanding of
- 45:57what binary is. I've shown you how to
- 46:01take a binary number, convert it to
- 46:03decimal so you can make sense of it and
- 46:06also how to take a decimal number and
- 46:07convert it to binary. And there is one
- 46:10final thing that we will want to do and
- 46:13be able to understand about binary
- 46:14numbers and that is how do we add them?
- 46:17And I talked a little bit about this
- 46:19earlier when we we talked about decimal,
- 46:21but let's go ahead and and recall our
- 46:23decimal example. Let's say I have 74 +
- 46:2839.
- 46:30Well, we keep we start at the rightmost
- 46:33digit position and we keep adding the
- 46:37values in the corresponding digit
- 46:39position. So, we'd add this 49 together
- 46:41and we'd write the sum of them below.
- 46:44So, let me actually pick a better
- 46:45example. Uh let's do uh 782
- 46:52plus um 531.
- 46:57So in our example, we'd start with this
- 46:58rightmost digit position. And we just
- 47:00know 2+ 1 is 3. So we write it down
- 47:03here. And we move on to the next digit
- 47:04position, which is 8 + 3. And 8 + 3 is
- 47:0811. Which you should remember this means
- 47:10we have carryover. So we put the
- 47:12remainder, which is 1, down here. And
- 47:16then we carry over a one up here. And
- 47:18then now when we get to the next digit
- 47:20position, we add 7 + 5 which is 12. But
- 47:23we also have to factor in this carryover
- 47:25which makes it 13. And that's exactly
- 47:28what we do. So for decimal, what we did
- 47:32is we started at the rightmost digit
- 47:33position and for each digit position, we
- 47:37added the corresponding numbers for a
- 47:39and b. If I'm letting this be A and this
- 47:41be B, our two operands, and I'm going
- 47:43from right to left until we've added all
- 47:45of the digit positions together, and you
- 47:47have your sum. And it turns out binary
- 47:50is going to be
- 47:52exactly identical to this. So, um let's
- 47:56see, we have our 22 and we also learned
- 48:00that uh let's take 22 and add uh another
- 48:05random number to it and see what the
- 48:07result is. So, I'm going to take 22,
- 48:08which we know is 1 0 1 1 0. And let me
- 48:12pick another number. Uh, so we don't
- 48:14have to reconvince ourselves that this
- 48:15is true. Um, and I'm going to come all
- 48:18the way back up here. And we said that,
- 48:22uh, 1 0 0 1 is equal to 9. So, let's do
- 48:28this. 1 0 0 1 is equal to 9. So,
- 48:32intuitively, we're adding 22 + 9. And
- 48:35these are both the decimal numbers we're
- 48:36so comfortable with. We know that's
- 48:38equal to 31. Uh and you know, maybe you
- 48:41have to to verify that yourself, but you
- 48:43can use your calculator here. Um so
- 48:45we're going to start right to left. And
- 48:48before I start this, you might have a
- 48:49quick question. And that's uh the two
- 48:52operands we have, this a and b, this 22
- 48:55and 9, do not have the same number of
- 48:57digit positions. So what do we do here?
- 49:01And there's something beautiful you
- 49:03learn that carries over and is just as
- 49:05true now. So let's go back to our
- 49:06decimal word for our decimal world for a
- 49:08second. And if I gave you the number 762
- 49:12arbitrarily chosen, then you know that
- 49:16this is equal to the same number as
- 49:180762,
- 49:20which is equal to the same number as
- 49:2100762.
- 49:23And more generally, uh any amount of
- 49:26zeros before our number are equal to the
- 49:28original number. And that's because we
- 49:30just ignore ignore any leading zeros.
- 49:34And why is this uh why can we do this if
- 49:37that's not clear? Um and that's because
- 49:40if we expand this 762 in our exponent
- 49:43way, we know we have 7 * 10 2 power + 6
- 49:47* 10 1st power + 2 * 10 to the 0 power.
- 49:52And if we add any number of twos, all
- 49:55we're doing is adding 0 * 10 to some
- 49:58increasing power. And we already
- 50:01discussed why 0 * any number is equal to
- 50:03zero. So this 0 * 10 the cubed is just
- 50:07going to drop out. And if we had the
- 50:08same thing again where we had a 0 * 10
- 50:104, that's just going to drop out. So any
- 50:13amount of leading zeros actually has no
- 50:16impact on the total value of our number.
- 50:19And so what I'm trying to get at and
- 50:20took a long way of explaining is that
- 50:22you're able to add number you're able to
- 50:24add zeros to the start of a number
- 50:25without changing its value. So what I'm
- 50:28going to say in binary is that if we
- 50:30have this number in binary, it's going
- 50:32to be the equivalent of this number in
- 50:35binary where we add one one or one zero.
- 50:38Or we could add any number of zeros
- 50:41and it's going to be the equivalent
- 50:43value in binary. So, I'm just going to
- 50:45go ahead and take that logic and
- 50:48make our two operants in this addition
- 50:50problem uh have the same number of digit
- 50:55positions. Just like that, I added a
- 50:58zero to the front of our number, but did
- 51:00that does not change the uh numerical
- 51:03interpretation of that value.
- 51:06So,
- 51:10going to take a sip of water here. Let's
- 51:12go ahead and add these two numbers
- 51:13together then. So we have a 0 and a 1,
- 51:18which 0 + 1 is 1. And then we have 1
- 51:20plus 0, which is 1. 1 + 0, which is 1. 1
- 51:24+ 0, which is 1. And 1 plus 0, which is
- 51:271. Um, and this is not that interesting.
- 51:32Uh, we didn't actually see carryover, so
- 51:34I kind of picked a bad example in
- 51:35hindsight, but we'll do another. Don't
- 51:37worry. Um I am going to claim that this
- 51:39number in binary plus this number in
- 51:41binary equals this number in binary. Um
- 51:44and our if we did everything right, we
- 51:46should hope that this number is actually
- 51:48equal to 31. So let's go ahead and uh
- 51:50convince ourselves that that's the case.
- 51:52So uh we start with 2 ^ of 0 1 2 3 4. So
- 51:57we have 1 * 2 ^ 4 + 1 * 2 ^ of 3 + 1 * 2
- 52:04^ of 2 + 1 * 2 1st power + 1 * 2 to the
- 52:09zero power. And that's cuz we have one
- 52:10in all these digit positions which is
- 52:12just equal to 2 4 which is 16 + 8 + 4 +
- 52:192 + 1. And 16 + 8 is 24 + 4 is 28 + 2 is
- 52:2630 + 1 is 31. And uh sure enough this is
- 52:31the exact result we were expecting.
- 52:34Um but what if I wanted to give a more
- 52:36nuanced example uh one where we had
- 52:39carryover. Well um let's do exactly
- 52:42that. Let's go ahead and do 101
- 52:46plus one one. Um, and I will go ahead
- 52:50and spill this out for you that this is
- 52:54uh five
- 52:56plus
- 52:597. Um, and we would hope that the result
- 53:02is then 12. And it'd be a good exercise
- 53:05for you probably to pause this video and
- 53:07convince yourself that those two numbers
- 53:09are uh five and seven. But uh we we need
- 53:13not do that for the sake of time. So,
- 53:15uh, we add this 1 + 1 and we may be
- 53:18convinced to write a two down here cuz,
- 53:20you know, there's no, it doesn't sum the
- 53:22more than 10. We don't carry over. But
- 53:24remember, in in binary, we only have
- 53:26zeros and ones to work with. So, versus
- 53:29decimal where we carry over when we're
- 53:31going from 9 back to to zero to 10. Uh,
- 53:35in binary, we carry over uh when we're
- 53:38going from one to two, i.e. we roll it
- 53:40back to a zero. So, we put this
- 53:42remainder down here. um we put a zero
- 53:45down below and then and then carry a one
- 53:48over and now we have 1 plus zero which
- 53:51is one but we have another one that we
- 53:52have to add the carryover and we're at
- 53:54two and we have the same issue as
- 53:56before. So we put the the carryover we
- 53:59put a zero below and then carry over
- 54:00once again. Um
- 54:03>> and now we have 1 plus 1 + 1 which is
- 54:07three. And we're going to go ahead and
- 54:10it's it's interesting. We we put the
- 54:12remainder uh when we modulo by two. So 3
- 54:17/ 2, the remainder is just then a one
- 54:21and then we carry over a one here. And
- 54:25uh this is our final result. And uh this
- 54:28is actually equal to the bi to the uh
- 54:30number 12. You can verify this yourself
- 54:32for it to be true. So basically when
- 54:35we're adding binary numbers, if we have
- 54:37a zero and a one in a position, it
- 54:40becomes zero. If we have a one and a
- 54:42zero in a position, sorry, I misspoke.
- 54:44If we have a zero and a one, it's a one.
- 54:46A one and a zero, it's a one. A zero and
- 54:49a zero sums to a zero. And then if you
- 54:52have a one and a one, we know this is
- 54:54binary two. And so that means we put a
- 54:57zero over here because the two divided
- 54:59by two, there's no remainder. And so we
- 55:01just carry over a one. And then the uh
- 55:04interesting case that we can't
- 55:05generalize from the remainder of these
- 55:06is if we have a one and a one and a one
- 55:08and that means we have three and we know
- 55:10that the binary representation of three
- 55:12is one one but what we do uh to get that
- 55:15if you don't understand is uh we have
- 55:18the three we take the remainder when you
- 55:20divide it by two 3id two has a remainder
- 55:22of one so we put the one below and then
- 55:24we uh carry over the extra one and uh
- 55:27these are kind of the four patterns you
- 55:30need to understand um when you're adding
- 55:33binary numbers.
- 55:35Awesome. Um and this is now uh has
- 55:41become clear how you can take binary
- 55:43numbers and convert between decimal
- 55:47either binary to decimal or decimal to
- 55:49binary and how you can add binary
- 55:52numbers together. Okay. So now you have
- 55:55uh learned all but one of the
- 55:58fundamental tricks of binary. So, we
- 56:00learn how to go from decimal to binary.
- 56:04Then we learn how to go from binary to
- 56:06decimal.
- 56:08And then we learn how to add binary.
- 56:13But we have yet to learn how to subtract
- 56:15binary.
- 56:19And that is the last thing we need to do
- 56:22before we have mastered binary.
- 56:24So what we would like to understand is
- 56:29how can we subtract two numbers in
- 56:30binary and it does follow a very similar
- 56:34process to the subtraction that we know.
- 56:36But it turns out there's a better way to
- 56:37do it. But before we can even look at
- 56:39subtraction, you may have another
- 56:41question that you wondered at some
- 56:42point. And that's how do we represent
- 56:44negative numbers?
- 56:46And there is a multitude of ways for us
- 56:50to represent negative numbers, but the
- 56:52one we're going to go with is a very
- 56:53popular one called TW's complement.
- 57:02[snorts] And what this is is a very
- 57:05simple rule where all you do is
- 57:09interpret the leftmost digit in your
- 57:12binary number to have
- 57:16a negative waiting. Now, this is
- 57:18confusing and it's going to require some
- 57:20digestion,
- 57:22but what we need to agree on now uh is
- 57:25how many digits each of our binary
- 57:27numbers are going to have. So, in
- 57:29decimal we have uh say the number 7 or
- 57:32it could be 656
- 57:34or 10,432
- 57:37and this has one digit, this has three
- 57:40digits and this has five digits. And we
- 57:42also saw some binary examples. uh we had
- 57:451 one which we saw was three and that's
- 57:48two digits and we had something more
- 57:50complicated uh where we could have like
- 57:52a 1 0 1 0 1 and that's going to be five
- 57:54digits. Um so binary and decimal have
- 57:57this property in common where you could
- 57:59represent a number and it could take any
- 58:02number of digits to represent that
- 58:04number. Um for two's complement it gets
- 58:08a little tricky with this variable
- 58:09notation. So, we actually want to agree
- 58:12on a fixed width for every number. And
- 58:16this may seem like a restriction, and it
- 58:18is. Um, computers uh aren't able just to
- 58:21arbitrarily represent any digit of any
- 58:24length. Um, and this is one of the
- 58:26design choices that will become more
- 58:27apparent why that's the case as we
- 58:29design our computer. But for now uh what
- 58:32I would like to do is let's just make
- 58:34this assumption or write this on the
- 58:36screen that every number in binary. So
- 58:40every binary number
- 58:46uh shall use
- 58:50four digits.
- 58:53So if our number that we're trying to
- 58:55represent in binary is less than four
- 58:57digits then we just pad it with zeros.
- 58:59Okay, that's easy. Uh, but what if we
- 59:01have a number that we want to represent
- 59:03that's more than five digits? We saw
- 59:04some examples earlier. Sorry, more than
- 59:06four digits. Um, we saw some examples of
- 59:08these numbers earlier and we're actually
- 59:10just going to say our computer is unable
- 59:12to represent them. We have a upper bound
- 59:15uh on the range of values we can
- 59:18represent. Um, and that's true. If if in
- 59:21decimal I said you can only use three
- 59:22digits. um then the largest number you
- 59:26could represent is 999 and the smallest
- 59:29you could represent is zero and that
- 59:32means there's actually 1,000 distinct
- 59:35values you can represent in this range.
- 59:37Um,
- 59:39and we're going to make the same
- 59:41restriction on binary. And I'm going to
- 59:43start this off with four. Uh, just so we
- 59:46can learn how to do this choose
- 59:48complement. And it turns out in our
- 59:50computer, uh, we're going to use eight.
- 59:53In our computer, we're going to restrict
- 59:54every number in binary that we represent
- 59:57to be exactly eight digits. And this is
- 59:59just one of many design choices that a
- 1:00:02uh, implementer of a computer has at
- 1:00:04their liberty. So, more modern
- 1:00:06computers, you may have heard of 32bit
- 1:00:08or 64-bit computers. Um, those are two
- 1:00:11very popular representations. Uh, and
- 1:00:14that is kind of the same rule. If you've
- 1:00:16heard those numbers before, what that
- 1:00:17means is internally that computer is you
- 1:00:21can say representing every number is
- 1:00:23exactly either 32 or 64 bits. Um, you
- 1:00:28may be wondering, hey, this is kind of a
- 1:00:30a pretty tight restriction. Like with
- 1:00:31four binary digits, we can't represent
- 1:00:34that many numbers. Um, and it's true.
- 1:00:36With 32 or 64, however, you are able to
- 1:00:39represent very large numbers and numbers
- 1:00:43larger than most people need to
- 1:00:45represent for computational purposes.
- 1:00:47And there are actually uh techniques
- 1:00:49that we can use to get around this to
- 1:00:50represent even larger numbers. Um, but
- 1:00:53those are uh implemented at a higher
- 1:00:55level. So I'm not going to say that each
- 1:00:59binary number shall use four digits. Um
- 1:01:02so uh we can't represent the number in
- 1:01:05our scheme 1 011 cuz that's five digits.
- 1:01:08Um cool. So I uh said uh we have this
- 1:01:14number one 011 and we know this is equal
- 1:01:18to let's just I picked this number out
- 1:01:19of nowhere. It's a four-digit binary
- 1:01:21number. We can expand this out as 1 * 2
- 1:01:25^ of 3 + 0 * 2 ^ of 2 + 1 * 2 ^ of 1 + 1
- 1:01:35plus sorry 1 * 2 ^ of 0 and what 2's
- 1:01:40complement says is we take the most
- 1:01:43significant digit position i.e. the left
- 1:01:45one and its weight is multiplied by
- 1:01:48negative one. So now instead of this
- 1:01:50being a positive 2 cubed, instead of
- 1:01:53this digit having weight 8, it's
- 1:01:55actually going to have weightg.
- 1:01:58So what this means is we have uh this -1
- 1:02:03* whatever is inside our representation
- 1:02:06of that digit position. Um + 0 * 2^ 2 +
- 1:02:111 * 2 ^ of 1 + 1 * 2 ^ of 0. And so that
- 1:02:16means that we have8
- 1:02:18+ 0 + 2 + 1. And that means we have -8 +
- 1:02:272 + 1. Sorry, I don't know why I wrote a
- 1:02:29six. And that's going to be equal to -5.
- 1:02:33Um, and this is should be a little bit
- 1:02:35confusing because you're you should be
- 1:02:36wondering, hey, why isn't this equal to
- 1:02:3811? And why did we choose it to be like
- 1:02:41this? Um so those are two loaded
- 1:02:45questions. So I want to make sure
- 1:02:47understand first is how we can interpret
- 1:02:49numbers in two's complement. Um and that
- 1:02:52is that this uh most significant digit
- 1:02:55position is going to have weight
- 1:02:56negative uh negative value. And this
- 1:03:01actually means that uh for our
- 1:03:02four-digit values, whenever we have a
- 1:03:05one in this most significant digit
- 1:03:06position, the leftmost one, our number
- 1:03:08is going to be negative. Um cuz this has
- 1:03:11the most weight and uh these all have
- 1:03:14less weight than it. So as long as this
- 1:03:16one's this leftmost digits a one, that
- 1:03:18means our number is negative. Um and
- 1:03:21then similarly if that's a zero then we
- 1:03:24have the original logic before uh where
- 1:03:26we're adding sums of weights of twos
- 1:03:29that are multiplied by either one or
- 1:03:30zero and so that means the number must
- 1:03:32be positive. Um
- 1:03:37so let's do one more example. Uh let's
- 1:03:40say I had one one one. So we have
- 1:03:47- 1 for this leftmost digit position
- 1:03:49time 2 ^ of 3 and then we have + 2^2 + 2
- 1:03:55the 1 + 2 0 and so that is -8 + 4 + 2 +
- 1:04:021 and that's going to be equal to uh -1
- 1:04:07if we sum these all up. And so this is
- 1:04:09interesting because you know in in what
- 1:04:11we learned about less than an hour ago
- 1:04:13we had uh this would be equal to uh 8 +
- 1:04:174 which is 12 + 2 which is 14 + 1 which
- 1:04:19is 15. Uh this should be 15 but now it's
- 1:04:21negative 1. And that's a little bit
- 1:04:23confusing. Um but this is actually how
- 1:04:26we're going to build our computer. So
- 1:04:28you should make sure this is clear to
- 1:04:30you. This isn't something I would
- 1:04:31recommend skipping over. uh our computer
- 1:04:34is going to use two's complement which
- 1:04:36is the exact binary we just learned with
- 1:04:38this one caveat that
- 1:04:42uh any weighted value i.e. The leftmost
- 1:04:46digit position has weight negative and
- 1:04:50this lets us represent negative numbers.
- 1:04:52Uh we just saw how to represent negative
- 1:04:54one. Now so what I'd like to show next
- 1:04:57uh well I will tell you that addition
- 1:05:01works out the exact same. So let's say I
- 1:05:04had -1 and I want to add -2. So uh if I
- 1:05:12wanted to or let's say we have uh -5 and
- 1:05:16negative 1 and we want to add those
- 1:05:17together then we have -5 + -1 which is
- 1:05:21equal to -6 and we know these binary
- 1:05:24representations are 1 0 1 1 and then 1
- 1:05:28one1. So we can do the same arithmetic
- 1:05:31as before. So 1 + 1 we put a zero below
- 1:05:34and carry a one over here. Then 11 one
- 1:05:36one we have a one below and a one
- 1:05:39carries over. And then one 0 one we have
- 1:05:41a zero below and a one carries over. And
- 1:05:46uh then we have 111 which is you know
- 1:05:48just three 1. Um and we've kind of made
- 1:05:52a interesting remark. Uh let's go ahead
- 1:05:55and ignore
- 1:05:59this leftmost digit position because we
- 1:06:00said we're only working with four bit
- 1:06:02values now. Fourdigit values. And let's
- 1:06:04figure out what 1 0 1 0 in two's
- 1:06:07complement binary equals. And that's
- 1:06:09going to be equal -2 ^ 3 plus we skip 2
- 1:06:15^ of two. We do have 2 the^ of 1 and we
- 1:06:18skip 2 to the^ of 0. And that's going to
- 1:06:20be equal to8 + 2 which is just equal to
- 1:06:23-6. And so that's that's that's
- 1:06:26beautiful. We had a -5 here ag -1. We
- 1:06:30added them together and we still got the
- 1:06:32-6.
- 1:06:34This does mean however that there are uh
- 1:06:38some binary values that fit in four
- 1:06:42digits but this if we add them together
- 1:06:44it can't actually fit in four digits. So
- 1:06:47let's let's let's look at an example of
- 1:06:48that. Let's say I have the binary number
- 1:06:51011 1 and I will tell you that this is 1
- 1:06:54+ 2 + 4 which is 7. So we're doing 7 + 7
- 1:06:58and we would expect 14 to come out. So
- 1:07:01let's do the arithmetic. 11 1 is zero.
- 1:07:0411 one is one with a carryover. 11 one
- 1:07:07is one with a carryover. And then 1 0 0
- 1:07:10is just one.
- 1:07:12Um and this should equal 14. But if we
- 1:07:16actually expand this out, uh we well we
- 1:07:19already know there's some danger because
- 1:07:20this leftmost bit is this leftmost digit
- 1:07:23is a one. Which means as I said earlier
- 1:07:26that the number is actually negative. We
- 1:07:28know this can't be the case because 14's
- 1:07:29positive. But let's go ahead and and
- 1:07:31expand it out. Uh we have -2 cubed + 2^
- 1:07:362 + 2 1 and that's -8 + 4 + 2
- 1:07:44and that's going to be equal to -2 which
- 1:07:47is not equal to 14.
- 1:07:49So I'm going to take a sip of water
- 1:07:50here.
- 1:07:57This is interesting.
- 1:08:01Because we have this two's complement
- 1:08:03rule, there are actually ranges of the
- 1:08:07values we can represent in terms of four
- 1:08:11binary digits
- 1:08:14and it's just a limitation and it's
- 1:08:17something we're have to be careful of
- 1:08:18when we're designing our computer. Our
- 1:08:20computer which I said will operate on
- 1:08:228bit values, eightdigit binary values.
- 1:08:26If we add two numbers that individually
- 1:08:30may be able to be represented in eight
- 1:08:32digits, uh it's possible their sums not
- 1:08:34able to be represented in eight digits.
- 1:08:36And we have this issue and this is
- 1:08:37called overflowing computers. You may
- 1:08:40have heard of it before. Um but it it
- 1:08:43means that we can't represent a number
- 1:08:45in the number of digit positions that we
- 1:08:47have. And that's just something to be
- 1:08:49aware of. um I will try ignore all of
- 1:08:52those cases and and hide things away so
- 1:08:54that we we don't have to worry about it
- 1:08:56because I don't want to get too
- 1:08:57technical here. But uh I just wanted to
- 1:09:01make it something that we aware of. And
- 1:09:03then there's one other really
- 1:09:04interesting uh property of two's
- 1:09:07complement and that is to negate a
- 1:09:10number.
- 1:09:14So uh in in in decimal it's easy. If we
- 1:09:17have 10 and we want to negate it, we
- 1:09:18just write -10. And if we have -6 and
- 1:09:21and we want to negate it, we just write
- 1:09:23six. And it's easy because we just have
- 1:09:25this negative sign that we can just
- 1:09:26throw in front of our number. And we are
- 1:09:29learning that you can't do the same in
- 1:09:31binary. There is no just negative sign
- 1:09:34we can throw on cuz we don't have a
- 1:09:35negative sign. All we have is zeros and
- 1:09:37ones to work with. And I mean that
- 1:09:39literally.
- 1:09:40So there is a really cool property. You
- 1:09:43do not need to understand why this
- 1:09:44works, but it turns out to negate a
- 1:09:47number, you invert you invert
- 1:09:52all the digit positions
- 1:09:59and then you add one to the result.
- 1:10:05So, uh let's come up here. Um we had
- 1:10:09seven which we know is is actually let's
- 1:10:11pick let's pick this example 1 0 1 0 we
- 1:10:13know is -6. So -6 in in decimal is 1 0 1
- 1:10:180 uh in this two's complement. And uh we
- 1:10:21want to figure out what the negated
- 1:10:23value is we know it's six but how do we
- 1:10:25get that now? And what I'm saying is
- 1:10:27step one is you invert all the digit
- 1:10:29positions. So your ones become zeros and
- 1:10:32your zeros become ones. So we end up
- 1:10:34with one becomes 0, a 0 becomes a 1, a
- 1:10:36one becomes a zero, and a zero becomes a
- 1:10:39one and then we add one to the result.
- 1:10:42So we have 0 1 0 1 and we just add one.
- 1:10:46And this is the binary addition we
- 1:10:48already learned how to do. So we know a
- 1:10:49one and a one is a zero with a
- 1:10:51carryover. And then we have 1 0 0 which
- 1:10:53is 1, 1 0 which is 1 and 0 0 which is 0.
- 1:10:57And this should be the negation of this.
- 1:11:01And we know this is equal to -6. So this
- 1:11:03should equal six. And let's go ahead and
- 1:11:05see if that's true. We have 2 to the^ of
- 1:11:08two, 2 to the^ of 1, and then nothing
- 1:11:10for 2 to the^ of 0, uh, which is 4 + 2,
- 1:11:13which is six. And so that's that's
- 1:11:16really cool. Um, so I showed you how to
- 1:11:19negate a number in two's complement. But
- 1:11:21but why did I do that? And that's
- 1:11:24because if I scrolled back up, uh, I
- 1:11:26said we learned how to do addition in
- 1:11:27binary, but we did not learn how to do
- 1:11:29subtraction. How can I do a? We know how
- 1:11:32to do a plus b. And how do I do a minus
- 1:11:35b? Interesting question. And uh it turns
- 1:11:38out you already know how to do it based
- 1:11:40on what I just showed you. Because a
- 1:11:42minus b is equal to a + b.
- 1:11:48And I know how to I showed you how to
- 1:11:50negate a number. I showed you how to
- 1:11:52take some b and make it negative b. And
- 1:11:54then I already showed you how to add two
- 1:11:56numbers together. So, it turns out you
- 1:11:58actually do know how to subtract. Um,
- 1:12:01and this is pretty powerful. So, let's
- 1:12:03say I wanted to do 6 minus 2. Well, we
- 1:12:06know that six in decimal is equal to 0 1
- 1:12:101 0 in our two's complent binary and two
- 1:12:15um in in in
- 1:12:18uh decimal I will go ahead and just tell
- 1:12:21you is this number right here. So, I
- 1:12:24want to do 6 minus 2. And to do that,
- 1:12:26I'm going to do 6 + -2. So the first we
- 1:12:29need to do is is is what is -2 uh in in
- 1:12:33binary. And so what we do is we take our
- 1:12:35representation of two. The first thing
- 1:12:37we do, I'm going to scroll up here. We
- 1:12:39invert all the digit positions. And then
- 1:12:41we add one. So 0 0 1 0 becomes 1 1 0 1.
- 1:12:45And then we add one to it. And we are
- 1:12:49left with
- 1:12:511 1 0. And you can convince yourself
- 1:12:53this is true, but I'm not going to for
- 1:12:55the sake of time. And then what we want
- 1:12:57to do is 6 to get 6 - 2. Uh, I'll write
- 1:13:02this out. We want 6 - 2. Uh, we're going
- 1:13:04to do 6 + -2. And we now have 6. And we
- 1:13:08now have -2. And we know how to add. So
- 1:13:11we'll just add them. So we'll do 0 1 1 0
- 1:13:14+ 1 1 0. And let's go ahead and add. And
- 1:13:18so that's zero here, a zero here, a one
- 1:13:22with a carryover, and a zero with a
- 1:13:24carryover. But we said we were working
- 1:13:26with fourdigit positions. We just look
- 1:13:28at the four that we have, and we would
- 1:13:31hope that this number is equal to four.
- 1:13:32And it turns out this is this is it
- 1:13:34because it is uh we have 2 the^ of 0, 2
- 1:13:37the^ of 1, and 2 the^ of 2. We just have
- 1:13:39a 2 to the^ of two, which is 2 * 2,
- 1:13:42which you should know is four by now. So
- 1:13:46you uh and I know we just went a little
- 1:13:48quickly and I only gave one example. The
- 1:13:51website I will link uh I will link a
- 1:13:53website below that I've written and it
- 1:13:55has more examples and is written with a
- 1:13:58little bit more detail. So if any of
- 1:13:59this is confusing to you uh you can just
- 1:14:02go to that website and get a more
- 1:14:04complete understanding and some examples
- 1:14:06may help work out the gaps. So now uh up
- 1:14:10to this point let's recap what we've
- 1:14:11learned. We have learned uh how to well
- 1:14:15first off we recaped decimal but I'm not
- 1:14:18going to include that because
- 1:14:19intuitively you already knew that we
- 1:14:21learned how to go from decimal to
- 1:14:23binary.
- 1:14:27We learned how to go from binary to
- 1:14:29decimal and we actually did that first.
- 1:14:34We learned how to negate. We learned
- 1:14:37two's complement. So how do we represent
- 1:14:39negative numbers?
- 1:14:42We then learned how to add binary
- 1:14:46numbers.
- 1:14:49And lastly, we learned how a a little
- 1:14:52trick that lets us subtract binary
- 1:14:54numbers.
- 1:14:59And this is all you need to know about
- 1:15:02how computers represent numbers. So even
- 1:15:05if you stop watching this video right
- 1:15:06now, you have walked away with a a very
- 1:15:09interesting uh lesson. And that is how
- 1:15:12do computers represent numbers? And you
- 1:15:15may not understand why it needs to be
- 1:15:17done like this yet because we haven't
- 1:15:18got any further. But at least you
- 1:15:20understand what's happening under the
- 1:15:21hood. And when you type in uh when
- 1:15:24you're typing in 5 + 7 to your
- 1:15:26calculator, it's not doing 5 + 7. It's
- 1:15:28doing uh 1 0 1 plus some other binary
- 1:15:32string. And it's pretty interesting. Um,
- 1:15:37so if you've made it this far, you have
- 1:15:39learned what in my subjective opinion I
- 1:15:42would say is one of the two most
- 1:15:44difficult components of this video. Uh,
- 1:15:46I think understanding this binary
- 1:15:48representation is very difficult and
- 1:15:51we're going to come back eventually and
- 1:15:52there's going to be one other really
- 1:15:54difficult concept uh, which is how we
- 1:15:56can store memory on computers. Um, and I
- 1:16:00think if you can power through both of
- 1:16:02those, then you will have a full
- 1:16:03understanding. And I think everything
- 1:16:05else in this video will be easier than
- 1:16:07those two topics. So, even though we're
- 1:16:09not halfway done with this video,
- 1:16:11metaphorically and in terms of
- 1:16:12difficulty, I would argue we are halfway
- 1:16:14through the difficulty.
- 1:16:16So, what we're going to do next is learn
- 1:16:20about something called a logic gate.
- 1:16:22And, uh, it's going to have nothing to
- 1:16:24do with what we just did. what I just
- 1:16:26did. I'm gonna ask that you mentally
- 1:16:28push aside and then we're immediately
- 1:16:30going to bring it back together. Uh and
- 1:16:32and and so I'm I've taught you binary.
- 1:16:35I'm now going to teach you something
- 1:16:36called logicates which are independent
- 1:16:38of binary. And then we're going to bring
- 1:16:40it together and see how these two topics
- 1:16:42relate.
- 1:16:44Okay? So I'm going to ask that you
- 1:16:46mentally put everything that we just did
- 1:16:48aside in your head. Ignore it all. and
- 1:16:52we're going to learn a new concept and
- 1:16:55it's going to seem a little bit familiar
- 1:16:58as it probably should and you'll see why
- 1:17:00they are familiar and similar in nature.
- 1:17:04But don't worry, uh, what we just
- 1:17:06learned is not going to be abandoned.
- 1:17:07Binary, I didn't put that in there just
- 1:17:09to torture you. I put that in because
- 1:17:11it's going to be a very real concept
- 1:17:13that is almost fundamental to the
- 1:17:15entirety of this video.
- 1:17:17and we're going to tie these things
- 1:17:19called logic gates back together with
- 1:17:21binary afterwards. So, let's go ahead
- 1:17:23and uh see what a logic gate is. And I
- 1:17:28actually think that you may find uh the
- 1:17:30content in this section pretty
- 1:17:32interesting. Not to say binary is
- 1:17:33uninteresting. I just think that the
- 1:17:35majority of people will find it a little
- 1:17:37bit tedious or boring the more specific
- 1:17:40you go into it. Let us start with the
- 1:17:44first logic gate which is called the AND
- 1:17:46gate
- 1:17:48and it looks like this.
- 1:17:52Uh I will zoom in and draw this a little
- 1:17:55bit better. So we will say we have a and
- 1:17:59b and then we will say the outputs y. So
- 1:18:02a logic gate takes in two inputs and
- 1:18:07puts out an output this and gate
- 1:18:09specifically. So what I will say is that
- 1:18:13the output y
- 1:18:16is a function of a and b. And please do
- 1:18:20not let this scare you if it's giving
- 1:18:22you uh PTSD to your high school algebra
- 1:18:25classes. It's not as difficult as it
- 1:18:28seems. And we're also going to add this
- 1:18:30rule that a is either a zero or a is
- 1:18:35equal to one. And we're going to do the
- 1:18:37same thing for b. B is going to be
- 1:18:39either a zero or it's going to be equal
- 1:18:41to one. And we're going to do the same
- 1:18:43thing for Y.
- 1:18:45Y will either be a zero or it will be a
- 1:18:48one. So our function here Y is a
- 1:18:54function. Y will be the output of this
- 1:18:56gate and its inputs to the gate are
- 1:18:59going to be A and B. So whatever A and B
- 1:19:02are will determine what Y is. and a and
- 1:19:06b can only be either zero or one. So
- 1:19:09there's not that many combinations. So
- 1:19:11there's two values that we have that are
- 1:19:14inputs to this function. And there's two
- 1:19:16different values that each of those
- 1:19:17inputs could have. So we're actually
- 1:19:19going to we could build out a table to
- 1:19:21represent each of the inputs and look at
- 1:19:23what the output's going to be. So I'm
- 1:19:26going to uh erase this
- 1:19:31and make this truth table. So we have a
- 1:19:35and b as our inputs and then I'll add
- 1:19:38this column for y which is the output.
- 1:19:40So uh our our four different possible
- 1:19:43cases are a and b are both zero. Maybe a
- 1:19:47is a one and b is a zero. Maybe a is a
- 1:19:50zero but b is a one. Or maybe they're
- 1:19:52both ones. And and this is uh this is
- 1:19:55all the possible input combinations
- 1:19:57there are. If you don't believe me,
- 1:19:59please try invent another one and I
- 1:20:02guarantee that you will not be able to
- 1:20:03do so.
- 1:20:06Now, I'm just going to tell you what the
- 1:20:08ANDgate does. Uh, you may have guessed,
- 1:20:11but it outputs a one if both of the
- 1:20:13inputs are one and otherwise it outputs
- 1:20:16a zero. So, it's an ANDgate because we
- 1:20:19say it outputs one if A and B are one.
- 1:20:23Otherwise, it's going to output a zero.
- 1:20:25So in our example here, when a and b are
- 1:20:27both ones, y is going to be equal to
- 1:20:29one. And in any other case, y is going
- 1:20:31to be equal to zero.
- 1:20:34And that's because the definition of an
- 1:20:36andgate is that it only outputs one if
- 1:20:39both of the inputs are one.
- 1:20:43Okay, congratulations. You've learned
- 1:20:45your first logic gate. We've learned
- 1:20:47that logic gates take in a a certain
- 1:20:50number of inputs, but they will always
- 1:20:52only output one number. I'll tell you
- 1:20:55that now. We're going to look at other
- 1:20:56logicates. Some may take in two inputs,
- 1:20:58some may only take in one input, but
- 1:20:59they're always only going to output one
- 1:21:01value. And that one value is going to
- 1:21:04always be determined strictly based the
- 1:21:06inputs. So us having an A set to one and
- 1:21:10B set to one means Y will always be set
- 1:21:13to one for an ANDgate. And this property
- 1:21:15is what we call determinism.
- 1:21:20And it's a scary sounding word, but to
- 1:21:22be deterministic, it means that the
- 1:21:24output y is is strictly dependent and
- 1:21:28can be determined based on the value of
- 1:21:30the inputs a and b. Um, and that's just
- 1:21:33a word that if you curiously read around
- 1:21:35online, you will probably come across.
- 1:21:37So, I thought it was worth mentioning.
- 1:21:39Let's go ahead and look at some more
- 1:21:40other logic gates that we have. We have
- 1:21:42the ANDgate. Now, let's go ahead and
- 1:21:44look at the ORgate.
- 1:21:49So the orgate looks like this.
- 1:21:54We have our two inputs still.
- 1:21:57We have a b and y. Uh and it looks
- 1:22:00different because it has this little
- 1:22:01curvature on the inside. Uh but this is
- 1:22:03a orgate. So let's do the same thing as
- 1:22:05before. Uh let's build this truth table
- 1:22:07out.
- 1:22:10And we have the same uh same conditions
- 1:22:13that our inputs and outputs are all
- 1:22:15binary. I.e. either either zeros or
- 1:22:17ones.
- 1:22:19So this table will be the exact same
- 1:22:21before up till now. And I will tell you
- 1:22:24that the orgate uh you should hopefully
- 1:22:26be able to guess the andgate outputs one
- 1:22:29if a if and a and b are both one i.e
- 1:22:33both of its inputs are one. The orgate
- 1:22:35is going to output a one as long as
- 1:22:37either of its inputs are one. So if a or
- 1:22:40b is a one then we're going to output a
- 1:22:42one. So uh this is going to happen not
- 1:22:45in our first case. Neither of the inputs
- 1:22:47are one. So we output nothing. We output
- 1:22:49a zero. In the remainder of the cases at
- 1:22:52least a or b one of them if not both is
- 1:22:56a one. So that's alga output a one.
- 1:23:00And it doesn't require there's nothing
- 1:23:02wrong with both of them being one. It
- 1:23:03just says as long as either of them is a
- 1:23:05one I will output a one. And that's what
- 1:23:08the orgate does.
- 1:23:10Now we're going to look at the exclusive
- 1:23:12orgate. And this is called XOR. Exor
- 1:23:17exclusive or. And it looks like our
- 1:23:19orgate, but it has this extra line.
- 1:23:28And this is going to be the exclusive
- 1:23:30ORgate. And what this one's going to do
- 1:23:32is it's going to output one as long as
- 1:23:35either A or B is a one. but is with the
- 1:23:39added condition that both of them can't
- 1:23:41be a one. So if A and B are both one,
- 1:23:44then it's going to output a zero. But if
- 1:23:46just one of them is a one, then it'll
- 1:23:47output a one.
- 1:23:49So let's draw this truth table out.
- 1:23:560 0 1 0 0 1. And it doesn't really
- 1:23:59matter for a truth table what order we
- 1:24:01put everything in as long as we have all
- 1:24:03the cases. So AB both zero there. It
- 1:24:07means there's no neither of them are
- 1:24:08zero. So we up a zero. Then a is one and
- 1:24:11b is zero. So uh either of them is one
- 1:24:14but not both of them. So it's a one. And
- 1:24:16the same can be said for the next case.
- 1:24:18But in this final case, a and b are both
- 1:24:22one. So we say that the output's going
- 1:24:24to be a zero cuz it has to be exclusive.
- 1:24:26Either one one of them can be a one but
- 1:24:28not both of them. And this is called the
- 1:24:31uh exclusive orgate. So in English this
- 1:24:33may translate to exactly one of a or b
- 1:24:37is equal to one.
- 1:24:40And what you're going to kind of see
- 1:24:41here uh and I've kind of intuitively
- 1:24:43hinted it but I'm going to now make it
- 1:24:44more explicit is that a lot of times we
- 1:24:46will interpret a zero to be false and a
- 1:24:50one to be truthful. Um so we can kind of
- 1:24:54give some of these values use these
- 1:24:56truth truth values if you could say. So
- 1:24:59if I looked at the output of some logic
- 1:25:01gate um then if it's a one the output of
- 1:25:04that gate is saying true. So the
- 1:25:06condition based on the inputs is being
- 1:25:09met. And if it's a zero it means the
- 1:25:10condition is not being met. So the
- 1:25:11output's false. Um and that's just just
- 1:25:14something worth putting out there. So
- 1:25:16we've seen the ANDgate, the OR gate, the
- 1:25:19exclusive orgate. Let's do a different
- 1:25:22type of gate and this is going to be
- 1:25:24called the inverter gate.
- 1:25:27And this is interesting because it only
- 1:25:30has one input. So I mentioned this
- 1:25:32earlier. I said logic gates have a
- 1:25:34variable number of inputs but always
- 1:25:37only have one output. And that's exactly
- 1:25:39what we have here. So our truth table uh
- 1:25:42this is the knockgate. And all the
- 1:25:44knockgate does is just invert its input.
- 1:25:47So if you throw in a zero, it's going to
- 1:25:48output a one. And if you throw in a one,
- 1:25:50it's going to output a zero. So let's go
- 1:25:53ahead and build a truth table for this.
- 1:25:56Well, this is easy. The A can either be
- 1:25:57zero or one. And then we just invert its
- 1:25:59value. So if we throw in a zero, we get
- 1:26:01out a one. And if we throw in a one, we
- 1:26:02get out a zero. And this is how the
- 1:26:04inverter gate works.
- 1:26:08So we've seen four gates and there's one
- 1:26:11other gate we should discuss and this
- 1:26:12gate is going to be a little bit
- 1:26:13interesting because it has a a pretty
- 1:26:15unique feature about it.
- 1:26:18And this is going to be called the NAND
- 1:26:20gate.
- 1:26:22So it is the output of the NAND of the
- 1:26:26and AND gate negated. So it means not
- 1:26:29and so as long as not A and B are both
- 1:26:33one, this is going to output a one. So
- 1:26:35it's literally going to be the opposite
- 1:26:37of our ANDgate. Our ANDgate only outputs
- 1:26:39one if A and B are both set to one. But
- 1:26:41our NANDgate is going to ensure it's
- 1:26:44going to output one. It's going to tell
- 1:26:46you if not A and B are both set to one.
- 1:26:50So, our NANDgate looks like our ANDgate,
- 1:26:53but it has this little circle
- 1:26:54afterwards, and it's going to take in
- 1:26:57our our same two familiar inputs. I'm
- 1:26:59also just arbitrarily calling these A
- 1:27:01and B. They can be called whatever. And
- 1:27:03in fact, when you see these logic,
- 1:27:04they're usually not labeled letters. I'm
- 1:27:06just trying to make it clear that we
- 1:27:07have our our inputs on the left and then
- 1:27:10our output on the right. Um, and that's
- 1:27:12what you should really capture here. So,
- 1:27:14let's build our truth table. We have A,
- 1:27:17B, and Y.
- 1:27:25And we are going to say this means not
- 1:27:28and so we will out output a one as long
- 1:27:30as the condition met. And the condition
- 1:27:32is that not both A and B are one. So
- 1:27:34that happens in our first three cases
- 1:27:36and not the last case. In the last case,
- 1:27:39A and B are both one. Um which means
- 1:27:43that A and B is true. But we want the
- 1:27:46negated version of that. we we we say
- 1:27:48not A and B. Uh so we output at zero.
- 1:27:52So there's this really interesting
- 1:27:54thing. I'm going to make two pretty
- 1:27:56shocking claims. So the first is we can
- 1:27:58build our entire computer out of these
- 1:28:01logic gates right here. The computer
- 1:28:04we're going to design is with one very
- 1:28:07minor exception is going to be built
- 1:28:09entirely out of logic gates. We are
- 1:28:12going to be able to build storage using
- 1:28:14logic gates. We're going to be able to
- 1:28:15add numbers with logic gates, subtract
- 1:28:17them, and do everything that a CPU can.
- 1:28:20It turns out your computer that you're
- 1:28:21watching this on is is generally
- 1:28:24speaking built out of just logic gates.
- 1:28:26The one exception uh for our computer is
- 1:28:29going to be this thing called the clock,
- 1:28:31which will just synchronize everything.
- 1:28:33Our clock is just going to alternate
- 1:28:35between 0 and one at a fixed pace. And
- 1:28:38every other component in our computer is
- 1:28:39going to look at that clock to know what
- 1:28:41time it is. Generally speaking,
- 1:28:44the clock's not going to be built with
- 1:28:45logic gates. And we're actually not
- 1:28:47going to study how the clock is built
- 1:28:48cuz it's going to be built out of
- 1:28:49electricity. But, uh, logic gates, uh,
- 1:28:53back to the claim, can can be used to
- 1:28:55build our entire computer. So, we're
- 1:28:57going to take these very, very simple
- 1:28:59logic gates and we can chain them
- 1:29:01together as in the output of one can
- 1:29:05become the input of another and we can
- 1:29:06build these very complicated circuits.
- 1:29:09And and the the goal of this video is to
- 1:29:12build a circuit that's complicated
- 1:29:13enough to to be an entire computer. And
- 1:29:16this sounds like a crazy ambitious goal,
- 1:29:18but it's it's really cool. And this was
- 1:29:20one of the most fascinating things for
- 1:29:22me when I learned this is that we can
- 1:29:24build an entire computer out of some
- 1:29:26logic gate, which seems pretty trivial.
- 1:29:29And I'm going to make another claim. I'm
- 1:29:32not going to back this one up, but it
- 1:29:33turns out that this nan gate right here,
- 1:29:36it's called the universal gate.
- 1:29:41And any of these other logicates can be
- 1:29:45built out of nan gates uh chained
- 1:29:47together. And we're going to see what
- 1:29:49chain together means shortly. But what
- 1:29:51that means, if you can take that to be
- 1:29:52the truth, is that you can actually
- 1:29:54build an entire computer just out of
- 1:29:57NAND gates, which is crazy. And that is
- 1:30:00uh to my understanding actually how most
- 1:30:02computers are implemented. You have just
- 1:30:03have a lot of nan gates.
- 1:30:06And how are we going to build a computer
- 1:30:08out of chains together? Uh well, I kind
- 1:30:10of mentioned this earlier when we were
- 1:30:11discussing binary. I said in computers,
- 1:30:14we either have electricity on a wire or
- 1:30:16we don't. If we have no electricity on a
- 1:30:19wire, we'll treat that as a zero. And if
- 1:30:21we do have electricity on that wire,
- 1:30:23we're going to treat that as a one. And
- 1:30:26these these these logicates can be built
- 1:30:29physically. We're not going to see how
- 1:30:31they're built physically because that
- 1:30:32also deals with electricity which I'm
- 1:30:35not well equipped to teach you about
- 1:30:36because I barely understand myself. But
- 1:30:39uh we can understand at at a level at a
- 1:30:42higher level that will just treat the
- 1:30:44presence of electricity as a one in the
- 1:30:45absence of it as a zero and build these
- 1:30:48these these uh logic gates together and
- 1:30:51chain them together in such a way that
- 1:30:53if we did have real electricity and a
- 1:30:54way of building these logic gates both
- 1:30:56of which we do uh it could it could run
- 1:30:59an entire computer and that's actually
- 1:31:02something I've done. I've built the
- 1:31:04computer that we're going to study uh
- 1:31:06with wires in the logic gates that you
- 1:31:08can buy online. And that's something I
- 1:31:10hope to demonstrate later on in this
- 1:31:12video. But let's get back to our goal
- 1:31:15here cuz I've I've made this crazy claim
- 1:31:17that we're going to build an entire
- 1:31:19computer out of Logicate. So I that's
- 1:31:21going to be what the next uh next big
- 1:31:24segment of this video is about. How do
- 1:31:26we actually go about doing this? Um, and
- 1:31:29to do that, I want to start by
- 1:31:30explaining how we can chain these logic
- 1:31:32gates together. So, let's explain how we
- 1:31:35could we could build a NANDgate by
- 1:31:37chaining two of the other logic gates we
- 1:31:39have together. So, uh, as a reminder,
- 1:31:42the NANDgate just takes whatever the
- 1:31:44output of the ANDgate is and inverts it.
- 1:31:47It negates it. So, if the ANDgate
- 1:31:49outputs a one, then we we output a zero.
- 1:31:52And if it if the ANDgate outputs a a
- 1:31:55zero, we should output a one.
- 1:31:57And uh if if I asked you which two gates
- 1:32:00we could combine um the answer would be
- 1:32:04we could combine an AND gate and a
- 1:32:07inverter gate together to build this
- 1:32:09circuit out. So let's go ahead and see
- 1:32:11uh what this does. I will spill the
- 1:32:13answer for you and then we will we will
- 1:32:15verify that things are true. So I'm
- 1:32:18going to take our A and B which are our
- 1:32:20inputs. I'm going to feed them into this
- 1:32:23and ANDgate. And then I'm going to feed
- 1:32:25the output of that and AND gate into a
- 1:32:29notgate. This gate that we saw down
- 1:32:31here. And then I'm going to let that be
- 1:32:33the output Y. And so I have this
- 1:32:36circuit. And this is this is pretty big.
- 1:32:37What we just did is we we took the
- 1:32:39output of one gate and fed it in as the
- 1:32:41input of another gate. And it's it's a
- 1:32:44small example, but we're we're going to
- 1:32:45see more complicated ones very quickly.
- 1:32:48So let's go ahead and convince ourselves
- 1:32:51that this is actually equivalent to our
- 1:32:54NAND gate from over here. And the way we
- 1:32:56can do that is we can build a truth
- 1:32:58table uh for what we have here. And what
- 1:33:00we have here is called a circuit. A
- 1:33:03circuit is what happens when you chain
- 1:33:05logic gates together. And by chaining
- 1:33:08logic gates together, we can provide we
- 1:33:10can build circuits that accomplish more
- 1:33:13interesting things. So these are these
- 1:33:16these these uh logic gates on their own
- 1:33:19don't do very much but by chaining them
- 1:33:21together we could actually have them do
- 1:33:23really interesting things. Uh and I mean
- 1:33:26the end goal is chaining them together
- 1:33:28in such a way that we build an entire
- 1:33:29computer. Uh and that is totally
- 1:33:31possible as I will try to convince you
- 1:33:34over the next few hours. So let's go
- 1:33:36ahead and build out our truth table. We
- 1:33:39have two inputs and one output.
- 1:33:42And let us see uh we know our our output
- 1:33:45cases are as follows. I'll change up the
- 1:33:49order here a little bit for the second
- 1:33:50and third rows. So when a and b are both
- 1:33:53zero, well we have a is zero here, a
- 1:33:56zero here. 0 and 0 is zero cuz not both
- 1:34:00of them are one. And then we invert it
- 1:34:02and uh produce a one. So we end up with
- 1:34:05a one as the output of our our circuit
- 1:34:07when the inputs are both zero and zero.
- 1:34:09And and let me change color here just so
- 1:34:11it's easier to follow. Then let's
- 1:34:12suppose we have zero and one. Then the
- 1:34:16endgate's still going to output a zero
- 1:34:18because not both the inputs are one. But
- 1:34:20when we invert it, it becomes a one. So
- 1:34:22uh this is a one here. And if I flip
- 1:34:25this uh if I say that B is going to if A
- 1:34:30is going to be sorry I did that
- 1:34:31backwards actually. Um, I showed you,
- 1:34:35let's see, I showed you 0 1. Oh, no, no,
- 1:34:37I did that correctly. Now I'm going to
- 1:34:39show you one zero. And we know the
- 1:34:40output of the endgate is going to be
- 1:34:42unaffected. It's still going to be a
- 1:34:43zero. But then when we invert it, it
- 1:34:44becomes a one. And lastly, uh, if we
- 1:34:48have a one and a one, then what happens
- 1:34:50is our AND gate outputs a one, but when
- 1:34:53we invert it, it becomes a zero. And so
- 1:34:55we we have this truth table right here.
- 1:34:58And
- 1:35:00I'm going to replace this with white now
- 1:35:02that we're done drawing.
- 1:35:08What we would expect is that if this
- 1:35:10circuit is equal to the nan gate, then
- 1:35:12the truth table should be identical. And
- 1:35:15if I scroll out, we can see that the
- 1:35:17truth tables are identical. Uh you can
- 1:35:19compare each of the four rows against
- 1:35:20each other. Um I know I've swapped the
- 1:35:22order of the middle two, which I
- 1:35:23shouldn't have in hindsight cuz it's a
- 1:35:25little confusing now. Uh, but I was
- 1:35:27trying to illustrate the point that the
- 1:35:28truth table doesn't matter what order
- 1:35:30the inputs are in as long as you cover
- 1:35:31all the possible inputs. Um, but in
- 1:35:35general, I've shown you how to build a
- 1:35:37circuit by chaining logic gates together
- 1:35:39and that you can verify that two
- 1:35:41circuits are equal by showing that their
- 1:35:45truth tables are identical for every
- 1:35:47pair of input combinations.
- 1:35:49So this function, this circuit is a
- 1:35:52function of A and B and it's going to
- 1:35:55equal Y. And so is our NANDgate. And it
- 1:35:58turns out they're actually they're the
- 1:36:00same function um because they always
- 1:36:02equal the same value. And so this is
- 1:36:05this is pretty interesting. And uh we
- 1:36:09could every time we we could avoid using
- 1:36:11the nan gate just by by drawing this.
- 1:36:13But it turns out that we use a nan gate
- 1:36:14enough where we we want to give it its
- 1:36:16own gate. um because it it kind of when
- 1:36:18we have these big circuits that chain a
- 1:36:20lot together, it it becomes a little bit
- 1:36:22more convenient to have uh simplified
- 1:36:25ways to represent things we use
- 1:36:27frequently. And we will see this later
- 1:36:29on. We'll design some interesting
- 1:36:30circuits and then we will just uh demark
- 1:36:33them as a new type of of of gate or
- 1:36:35maybe we'll say uh a triangle represents
- 1:36:38this circuit underneath the hood. Um but
- 1:36:40but don't think about that now. That's
- 1:36:42something that uh is more of a future
- 1:36:43concern. Let's try another circuit. So
- 1:36:46you've seen um a circuit now that has
- 1:36:49two inputs and
- 1:36:53one output. And so for logic gates, I I
- 1:36:56made a claim. I said a logic gate has uh
- 1:36:59at least one input
- 1:37:02and it always has exactly one output. A
- 1:37:06circuit has at least one input,
- 1:37:10but it may have multiple outputs. And
- 1:37:12we'll see this later um when we actually
- 1:37:15try to build more meaningful circuits.
- 1:37:22Let's try build something uh and let me
- 1:37:25draw a circuit and then we will build a
- 1:37:28truth table for it and and analyze that
- 1:37:30truth table and see if we can derive
- 1:37:32some meaning for that circuit.
- 1:38:08Okay, this is our circuit. I'm going to
- 1:38:11take a sip of water while you look at
- 1:38:12that. And I would like you to notice
- 1:38:14that there's three inputs.
- 1:38:19and one output. And uh we have a
- 1:38:24inverter a notgate right here. Then we
- 1:38:27have two ANDgates over here. And then we
- 1:38:29have an OR gate over here.
- 1:38:33That's just because uh you know it may
- 1:38:35actually be useful to screenshot this as
- 1:38:36you follow along or just you can Google
- 1:38:38logic circuits and it'll be there. It's
- 1:38:40also in the website I have linked below.
- 1:38:43Um but we have a a circuit now and uh
- 1:38:47this may seem like a random circuit but
- 1:38:48it actually does something a little bit
- 1:38:49interesting. Um so [snorts] I will spoil
- 1:38:53the fun and say that this is a selector
- 1:38:56circuit. So if you put some value of A
- 1:38:59and B uh put some values in A and B then
- 1:39:03C serves as a selector where if C is
- 1:39:07zero then the output so I'll write this
- 1:39:10out. If C is zero, then
- 1:39:14Y is going to equal to A. And if C is
- 1:39:17one,
- 1:39:19then Y will equal B. So C effectively
- 1:39:24controls what flows through as the
- 1:39:26output of this. So I'm going to move
- 1:39:28this over here. And let's verify this by
- 1:39:32building a truth table for our circuit.
- 1:39:35So this truth table is going to be a
- 1:39:37little bit longer. There's actually
- 1:39:38gonna be eight different values we can
- 1:39:40pass in. Um, so I'm going to come here.
- 1:39:45We have eight different values we can
- 1:39:47pass in. Our output's still y. And uh, I
- 1:39:51will write out all the eight values. Uh,
- 1:39:53it may be interesting to you where I'm
- 1:39:55getting these values from. Uh, but
- 1:39:59you you need not worry about it. Um, I'm
- 1:40:02just you'll get more comfortable
- 1:40:04enumerating all these values out the
- 1:40:05more you do do it on your own. Um,
- 1:40:22it's getting a little messy because I
- 1:40:23have not the best handwriting. Um,
- 1:40:29okay. So, uh, believe me, please when I
- 1:40:31say that these are all the possible
- 1:40:32values of A, B, and C. If you do not
- 1:40:34believe me that I challenge you to pause
- 1:40:36this and try to generate a a
- 1:40:40new uh combination of A, B, and C that's
- 1:40:42not in this table. And if you're curious
- 1:40:44where this this comes from, why how do I
- 1:40:47know how many are in how many different
- 1:40:48values there are? Well, if we're looking
- 1:40:50at A, B, and C stacked next to each
- 1:40:52other, um they're all either they're
- 1:40:56binary values. They're binary digits.
- 1:40:58So, there's two different values that
- 1:41:00can go into each of these digit
- 1:41:02positions. And so I multiply the
- 1:41:04different possibilities together to
- 1:41:06figure out the total number of
- 1:41:07combinations. So in that case there's
- 1:41:09eight. Uh and that's because um for each
- 1:41:12of the position we can either choose a
- 1:41:14zero or one uh 01. And then we multiply
- 1:41:17that by the number of ways there are to
- 1:41:19pick out the remaining digits. Um and we
- 1:41:21can apply this process over and over.
- 1:41:24Um,
- 1:41:26but I'm not going to get into that cuz I
- 1:41:27think it's a little mathy and uh that's
- 1:41:29actually a study of combinotaurics,
- 1:41:32which is probably a little too uh
- 1:41:35technical for what we're getting into
- 1:41:36today. But let's go ahead and trace
- 1:41:39through this. So, I'm going to switch my
- 1:41:41pen back to red and I'm going to make it
- 1:41:42a little bit bigger here so it's more
- 1:41:44readable. Our first example um I'm going
- 1:41:47to zoom out here is I'm saying if A and
- 1:41:50B are both zero and
- 1:41:53my claim is that if C is zero which or C
- 1:41:57is one then our output should be B which
- 1:42:01is zero in this case. Um but it's a
- 1:42:03little hard to distinguish because
- 1:42:04they're actually both zero. But let's
- 1:42:06let's verify that it's not one for sure
- 1:42:08and that'll have you partially
- 1:42:09convinced. So, uh, what we do right
- 1:42:12here, um, is we have C, which is one.
- 1:42:15And so, that means that we invert it.
- 1:42:17It's going to be a zero here, and it's
- 1:42:19going to be a one here. And then we have
- 1:42:21these carried through from our our
- 1:42:23original logic gates. And so, for the
- 1:42:25first gate, we know 0 and 0 is zero. And
- 1:42:280 and one for the second logic gate,
- 1:42:30still zero. And so, we have two zeros
- 1:42:32flowing into an orgate, which means the
- 1:42:33output is zero. Um, so we traced through
- 1:42:37the circuit and we our claim is verified
- 1:42:39so far. Uh, C is one and the output was
- 1:42:42equal to B. But you should be confused
- 1:42:45because how do I know that it wasn't
- 1:42:47equal to A? Um, and or just it just
- 1:42:50happened to be zero independently of
- 1:42:52what B was picked. Um,
- 1:42:55and uh, that's a great question. And
- 1:42:58let's actually toggle whatever. Let's
- 1:43:01set B to a one and see what changes. So,
- 1:43:04I'm going to erase this. Um,
- 1:43:08and everything I've left on the screen
- 1:43:10so far is un is unaffected by our
- 1:43:12changing of B from a zero to a one. But
- 1:43:14now, if I set B to a one, then this AND
- 1:43:16gate over here is going to output a one,
- 1:43:19which means this or gate's going to
- 1:43:21output a one. Uh, and and now we we do
- 1:43:24have a little more substance to our
- 1:43:25claim. So, we have the case here of uh A
- 1:43:29is zero, B is one, and C is one, which
- 1:43:32is over here. And we know this output's
- 1:43:34going to be one. Um, so I'm going to
- 1:43:36keep going through these examples. But
- 1:43:38what should be a little bit apparent by
- 1:43:40by now uh is
- 1:43:43if you look at these and gates,
- 1:43:46we know that for an ANDgate to output
- 1:43:48one, both of its inputs need to be one.
- 1:43:51And C goes to both of these AND gates,
- 1:43:53but one of them gets the regular C and
- 1:43:55one of them gets the opposite of C, the
- 1:43:57inverted value of C. So we know that the
- 1:43:59one that's getting the the uh we know
- 1:44:03one of these and gates can never fire
- 1:44:05because by virtue of C getting C going
- 1:44:09to one gate and not C going to the other
- 1:44:11gate then
- 1:44:13the gate that gets the zero version of C
- 1:44:16whether that's the inverted version or
- 1:44:17not can never output a one because it
- 1:44:19it's both of its inputs can't be one. So
- 1:44:21for example if I if I set C to one here
- 1:44:24then this is going to be a zero. So this
- 1:44:26this gate can never output anything but
- 1:44:28a zero. So this gate effectively gets
- 1:44:31silenced and then the value of B can
- 1:44:34just flow through this gate and it gets
- 1:44:36to this orgate where it's just going to
- 1:44:38go through because the orgate has a zero
- 1:44:40here. Um and and it may take a little
- 1:44:42bit of time for you to rationalize this.
- 1:44:44So So pause it. I I would recommend you
- 1:44:46pause things actually and fill out the
- 1:44:49rest of the circuit for yourself
- 1:44:50mentally or pause it as I work through
- 1:44:53some of the cases. So now let's look the
- 1:44:55example um and I I miswrote this here.
- 1:44:58There should be 0 0 0 where everything
- 1:45:00is zero. So uh 0 0 and then we have a
- 1:45:05zero here which means a one comes here
- 1:45:07and a one comes and a zero goes there.
- 1:45:09So in this case uh both and gates output
- 1:45:12a zero. So our y is also going to be a
- 1:45:14zero. Um [snorts] and we kind of have
- 1:45:16this rule where we said if if c is zero
- 1:45:18then y is equal to a. And that that's
- 1:45:20still the truth because C is zero and
- 1:45:22and we have Y equal to A which is still
- 1:45:24zero.
- 1:45:29Okay. Uh
- 1:45:32now let's look at a more interesting
- 1:45:34case. So if we have A is zero but B is
- 1:45:38one then let's look at the first case
- 1:45:41where uh C is zero. So if C is zero then
- 1:45:45this is going to be a zero. So this gets
- 1:45:47cut off cuz we can't output anything but
- 1:45:49with a zero. And then this is a one. Uh
- 1:45:51but we know one and zero is zero. But
- 1:45:53this is still a's value flowing through
- 1:45:55cuz if a was a one, a one would get
- 1:45:57through. And a is a zero and a zero goes
- 1:45:59through. So a's value is is flowing
- 1:46:01through here. That's what I'm hoping you
- 1:46:02can see. And then we have a zero or a
- 1:46:05zero which is is a zero which A's value
- 1:46:07still flows through because if it was a
- 1:46:08one then that's sufficient for this
- 1:46:10orgate to activate. So we have C is zero
- 1:46:14and then in our case A goes through
- 1:46:16which is is kind of what we would hope
- 1:46:17to see. And I am going to uh quickly
- 1:46:22work through the remaining cases
- 1:46:29because I said I would.
- 1:46:32So let's do uh A is 1 and B is zero. A
- 1:46:37is one, B is zero. Uh the first case
- 1:46:39will start with C is zero. So then a one
- 1:46:42goes through here, a zero comes through
- 1:46:43here, a 0 and 0 is 0, one and one is
- 1:46:46one, and then a one or one is one. And
- 1:46:48you can verify this. This meets what we
- 1:46:50would expect of the rule. And now if we
- 1:46:52flip the value of C to get the next row
- 1:46:54in the table, then we have a C is one,
- 1:46:58this is zero, this is one, um, and then
- 1:47:02we have a zero coming through here, a
- 1:47:04zero coming through here, which means we
- 1:47:05output a zero. And this this rule still
- 1:47:07holds. And now let's look at the very
- 1:47:10last case. Uh when both the inputs are
- 1:47:13one. So if both the inputs are one and C
- 1:47:16is a zero. Um start with that case. Then
- 1:47:20this is a one. This is a zero. This
- 1:47:22outputs a zero. This outputs a one. And
- 1:47:24that means we output a one. I'm going
- 1:47:26intentionally fast here just because uh
- 1:47:29I don't want to waste too much time.
- 1:47:32Our very last case we switch C to a one.
- 1:47:34And now we have a zero going to this
- 1:47:36gate which is effectively cutting it
- 1:47:37off. And we have a one going to this
- 1:47:39gate which is letting B's value flow
- 1:47:40through. And we have zero or one which
- 1:47:42is one. And now we've completed this
- 1:47:45truth table. And let me erase what I
- 1:47:48have.
- 1:47:51And uh
- 1:47:54hopefully you can you can verify this
- 1:47:56and see that uh this claim I've made
- 1:47:59actually does hold. Um if C is a zero,
- 1:48:02then we let the value of A flow through.
- 1:48:04And if C is a one, then we let the value
- 1:48:06of B flow through. So we've built what
- 1:48:08we called a selector. This is called a
- 1:48:10selector. And hopefully my goal in
- 1:48:13showing you this was not to waste your
- 1:48:15time, uh, but to show you a circuit that
- 1:48:17we are going to revisit in the future,
- 1:48:20um, but also show you that we can chain
- 1:48:22these logic gates together to do pretty
- 1:48:24interesting things. Um, this is a a
- 1:48:27somewhat of a trivial task, but it's
- 1:48:29it's actually not that trivial. It's
- 1:48:31it's it's trivial because I gave you the
- 1:48:33solution, but if I asked you to invent
- 1:48:35this on your own, it might not have been
- 1:48:37apparent as to how we how we do this.
- 1:48:40Um,
- 1:48:42so yeah, this is a a a brief overview of
- 1:48:45circuits and how we can chain logic
- 1:48:47dates together and build circuits. Okay,
- 1:48:51so what we've now accomplished is I
- 1:48:54clear my screen here. I showed you what
- 1:48:57a logic gate is. I showed you what a
- 1:49:00truth table is and how to derive a truth
- 1:49:03table by looking at either a circuit or
- 1:49:04a logicate. And then I showed you how
- 1:49:07you could compose logicates together to
- 1:49:10build what we call circuits that
- 1:49:13encapsulate more meaningful behaviors.
- 1:49:16And I also made this crazy claim that
- 1:49:18we're going to build an entire computer
- 1:49:20out of just logic gates.
- 1:49:24So before we even did that, we talked
- 1:49:27about binary
- 1:49:29And what I would like to do now, as I
- 1:49:32promised, I would like to bridge those
- 1:49:34two different concepts together. So, we
- 1:49:36discussed binary
- 1:49:39and we discussed logic gates. Um,
- 1:49:44but I haven't yet told you how they
- 1:49:46relate to one another. That was a bad
- 1:49:48arrow.
- 1:49:50And what I'm going to do in this part of
- 1:49:53the video is is bridge this together by
- 1:49:57showing how we can build a circuit, i.e.
- 1:50:00chain some series of logic gates
- 1:50:03together to build a circuit that can add
- 1:50:06binary numbers. And this is going to be
- 1:50:08cool because
- 1:50:12we have a way of going from the decimal
- 1:50:14numbers we know to binary numbers. And
- 1:50:16then I'll build I'll we'll end with a
- 1:50:18circuit that can add two binary numbers
- 1:50:22together.
- 1:50:23And in the real world, these logic gates
- 1:50:26act incredibly quickly. If you change
- 1:50:29the inputs on a on an ANDgate, for
- 1:50:30example, the output will will settle.
- 1:50:34It's what we call propagate very
- 1:50:36quickly. And in this way,
- 1:50:40if we uh assume that there's no time for
- 1:50:43us to convert from decimal to binary,
- 1:50:45which is obviously not true. But if we
- 1:50:48just assume that we have a long list of
- 1:50:51binary numbers and we wanted to add them
- 1:50:54all together, then doing it with a
- 1:50:57calculator, I guess say we also have a
- 1:50:59decimal equivalent, then adding those
- 1:51:01numbers up with a calculator or
- 1:51:03manually, should I say, adding those
- 1:51:05numbers up manually as a human is going
- 1:51:07to take some time. Whereas we could
- 1:51:09build this circuit that that outputs the
- 1:51:12value once you put the numbers in almost
- 1:51:14immediately.
- 1:51:16And these logic gates operate very
- 1:51:18quickly and this will be a useful
- 1:51:20circuit because adding numbers is
- 1:51:23something we would like to automate as a
- 1:51:25computer. At the end of the day, you may
- 1:51:27have heard some saying that a computer
- 1:51:28is a glorified calculator. And the
- 1:51:31further along you get in this video, the
- 1:51:33more convinced you may become that that
- 1:51:34is the reality. And it is true.
- 1:51:38Computers operate on numbers and they
- 1:51:39are able to perform arithmetic on
- 1:51:41numbers incredibly quickly. And in in
- 1:51:44that sense, a computer really is just a
- 1:51:45glorified glorified calculator. But
- 1:51:48let's start with the simplest case.
- 1:51:53I previously said when we learned two's
- 1:51:55complement that we had to assume that
- 1:51:57every number in binary is going to be
- 1:51:59the same number of digits. I also then
- 1:52:02said that our computer is going to be an
- 1:52:048bit computer, meaning that we use eight
- 1:52:07digits to represent every binary number.
- 1:52:09And I I should have mentioned this
- 1:52:11earlier, but I' i've been I've been
- 1:52:12trying to avoid it just in hopes of
- 1:52:14trying to avoid throwing too many words
- 1:52:16at you. Uh bit is just a zero or one.
- 1:52:19It's synony synonymous with a binary
- 1:52:21digit uh bit. And we talked about how
- 1:52:24most modern a lot of modern computers
- 1:52:26use 32 bits or 64 bits or even 128 or
- 1:52:30256 to represent their numbers. We're
- 1:52:34going to build an eightbit computer
- 1:52:36because it's enough for us to represent
- 1:52:39some numbers uh and build these circuits
- 1:52:41out without using incredible number of
- 1:52:43logic gates. But but at the end of us
- 1:52:45building the computer, it'll be
- 1:52:47incredibly easy for you to understand
- 1:52:49how we could scale it up to be a 32 or
- 1:52:5164bit computer, something perhaps, let's
- 1:52:54say, more modern. And the reason I won't
- 1:52:56do it is because uh I am drawing these
- 1:52:58logic gates out by hand and and drawing
- 1:53:01something 64 times every time we want to
- 1:53:03have a number. This will make more sense
- 1:53:05later is painful compared to eight which
- 1:53:07is still inherently repetitive but
- 1:53:09bearable. So let's start by building a
- 1:53:13circuit that does one bit addition. So
- 1:53:18one bit addition means we're adding
- 1:53:20binary numbers that are just one digit
- 1:53:22position. And and so this is pretty
- 1:53:24easy. If we're just adding two numbers,
- 1:53:26we know that the the two uh if we're
- 1:53:28doing the addition tables, we could have
- 1:53:30a 0 plus 0, a 0 plus a 1, a 1 + a zero,
- 1:53:36or a 1 plus a 1. And I'm setting these
- 1:53:39up in the way we we normally do
- 1:53:40addition. And so we know the output in
- 1:53:42this case is a zero. Uh in this case is
- 1:53:45a one. In this case is a one. And in
- 1:53:47this case, we have a zero here, but we
- 1:53:49carry over a one. And so the output's 1
- 1:53:52zero. And this makes sense. We're we're
- 1:53:54what we're saying here is that 0 + 0 is
- 1:53:560. And then here we're saying 0 + 1 is
- 1:53:591. And then here we're saying 1 plus 0
- 1:54:01is 1. And here we're saying 1 plus 1 is
- 1:54:042. Because in in binary this is uh 2 the
- 1:54:071st + 2 to the 0, which is just 2 to the
- 1:54:091st, which is just two.
- 1:54:12So we'd like to build a simple circuit
- 1:54:16that can do this arithmetic for us. So
- 1:54:19if we set a to be one number and b to be
- 1:54:22the other, we should get the output.
- 1:54:24[snorts] And what we've noticed is that
- 1:54:27we have two inputs here. So let's try do
- 1:54:30this in reverse. We previously looked at
- 1:54:32a circuit and then built a truth table
- 1:54:34for it. Let's in this case start with a
- 1:54:37truth table just we have our our
- 1:54:39consolidation and then try guess what
- 1:54:41circuit might match it. So in our case,
- 1:54:44our two operands, operand meaning the
- 1:54:46numbers that we're adding together are a
- 1:54:48and b. And we'll let out our output y be
- 1:54:52our sum. And for [snorts] now, we're
- 1:54:55going to ignore this carry bit. We're
- 1:54:56just going to say
- 1:54:58the the trivial uh onedigit result. And
- 1:55:04so in that in that case, I'm going to
- 1:55:06kind of draw a red circle on this cuz
- 1:55:07it's something we're going to have to
- 1:55:08revisit. um because when we do add one
- 1:55:10and a one, the output's not going to be
- 1:55:12zero, but we're just going to design our
- 1:55:14circuit to only have one output for now.
- 1:55:16And we'll come back and and and add a
- 1:55:18second output that could be used to
- 1:55:20represent that carry bit. So if our
- 1:55:23truth table may look something like this
- 1:55:28and we know the output in each of this
- 1:55:30case is a is as follows. And so what
- 1:55:36we'd like to do is build a circuit that
- 1:55:39that encapsulates this truth table. And
- 1:55:43now what you may be recognizing if you
- 1:55:46paid close enough attention is that this
- 1:55:49truth table over here is is uh very
- 1:55:53similar to the one I had for the
- 1:55:55exclusive orgate. And it's not just that
- 1:55:58it's very similar, it's actually the
- 1:56:00case that they are identical.
- 1:56:02And this is uh something that works out
- 1:56:05just conveniently. And this exclusive
- 1:56:08orgate can be used uh to do our our
- 1:56:10little bit of a one bit addition here.
- 1:56:13Um
- 1:56:15so as it as it turns out uh if I let A
- 1:56:19and B be our inputs
- 1:56:22then we could feed it into this
- 1:56:25exclusive orgate
- 1:56:27and the output Y uh is is holds. And so
- 1:56:32this does our our addition for us. You
- 1:56:34could fill this truth table out again if
- 1:56:35you don't believe me, but that's pretty
- 1:56:37cool. Um I know we made this huge
- 1:56:40oversimplification. We're looking at
- 1:56:41onedigit numbers, but it's cool that
- 1:56:44this one gate can be used to perform uh
- 1:56:47this one singledigit position worth of
- 1:56:49arithmetic.
- 1:56:51But what we're missing out here is that
- 1:56:53we have in the in this last case where
- 1:56:55this red is on the screen, we have it's
- 1:56:58possible that if we're adding a onedigit
- 1:57:02number, two one-digit numbers, that our
- 1:57:04output could be two digits. So if we're
- 1:57:06adding two one-digit numbers, a
- 1:57:09one-digit number and a one-digit number,
- 1:57:10our output doesn't always have to be one
- 1:57:12digit. It could be two digits as we saw
- 1:57:15here. So what we need to do is update
- 1:57:17this circuit to accommodate for this. So
- 1:57:21what we could say
- 1:57:23in each of these examples that only have
- 1:57:26one bit of output. I talked earlier
- 1:57:28about how we can pad with zeros. So I'm
- 1:57:31just going to pad each of these
- 1:57:32scenarios with a different zero. I'm
- 1:57:34going to do a little bit of separation
- 1:57:36here. And now let's say we have a
- 1:57:38circuit that takes in two inputs and
- 1:57:40produces two outputs. The two outputs
- 1:57:44will be the two bit positions. And what
- 1:57:46we're going to do is we're going to call
- 1:57:47this one the sum bit.
- 1:57:50Sorry, I wrote that weird. This is the
- 1:57:52sum bit and this is the carry bit. And
- 1:57:56uh I'm just going to happen to call it
- 1:57:57that accordingly. Um so what I'd like to
- 1:58:00do then is update our truth table and
- 1:58:03and add in these additional values. So
- 1:58:05our carry bit and our sum bit. And it's
- 1:58:07just going to be the exact same values
- 1:58:09that we had as before.
- 1:58:11Um
- 1:58:14but the interesting thing is now that
- 1:58:15we're able to represent correctly the
- 1:58:18the value of what happens when we add 1
- 1:58:21plus 1. We can represent two. And that's
- 1:58:24because as we talked about earlier, we
- 1:58:25can't represent two with one binary
- 1:58:27digit cuz that's just not possible. And
- 1:58:30you also may be wondering what about
- 1:58:32this two's complement? Uh let's just
- 1:58:34ignore it for now. Ignore's complement
- 1:58:35because we're we're just going to assume
- 1:58:37that we're working just with positive
- 1:58:38numbers. So ignore that rule where you
- 1:58:40multiply the leftmost digit by the
- 1:58:43negative one of its [clears throat]
- 1:58:44weight. And then over here, let me just
- 1:58:46write a note that uh we're going to say
- 1:58:48S stands for the sum position and C
- 1:58:50stands for the carry position. So now
- 1:58:53what we want to do is build a circuit
- 1:58:55that has two outputs. One for the carry
- 1:58:58bit and one for the sum bit. And
- 1:59:01[snorts]
- 1:59:02well, we already knew how to build the
- 1:59:04sum bit. We said the sum or the carry
- 1:59:06the sum bit, sorry. Uh, we already knew
- 1:59:09how to build this out and I' I've made a
- 1:59:11mistake here. There should be a zero. We
- 1:59:13already knew that the sum bit is going
- 1:59:15to be equal to the exclusive orgate. So,
- 1:59:17let's recreate that. I shouldn't have
- 1:59:19erased it, but I did. Uh, just cuz I
- 1:59:22wanted to have us a fresh slate for us.
- 1:59:24Um, and let's say that the exclusive
- 1:59:28orbit right here gets the input from A
- 1:59:32and it gets the input from B. And this
- 1:59:36is going to output. Let's put this over
- 1:59:38here so we can get it in the left to
- 1:59:40right. This is going to output the sum
- 1:59:42bit. And then now let's look at this
- 1:59:45carry bit. If we look at the carry bit,
- 1:59:47it always outputs zero except for when a
- 1:59:50and b are both one. And if you uh pause
- 1:59:54pause for a second here and try to think
- 1:59:56of what gate this reminds you of. And
- 1:59:59the answer is that this is equal to the
- 2:00:01AND gate. This has the same exact truth
- 2:00:03table as our AND gate up here, the
- 2:00:05[snorts] very first gate we talked
- 2:00:07about. And this works out really
- 2:00:09convenient uh because it means that we
- 2:00:10can just steal the AND gate and use it
- 2:00:12to represent this uh C
- 2:00:15this carry bit position. So if I just
- 2:00:17have an AND gate, then the uh output
- 2:00:22sorry let me write this over here. So we
- 2:00:25have the carry bit here um and let's
- 2:00:28have the sum here. here. So that let's
- 2:00:29just read it left to right as we we did
- 2:00:31up here. But let's go ahead and chain
- 2:00:35these inputs in. So when A and B are
- 2:00:39both to one, then we should have this
- 2:00:41carry. And I apologize because uh I
- 2:00:47accidentally inverted this CNSS,
- 2:00:49which I apologize for confusion. Uh
- 2:00:51that's the summit bit the one that we
- 2:00:53saw we could already use the exclusive
- 2:00:54or and then we wanted to add this carry
- 2:00:56functionality which we saw the andgate
- 2:00:58lets us do
- 2:01:00and I uh now you have built a circuit
- 2:01:04that uh takes two one bit i.e e onedigit
- 2:01:09binary values and outputs the sum of
- 2:01:12them and I'm not going to trace through
- 2:01:14every single example but uh I will do
- 2:01:17one let's say we are adding one and one
- 2:01:20then we can look at this gate we see a
- 2:01:23and b are going into both of these gates
- 2:01:25so one exclusive or one is zero but then
- 2:01:29one and one is one um and so we have
- 2:01:32this this this uh carry so our result we
- 2:01:35know is in the order of we read it left
- 2:01:37to right which is carry sum and so we
- 2:01:39have a one for carry and a zero for sum
- 2:01:42and if we interpret this as a binary
- 2:01:44value then we have 1 zero which is two.
- 2:01:47So this is really interesting. We've
- 2:01:49we've learned about binary we thought it
- 2:01:51was useless but uh we actually then
- 2:01:54learned about logic circuits and built a
- 2:01:57logic circuit that can add two one-digit
- 2:02:01binary numbers together.
- 2:02:03And this is really interesting
- 2:02:06and I will let you suggest that you
- 2:02:09pause this video and trace this circuit
- 2:02:11through every case and make sure you
- 2:02:13really understand what's happening here
- 2:02:15because what's really happening is that
- 2:02:17if we look at this uh there's one way to
- 2:02:19justify this truth this this circuit is
- 2:02:21by the truth table. But what I like to
- 2:02:23do is I like to have an intuitive
- 2:02:25understanding for why these circuits
- 2:02:26work the way they do. And I think I kind
- 2:02:28of did a a what I would hope was an
- 2:02:31explanatory job with the selector
- 2:02:32circuit we previously looked at. But for
- 2:02:35this example, let's try to do a little
- 2:02:36bit of rationing. Um there's only going
- 2:02:39to be a carry if we are adding one and
- 2:02:41one. That's the only case there's a
- 2:02:43carry. So if there in any other case the
- 2:02:45carry zero. So we can use an andgate
- 2:02:47kind of to represent the carry logic. So
- 2:02:50whenever there's a one and a one then
- 2:02:52this and get triggered and that's the
- 2:02:53only scenario in which we carry. And
- 2:02:55then for this exclusive or, what that's
- 2:02:58saying is if we're adding zero and zero,
- 2:03:02then we don't want anything to be
- 2:03:03outputed for the sum position. And if
- 2:03:05we're adding a one and a one, we also
- 2:03:07don't want anything to be included for
- 2:03:09the sum position because there's going
- 2:03:10to be a carryover. So we only want
- 2:03:12something to be added if there's just
- 2:03:14one one of the if if one of the two
- 2:03:16inputs is a one. Exactly one of the two
- 2:03:18inputs is a one. And that is just the
- 2:03:20definition of the exclusive orgate. So
- 2:03:22this works out perfectly.
- 2:03:25So, we've built uh this circuit and it
- 2:03:28turns out this circuit has a pretty uh
- 2:03:32it's famous enough where it has its own
- 2:03:34name and this is called the half adder.
- 2:03:41And this is cool because if we're adding
- 2:03:45two binary numbers 0 1 0 1 0 or 1 1 0 1
- 2:03:501 then this circuit lets us add
- 2:03:55each of the corresponding digit
- 2:03:57positions together. Right?
- 2:04:00And when we're adding numbers in binary
- 2:04:02or decimal for that case we do it as we
- 2:04:05can think of we actually divide up the
- 2:04:07work. We look at each digit position at
- 2:04:09a time. We start with the rightmost
- 2:04:11digit position, do its work, and then
- 2:04:14put the sum below and then do the next
- 2:04:16digit position and put the sum below.
- 2:04:17And this right here, this circuit is
- 2:04:20effectively doing that for one digit
- 2:04:23position.
- 2:04:25Now, there is a little bit of a
- 2:04:26shortcoming to this. What we'd like to
- 2:04:29do is to be able to have these half
- 2:04:31adders. If we want to add to in our
- 2:04:34example, we have two five bit values,
- 2:04:36fivedigit values. If we wanted to add
- 2:04:39them together, we would like to use five
- 2:04:41half adders and put them next to each
- 2:04:44other. And so we could write in all the
- 2:04:46operands values on uh each of the A
- 2:04:49lines and then all the other ones on
- 2:04:51each of the B lines um and and have a
- 2:04:54circuit that could just produce the
- 2:04:55output immediately.
- 2:04:58But
- 2:04:59this uh this unfortunately is missing
- 2:05:03something. And I I I would actually take
- 2:05:05it as a challenge to pause the video and
- 2:05:07try think about why we can't do what
- 2:05:09I've just described. Because in theory,
- 2:05:12we've built a circuit that can add one
- 2:05:14digit position. So why can't we just
- 2:05:17have a bunch of these circuits next to
- 2:05:19each other? Why couldn't we place five
- 2:05:20of these next to each other and let that
- 2:05:22be used to add the five-digit positions?
- 2:05:27And I will spoil it now. The issue is
- 2:05:31exactly what happens when we carry over.
- 2:05:34So let's look here.
- 2:05:37Let's do our little example. So we have
- 2:05:40a one and a zero. If we fed this into
- 2:05:43our into our half adder, then we would
- 2:05:46get the output 01. So we'd have a one
- 2:05:50for the sum and a zero we would carry
- 2:05:52over. And so that works out fine. And
- 2:05:56now if we do the input 1 one if we
- 2:05:58suppose we had a half adder that did
- 2:06:00this this computation we know it would
- 2:06:02output a zero for the sum bit. So a zero
- 2:06:04would go down here and then a one would
- 2:06:07go up top for the carry bit. And now the
- 2:06:10issue comes when we run into this digit
- 2:06:12position here because we have three
- 2:06:14values we need to add for this digit
- 2:06:16position but our half adder only adds
- 2:06:19two different values.
- 2:06:22So there's an issue in that we output
- 2:06:24the correct number of values because for
- 2:06:26each digit position we have one we have
- 2:06:28two outputs. We need to know what goes
- 2:06:31down here and if we carry over to the
- 2:06:33next position.
- 2:06:36But our fatal shortcoming is that we are
- 2:06:40missing the scenario for when there is
- 2:06:42carryover. We actually have three digits
- 2:06:44we want to be adding.
- 2:06:47And this is something that we are not
- 2:06:50accounting for in our circuit. So maybe
- 2:06:54you guessed by the name, but half adder
- 2:06:57uh lets us do half the adding logic, but
- 2:06:59what we're looking for is a circuit
- 2:07:00called a full adder, which lets us do
- 2:07:03the exact logic. So we'd like to do is
- 2:07:05we'd like to have our A and B, but we'd
- 2:07:08also like to add a new line for carry
- 2:07:11in. And so what we'll do is we're going
- 2:07:16to have to build a new circuit that can
- 2:07:18kind of handle this logic. So why don't
- 2:07:20we try start with the truth table for
- 2:07:22this. We have a b these are our two one
- 2:07:26bit values and there could be a possible
- 2:07:29carry in. And I'm not going to use a uh
- 2:07:32I want to distinguish because our output
- 2:07:34over here we had a C and now we're going
- 2:07:36to have a C as the input. And that's
- 2:07:37because there's a carry in and a carry
- 2:07:39out and they're fundamentally different
- 2:07:41as you know. So our output now is going
- 2:07:44to be carry out. I almost wrote in
- 2:07:47and then the sum. So we still have two
- 2:07:50outputs but now we have three inputs.
- 2:07:52So, let me uh go silent for a moment as
- 2:07:54I populate this truth table.
- 2:07:58[snorts]
- 2:08:22Okay. So now let's take this truth table
- 2:08:25and think about what this means. So now
- 2:08:27we're adding effectively because of the
- 2:08:29carry in bit we're adding three three
- 2:08:33one-digit values.
- 2:08:39And again we're still ignoring choose
- 2:08:41complement. Uh we'll come back to this
- 2:08:43later, but let's not over complicate
- 2:08:45things now.
- 2:08:47And let's see what happens. So uh I'm
- 2:08:50going to go ahead and uh it's it's easy
- 2:08:53to do these quickly because uh we're
- 2:08:56working with zeros and ones. So 0 plus 0
- 2:08:58plus 0 is these are all binary numbers.
- 2:09:00But remember that uh 0 in binary is
- 2:09:04equal to 0 in base 10 and one in binary
- 2:09:07is equal to one in base 10. So we can
- 2:09:09kind of ignore we don't need to convert
- 2:09:11between binary because we don't need to
- 2:09:13convert these binary operants these
- 2:09:15binary inputs to our circuit to decimal
- 2:09:18because for 0 and one they're equivalent
- 2:09:20which just works out perfectly for us
- 2:09:21because we don't have to overthink but
- 2:09:23it can be tricky to sometimes wrap your
- 2:09:26head around that. So we're adding 0 plus
- 2:09:280 plus 0. So we know the output's just
- 2:09:30going to be zero. Um
- 2:09:33i.e. uh there's there's we're adding
- 2:09:37zero. we need to represent that in two
- 2:09:39digits. The output zero. The uh if we're
- 2:09:42adding a zero and a zero in a digit
- 2:09:44position, but the carry in is one, then
- 2:09:47we know we output a one cuz that's what
- 2:09:49we sum. And then there's no carry over
- 2:09:50to the next digit position. We know we
- 2:09:52just we just throw a one down below. So
- 2:09:54that's fine. Then let's look what
- 2:09:56happens if we're adding our A and B,
- 2:09:58which are zero and one in the next row.
- 2:10:01And then first off, we have no
- 2:10:03carryover. So if we're just adding a
- 2:10:04zero and a 1, then we sum a one with no
- 2:10:08carry out. But if we have a carry in,
- 2:10:12then we have 1 + 1, which is two. And we
- 2:10:16know we put the remainder when you
- 2:10:18divide by two below. So two divides into
- 2:10:21two exactly. So there's no remainder.
- 2:10:23And then we do have a carry out. So in
- 2:10:25this case, we have a one for the carry
- 2:10:26out, but a zero for the sum. And and
- 2:10:29maybe rework that for yourself if it's
- 2:10:30unclear what's happening. But you may
- 2:10:32need to go back to the earlier part of
- 2:10:34the video where I showed you how to do
- 2:10:36addition of binary numbers.
- 2:10:40Let's move on to the next case. Uh which
- 2:10:42is when you have a one and a zero. And
- 2:10:45the first one there is no carry-in. And
- 2:10:48this is kind of what we looked at
- 2:10:50before. You just have a one carries down
- 2:10:52and there's no carryover. Uh so this is
- 2:10:54a zero and a one. But if you do have a
- 2:10:56carry-in then uh you have 1 plus 1 which
- 2:11:00is two and two divides perfectly into
- 2:11:02two. So the remainder is zero and then
- 2:11:04we carry over a one. So we have a one
- 2:11:06here.
- 2:11:08And then the last case is last two cases
- 2:11:11are when we're adding a one and a one.
- 2:11:13So if we don't have any carry in then 1
- 2:11:16+ 1 we already know is two. So the
- 2:11:18output is that we carry out over once
- 2:11:20and then put a zero below. And then the
- 2:11:23uh edge case that is is bringing us here
- 2:11:26uh is this 1 one one. Um and that means
- 2:11:291 plus 1 plus 1 is three. And that means
- 2:11:32we put the remainder down below. So
- 2:11:34three would the remainder 1 divided by
- 2:11:36two is one. And we have the carryover.
- 2:11:38Um and so we have we have three up here.
- 2:11:40This is actually three in base 10. And
- 2:11:43you know this makes sense because this
- 2:11:44is in binary. We have 11 one two in base
- 2:11:472 which is equal to three in base 10. if
- 2:11:50you do the conversion.
- 2:11:55Cool. So, we have our truth table. Now,
- 2:11:57let's think about how we can actually
- 2:11:59build this circuit. [snorts]
- 2:12:01And so, what I'd like to do for this is
- 2:12:05go ahead and I think this is a difficult
- 2:12:08one to build because we have three
- 2:12:10inputs, which is more than two. So, we
- 2:12:12have eight different cases we need to
- 2:12:14handle and we have two outputs. But I
- 2:12:17would like to take a logical approach to
- 2:12:19building this. Not just spill out the
- 2:12:21answer and let you prove it yourself,
- 2:12:22but kind of give the answer um build up
- 2:12:27and explain why it is we're doing what
- 2:12:30we are doing. And so the way I would
- 2:12:32think about this is
- 2:12:35uh let's look at each of the outputs
- 2:12:37separately. We could build a separate
- 2:12:40out a separate circuit for each output.
- 2:12:42We could think of building a separate
- 2:12:43circuit for each output. Um and that's
- 2:12:46because
- 2:12:48uh they are two different outputs. We
- 2:12:50could build two different circuits. Uh
- 2:12:53one circuit that takes a b and c in and
- 2:12:55outputs c out and another circuit that
- 2:12:57takes a b and c in and outputs s. But uh
- 2:13:00this would be inefficient because uh
- 2:13:03computers are have to be physically
- 2:13:06built. This computer that we're going to
- 2:13:07build has to add numbers. They have to
- 2:13:09be physically built and logicates cost
- 2:13:12money in the real world to buy. uh they
- 2:13:15are incredibly small. Your computer has
- 2:13:17trillions of them, but they do incur
- 2:13:20some cost. And so we would like to
- 2:13:22design a circuit that minimizes the
- 2:13:24number of logic gates used. When we're
- 2:13:26building our computer, we would like to
- 2:13:27minimize the amount of logic gates used.
- 2:13:30And uh an easy way to minimize those is
- 2:13:32to try combine the logic for these
- 2:13:34circuits. Don't build a separate circuit
- 2:13:36for the carry out and the sum. Just just
- 2:13:38do it all together.
- 2:13:42Okay, let's start by thinking about the
- 2:13:45sum bit. So if we stack this in the uh
- 2:13:49vertical kind of notation that you're
- 2:13:52used to and that we've kind of seen
- 2:13:54throughout this video multiple times now
- 2:13:56we're interested we know this is the sum
- 2:13:58bit. We know this is the carry carry out
- 2:14:00bit and the carry in bit comes up top
- 2:14:04and this is per bitwise operation. We're
- 2:14:06just looking at one vertical digit
- 2:14:08position. So let's figure out each of
- 2:14:12the definitions in which the sum bit is
- 2:14:15going to equal one. So if we ignore this
- 2:14:18carryin bit then we know the sum is
- 2:14:22going to equal one as long as either a
- 2:14:25or b equals 1 but not both of them
- 2:14:28because if so if neither of them equal
- 2:14:30one then we we output nothing. uh in the
- 2:14:32case where it's a 10 or a 01 then we
- 2:14:35just output a one for the sum but if
- 2:14:37they're both one then we actually output
- 2:14:39a zero and then the carry out is going
- 2:14:41to be what's equal to one. So in the
- 2:14:45case where carry in equals zero. So
- 2:14:47let's let's try make a rule here. So if
- 2:14:50carry in equals zero then we want
- 2:14:54exactly one of a or b to be true then
- 2:14:59then sum is going to be exactly a
- 2:15:02exclusive or b and uh recall what
- 2:15:06exclusive or is from earlier. Exclusive
- 2:15:08or says output a one if either a and or
- 2:15:12b is true but not both of them. So this
- 2:15:15is exactly what we're going for because
- 2:15:16if A and B are both zero, the exclusive
- 2:15:19or of those two values is going to be
- 2:15:21zero. If A and B are going to be one,
- 2:15:24they're both one, then the exclusive or
- 2:15:26is going to be zero, which is synonymous
- 2:15:28with the sum in these two cases. And for
- 2:15:30any of the other two cases, we have one
- 2:15:33of A or B is equal to one and the other
- 2:15:35is equal to zero. And that's going to
- 2:15:37output a one, which is what we'd expect.
- 2:15:39So we've kind of built this rule out
- 2:15:41where if the carry in is zero then the
- 2:15:44sum bit is equal to a exclusive or b and
- 2:15:47we have the exclusive or gate. So we can
- 2:15:49kind of build that out. Uh but what
- 2:15:52happens we need to complete the rule
- 2:15:54then if the carry in is one.
- 2:15:58So then if if I clean up the screen a
- 2:16:00little bit here but if carry in is equal
- 2:16:03to one then what is the sum going to be?
- 2:16:05And for this one, we can actually
- 2:16:07probably get a little more context out
- 2:16:08of looking at the truth table. So, uh,
- 2:16:11in this row, carry is one. In this row,
- 2:16:13carry is one. And we have four rows
- 2:16:16where Krion is equal to one. And we can
- 2:16:19see that in this case, uh, sum is one
- 2:16:23because and a and b are both ones. In
- 2:16:26this case, sum is zero and only one of a
- 2:16:30and b is a is a one. Over here we have
- 2:16:33sum is zero and it's the same condition.
- 2:16:35So it looks like when it's just one of a
- 2:16:37or b i i.e if we have a exclusive or b
- 2:16:41then sum's going to be zero and then if
- 2:16:45we have not that then it looks like the
- 2:16:47sum's going to be one. So we can
- 2:16:49actually draw this rule up where if if
- 2:16:51the carrying is one then s is going to
- 2:16:55equal to not so I'll do like negative to
- 2:16:59represent a negation
- 2:17:01ax or b
- 2:17:04and uh this is probably a good time to
- 2:17:08pause this and and and verify this is
- 2:17:10true that is if you're interested in in
- 2:17:13knowing where this full adder circuit
- 2:17:15that I'm I'm going to design comes from.
- 2:17:17if you don't really need to understand
- 2:17:18that technically to move on, but I just
- 2:17:20thought your inner curiosity might be
- 2:17:22satisfied if if you had a more complete
- 2:17:24answer. So let's let's let's build this
- 2:17:27out as a circuit then. So our our inputs
- 2:17:30um and this is just for uh just for S.
- 2:17:33So if our inputs are a b and carry n
- 2:17:39then well if c in equals zero I'm going
- 2:17:43to go ahead and spoil the most efficient
- 2:17:46way to do this. It is probably a good
- 2:17:48practice for you to try implement this
- 2:17:50on your own but uh I will go ahead and
- 2:17:53uh spoil this. So what you actually end
- 2:17:56up doing uh is for the first part we
- 2:17:58will use an exclusive ore which isn't
- 2:18:02that surprising because exclusive or was
- 2:18:04there and then we're going to actually
- 2:18:07output this into another exclusive or
- 2:18:12and the output of that exclusive ore is
- 2:18:14going to be equal to y which is you know
- 2:18:16let's not even call it y let's just call
- 2:18:18it the sum that's what it is and the
- 2:18:21other input of the exclusive ore is
- 2:18:24going to be this right here this carry-
- 2:18:26in. And so what this what this says is
- 2:18:28if carry-in equals zero. So if carry-in
- 2:18:31equals zero, then the output of this
- 2:18:34exclusive or right here is just going to
- 2:18:36be whatever flows in. So whatever flows
- 2:18:38in uh will just flow straight through.
- 2:18:41And that's because if we put a zero on
- 2:18:43the top line, then zero exclusive or
- 2:18:45zero is zero. And if we put a one up
- 2:18:48here, then zero exclusive or one is one.
- 2:18:51So uh if C in if the carry in is zero
- 2:18:54then whatever comes in here will be the
- 2:18:56output. And so what is it that comes in
- 2:18:58here? It's a exclusive or b. So that's
- 2:19:01what we've built out right here. We've
- 2:19:03shown that when the carry in is zero
- 2:19:05then the output is equal to this gate
- 2:19:07and this gate is a exclusive or b.
- 2:19:14Now if carryen is one let's see what
- 2:19:16happens. Krion is one then the output
- 2:19:20here will be the opposite of whatever
- 2:19:22comes in because if if if we have a zero
- 2:19:24coming in here then zero exclusive or
- 2:19:27one is a one but if we have a one in
- 2:19:29here one exclusive or one well that's
- 2:19:32both inputs are being on and that's a
- 2:19:33zero and so it kind of functions as a as
- 2:19:36almost a negator in this context and uh
- 2:19:39we know that whatever so we we know
- 2:19:41that's the the negated of whatever is
- 2:19:43coming in here and we already showed
- 2:19:44that whatever coming in here is is A
- 2:19:46exclusive or B and uh as it turns out
- 2:19:49this is this is the most efficient way
- 2:19:52to implement this in terms of minimizing
- 2:19:55the number of gates that are being used.
- 2:19:58So that's how we derive the sum bit.
- 2:20:01What we're then interested in is the
- 2:20:02carry out bit. So I'm going to erase
- 2:20:04what we have right here.
- 2:20:08And again, if you need to pause the
- 2:20:11video and and convince yourself this is
- 2:20:13true, then now is a great time to do
- 2:20:15that. We have the sum bit. Let's look at
- 2:20:17this carry out bit. We have this carry
- 2:20:20out bit which is going off in a few
- 2:20:23interesting cases.
- 2:20:25And so we intuitively know that we're if
- 2:20:29we're if we're stacking numbers, we can
- 2:20:30look at it this this visual approach
- 2:20:32again where we have our AB
- 2:20:35and then we're adding them and then
- 2:20:37we're also adding a carry-in. So, so
- 2:20:40then if we look at this right here, if A
- 2:20:43and B
- 2:20:46together
- 2:20:48sum to anything greater than one,
- 2:20:51then we're going to have to carry out.
- 2:20:53So, if if A and B are both set to one,
- 2:20:56then we're for sure carrying out. And it
- 2:20:58doesn't even matter what the carry in is
- 2:21:00in this case because we know uh if the
- 2:21:02carry-in is zero, then we output 1 zero.
- 2:21:05And if the carry-in is one, then we
- 2:21:07output 1. But in both of those cases,
- 2:21:09we're carrying out. So for for
- 2:21:13determining carrying out, if if A and B
- 2:21:18are both equal to one, if A and B are
- 2:21:22both equal one,
- 2:21:26then we uh we know that carry out is
- 2:21:28going to equal one. And there's not the
- 2:21:31only case here. So uh that would cover
- 2:21:34in our in our truth table that would
- 2:21:37cover these two cases right here. A and
- 2:21:40B are both one and we carry out. But
- 2:21:42notice that uh we have two other cases
- 2:21:44where A and B are not both one but we
- 2:21:47still carry out. And what happens here?
- 2:21:50And that's what happens when we only
- 2:21:52have one of A and B. So a or b but we
- 2:21:56also carry in cuz then we have 1 plus 1
- 2:21:59effectively which which is a carry out 1
- 2:22:01zero. So then if a exclusive or b
- 2:22:09i i.e if there's just one of a or b is
- 2:22:12set and
- 2:22:14carry in is equal to one then we carry
- 2:22:17out. So these are our our two conditions
- 2:22:20for when we actually carry out and uh
- 2:22:24let's go ahead now and and see how we
- 2:22:26can build this up with logic gates. So
- 2:22:29we we it's obviously we're going to need
- 2:22:30some and gates. So uh let's start with
- 2:22:33this first rule. If A and B both equal
- 2:22:35to one, then we carry out. So I'm going
- 2:22:38to add an AND gate down here. And I'm
- 2:22:40just going to feed whatever A and B's
- 2:22:43values are
- 2:22:45into this gate. And uh we will start by
- 2:22:48claiming that this is the carry out. Uh
- 2:22:52so we know that if a and b are both
- 2:22:54equal to one then we do carry out. But
- 2:22:55there's another case uh it could either
- 2:22:58be that or if we have a exclusive or b
- 2:23:02and a carry in then we also carry out.
- 2:23:05So there's actually two cases. So let's
- 2:23:07let's implement the second case. Um and
- 2:23:11I'm going to extend this line just cuz
- 2:23:13it's going to get a little messy here if
- 2:23:14I don't. Uh the second case is we need
- 2:23:17to know if there's a exclusive or b
- 2:23:19which we have right here. So we can
- 2:23:21reuse this logic gate and this is what I
- 2:23:23was talking about with optimizations.
- 2:23:25So if we need a x or b so I'll just
- 2:23:28bring this down. Um and we have a
- 2:23:30carry-in. So we can just bring this down
- 2:23:33too. And
- 2:23:36this is another and gate. Uh then we're
- 2:23:38saying that this should also mean we
- 2:23:40carry out. But we want to carry out when
- 2:23:42either of these lines are a one. So
- 2:23:44let's join them with an orgate. We have
- 2:23:46a gate that already handles this. This
- 2:23:48gate will trigger if either of the
- 2:23:52inputs is a one and that's an and not an
- 2:23:55or. Here is an orgate. And we can call
- 2:23:59this carry out. And this uh as it turns
- 2:24:04out is what we call a full adder.
- 2:24:09And I've done a better job of drawing
- 2:24:11this up here. So let me go ahead and
- 2:24:16bring it down
- 2:24:18and let's just look at this drawing
- 2:24:21which is not as as painful to look at as
- 2:24:23the one I I have provided. Uh so I will
- 2:24:27respectfully
- 2:24:28uh move this out of the way.
- 2:24:31Okay. And I'm also going to do a little
- 2:24:34cleanup here just because I'd like this
- 2:24:36to be referenceable later in case I need
- 2:24:38to. But this circuit right here is a
- 2:24:41full adder. And uh this is a another
- 2:24:45great opportunity. Let me go ahead and
- 2:24:46erase this to convince yourself that
- 2:24:49this is true. Uh if you would like the
- 2:24:51exercise, go through take this circuit,
- 2:24:54I'll zoom out the perfect amount. Uh
- 2:24:56pause this video and for each of the
- 2:24:58rows you see in this truth table,
- 2:25:01compute what the output of the circuit
- 2:25:02should be and verify that it's equal to
- 2:25:04what you see on the right hand side over
- 2:25:06here. If it's not, then there's
- 2:25:08something wrong with your logic or I
- 2:25:10made a mistake in this video, which I
- 2:25:12will hopefully correct in the
- 2:25:13description or someone will point out in
- 2:25:15the comments if if that if someone ever
- 2:25:17watches it. And
- 2:25:20what we have is this really cool circuit
- 2:25:23which if we're doing some sort of binary
- 2:25:26addition,
- 2:25:29then can correctly do the addition for
- 2:25:32each one of these these vertical
- 2:25:35positions. So for each digit position,
- 2:25:38this full adder can perform the correct
- 2:25:40addition. And where we're going to go
- 2:25:43with this is we're actually going to
- 2:25:44build a circuit that can add uh 8 bit
- 2:25:47numbers together because we said our
- 2:25:49computer is 8 bits. So let's let's get
- 2:25:50back to the realm of our computer.
- 2:25:53And that circuit's going to work by us
- 2:25:55effectively having eight full adders
- 2:25:58together. And we're actually going to
- 2:25:59chain them together because the carry
- 2:26:02out from this add adder right here
- 2:26:04should become the carry into this adder.
- 2:26:06And then the carry out from this adder
- 2:26:08should become the carry into this adder.
- 2:26:10And then the carry out from that adder
- 2:26:11should be the carry into this adder. And
- 2:26:13so on and so on. And it might be a
- 2:26:16little bit vague what I'm trying to say,
- 2:26:17but hopefully at a high level you
- 2:26:18understand that the the carry out from
- 2:26:22this position right here becomes the
- 2:26:24carry in over here. And then the carry
- 2:26:26out for this sum becomes the carry-in
- 2:26:29over here. And we've built this
- 2:26:31generalized circuit which can handle any
- 2:26:34of the possible input combinations and
- 2:26:36correctly give us the the sum bit and
- 2:26:38the carry out bit. And now I hopefully
- 2:26:42convinced you that we've been able to
- 2:26:44tie together the first fundamental
- 2:26:46concepts we learned in this video. Uh
- 2:26:49that being binary and logic gates. We
- 2:26:52now see a bridge between these seemingly
- 2:26:54distinct concepts and we're going to
- 2:26:57work on drawing them together. And so
- 2:26:59we're actually going to work on building
- 2:27:00our first part of the computer which is
- 2:27:02called the ALU, the arithmetic and logic
- 2:27:05unit. And that's going to be responsible
- 2:27:07for adding and subtracting numbers. So
- 2:27:10[snorts] I will uh go ahead and move on.
- 2:27:14Now's the last chance to pause this and
- 2:27:16just make sure you understand everything
- 2:27:18that's on the screen. But we'll move on
- 2:27:20and see how we can build on top of these
- 2:27:22full adders and combine them together to
- 2:27:24build a circuit that can do more
- 2:27:27non-trivial addition because right now
- 2:27:29this is trivial. This adds uh this adds
- 2:27:32technically it's meant to add one digit
- 2:27:34position together but it could add three
- 2:27:36binary numbers three binary digits
- 2:27:38should I say and and tell you what the
- 2:27:40output's going to be. And you should
- 2:27:42also be able to convince yourself that
- 2:27:44uh for any three binary digits, the sum
- 2:27:47of those is going to be somewhere in the
- 2:27:50range of 0 0 which is zero or 1 one
- 2:27:54which is three in binary uh
- 2:27:58three in decimal one in binary. And you
- 2:28:00should be able to see that this fits
- 2:28:02within two different uh bit positions.
- 2:28:06So there should be no doubt in your mind
- 2:28:08that for whatever values the inputs are,
- 2:28:11we are able to correctly represent the
- 2:28:12output without any loss of memory or
- 2:28:16information representation.
- 2:28:18Okay. So before we actually do the uh
- 2:28:21expand this out to multiple bit
- 2:28:23addition, let's go ahead and and give
- 2:28:25some notation so it makes sense. So I
- 2:28:28guess the example we just built out, we
- 2:28:30did something along the lines of A and B
- 2:28:34and we get from that a sum and then we
- 2:28:38also possibly get a carry out carry out.
- 2:28:44So there's there's there's two inputs
- 2:28:46and two outputs for each digit position.
- 2:28:49And this happens in regular addition as
- 2:28:52well as as well as binary edition. So if
- 2:28:55I give you two numbers, say 74 and 83,
- 2:29:02then we could say that for this digit
- 2:29:04position right here, the sum is seven.
- 2:29:08And then there's no carryover. So we'll
- 2:29:09just say the carry the carryover is
- 2:29:11zero. And then for this digit position
- 2:29:15right here, the sum is five and the
- 2:29:18carryover is a one, which comes down.
- 2:29:21And the same thing happens in binary. So
- 2:29:24if I gave you one zero and then one one
- 2:29:28then here when we're adding this digit
- 2:29:30position we sum a one and then there's
- 2:29:33no carryover. So we can implicitly write
- 2:29:35a zero for the carry. And here we have a
- 2:29:38sum and a carry which comes down.
- 2:29:43So that's just a little bit of recap. So
- 2:29:46now let's say we want to have two bit
- 2:29:49numbers we want to add. That's what I
- 2:29:51said we would build up to now. So let's
- 2:29:53give some notation. So A and B are now
- 2:29:56our two operandines are two bits. So
- 2:29:59let's let's give them indexes to make
- 2:30:02this more apparent what's happening. So
- 2:30:03we can say we have A2 and A1 and we're
- 2:30:08adding it to B2 and B1.
- 2:30:11And then from this we would get a sum
- 2:30:14down here. And we're actually going to
- 2:30:16get two sum bits. So let's have a way of
- 2:30:18distinguishing them. And I think it
- 2:30:20makes sense naturally to give them the
- 2:30:22same indexes that we did for the the
- 2:30:24operands. So we get a sum one and then
- 2:30:28we get a possible carry over one. And
- 2:30:31then for this digit position, we get a
- 2:30:34sum two and possibly a carryover from
- 2:30:39two. And if that's the case, then we we
- 2:30:41carry it down. And again, carryover is
- 2:30:44either going to be a zero or one. So it
- 2:30:46makes sense that if we have the zero and
- 2:30:48then some binary digits, it's the same
- 2:30:50thing as just the binary digits that we
- 2:30:53saw earlier.
- 2:30:55And so
- 2:30:57what this means, and I'll go ahead and
- 2:30:59erase this
- 2:31:01to stop the screen from getting too
- 2:31:02crowded, is we are going to effectively
- 2:31:05use two of these full adders we've
- 2:31:08described and
- 2:31:12chain them together with these operands
- 2:31:14as so. And so what we're going to see is
- 2:31:16that the uh first full adder is going to
- 2:31:20take this a1 and b1 as its operands. And
- 2:31:23then we're going to treat the sum output
- 2:31:26as someone. And then what we're actually
- 2:31:28going to do with the carry out this C
- 2:31:31this carry out uh that we have right
- 2:31:34here is we're going to feed it into the
- 2:31:36carry in of the second h full adder. And
- 2:31:40the second full adder is going to be
- 2:31:42operating on A2 and B2.
- 2:31:45So we can kind of see how these get
- 2:31:47chained together.
- 2:31:49And so why don't we go ahead and try
- 2:31:51build that. And luckily because I'm
- 2:31:53drawing on my iPad, I can just duplicate
- 2:31:57this right here. And I'm going to paste
- 2:32:00it twice below.
- 2:32:03And we will give the proper notation. So
- 2:32:06let's not this I have up there.
- 2:32:10And
- 2:32:13I'm going to copy this again and paste
- 2:32:16it one more time right here.
- 2:32:19Okay. So now what I'm saying and I think
- 2:32:22this will make a little more sense now
- 2:32:25is
- 2:32:26let me move this over here.
- 2:32:30Okay. So if I have A1 and B1 I want to
- 2:32:35use this
- 2:32:39half adder and let me actually yeah I'm
- 2:32:42going to use this this full adder.
- 2:32:45Sorry, not half adder, full adder to do
- 2:32:48the A1 plus B1. So what I do is I'm
- 2:32:51going to feed in A1 and B1. And this is
- 2:32:56the the the
- 2:32:58rightmost digit of the two numbers we're
- 2:33:00trying to to operate on. And now you
- 2:33:04might be wondering, this is a good
- 2:33:05question. What do we do for carry in?
- 2:33:08Because for this rightmost digit
- 2:33:09position, we're never going to have a
- 2:33:11carry in. I mean, if if we think about
- 2:33:13it, that's where we start our addition
- 2:33:14at. So, how could there already be
- 2:33:17something before that to which we could
- 2:33:18have carried into? And the answer is
- 2:33:20there's nothing. There's no way we could
- 2:33:22ever have a carry in on the rightmost
- 2:33:23digit position. But we do know is that
- 2:33:27what we're effectively doing is a1 + b1
- 2:33:29plus the carry in.
- 2:33:32That if if we're doing this plus this
- 2:33:36plus this, and we know that the carry in
- 2:33:37is zero, then we're really just left
- 2:33:39with a1 plus b1.
- 2:33:43And so what we're going to do is just
- 2:33:45hardwire this right here to be a zero
- 2:33:50because there's no way we could have
- 2:33:51carried into our first bit of addition.
- 2:33:54And then that's going to let us use this
- 2:33:56this this full adder we have to do
- 2:33:58exactly what we want. So now let me go
- 2:34:00ahead and erase what we have marked for
- 2:34:03these outputs. And let's say that the
- 2:34:06output of this is going to be S1. and
- 2:34:10then the carry out. So this is carry
- 2:34:14one. We're going to feed that in to the
- 2:34:18carry in of this next full adder.
- 2:34:24And and visually that is the arrow we
- 2:34:27see right let me erase these. That is
- 2:34:30the arrow we see right here. When we add
- 2:34:33A1 and B1 we get the sum one down below.
- 2:34:35And then we may have a carry out a
- 2:34:38carryover from S1 from that first
- 2:34:41edition into the second edition. And
- 2:34:43that's exactly what this arrow
- 2:34:44represents.
- 2:34:46So now for this second full adder, we
- 2:34:49will feed in not a1 and a b1 but a2 and
- 2:34:53b2. So now I'll throw in a2
- 2:34:57and b2. And from this we get
- 2:35:02sum two and then carry two. So now you
- 2:35:07can see here that if we have and let me
- 2:35:10go ahead and erase this cuz I think it's
- 2:35:12a little complicated. If we had two
- 2:35:16operands we wanted to add and both of
- 2:35:18those operands were two binary numbers,
- 2:35:20two binary digits, then we could simply
- 2:35:23plug them into this circuit right here
- 2:35:25and we would get the sum as something we
- 2:35:27could read from S1 and S2 combined with
- 2:35:32C2. And I should not have erased that.
- 2:35:35And this C1, it's not that it's useless,
- 2:35:37but it doesn't actually show up in our
- 2:35:39output. We use it as part of the
- 2:35:41computation, but we only care about
- 2:35:43these three for our output because these
- 2:35:45are what we actually read and that's
- 2:35:46what we want to know. We want to know
- 2:35:47the sum of the value. We don't really
- 2:35:49care about where the carryover happen
- 2:35:51intermediately and internally. We just
- 2:35:53need to know that we make sure that we
- 2:35:54deal with it correctly when it does
- 2:35:55happen.
- 2:35:57So let's go ahead and plug in a little
- 2:35:59bit of an example here. Uh just to make
- 2:36:01sure that this works. Suppose I wanted
- 2:36:03to add one zero. Sorry, I wanted to add
- 2:36:07the binary numbers 1 1 and 0 1. And this
- 2:36:12in binary is going to be equal to 3 + 1.
- 2:36:18So 3 sub in base 10 + one in base 10.
- 2:36:22And we know we should expect four back
- 2:36:23in base 10. And we can do this
- 2:36:26arithmetic manually. And we would see
- 2:36:29that we know the 1 + 1 is a zero, but we
- 2:36:33carry over a 1. And then we know that
- 2:36:35this 1 plus one also a zero but we carry
- 2:36:38over again another one and then that one
- 2:36:40drops down. So we can kind of see that
- 2:36:43we would expect this to be s1 this is
- 2:36:46sub2 and this is the c2. And then we
- 2:36:49know that this is we know how a1 and a2
- 2:36:52are structured based on this diagram
- 2:36:53over here.
- 2:36:55And uh sure enough uh we if we plug this
- 2:36:59into our circuit we expect to get that.
- 2:37:01So let's go ahead and do this. So I'm
- 2:37:03going to plug in
- 2:37:07to our circuit. We have a one and a one.
- 2:37:11This is the A1 and B1. And then a one
- 2:37:13and a zero for the A2 and B2. And we
- 2:37:17have to start with this circuit on the
- 2:37:18right because you notice the circuit on
- 2:37:20the left. One of the inputs
- 2:37:23comes from this line over here. And
- 2:37:25that's actually the output of the
- 2:37:26circuit on the right. So we'll have to
- 2:37:27start by doing this first. So we have
- 2:37:30one exclusive or one which is a zero.
- 2:37:33And then we have to this right here we
- 2:37:36have zero exclusive or zero which we
- 2:37:39know is just a zero. So sum one I'm
- 2:37:43saying a zero. And that that checks up
- 2:37:44with what we have here. And then I'm
- 2:37:47saying let's come down to this andgate
- 2:37:49over here. I am feeding that a one and a
- 2:37:51one. So I'm going to output a one from
- 2:37:53that andgate. And then over here I have
- 2:37:57a zero and a zero going into this gate.
- 2:38:00So this is going to output a zero, but
- 2:38:02they feed into an orgate. So we're going
- 2:38:04to have a one or zero. And that means
- 2:38:06we're going to output a one. And so that
- 2:38:08means that carry one should be one. And
- 2:38:11this makes sense because we have a one
- 2:38:13up here. And that's carry one. You know,
- 2:38:15this should be carry one and this should
- 2:38:17be carry two.
- 2:38:20So then we bring this one all the way
- 2:38:21around here. And we can do the same
- 2:38:24calculation for this full ladder. So we
- 2:38:29have one exclusive or zero which is a
- 2:38:31one. And then we have
- 2:38:35this one exclusive or one going into S2
- 2:38:39which means we're going to output a zero
- 2:38:41cuz one exclusive or one is zero cuz
- 2:38:43both the inputs are set. And that checks
- 2:38:45out with what we have here. And then we
- 2:38:48come down to this and gate over here and
- 2:38:50we have one and zero which means we
- 2:38:52output a zero. And then this and gate
- 2:38:54down below is one and one which means we
- 2:38:56output a one and then when we or those
- 2:38:59we get a one and this is exactly what we
- 2:39:02see. So this is really interesting. We
- 2:39:06have the two full adders chained
- 2:39:09together and now we're able to do two
- 2:39:12bit addition. We're able to add numbers
- 2:39:14that are two bits in length. But one
- 2:39:16thing you may be noticing is that this
- 2:39:18is pretty ugly to look at. We're having
- 2:39:20a lot of logic gates and it's not
- 2:39:24visually appealing to look at. And I
- 2:39:25kind of hinted at this earlier, but we
- 2:39:27can kind of abstract this away. So
- 2:39:30instead of drawing this ugly circuit
- 2:39:32out, let's find a way that we can just
- 2:39:35represent the full adder as something
- 2:39:37easier. And let's just give it a square.
- 2:39:40Let's just say that if we have a square,
- 2:39:42sorry, a rectangle with full adder FA
- 2:39:46written in it, we just know it means a
- 2:39:48full adder. And what we really need to
- 2:39:49show is the inputs and outputs cuz we
- 2:39:52now understand how the full adder works
- 2:39:53internally. But when we use it to build
- 2:39:55more complicated circuits, we don't
- 2:39:57necessarily need to see all the logic
- 2:39:59gates inside of it. We just need to be
- 2:40:00able to represent what goes into it and
- 2:40:02what comes out of it. And so we know
- 2:40:04that for a full adder the inputs are an
- 2:40:07A, a B and the carry in. And then the
- 2:40:11outputs are a sum bit and a carry out
- 2:40:13bit. And all you need to understand is
- 2:40:17that this full adder I've this this this
- 2:40:19rectangle which I'm claiming to be a
- 2:40:22full adder. If we really wanted to see
- 2:40:24what was inside this rectangle, it would
- 2:40:26be this right here, a full adder.
- 2:40:31So if we assume this diagram to be true,
- 2:40:33and this is something we're allowed to
- 2:40:34do. We're we're building our computer.
- 2:40:36So we don't want to have just logicates
- 2:40:38littered everywhere. What we're going to
- 2:40:40like to do is build out individual
- 2:40:41components of our computer and then
- 2:40:44abstract them away in these rectangles.
- 2:40:46So what I'd like to do now is if you
- 2:40:48understand or at least can believe that
- 2:40:50this is going to be used to represent a
- 2:40:52full adder, let's rebuild the circuit
- 2:40:54that I've drawn up here and show how
- 2:40:56much easier it is. And to do that, all
- 2:40:58we need is another full ladder,
- 2:41:02which I will copy and paste.
- 2:41:08And all we now need to do is update our
- 2:41:10inputs and outputs. So, we know that
- 2:41:12we're feeding in a zero here because we
- 2:41:14don't carry in to our first full ladder.
- 2:41:17And then we know that this is A1 and B1.
- 2:41:19And we know that this output is S1.
- 2:41:22And then we feed this carry over into
- 2:41:26the carry in of the next full ladder.
- 2:41:30And then we're calling this A2 and B2.
- 2:41:33And then from there we get the sum two
- 2:41:35and carry two. And look how much easier
- 2:41:38this is to visualize compared to the
- 2:41:40mess of logic gates we had above.
- 2:41:43So this is pretty interesting. We've now
- 2:41:47learned how to do two bit addition. So
- 2:41:49we started with one bit addition. We've
- 2:41:51done two bit addition, but now I'd go
- 2:41:53ahead and like to show you how our
- 2:41:55computer's going to do addition. And it
- 2:41:57turns out it's nothing new. What I said
- 2:42:00earlier is that our computer is an 8bit
- 2:42:02computer. 8bit computer, CPU, central
- 2:42:06processing unit. And what this means is
- 2:42:09we operate we operate
- 2:42:13on 8bit values.
- 2:42:18And to elaborate on that, every value we
- 2:42:22store in our computer is going to be
- 2:42:24eight binary digits long. Nothing more
- 2:42:27and nothing less. And this makes this
- 2:42:29makes things easier. As you will
- 2:42:31eventually see, if every single
- 2:42:34component of our computer is expecting
- 2:42:37values to come in eight bits, exactly
- 2:42:40eight digits, then we can standardize a
- 2:42:43lot of components of our computer and it
- 2:42:45makes ensures a lot of consistency
- 2:42:47between the different components. And
- 2:42:49this eight, as I also mentioned earlier,
- 2:42:51is just a random number. Modern
- 2:42:53computers can use 32 or 64. And we'll
- 2:42:56we'll we're going to build an 8-bit
- 2:42:57computer. And then we'll eventually talk
- 2:42:58about how we can scale up to 32 or 64.
- 2:43:01And it turns out it's not that
- 2:43:02difficult. But what I'd like to do then
- 2:43:05is build a circuit that adds 8 bit
- 2:43:08numbers. So what would this look like?
- 2:43:11Every input to our circuit is going to
- 2:43:14take in A1 through A8 and then
- 2:43:19A B1 through B8. So now all of our
- 2:43:23operands, we can still we're just
- 2:43:24building a circuit that just adds
- 2:43:26numbers.
- 2:43:27But we're going to go ahead
- 2:43:30and make sure that those numbers are all
- 2:43:33eight bits. They all have eight binary
- 2:43:34digits. And so if you understand what we
- 2:43:37did up here, then it turns out the
- 2:43:39process for eight bits is not any more
- 2:43:41complicated. Instead of two full adders
- 2:43:45for adding two bit numbers, we're just
- 2:43:47going to use eight full adders for
- 2:43:49adding eight bit numbers.
- 2:43:51And this ends up making things look
- 2:43:54pretty easy. So I'll go ahead and give
- 2:43:56the expanded notation just so we have
- 2:43:58something to work with. But in general,
- 2:43:59if we're adding two 8-bit numbers, what
- 2:44:01it looks like in the graphical form that
- 2:44:03you and I are both used to is we'd have
- 2:44:0688 and then our A value has eight
- 2:44:10different bits in it.
- 2:44:17And our B value has eight different bits
- 2:44:19in it.
- 2:44:22And if you are a computer person, you
- 2:44:25may be wondering why through this point
- 2:44:27in the video I've been doing
- 2:44:35one indexing. I've been starting at
- 2:44:37index one and going onwards. Uh even
- 2:44:39though you know that in computer science
- 2:44:42we start at index zero and move onwards.
- 2:44:44And the reason I'm doing this is because
- 2:44:46at the start of this video I said I
- 2:44:47wanted it to be understandable for
- 2:44:48everybody. Even if you didn't have a
- 2:44:50computer science background and to those
- 2:44:54of us who do not have a computer science
- 2:44:55background, it is my belief that
- 2:44:58indexing starting it based on one is
- 2:45:00more intuitive to understand compared to
- 2:45:03indexing based at zero. It's one of the
- 2:45:06things that I mentally had to adjust to
- 2:45:08when I started learning computer
- 2:45:09science. So, I figured it'd be easier if
- 2:45:11I just didn't make the viewer
- 2:45:13additionally bear that burden of having
- 2:45:15to mentally shift everything over by one
- 2:45:17as they watch. So, for those of you who
- 2:45:19do have a computer science background, I
- 2:45:22think it's not too painful for you to
- 2:45:24mentally put the zero indexing away and
- 2:45:26go back to one indexing for this video.
- 2:45:28And for those of you who have no
- 2:45:30computer science background, you don't
- 2:45:31even understand what I'm talking about.
- 2:45:33And this is intuitively how you would
- 2:45:36represent things to begin with. [snorts]
- 2:45:38Cool. So, these are our two operands.
- 2:45:41We're just looking at addition. And for
- 2:45:43now, we are assuming that they are
- 2:45:45positive numbers. We will after we build
- 2:45:48an addition, we will come back and look
- 2:45:49at subtraction and and negative numbers.
- 2:45:52But we would expect then you when we're
- 2:45:54doing this addition, you'd start with
- 2:45:55the A1 and B1. You get a sum one and
- 2:45:58then you get a carry one. And then you
- 2:46:01would add those A2 B2 and the carry one
- 2:46:04together and you get a sum two and a
- 2:46:06carry two. And then you'd add A3 V3 and
- 2:46:10the previous carryover and you would get
- 2:46:12sum three and carry three. And this
- 2:46:15process would repeat
- 2:46:31and then the one interesting is the very
- 2:46:33last addition. We take the carry 8 and
- 2:46:38if it exists or not we bring it down. So
- 2:46:42this is the the addition we have and
- 2:46:46all we need to do is chain eight of
- 2:46:49these full adders together. So I will
- 2:46:53start by drawing that out. And this is
- 2:46:55not going to be a pretty drawing because
- 2:46:56I don't have good handwriting. So I am
- 2:46:58just going to go silent for a minute as
- 2:47:00I draw this out because I find that the
- 2:47:01more I try talk while drawing the more
- 2:47:04errors I make.
- 2:47:11So, we start with a full ladder and
- 2:47:14we're going to feed in A1
- 2:47:17and B1. And then we actually feed in
- 2:47:20this hard-coded zero for the carry-in.
- 2:47:23And then we will take a another full
- 2:47:25adder.
- 2:47:28And I probably drew that a little too
- 2:47:30close together.
- 2:47:32And from the output of this one, we get
- 2:47:37I'm going to bring this down here just
- 2:47:40so it's easier to read. We get the sum
- 2:47:43one and then the carry one is going to
- 2:47:47come over here.
- 2:47:49And
- 2:47:51for this one, we will feed in A2 and B2.
- 2:47:58And this is still a full adder. and we
- 2:48:01get sum two coming out
- 2:48:06and then we're gonna have the out the
- 2:48:08carryover feed into the next full adder.
- 2:48:10So then we have another full adder
- 2:48:14and we're going to feed into here A3 and
- 2:48:18B3
- 2:48:21and don't forget about the carry out
- 2:48:25that's going to come in. And then from
- 2:48:27here we get sum three.
- 2:48:32And I'm going to move this over before I
- 2:48:34run out of room.
- 2:48:38And then
- 2:48:40what we're going to do is we're going to
- 2:48:41have another full ladder.
- 2:48:47And that's going to take in A4
- 2:48:52and B4
- 2:48:54and the carry out from the previous
- 2:48:57adder.
- 2:48:59And then we're going to have the sum for
- 2:49:03and the carry for. Then we have another
- 2:49:05full adder.
- 2:49:10We feed into this one A5 and B5.
- 2:49:16And then we also feed in the carry out
- 2:49:20from the previous full adder. And we now
- 2:49:24get sum five in the next carry out.
- 2:49:28And then we will have another full
- 2:49:30adder.
- 2:49:31I know this is getting repetitive and
- 2:49:33that's because it it is. We've designed
- 2:49:34this so that we don't have to build out
- 2:49:36this massive circuit that handles every
- 2:49:38possible value of the two combinations
- 2:49:41of 8bit inputs. We've built this
- 2:49:44something simple circuit, this full
- 2:49:45adder that lets us reuse everything. And
- 2:49:49once again, we feed in A6 and B6.
- 2:49:53And then we also take the carryover from
- 2:49:56the last one.
- 2:49:58And
- 2:50:00from here, we output S6.
- 2:50:04And we are getting so close.
- 2:50:08We have a full adder.
- 2:50:11We get an A7 and B7
- 2:50:15and the carryover from this last one
- 2:50:21and we get S7. And now we have our last
- 2:50:24full adder
- 2:50:27where we take in A8 and
- 2:50:32B8.
- 2:50:35we get this S8.
- 2:50:37And then we're also going to get this
- 2:50:41carryover from eight. And the last thing
- 2:50:44we need to do is make sure that we chain
- 2:50:46this carry in. Cool.
- 2:50:50And I'm not even actually allowed to
- 2:50:51zoom out that far on my my iPad without
- 2:50:54it complaining. So I'm going to hold it
- 2:50:57here and let's look at what we have.
- 2:51:00We've now built a circuit where we can
- 2:51:02put in any two 8digit values into our
- 2:51:07input lines and we'd be able to output
- 2:51:09their sum. And I'm not going to work
- 2:51:12through an example because I'd probably
- 2:51:14take me just as long as the entire video
- 2:51:16up till now to look at each of the logic
- 2:51:18gates for each of these full address.
- 2:51:20But you should be able to convince
- 2:51:22yourself this is true. And this is
- 2:51:24something that's really novel. We've
- 2:51:25built something simple and we've chained
- 2:51:28it together to build something more
- 2:51:29complicated.
- 2:51:31And this is a fundamental principle of
- 2:51:33computer science. It's called
- 2:51:34abstraction. We've built the circuit
- 2:51:37that's a full adder and we then we've
- 2:51:39abstracted away by just drawing it as a
- 2:51:41rectangle and then we're building
- 2:51:43something on top of it. And that
- 2:51:45abstraction actually lets us lets us add
- 2:51:48uh 8 bit numbers. So we've we've taken
- 2:51:51these logic gates which on their own are
- 2:51:54pretty trivial and have now forced them
- 2:51:57in arranged them is probably a better
- 2:51:59word should I say we've arranged them in
- 2:52:01such a way that the logic gates do
- 2:52:03something useful to us and you may be
- 2:52:07wondering this is this is cool and all
- 2:52:08but how does this actually happen in the
- 2:52:10real world? Well, I mentioned this
- 2:52:12earlier, but uh all of these lines I'm
- 2:52:15drawing, you can actually think of them
- 2:52:17as wires. And the fundamental property
- 2:52:20you need to understand of wires is that
- 2:52:22they conduct very fast. So if I have a
- 2:52:25long wire,
- 2:52:29assume there's no electricity on it. If
- 2:52:32I put electricity on it on this end,
- 2:52:35then we will say almost instantly this
- 2:52:38is a big asterisk
- 2:52:41the electricity will appear on this side
- 2:52:43because wires conduct electricity.
- 2:52:47And we're saying almost because nothing
- 2:52:49in this world is immediate. And there
- 2:52:51actually is a little bit of delay
- 2:52:53between when we put electricity on a
- 2:52:55wire and when it's received on the other
- 2:52:57end, you know, cuz electrons actually
- 2:52:59have to move across the wire.
- 2:53:04So what you can actually believe in and
- 2:53:06and kind of use to understand this is
- 2:53:08that all the lines I've drawn in these
- 2:53:11above diagrams and up until now are
- 2:53:13physical wires.
- 2:53:15And this is not an exaggeration. This is
- 2:53:17this is the truth. And if I I also said
- 2:53:22that we can build these logic gates
- 2:53:23physically. You can buy these little
- 2:53:24chips that have them built in. And so
- 2:53:27one such chip has it looks like this.
- 2:53:32And it has many inputs and many outputs.
- 2:53:37But I could then put electricity on this
- 2:53:41line and this line this line and
- 2:53:45I by electricity I mean I'd either put
- 2:53:47electricity or not put electricity. This
- 2:53:50is a high level. Again there's a little
- 2:53:52bit different in the in the world of
- 2:53:53physics but this is how we will
- 2:53:54understand it and how I think it's all
- 2:53:56you need to understand it as. And if I
- 2:53:59put electricity on the wire we say that
- 2:54:01it's a one. There is a truth truthful
- 2:54:04value on the wire a one. And if there's
- 2:54:06no electricity, we interpret that value
- 2:54:08to be a zero. So then this chip that
- 2:54:11that does exist internally does
- 2:54:13something. It somehow manipulates the
- 2:54:16electricity in the real world to
- 2:54:17function like a logic gate to this
- 2:54:19output. And I have this chip. And so if
- 2:54:23I genuinely put electricity on this wire
- 2:54:27and didn't put electricity on this wire,
- 2:54:29then there would be no electricity on
- 2:54:31this output wire. And then if I did put
- 2:54:34electricity on both the input wires,
- 2:54:36then there would be electricity on the
- 2:54:38output wire. And we're not going to
- 2:54:40study how this works in the real world.
- 2:54:43We're not going to study how you can
- 2:54:44build these logicates.
- 2:54:46But it is it is really possible. And
- 2:54:49it's it turns out it's not too difficult
- 2:54:50to actually build them. And there's a
- 2:54:53lot of resources online which uh I'd be
- 2:54:55happy to link if if someone requests.
- 2:54:59But what we do want to understand for
- 2:55:01the sake of this video is that when I'm
- 2:55:03drawing these lines, they're actually
- 2:55:04wires. I'm I'm drawing something out
- 2:55:07that could really exist in the real
- 2:55:08world. And these lines are wires. And
- 2:55:11when I say put a one or put a zero on a
- 2:55:14on on a line or comes in or out of a
- 2:55:17logic gate, I'm really saying we either
- 2:55:19have electricity or don't have
- 2:55:20electricity. But but thinking about it
- 2:55:23at the level of ones and zeros is
- 2:55:25certainly easier than thinking about it
- 2:55:27at the level of electricity or no
- 2:55:30electricity. Electrons or no electrons.
- 2:55:33So I'm going to stick to this
- 2:55:34understanding where I say zeros and
- 2:55:36ones. But really you should understand
- 2:55:38that this is actually something that
- 2:55:40could exist in the real world and uh
- 2:55:43something we we'll talk about more more
- 2:55:45later on down the line.
- 2:55:52Okay, so we've now built an 8bit adder.
- 2:55:55We built an 8bit adder,
- 2:56:00but there's an issue here, and I I've
- 2:56:01mentioned it a few times.
- 2:56:05How does subtraction work?
- 2:56:10And
- 2:56:12it may seem to you like we will need to
- 2:56:15destroy what we have and rebuild the
- 2:56:19entire computer or the entire adding
- 2:56:22logic circuit. But it turns out another
- 2:56:25really interesting takeaway uh at least
- 2:56:28what I would call interesting is that we
- 2:56:30are actually 95% of the way there with
- 2:56:32what we have up top to being able to do
- 2:56:34subtraction.
- 2:56:36And the reason is is remember what we
- 2:56:39said earlier. We said that if we wanted
- 2:56:41to do a minus b, it is really the
- 2:56:45equivalent of doing a +
- 2:56:48b. And so we know this circuit can do a
- 2:56:52plus negative b. But the issue is we we
- 2:56:55have b feed being fed in as all of our
- 2:56:58inputs. We don't have negative b.
- 2:57:02And how then if we have all these B
- 2:57:04inputs, can we actually make them
- 2:57:08negative B? So what I'm going to do here
- 2:57:10is pause this video and redraw this
- 2:57:13circuit in a slightly more optimal and
- 2:57:16more condensed way and at least in a way
- 2:57:18that I can I can show everything on my
- 2:57:20screen at once and then we will I will
- 2:57:23uh cut back and we can pick up and
- 2:57:24answer this question. Okay, so I have
- 2:57:29drawn this in and let me go ahead
- 2:57:31[clears throat] and erase these bars on
- 2:57:32the side. And let's do a little recap of
- 2:57:35what I have here. And you've also
- 2:57:36noticed that for about the first time in
- 2:57:39this video, I've decided to use
- 2:57:40something besides the color white. So
- 2:57:42you're welcome. And
- 2:57:45basically, I wanted to color code things
- 2:57:47because we have a lot going on here. And
- 2:57:49I'd also before I even start to explain
- 2:57:51this would like to appreciate or hope
- 2:57:53that you can appreciate how much less
- 2:57:56painful this is now that we've
- 2:57:58abstracted these logic gates out of the
- 2:58:00way. And it's still pretty messy. So we
- 2:58:02we can do more eventually. We'll
- 2:58:04abstract this entire thing. But um as we
- 2:58:08have it right now, there's this is this
- 2:58:09is fairly reasonable to look at. And
- 2:58:12hopefully with the color coding and the
- 2:58:13explanation I'll give in the next few
- 2:58:14minutes, we can make sense of this.
- 2:58:16[snorts]
- 2:58:17So, what I have up top are our eight A
- 2:58:20inputs and our eight B inputs. And I'm
- 2:58:24drawing these little circles because uh
- 2:58:26you'll you'll see this notation if you
- 2:58:27ever end up watching some other videos
- 2:58:30where uh this this represents an input
- 2:58:32almost. And we can either put in a zero
- 2:58:36or a one to that input. And it's just a
- 2:58:38notation. And I personally think it's a
- 2:58:41reasonable notation. And if we were to
- 2:58:43do this in the real world, then this
- 2:58:45circle would probably just be some
- 2:58:47source of electricity or not. And you
- 2:58:49know, we we'd connect electricity there
- 2:58:51and go through that wire into the
- 2:58:53corresponding full ladder. [snorts]
- 2:58:55But I have all the A inputs highlighted
- 2:58:58in red and or orange if if that is
- 2:59:01orange to you. And I'm actually not sure
- 2:59:03what it is to me. I I'll stick with the
- 2:59:05orange. So I have all the orange
- 2:59:06connected to all the A's and those go
- 2:59:09into the A lines of the full adder. And
- 2:59:12it doesn't really matter if we we
- 2:59:13commute A or B for the full ladder. It
- 2:59:15doesn't really make a difference because
- 2:59:16A plus B is the same as B plus A.
- 2:59:20But more interestingly,
- 2:59:22I have or equal equally interesting. I
- 2:59:25guess there's not really anything more
- 2:59:26remarkable about it. I have all the B's
- 2:59:29in blue going into the B inputs of each
- 2:59:32of these eight full adders.
- 2:59:34And then I have in gray here the carry
- 2:59:39out from each outer adder going into the
- 2:59:43carry in of the next adder. And the one
- 2:59:46exception to that is the very last carry
- 2:59:49out from the very last full adder. And
- 2:59:52that comes down here. And so uh the
- 2:59:55greens are the sum bits of each of the
- 2:59:58full adders.
- 3:00:00And sorry I don't know if I was just
- 3:00:03saying half adder. I meant to be saying
- 3:00:04full ladder. If I was, I apologize. And
- 3:00:07the we know that the carry out from the
- 3:00:09last full ladder is special because it
- 3:00:12it is not just carry out, but it's part
- 3:00:14of the the output of our sum. Whereas
- 3:00:17all the other previous carry outs, we we
- 3:00:19need them to do the computation, but we
- 3:00:21don't really care what they are. We just
- 3:00:23care what the result is. And that last
- 3:00:25carry out is is technically part of the
- 3:00:27result.
- 3:00:28And the only other interesting thing is
- 3:00:32this this over here where I have this
- 3:00:35carry into the very first full ladder.
- 3:00:37And we said that's just going to be a
- 3:00:39zero. So I kind of written this zero in
- 3:00:40quotations.
- 3:00:43And uh I I've I've given it some special
- 3:00:45attention. That's because we're going to
- 3:00:47see that it it may not actually always
- 3:00:49be the case that we want it to be zero.
- 3:00:51And I also wrote S9 in quotes down here
- 3:00:55because it's it's really equal to the
- 3:00:57carry out of the eighth full adder. So
- 3:00:59we could say carry 8, but I wanted to
- 3:01:03make it apparent now that you know even
- 3:01:05though this is the carry out when we use
- 3:01:07it, it actually does become part of the
- 3:01:10product, the result of the sum.
- 3:01:13And so I think it it makes sense to
- 3:01:14treat it like the rest of the result
- 3:01:16bits. But I I'll leave it in quotations
- 3:01:18from this diagram for now so you can
- 3:01:20understand that is it is a little bit
- 3:01:22different than the rest and where it
- 3:01:23comes from. But when it comes to
- 3:01:25interpreting the output, it's the same.
- 3:01:27So now you can see we have this circuit
- 3:01:29where we could put in our A values and
- 3:01:31then our B values and then we'd be able
- 3:01:33to read the output right here. And you
- 3:01:35could understand all the logic gates if
- 3:01:36you really wanted to. You could take
- 3:01:38this yourself and draw out all the logic
- 3:01:40gates, but that's that's not necessary
- 3:01:42for what we have going on right here.
- 3:01:44Now, what we really said that we wanted
- 3:01:46to do was figure out how to do this
- 3:01:48subtraction with the our circuit that we
- 3:01:50have here. And we know that this circuit
- 3:01:53can do a plus b. And the issue is we
- 3:01:56want to do a minus b. And how could we
- 3:01:59do that? Well, I I invoked the rule that
- 3:02:01we learned at the start of this video,
- 3:02:03which was a minus b is equal to a +
- 3:02:07negative b.
- 3:02:09So, what we really want to be able to do
- 3:02:11here is
- 3:02:13take the inputs. We'd like to have the
- 3:02:14same circuit. We'd like to be able to
- 3:02:16use the same circuit for addition and
- 3:02:18subtraction and have a way of telling it
- 3:02:20when we're adding and when we're
- 3:02:21subtracting. And when we're subtracting,
- 3:02:24we don't want to feed the B's. We want
- 3:02:26to put our our B input up here, but we
- 3:02:28don't want these wires just to feed
- 3:02:30directly into these gates cuz we want
- 3:02:32negative B to feed into each of these
- 3:02:34adders.
- 3:02:36And so, let's think about how we can
- 3:02:38accomplish that. And I'm going to write
- 3:02:40down what we learned earlier. Given B or
- 3:02:44given A or B or C any variable
- 3:02:48to get negative B
- 3:02:52what do we do? We do we invert every bit
- 3:02:56in B. So invert
- 3:03:00the bits [snorts] bit meaning just a
- 3:03:02digit position
- 3:03:05in B. And more formally put,
- 3:03:09let ones become zeros
- 3:03:13and let zeros become one.
- 3:03:18And once we do that, there's one other
- 3:03:20thing we have to do. If you remember,
- 3:03:22that's what we have to add one to the
- 3:03:23result. So add one to the result.
- 3:03:30And that's that's decimal one or binary
- 3:03:33one. They're equivalent. whatever one
- 3:03:35you want to conceptualize. Um, and so if
- 3:03:39we had
- 3:03:40if we had this number one zero one1 and
- 3:03:44we wanted to negate it, then we do 0 1 0
- 3:03:510. So that's our step one. Then we add
- 3:03:54one to that for step two. So we do 0 1 0
- 3:03:570 plus 0 0 1. And we're left with this
- 3:04:00result right here.
- 3:04:02And you might be wondering something
- 3:04:04very valid and that's I said up until
- 3:04:07this point we we've been building these
- 3:04:09full adders that only work on positive
- 3:04:12numbers.
- 3:04:14And that's true but it actually works
- 3:04:16out with negative numbers as well.
- 3:04:19And this is true because I very earlier
- 3:04:23in the video I showed you how to do
- 3:04:25addition and subtraction in binary. And
- 3:04:28we learned that addition for negative
- 3:04:30numbers is the same as positive numbers
- 3:04:33for two's complement representation. And
- 3:04:36subtraction also works out as long as we
- 3:04:38can just negate the number. So this
- 3:04:40circuit, we've only been using it with
- 3:04:42positive numbers, but it turns out we
- 3:04:44can use it to add negative numbers as
- 3:04:46well.
- 3:04:47And
- 3:04:49>> so now we're going to learn how we can
- 3:04:54now that I've kind of I kind of shaken
- 3:04:55that up a little bit because I've been
- 3:04:56ignoring all these negative numbers, but
- 3:04:58it is the case that this works with that
- 3:05:00that it does work with negative numbers.
- 3:05:02You could actually plug in an example
- 3:05:04maybe maybe not on the 8 bit one, but on
- 3:05:06our our two bit example, our two-bit
- 3:05:09adder when we just had two full adders
- 3:05:11trained together and and see that it
- 3:05:12actually does work out. And what we're
- 3:05:15interested in though, back to the topic,
- 3:05:17is how can we do subtraction? And so we
- 3:05:20have B and we want to get negative B. So
- 3:05:22what we really saw is we could take all
- 3:05:25of the bits from B for step one and just
- 3:05:29flip them. And how do we do that here?
- 3:05:33And what we can recall is that we
- 3:05:35actually have a logicate that does
- 3:05:37exactly this. And it's our good old
- 3:05:39inverter. The inverter
- 3:05:43looks like this. And if you feed it in a
- 3:05:45zero, you're going to get a one. And if
- 3:05:46you feed it in a one, you're going to
- 3:05:48get a zero. And
- 3:05:51oops, let me erase that.
- 3:05:54This is exactly what we'd like. So to
- 3:05:57accomplish the first step, what we can
- 3:05:58really do is is have our inputs of B and
- 3:06:01just feed each of them through an
- 3:06:03inverter whenever we want to subtract.
- 3:06:06That's the issue. We we want to be able
- 3:06:08to distinguish when we're adding and
- 3:06:10subtracting. But let's just assume that
- 3:06:12we're just going to use this for
- 3:06:13subtracting. So we'd we'd end up
- 3:06:16inverting all of these. And so I guess
- 3:06:19I'll just draw an arrow and I do some uh
- 3:06:23some sort of demarcation that we'd
- 3:06:25invert. And that handles the first step.
- 3:06:29And then the second step is adding a one
- 3:06:32to the result. And now let's think about
- 3:06:35this because this is this is a little
- 3:06:36bit weirder. And
- 3:06:40how could we do this with the paradigm
- 3:06:42that we have up here? Uh this is a good
- 3:06:44good challenge question. And it turns
- 3:06:47out to add one, we could just feed in a
- 3:06:50carry-in of one to the very first
- 3:06:52addition because we know that when we
- 3:06:55have uh for some digit position when
- 3:06:57we're doing addition, if we have a to
- 3:07:00the x and then b to the x position, then
- 3:07:03we also take in a carry in at the x
- 3:07:06position and we output a sum at the x
- 3:07:09position and a carry out at the x
- 3:07:12position. And this carry in effectively
- 3:07:15just adds another value to our step. And
- 3:07:19what we've been saying so far, if we
- 3:07:21come back up here, is that when we're
- 3:07:24doing these 8bit addition, then we
- 3:07:27actually are sure that we're never going
- 3:07:30to have a carry in the first time
- 3:07:31because we have nothing else to carry in
- 3:07:33from. But if we actually just set a
- 3:07:35carry-in to be one, then we're
- 3:07:37effectively adding one to our overall
- 3:07:39result. And so this actually works out
- 3:07:42perfectly. And so you might be
- 3:07:44wondering, well, this this adds one to
- 3:07:47our result, but we're trying to just add
- 3:07:49one to B. But doing those are
- 3:07:51synonymous. If I do um if I do a plus a
- 3:07:56+ b, so if I have all these a's and then
- 3:08:00I have all these b's, but I want to do
- 3:08:03neg a minus b, then I first off, I
- 3:08:06invert all of these. And I'm just using
- 3:08:09this bar up top. Uh this this this
- 3:08:11notation of of this bar on top of B just
- 3:08:15means the opposite of B. Um
- 3:08:20and if we just throw a one up here, then
- 3:08:22this is the same thing as doing and now
- 3:08:26this becomes addition. A a a plus
- 3:08:30[snorts] and then we could have done uh
- 3:08:33bb
- 3:08:36the negated version plus a one. So if we
- 3:08:39did that sum and then this outer sum,
- 3:08:43then it's the same as just just doing it
- 3:08:45all at once because a plus we're
- 3:08:48effectively saying here that a + b + 1
- 3:08:52is just the same thing as a + b + 1,
- 3:08:57which could just be however order you
- 3:08:59want to permute it because addition has
- 3:09:01this this commutive property you learned
- 3:09:03about when you when you were way
- 3:09:04younger.
- 3:09:06And this is a really powerful result.
- 3:09:09This lets us mean that when we want to
- 3:09:12do subtraction, we could just set this
- 3:09:14carry in which we know is going to be a
- 3:09:16zero for addition to be a one and it
- 3:09:18adds one to our result. And so we found
- 3:09:22a way effectively using our circuit of
- 3:09:26full adders that we originally designed
- 3:09:28for addition to be able to do
- 3:09:29subtraction. And when we want to do
- 3:09:31subtraction, we're going to do instead
- 3:09:33of a minus b, we're going to do a plus
- 3:09:35negative b. And we have b's as the input
- 3:09:39over here. And to make it negative b,
- 3:09:41we're going to take the two-step
- 3:09:42process. The first of which is inverting
- 3:09:44all of b's bits from ones to zeros or
- 3:09:46zeros to one. And the second step is
- 3:09:49adding a one to the result. And we can
- 3:09:51do both of that with the circuit we
- 3:09:53already have minus a few additions of
- 3:09:55inverters.
- 3:09:57So what we're going to go ahead and do
- 3:10:00now is there's one final step and that's
- 3:10:02that we need to distinguish when we're
- 3:10:04adding or subtracting because when we're
- 3:10:07adding we don't want we don't want these
- 3:10:10values to be inverted
- 3:10:13and when we are adding we also want this
- 3:10:16carry-in to be a zero but when we're
- 3:10:19subtracting we want the carry-in to be a
- 3:10:21one and when we're subtracting we want
- 3:10:23all of B's bits to be inverted.
- 3:10:26So, how can we actually do that? And
- 3:10:28what we're going to do is add another
- 3:10:31input to our circuit. And that's just
- 3:10:33going to be the addition subtraction
- 3:10:35flag. So, I'll make this a circle for
- 3:10:36consistency. And I'll just write this is
- 3:10:40a slash s. And what I'll say is that if
- 3:10:43if this is zero, so if zero, then
- 3:10:48addition, and if one, then we'll do
- 3:10:51subtraction. That's just how we're
- 3:10:53designing this. And then we'll be sure
- 3:10:55for the rest of this of this uh to make
- 3:10:58sure that we adhere to that
- 3:10:59consistently.
- 3:11:01And
- 3:11:02then what we want to do is how do we
- 3:11:04deal with well this this first part's
- 3:11:06easy for the inverting the adding the
- 3:11:09one. It's easy. It's just the value of
- 3:11:12this because if we are adding then we
- 3:11:14want no carry into the first full adder.
- 3:11:17And if we're subtracting, we want to
- 3:11:18carry into the first full adder so that
- 3:11:20we have the effect of one, the effective
- 3:11:23addition of one that we needed for the
- 3:11:24binary conversion. But this this
- 3:11:27inverting part is a little difficult. If
- 3:11:29we have this line
- 3:11:31and we have a value, let's just look at
- 3:11:34B1, then how can we use both of those to
- 3:11:37get the right B1 that should go into the
- 3:11:40gate or the right, I guess, uh, modified
- 3:11:44B1 or not that should go into the gate.
- 3:11:46And so what we really have is
- 3:11:50if as is set so if as equals 1 then let
- 3:11:56b then we want to invert so we should
- 3:11:59invert b1
- 3:12:03and if as is zero meaning we want to add
- 3:12:07then we leave b1 alone
- 3:12:10and how can we do this? Well, a a simple
- 3:12:14simple gate. We can do one gate and
- 3:12:16that's the exclusive orgate. And let's
- 3:12:20see what that looks like. So if we feed
- 3:12:22in B1 here and then this AS line, then
- 3:12:27let's look at happens for each of the
- 3:12:28input cases. So if as is one, then we
- 3:12:32want to invert B1. So if B1 is zero,
- 3:12:35then we would we would hope to get a one
- 3:12:37out and one exclusive or zero is one. So
- 3:12:40that is correct. And similarly, if B1 is
- 3:12:43is is one, we'd hope to get a zero out.
- 3:12:46And one exclusive or one is a zero. So
- 3:12:49So this works.
- 3:12:52And then if as is zero, we would want B1
- 3:12:56to to come out exactly as it is. So if
- 3:12:59as is zero, if B1 is zero, then zero
- 3:13:02exclusive or zero is zero. So that
- 3:13:05flowed through. And if it's one, then we
- 3:13:08know one exclusive or zero is one. And
- 3:13:11so that is exactly how this behaves. And
- 3:13:14if you have a little bit of trouble
- 3:13:16conceptualizing that, go back earlier to
- 3:13:18when we looked at the truth table for
- 3:13:20the exclusive orgate or you can just
- 3:13:22Google it now. But this is just a
- 3:13:24property of the gate and it it works out
- 3:13:26very conveniently that we can use it for
- 3:13:28this this task that we have right here.
- 3:13:30And then it turns out this is uh we were
- 3:13:33looking just at B1, but we can do this
- 3:13:35for each of the B's.
- 3:13:37And that's exactly what we'll do. We
- 3:13:40will have an exclusive or gate for each
- 3:13:42of these B's and we will exclusive or
- 3:13:47the corresponding B with the same AS
- 3:13:50line that we have up here. So I for the
- 3:13:53sake of drawing am going to pause and
- 3:13:56update this diagram to have that in
- 3:13:58there. Okay. So I've updated the diagram
- 3:14:02now and I was running out of color. So I
- 3:14:04have this lightish purple and basically
- 3:14:08all that changed in the past millisecond
- 3:14:10is I have exclusive ored each of the B
- 3:14:16gates with the value from this as line
- 3:14:20this addition subtraction line before
- 3:14:23feeding it into the B input of the full
- 3:14:25adders. And so what this means now is
- 3:14:29that if we want to add, we load in our
- 3:14:31values to A, load in our values to B,
- 3:14:34and then we can look and get the result
- 3:14:36on the S lines down below. And if we
- 3:14:40would like to subtract, we do the same
- 3:14:42thing. We put in the A, we put in the B,
- 3:14:47and then we set this AS line to be one.
- 3:14:51So whenever this as line is zero, it's
- 3:14:54just going to add this circuit is just
- 3:14:56going to add whatever is on the input
- 3:14:57lines. Even if we don't have any
- 3:14:59meaningful value, it's it's a circuit.
- 3:15:01The logic gates are going to do what
- 3:15:02they do. And we're going to get some
- 3:15:04output that we can read on these S
- 3:15:05lines. And if we set this S line, this
- 3:15:08AS line to one, then it's going to
- 3:15:11subtract whatever values happen to be on
- 3:15:13the A line and the B line and come into
- 3:15:17this S line as the output.
- 3:15:20And
- 3:15:22so this is the extent of difficulty
- 3:15:24we're going to need for this video. And
- 3:15:28computers can do uh multiplication and
- 3:15:30division, but it's a bit more tedious
- 3:15:33and involved of a process. And I don't
- 3:15:36think there's as much not to say there's
- 3:15:38not benefit, but I think this suffices
- 3:15:42for understanding the rest of the
- 3:15:44fundamental concepts of computing.
- 3:15:47So there is no plan for me to show how
- 3:15:50subtraction or multiplication division
- 3:15:52work but there is plenty of resources
- 3:15:54online that you can feel free to look up
- 3:15:57if you are curious about it. It is uh
- 3:16:00interesting because we then have to
- 3:16:02without going into too much detail you
- 3:16:04have to update how you represent
- 3:16:05numbers. For instance, we can only
- 3:16:07represent whole numbers. But if I
- 3:16:09divided seven by two, the output's 3.5.
- 3:16:13But we have no way in binary b up till
- 3:16:16now what I've taught you of representing
- 3:16:18this.5. And so you kind of have to go
- 3:16:20back and and revisit your representation
- 3:16:23of numbers. But we're going to stick
- 3:16:24with this two's complement. And so now
- 3:16:27we're back and we have this we have this
- 3:16:31circuit that can add. But there's a
- 3:16:32little bit of an issue. And it I think
- 3:16:34I've kind of made it not super clear
- 3:16:36until this point until I was working
- 3:16:38through, but that is these are logic
- 3:16:41gates. And so they're always just going
- 3:16:43to operate based on whatever the inputs
- 3:16:44are. So if we don't really have any
- 3:16:48meaningful values on these A lines or B
- 3:16:50lines, there's still going to be some
- 3:16:52value in the S line. But that what that
- 3:16:54also means is if we did want to add two
- 3:16:56numbers and we put them in the A lines
- 3:16:58and B lines, then the output's going to
- 3:17:00correctly come out on these S lines down
- 3:17:03below, but as soon as we change any of
- 3:17:06these inputs, the output may or may not
- 3:17:08change. And that's that's that's
- 3:17:11actually problematic. Uh we'd like to be
- 3:17:13able to to save the result. And
- 3:17:17let's say I'd like to to add two
- 3:17:19numbers, put them I put them on the A
- 3:17:21lines and B lines and I get the result.
- 3:17:23And then let's say I want to take that
- 3:17:24result and and add it to something else.
- 3:17:27Then right now there's not really a
- 3:17:29clear way of me doing that. And that's
- 3:17:31kind of as we're going to get into the
- 3:17:33more uh different components of
- 3:17:35computers and how we can actually make
- 3:17:38this this this adder and subtractor do
- 3:17:41meaningful work rather than us having to
- 3:17:44manually put electricity or at our level
- 3:17:47put zeros and ones onto each of these
- 3:17:49input lines. And what we've built right
- 3:17:52here is 95. Again, we're not fully done.
- 3:17:55We're actually going to revisit this one
- 3:17:57more time, but it's not going to be to
- 3:17:59add anything too more complicated. But
- 3:18:02what we've built right here is called
- 3:18:04the ALU. Stands for the arithmetic logic
- 3:18:07unit. And every computer has one of
- 3:18:10these. Uh the computer you're watching
- 3:18:12this on has one. And it's responsible
- 3:18:13for doing doing the arithmetic. And I
- 3:18:17mentioned this earlier, but computers
- 3:18:18are effectively glorified calculators.
- 3:18:22So, this is actually probably the uh
- 3:18:24heart of most modern computers. And
- 3:18:26obviously, your computers are
- 3:18:28implemented in ways that make these run
- 3:18:31incredibly fast and uh can do a lot more
- 3:18:34than what I've shown uh more than just
- 3:18:36the addition of subtraction. But this is
- 3:18:38just to illustrate the concept. And what
- 3:18:41we'd like to do, as I' I've kind of
- 3:18:42hinted now, is be able to take the
- 3:18:45result of an addition or subtraction we
- 3:18:47do on this circuit and save it.
- 3:18:50But we know with these logic gates that
- 3:18:52the moment we change one of their
- 3:18:53inputs, the output may or may not change
- 3:18:56depending on what the gate is. But in
- 3:18:58general, it's it's safe to assume that
- 3:19:00once you change the input to a logic
- 3:19:02gate or a circuit, if you change any of
- 3:19:04the inputs, it's not necessarily going
- 3:19:06to be the case that the output stays the
- 3:19:07same. So, if I have these A lines set to
- 3:19:10some value and I have these B lines set
- 3:19:12to some value, I would need to in the
- 3:19:15real world wait a small amount of time
- 3:19:17for these logic gates to do their work
- 3:19:19and settle. And then that's something
- 3:19:22we'll talk about more later. But then
- 3:19:24once we we give it some time to settle
- 3:19:26and it do all the electricity flows
- 3:19:28through and everything, we we'd like to
- 3:19:30be able to take this output and save it.
- 3:19:32And this is a what I mentioned earlier
- 3:19:36in the video at the very start. This is
- 3:19:38going to be the second hardest concept
- 3:19:39we taught in the video. The first most
- 3:19:42difficult I in my opinion was learning
- 3:19:44binary which you made it past and this
- 3:19:46is the fullest you'll learn binary. But
- 3:19:49the second concept is how can we save
- 3:19:51numbers with logic gates. And so I'm
- 3:19:54going to scroll down because this is
- 3:19:55going to be a new segment of the video.
- 3:19:58So everything we've looked at so far had
- 3:20:00this property that I talked about
- 3:20:01earlier called determinism
- 3:20:06determinism.
- 3:20:09And what this meant is that the output
- 3:20:12of a circuit dependent strictly on the
- 3:20:15input values. And this is not really
- 3:20:17that complicated or it probably sounds a
- 3:20:20little bit obvious to you because
- 3:20:21obviously these outputs just determine
- 3:20:23on the inputs because they all chain
- 3:20:24into each other. But let me give you a
- 3:20:27circuit that actually breaks that
- 3:20:29principle. And it's something we haven't
- 3:20:31seen before. But uh what happens if I
- 3:20:34take this simple orgate? So this is the
- 3:20:36orgate. And I have some input. Let's
- 3:20:39just call this X.
- 3:20:41And let's take the output of this orgate
- 3:20:44and actually feed it back in as the
- 3:20:46other input. And this is really weird.
- 3:20:49We haven't seen this before. We've seen
- 3:20:51the output of logic gates go into the
- 3:20:53input of other logic gates, but we
- 3:20:56haven't seen the output of a logic gate
- 3:20:58come back into itself. And this is going
- 3:21:01to break this idea of determinism
- 3:21:03because let's assume that when I turn
- 3:21:07this on, I have a zero on this line. And
- 3:21:09then let's assume that there's a zero
- 3:21:11coming out. So I have zeros all around.
- 3:21:14So I have if I make this input output,
- 3:21:17if I make a truth table, actually that's
- 3:21:18what we'd like to do.
- 3:21:20So let's call this this input X and this
- 3:21:23output Y. Then I've shown right here
- 3:21:26that we could have a zero for X and that
- 3:21:28we have a one for Y. But now let's look
- 3:21:31at what happens if we set this X to be a
- 3:21:35one.
- 3:21:36So if I set X to be a one, then we have
- 3:21:40the inputs 0 and one feeding into an O
- 3:21:42orgate. And an O orgate turns on as long
- 3:21:44as either of the inputs is one. So then
- 3:21:46the output of this orgate becomes a one
- 3:21:49and something else happens at the same
- 3:21:52exact time is this output becomes a one
- 3:21:54but it's also the input to this orgate
- 3:21:56which means it's this input is now
- 3:21:58effectively a one as well and what this
- 3:22:02means is that this this orgate is now
- 3:22:06forever going to output a one because we
- 3:22:10have it outputting a one now which means
- 3:22:12it's inputting a one on this top line
- 3:22:14and that means that it's guaranteed to
- 3:22:16be getting in a one forever. And what I
- 3:22:19mean by that is you convince yourself
- 3:22:20this is true by changing this input x
- 3:22:23back to zero. And if I change it back to
- 3:22:26zero, then notice that the two inputs
- 3:22:28are a zero and a one, which still ores
- 3:22:31to one.
- 3:22:33And this might take a little bit to wrap
- 3:22:35your head around because it it is fairly
- 3:22:38confusing and I I struggle with this
- 3:22:40when I learn the concept. And it's not
- 3:22:42very intuitive to take the output of a
- 3:22:44gate and feed it back into a gate. But
- 3:22:47it turns out that when we do that, we
- 3:22:48have some really powerful properties
- 3:22:50that we can achieve. And so if you can
- 3:22:54kind of understand that what's happening
- 3:22:55right now, uh let me prove to you that
- 3:22:58this is unlike anything we've seen. If
- 3:22:59that's not already clear, because now we
- 3:23:02have a zero uh a
- 3:23:05sorry, this this is correctly
- 3:23:06incorrectly written. When we powered
- 3:23:08this on, we had a zero going into x and
- 3:23:09we had a zero coming out. But now we
- 3:23:12have a zero and then we so we started
- 3:23:15with zero going in and zero coming out
- 3:23:18and then we made it a one going in and
- 3:23:20we had a one coming out and now we've
- 3:23:22set x back to zero and the output is
- 3:23:26still a one. And you may notice that
- 3:23:29these [snorts] first and third entries
- 3:23:31in this truth table contradict each
- 3:23:32other. And what I said about determinism
- 3:23:35earlier is that a circuit is
- 3:23:37deterministic if the outputs depend
- 3:23:39strictly on the inputs. And clearly this
- 3:23:42is not the case because we have this
- 3:23:44output one
- 3:23:47and it happens sometimes when x is one
- 3:23:50and sometimes when x is zero. So this
- 3:23:52output one isn't depending just on
- 3:23:54whatever the input x is at the time.
- 3:23:56There's clearly something else going on.
- 3:23:58And the difference here is that the
- 3:24:00output depends on not just the input but
- 3:24:04also previous values that were emitted
- 3:24:06by the circuit. And so this is what we
- 3:24:08call a sequential circuit.
- 3:24:13This is sequential logic. Sequential
- 3:24:15logic does not have this property of
- 3:24:17determinism that made things work out
- 3:24:19well. And as we've seen, this isn't an
- 3:24:22invalid circuit. We've done something
- 3:24:24valid here. We've just taken the output
- 3:24:25and feeding it back into one of the
- 3:24:27inputs. But a truth table doesn't
- 3:24:29actually work. And we're going to have
- 3:24:31these things called timing diagrams that
- 3:24:34that that better illustrate this
- 3:24:36property. So let's try create a timing
- 3:24:38diagram to explain what we saw here.
- 3:24:45So I'm going to erase these again. So
- 3:24:48this timing diagram is literally going
- 3:24:51to be a graph with
- 3:24:55time is the x axis and then we'll say a
- 3:25:01uh we we'll have separate lines for the
- 3:25:04x and y. So oops did not mean to erase
- 3:25:09that
- 3:25:11x and y. And we assume that they both
- 3:25:15start off as zero. So we'll we'll we'll
- 3:25:17let this be uh the the zeros line and
- 3:25:21then we'll let the one for y be up here
- 3:25:24and we'll do the same thing for x. And
- 3:25:26so x and y are different but they both
- 3:25:28progress in time together. So we want to
- 3:25:30see how x and y change as we move
- 3:25:34forward in time.
- 3:25:36So we started off with zero and zero and
- 3:25:40then I eventually at some point changed
- 3:25:44this x to be a one and at the same exact
- 3:25:47time this y became a one. So I set x to
- 3:25:51be a one and then y became a one and
- 3:25:53then we just left it like that for a
- 3:25:55little bit.
- 3:25:57And you may be wondering
- 3:26:00uh I said earlier that these logic gates
- 3:26:02have a little bit of delay in the real
- 3:26:03world. And so if I set X to be one,
- 3:26:05there should be a little bit of delay
- 3:26:06before Y becomes one. And that's that's
- 3:26:08the truth. But we we won't worry about
- 3:26:11that delay for this part. Uh we don't
- 3:26:12want to over complicate too much. So
- 3:26:15let's just assume that this logic gate
- 3:26:17works instantaneously. As soon as one of
- 3:26:19the input changes, the output
- 3:26:21immediately reflects what the correct
- 3:26:23value of that logic gate should be. So
- 3:26:26then now we have one and one. But the
- 3:26:29difference is that I noticed that when
- 3:26:31we brought this x back down to zero
- 3:26:34that y stayed as a one and then time
- 3:26:38continued and they both just stayed
- 3:26:39where they were at. And it turns out no
- 3:26:41matter how many times we bring this up
- 3:26:43or down this y is just going to stay at
- 3:26:46one.
- 3:26:47And so this is what we call a timing
- 3:26:50diagram.
- 3:26:54This right here shows the state of a
- 3:26:57sequential circuit as we pass through
- 3:26:59time. And we saw the issue with the
- 3:27:02truth table is that a truth table does
- 3:27:03not complete the full picture for a
- 3:27:05non-deterministic circuit. But a tying
- 3:27:08diagram does let us see everything
- 3:27:09that's happening. And so this is
- 3:27:12something that we will see uh
- 3:27:14increasingly in the next segment of the
- 3:27:16video. But what we'd like to now do is
- 3:27:19I'd like to show you how you can build a
- 3:27:21sequential circuit that actually lets
- 3:27:23you store a value. So we talked about
- 3:27:26this this 8 bit adder we have here and
- 3:27:29that we wanted to be able to store the
- 3:27:30outputs that are are coming out onto
- 3:27:33these output lines and we're going to
- 3:27:35dumb this down. We we didn't build this
- 3:27:37this 8 bit adder all at once. We started
- 3:27:40with a one bit adder and then scaled up.
- 3:27:42So we're gonna do the same thing. We're
- 3:27:43going to try to build a circuit that is
- 3:27:45sequential that can save one bit of
- 3:27:48data. And we'd like to design this
- 3:27:51circuit so that we can choose when we we
- 3:27:53save the value um and update its value
- 3:27:56afterwards. And so what we're actually
- 3:27:59going to do is I'm going to scroll all
- 3:28:02the way back up to one of the first
- 3:28:06things I showed you, and that was this
- 3:28:08selector gate right here. And I'm going
- 3:28:11to copy this
- 3:28:13down below
- 3:28:20and this will go right here. And this
- 3:28:25selector circuit is deterministic.
- 3:28:29The output depended strictly on the
- 3:28:32inputs. And so uh if you happen to not
- 3:28:35see the earlier part of the video, then
- 3:28:36I'll just go ahead and quickly
- 3:28:37summarize. Our selector circuit takes
- 3:28:40two inputs A and B
- 3:28:43and the output of that circuit will be
- 3:28:46the A input if C is zero
- 3:28:50I.e. If C is zero, then we let whatever
- 3:28:52A is flow through. And if C is one, then
- 3:28:56we let whatever B is flow through. And I
- 3:28:59originally showed you this this circuit
- 3:29:01earlier in the video to show you uh a
- 3:29:04motivation as to how you could build
- 3:29:06more interesting circuits by chaining
- 3:29:08logic gates together. And this was the
- 3:29:10first example I showed. But it turns out
- 3:29:12we can uh we can we can kind of build
- 3:29:15something very interesting by
- 3:29:18by making this selector
- 3:29:20non-deterministic.
- 3:29:22And so let's see just how we can do
- 3:29:25that. And what we saw when we did this
- 3:29:28orgate earlier, we started with the
- 3:29:30ordinary orgate which looks like this.
- 3:29:34And we made it sequential
- 3:29:36by doing something like this where we
- 3:29:38took the output and wired it back in.
- 3:29:41And then we had our one input and this
- 3:29:43was simultaneously this y line was an
- 3:29:45output and it is an input over here. So
- 3:29:50we're going to be able to do something
- 3:29:52very similar
- 3:29:54with this selector.
- 3:29:56So I'll keep the original selector up
- 3:29:58there for reference.
- 3:30:00And
- 3:30:03then I will bring this one down.
- 3:30:07And all I'm gonna do is with this Y, I'm
- 3:30:11going to get rid of our input A here
- 3:30:14and feed it back in.
- 3:30:17And I don't know why I drew that so far
- 3:30:18back. So I'll redraw that.
- 3:30:21And now let's see what happens. So our
- 3:30:26inputs are kind of weird. We have this
- 3:30:28this C and B. Uh it doesn't really
- 3:30:30matter what they're called. Well, why
- 3:30:31don't we just uh make this easier and
- 3:30:33rename this A because we no longer have
- 3:30:35an A input. And so we have a A input and
- 3:30:38a C input. And I'll keep the C as C
- 3:30:41because later it's going to stand for
- 3:30:42the word clock, but we don't really know
- 3:30:44what that is yet or why. So I'll I'll
- 3:30:47leave that there just so when it is
- 3:30:48introduced later, it's not as confusing
- 3:30:50to understand. Uh but for now, let's
- 3:30:52just think of it as the control line
- 3:30:54because that's kind of what we saw in
- 3:30:55the selector. The C is what controls
- 3:30:57which the inputs goes through. And then
- 3:30:59this Y stays the same. So let's see what
- 3:31:02happens. Let's suppose we start our
- 3:31:04circuit and C is a zero.
- 3:31:09Then we know that when C is a zero, it
- 3:31:12lets the value up top flow through. And
- 3:31:14let's also assume when we start the
- 3:31:15circuit, everything is a zero. So this Y
- 3:31:18is also a zero. So we have a Y coming
- 3:31:20out and then we have a Y over here,
- 3:31:22which means and you know the Y flows
- 3:31:24through. So the if we uh even try to
- 3:31:26change this a to a one let's say then uh
- 3:31:29the other output the other input to this
- 3:31:31and gates a zero. So this this output of
- 3:31:34this and gate is always going to be z is
- 3:31:36zero regardless of what a is and then we
- 3:31:39have the zero ored with the zero and so
- 3:31:43we're always going to output a zero. But
- 3:31:45then let's suppose we have our zero
- 3:31:48here. So we have our zero on y still.
- 3:31:52And let's let's go back to zero A. And
- 3:31:55now let's suppose we flip C from 0 to
- 3:31:58one. And now what this means is that
- 3:32:00whatever's on A's value should flow
- 3:32:02through. So [snorts]
- 3:32:04we have this we have this zero going
- 3:32:06through and it's just going to propagate
- 3:32:08out. And it's also we already had a
- 3:32:09zero. So it's going to propagate in. And
- 3:32:11that's the same thing as before.
- 3:32:14But things get a little bit interesting
- 3:32:17when we actually take this a and make it
- 3:32:21a one. And that's not the only thing we
- 3:32:23need to make this interesting cuz we
- 3:32:24know when we make a a one then this is
- 3:32:26going to be a one which means this is
- 3:32:28automatically going to be a one and this
- 3:32:31is the same one as above. So all that's
- 3:32:34really changed right now is is is
- 3:32:35nothing. We've seen that when C was
- 3:32:38started off as zero, then we actually
- 3:32:41weren't able to change the output at all
- 3:32:43because it was just the the input the
- 3:32:47output was flowing through in a circular
- 3:32:49fashion. But now in C's one, we let this
- 3:32:52a flow through and it kind of controls
- 3:32:55this entire circuit because it flows
- 3:32:57through and it's flowing back around
- 3:32:59here.
- 3:33:00But let's look at what happens the
- 3:33:03moment we go from a uh from c being one
- 3:33:06to zero. And this is where things get a
- 3:33:09little bit tricky to rationalize.
- 3:33:12But what we see here is that we start
- 3:33:16off we have a one coming out here which
- 3:33:19is a one up here. And I'm just actually
- 3:33:22going to erase that cuz it's the same
- 3:33:23one. It's the same wire. And we have C
- 3:33:26being one. And the moment we go from C
- 3:33:28being one to zero,
- 3:33:30then what happens is that this becomes a
- 3:33:34zero and this becomes a one. And we know
- 3:33:38that the output of 0 and one is zero
- 3:33:41here and the output of one and one is
- 3:33:43one here. And so we have this one come
- 3:33:46through and then the output of that
- 3:33:47orgate is still going to be a one. And
- 3:33:51this line doesn't change at all. And
- 3:33:55that's uh a little it may may take a
- 3:33:57little bit to understand that but
- 3:33:59nothing crazy has happened. But if we
- 3:34:01change a to zero
- 3:34:04then nothing is going to change either
- 3:34:06because we already know that this and
- 3:34:08gate is always going to output a zero.
- 3:34:10And we know that when c is equal to zero
- 3:34:13the uh whatever value is on this line is
- 3:34:15going to flow through. So what this
- 3:34:17pretty much means is we have two
- 3:34:18observations is when C is zero
- 3:34:23output doesn't change output doesn't
- 3:34:26change
- 3:34:29when C is one.
- 3:34:35The output
- 3:34:37follows A. And I'm using follows as
- 3:34:41synonymous with equals. The output is
- 3:34:42just going to be whatever A is. And the
- 3:34:45interesting thing that we saw is that
- 3:34:49when C goes from 1 to zero,
- 3:34:55C goes from 1 to zero, then we actually
- 3:35:01freeze whatever the output is at that
- 3:35:03exact time. We kind of and the output at
- 3:35:06that exact time was whatever on was on
- 3:35:08the value of A. So when C goes from one
- 3:35:11to zero, we lock in the value of A. we
- 3:35:14lock in the value of a
- 3:35:17and it's not going to change
- 3:35:20the entire whenever c is zero as we
- 3:35:22already dictated because we set it up
- 3:35:23here we have a rule that the output
- 3:35:25doesn't change when c is zero. So when C
- 3:35:27is one, we have this output following
- 3:35:29whatever A is. And then the really
- 3:35:31interesting thing is the moment we go
- 3:35:33from C being one to zero, we kind of
- 3:35:35latch in A's value.
- 3:35:38And this is very interesting because now
- 3:35:41we can freely change A and the output
- 3:35:45doesn't change because of our rule up
- 3:35:46here. So in an interesting way, this is
- 3:35:50actually storing data because what we
- 3:35:53have happening is if I wanted to store a
- 3:35:56value on this line Y, then what you
- 3:35:59could use, what you could infer from
- 3:36:01these three rules is that you would need
- 3:36:04to set the value of C to one to let the
- 3:36:07output equal whatever A is. Set A to
- 3:36:10whatever you want it to be. And so then
- 3:36:12the output currently equals A, which is
- 3:36:14what you wanted it wanted the value to
- 3:36:16save. And then you set the C from one to
- 3:36:19zero and that locks in the value. And so
- 3:36:21the output is still the exact same thing
- 3:36:24that you had as a but now you can change
- 3:36:26A freely and the output is still
- 3:36:28captured. And this is really useful.
- 3:36:31And what we've done now is we've we've
- 3:36:34effectively stored data. And I think
- 3:36:37this this diagram gets a little bit
- 3:36:39confusing. So the same way we
- 3:36:41represented a full adder with a
- 3:36:43rectangle, let's go ahead and represent
- 3:36:46the generic selector as so. So we're
- 3:36:49going to call this selector notation.
- 3:36:52And
- 3:36:54we have a b and then uh we can call it c
- 3:36:59for your your your choice or s for your
- 3:37:02selector. I'll just call it call it c.
- 3:37:05And then you have your output y. And all
- 3:37:08this is saying is this is our original
- 3:37:09selector before we had the output going
- 3:37:11back to the input. So that right here
- 3:37:13represents this. These are the same A,
- 3:37:16B, and C and Y as before. And so what
- 3:37:20we've done now, and I think a more
- 3:37:22intuitive way to represent this is we've
- 3:37:26taken
- 3:37:28I don't know why I made that so
- 3:37:29vertical.
- 3:37:32We've taken this A output and gotten rid
- 3:37:35of it. So we just have this B and this
- 3:37:37clock, this carry, this choice, and our
- 3:37:42output Y
- 3:37:44is still going to be an output, but it's
- 3:37:46also going to serve as an input. And you
- 3:37:48know the rule selector
- 3:37:51is that we've seen that we kind of have
- 3:37:53this above. So when C is zero, the
- 3:37:55output doesn't change. When C is one,
- 3:37:58the output's going to follow, and I'm
- 3:38:00just going to replace this with A. It's
- 3:38:02going to follow whatever A is. And then
- 3:38:05the interesting case is when we go from
- 3:38:07C to one, I've shown you that we
- 3:38:08actually lock in a value. And we've come
- 3:38:11to a point in the video, I've been
- 3:38:13drawing on this screen for about 3 hours
- 3:38:16that my my regressive handwriting skills
- 3:38:20are are getting a little too complicated
- 3:38:22to follow for you. We have these ones
- 3:38:24and zeros diagrammed all over these
- 3:38:26these these logic gates, and it's it's
- 3:38:28not very intuitive what's happening
- 3:38:29anymore.
- 3:38:30And we're actually, as we saw earlier
- 3:38:33with sequential logic, we have to rely a
- 3:38:34lot more on timing diagrams.
- 3:38:37So, it is time for me to actually switch
- 3:38:40over to some computer software and make
- 3:38:43this a lot easier for you to understand.
- 3:38:46So, let's look at this exact same
- 3:38:47example before, but let's let's migrate
- 3:38:49it over to computer software. So, I'm
- 3:38:51going to switch screens here now on this
- 3:38:53new software. And as you can see, our
- 3:38:55logic gates are actually drawn somewhat
- 3:38:57visibly coherent.
- 3:39:02And I've built the original selector
- 3:39:04that we've seen. And I'd like to show
- 3:39:06you that the selector works as we
- 3:39:08expect. So what we have right here is
- 3:39:11I'm going to set our our C is zero. So I
- 3:39:14guess I should first distinguish
- 3:39:15distinguish that this this dark green
- 3:39:18represents a zero and this this lighter
- 3:39:20green represents a one in the software
- 3:39:22I'm using. The software I'm using is
- 3:39:24actually called digital. The website
- 3:39:26that I link below that I wrote with one
- 3:39:29of my great friends is all of our
- 3:39:32graphics are built in digital and you
- 3:39:33can actually follow along. There's
- 3:39:34instructions there. I won't explain
- 3:39:36exactly how to do everything I do in
- 3:39:38digital, but you will see me build out
- 3:39:40in digital.
- 3:39:41And
- 3:39:44for now, all you should need to know,
- 3:39:46and I'll walk through everything as we
- 3:39:47go, is that this this light green is a
- 3:39:48one and this dark green is a zero. So in
- 3:39:51our first case, we can see that C is a
- 3:39:53zero. And the rule we said earlier for a
- 3:39:56regular selector is that if c is equal
- 3:39:59to zero then y should follow follow
- 3:40:02whatever a is. And we see this
- 3:40:04happening. You can kind of see and I
- 3:40:05think it's easier to visualize now the
- 3:40:07this this this a just flowing through.
- 3:40:10And you can see b's value just gets cut
- 3:40:13off by this and gate because its value
- 3:40:14is zero. And this is far more intuitive
- 3:40:17to see on the software once you can
- 3:40:18recognize the the lighter green being a
- 3:40:22one and this dark green being a zero.
- 3:40:25And then we can see that if I if I
- 3:40:28toggle C, then the output should follow
- 3:40:30B. And that's exactly what happens. So
- 3:40:32the output follows B no matter what A
- 3:40:36is. And we've we've built a a our our
- 3:40:40selector circuit. And another cool thing
- 3:40:43the software does is it will let me
- 3:40:46generate a truth table automatically. So
- 3:40:48we don't have to do everything by hand.
- 3:40:50So you can see
- 3:40:52for this this circuit we have right here
- 3:40:55that the truth table that I I have drawn
- 3:40:58out previously in the video is equal to
- 3:41:00the same truth table that's being shown
- 3:41:01right here. And I won't switch back to
- 3:41:04my drawing because it's going to be a
- 3:41:06pain, but you can go back in the video
- 3:41:08and see yourself that's true. And then
- 3:41:11the last thing I showed you before I
- 3:41:14before I switched to this view was that
- 3:41:17there's a a notation the to draw a
- 3:41:20selector. So, and we said it was
- 3:41:22represented with this right here. So,
- 3:41:24let's go ahead and see what that looks
- 3:41:26like. So, I'm going to copy
- 3:41:31this over
- 3:41:34and
- 3:41:37we will see what the output looks like.
- 3:41:39So I have our A and let me call this A2
- 3:41:43so we don't get it confused. Then we
- 3:41:46have B. I'll call it B2. And then we can
- 3:41:50also have our C2. And these are the
- 3:41:52same. This is the same circuit before.
- 3:41:54And and we're going to have our
- 3:41:57Y2. And another thing about the circuit
- 3:41:59is we represent our inputs with these
- 3:42:01squares. And you can see you saw me
- 3:42:02previously clicking them. And our
- 3:42:04outputs are going to be these circles.
- 3:42:09So now if I if I play this, let's
- 3:42:11convince ourselves this is true. So C2
- 3:42:13is zero. So the whatever we set A, it
- 3:42:16should flow through and that should
- 3:42:18happen regardless of what regardless of
- 3:42:21what B is and we see that happening. And
- 3:42:24then if I toggle B, then nothing should
- 3:42:26happen. And that's the case. And then if
- 3:42:29I flip to C, flip C to one, then we see
- 3:42:33B flows through. And toggling B lets
- 3:42:35that value flow through. and toggling A
- 3:42:38has no effect. And hopefully you that is
- 3:42:42enough to convince you that these are
- 3:42:44are are equivalent circuits. And I can
- 3:42:49actually delete this right here and do
- 3:42:51the same truth table generation. And if
- 3:42:55you go back uh less time this time, just
- 3:42:57a minute, you'll see that these true
- 3:42:58these two truth tables are the same.
- 3:43:01And so now what we want to do is do what
- 3:43:05I showed earlier where we took the
- 3:43:08output and chain that to the input. So
- 3:43:11I'm going to rename this. I'm going to
- 3:43:14rename everything accordingly. And this
- 3:43:17A goes away. But let's just call this
- 3:43:19this B and let's call this C. And let's
- 3:43:23actually just we said A when I was
- 3:43:25drawing on the screen. So let's be
- 3:43:26consistent here.
- 3:43:28And let's have this output feed into the
- 3:43:32input. So now if I do this then the
- 3:43:36point I was trying to make earlier which
- 3:43:37I think may have been a little hard to
- 3:43:39visualize without seeing it in this
- 3:43:40manner is that whenever C is zero the
- 3:43:45output is not going to change because
- 3:43:48whenever C is zero we let this top input
- 3:43:51flow through the output. And then
- 3:43:53whenever C is one, the output's just
- 3:43:56going to be whatever the input is,
- 3:43:58whatever this value A is because a
- 3:44:00selector behaves such that when the C is
- 3:44:02equal to one, we let the bottom input
- 3:44:04flow to the output. And
- 3:44:08the interesting thing was then when we
- 3:44:11toggled C from one to zero and what we
- 3:44:14said is going to happen is that at the
- 3:44:16moment we toggle C from one to zero,
- 3:44:18it's going to go from letting this
- 3:44:20bottom input flow through, it's going to
- 3:44:22go from letting the bottom input flowing
- 3:44:24through to letting the top input flow
- 3:44:26through. And the top input is actually
- 3:44:29equal to the bottom input whenever C is
- 3:44:31one because it's all the same circuit as
- 3:44:33you've been able to see. So what's going
- 3:44:35to happen is I'm going to toggle this to
- 3:44:37zero and this value is going to start
- 3:44:39coming through and this value is a one
- 3:44:42and it's going to trap this one in this
- 3:44:44loop right here. We have a little bit of
- 3:44:45a feedback loop happening and I know
- 3:44:48this is a little difficult to understand
- 3:44:50but uh it should be it should be this is
- 3:44:54what I explained is the other one of two
- 3:44:57hardest concepts to understand in the
- 3:44:59video is what I'm showing you right now.
- 3:45:01But let's see what happens. So we
- 3:45:03toggled this C from one to zero. And
- 3:45:06this is what you would expect because
- 3:45:09the input at that time we toggled C from
- 3:45:121 to zero was a one up here. And so when
- 3:45:14we actually toggle C back to zero, we
- 3:45:16just let this one flow through. And now
- 3:45:18it doesn't matter what we set A to
- 3:45:20because it's we have this rule that
- 3:45:22whenever C is zero, we just let this top
- 3:45:24input flow through. And so we've
- 3:45:26actually trapped the value in here. And
- 3:45:28if we wanted to trap a uh a one a zero
- 3:45:31in here, then what we need to do is have
- 3:45:34C go from one back to zero. So in order
- 3:45:36to do that, we have to set C back to
- 3:45:38one. And then we would set whatever
- 3:45:40value we want on A. And then to trap it,
- 3:45:42we'd set C from one back to zero. And
- 3:45:45the the remarkable thing that's
- 3:45:47happening here is that we trap the value
- 3:45:49on A at the exact moment that A C goes
- 3:45:53from one to zero. And let me show you
- 3:45:55exactly what I mean. So I am going to
- 3:45:58add another cool thing this software has
- 3:46:00is the timing diagram we saw from before
- 3:46:03and I'm going to bring this back in case
- 3:46:05I need to use a lot of space. But we
- 3:46:08start off with C. These are all zeros.
- 3:46:10Uh we see the two inputs are zeros and
- 3:46:12the outputs are zero. If I toggle one,
- 3:46:15if I toggle this A, nothing happens
- 3:46:16because C is zero. And then when C is
- 3:46:20one, you can see on this diagram right
- 3:46:22here that the value of Y is just equal
- 3:46:25to whatever the value of A is. And then
- 3:46:29suppose we wanted to lock in a one as
- 3:46:31the output. I need to have C go from the
- 3:46:33one it is right now to the zero. And you
- 3:46:38can see that C goes from one to zero.
- 3:46:42And now it's at this my claim is that
- 3:46:44it's at this exact moment that we lock
- 3:46:46in the value because now whenever I
- 3:46:48change a c is going to stay at that
- 3:46:51original value that it was at. And now
- 3:46:54suppose I wanted to lock a zero in. We
- 3:46:57said it only happens we can only lock a
- 3:47:00value in when this C goes from one to
- 3:47:02zero. So what I need to do is bring C
- 3:47:04back up to one. And as soon as we do
- 3:47:06that we can see that the output starts
- 3:47:08updating. It follows our input A. But to
- 3:47:11lock it in, I need to bring the C back
- 3:47:12down to a zero. And now you can see the
- 3:47:15C, we have this falling clock edge. We
- 3:47:18have a rising clock edge here and a
- 3:47:19falling clock edge here. And the falling
- 3:47:21clock edge is what actually latches in
- 3:47:23that value. So now I toggle A and
- 3:47:26nothing changes.
- 3:47:28So
- 3:47:30the good news is that if you follow me,
- 3:47:34you're halfway through the complexity.
- 3:47:37We're going to turn this up one more
- 3:47:39notch and then we're going to be done.
- 3:47:41So the good news is you're halfway. And
- 3:47:43the bad news is that it gets a little
- 3:47:45bit more complicated than this. So if
- 3:47:47you do find yourself confused by this,
- 3:47:50this is not something that you should
- 3:47:52let stop you from proceeding. You should
- 3:47:54check out the website that's linked in
- 3:47:55the description that I wrote. It's it's
- 3:47:57meant to illustrate this example a lot
- 3:47:59more detail.
- 3:48:00And you should just draw through this
- 3:48:03and play with it by hand until you're
- 3:48:05able to rationalize what's happening.
- 3:48:08Personally, when I learned this, I found
- 3:48:09this incredibly difficult and was not
- 3:48:11able to wrap my mind around it for days.
- 3:48:13It took me multiple sessions of opening
- 3:48:15up my computer and drawing things
- 3:48:17through before I finally had this aha
- 3:48:19moment and everything snapped. So, don't
- 3:48:22be discouraged if it takes you some
- 3:48:23time. And
- 3:48:26once you do feel like you have an
- 3:48:28understanding of everything I've spoken
- 3:48:30about this circuit that we have on
- 3:48:31screen, then you can continue is that
- 3:48:35this is a something called a positive
- 3:48:38latch. And what that means is that the
- 3:48:40output's only ever going to change when
- 3:48:43C is one. When C is positive, the
- 3:48:46output's going to change.
- 3:48:48Interestingly enough, we could actually
- 3:48:50just negate C and we'd get something
- 3:48:53called a negative latch. And that's the
- 3:48:56same behavior is that the output of the
- 3:48:59Y is only going to change when C is
- 3:49:01zero. So on the positive latch that we
- 3:49:04just saw, you lock in a value when the
- 3:49:06the C line goes from a one to a zero.
- 3:49:10And on the negative, it's the opposite.
- 3:49:12You lock in the value when the C goes
- 3:49:14from a zero to a one. So, let's actually
- 3:49:18look at what that is. And I have
- 3:49:21inverter here. And I probably shouldn't
- 3:49:23have erased this. Let me
- 3:49:27do this.
- 3:49:29And now let's look at our timing
- 3:49:31diagram. So
- 3:49:34C is zero now. And previously we said
- 3:49:39that when C is zero, the output's going
- 3:49:42to follow this in this this top input
- 3:49:45which is equal to the output. So it's
- 3:49:47never going to change. But now we see
- 3:49:49we're toggling A and it is changing. And
- 3:49:51that's because when you invert this C
- 3:49:54line to a selector, also known as a
- 3:49:56multipplexer, it just inverts the
- 3:49:59behavior. So the original selector let
- 3:50:02when C is zero, it lets this top input
- 3:50:04flow through. And when C is one, it lets
- 3:50:07this bottom input flow through. But now
- 3:50:09that we've inverted it, it's the
- 3:50:10opposite. When C is zero, we let this
- 3:50:12bottom input flow through. And then when
- 3:50:14it's one, we let this top input flow
- 3:50:16through. And so if I want to set a
- 3:50:18value, I need to get it so that we we
- 3:50:21have the value coming through. And then
- 3:50:22I want to pick the output to be this
- 3:50:25one. And we do that by setting C to be
- 3:50:27one. So to set a value, I have my A.
- 3:50:30Let's say suppose I want to store a one.
- 3:50:33Then I need to put this this this C to
- 3:50:35one. And now we're selecting this top
- 3:50:37line. And now as much as I toggle A,
- 3:50:39nothing happens. And then if I
- 3:50:43set C again, then notice now that the
- 3:50:45output follows A. And then at the moment
- 3:50:49where I set C back to one, we start
- 3:50:52picking this top input again. And so now
- 3:50:53the output's never going to change. And
- 3:50:57so this is called a negative latch
- 3:51:00because it latches onto the value
- 3:51:03whenever we go from
- 3:51:09zero to one. So it's it's latching on
- 3:51:14whenever we have this this input C being
- 3:51:19one. And it turns out that there is a
- 3:51:23shortcoming with what I've described
- 3:51:24here. So this is a very interesting
- 3:51:29combination of circuits and not that
- 3:51:31many logic gates that actually enabled
- 3:51:33us to to persist information. But the
- 3:51:37issue is that if I go back to this this
- 3:51:41original uh positive latch instead of
- 3:51:45the one we were just looking at, the
- 3:51:49output is changing
- 3:51:53whenever C is one. And
- 3:51:57it works out that if we're trying to
- 3:51:58store a value, it's fine cuz we know
- 3:52:00that whenever C is is falling from one
- 3:52:04back to zero, it it it stores the value
- 3:52:06in and then it's not going to change.
- 3:52:08But we'd like that to be true until the
- 3:52:11next time C falls from one to zero. But
- 3:52:14that's not the case because as you can
- 3:52:16see right here,
- 3:52:19the outputs uh going from 0 to one. And
- 3:52:22now we have we have this uh we have this
- 3:52:25this output changing before there's
- 3:52:27another falling edge. And so it's hard
- 3:52:30to give full motivation as to why we
- 3:52:32need this behavior.
- 3:52:34But it turns out as something that will
- 3:52:37become more clear as we design more
- 3:52:39parts of this computer
- 3:52:41is that if we can have information
- 3:52:45only change at one specific time, then
- 3:52:49it gives us more time to actually look
- 3:52:51at this value. So we know that on our in
- 3:52:54our current circuit that whenever C
- 3:52:58falls from one to zero, it's safe to
- 3:53:01assume that the output is going to be
- 3:53:03the same. until C goes from 0 to one.
- 3:53:08And this is this may seem fine. You're
- 3:53:10saying, "Hey, look, this is a lot of
- 3:53:11time, but what we'd actually like to do
- 3:53:13is make this as long as possible."
- 3:53:15Because I mentioned that these logic
- 3:53:16gates take time to settle. So, we'd like
- 3:53:18our output to be able to be used in
- 3:53:21other parts of our computer for as long
- 3:53:23as possible before we lose that stored
- 3:53:26in value. So what we'd like to do and
- 3:53:29what we're going to do next is update
- 3:53:32this circuit such that it only
- 3:53:37the output Y only updates every time C
- 3:53:42goes from one to zero.
- 3:53:45And this is going to be very useful
- 3:53:49because then it means until the next
- 3:53:52time C falls from 1 to zero that value Y
- 3:53:57is going to be the last latched on
- 3:53:59value. And you can see that's not the
- 3:54:02case here because in between this C
- 3:54:04going from 1 to zero and the next time C
- 3:54:06goes from 1 to zero, we have our output
- 3:54:09Y changing.
- 3:54:11And so this circuit that we have right
- 3:54:13here is called a latch. as I've
- 3:54:15mentioned and we're going to build
- 3:54:17something called a flipflop which has
- 3:54:20this desirable property that the
- 3:54:21output's only going to change when C
- 3:54:23goes from one to zero. Build this. I'm
- 3:54:27going to spoil the solution because it
- 3:54:29is something that would be incredibly
- 3:54:31difficult to come up with on our own.
- 3:54:34And once I spoil the solution, we'll go
- 3:54:36ahead and convince ourselves that it is
- 3:54:38true.
- 3:54:39So, the solution
- 3:54:41is that we're going to take a positive
- 3:54:43latch, which we have right here, and
- 3:54:46feed it into a negative latch. And let's
- 3:54:50go ahead and see what I mean by that.
- 3:54:51So, I'm going to copy this positive
- 3:54:53latch we have here, and I'm going bring
- 3:54:55this over here. And what I'm saying is
- 3:54:59that I'm going to take the output from
- 3:55:01this first latch and make that be the
- 3:55:04out the input into this other latch.
- 3:55:08do.
- 3:55:11So I take the output from this latch and
- 3:55:15I'm going to make it be the input into
- 3:55:17this latch. And then we we still want
- 3:55:19the same property where we have one A,
- 3:55:21one C, and the outputs the Y. So we we
- 3:55:23have two C's here. So I'm going to get
- 3:55:26rid of this. And I said we take a
- 3:55:29positive latch, which we have here, and
- 3:55:31feed it into a negative latch. And the
- 3:55:33way just a few minutes ago that I took a
- 3:55:35positive latch and made it into a
- 3:55:37negative latch was was by inverting the
- 3:55:39C line. Because we saw that inverting
- 3:55:41the C line has this nice consequence
- 3:55:45that it it flips the behavior of the
- 3:55:47latch making it a positive to a negative
- 3:55:51or vice versa.
- 3:55:54Um, in our in our default case, the
- 3:55:56software I'm using, it's a positive
- 3:55:58latch by default, meaning that the input
- 3:56:02the output follows the input whenever
- 3:56:04C's value is positive. And if we invert
- 3:56:07it, then we have the opposite behavior
- 3:56:09where the output only follows C's input
- 3:56:13when C is negative, zero.
- 3:56:18Cool. So let's go ahead and
- 3:56:22use our timing diagram that we have
- 3:56:24automatically generated
- 3:56:26to verify that this property holds
- 3:56:31that the output Y is only ever going to
- 3:56:34update at the exact moment C goes from 1
- 3:56:37to zero. And the value that it'll latch
- 3:56:41in at that moment that C goes from 1 to
- 3:56:43zero is whatever value is on A. So let's
- 3:56:46say we want to latch in a one here. So C
- 3:56:49is zero. So I'm going to show the
- 3:56:51output's not changing even when we
- 3:56:52toggle A. That's correct. We have our
- 3:56:54our input toggling, but there's no
- 3:56:57falling edge. There's no C from one to
- 3:56:59zero. So we don't change. Now,
- 3:57:03um I'm going to set C to one. And we see
- 3:57:07that C the output Y still doesn't
- 3:57:10change. And this this is different than
- 3:57:11what we saw before. But we saw before
- 3:57:13the output y would have changed here.
- 3:57:16But now as I keep toggling a nothing is
- 3:57:18going to change because we are waiting
- 3:57:20for this falling edge of c to happen. So
- 3:57:23let's actually do that. The moment I
- 3:57:25toggle c from one to zero we would
- 3:57:28expect this y to latch in the value
- 3:57:30finally.
- 3:57:32And that's exactly what we see. And now
- 3:57:34I toggle
- 3:57:36a and nothing happens. And to to do the
- 3:57:40cycle one more time, let's we've shown
- 3:57:42ourselves once that this this y value
- 3:57:44only updates when C falls. It has a
- 3:57:46falling edge. Let's do that one more
- 3:57:48time. Let's get back to that point and
- 3:57:50say I want to replace it with a zero
- 3:57:51now. So I bring C back up and I can show
- 3:57:55you that toggling A has no effect. And
- 3:57:57then I set A to what I want it to be.
- 3:57:59And now the moment that C goes from one
- 3:58:01to zero, we should be able to hope that
- 3:58:03this Y value locks in the zero. And
- 3:58:07that's exactly what happens.
- 3:58:09And so
- 3:58:12this is the exact circuit that we call a
- 3:58:16flip-flop.
- 3:58:18So let's try give a more reasonable and
- 3:58:20intuitive explanation as to why this
- 3:58:22behavior happens.
- 3:58:24And this is something that you could
- 3:58:27derive your on your own just by pausing
- 3:58:29this video and playing around and trying
- 3:58:31to offer up and justify the behavior of
- 3:58:35the logicates that you just saw. But
- 3:58:37I'll go ahead and spoil that out for
- 3:58:39those of you who don't want to
- 3:58:40rationalize on your own like myself
- 3:58:42would have not wanted to. So
- 3:58:46what we have here when we start this is
- 3:58:49C is zero.
- 3:58:51So whenever C is zero, the output here
- 3:58:57is not going to change because we're
- 3:58:59locking in this top value. So in order
- 3:59:02to for us to get a value from A to Y, we
- 3:59:05know that we have to get A onto this
- 3:59:07line at some point or else it can't even
- 3:59:09make it over here. So the only way to
- 3:59:11get A onto the line is to toggle this C
- 3:59:16positively. And now we can have A
- 3:59:18getting onto this line over here.
- 3:59:21But then the issue is that we also have
- 3:59:23to we want to get A over here. And
- 3:59:26because this is a negated clock, the
- 3:59:28only way we can get a to come over here
- 3:59:31is if we we get a
- 3:59:35zero
- 3:59:36onto this line because then a one would
- 3:59:39come onto this line and let this value
- 3:59:40through. And the only way we can then do
- 3:59:43that is we now have the value on this
- 3:59:46intermediate wire that connects the two.
- 3:59:49And it's the exact moment that I toggle
- 3:59:52C that this value gets trapped in this
- 3:59:55wire right here. Because when I toggle
- 3:59:58C, then this original latch that we're
- 4:00:00so comfortable with now, the output of
- 4:00:03it is just going to be this top line,
- 4:00:04which is a one. So C goes down and then
- 4:00:08this one is going to be locked on here
- 4:00:12even if I toggle A. So if I do that, I
- 4:00:16toggle C down. Then notice how me
- 4:00:18toggling A has no effect on this middle
- 4:00:20line. This value is is locked into this
- 4:00:23intermediate wire. And
- 4:00:28the last thing
- 4:00:32is that at that same time that we had C
- 4:00:38going from this one letting this value
- 4:00:42through to a zero, we also had something
- 4:00:44interesting happening over here because
- 4:00:47we we trap the one on this line. But
- 4:00:50then having this clock become zero means
- 4:00:53that this line becomes one and that we
- 4:00:56actually let this bottom input through.
- 4:00:59So now that in simultaneously what
- 4:01:01happens is we trapped the value of a on
- 4:01:04this intermediate wire and we now let
- 4:01:07our gate output what that intermediate
- 4:01:09wire is.
- 4:01:11And I know that probably sounds fuzzy.
- 4:01:15So, so take the time to justify this on
- 4:01:17your own, but that's the high level of
- 4:01:19what's happening here. And I'm again not
- 4:01:21going to spend too much time dwelling on
- 4:01:23this because the article that I wrote,
- 4:01:26which is linked in the description, goes
- 4:01:28through a lot more. So, I will say that
- 4:01:31you are 95% of the way done with
- 4:01:34learning the second hardest concept in
- 4:01:37this video. There's one final thing we
- 4:01:39need to do. And so recall that I taught
- 4:01:42you what a latch is and it was a
- 4:01:44positive latch. And then I showed you
- 4:01:46that inverting the clock makes it a
- 4:01:48negative latch.
- 4:01:50So what we've actually built here is not
- 4:01:53a flip-flop, but it's a negative
- 4:01:56flip-flop because the value is only ever
- 4:01:58locked in on the falling edge. When C
- 4:02:02becomes negative, i.e. it goes from one
- 4:02:05to zero uh a more negative value then
- 4:02:09the value is latched in. And so this is
- 4:02:11incredibly useful. But what if we wanted
- 4:02:13to have the opposite behavior where we
- 4:02:16wanted the value to get latched in when
- 4:02:19C goes from 0 to one? It turns out that
- 4:02:23we just
- 4:02:26negate our order of operations. So right
- 4:02:28now we have a positive latch being fed
- 4:02:31into a negative latch. If we just have a
- 4:02:33negative latch being fed into a positive
- 4:02:35latch, then the output is that our our
- 4:02:40our intuition remains the same except
- 4:02:43the output y only ever changes on a
- 4:02:47rising edge when C is becoming positive.
- 4:02:50So let me go ahead and update this to
- 4:02:53show that. So I get rid of this negator.
- 4:02:57So now we have regular C coming into
- 4:02:59this selector. So, this is a positive
- 4:03:01latch, but we need to make this one
- 4:03:03negative. And so, I'm going to do that
- 4:03:05by bringing this down here.
- 4:03:09And I'm going to add a negator.
- 4:03:16Let me rotate this
- 4:03:20like so.
- 4:03:22And now you can see that this this first
- 4:03:26this first latch is inverted meaning
- 4:03:29meaning it's a negative latch and then
- 4:03:31this one's the positive latch.
- 4:03:34So now what happens is that the value of
- 4:03:38C only ever changes on the rising clock
- 4:03:41edge. This is because when C is zero we
- 4:03:43have this value on the intermediate
- 4:03:45wire. We have this A coming to the
- 4:03:47intermediate wire. And the exact moment
- 4:03:49that we toggle C from a zero to a one,
- 4:03:52then this becomes a zero over here. So
- 4:03:57we trap in this current value of A in
- 4:04:01this feedback loop up top. So we're
- 4:04:03trapped in the value of a onto this
- 4:04:05line. And at the same time, this becomes
- 4:04:08a one. So instead of selecting the
- 4:04:10feedback loop to output, we select the
- 4:04:13value of this intermediate line to
- 4:04:14output, which is the value of a. And so
- 4:04:17we'd expect that when I toggle this from
- 4:04:20zero to one that the y becomes a one.
- 4:04:22That's exactly what happens. And now
- 4:04:25when I toggle this, the output is not
- 4:04:27going to change because we've locked in
- 4:04:30the original value of a onto this wire.
- 4:04:32And it's not going to change because of
- 4:04:34this this latch right here.
- 4:04:38Cool. So this is something very
- 4:04:40powerful.
- 4:04:42And I'll prove it one more time that the
- 4:04:44output only changes when C hits a rising
- 4:04:47edge. And this right here is incredibly
- 4:04:51powerful. A latch did let us store
- 4:04:54values, but this flip-flop is going to
- 4:04:56let us store values in in a in a way
- 4:04:58that modern computers actually do do
- 4:05:00things. And it's very important for us
- 4:05:03that we only update the value that we're
- 4:05:05storing on a specific clock edge, either
- 4:05:08the rising one or falling one.
- 4:05:12because that maximizes the amount of
- 4:05:14time that the output is stable that this
- 4:05:16this value is going to be just whatever
- 4:05:19we intend it to be versus we saw in a
- 4:05:22latch that half the time whenever
- 4:05:25depending on which type of latch you're
- 4:05:27looking at but for either when C is zero
- 4:05:30or C is one depending on the type of
- 4:05:32latch the output is just going to follow
- 4:05:34whatever the input is and that's not as
- 4:05:35useful to us because we would we would
- 4:05:37like to persist the value Y for as long
- 4:05:40as possible.
- 4:05:41So, now that we've we've seen how to
- 4:05:45build this flip-flop, let's actually put
- 4:05:48it to use. So, in the previous section
- 4:05:51of this video, we built an alou. And our
- 4:05:53motivation for even doing any of what I
- 4:05:55was talking about is that we'd like to
- 4:05:58be able to save the value of the output
- 4:06:01of our of our adder. So, if I if I add
- 4:06:04two values, I'd like to be able to save
- 4:06:06them. And what we have right here is a
- 4:06:09circuit that lets us save one value. But
- 4:06:15what happens if we want a circuit that
- 4:06:17lets us save two values? And it's pretty
- 4:06:19easy. All we have to do is just have two
- 4:06:23flip-flops.
- 4:06:24And what that means is that if we have a
- 4:06:28value A1 and A2 we want to persist, then
- 4:06:31we could feed A1 into the first
- 4:06:33flip-flop, A2 into the second flip-flop,
- 4:06:36and then feed the same C control line
- 4:06:39into both of those. And then at the
- 4:06:41exact moment we go from a r a rising
- 4:06:44clock edge, then we latch in both of
- 4:06:46those values. And the two outputs are Y1
- 4:06:48and Y2 effectively save the value of the
- 4:06:51ALU. And before I want to move on, I
- 4:06:55wanted to add this in and that is a
- 4:06:57little bit of notation. So we saw when
- 4:06:59we built our full adders that it was
- 4:07:01pretty difficult to conceptualize what
- 4:07:03was happening. We had so many of them.
- 4:07:05So we abstracted away as a little
- 4:07:06rectangle. And then not too long ago, I
- 4:07:10showed you how to abstract away the
- 4:07:13selector that we built with this
- 4:07:14trapezoid shape. And it turns out
- 4:07:18because this flip-flop we've built is so
- 4:07:20common, it's called a D flip-flop.
- 4:07:22Actually, there's there's different
- 4:07:23variants of flip-flops, but the one
- 4:07:25we'll use for for our computer, we only
- 4:07:27need D flip-flops.
- 4:07:29And we can abstract it away with this
- 4:07:32rectangle.
- 4:07:34And what we can see is that takes in a
- 4:07:38D, which stands for data because that's
- 4:07:40the data that we're going to be saving.
- 4:07:42takes in a C, which is this clock
- 4:07:45signal. And we've we've I I've kind of
- 4:07:48beat around the bush here, but we'll see
- 4:07:50as soon as we finish the next section
- 4:07:52why what this clock exactly is and what
- 4:07:54it's going to do. And then we get two
- 4:07:56outputs on the right side. Uh it's
- 4:07:58called Q and not Q. So, traditionally,
- 4:08:01if you do decide to research into
- 4:08:02flip-flops more or even latches, you'll
- 4:08:04find that Q is the common symbol to
- 4:08:07denote the uh stored value. And and in
- 4:08:11this software I'm using, we get Q and
- 4:08:14not Q because in some certain cases it
- 4:08:16could be useful to have the inverted
- 4:08:18value. But what I really want to show is
- 4:08:20that these two are equivalent. So we
- 4:08:23know that the value should only update
- 4:08:24when C goes from 0 to one. So if I want
- 4:08:28to lock in a one, what I would need to
- 4:08:30do is is put in a one on my input line.
- 4:08:33And then the exact moment that C goes
- 4:08:34from 0 to one, we should see the one co
- 4:08:36the the value of a get locked in over
- 4:08:38here. And that's what we see with this
- 4:08:40circuit. We already we already saw that.
- 4:08:42And to prove that these are similar or
- 4:08:44actually identical, we'll do the same.
- 4:08:45And we see the same behavior here.
- 4:08:48And then similarly, we know that if we
- 4:08:50toggle a while uh at any other time, the
- 4:08:55data on the output line's not going to
- 4:08:56change. So if I wanted to write a zero,
- 4:08:58I would need to let the clock go back
- 4:09:00down to zero and then the clock put the
- 4:09:02clock from 0 to one. So I do that and
- 4:09:05then this has the same exact behavior.
- 4:09:08So, this this right here will be used to
- 4:09:10represent a flip-flop and it'll make our
- 4:09:13our analysis easier and it'll save me
- 4:09:16time when I'm building these circuits
- 4:09:18having to draw these selectors out every
- 4:09:20single time. So, you can kind of see
- 4:09:22this already makes it easier than
- 4:09:24drawing this and these are already
- 4:09:26easier than drawing all the logic gates.
- 4:09:28So, it's really nice to have these
- 4:09:29layers of abstraction.
- 4:09:31So now what I'd like to do is we talked
- 4:09:34about we wanted to save the value that
- 4:09:36our adder can have. And the issue is I I
- 4:09:40drew my adder on on my uh iPad, but we
- 4:09:44don't have an adder built here. So I'm
- 4:09:46going to stop this and we're actually
- 4:09:49going to build an adder. Uh we're going
- 4:09:51to build exactly what we had before and
- 4:09:53then proceed from there. And if I come
- 4:09:57down to this arithmetic section, you can
- 4:10:00see that there is a circuit called an
- 4:10:01adder. And this should look very
- 4:10:03familiar. You see there's an A and a B.
- 4:10:06And then the CI is the carry in we're
- 4:10:08very familiar with. And then the output
- 4:10:09we get is a S for the sum bit and a CO
- 4:10:12for the carry out bit. And what I'm
- 4:10:16going to go ahead and do is I'm going to
- 4:10:17pause the video and then build our full
- 4:10:19arithmetic logic unit and then we will
- 4:10:22we will come back and and go from there.
- 4:10:24Okay, so I've cut back and I know this
- 4:10:27looks like a lot, but this is exactly
- 4:10:30what we had earlier. We have our series
- 4:10:32of A inputs and they get wired into each
- 4:10:35of the A inputs of the full adders. We
- 4:10:38have eight A's, eight B's, eight full
- 4:10:41adders and eight outputs. We have all of
- 4:10:44the B's and we have them exclusive or
- 4:10:47with our add subtract flag. And then we
- 4:10:50also have that add subtract flag going
- 4:10:52into the first carry-in of the rightmost
- 4:10:55full ladder.
- 4:10:57And before we proceed to add um our
- 4:11:01flip-flops to this, let's let's make
- 4:11:04sure this works. So this is two and this
- 4:11:07is two. And we expect that 2 + 2 is four
- 4:11:10and this is four in binary. And if we
- 4:11:14just have 0 over here plus two, we just
- 4:11:16get two. That makes sense. or 0 + 1. And
- 4:11:20if we had something like 3 + 1, we would
- 4:11:25expect 1 2 4. And we can verify that
- 4:11:28subtraction still works. Let's suppose
- 4:11:30we had four and we wanted to get rid of
- 4:11:32one. So, we toggle our subtraction. And
- 4:11:35then this is 1 + 2, which is three. I
- 4:11:38know I went fast with the binary
- 4:11:39conversions there. I've done it enough
- 4:11:40where it's almost second nature. But if
- 4:11:43you wanted to pause and go through the
- 4:11:46sections I showed slower, you would be
- 4:11:48able to verify that this is all true.
- 4:11:50And now that we've done that, we have
- 4:11:53the issue as we can see and we talked
- 4:11:56about where changing the output changing
- 4:11:59the input immediately changes the
- 4:12:00output. And
- 4:12:03this is problematic because we would
- 4:12:04like to capture the output of our adder
- 4:12:07subtractor, our ALU, arithmetic logic
- 4:12:09unit, which I'll call the ALU here
- 4:12:11onwards. as if I haven't already done
- 4:12:13that in the video earlier, but we just
- 4:12:16learned that we have this flip-flop that
- 4:12:19we can use that can let us accomplish
- 4:12:20exactly that. So, I'm going to stop this
- 4:12:22simulation and
- 4:12:25going to zoom out a little bit here
- 4:12:29and let's use the flip-flop that was
- 4:12:32already provided to us. And I'm not
- 4:12:35going to skip the video this time
- 4:12:36because I think there is some true
- 4:12:38benefit to to seeing this.
- 4:12:43And I don't want to just keep confusing
- 4:12:45everyone by by skipping back and forth.
- 4:12:48Wow, this is not my nicest performance.
- 4:12:50Oh, maybe this is exactly what I did
- 4:12:52want.
- 4:12:54Yes, this is what I want. Okay, so what
- 4:12:57we going to have is we know that each of
- 4:13:00our flip-flops can store one bit. So,
- 4:13:04just as we had each of our full adders
- 4:13:06could add one bit, we're just going to
- 4:13:07have and our solution to add eight bits
- 4:13:10was to have eight full adders. If we
- 4:13:13have a flip-flop that can store one bit,
- 4:13:15our solution to storing eight bits is to
- 4:13:17have eight of these. And we're all going
- 4:13:20to feed them the same
- 4:13:22uh clock input line because we have some
- 4:13:26value on our output from our ALOU and we
- 4:13:29want to trap each of those bits at the
- 4:13:31same exact time because collectively
- 4:13:34each of those bits is just a zero and a
- 4:13:36one. But if we look at all of them eight
- 4:13:38in a row, we know we can actually
- 4:13:39interpret a human readable number from
- 4:13:42this. So I'm going to create a new input
- 4:13:45that is going to be our clock.
- 4:13:49And that's going to get fed into every
- 4:13:51single one of these. I'm actually going
- 4:13:52to bring this down.
- 4:13:55And we're going to have eight of these.
- 4:13:58So
- 4:14:00I will
- 4:14:04have eight.
- 4:14:09And let me bring this up a little bit. I
- 4:14:13think we may need to bring this down
- 4:14:14later. And then we're going to get rid
- 4:14:16of our outputs here because they're
- 4:14:17actually no longer outputs. We will be
- 4:14:19needing them in feeding in each of these
- 4:14:24logic gates. So I'm going to delete
- 4:14:27this. And let's go ahead and wire in
- 4:14:31each of the data the D lines for our
- 4:14:35adder.
- 4:14:37So this is easy based on the
- 4:14:39construction I have. We can just bring
- 4:14:41these all the way down.
- 4:14:49And I admittedly did not need to bring
- 4:14:51it so far down. I thought it'd be a
- 4:14:53little more complicated. Um, but now we
- 4:14:56can feed this clock in to each of these.
- 4:15:02And on this software, you'll notice that
- 4:15:06when you have two wires overlapping each
- 4:15:08other, it doesn't mean they're the same
- 4:15:10wire. They can be distinct. They are the
- 4:15:13same wire if you have this dot. So you
- 4:15:15can see right here this wire is
- 4:15:17physically connected to this wire but
- 4:15:18there's no dot at this intersection. So
- 4:15:20they're actually two different wires.
- 4:15:23Okay. And then we have that. So let me
- 4:15:26then come down here and let's take our
- 4:15:29outputs of these and use them
- 4:15:32accordingly.
- 4:15:34So let's see if it's 90. Nope. 270.
- 4:15:39And I will have eight of these in a row.
- 4:15:59>> Okay. And then we should be able to And
- 4:16:03we want to look at the Q, not the
- 4:16:06inverted Q.
- 4:16:12Because as I mentioned earlier, we
- 4:16:14actually don't care about the inverted
- 4:16:16queue for
- 4:16:18the computer we're building.
- 4:16:26Okay. So now I'm going to run this
- 4:16:27circuit and let's let's see how we can
- 4:16:29actually use this. So let's say I wanted
- 4:16:33to add the numbers 1 + 1 and we would
- 4:16:36expect two. So I'm going to put in a one
- 4:16:39and a one. And our input our add
- 4:16:42subtract line is zero. So we're going to
- 4:16:44be adding and you can kind of see by
- 4:16:47looking at these lines up here that we
- 4:16:48have we have a one or a two as our
- 4:16:51result. Sorry. But we want to capture
- 4:16:54that result because the moment I start
- 4:16:56changing this input, you can see the
- 4:16:58output starts changing and that's not
- 4:17:00good. We want to be able to save what we
- 4:17:01have. So we know then from here that the
- 4:17:06whatever the input lines are, they only
- 4:17:08update to the output lines at the exact
- 4:17:10moment this clock goes from 0 to one. So
- 4:17:12if I set this from 0 to one, we should
- 4:17:14expect to see this bit be set cuz that
- 4:17:17represents two. And that's exactly what
- 4:17:19we see happen. And now if I keep
- 4:17:22changing this input, you can see that
- 4:17:23the outputs of this of the ALU are
- 4:17:25changing, but they're not going to get
- 4:17:27trapped as the stored value. The stored
- 4:17:29value is not going to update until the
- 4:17:31next time the clock goes from zero to
- 4:17:32one. So I'll keep changing this. Nothing
- 4:17:34happens. Set the clock to low. I can see
- 4:17:37even changing things has no input. And
- 4:17:39then now suppose I wanted to latch a new
- 4:17:41value in. Suppose I wanted to do uh 4
- 4:17:44minus one. And I would get the output of
- 4:17:50three.
- 4:17:52And
- 4:17:54if we do that and propagate this
- 4:17:56through, then we Oh, it looks like I Oh,
- 4:18:02I messed up something. I did four and
- 4:18:04one, but I had the add line. So, that's
- 4:18:07fine. I will fix this. Let me set the
- 4:18:09subtract line. And then the moment the
- 4:18:11clock goes from low to high, now we can
- 4:18:13see this this three gets latched in
- 4:18:15here. And changing the inputs has no
- 4:18:17effect. And so this is very very useful
- 4:18:21because we're now actually able to store
- 4:18:23values. And that's that's something that
- 4:18:25we'd like to do in our computer. Our
- 4:18:27computer actually needs to store values.
- 4:18:29We have this effectively calculator up
- 4:18:31here, but if we can't save anything, it
- 4:18:33it's not very useful. And what we've
- 4:18:36actually built here is not just eight
- 4:18:38flip-flops. This entire thing is what we
- 4:18:41call a register. So a register is a
- 4:18:46abstraction over a flip-flop. It's
- 4:18:48multiple flip-flops together, but we
- 4:18:50don't we don't perceive them as
- 4:18:52individual flip-flops. We looked at them
- 4:18:53we look at them in aggregate. And each
- 4:18:55of these flip-flops get in their own
- 4:18:58inputs, but they all have the same clock
- 4:18:59line and then their outputs are all read
- 4:19:02together. And if you've done a little
- 4:19:05bit of computer programming before,
- 4:19:07specifically in the language C, you may
- 4:19:09or may not be familiar with the keyword
- 4:19:12register. And if you're defining a a
- 4:19:14variable in a programming language,
- 4:19:16which if you have no idea what I'm
- 4:19:17talking about, don't worry about it. If
- 4:19:20you define a variable in a programming
- 4:19:21language C and you mark it with the
- 4:19:23keyword register, then it instructs the
- 4:19:26compiler to try store that value in a
- 4:19:29register instead of in your computer's
- 4:19:31RAM, which is what we'll come up to
- 4:19:33next. And this is because these
- 4:19:35registers are very very fast to read and
- 4:19:37write from. You can see they they
- 4:19:40operate as soon as the clock goes from 0
- 4:19:43to one and then their values are
- 4:19:45immediately persistable. What we're
- 4:19:47actually going to do next in this video
- 4:19:48is build up RAM for our computer so we
- 4:19:50can save values that we add into
- 4:19:52different spots in memory. And you'll
- 4:19:54see when we actually go to use it that
- 4:19:56it takes more time to interact with
- 4:19:59memory from RAM. And that's because you
- 4:20:01would have to figure out where in RAM
- 4:20:03you want to go and then pull that value
- 4:20:05back out and then put it into a
- 4:20:07register. [snorts] So there's a few more
- 4:20:09steps involved. But before we build RAM,
- 4:20:12I'd like to show what would we could do
- 4:20:14by taking the output of our register and
- 4:20:18then chaining it as the input to one of
- 4:20:21the arithmetic logic unit sides. So I'm
- 4:20:25going to stop our program here and I'm
- 4:20:27going to copy this cuz I I'd like to
- 4:20:29keep it. And what I'm going to do is
- 4:20:32destroy these and destroy
- 4:20:38I just want to destroy. That's not
- 4:20:40possible. Okay. But I'm going to take
- 4:20:44our outputs, our register value, and
- 4:20:46make it the input to the ALU. And what
- 4:20:49that's going to do is that the it means
- 4:20:51we're always going to be adding or
- 4:20:53subtracting the current value that's
- 4:20:56stored in the register with whatever our
- 4:20:58input is. So now we only have one input
- 4:21:00value and we can add or subtract
- 4:21:02whatever value in the register is. We'd
- 4:21:04pulse the clock and then it update the
- 4:21:06register with the result and we could do
- 4:21:07another addition on that. So let's build
- 4:21:10this and then we'll see what I actually
- 4:21:11mean here.
- 4:21:24Okay. So now something interesting
- 4:21:26happens if I if I start this circuit.
- 4:21:29And it's it's weird. We only have we
- 4:21:31have one we have one one input here. And
- 4:21:36I've I've done a poor job of designing
- 4:21:39this. But you can see that our our
- 4:21:41register is also outputting a zero right
- 4:21:44now.
- 4:21:45And what I can do though is let's say I
- 4:21:49add one here. Then we're we have since a
- 4:21:53register is storing zero that means our
- 4:21:55our input a side is zero and then we're
- 4:21:58adding a one and so we can see here the
- 4:22:00result is a one and if I want to pulse
- 4:22:03that in clock then we can trap that
- 4:22:06value in the register so I do that and
- 4:22:09now you can see that the register is
- 4:22:10outputting a one
- 4:22:12and let me actually pause this one more
- 4:22:15time because I think it could benefit
- 4:22:18from
- 4:22:20some actually labeled outputs.
- 4:22:28Okay, this is a better representation.
- 4:22:31But so we started off with we have a
- 4:22:33zero on our output which is also our
- 4:22:35input A. So now we add we want to add
- 4:22:37one to that and I'll pulse the clock
- 4:22:40from low to high. And now we get a one
- 4:22:42as our output. And notice if I keep one
- 4:22:45on this circuit, then now we have our
- 4:22:47one here and we're we're keeping it as a
- 4:22:50one here. So then the next time this
- 4:22:52clock goes from low to high, I should
- 4:22:53expect to see 1 plus 1, which is two
- 4:22:55being on the output of the register. And
- 4:22:57we see that happen. And now I have two
- 4:22:59here and two is our first input and one
- 4:23:02is our second input. So I should see
- 4:23:04three, which means this and this should
- 4:23:05be set the next time the clock goes from
- 4:23:07low to high. That's exactly what
- 4:23:09happens. And if I keep pulsing this
- 4:23:12clock, we have three. and then I'll go
- 4:23:14to four and then five and then six and
- 4:23:18then seven and then eight and it would
- 4:23:22keep on going.
- 4:23:23But what we have is a circuit that lets
- 4:23:27us count. And this is going to be
- 4:23:30useful.
- 4:23:32It's a sake of illustration for now, but
- 4:23:34later in the computer we're actually
- 4:23:36going to revisit this. We we are going
- 4:23:40to have a part of our computer which
- 4:23:44just incrementally counts and it's
- 4:23:46counting up and up by one at a time to
- 4:23:49know what instruction i.e. what work it
- 4:23:52needs to do next. But that's not
- 4:23:54something we need to worry about for
- 4:23:55now. Uh I just wanted to put this in to
- 4:23:58maybe give a little bit of context about
- 4:23:59our our alou. And we can also count back
- 4:24:02down from zero. So we have eight. If I
- 4:24:04toggle the subtract line, now we have
- 4:24:06eight. And every time I pulse the clock,
- 4:24:08we're going to be subtracting one from
- 4:24:09the value. So I go to seven and then six
- 4:24:13and then five 4 3 2
- 4:24:191 and then we're back at zero. And
- 4:24:22interestingly enough, if I subtract one
- 4:24:24again, then
- 4:24:260 - 1 should be negative 1. And this is
- 4:24:29actually the binary representation using
- 4:24:312's complement of negative 1. So this is
- 4:24:34very interesting.
- 4:24:36So now what we'd like to do is
- 4:24:39operate on multiple values. So we would
- 4:24:43like ideally to be able to perform large
- 4:24:46and more complex expressions. And what I
- 4:24:49mean by that is right now we can either
- 4:24:51do a + b or a minus b. And I'm not
- 4:24:55suggesting that we're going to do
- 4:24:56multiplication or division because I
- 4:24:57said that's probably out of the scope
- 4:24:58for our video because of YouTube's
- 4:25:00upload limit. But what we would like to
- 4:25:03do is a + b minus c plus d. Something
- 4:25:07that involves more variables than just
- 4:25:09two. And the only way we can do this
- 4:25:12with our alou is if we had a certain way
- 4:25:15to store memory beyond one register
- 4:25:18because we're always going to only have
- 4:25:20two inputs to our alou. And what we'd
- 4:25:22like to do is just be able to control
- 4:25:23what those inputs are based on looking
- 4:25:26up values in memory. And to bridge this
- 4:25:29gap, we're going to build what we call
- 4:25:30RAM. And you are probably familiar with
- 4:25:33RAM independent of how well you know
- 4:25:34computers. And RAM stands for random
- 4:25:37access memory.
- 4:25:39And so the way RAM works is that we will
- 4:25:44be able to give it an address and get
- 4:25:46back a value. And we'll either be able
- 4:25:49to give an address and get back a value.
- 4:25:52And that's when we want to read from our
- 4:25:53RAM or we give it an address and a new
- 4:25:56value. and the the RAM unit will update
- 4:26:00whatever is in memory at that address.
- 4:26:03And what I mean by address is we
- 4:26:05effectively have a table of values. So
- 4:26:08what I'm going to do is switch back to
- 4:26:10my drawing screen for the next segment
- 4:26:12of this video so we can make some sense
- 4:26:13of this and then we'll come back here
- 4:26:15and see if we can build it out in
- 4:26:16hardware.
- 4:26:18Okay, so we're back to the iPad. Let's
- 4:26:20recap where we were. So, we had
- 4:26:23um this ALU, arithmetic logic unit, and
- 4:26:27you'll often see it denoted in this
- 4:26:29V-shaped form, and it kind of means
- 4:26:31input one, input two, and then your
- 4:26:36output. And I know we're ignoring some
- 4:26:37stuff like the add subtract flag, but
- 4:26:40that's just for sake of demonstration.
- 4:26:42And
- 4:26:43we had a our output of our ALOU coming
- 4:26:47back around into a register
- 4:26:55and then that would actually feed into
- 4:26:56one of the outputs or back into one of
- 4:26:58the inputs and then this other input was
- 4:27:00controlled by us. And what this let us
- 4:27:04do and there's also this like clock
- 4:27:05signal or latch signal for the register
- 4:27:07that I'm also ignoring just for the sake
- 4:27:09of visualizing. What this let us do is
- 4:27:12keep operating on one value that was
- 4:27:15persistently being stored in this
- 4:27:17register. So the output of the alou we'd
- 4:27:21freeze it and then we could do something
- 4:27:23um that we call that add any term our
- 4:27:25result and then we could say if I want
- 4:27:27to add one I could throw in a one here
- 4:27:29or if I wanted to subtract two I could
- 4:27:31throw in a negative -2 here and then I'd
- 4:27:33let that propagate through and capture
- 4:27:36the output in the new register. And the
- 4:27:39issue with this that we're seeing is
- 4:27:40well there's no issue with it but it's
- 4:27:42kind of simple and that we'd like to be
- 4:27:44able to do more. So instead of having
- 4:27:46one value um that we can save, what if
- 4:27:48we had like a whole ton of values over
- 4:27:50here and we had like several values like
- 4:27:54value one and two and three and keeps
- 4:27:58going and then at any point we could say
- 4:28:00hey I want to take uh whatever is at
- 4:28:02like this value three and feed it into
- 4:28:05our AOU do some work and then maybe take
- 4:28:08the output and then uh have that output
- 4:28:10go back and we write it into say like
- 4:28:12address one or something. Um, and this
- 4:28:15is kind of abstract. So, what we're
- 4:28:17going to do is figure out like what this
- 4:28:19actually means. So, for now, what I'm
- 4:28:21actually gonna say is let's throw away
- 4:28:23all of our thinking of the AOU and just
- 4:28:26focus on this thing over here because
- 4:28:29what we want is a way to be able to
- 4:28:31store data. And I talked about this just
- 4:28:33a few minutes ago, but um, yeah, there's
- 4:28:37going to be some replication here, but
- 4:28:38let's try to figure out what this this
- 4:28:40part actually means here. And
- 4:28:44the first thing you'll see is we're
- 4:28:46talking about storing values. And your
- 4:28:48mind's probably jumping, hopefully it's
- 4:28:50jumping straight to registers. Like a
- 4:28:52like if we want to store a bunch of
- 4:28:53values, let's just have a bunch of
- 4:28:54registers. And that would be the correct
- 4:28:56intuition. So let's say um we want to
- 4:29:01have several registers storing values.
- 4:29:04But before we even get there, let's just
- 4:29:06figure out like what this might look
- 4:29:07like on a table. So we we have several
- 4:29:10values that are all unique and so we
- 4:29:12want like a table to represent like what
- 4:29:15the state of this memory unit looks like
- 4:29:17at any given time. And so we can have
- 4:29:20this like this list of entries. So like
- 4:29:22maybe the first entry has like value 0 0
- 4:29:260 and the second entry has value 0 1 1 0
- 4:29:30and the third entry has values 1 0 1 0
- 4:29:33and the fourth value maybe it's uh 1 0 0
- 4:29:360 and so on. These are just random
- 4:29:39values and it actually turns out not to
- 4:29:41get ahead of myself when you plug in
- 4:29:43your computer for the first time and
- 4:29:44start it up the RAM takes on any number
- 4:29:47of values. the actual values specified
- 4:29:49in memory are kind of just subjective.
- 4:29:51Um, we usually reason about them
- 4:29:53starting off as all zeros when you first
- 4:29:55plug in a computer. And I don't want to
- 4:29:56get too lost in specifics, but that is
- 4:29:59an interesting thing. Um, if you like
- 4:30:01plug in a RAM unit and then try inspect
- 4:30:04the values right away, you'll see like
- 4:30:06sometimes they're all over the place.
- 4:30:08Um, and so let's say in this
- 4:30:10hypothetical we have three, five
- 4:30:13different values here. Um, we need a way
- 4:30:15to assign each of these values some
- 4:30:17unique identifier. Um, when I'm when I
- 4:30:20want to read like this value right here,
- 4:30:23that's a bad arrow. It's kind of Let's
- 4:30:25say I wanted to read this value right
- 4:30:26here. I need a way to tell the RAM unit,
- 4:30:29hey, I want that that second value in
- 4:30:31that list. And I either want to read
- 4:30:33read what that value is or write
- 4:30:35something new into that position. Um,
- 4:30:38and so what what is that like? We how do
- 4:30:41we actually represent that? And that is
- 4:30:43what we call an address which is pretty
- 4:30:45straightforward if we like how we can
- 4:30:48reason about the addresses is just what
- 4:30:49position we are in our list of numbers.
- 4:30:52So whereas this this right hand side has
- 4:30:55the value at a particular address the
- 4:30:58left hand side specifies what the
- 4:31:00address actually is. And we'll start
- 4:31:02counting from address zero. And so we
- 4:31:04can say this first value has address
- 4:31:06zero. This second value has address one
- 4:31:09and so on. And this can keep going. Um,
- 4:31:13and so now it's easy for us to ask the
- 4:31:16RAM, hey, give me uh RAM, give me what's
- 4:31:19at this address 2, and it would
- 4:31:22correctly return one 0 1 0. Or I could
- 4:31:25say, hey, write some value into address
- 4:31:28one. And that value is 0000 0. And uh
- 4:31:32the RAM after that operation would write
- 4:31:34that correct value into this address.
- 4:31:43So um
- 4:31:46that's how we represent things. RAM is a
- 4:31:48series of addresses and values. And you
- 4:31:51can kind of notice that there's there's
- 4:31:52two things that vary here. Um the first
- 4:31:55and kind of obvious one is is hinted by
- 4:31:57here and I say a dot dot and how many
- 4:32:00values do we actually store in RAM. So I
- 4:32:02guess our our tunables to say our
- 4:32:05parameters when we're designing our RAM
- 4:32:07system is number one
- 4:32:09uh how many addresses
- 4:32:16and the second thing is for any given
- 4:32:18address and this might not be apparent
- 4:32:20but it might be more subtle. Uh right
- 4:32:22now I just said each address has four
- 4:32:24bits like that's how at each address the
- 4:32:27value that we store there is four bits.
- 4:32:30um that's arbitrary. I just did that
- 4:32:32because that's easy to draw out. But uh
- 4:32:34what is the actual like width of the
- 4:32:36values at the address? So um bits of
- 4:32:40values. So uh for a given address,
- 4:32:48how many bits are we storing there?
- 4:32:57So for modern computers, this ends up
- 4:32:59being uh larger numbers um millions and
- 4:33:04millions into billions of addresses and
- 4:33:06each value is is a 64-bit address or
- 4:33:09even some computers it can be even
- 4:33:11higher 128 bits. Um I'm actually going
- 4:33:13to get to the point where we we build up
- 4:33:15a fully functioning RAM in the same
- 4:33:17software I just came from. So I'm going
- 4:33:19to keep the value small here because you
- 4:33:22can learn the concept without getting
- 4:33:23lost in the uh specifics of trying to
- 4:33:26make it one to one with the computer
- 4:33:27we're going to build. So I'm going to
- 4:33:28build a simple version of RAM that says
- 4:33:32uh let's say it's going to put the
- 4:33:34number we'll say four different
- 4:33:36addresses and then for also each address
- 4:33:38will store a four bit value. Um these
- 4:33:40two numbers do not have to be the same
- 4:33:42and I'm just doing that because it'll
- 4:33:43make our construction simpler here. So
- 4:33:46if I relook at this table now given this
- 4:33:49um we have addresses
- 4:33:560 1 2 and three and then in terms of the
- 4:34:00values let's just make up some random
- 4:34:02values.
- 4:34:09Uh let's just say this is the state of
- 4:34:11our RAM at any time. Um,
- 4:34:14and now let's get into the construction.
- 4:34:17So, we kind of suspected we were going
- 4:34:19to have registers to hold these actual
- 4:34:21values, and that would be correct.
- 4:34:23That's what we're going to get to. Um,
- 4:34:25so let's say we have a register for the
- 4:34:28first value, and then register for the
- 4:34:32second value
- 4:34:35and a register for the third value,
- 4:34:38and then finally a register for the
- 4:34:40fourth value.
- 4:34:42kind of made my spacing wheel too big
- 4:34:44here. But um
- 4:34:48let's now talk about before we actually
- 4:34:49get into construction. I got a little
- 4:34:50bit of my a little bit ahead of myself
- 4:34:52there. Um the two operations we have to
- 4:34:55RAM. So this this table diagrams the
- 4:34:58internal state of RAM and how we think
- 4:35:00about it. And we know that like under
- 4:35:02the hood once we build this out it's all
- 4:35:04going to be a mess of logic gates. But
- 4:35:07this is the the the values that are
- 4:35:09underlying underlying held in those
- 4:35:12logic gates. Um so RAM has two
- 4:35:14operations
- 4:35:16and they're surprisingly
- 4:35:18straightforward. Um and you could
- 4:35:20probably also deduce it by now. So the
- 4:35:22first one um operations.
- 4:35:27The first one is read
- 4:35:30and it takes in an address
- 4:35:35and then your output is going to be a
- 4:35:37value. So in our example, if I called
- 4:35:40this read function and said I want to
- 4:35:43read what's at address 2, then the RAM,
- 4:35:46if you told it that, it would give you,
- 4:35:48if it's built correctly, it should give
- 4:35:50you um 0000.
- 4:35:54So that's the first half of RAM, being
- 4:35:56able to read the values that exist. And
- 4:35:58then if we could only read values, that
- 4:36:00would be cool. But uh part of the thing
- 4:36:02we wanted to motivate in our previous
- 4:36:03example was being able to take the
- 4:36:05output from our arithmetic logic and
- 4:36:06possibly write it back into one of these
- 4:36:08values. And so you could probably guess
- 4:36:11the second thing we want to do, the
- 4:36:12second operation we'd want to expose is
- 4:36:14called write.
- 4:36:16Um and write takes in a value that you
- 4:36:19want to write into RAM. and then the
- 4:36:21address
- 4:36:23that you want to write that that value
- 4:36:25into. And there's there's really no
- 4:36:27output here. Um it just kind of it
- 4:36:30happens. You don't get anything from RAM
- 4:36:31and return really. Um so in our example
- 4:36:35if I called this write function and I
- 4:36:38said hey write the value uh one one one
- 4:36:42into address let's say address two then
- 4:36:45what we'd expect to happen is that in
- 4:36:48this address we'd end up with one one
- 4:36:50one and then if I came back and called
- 4:36:52the same read operation we did earlier I
- 4:36:55should expect not to get 0000 0 I'd
- 4:36:58expect to get 11 one1 because that's the
- 4:37:00new value we just persisted in
- 4:37:02So these are the two basic operations of
- 4:37:04RAM. But it turns out that's also the
- 4:37:06complete operations of RAM. There is
- 4:37:08truly nothing more to it than the
- 4:37:09ability to read from a certain address
- 4:37:11or write a particular value into a
- 4:37:13particular address. And I'm going to
- 4:37:17clear this out.
- 4:37:20We are going to start with the read
- 4:37:23because the read and the right. Well,
- 4:37:25the write's a little more complicated
- 4:37:26than the read, but you kind of if you
- 4:37:28understand how reading works, writing is
- 4:37:31not too much more complicated. Um, so
- 4:37:34we're going to start with the read. Uh,
- 4:37:36and now with that proper context, I'll
- 4:37:39jump back to these four registers here.
- 4:37:41So, let's say this is our RAM.
- 4:37:45I'm just drawing around here. Um let's
- 4:37:48say for the read operation we need to
- 4:37:50specify an input which is our address
- 4:37:53and that would go into this RAM and out
- 4:37:55of RAM we'd expect to get some 4bit
- 4:37:57value back. Um and now here's where
- 4:38:00things get a little tricky. How do we
- 4:38:02actually do this? So we understand how
- 4:38:04these registers work and we understand
- 4:38:05that they hold values. So let me do a
- 4:38:09little bit of erasing.
- 4:38:13move these over.
- 4:38:16And let me also show the values that are
- 4:38:19in each of these registers.
- 4:38:44These are all just fictitious values.
- 4:38:47Okay. So the first thing is how do we uh
- 4:38:52capture this input. So these addresses 0
- 4:38:541 and 2 and three are just they're
- 4:38:56they're base 10 values. Um so I can
- 4:38:59denote that here to keep it clear. Base
- 4:39:0210 recall is just how we reason about
- 4:39:03numbers as humans. But we also learned
- 4:39:06uh several times now that computers
- 4:39:07don't really understand these values.
- 4:39:09computers especially the one we're
- 4:39:10building think in base two. So our
- 4:39:13addresses are actually have to come in
- 4:39:15as base two values. So let's let's for
- 4:39:18the sake of uh understanding here um
- 4:39:20let's go ahead and make our add a new
- 4:39:23column to our table which just shows the
- 4:39:25address in binary. So address and then
- 4:39:28in base 2 and then this address that
- 4:39:30we've been reasoning about is in base
- 4:39:3110. And so we have four different values
- 4:39:34and uh I'll just spill out the answer
- 4:39:36because it's not too complicated.
- 4:39:38um we're just counting in binary here.
- 4:39:41So these are the binary values and you
- 4:39:45can see to encode these four different
- 4:39:46values we need two bits. So when we're
- 4:39:50thinking about address into our RAM unit
- 4:39:52we're looking for two binary inputs. So
- 4:39:56that will actually be the representation
- 4:39:58of our input here. So we'd expect uh on
- 4:40:01our input
- 4:40:04um
- 4:40:06some value that is two bits and
- 4:40:11I'm going to bring that up here and
- 4:40:12you'll see why shortly. And um this will
- 4:40:17be human for now. Eventually we'll
- 4:40:19automate this entire thing when we
- 4:40:20finish the construction of our computer.
- 4:40:22These will be values that we can
- 4:40:23specify. So I can write 01 and uh I' I'd
- 4:40:28hope to get uh this
- 4:40:33second register. So this one right here.
- 4:40:35Um I'd want that output to flow through.
- 4:40:39So
- 4:40:40um
- 4:40:42that's how we represent our input. And
- 4:40:44then we know our output. Since we're
- 4:40:45storing four bit values, the output,
- 4:40:51we'd expect to just be four bits.
- 4:40:58And so if the user specifies 01 as their
- 4:41:01input, um we'd want the values in this
- 4:41:04register to flow into this into our
- 4:41:08output representation. And then if I
- 4:41:10switch that input, let's say to 0 0,
- 4:41:14we'd immediately want the values that
- 4:41:16are in this register to flow out to
- 4:41:18here. So let's figure out this first
- 4:41:22arrow that I've been drawing over here
- 4:41:25based on whatever the input is. How do
- 4:41:27we collectly correctly select uh the
- 4:41:30right register that we want? And so
- 4:41:32we're going to learn uh a new type of
- 4:41:34circuit. It's not too complicated, but
- 4:41:36it has a a word to it. Um it's called a
- 4:41:39decoder. So a decoder says for a given
- 4:41:43input we will decode that in spec like
- 4:41:46pick exactly one output. Um and so what
- 4:41:51does that look like? Let's start by
- 4:41:53giving each of these registers their
- 4:41:55addresses up top. So we start with 0 0.
- 4:41:58Here's 0 1. Here's one zero. And here's
- 4:42:01one one. And that'll just help us for
- 4:42:03referencing. And let's also
- 4:42:10extend these wires that capture the
- 4:42:13input all the way down here. This will
- 4:42:16make sense shortly. Um, and recall that,
- 4:42:19you know, if I if the user puts a one
- 4:42:20here, then no matter where you fork
- 4:42:23from, you're getting a one on this value
- 4:42:25because it's a wire. So, it just carries
- 4:42:26that value uh as far as it can. So,
- 4:42:31um, let's start with this register 0 0.
- 4:42:37I'm going to spill out the answer to the
- 4:42:38first one and then we're going to figure
- 4:42:40out why it works and then go from there.
- 4:42:42So, what I will say here is that we want
- 4:42:46some we want this register to be
- 4:42:48selected when both of our inputs are
- 4:42:50zeros. And so, the way I'm going to do
- 4:42:52that is I'm going to invert both of the
- 4:42:55signals.
- 4:42:56Remember, this is the not gate.
- 4:42:59And then I'm going to feed it
- 4:43:02into an andgate.
- 4:43:05And now we have something interesting.
- 4:43:07So I I you're probably confused how I
- 4:43:09got here. Let me prove to you that this
- 4:43:11works first. So if both of our inputs
- 4:43:14are zero, we're going to get a zero here
- 4:43:15and a zero here. When we invert it, we
- 4:43:18get ones because the inversion of a zero
- 4:43:20is a one. And then for an ANDgate, it
- 4:43:23only spits out a one if both the inputs
- 4:43:25are ones, which happens in this case.
- 4:43:27And we get a one here. And you can kind
- 4:43:30of see that for any other combination of
- 4:43:31values, the output of this this on this
- 4:43:34line at the end here is going to be a
- 4:43:36zero. Um, so for example, if I threw in
- 4:43:39the input, if the user had specified the
- 4:43:41input one zero, then what would happen
- 4:43:44here is this top inverter would spit out
- 4:43:46a one, this bottom inverter would spit
- 4:43:48out a zero. And then one and zero. Since
- 4:43:51neither since not both of the inputs are
- 4:43:52ones, we'd spit out a zero here. And
- 4:43:55I'll let you uh work backwards. And if
- 4:43:57you want to trace through every possible
- 4:43:59uh case of the four input combinations,
- 4:44:02you'll see that the only time that this
- 4:44:05line right here gets a one is if both of
- 4:44:07the inputs are zero. Um there's another
- 4:44:10way to think about this too is work
- 4:44:13backwards. So we if we want a one on
- 4:44:16this output line, then we can we can
- 4:44:19work from right to left. So we'd say if
- 4:44:21this and AND gate outputs a one it means
- 4:44:23that both of the inputs must have been
- 4:44:25one by the definition of the AND gate.
- 4:44:27And then for this inverter up here if
- 4:44:29the output is one then the input must
- 4:44:32have been the opposite of one which is
- 4:44:34zero. And the same would follow for our
- 4:44:36our gate down here. And then you can
- 4:44:38kind of see that the only time that we
- 4:44:41could possibly end with a one over here
- 4:44:42is if both of the inputs are zero, which
- 4:44:44I think is a pretty neat way of thinking
- 4:44:46about this.
- 4:44:49So that would correctly let us pick out
- 4:44:51this first input. And then let's try go
- 4:44:54do the same for this next input. So this
- 4:44:56next input, we'd only want we'd have
- 4:44:58some line here. We only want this line
- 4:45:01to have a one if the user has zero one
- 4:45:03on their inputs here. So what I'll do is
- 4:45:08we'd want something very similar to what
- 4:45:10we have above, but maybe we drop some
- 4:45:12inversions. So, we'd want this to be a
- 4:45:16zero and this to be a one. So, what I'll
- 4:45:21do is I'll invert this zero
- 4:45:23and then this one would just feed
- 4:45:25through and we'll just funnel it into an
- 4:45:27AND gate. And we have this wire out
- 4:45:30here. And so now you can kind of see
- 4:45:32again that the only way this can be a
- 4:45:35one is if both the inputs of this
- 4:45:37ANDgate are one. And that means that for
- 4:45:40this inverter up here, if the output of
- 4:45:42the inverter is one, that it means the
- 4:45:43input must have been zero. And for this
- 4:45:45line right here, it just it just pulls
- 4:45:47in from this uh this input from the
- 4:45:50user. The only way that could be one is
- 4:45:52if the user had specified one there. And
- 4:45:55you can kind of see that's exactly what
- 4:45:56we have going on here, which is pretty
- 4:45:58interesting. And
- 4:46:01we can then do the same for the next
- 4:46:02case.
- 4:46:04So, uh, now we want to do one zero. So
- 4:46:08we only want this output to be a one if
- 4:46:10our input looks like this. So one zero
- 4:46:15means that this should be a one and this
- 4:46:19right here should be a zero. So we can
- 4:46:21invert this one and then feed both of
- 4:46:24these into the end gate like we've been
- 4:46:26doing above.
- 4:46:28And you'll see that it's kind of just
- 4:46:30the uh the this top one and this bottom
- 4:46:33one are just reflections of each other.
- 4:46:35And that kind of follows from the fact
- 4:46:36that the 01 flipped is just one zero.
- 4:46:40And last but not least, uh our very our
- 4:46:43fourth and final register. We'd only
- 4:46:45want that line to spit out a one if both
- 4:46:49the inputs are one. And this one's
- 4:46:51straightforward. So if if we if we want
- 4:46:53both the inputs to be one, we'll just
- 4:46:55and them directly.
- 4:46:58So the only way this can be a one is if
- 4:47:00both the inputs are one, which should
- 4:47:01imply that user had selected one one.
- 4:47:05So this is pretty neat. What this means
- 4:47:07is that for every value we put in here,
- 4:47:12we will get only exactly and only one of
- 4:47:16these four output lines will be turned
- 4:47:19on and that is really neat. So if I
- 4:47:23specify 0 0 then this will turn on and
- 4:47:28the rest of them will turn off. If I
- 4:47:30specify 01, you'll see that
- 4:47:34this one turns on and the rest of them
- 4:47:36turn off. And that keeps going. For one,
- 4:47:40zero, we'd see off, off, on, off. And
- 4:47:44last but not least, if we had one, one,
- 4:47:47it'd be off, off, off, on. And so we've
- 4:47:51kind of built this selectoresque
- 4:47:54circuit that says for no matter what the
- 4:47:58input is for the input we will correctly
- 4:48:01turn on only one of these output gates.
- 4:48:04And that'll pretty much be our cue for
- 4:48:05the register to then say hey if for each
- 4:48:10register it can say at any point in time
- 4:48:12if its corresponding selection line is
- 4:48:15on then it wants to pass its value to
- 4:48:18the output over here.
- 4:48:20And this is pretty interesting, but what
- 4:48:22does it actually mean uh to now pass the
- 4:48:24output? That's where things get tricky.
- 4:48:26So, we've dealt with the input side. For
- 4:48:28the input side, uh we have this, it's
- 4:48:30not connected to our registers yet, but
- 4:48:32we have this circuit that lets us say,
- 4:48:34uh lets each register kind of know if it
- 4:48:37should be pushing its value to this
- 4:48:39output line. Now, we need to figure out
- 4:48:41how to look at that signal um i.e. look
- 4:48:44at that line and if it is set, i.e. it
- 4:48:47is one. Then how do we actually push the
- 4:48:49the value in the register at that
- 4:48:51current time to the output lines?
- 4:48:58And so
- 4:49:00let's start with our bottom register. It
- 4:49:02turns out
- 4:49:04that this is pretty straightforward to
- 4:49:07do. Um my drawing is going to get messy
- 4:49:09here, but we're quickly going to move on
- 4:49:11and build this in our our digital logic
- 4:49:13simulator. So, uh it shouldn't be too
- 4:49:16much of a concern here. So, recall that
- 4:49:19our register um has output lines
- 4:49:24and how I choose to visualize this is up
- 4:49:26to me, but um it has its output lines
- 4:49:30and pretty much uh what I'm going to do
- 4:49:34is I'm going to take this signal and and
- 4:49:37it with either each of the output lines.
- 4:49:40So, what I mean by that, let me draw it
- 4:49:42out.
- 4:50:06Now what does this mean? So what do the
- 4:50:09outputs here look like? If our selection
- 4:50:12line is a zero then we can guarantee
- 4:50:16that all of the output lines will be
- 4:50:18zero because the these are and gates and
- 4:50:22we know that the nature of an andgate
- 4:50:23says that if any of the inputs are zero
- 4:50:25then the output for sure will be zero.
- 4:50:28So this is interesting because it means
- 4:50:30for this we can verify that if our if
- 4:50:32our current register is not selected
- 4:50:34i.e. this line is a zero then the output
- 4:50:36of these four andgates down here will be
- 4:50:38zero. Now, let's see what happens if we
- 4:50:41actually were to flip this to a one.
- 4:50:45Then we'd have ones. And I've kind of
- 4:50:48alternated uh putting these on the top
- 4:50:50and the bottom, which is my fault here.
- 4:50:52At least each of these inputs the
- 4:50:54ANDgate there would be one of the inputs
- 4:50:55would be a one. And then the other input
- 4:50:59is just the value from that
- 4:51:00corresponding bit position in the
- 4:51:02register. And so when that happens we
- 4:51:04know that the output of the AND gate is
- 4:51:06just going to be whatever the out the
- 4:51:08the uh other input is. So for here this
- 4:51:10zero will flow through here this one
- 4:51:13will flow through here this zero will
- 4:51:15flow through and here this one will flow
- 4:51:17through. And so now we can see that when
- 4:51:20the the selection line is a one then the
- 4:51:23output of these registers the output of
- 4:51:25these and gates is just going to be
- 4:51:26whatever is in the register itself. And
- 4:51:29when that uh selection line is a zero,
- 4:51:31the outputs will be all zeros. So this
- 4:51:34is pretty interesting
- 4:51:36um because it then means we can now we
- 4:51:39know that uh if we extend this to all
- 4:51:41four registers
- 4:51:43um we we can kind of get the uh the same
- 4:51:46behavior where we have these these four
- 4:51:50gates that spit out values.
- 4:51:54I'm not going to reconstruct the same
- 4:51:55circuit. I don't have enough space here,
- 4:51:57but uh
- 4:52:02I can kind of box these in together. How
- 4:52:05about that? Oops. That should not
- 4:52:10Okay,
- 4:52:13so this is this is this the first
- 4:52:15register because I kind of have them
- 4:52:17close together. This is the second
- 4:52:18register,
- 4:52:20third register. And then we already have
- 4:52:22our our fourth register down here. uh
- 4:52:25that's just for distinction.
- 4:52:27So if each register builds this property
- 4:52:29up then we know that for at any point in
- 4:52:33time um three of the four registers
- 4:52:37their output will all be zero and then
- 4:52:39that last register whatever one it is
- 4:52:41will have the correct values uh being
- 4:52:44pushed through i.e. whatever is stored
- 4:52:45in that specific register and so then we
- 4:52:48kind of want to join these all together
- 4:52:50to the actual output. So let's look at
- 4:52:53the uh the rightmost bit only for each
- 4:52:57register.
- 4:52:59So we'd want
- 4:53:01that rightmost bit from here to flow to
- 4:53:03this one. Um and the same for the rest
- 4:53:06of them.
- 4:53:08And recall what I just said a second ago
- 4:53:11where for any particular address that
- 4:53:14the user specifies on that input line,
- 4:53:17three of those four lines, we don't know
- 4:53:19which one. It depends on whatever the
- 4:53:21selected register is. Three of those
- 4:53:23four lines are guaranteed to be zeros.
- 4:53:26Um, and that's because only uh only one
- 4:53:30of the selection lines over here will be
- 4:53:33true at any time. And so that means for
- 4:53:35the remaining three that their gates are
- 4:53:37just going to get blocked as we just
- 4:53:39learned a few minutes ago. And so then
- 4:53:41it means that the last one it either
- 4:53:43outputs a zero or one. And that's the
- 4:53:46one that we want to flow through. So uh
- 4:53:48how we simplify that we can't just have
- 4:53:50four of these lines going into
- 4:53:53um into the output line is we can ore
- 4:53:56them together because when we or these
- 4:53:59if zero or zero or zero the ore of the
- 4:54:03three that are off is always going to be
- 4:54:04zero and then if we or that with the
- 4:54:07correct one that we do want to pass
- 4:54:08through the value will just flow through
- 4:54:11because zero or x is just going to equal
- 4:54:15x. Um, so let's kind of show what that
- 4:54:19looks like. So
- 4:54:23for this specific one right here, um, we
- 4:54:26could take a
- 4:54:30orgate and feed in the rightmost bit
- 4:54:33from each of our registers.
- 4:54:39And that will correctly let us capture
- 4:54:41prop push through the uh correct
- 4:54:44rightmost bit position of all the
- 4:54:46registers to the output one. And that
- 4:54:48that handles the rightmost bit. Uh and
- 4:54:51my drawing as I said is getting bad. And
- 4:54:53we just do the same for all the other
- 4:54:55bit positions. So this second from right
- 4:54:58would just we'd ore all of them together
- 4:55:01from all of our input registers.
- 4:55:04And that kind of captures our output.
- 4:55:07So, this it turns out is the
- 4:55:09fundamentals of RAM and how we build
- 4:55:12reading RAM. Um, I've kind of gone a
- 4:55:15little bit fast here and I've like to
- 4:55:17keep it everything correct and thorough.
- 4:55:20And so, we're going to jump back and
- 4:55:21actually build this in our logic
- 4:55:23software.
- 4:55:40Okay, so I built the uh very first half
- 4:55:42which was the selector. So there's none
- 4:55:43of the register logic, no registers or
- 4:55:46output flowing through. But um this was
- 4:55:49the very first part where we said uh
- 4:55:50based on whatever the input is, we'd
- 4:55:52expect only one of these four outputs to
- 4:55:55be true. Um and we'd expect it to match
- 4:55:58the input. So we can kind of see that
- 4:55:59when we have 0 0 the very first one
- 4:56:02turns on and uh the next one would be
- 4:56:0501. So if I keep this as a zero and turn
- 4:56:08this to one we'd expect only this one to
- 4:56:11be on and the remaining three to be off.
- 4:56:13We can see that that happens. And then
- 4:56:16the next input was 1 zero. So that we'd
- 4:56:20expect if I flipped this on and this
- 4:56:22off, we expect this one to turn on and
- 4:56:25the remaining three to turn off. So
- 4:56:27that's true. And last but not least was
- 4:56:301 one. So if both of our inputs are on,
- 4:56:33we'd expect just this one to be on. And
- 4:56:35that seems to be true. So it looks like
- 4:56:37this first part is all good. So I'll go
- 4:56:39ahead and continue with the building
- 4:56:41there.
- 4:56:56reconstructing what we had diagrammed on
- 4:56:59my iPad uh in this software. In some
- 4:57:02respects, it is cleaner than what I was
- 4:57:04drawing on my screen and in some
- 4:57:06respects it's a lot uglier. Namely, uh
- 4:57:09over here this gets messy. Um so, let's
- 4:57:12actually walk through and see what's
- 4:57:14happening here. But before I start the
- 4:57:16simulation, one thing I'd like to call
- 4:57:18out is that uh instead of using actual
- 4:57:20registers, i.e. making a bunch of
- 4:57:23flip-flops next to each other,
- 4:57:26um I'm just using inputs. And that way
- 4:57:27we can easily change the value that's in
- 4:57:30RAM just by clicking ourselves before we
- 4:57:32actually go and um implement the uh
- 4:57:35writing the writing part of our RAM, the
- 4:57:37second half. So I'm going to go ahead
- 4:57:39and start the simulation.
- 4:57:41And this is our address selecting line.
- 4:57:43So right now we can see it's 0 0 and the
- 4:57:47coloring here is pretty interesting. Um
- 4:57:49you know we can see some things light up
- 4:57:50and it kind of corresponds to this this
- 4:57:52selector part here. So first off we
- 4:57:54correctly see that only uh this first
- 4:57:56line gets selected and we can see these
- 4:57:58and gates are all fed uh ones versus the
- 4:58:02others all of theirs are fed zero which
- 4:58:04means they're all outputting zero
- 4:58:06independent of the value that's stored
- 4:58:08you know in in each of these RAM uh in
- 4:58:10each of these registers. But this first
- 4:58:12one's different um correctly since it's
- 4:58:14the address we're selecting is giving
- 4:58:16the data in these registers the ability
- 4:58:19to flow through. And so basically this
- 4:58:22is our output line. And what I'd expect
- 4:58:24to happen if I turn on this rightmost
- 4:58:26bit position is that the output should
- 4:58:28show that rightmost bit position. And uh
- 4:58:31that's exactly what happens. So um how
- 4:58:36do we make sense of the uh the mess
- 4:58:38that's going on over here? So, we know
- 4:58:40that uh these are our registers, our
- 4:58:43four registers. They're kind of just uh
- 4:58:44inputs right now, but they will become
- 4:58:46registers not too long from now. And
- 4:58:48then we also had our decoder over here.
- 4:58:50Uh this decodes the input address
- 4:58:53selection and we'll select uh one at a
- 4:58:57time of the correct quote unquote
- 4:58:59registers. And then we then join the
- 4:59:03value that's in each of these registers
- 4:59:05with the value of the decoding signal to
- 4:59:08determine which value should flow
- 4:59:10through each of our four output lines.
- 4:59:13And this happens at the per register
- 4:59:15level. And then what we have to do is we
- 4:59:18have um an output line for each bit
- 4:59:21position of each register is we actually
- 4:59:23need to go join them uh to get the
- 4:59:26output for our for the RAM unit as a
- 4:59:28whole. So if I look at this this uh
- 4:59:31let's say this rightmost bit position
- 4:59:34we're seeing an orgate whose input is
- 4:59:37two more the whose input is the output
- 4:59:40of two other orgates. So this is just
- 4:59:42kind of a four-way orgate. Um if any of
- 4:59:45these four inputs are true uh the value
- 4:59:49one will flow through and the output
- 4:59:51overall will be a truth. The software
- 4:59:53I'm using, as far as I know, does not
- 4:59:55have the easy ability to do um or gates
- 4:59:59that accept multiple inputs. So, this is
- 5:00:01kind of how I've gone the show around,
- 5:00:02but that's fine. It doesn't make our
- 5:00:03logic too much worse here. Um and so, if
- 5:00:07this output corresponds to the rightmost
- 5:00:10bit position, what I'd expect is that
- 5:00:12the rightmost bit position from each of
- 5:00:14our four registers should be the four
- 5:00:16inputs to this. And that's kind of what
- 5:00:19we see. So if I turn this on, we can
- 5:00:21kind of see, hey, this green over here
- 5:00:23flows to this one. And then this line
- 5:00:27right here flows to that top register,
- 5:00:29the top output of the second register,
- 5:00:31which hooks into its rightmost bit
- 5:00:33position. Similarly, if I look at our
- 5:00:35third register, here's the rightmost bit
- 5:00:36position. Here's that output. If I trace
- 5:00:39it up, it comes into that third ore. And
- 5:00:42last but not least is our uh fourth
- 5:00:46register. Here's the rightmost bit
- 5:00:48position output. If I follow that line,
- 5:00:51which gets a little tricky to do, I can
- 5:00:53see it follows into the fourth bit
- 5:00:56position. And so because of this the the
- 5:00:59decoding properties combined with our
- 5:01:01andgate uh little trick there, we know
- 5:01:04that at any time um three of the four
- 5:01:08inputs to this quad orgate is guaranteed
- 5:01:11to be off. Um which means the fourth
- 5:01:15value will effectively flow through. So
- 5:01:18if it's a zero, the entire circuit will
- 5:01:20output a zero. And if it's a one coming
- 5:01:22in here, that value will just flow
- 5:01:24through. Uh and this is pretty neat. So
- 5:01:27now let's suppose I put in the value um
- 5:01:32this value into the second register. So
- 5:01:33that's what is that? That's 2 + 4.
- 5:01:35That's the value six here. And if I then
- 5:01:38switch the address selection part of the
- 5:01:40RAM to read what's in this second
- 5:01:42register, then I'd expect that value to
- 5:01:44get reflected over here. So the address
- 5:01:46for this register is 0 0. The address
- 5:01:49for this one is 01. So to switch it, I
- 5:01:51just turn the second one on. And now we
- 5:01:54correctly see that the uh the output of
- 5:01:56our RAM um corresponds with the register
- 5:01:59denoted by our input address selection,
- 5:02:02which is pretty cool. And if I then turn
- 5:02:04that back off and go and select uh
- 5:02:06address zero, then I get that original
- 5:02:08value um correctly outputed here.
- 5:02:11Similarly, if I were to select uh the
- 5:02:13[snorts] third register, the register
- 5:02:15whose the address in RAM uh
- 5:02:18corresponding to one zero, this third
- 5:02:20one down here, we can see its output is
- 5:02:22all zeros because the value of that
- 5:02:24register is all zeros. If I flipped it
- 5:02:27one bit at a time to turn all of them
- 5:02:29on, we then go ahead and you can see
- 5:02:31that the output turns on. And uh just
- 5:02:34for sake of completion, let's go with
- 5:02:37this for our last our last register. And
- 5:02:40this is address 11 one in RAM. So if I
- 5:02:43select one one on our input select our
- 5:02:45input address selector I get the uh
- 5:02:48exact value outputed here. So this is
- 5:02:52pretty cool. And we notice that even as
- 5:02:54I select uh different addresses
- 5:03:00that the values in RAM are held but
- 5:03:03we're just only letting one of them flow
- 5:03:05through at a time. So this is pretty
- 5:03:07cool. We have four different 4-bit
- 5:03:10values. They just exist as is. And based
- 5:03:14on how we specify an address in our
- 5:03:17control input, we get to read the value
- 5:03:20of RAM for that given address at any
- 5:03:22time on this output line.
- 5:03:25It's pretty powerful. Um, the next thing
- 5:03:29we'd like to do was we can now read from
- 5:03:31RAM, but we'd actually like to be able
- 5:03:34to write in values into RAM. So, what
- 5:03:36I've been doing for this demonstration
- 5:03:37is just uh toggling the values here and
- 5:03:40they're just kind of input units. But we
- 5:03:42really know that these uh this shouldn't
- 5:03:44this shouldn't be a you know four input
- 5:03:46units. It should just be a four bit
- 5:03:48register which boils down to four
- 5:03:50flip-flops. So, what I'm going to go
- 5:03:52ahead and do is uh we what we want to do
- 5:03:56next is actually replace each of the
- 5:04:00inputs that I've mainly spent with uh
- 5:04:03flip-flops. So, I'll actually show the
- 5:04:05first one. Um, let me get rid of these.
- 5:04:09And if I go over here in the tool, this
- 5:04:11is less relevant. Uh, we want to D
- 5:04:13flip-flop because that's what we learned
- 5:04:14about previously. Go ahead and rotate
- 5:04:17it.
- 5:04:20Oh, wrong way.
- 5:04:25And that's one bit position. We know
- 5:04:28just a register is just uh a four-bit
- 5:04:32register is just four
- 5:04:34flip-flops next to each other. And then
- 5:04:36I'll hook up the wiring. So recall that
- 5:04:39uh in our digital software, we get the
- 5:04:42output of the register is denoted Q and
- 5:04:44we also get not Q which is the inverted
- 5:04:46value. We only care about the value as
- 5:04:48is. So we'll just stick with Q. And
- 5:04:53cool. So now we've replaced
- 5:04:56um instead of selectors, we've used
- 5:04:58actual flip-flops.
- 5:05:00So I'll go ahead and do that for the
- 5:05:02rest of them.
- 5:05:09I'm ahead and replace each of our
- 5:05:10selectors with actual flip-flops. And
- 5:05:13recall that when we chain flip-flops
- 5:05:15together, just stack them next to each
- 5:05:17other, we get um registers. So now the
- 5:05:22next thing is how do we actually go
- 5:05:25ahead and make it such that we can write
- 5:05:26values in. So we have the reading of of
- 5:05:29our RAM working. How can we actually
- 5:05:30write a value into one of these
- 5:05:32registers? So let's start just by saying
- 5:05:35that uh these over here can be the four
- 5:05:40bits. So if I were to want to uh you
- 5:05:42know oops it's not going to let me run
- 5:05:44this. If I were to want to uh write in a
- 5:05:48new value to a particular address, then
- 5:05:52what I want to do is be able to put
- 5:05:53punch in that address here and then
- 5:05:55punch in that value here and then have
- 5:05:58that um be the signal that tells our RAM
- 5:06:03unit to actually go ahead and hey like
- 5:06:04do this right operation. So there's two
- 5:06:07things to note here. The first one is
- 5:06:09that if these are our if this is the
- 5:06:11input for um reading a value in to RAM,
- 5:06:15then we can hook this up to each of our
- 5:06:18registers pretty much like the only way
- 5:06:20to replace a value in a register is to
- 5:06:22specify it on this on these four lines
- 5:06:24just by our construction here. So uh the
- 5:06:28same way we can loop this this right bit
- 5:06:30into the the input line uh for each of
- 5:06:34our right bits of our four registers
- 5:06:38and I won't do that right now for the
- 5:06:40sake of uh time. I do that for each bit
- 5:06:42position. So that's observation number
- 5:06:43one. So each of these registers whenever
- 5:06:46it is going to update its value it's
- 5:06:48just going to look at whatever has been
- 5:06:49set by the user and right now that's
- 5:06:52just going to be set by the humans.
- 5:06:53Eventually we'll get to the point that
- 5:06:55the computer sets the values itself
- 5:06:56because you know the computer is fully
- 5:06:58autonomous in that sense but that's uh
- 5:07:01we're still a little bit of ways away
- 5:07:02from that. And that's the first
- 5:07:05observation. So I can go ahead and do
- 5:07:07that wiring. The second observation is
- 5:07:10uh I know we've talked about registers a
- 5:07:12little bit and we're a little bit of
- 5:07:13back but and we're going pretty quickly
- 5:07:14here and it's that even if we hook in
- 5:07:17the input here so like if I had you know
- 5:07:20each of these four bit positions lined
- 5:07:22up here um the only way to actually
- 5:07:27get uh the value the register to accept
- 5:07:30the new value is by that clock signal.
- 5:07:33Um, so recall there has to be like a a
- 5:07:36clock edge, a transition from low to
- 5:07:38high or high to low depending on what
- 5:07:40flip-flop you're using. Um, and so we're
- 5:07:43going to add one more input here. And
- 5:07:46that's going to be
- 5:07:49uh kind of this I guess we'll call this
- 5:07:50like this this trigger operation. Um, so
- 5:07:54if if I wanted to write a new value into
- 5:07:57a particular address, I'd punch in the
- 5:07:59address here would punch in the value
- 5:08:02here and then because RAM needs a uh
- 5:08:05because registers need a clock edge
- 5:08:07rising or falling to be triggered, I'd
- 5:08:10have to then punch this. And at the
- 5:08:12exact moment I punch this and it
- 5:08:14triggers a transition from high to low
- 5:08:16or low to high, the correct register uh
- 5:08:18would hold in that value. So we said
- 5:08:21that for reading in the data input for
- 5:08:23each of these registers it's going to
- 5:08:25come from these lines. So we can hook
- 5:08:26these input lines to each of the
- 5:08:28registers. But we can't hook the clock
- 5:08:31line um into each of the registers. And
- 5:08:34the reason is is if we did that then the
- 5:08:37moment we punch this clock line the
- 5:08:39values here would get written into every
- 5:08:42single register. But when we punch the
- 5:08:45clock line, we only actually want to
- 5:08:47write the write into the register that's
- 5:08:50uh being referenced by this address
- 5:08:52setting line right here. So recall that
- 5:08:55we built the decoder to actually solve
- 5:08:57this problem already. So we can kind of
- 5:08:59reuse that. We know that at the exit the
- 5:09:02output of each of these andgates that we
- 5:09:04have on this vertical um it'll only
- 5:09:07light up if the address selected by the
- 5:09:09user here is quote unquote picking this
- 5:09:12register. And that was for reading, but
- 5:09:14we're going to use the same logic for
- 5:09:15writing. So what we'll actually do is
- 5:09:18take advantage of that same principle
- 5:09:19that we have with the each of these and
- 5:09:20gates. And that will and the decoder
- 5:09:24output with this this uh clock line and
- 5:09:27feed that as the clock line into each of
- 5:09:29these registers. And what that'll allow
- 5:09:31us to accomplish is that when we punch
- 5:09:34this clock line, it won't actually
- 5:09:36replace the value in all of these
- 5:09:37registers. it'll only replace the value
- 5:09:40in the register whose ANDgate uh here
- 5:09:44i.e. the output from the decoder
- 5:09:46corresponds to the input set on these
- 5:09:48lines right here. So uh I think
- 5:09:51demonstrations will make this clear. Let
- 5:09:53me go ahead and wire this all up.
- 5:10:08gone ahead and finishing up the wiring.
- 5:10:10And uh a few things are going to look
- 5:10:12different now. So I've kind of moved
- 5:10:14some of the stuff around from when I cut
- 5:10:16the last video to make it fit. But um
- 5:10:18you'll see that this is our value input
- 5:10:21line. So when we want to write a new
- 5:10:23value, we set the value here. This is
- 5:10:25the same. when we want to read or write
- 5:10:27to a register in RAM a specific address,
- 5:10:31we punch in that address on these two
- 5:10:33bits.
- 5:10:34And uh last but not least, you'll see
- 5:10:37that this is the clock signal. So uh in
- 5:10:41our diagrams, we're using positive D
- 5:10:43flip-flops. So that means that this
- 5:10:46register will latch in a value uh on a
- 5:10:50rising edge of that clock signal. So
- 5:10:52whenever the C line goes from zero to
- 5:10:54one, uh that's the exact moment that the
- 5:10:57register will actually look at what's on
- 5:10:59its input lines, these D lines, and hold
- 5:11:02that and record that as the new value
- 5:11:04that it persists. And so if I zoom out a
- 5:11:07little bit, we can see that this is our
- 5:11:09input value. So when we want to write a
- 5:11:11new value, we place it here. And you can
- 5:11:13kind of see that uh it is simply fed in
- 5:11:17uh left to right the same way on all
- 5:11:19four of our registers. So since these
- 5:11:23four lines are the only way to specify a
- 5:11:26new value, we can just hook each bit
- 5:11:29position of the register, i.e. each bit,
- 5:11:32each latch um or sorry each flip-flop
- 5:11:36to the correct uh position on the line
- 5:11:38here. And then we said we could not do
- 5:11:41the same for the clock signal because if
- 5:11:43we did that same thing for the clock
- 5:11:44signal, then the moment we punched it
- 5:11:47and went from a low edge to a high edge,
- 5:11:50uh, all of these registers would read in
- 5:11:53the new value that's on these four
- 5:11:54lines, which would write to every single
- 5:11:56address on our RAM when we really only
- 5:11:58want to write to the address denoted by
- 5:12:00the user selection here. So that's
- 5:12:02enough talking. Let me go ahead and run
- 5:12:04this circuit and turn it on and let's
- 5:12:06see what happens. So the first thing to
- 5:12:08note is that if I look at the output of
- 5:12:10each of the registers,
- 5:12:13then you can see they're all all zeros.
- 5:12:16So that's just the way that uh registers
- 5:12:18uh initialize in this software, which
- 5:12:21means that if all the values in our RAM
- 5:12:23are zero at every address position, then
- 5:12:25no matter what address position I put in
- 5:12:27here, uh the output's always going to be
- 5:12:29zero. But that's not very interesting.
- 5:12:32What we want to do is if we know
- 5:12:34everything's at uh zero, let's go ahead
- 5:12:37and write a value to a specific
- 5:12:39register. And uh we'd expect that when
- 5:12:41we select and selected that register,
- 5:12:43the uh output would be captured here or
- 5:12:45the value of that register after we
- 5:12:46perform the write instruction. So let's
- 5:12:49write this second register. This
- 5:12:51register is the first one in our our
- 5:12:54RAM. So that's address zero. This one is
- 5:12:57address one in our RAM. So I'm going to
- 5:12:58punch in address one. And then let's say
- 5:13:01we want to write all ones to it. Uh 11
- 5:13:05one1 in binary. Um which I believe is
- 5:13:0715. 8 + 4 is 12 + 2 + 1. Yep, that's 15.
- 5:13:11So we have 15. We want to write 15, the
- 5:13:14value 15 into address one. So we've
- 5:13:17specified those two things. And what we
- 5:13:19now need is a rising clock edge. So I'm
- 5:13:21going to punch this. And the exact
- 5:13:23moment I punch this, two interesting
- 5:13:25things are going to happen. First the
- 5:13:27value 1111 should be captured in this
- 5:13:29register. So you'd expect to see these
- 5:13:31four lines light up. And then since uh
- 5:13:35we are selecting this address still and
- 5:13:37not changing that this output line is
- 5:13:40all is still going to be reading what's
- 5:13:42in this register. So we'd expect 111 to
- 5:13:45now be the new value in the register. So
- 5:13:47if our implementation is correct, we'd
- 5:13:49expect 1111 to appear on the output
- 5:13:51line. So let's go ahead and trigger a
- 5:13:54rising clock edge to see that. And it
- 5:13:58everything looks correct to me. We have
- 5:14:011111 as the value in the register and
- 5:14:03all ones
- 5:14:05um on our output line. So let's do two
- 5:14:08things. Let's clear this just for
- 5:14:09visibility sake. It doesn't really
- 5:14:11matter. We don't have to because we know
- 5:14:13that the next time uh the values on this
- 5:14:16line are going to be useful is the next
- 5:14:18time our clock signal goes from low to
- 5:14:20high. And it's at high right now. So I'm
- 5:14:22also going to push it back to low. And
- 5:14:24that's also not going to do anything
- 5:14:25because of the discussion we had on
- 5:14:27flip-flops earlier. But now if I go back
- 5:14:30to address zero, it correctly has zero.
- 5:14:33That's where we started. And in fact,
- 5:14:35all the other addresses are still going
- 5:14:36to spit out zero. What would be
- 5:14:39interesting is if I specify address one,
- 5:14:41I'd expect to see 1111 on the output. So
- 5:14:44let's do that. And we can now see that
- 5:14:46we are correctly selecting the right
- 5:14:48output. So this looks good. Um let's go
- 5:14:51ahead and punch in values to
- 5:14:54uh the other registers just to make
- 5:14:56sure. So we'll start with this one uh
- 5:14:57register zero uh the first address spot.
- 5:15:00So 0 0. We already have 0 0 punched in
- 5:15:02here. And let's say we just want to
- 5:15:03write the value one to it. Then as soon
- 5:15:06as I push this, we'd see a rising clock
- 5:15:09edge 0 to one. And we'd expect that
- 5:15:11value to get latched in here. And then
- 5:15:13since we're still selecting one, um
- 5:15:15since we're still selecting the address
- 5:15:16zero, we'd expect to see that on the
- 5:15:18output side as well. So, let's go ahead
- 5:15:19and do that. I see one and then I see
- 5:15:23one. So, that looks good to me. Um,
- 5:15:27let's now I'll undo this and unset that.
- 5:15:30Let's write a value into the third
- 5:15:31register. Oh, so we can actually say I
- 5:15:33need to check that we haven't broken
- 5:15:34anything. So, we know we wrote one here
- 5:15:36and one one here. So, if I switch to
- 5:15:39this address, I still see 1111.
- 5:15:42And uh let's go ahead and uh write to
- 5:15:45our last our third right of storage to
- 5:15:47make sure. Um, so that's address 1 zero.
- 5:15:50Let's say I want to spit in uh 1 one.
- 5:15:54Then I'll trigger that rising clock
- 5:15:55edge. We see that as soon as that
- 5:15:57happens, 1 one gets written into the
- 5:15:59register. And we also see that being
- 5:16:01reflected on the output line. And we can
- 5:16:04go ahead and do this for the final
- 5:16:06register um by let's say we want to
- 5:16:10write this value into it. Uh we specify
- 5:16:12address 11 one and
- 5:16:18that is interesting. So I wasn't
- 5:16:21expecting it uh to actually read in any
- 5:16:24value. Um
- 5:16:27so let me see what's happening here.
- 5:16:32My mistake here. So I I misspoke. What I
- 5:16:34originally said is that uh when the only
- 5:16:38way we can actually write this value
- 5:16:40into a new register is when this goes
- 5:16:43from zero to one. Uh I actually have a
- 5:16:45clarification to make that uh that's
- 5:16:48actually not the case. Um ideally after
- 5:16:51we write a value into a register, we
- 5:16:52should put that this uh read signal back
- 5:16:55down. The reason is is let's say I
- 5:16:57wanted to write a new value into address
- 5:16:59111.
- 5:17:01Um, let's say I wanted to write the
- 5:17:02value 1111 into this final register down
- 5:17:06here. So, if I switch to this address
- 5:17:11and this is already high, it's going to
- 5:17:13cause a right to happen. And I'll prove
- 5:17:15that to you. Let me switch to address
- 5:17:17one one. And we can see that the right
- 5:17:19happens because that's the value being
- 5:17:20reflected here. But, uh, that's actually
- 5:17:22not what we want to happen. And at first
- 5:17:24this appears to be a violation of what I
- 5:17:26said that uh latches or sorry flip-flops
- 5:17:28only write hold in a new value um when
- 5:17:31you go from a low to high clock signal
- 5:17:33but that's actually uh we have not
- 5:17:35violated that that is still true. So if
- 5:17:37I punch this back down let's say we want
- 5:17:39to write this value into that register.
- 5:17:41Um and
- 5:17:44when I
- 5:17:46uh what's interesting is when I even if
- 5:17:49this line is set to high when I go and
- 5:17:51push the right address of 1 one in what
- 5:17:54happens is that that triggers this and
- 5:17:56gate here. Um so this uh this the
- 5:18:00selector will then get the right value
- 5:18:03to see hey one is set and one is set. So
- 5:18:05it comes through and uh originally this
- 5:18:08AND gate was outputting a zero but then
- 5:18:09it outputs a one and it goes from a low
- 5:18:11to a high and that output of that AND
- 5:18:13gate is what we're feeding into the
- 5:18:14clock signal not actually just the clock
- 5:18:17signal itself. So that's why that
- 5:18:19happens. Um so we should be careful that
- 5:18:23uh once we write a value in we should
- 5:18:25push this signal back to low. Um, and
- 5:18:28that way when I swap to address one one,
- 5:18:31this time I see that the value on the
- 5:18:33input line isn't uh getting written to
- 5:18:37immediately. In fact, it's not until I
- 5:18:39click this and trigger the rising edge
- 5:18:40that that happens. And the the nuance is
- 5:18:43then that now that I've done my right, I
- 5:18:44should push this back down to avoid uh
- 5:18:46the issue I just described happening
- 5:18:50over the ALOU arithmetic logic unit that
- 5:18:53we built uh probably about an hour ago.
- 5:18:56And I made a few modifications. So first
- 5:18:59it was adding on 8 bit numbers and
- 5:19:02therefore putting out 8 bit results.
- 5:19:04Since our RAM only stores 4bit values,
- 5:19:07I've go ahead and cut this ALU down to
- 5:19:10four bit values only for both inputs and
- 5:19:13outputs. And then the second thing I've
- 5:19:16done is I've made both the inputs to
- 5:19:19alus be registers and just let the
- 5:19:21output be asis. And uh basically the
- 5:19:25reason I've done this is because what
- 5:19:27we'd like to do is connect the ALOU and
- 5:19:31the ALU and the RAM together. And so
- 5:19:34what that might look like is I might
- 5:19:36load one value from a particular RAM
- 5:19:38address into this register. Then put on
- 5:19:41a different address in the selector,
- 5:19:43load that value into this part of RAM
- 5:19:46into this register. And then I let the
- 5:19:48arithmetic happen. And then maybe I want
- 5:19:50to take the output and then write that
- 5:19:52back into a particular address in RAM.
- 5:19:56And so um I' I've made each of these
- 5:20:00inputs be registers so we can read from
- 5:20:02different parts of RAM uh without
- 5:20:04worrying about like arithmetic
- 5:20:05happening. Um and then we'll deal with
- 5:20:07the output of this and how we can like
- 5:20:09that together. So uh here's the output
- 5:20:12of our RAM. If we want to be able to
- 5:20:14read from RAM into uh positions in this
- 5:20:18ALU, then what I could do is I could
- 5:20:21wire each of these output positions into
- 5:20:24the input positions of the registers
- 5:20:26that represent the input to the ALU. So
- 5:20:29we'll call this the A register and the
- 5:20:30the B register. Um and so if I did that,
- 5:20:34you know, I have a full connection of
- 5:20:35these four to these four inputs and then
- 5:20:37these four to these four inputs. And if
- 5:20:40I wanted to load a value, what I could
- 5:20:42do is I could, you know, punch in the
- 5:20:43address here. The value would come up.
- 5:20:45It'd read into both these registers, but
- 5:20:47then because of the clock command, it
- 5:20:49wouldn't actually write into those
- 5:20:50registers until we'd actually pulse one
- 5:20:52of those. Um, so that would work and
- 5:20:55that would be fine. But the issue is
- 5:20:58that as we design this computer, there's
- 5:21:01going to be more components. And what
- 5:21:03we're doing is a onetoone mapping of
- 5:21:06outputs to inputs that we know are going
- 5:21:08to exist. But let's say the RAM like
- 5:21:11there's other things that might want to
- 5:21:12read from RAM. Then this would require
- 5:21:14us to also extend not only wires from
- 5:21:17here to here to here. Uh but also from
- 5:21:20here to you know maybe somewhere else
- 5:21:21conceptually on this on this figure
- 5:21:23board. Um and both of you both these uh
- 5:21:28like this gets do the same result. Like
- 5:21:29there's nothing wrong with this in terms
- 5:21:31of functional correctness. This will
- 5:21:33behave as expected. But you can already
- 5:21:35see here you know simple things require
- 5:21:37a lot of wires and uh it's it's it's
- 5:21:40pushing the design limits with a lot of
- 5:21:42connections happening. Um
- 5:21:45similarly you know like the output of
- 5:21:48this uh alou if we want to write that to
- 5:21:50a specific position in RAM the easy
- 5:21:53solution is to take these outputs and
- 5:21:55you know kind of wire them into the
- 5:21:57inputs here. But then you know what if
- 5:21:59something else in the computer wants to
- 5:22:01write write into RAM it also would then
- 5:22:02have to you know wire something to these
- 5:22:05same lines um that gets risky you know
- 5:22:08you don't want to be writing uh
- 5:22:11different values on different lines at
- 5:22:13the same time by accident um and so this
- 5:22:17generally becomes a like design
- 5:22:18bottleneck here. So what we do is
- 5:22:22introduce the concept of a bus.
- 5:22:25And what a bus is in our example here,
- 5:22:29it'd be pretty much it's fairly
- 5:22:31straightforward. It just be four control
- 5:22:35lines.
- 5:22:40And then for every component that wants
- 5:22:42to interact with another component of
- 5:22:44the computer, instead of wiring those
- 5:22:46two components to touch each other
- 5:22:47directly, we just wire those two
- 5:22:50components to touch the bus. And then um
- 5:22:54if I want to read a value into this
- 5:22:56register, I would have the output uh of
- 5:22:59the RAM write some value onto the bus
- 5:23:02and then this register would just read
- 5:23:03whatever value is on the bus. Similarly,
- 5:23:05this register could connect to the bus
- 5:23:07too. And that way instead of having a
- 5:23:09onetoone pairing um between everything
- 5:23:12that wants to connect to each other,
- 5:23:14each component just needs to have one
- 5:23:16connection to the bus and that's all. So
- 5:23:18it's you know it's it becomes like a one
- 5:23:21uh connection per component rather than
- 5:23:24something that in the worst case could
- 5:23:25be exponential if every component wanted
- 5:23:28to connect to every other component. And
- 5:23:30this may seem trivial in the context of
- 5:23:33connecting RAM and the ALOU, but uh you
- 5:23:37know now that we've once we finished
- 5:23:38these two components, we're going to go
- 5:23:40ahead and add a few more simpler ones to
- 5:23:42the computer. Simpler in terms of
- 5:23:44understanding them, but still critical
- 5:23:46for correctness and actually making this
- 5:23:48computer run independently without us
- 5:23:50needing to punch everything. Um so as
- 5:23:53long as you can agree or understand
- 5:23:54what's happening here, then um that
- 5:23:58makes sense. So then similarly you know
- 5:24:00like if we wanted the output of RAM to
- 5:24:03be input uh possibly to each of our
- 5:24:05operands for the ALOU we just write this
- 5:24:08output of RAM onto the bus. We connect
- 5:24:10RAM to the output of RAM to the bus and
- 5:24:12then we connect each of these input
- 5:24:14registers to the bus as well. Um and
- 5:24:16that works uh you know we could
- 5:24:19literally hardcode these wires as is. Uh
- 5:24:22and then similarly you would want to say
- 5:24:25if we want to then write the output of
- 5:24:27possibly an arithmetic computation into
- 5:24:30RAM we just connect our output here to
- 5:24:32the bus and then we could connect our
- 5:24:34our our input over here to the bus as
- 5:24:36well. And that way you know if there was
- 5:24:38we had some result here and we wanted to
- 5:24:40write it. We'd you know let this value
- 5:24:41write to the bus. We we'd tell hey RAM
- 5:24:43RAM needs to stop writing onto the bus.
- 5:24:46Um this value can write it it's what it
- 5:24:48wants onto the bus. And then uh this
- 5:24:52value over here can can
- 5:24:55read what's on the bus and then you know
- 5:24:57we punch in the right address and you
- 5:24:59know pulse this clock and that'd be
- 5:25:01fine. So the only thing to be careful
- 5:25:03about here um anything can read from the
- 5:25:06bus. Reading from the bus is free. So
- 5:25:08literally to connect these registers to
- 5:25:10the bus I just wired them in as is. But
- 5:25:13the issue is we have to be careful to
- 5:25:17ensure that only at most one thing is
- 5:25:20writing to the bus at a given time. It
- 5:25:22is totally fine if nothing is writing to
- 5:25:24the bus. But we'd uh we cannot have two
- 5:25:27things writing to the bus. The reason
- 5:25:29this cannot happen is because you could
- 5:25:32short your entire circuit. So what
- 5:25:35happens if this wants to write a one to
- 5:25:39this wire of the bus and this is still
- 5:25:41just connected to the bus without any
- 5:25:42disconnecting capability. Uh and this
- 5:25:44writes a zero to the bus. So what
- 5:25:48happens is if you're writing a one to
- 5:25:50the one to a wire and a zero to a wire
- 5:25:53well the wire as we learned earlier can
- 5:25:55only have a zero or a one but you are
- 5:25:57simultaneously trying to write a one and
- 5:25:59a zero to the wire at the same time. Um,
- 5:26:03this this is bad. This can't happen.
- 5:26:05It's going to actually, you know, it
- 5:26:06would it would break your computer. So,
- 5:26:09I actually don't know the the physics
- 5:26:11behind this too well about electricity
- 5:26:13itself. So, I won't try to speak to this
- 5:26:15too much. Um, I believe this is just
- 5:26:17called a short circuit. You know,
- 5:26:19connecting high to low directly with
- 5:26:21electricity uh will cause like a surge
- 5:26:23of electricity to flow through uh and
- 5:26:26it'll just like blow your computer. Um,
- 5:26:28I'm not going to say anything more than
- 5:26:29that because honestly I don't
- 5:26:30understand. But, um, that's what we need
- 5:26:33to be careful about. Uh, the issue that
- 5:26:36I just described only applies when two
- 5:26:37things try to write onto the bus at the
- 5:26:39same time. I said that they only apply
- 5:26:41when you try to write onto the bus uh,
- 5:26:44and not when you read from the bus. And
- 5:26:45that's because when you're reading from
- 5:26:47the bus, you're not like these
- 5:26:48components aren't actually putting out a
- 5:26:50zero or a one. It's just reading what's
- 5:26:52on the wire connecting to it. So uh
- 5:26:54reading from the bus is fine because
- 5:26:55you're not actually putting a value out
- 5:26:57there. The issue is when you put
- 5:26:58possibly contradicting information onto
- 5:27:00a wire. So how do we get around this is
- 5:27:04something called a in this case um we
- 5:27:07will what we'd like to do is simply uh
- 5:27:10if we know something is about to write
- 5:27:13onto the bus uh that and we want we
- 5:27:15would actually want to you know
- 5:27:16establish that connection with the
- 5:27:18outputs onto the wires. Um, but if
- 5:27:21something is that something is in a
- 5:27:23state where it could write to the bus in
- 5:27:24the future, but it doesn't want to right
- 5:27:26now, we need to disconnect it
- 5:27:28physically. So, uh, one way is, you
- 5:27:30know, simply destroy the wires and then
- 5:27:32reinstrument them when you do actually
- 5:27:34want to ride on the bus. That's pretty
- 5:27:35painful to do. So, instead, what we have
- 5:27:38is, uh, turns out this is a common
- 5:27:39enough thing that we can just use
- 5:27:42something called a
- 5:27:44switch. um
- 5:27:49switch. Oh, there's a whole section for
- 5:27:51them. And what the switch will let us do
- 5:27:53is it'll literally, you can kind of see
- 5:27:54this in this diagram. It might be a
- 5:27:56little small. Um uh if I click it, uh
- 5:28:00it'll, you know, connect the two ends of
- 5:28:02the wire. So, here's your switch. You'd
- 5:28:03have something like this and then this.
- 5:28:06So, in this current state, these two
- 5:28:08wires are not connected. But then if I
- 5:28:10was writing the simulation, I clicked
- 5:28:11it, it drop this down and it connected
- 5:28:13two wires. And so that's pretty much
- 5:28:16what we're going to use here. When we
- 5:28:17don't want this or this to be writing
- 5:28:19onto the bus, uh, then we disconnect it.
- 5:28:22And when we do want to write its value
- 5:28:23onto the bus, we'd click it and it would
- 5:28:25drop down and establish a full
- 5:28:26connection. So let me go ahead and wire
- 5:28:29this up and then we'll come back and see
- 5:28:30what that actually looks like in
- 5:28:32practice.
- 5:28:51Okay, so I finished wiring things up. A
- 5:28:54few changes I've made. So, first off, we
- 5:28:56had a lot of extra space here. Uh, I I
- 5:28:58condensed things in. No functional
- 5:29:00changes there, but just wanted to make
- 5:29:02things so I had to do less navigation
- 5:29:04and zooming around.
- 5:29:06Second thing you'll see is I've
- 5:29:07implemented the bus right here. It's
- 5:29:09just four ordinary wires. The A and B
- 5:29:12registers to our ALU read in into each
- 5:29:16of their corresponding data bits from
- 5:29:18this bus.
- 5:29:21Similarly, the output writes onto the
- 5:29:24bus, but it's gated behind these
- 5:29:26switches we've talked about. Therefore,
- 5:29:29we don't risk two different components
- 5:29:30running onto the bus at the same time,
- 5:29:32breaking our circuit and leading to an
- 5:29:34invalid state. And I've also updated
- 5:29:38RAM. So, the output of RAM also writes
- 5:29:42onto bus. And similarly, it's gated
- 5:29:45behind these switches for the
- 5:29:46affformentioned reasons. And on top of
- 5:29:49that, for when we want to write read
- 5:29:51values uh from the bus into a specific
- 5:29:54part of RAM, I've now connected our
- 5:29:56input lines which we previously had as
- 5:29:58toggles up here uh onto the bus. And
- 5:30:02then other thing I've done, I've added
- 5:30:06outputs to our bus so we can easily see
- 5:30:08the value on the bus. It's already
- 5:30:10apparent by like the dark green versus
- 5:30:12light green. I just think sometimes
- 5:30:14having this explicit signal is easier to
- 5:30:18uh see, especially if if you're watching
- 5:30:21this on a phone or something. And then
- 5:30:24um the last changes I've made are up
- 5:30:26here. So the first one is for being able
- 5:30:29to uh write stuff onto the bus myself
- 5:30:32manually. I have these input lines and
- 5:30:35they're also connected by switches
- 5:30:37because that's writing onto the bus
- 5:30:38which has to be gated against. And uh
- 5:30:41this is because when we turn on our
- 5:30:43computer, all of the registers,
- 5:30:45flip-flops in this software will
- 5:30:48initialize to zero. So everything in RAM
- 5:30:51will be zero. Everything in the ALOU
- 5:30:52will be zero. So if we wanted to move
- 5:30:54values from RAM to the ALOU, do some
- 5:30:56math and then send them back to
- 5:30:57different address in RAM. It would be uh
- 5:30:59inconsequential
- 5:31:01um because every value is zero. So when
- 5:31:04we turn on the computer or start the
- 5:31:06simulation, I'll use this these manual
- 5:31:08toggles to write some values into
- 5:31:10specific addresses of RAM. And that way
- 5:31:12we can actually move them onto the bus
- 5:31:14and then into a register of the ALOU op
- 5:31:17one of the ALOU operand registers. And
- 5:31:19then we'll actually have some sensical
- 5:31:20data about rather than dealing with a
- 5:31:22bunch of zero plus zeros. And the last
- 5:31:25thing I've done is uh you probably
- 5:31:28noticed that we have a decent number of
- 5:31:29signals now. Uh signals, flags, however
- 5:31:32you want to call it, but um basically we
- 5:31:34have several registers. So you know we
- 5:31:36need a a flag to write into the register
- 5:31:38A, a flag to write into register B. For
- 5:31:41our ALOU, we have an add subtract flag.
- 5:31:43Then we also have a flag to update a
- 5:31:45specific address in RAM. Then we have
- 5:31:47two inputs um for when we want to select
- 5:31:49a specific address in RAM. So I grouped
- 5:31:52all of these up here. And I also wanted
- 5:31:54to call out that uh or highlight doubly
- 5:31:57so that these switches which control
- 5:31:59whether or not we write onto RAM are
- 5:32:01right now something that we'll have to
- 5:32:02click and toggle. Uh if we use a
- 5:32:04different unit, we could you know kind
- 5:32:06of add that functionality uh as
- 5:32:08something we toggle here. Uh maybe I'll
- 5:32:10do that afterwards. But what I wanted to
- 5:32:12highlight is that um these these two
- 5:32:16areas or three areas we write onto RAM
- 5:32:18plus these are all that we have to
- 5:32:20control. And once we get this
- 5:32:23demonstration working, uh, a natural
- 5:32:25next question is like, well, okay, these
- 5:32:27things are all punched by humans. So
- 5:32:28like, how do we actually get the
- 5:32:29computer to know like a how is it, how
- 5:32:32could it be possible the computer could
- 5:32:33even know to punch certain things? Like
- 5:32:36what is the computer meant to be doing
- 5:32:37when it's turned on? And b, if the
- 5:32:39computer had some instruction uh about
- 5:32:42what it should be doing, then how could
- 5:32:44we actually rearchitect this to make it
- 5:32:47such that the computer itself can be the
- 5:32:49one pushing these buttons? Um, and I I
- 5:32:52say that lightly because it doesn't
- 5:32:53actually look at that in practice, but
- 5:32:54uh the computer is not physically going
- 5:32:56out and pushing these. It just it's
- 5:32:58wired into control. That's the output of
- 5:33:00some other decision-making part of our
- 5:33:02computer that we'll get to. Um, but I
- 5:33:05digress there. So now what I'm going to
- 5:33:07do is go ahead and power this on. Uh, as
- 5:33:09I kind of mentioned, you know,
- 5:33:11everything is is all zeroed out. So if
- 5:33:13I, you know, if I pulse pulse any
- 5:33:16address in RAM, you can see that the
- 5:33:18output here is zero. And then the other
- 5:33:20thing that's actually new here is we've
- 5:33:22seen in this software that you know zero
- 5:33:24uh is this dark green and this brighter
- 5:33:27green is denotes a one and we see that
- 5:33:30on all of our wires and stuff but now
- 5:33:31for the first time we're seeing gray
- 5:33:33here. Uh and what is gray here? Gray
- 5:33:36would be the absence of zero or one. So
- 5:33:38now that we uh have things that connect
- 5:33:40to the bus conditionally if nothing is
- 5:33:43writing to the bus at any time then
- 5:33:44there is simply just no values on the
- 5:33:46bus which is fine. It's just a different
- 5:33:49state that we uh we think about. You
- 5:33:51know, we're used to our our wires and
- 5:33:53all of our uh logic gates taking in
- 5:33:55strictly zeros or ones. And that is true
- 5:33:57and that still has to hold true. Um but
- 5:34:00you know, it's not actually you can have
- 5:34:02a wire. You can imagine this. It's not
- 5:34:04that difficult a concept. If you just
- 5:34:06had a physical wire that you held in
- 5:34:07your hand that was not connected to
- 5:34:09anything on either end, that would have
- 5:34:11neither a zero or one uh no amount of
- 5:34:14electricity on it. So that's what we're
- 5:34:16seeing here. But uh if I actually want
- 5:34:18to put some values on the bus manually
- 5:34:19specified then uh you can see I can
- 5:34:22toggle these switches which connects
- 5:34:24it'll connect you know here's my input
- 5:34:26line to the this line of the bus and
- 5:34:27then you can see that you know since
- 5:34:29we've now written values onto the bus
- 5:34:31anything that connects to the bus and
- 5:34:33the bus itself now has zeros or ones on
- 5:34:35it. So let's say we want to uh write
- 5:34:38some values into RAM. Now let's say I
- 5:34:41just want to do something simple like in
- 5:34:43address zero of our RAM I want to write
- 5:34:45the value one. In address two of the RAM
- 5:34:49I want to write the value two. And then
- 5:34:51I want to add that one in that two. I'd
- 5:34:54expect a three. And then I want to write
- 5:34:56that back to a different address in RAM.
- 5:34:58Um how can we do this? So first let's
- 5:35:01use this manual hack I have. Let's write
- 5:35:03one onto the bus. And let's actually
- 5:35:05write uh that that value one. Let's read
- 5:35:09that from the bus into the RAM address
- 5:35:11zero. So we already have address zero
- 5:35:13selected. So that's not that
- 5:35:14interesting. And then all I need to do
- 5:35:16now is pulse this line for writing into
- 5:35:18RAM. And recall when we go from a low to
- 5:35:21a high, RAM will catch that value. You
- 5:35:23can kind of see that happening
- 5:35:24internally. You can see, you know, uh
- 5:35:26we're not letting RAM write onto the
- 5:35:28bus, but if we did, it's trying to write
- 5:35:29the value one. So that's cool. That
- 5:35:31seems to work. Now we want to write the
- 5:35:33value uh three two into actually let's
- 5:35:36let's write an interesting value. Let's
- 5:35:37write the value three um into the next
- 5:35:40address in RAM. So I I put the value
- 5:35:42three onto the bus and let's write that
- 5:35:43into address 01. And um I messed up uh
- 5:35:48it already actually captured the value
- 5:35:51as you can see. Recall what we talked
- 5:35:52about 20 minutes ago. I should have let
- 5:35:54this value fall back to zero after I
- 5:35:56wrote into the RAM, but I didn't. Um so
- 5:35:59I fixed that now. put the the values in
- 5:36:00RAM. And now let me go ahead and
- 5:36:04disconnect our manual input from the bus
- 5:36:07and connect the output of the RAM unit
- 5:36:10onto the bus. And so now I can see if I
- 5:36:13select address zero on the RAM selector,
- 5:36:16we have the value one in address zero.
- 5:36:19And if I select address one, we have the
- 5:36:21value three. So we can see that we've
- 5:36:23correctly written these values into RAM.
- 5:36:25And now that we've written values into
- 5:36:27RAM, let's get those into the ALOU. So
- 5:36:29let's put the value one into this
- 5:36:32register and then the value two into
- 5:36:34this register and we'd hope to see a
- 5:36:36three. So I have the value one written
- 5:36:38on the bus because I have address zero
- 5:36:39selected. And now what I need to do is
- 5:36:42toggle the line to write into register
- 5:36:44A. So I'll do that. And now register A
- 5:36:46has the value one. I'll put that low.
- 5:36:49Now I want to write uh the register I
- 5:36:51want to take what's in address two of
- 5:36:53RAM and write it into this register. So
- 5:36:55let's put address two of RAM onto this
- 5:36:57bus. At address two, we have the value
- 5:36:59three. And I'll now post the line for
- 5:37:02writing into register B. And when I do
- 5:37:04that, you can see there's now this three
- 5:37:05there. And so, um, now what I'm going to
- 5:37:09do, I've done writing stuff from RAM
- 5:37:11into these registers. So, I'm going to
- 5:37:13disconnect our RAM output from the bus.
- 5:37:16And now what we can see happening is
- 5:37:19that our ALU, uh, well, this was
- 5:37:21happening before I disconnected the bus.
- 5:37:22I just didn't want to forget to do that.
- 5:37:24Our ALOU has the output of three + one.
- 5:37:29And we can see that it's trying to write
- 5:37:31four onto the bus. We disconnected it
- 5:37:33though. So let's connect the output of
- 5:37:35the ALU onto the bus. And we see that
- 5:37:38the value four is out there. And let's
- 5:37:40write that back into a register. Let's
- 5:37:42let's say let's write it into the
- 5:37:44original address uh zero address zero in
- 5:37:47RAM. Um I'll do that by setting the
- 5:37:50correct address uh field. And then I
- 5:37:53will pulse the flag to write into RAM.
- 5:37:56And that should be done. So if I now
- 5:37:58disconnect our ALOU from writing onto
- 5:38:00the bus and let RAM write its value back
- 5:38:02onto the bus. I can now see that with
- 5:38:04address zero selected, the value four is
- 5:38:07what's stored in there. Uh and if I
- 5:38:09pulse back to the other address we set,
- 5:38:10we'd expect a three, which we see 1 + 2.
- 5:38:13Um and so yeah, this looks functionally
- 5:38:15complete. Uh and this is pretty
- 5:38:17interesting because now we're doing
- 5:38:19complex arithmetic. you know we have
- 5:38:21four different values we can be
- 5:38:22operating with. So we can do a plus b
- 5:38:26minus c plus d whatever we want to do by
- 5:38:29you know simply moving values from RAM
- 5:38:31into these corresponding registers
- 5:38:33setting the add or subtract flag if we
- 5:38:34want to do subtraction letting the ALU
- 5:38:37do its computation writing that value
- 5:38:39back onto the bus and then reading it
- 5:38:40from the bus back into RAM. And you can
- 5:38:42kind of see we we did something very
- 5:38:43sequential here. you know, this is very
- 5:38:45reproducible. Um, you know, to to write
- 5:38:48a value onto the uh to read a value from
- 5:38:51the bus into RAM, you have to, you know,
- 5:38:53specify the address plus the flag. Then,
- 5:38:55if you wanted to read a value, write a
- 5:38:57value from RAM onto the bus, you need to
- 5:38:58connect the the uh RAM output to the
- 5:39:02bus, select the right address, and then
- 5:39:04it'll be on the bus. And then, we wanted
- 5:39:07to read the value from the bus into one
- 5:39:08of these registers, we just do the same
- 5:39:10thing. We just post that flag. Uh, it's
- 5:39:12pretty interesting. So the last thing I
- 5:39:14want to show here is I said you can't
- 5:39:16write zero and one uh to the bus at the
- 5:39:19same time else you cause a short. So
- 5:39:23we have the value uh let's look at this
- 5:39:25rightmost the rightmost bus position has
- 5:39:27a one on it. Let's what see what happens
- 5:39:29if I put a zero on it and then try
- 5:39:32connect this zero to the bus. And when
- 5:39:34that happens what you're going to see is
- 5:39:35that we're connecting a zero and the one
- 5:39:37and I guarantee you the software is not
- 5:39:39going to like it. Perfect. Yeah. So more
- 5:39:42than one output is active on a wire
- 5:39:44causing a short circuit. Cool. So I was
- 5:39:46right that when you try to write a
- 5:39:48concurrent zero and a one onto a
- 5:39:50specific wire, it's called a short
- 5:39:51circuit. Um cool. So
- 5:39:56that uh now concludes our ALU and our
- 5:39:59RAM sections. Uh this is probably the
- 5:40:02trickiest part. Uh it is a tricky part
- 5:40:06to reason about holistically. you know,
- 5:40:08you get into a a lot of logic gates, but
- 5:40:10um the rest of the stuff we the next few
- 5:40:13things we'll do are far simpler and uh
- 5:40:15are just going to iterate on uh be
- 5:40:17things actually reductions of what we've
- 5:40:18already seen. So, the next little bit of
- 5:40:20the video should be a bit chiller.
- 5:40:24So, one of the things that you might
- 5:40:26have noticed that can be kind of
- 5:40:27annoying during this process was uh
- 5:40:29trying to go from binary values to
- 5:40:31figure out what the actual decimal value
- 5:40:33was uh for a particular thing. So, you
- 5:40:36know, if we were feeding an address to
- 5:40:38our RAM, uh, we kind of had to like peek
- 5:40:40at these four lines and see which vendor
- 5:40:42were set to then know what the actual
- 5:40:44value was. And that's kind of how we
- 5:40:45were sanity checking. Similarly, if we
- 5:40:47wanted to know what was stored in the
- 5:40:48registers for the ALOU, the A and B
- 5:40:50registers, we kind of have to look at
- 5:40:52these four lines or these four lines and
- 5:40:54and figure out what's happening uh what
- 5:40:56the actual value is. And you know this
- 5:40:59is 4bit values so it's not too much
- 5:41:02effort to do it but it can be kind of
- 5:41:03annoying to go to have to do that so
- 5:41:04much um especially when you're you know
- 5:41:07kind of early onto this and still bring
- 5:41:08your intuition. So what if we had a way
- 5:41:12to actually just visualize the numbers?
- 5:41:14You know, we know computers
- 5:41:16operate in base 2 binary, but you know,
- 5:41:20us humans when we're debugging these
- 5:41:21machines or or trying to inspect the
- 5:41:23internal state at any particular time.
- 5:41:25Be nice to be able to see like, hey,
- 5:41:27like what values on the bus, uh, and I
- 5:41:30could see that, you know, just as digits
- 5:41:32without having to, you know, scroll in
- 5:41:34to the bus and look at each of the wires
- 5:41:36and, you know, start counting powers of
- 5:41:38two and adding them together to figure
- 5:41:40this out. And um for this we have
- 5:41:43something called a seven segment
- 5:41:44display. So I'm going to hop over here.
- 5:41:47Um and this is something that you can
- 5:41:50see takes in a binary input up here i.e.
- 5:41:53machine readable values and it'll it'll
- 5:41:56draw out the actual uh decimal value
- 5:41:59that we can see that we can easily
- 5:42:01reason about. And some of you may have
- 5:42:04seen this some of you may have claimed
- 5:42:05to have never seen this before but I
- 5:42:06guarantee that you actually have seen
- 5:42:08this. If I come over here, uh this is a
- 5:42:11scoreboard, a picture of a scoreboard
- 5:42:13probably that you maybe have seen in
- 5:42:14your high school. And you can see that
- 5:42:17actually everything is a seven seg seven
- 5:42:19segment display. So why do we call it a
- 5:42:22seven segment display? If you look at
- 5:42:24each of these numbers, let's just pick
- 5:42:26this one here arbitrarily. You can see
- 5:42:28that there's um seven different lines
- 5:42:32that make up the display. So there's
- 5:42:34four up here and then three in the
- 5:42:36bottom. 4 + 3 7. And
- 5:42:41um by turning on or off certain
- 5:42:43combinations of these individual lights,
- 5:42:46we can create the illusion of drawing
- 5:42:48the number. And I wouldn't even say it's
- 5:42:50an illusion. We actually just are
- 5:42:51drawing the number. And uh this is a
- 5:42:54pretty simple way, you know, without
- 5:42:55having to get a whole LCD display, which
- 5:42:58we'll talk about later. Um, it's an easy
- 5:43:00way to draw numbers in a way that this
- 5:43:03is significantly easier to see that this
- 5:43:04is a two rather than trying to like do
- 5:43:06some binary to decimal conversions and
- 5:43:09reason about that yourself. And there
- 5:43:12are things like there's seven segment
- 5:43:14display, there's higher number segment
- 5:43:16displays um, and those can do more
- 5:43:19complicated things and maybe show
- 5:43:21symbols like the division symbol. Um,
- 5:43:24for the sake of illustration here, we're
- 5:43:25going to keep it to seven segment
- 5:43:27displays. And we're also going to keep
- 5:43:30it down to just one single digit. So,
- 5:43:33uh, we know that our bus here is the one
- 5:43:35we've built is actually four bits. So,
- 5:43:37there's two to the four different val
- 5:43:40uh, different numbers. Sorry, there's 2
- 5:43:42to the^ of four different values that we
- 5:43:45could write on the bus. 2 to the^ of
- 5:43:47four is 16, which means we can represent
- 5:43:50with these four bits numbers 0 through
- 5:43:5115. So, it turns out digits 10 through
- 5:43:5415 require two of these displays if we
- 5:43:57wanted to. Um, the logic is the exact
- 5:44:00same. It just requires more effort. And
- 5:44:02so, we're going to keep it simple and
- 5:44:03say that like our display for now will
- 5:44:05only show the numbers 0 through 9. And
- 5:44:08uh you'll understand that if we wanted
- 5:44:10to have uh we could put two of these
- 5:44:12next to each other if we wanted to
- 5:44:14handle two digits, but it just requires
- 5:44:16a lot more work uh and doesn't teach you
- 5:44:18anything that you wouldn't learn uh by
- 5:44:20doing the one seg the one individual
- 5:44:22digit display. And so this is what this
- 5:44:25chip looks like in real life. You can
- 5:44:27kind of see there's uh several pins on
- 5:44:29the bottom here. And turns out if you
- 5:44:32write a one or put power these are
- 5:44:35synonymous things uh to one of these
- 5:44:37specific pins then it'll light up a
- 5:44:39corresponding part of the display. And
- 5:44:42so if I look at a diagram uh that I
- 5:44:45found online for what one of these these
- 5:44:47physical units that you can buy what
- 5:44:49that pin structure looks like, you kind
- 5:44:51of see that uh you know we have these
- 5:44:54these individual lights labeled A, B, C,
- 5:44:57D, E, F, and G. It kind of wraps
- 5:44:59clockwise with the G being the last one.
- 5:45:01And they each correspond to a specific
- 5:45:04uh input pin. So if I put one here and
- 5:45:07zeros for the rest of these, we'd see
- 5:45:10just this one light up. And you're also
- 5:45:12probably wondering, uh, well, we have
- 5:45:14inputs A through G. That makes sense.
- 5:45:16What is this DP and ground? Um,
- 5:45:20in this specific unit, DP will let you
- 5:45:23hit that decimal point. And then ground
- 5:45:26is just effectively you need to give it
- 5:45:28power. Um, so it can complete the
- 5:45:30circuit internally. We don't really have
- 5:45:31to worry about that for the sake of what
- 5:45:33we're building here. Um, but let's
- 5:45:36actually see like what each number looks
- 5:45:38like visually. So you can see we can
- 5:45:41represent numbers zero through nine. And
- 5:45:45to turn to represent the number uh zero,
- 5:45:47we turn on A, B, C, D, E, and F. And
- 5:45:52we'd leave G off. And for the number
- 5:45:54one, uh we just turn on B and C and
- 5:45:57leave everything else off. And you can
- 5:45:59see that we can kind of just draw out
- 5:46:00every number and pretty easily see what
- 5:46:03we need to turn on to get each digit
- 5:46:05position ready. So, what I've done is
- 5:46:09gone ahead and made that into a table.
- 5:46:12Um, we have our 10 different numbers
- 5:46:14that we're going to be capable of
- 5:46:15drawing with our singledigit display.
- 5:46:18And, uh, you can see decimal numbers
- 5:46:21zero and then I have that in binary 2.
- 5:46:24And you can see that, you know, for
- 5:46:26zero, uh, you'd turn everything on
- 5:46:28except G. And if I tab back here, you
- 5:46:30can kind of see that's the same source
- 5:46:32of truth we have here. We can check one
- 5:46:34more as well. uh let's say the digit
- 5:46:36seven, you'd only turn on A, B, and C.
- 5:46:38So if I look here at digit seven, we can
- 5:46:41see that only A, B, and C are on, and
- 5:46:43the rest are off. And so this probably
- 5:46:44looks familiar. This is the truth table
- 5:46:46that we looked at way earlier in this
- 5:46:48video. Um, and what I'd like to do is
- 5:46:52actually go back to our software and and
- 5:46:55build something out that'll let you
- 5:46:58specify your 4bit binary value and it'll
- 5:47:02correctly light up the correct segments
- 5:47:04of the display. Um, so if I tab back
- 5:47:07here, I can see that my software that
- 5:47:11I'm using actually lets me have this.
- 5:47:13Uh, so I've wired in our display and it
- 5:47:16has uh, you know, pins for each of the
- 5:47:20values. And so I can kind of see here's
- 5:47:22that A, here's B, C, D,
- 5:47:27E, F, G, and then the bottom right here
- 5:47:31is the decimal point. We're not really
- 5:47:32going to use it, so we don't really have
- 5:47:34to worry about it for now. But uh what
- 5:47:36I'd like to do is go from this truth
- 5:47:40table to logic gates that actually
- 5:47:42correctly light up the display. So let's
- 5:47:44see if I look at uh this position A
- 5:47:48here. Um position A, then I can see that
- 5:47:52what numbers on the input line should
- 5:47:55turn position A on. You can see that's
- 5:47:57numbers one, two, or sorry, that's
- 5:47:59number zero, two, three, five, six, 7,
- 5:48:068, and 9, which is kind of what we see
- 5:48:08in this table here. If I look at the
- 5:48:09column for a, when should a be turned
- 5:48:12on? It looks like it's for every number
- 5:48:14except one and four. So then what I'd
- 5:48:17want to do is if I had, you know, the
- 5:48:19four uh binary inputs coming down from
- 5:48:23the bus, if that's what we wanted to
- 5:48:24display at any time, then I need to do
- 5:48:27some logic where like if the value of of
- 5:48:30the four bits represents any of those
- 5:48:32numbers, then this input line should
- 5:48:34turn on. And we do that for each of the
- 5:48:37each of the different segment uh pills
- 5:48:39that we have on our display here. And it
- 5:48:42turns out we've already done something
- 5:48:44pretty similar to this. We built this
- 5:48:45decoder earlier for RAM where we have
- 5:48:48something uh it's easier because there's
- 5:48:50only two bits of addressing space for
- 5:48:52our RAM. But basically we know that
- 5:48:55whatever value the user puts on RAM uh
- 5:48:58we can correctly select the right index
- 5:49:01uh in our RAM. So you know uh it's 0 0
- 5:49:04right now and we see this first position
- 5:49:06lights up. When I put in one, I see that
- 5:49:08second position lights up. And if I put
- 5:49:11in the maximum index, that's 2 + 1 3.
- 5:49:14And I can see 0 1 2 3. Uh index number
- 5:49:18three lights up. So we've already built
- 5:49:19out this decoder logic earlier. So we're
- 5:49:22literally just going to do the same
- 5:49:23thing except this time we have to extend
- 5:49:25it uh to be four bits, which is a little
- 5:49:27more complicated. So, what I'm going to
- 5:49:29do is bring our bus further down
- 5:49:34and
- 5:49:36build this off to the side here.
- 5:49:39So, I'm going to actually pause the
- 5:49:41video or just speed through this part um
- 5:49:44and and we'll we'll talk through the
- 5:49:46output.
- 5:50:03Okay, so I've gone ahead and built this
- 5:50:05decoder and uh basically what I have I
- 5:50:08detach it from the bus so it's its own
- 5:50:10unit. Right now I have a 4bit input and
- 5:50:13for each of those bits um I actually
- 5:50:16carry that input bit down and then also
- 5:50:19I carry a negated version of it all the
- 5:50:20way down. Um, and the reason I do that
- 5:50:23is because if I jump over to our RAM,
- 5:50:26basically what we had to do for our RAM
- 5:50:28whenever we wanted to negate a line was
- 5:50:30to manually add an inverter.
- 5:50:33And uh this means we end up using a lot
- 5:50:36several inverters when really if we just
- 5:50:38used one inverter up here to create a
- 5:50:41forked version of or two one per line,
- 5:50:44two different inverters to create a
- 5:50:45forked variant that inverts each of the
- 5:50:47two input bits, then we could have just
- 5:50:49had our inputs pulled in from these
- 5:50:50hypothetical lines directly. So, not
- 5:50:52only does it use fewer logic gates to do
- 5:50:54it the way we've done here, I'd also
- 5:50:56argue it actually makes things easier to
- 5:50:58read because we kind of know this means,
- 5:51:00you know, uh, leftmost bit and then the
- 5:51:03inverse of the leftmost bit, and then
- 5:51:05bit position number two, the inverse of
- 5:51:07that, bit position number three, the
- 5:51:09inverse of that, the rightmost bit
- 5:51:11position, the inverse of that. And so,
- 5:51:12you can kind of see then, you know, uh,
- 5:51:15this would correspond to zero, then one,
- 5:51:17two, and so on. So for zero, what I'm
- 5:51:19doing is I'm looking for 0 0 0 which is
- 5:51:22the inverted of all of the bits. So 0 0
- 5:51:29and zero. And you can kind of see that
- 5:51:31you know uh if I were to turn this
- 5:51:33circuit on and all the inputs were zero
- 5:51:37then you can see all the inverted lines
- 5:51:39turn on and then that triggers this this
- 5:51:41and gate where it's looking for the the
- 5:51:44this bit positions off this bit
- 5:51:46positions off this bit positions off and
- 5:51:48this bit position is off and that's why
- 5:51:49we can see exactly one output lights up
- 5:51:52and we've decoded this input. Um, and so
- 5:51:56similarly, if I turn this off just for
- 5:51:57visualization, let's jump to the next
- 5:51:59one, which we'd expect to line up with
- 5:52:01the 00001. So, we can see there's the
- 5:52:05input in inverted of the first bit, the
- 5:52:08inverted of the second bit, the inverted
- 5:52:10of the third bit, and then the regular
- 5:52:14of the fourth bit. And that would give
- 5:52:15us that's saying 0 0 1. All four of
- 5:52:21those have to be true. So now if I
- 5:52:22powered this on and turn this to one,
- 5:52:24we'd see the same thing. And you kind of
- 5:52:26continue that logic all the way down.
- 5:52:28And we'll verify this is correct by
- 5:52:29counting through. So we tested zero and
- 5:52:31one. Now if I plug in two, we'd expect
- 5:52:33this third output to turn on. That's
- 5:52:36case. If I go to three, we'd expect this
- 5:52:39to come on. Cool. If I go to four, I'd
- 5:52:42expect the next one to come on. Then
- 5:52:45five. Cool. Then six.
- 5:52:50then seven
- 5:52:52and then
- 5:52:54eight and the last one is nine. Cool. So
- 5:52:58it looks like zero through nine work
- 5:53:00correctly. And so now that I have an
- 5:53:02output line for each of the numbers, um
- 5:53:05I can feed this into our seven segment
- 5:53:07display. So this simple one right here,
- 5:53:10this bit turns on. This is the A in our
- 5:53:13diagram. So if I come here uh I now want
- 5:53:17to pull that to be I want to ore all I
- 5:53:21would like to logically ore together all
- 5:53:23the numbers for which this a should be
- 5:53:25on which is 0 to so 0 2 3 5 6 7 8 9. So
- 5:53:31we will draw lines from all of those
- 5:53:34numbers that I just listed out. We will
- 5:53:36or them all together using several
- 5:53:38orgates and then feed it into this line
- 5:53:40right here. So, I'll go ahead and do
- 5:53:43that and then we'll uh come back.
- 5:53:50Okay. So, I've gone ahead and built out
- 5:53:53everything for all the logic for
- 5:53:55deciding if we turn on a this top line
- 5:53:57up here. And then for all the other
- 5:53:59inputs to seven segment display, I've
- 5:54:01just wired it to this thing right here,
- 5:54:03which is called ground. It just means
- 5:54:05zero. It's a logical zero. So, it means
- 5:54:07all the other segments will be off. And
- 5:54:09if I jump back to our table that we
- 5:54:11started with over here, I can see that
- 5:54:13we'd expect this A button to be on for
- 5:54:16everything except numbers one and four.
- 5:54:20So, let's go ahead and pulse through
- 5:54:22each of the input combinations and
- 5:54:25verify that this works. So, we start off
- 5:54:27with zero. And this is on. That's good.
- 5:54:30Now, I'm going to put one, and we'd
- 5:54:31expect it to turn off. That looks good.
- 5:54:34Two should be on. Three should be on.
- 5:54:39Four should be off. That looks good.
- 5:54:42Five should be on. Six should be on.
- 5:54:45Seven should be on.
- 5:54:47Eight should be on. And nine should be
- 5:54:49on. So this looks totally good. And
- 5:54:52we've done this together just by oring
- 5:54:55together everything except the two
- 5:54:57values for which this segment should be
- 5:54:59off. So that means if if one or sorry if
- 5:55:03zero or two or three or five or six or
- 5:55:09seven or eight or nine is selected by
- 5:55:13the user by the input then we should
- 5:55:15turn on that one. So this is kind of the
- 5:55:17logic uh and we'll go ahead and do this
- 5:55:19for the remaining ones.
- 5:55:38Okay, so we have built this out. You can
- 5:55:40see there's a lot of logic gates. Uh I
- 5:55:42probably could have done this more
- 5:55:43elegantly in hindsight, but uh should be
- 5:55:47working. Um, so you can kind of see for
- 5:55:50each of these uh what we did for this
- 5:55:52this A kind of repeated for B and C, D,
- 5:55:57E, F, and G oring a bunch of stuff
- 5:56:00together based on the input lines and
- 5:56:02then feeding them around to this uh
- 5:56:04seven segment display. And also that
- 5:56:07control bit for the dot we just hardcode
- 5:56:10to zero because we're not going to use
- 5:56:11it here. So let's go ahead and
- 5:56:15make sure that this works. So, I'll go
- 5:56:17one and then I'll count to two. That
- 5:56:20looks good. The next is three. That
- 5:56:22looks good. Then four. That looks good.
- 5:56:26Then five. That looks good. Then six.
- 5:56:29That looks good. Seven looks good.
- 5:56:33Eight looks good. And last but not least
- 5:56:35is nine. So we can see that 0 through
- 5:56:37nine work as expected. And then uh our
- 5:56:41logic gets set up so they work for 0
- 5:56:43through 9 correctly. We said we're not
- 5:56:45going to consider multi-digit
- 5:56:48uh numbers for now, but just out of
- 5:56:50curiosity, what happens if I tried to
- 5:56:52put in 10? And you can kind of see
- 5:56:55uh just by chance, you're this one lit
- 5:56:57up nothing. Um 11
- 5:57:0212
- 5:57:04Okay. Yeah. So,
- 5:57:07um I was expecting gibberish output, but
- 5:57:09that actually works. So, yeah, we can
- 5:57:11see this this works as expected. you
- 5:57:12didn't have to bear the pain of what I
- 5:57:14went through to make these logic gates,
- 5:57:15but you probably saw in the sped up
- 5:57:17version. And you might be wondering
- 5:57:19yourself, this seems kind of
- 5:57:20inefficient. Um, you know, for everyone
- 5:57:23who ever wants to use one of these
- 5:57:24displays, they'd have to rebuild the
- 5:57:26same exact circuit themselves, which
- 5:57:28kind of sounds interesting and uh
- 5:57:30redundant. And you can imagine there's
- 5:57:33other times where we'd want to replicate
- 5:57:36similar behavior because what we've
- 5:57:38effectively built here is a lookup
- 5:57:40table. So we we clearly specified here
- 5:57:45for every possible input here is the
- 5:57:48exact output we would want. Um and it
- 5:57:53turns out this is a very common thing
- 5:57:55and we'll actually come to it again not
- 5:57:56too long from now on our computer uh
- 5:57:58that there is a chip for this. So I'm
- 5:58:01going to tab over here um
- 5:58:05and there is something called ROM read
- 5:58:08only memory. So let's read the
- 5:58:10definition from Wikipedia. Readonly
- 5:58:12memory is a type of nonvolatile memory
- 5:58:15used in computers and other electronic
- 5:58:17devices. Data stored in ROM cannot be
- 5:58:19electronically modified after the
- 5:58:21manufacturer of the memory device.
- 5:58:23Readon memory is useful for storing
- 5:58:26software that is rarely changed during
- 5:58:27the life of the system. Software
- 5:58:29applications such as video games for
- 5:58:31programmable devices can be distributed
- 5:58:32as plug-in cartridges containing ROMs.
- 5:58:35So uh let's not get this confused with
- 5:58:38RAM. RAM stands for random access
- 5:58:40memory. I don't actually think I
- 5:58:42explained why it's called that. Uh RAM
- 5:58:44is called random access memory because
- 5:58:46in our implementation we can look at any
- 5:58:50specific address in RAM just by punching
- 5:58:53in a value. So it supports random
- 5:58:55lookups. Uh this might seem intuitive
- 5:58:57but earlier versions of of memory were
- 5:59:00actually sequentially accessed. So, if I
- 5:59:02as if I read address one, I would have
- 5:59:05to read address two next, and it'd have
- 5:59:07to uh circle all the way back around the
- 5:59:10address space for me to be able to read
- 5:59:12address zero if I'm at address one
- 5:59:14already. So, that's where RAM comes
- 5:59:16from. ROM, read only memory, is pretty
- 5:59:19different. Um, the second thing that we
- 5:59:22should break down in this definition is
- 5:59:23what is nonvolatile memory. So RAM is
- 5:59:26considered volatile because when you
- 5:59:28unplug and restart your computer,
- 5:59:32RAM starts off being zeroed out or has
- 5:59:35some random values. So the the values we
- 5:59:37put in these registers are not lock are
- 5:59:39not persisted. You can see that if I
- 5:59:40punch in a value and then stop the
- 5:59:42computer and start the simulation again,
- 5:59:44that value is gone. Um, and I guess the
- 5:59:48uh analogy to your computer is if you're
- 5:59:50typing on a word document, if you
- 5:59:53command S or control S if you're on
- 5:59:55Windows to save it, that writes it to
- 5:59:57your hard drive and that's that's
- 5:59:58stored. Until you do that, the text that
- 6:00:01you've you have pending in your editor
- 6:00:03is just sitting in RAM of your computer.
- 6:00:05And if you were to unplug it and plug it
- 6:00:07back in, you lose that data. So, you've
- 6:00:10probably seen this and dealt with the
- 6:00:11frustration before of computer shuts
- 6:00:13down or loses power, someone trips over
- 6:00:15the cord, and you lose all of the state
- 6:00:17of your computer. And that's because all
- 6:00:19those things are stored in RAM, which is
- 6:00:21significantly faster to access than from
- 6:00:23disk. Uh, but has this trade-off of, you
- 6:00:26know, not being persistent. But I
- 6:00:29digress. Um, so ROM is effectively a big
- 6:00:33lookup table. And something interesting
- 6:00:36about ROM is that it says it cannot be
- 6:00:38modified after the manufacturer of the
- 6:00:41memory device. So if I actually wanted
- 6:00:44um to build a readonly memory for what
- 6:00:47we' built right here, I'd need to find a
- 6:00:50manufacturer for ROM and effectively
- 6:00:52send them this table and they would
- 6:00:54manufacture a physical chip um that
- 6:00:58would look like this. and you would plug
- 6:01:00in your whenever you plug in your inputs
- 6:01:02on some of these pins, it's guaranteed
- 6:01:04to to light up the correct pins on the
- 6:01:06output. Uh, which is pretty cool, but
- 6:01:07you know, unfortunately,
- 6:01:10uh, that's kind of limited. You know,
- 6:01:11what if we accidentally made a mistake
- 6:01:13in this table, got that ROM chip, and,
- 6:01:17uh, realized that there was an issue,
- 6:01:19we'd be out of luck. You can't do
- 6:01:21anything about it. You'd have to go to
- 6:01:22the manufacturer and and get a new one.
- 6:01:25So, this is kind of inefficient. So what
- 6:01:27came after ROMs was called PROMs which
- 6:01:30stands for programmable ROM. And let's
- 6:01:34read the definition from Wikipedia. It
- 6:01:36says a PROM is a form of digital memory
- 6:01:38where the contents can be changed once
- 6:01:41after manufacturer of the device. So
- 6:01:44basically what this means is uh I mean
- 6:01:48it's exactly what it says. you now get
- 6:01:50the ROM chip that we kind of have here.
- 6:01:52But then there's also this burner and it
- 6:01:55lets you specify the values as you want
- 6:01:57them. So rather than having to spend
- 6:01:59that data sheet to the manufacturer, the
- 6:02:01manufacturer will just give you the ROM
- 6:02:02and you can burn in the values yourself.
- 6:02:05But if we look back to the definition,
- 6:02:07uh it can say it says can be changed
- 6:02:10once after manufacturer. So this kind of
- 6:02:12still has the same mistake. If you
- 6:02:14accidentally punch in the wrong value at
- 6:02:15a specific for a specific input
- 6:02:17combination, your chip's useless. Uh,
- 6:02:19and you'd have to throw it away and get
- 6:02:21a new one. So, that's also not optimal.
- 6:02:23Um, so what came after that was called
- 6:02:26EPROM. Stands for erasable programmable
- 6:02:30readonly memory. And so, we're not going
- 6:02:32to read this long definition, but what
- 6:02:34it is is I'll show you a picture of it.
- 6:02:36Uh, it looks very similar to the
- 6:02:38readonly memory we saw earlier, but it
- 6:02:40has this exposed element here. And it
- 6:02:43turns out that if you uh shine UV light
- 6:02:48onto this exposed element for enough
- 6:02:50time, usually it's like 15 or 20
- 6:02:52minutes, it'll wipe the entire contents
- 6:02:54of the ROM uh out. It'll replace
- 6:02:57everything with zeros, which means you
- 6:02:59could then take a a programmer and do
- 6:03:01the same kind of burning that we had for
- 6:03:03uh programmable ROMs. So, this is pretty
- 6:03:06cool. Um it now means that if we
- 6:03:08accidentally plug in a wrong value, we
- 6:03:10don't have to throw away our entire
- 6:03:11trip. we can actually uh just redo it
- 6:03:14ourselves. We can clear out the entire
- 6:03:16contents of the chip and then redo it
- 6:03:17ourselves and then it's still ROM at the
- 6:03:19end of the day. So once it's in my
- 6:03:21computer and I have it programmed, if I
- 6:03:23keep powering the computer on and off,
- 6:03:25the values in this lookup table will
- 6:03:27still exist. So that's cool, but
- 6:03:30um it turns out that's still suboptimal.
- 6:03:33As I just said, it takes 15 to 20
- 6:03:35minutes, I think, uh to clear out these
- 6:03:37erros. It also requires you to pull it
- 6:03:39out of your computer, which is not
- 6:03:40ideal. So the the latest thing we have
- 6:03:43um is called an EROM. Stands for
- 6:03:46electronically erasable programmable
- 6:03:48readonly memory. So let's build up from
- 6:03:50what we have. We know what a ROM is.
- 6:03:52That's just a basic lookup table.
- 6:03:54Programmable means that we can program
- 6:03:56it ourselves using this programmer tool.
- 6:03:58Erasable means that we are now able to
- 6:04:00clear the values of it um if we
- 6:04:03accidentally put in a different an
- 6:04:04incorrect value or just want to change
- 6:04:06it for our own reasons. Perhaps you want
- 6:04:07to use it in a different computer or
- 6:04:09something. And the last thing is
- 6:04:10electronically erasable. And that means
- 6:04:13that instead of having to pull it out of
- 6:04:15your machine and expose it to UV light
- 6:04:16for 20 minutes, there's simply uh a line
- 6:04:19on this that if you write uh if you put
- 6:04:22one on, it'll clear out the entire
- 6:04:23contents of the ROM. Um so this is
- 6:04:26pretty useful. And
- 6:04:29it turns out um we're going to need this
- 6:04:31in our computer again. So if I come back
- 6:04:34here then all this is to say these logic
- 6:04:38gates are functionally correct and work.
- 6:04:40But we could also just have used a um a
- 6:04:44some form of one of these variants of
- 6:04:46ROM ideally probably just like a EROM
- 6:04:48and uh program this table in uh using by
- 6:04:52burning the the physical values. So I
- 6:04:55literally burn in for this specific
- 6:04:57input 000000. These would be the outputs
- 6:05:00that the ROM should output. Now, I do
- 6:05:02that for all of the uh 10 different
- 6:05:03values. And that way, our wiring would
- 6:05:06be a lot easier. Instead of having all
- 6:05:08this right here, decoders uh feeding
- 6:05:10into all this mess of logic gates, we'd
- 6:05:12have the outputs here feeding into a ROM
- 6:05:14chip, and then the outputs of the ROM
- 6:05:16chip would just feed directly into the
- 6:05:17seven segment display.
- 6:05:19So, that's pretty cool. Um, and that's
- 6:05:22all we'll talk about for ROMs for now,
- 6:05:24but hold on to what we just learned
- 6:05:25because it turns out ROMs are going to
- 6:05:27be the the glue that irons this computer
- 6:05:30together. and lets us go from the human
- 6:05:32having to punch specific control lines
- 6:05:35to the computer knowing what it should
- 6:05:36do when based on some predetermined
- 6:05:39human instruction that exists somewhere
- 6:05:41in the computer's uh computer's mind. Um
- 6:05:45so the last thing I'm going to do here
- 6:05:46is right now this is connected to inputs
- 6:05:49that we're just toggling manually.
- 6:05:52Um I'm going to connect this to the bus
- 6:05:54so we can actually just see what values
- 6:05:56on the bus at any times uh for values
- 6:05:58that are under or equal to 9. But uh I
- 6:06:03will do one other thing where I'm
- 6:06:04actually uh going to hook that into a
- 6:06:06register. So the issue with just
- 6:06:09displaying the values of the bus at any
- 6:06:11time is we saw that when we were moving
- 6:06:13values in between uh RAM and the ALOU uh
- 6:06:16the state of the bus is changing pretty
- 6:06:18constantly. But if we just wanted to
- 6:06:20load something from RAM into the ALOU,
- 6:06:22do an operation, and then see what the
- 6:06:24result of it is on our display, uh it'd
- 6:06:26be easier if we uh could only display
- 6:06:30the value that's on the bus at a
- 6:06:32particular time. So the way we get
- 6:06:33around that is we just have our bus uh
- 6:06:37read in. We build a new register like
- 6:06:38we've done for the A registers here and
- 6:06:40the B register here. We just have
- 6:06:42another register and um it has its own
- 6:06:45control line. So right into the like we
- 6:06:48could say like the display register
- 6:06:50and whenever we pulse that line uh the
- 6:06:53register will latch whatever is on the
- 6:06:55bus and then that value will be locked
- 6:06:57into the display until the next time we
- 6:06:59change it. So that way even if the bus
- 6:07:00starts changing immediately and we just
- 6:07:02want to keep the value there. Um we
- 6:07:04don't have to you know have the user be
- 6:07:07seeing a bunch of intermediate values
- 6:07:09that are effectively nonsensical to
- 6:07:11them. And this would be pretty cool
- 6:07:13because uh you know one of the first
- 6:07:15programs we're going to write for our
- 6:07:16computer is just counting by twos. So
- 6:07:17we'd like to see like 0 2 4 6 8. And
- 6:07:21turns out if we didn't have a way to
- 6:07:23selectively decide when we'd want to
- 6:07:25display the value on the bus to the user
- 6:07:28uh I guess to the human um it'd be a lot
- 6:07:30of gibberish and you would see a lot
- 6:07:31more numbers being displayed than the
- 6:07:33the counting you'd expect even though
- 6:07:35your computer's working. but you just
- 6:07:37wouldn't really know um what to what to
- 6:07:40interpret versus what's a scratch value
- 6:07:42being used temporarily. So, let me go
- 6:07:44ahead and wire that up.
- 6:07:50Okay, so I've pulled the bus down a
- 6:07:52little further, added new a new
- 6:07:54register, 4bit register, and uh the
- 6:07:58clock signal for that register traces
- 6:08:00this wire all the way here, which is now
- 6:08:03w right into the out register. So
- 6:08:05whenever we pulse that from low to high
- 6:08:07uh whatever value is on the bus will get
- 6:08:09latched into this register and will be
- 6:08:11shown onto this display. And I've also
- 6:08:14prepared this by loading uh two values
- 6:08:17into RAM. So at address 0 we have the
- 6:08:20value we have the binary value 000 which
- 6:08:23is two and then at address one uh we
- 6:08:26have the value 00001 which is just one.
- 6:08:30Um so we can do we have two and one. uh
- 6:08:33let's load those from RAM into the ALOU
- 6:08:36and then do the arithmetic and then
- 6:08:38capture the result onto the uh output
- 6:08:41register and expect it to be displayed.
- 6:08:43So what I'll do is I will connect the
- 6:08:46RAM to the bus. Uh let's start with
- 6:08:49address zero. So we can see we have uh
- 6:08:52the value two written onto the bus.
- 6:08:54Let's write that into register A. Now
- 6:08:57let's switch to the second address in
- 6:08:59RAM and let's write that into register
- 6:09:04B.
- 6:09:05And now we can see that we have two in
- 6:09:07this register and one in this register.
- 6:09:10And
- 6:09:12um
- 6:09:15that all looks good.
- 6:09:18And
- 6:09:21let's go ahead and disconnect this
- 6:09:24from the bus.
- 6:09:27and connect these two connect the output
- 6:09:30of the alou. So now we can see the
- 6:09:32output of the uh RAM which was doing 2 +
- 6:09:361 is now three. That's binary 0011.
- 6:09:40And what I'll do oops uh doesn't really
- 6:09:44matter what address we're selecting on
- 6:09:45RAM. What I'll do is I'll pulse this uh
- 6:09:48right to our register. So I'll set the
- 6:09:50clock input on this register from zero
- 6:09:52to one which is triggers a rising edge
- 6:09:55which means the register will latch in
- 6:09:57the input value which is 0011
- 6:09:59corresponding to binary 3 and we'd hope
- 6:10:01to see that on our display. So let's go
- 6:10:04ahead and uh set this high. Congrats. We
- 6:10:09see three. I'll put this down low. So um
- 6:10:14now let's just take this a little bit
- 6:10:16further. So we have the output of three
- 6:10:18onto the bus. Let's let's do uh 3 + 1.
- 6:10:22So we have value three on the bus. Let's
- 6:10:24read that back into the reg the a
- 6:10:26register which has two
- 6:10:30and I can now see four is written on the
- 6:10:32bus. That's 0 1 0 0 which is binary
- 6:10:35four. So if I pulse this flag
- 6:10:38I can now see four is written on the
- 6:10:40bus. If I do the same thing I can keep
- 6:10:43just adding by one. So the steps we take
- 6:10:46now that we've gotten our computer into
- 6:10:47this state is to read the output of the
- 6:10:50ALOU which is on the bus into register
- 6:10:52A. Step one, read into register A. Step
- 6:10:56two is simply just update the out the
- 6:10:58out register.
- 6:11:01And now we're at five. And so I can just
- 6:11:02keep doing these two things.
- 6:11:16And you'll see that the uh the register
- 6:11:18just keeps counting up on the on the
- 6:11:19display. And if I then disconnect the
- 6:11:22output of the ALOU from the bus, you
- 6:11:25know, it doesn't affect our display. Um
- 6:11:26it still just holds on to that that last
- 6:11:28value. So our display is is is kind of
- 6:11:30stateful in a sense. It is a register
- 6:11:33which is then connected to a readonly
- 6:11:35memory that uh forks into a seven
- 6:11:39segment display.
- 6:11:41Cool. Um
- 6:11:43that's all we will do for now and let's
- 6:11:45jump back to my iPad.
- 6:11:49So we're back here and let's diagram
- 6:11:52where we left off uh at at a more
- 6:11:54abstract level rather than showing
- 6:11:55specific logic gs. Um so we can just
- 6:11:58reason at a higher level. So we have
- 6:12:00this bus
- 6:12:06and in the demonstrations we just built
- 6:12:10we had a 4-bit bus. Our computer as I
- 6:12:14said earlier is going to be an 8bit
- 6:12:16computer. The reason I was doing four
- 6:12:18bits in the demo is you could imagine
- 6:12:21that the complexity would just increase
- 6:12:23exponentially every time you add a more
- 6:12:25a new bit. So you know for each register
- 6:12:28there'd be a lot more control lines um
- 6:12:30and RAM would be a lot more complicated.
- 6:12:33So the the issue is for the sake of time
- 6:12:36it made more sense for me to work with
- 6:12:38four bit buses and four-bit values but
- 6:12:41the concepts are still the same for 8
- 6:12:42bits. You just imagine we literally
- 6:12:44extend everything. So all of our
- 6:12:45registers are 8 bits and um
- 6:12:50we will also increase our memory
- 6:12:52addresses for RAM to four bits. But
- 6:12:54let's just uh start with the bus. So
- 6:13:02six
- 6:13:047
- 6:13:068. Okay, so we have eight lines and uh
- 6:13:12this is going to be our bus.
- 6:13:16And so every component will connect to
- 6:13:18the bus from here on out. And the next
- 6:13:21thing we had was the alou. So I'll draw
- 6:13:24that.
- 6:13:33And the inputs to the alou were actually
- 6:13:36two registers. So we'll call this
- 6:13:38register
- 6:13:40A
- 6:13:43and its output fed into the first
- 6:13:45operand of our ALU. and then register B
- 6:13:50was our second operand and it both these
- 6:13:54always just feed straight into the ALOU
- 6:13:56but then they can also read values in
- 6:13:59from the bus. So these are both
- 6:14:02connected to the bus and
- 6:14:08and then we had uh an add subtract line
- 6:14:27and then the output of the ALO wasn't
- 6:14:30directly connected to the bus because
- 6:14:32recall only one thing can be written to
- 6:14:33the bus at a time. Um so it's actually
- 6:14:37going to be backed by something we call
- 6:14:40a tri-state buffer. So a tri-state
- 6:14:43buffer um pretty much in the examples we
- 6:14:46were showing we were using a switch. So
- 6:14:48I'd manually have to click and it would
- 6:14:50either physically disconnect or connect
- 6:14:53uh each bit position of a particular
- 6:14:55component. In our example, that was
- 6:14:57either the ALOU output or the RAM output
- 6:15:00to the bus. Um, rather than us having to
- 6:15:02click, uh, it'd be nice if we could just
- 6:15:04have an input signal and that would
- 6:15:06determine if something was connected or
- 6:15:08not. So, uh, let's see here.
- 6:15:14So, the tri-state buffer is kind of
- 6:15:16denoted, let me move over here to some
- 6:15:18crash base. It's kind of denoted like
- 6:15:20this. It's denoted like this. And I know
- 6:15:22this gets confusing because our inverter
- 6:15:24gate is denoted like this. Uh but that
- 6:15:27that circle kind of makes a world of
- 6:15:28difference. And we have some input A and
- 6:15:33then we have this control line B and
- 6:15:37then the output of that is C. So pretty
- 6:15:40much what we can say is
- 6:15:44if B
- 6:15:47is one and there's obviously inverted
- 6:15:50versions of this. Let's just say if B is
- 6:15:51high then
- 6:15:54then C will equal A. I.e. the value of A
- 6:15:58will just flow on through.
- 6:16:02Then if B
- 6:16:05is zero it does not mean that C is zero.
- 6:16:11It does not mean that C is one. It means
- 6:16:13that C is just disconnected from the
- 6:16:16from the bus.
- 6:16:21So it's not an output of 01. It
- 6:16:23literally means no output, the absence
- 6:16:25of an output. And so that'll physically
- 6:16:27disconnect us in the same way that we
- 6:16:29saw in the software um
- 6:16:33that uh clicking that switch would
- 6:16:34physically d disconnect the wire. So you
- 6:16:37can imagine like it's kind of the same
- 6:16:39thing we saw um
- 6:16:45here. This is what the software looked
- 6:16:46like. And so pretty much whenever we
- 6:16:48have B is being one um then when B is
- 6:16:52one the thing will fall and it'll let
- 6:16:53the it'll let A connect to C and then
- 6:16:56whenever B is zero it'll pick this thing
- 6:16:58up and it'll be physically disconnected
- 6:17:00and that's how we'll guarantee that uh
- 6:17:02only one thing is writing to the bus at
- 6:17:04a time. And this is nice because it now
- 6:17:07adds a new toggle for us. You know we've
- 6:17:09talked about the toggles we have for
- 6:17:11writing values into registers or putting
- 6:17:13something out on the bus. And here's a
- 6:17:15new one we have uh for physically
- 6:17:16connecting or disconnecting us from the
- 6:17:18bus. So, let me go ahead and clean this
- 6:17:21up
- 6:17:26and let's add this in here.
- 6:17:40And so that means we actually have a new
- 6:17:42control line now. And we'll call this
- 6:17:45ALU out.
- 6:17:49And pretty much when this is set, the
- 6:17:51output of the ALU will be written onto
- 6:17:53the bus. And when it's not set, i.e.
- 6:17:55it's zero, it'll be physically
- 6:17:56disconnected. So I'm also going to do
- 6:17:58one other thing here is I'm going to
- 6:17:59start highlighting all of the control
- 6:18:00lines we have because we kind of have a
- 6:18:02good number of them now. So let's just
- 6:18:04uh keep track of this. Uh the add
- 6:18:06subtract one is one we have.
- 6:18:11And then we also have control lines for
- 6:18:18um
- 6:18:21register A in
- 6:18:27register B in.
- 6:18:35So let me highlight those as well.
- 6:18:44Cool. So that's our ALOU. And then after
- 6:18:48we had the ALU, we went and built RAM.
- 6:18:50So we have pretty much a register that
- 6:18:55reads uh an address from the bus. So our
- 6:18:59bus is 8 bits. Uh we're going to make
- 6:19:01our addressing space four bits. So even
- 6:19:04though the bus is an 8- bit bus,
- 6:19:09we will actually say that our memory
- 6:19:10addresses in our computer are all four
- 6:19:13bits. And this is a design choice. We
- 6:19:17are designing this ourselves. We
- 6:19:19actually could make them any number of
- 6:19:20bits. More bits means more address
- 6:19:22spaces, which means that your computer
- 6:19:24can have more working memory. Um, but
- 6:19:27we'll see that when we need to do an
- 6:19:29operation, we need to specify an
- 6:19:31address. And so we are going to get to a
- 6:19:34point where we need to say something
- 6:19:35like load the address from load the
- 6:19:39value from some address in RAM onto the
- 6:19:41bus and we need to encode that signal
- 6:19:44onto the bus itself. So if our address
- 6:19:46was 8 bits then there's no way that we
- 6:19:48could fit in a operation that says to
- 6:19:51read from RAM whatever signal that may
- 6:19:53be however we would like to encode that
- 6:19:55and the actual address. So we decide
- 6:19:57that uh this is just by decision that
- 6:20:00we'll say four bits are going to be for
- 6:20:02addressing and then maybe four bits
- 6:20:05later down the road will be used for
- 6:20:06saying what we want to do with that
- 6:20:08address. Um
- 6:20:11so yeah so we have something we'll build
- 6:20:14a register uh in this register we
- 6:20:17previously in our software
- 6:20:19representation just called it the RAM
- 6:20:21address selector. We're going to give it
- 6:20:23a bit more uh a slightly changed name,
- 6:20:26but the effect is still the same. We're
- 6:20:28now going to call this the memory
- 6:20:30address register. Uh it's short for uh M
- 6:20:35is the acronym.
- 6:20:38And we can just know that it stands for
- 6:20:41memory
- 6:20:44address
- 6:20:46register.
- 6:20:49And so it is a 4bit register.
- 6:20:54So let me actually show that a little
- 6:20:57bit better.
- 6:21:00So I will say a four up here. And all of
- 6:21:03our other registers that we've worked
- 6:21:05with so far are 8 bit registers. So let
- 6:21:08me make that clear too.
- 6:21:13And you know this is an eight bit value.
- 6:21:16The output of the ALU is an 8bit value.
- 6:21:17So it'll write to all four uh all eight
- 6:21:22sorry all eight lines of the bus. The
- 6:21:23memory address register will just read
- 6:21:25in the memory the bits from the
- 6:21:27rightmost four address lines. So it
- 6:21:30won't actually connect to all four of
- 6:21:31the address all eight of the bits uh on
- 6:21:34the bus because it's our memory
- 6:21:36addresses are only four bits. So then
- 6:21:38there's kind of a choice of like which
- 6:21:39four bits are we going to actually use
- 6:21:42on the bus whenever some other component
- 6:21:44wants to put out a memory address for
- 6:21:45RAM to operate on. And just by design,
- 6:21:48again, we could have picked any four
- 6:21:50bits, but uh just by design, we're going
- 6:21:53to go with the rightmost four bits. And
- 6:21:54these are called the least significant
- 6:21:56bits. And the leftmost four bits would
- 6:21:58be the the most significant bits or the
- 6:22:00highest significant bits. So we have our
- 6:22:03memory address register hooked in to the
- 6:22:06least four significant bits of the bus.
- 6:22:09And this is always just reading in. So,
- 6:22:12let me actually uh update that
- 6:22:14representation slightly so it's not
- 6:22:15ambiguous in the future because we're
- 6:22:17going to be adding several more
- 6:22:19components here.
- 6:22:29Uh versus these two registers
- 6:22:34are both reading the full eight bits.
- 6:22:40And let me clean up this right here.
- 6:22:43Cool. And then there's also another uh
- 6:22:46control signal here. You know, the um
- 6:22:50the
- 6:22:51we we're turning this into a register.
- 6:22:53It was just a selector in our original
- 6:22:55thing, but we're now making this encode
- 6:22:57the value in register. And we know that
- 6:22:59for all registers, uh they need some
- 6:23:00control line to determine when they
- 6:23:02should read the value that's on the bus
- 6:23:03into their uh bit positions. So, there's
- 6:23:06a new signal called
- 6:23:09um we'll just call it M in.
- 6:23:18And let me highlight that so we can keep
- 6:23:19track of all of our signals, our control
- 6:23:21lines. And then this memory address RAM
- 6:23:25is always looking into
- 6:23:30what value is here because recall that
- 6:23:35RAM has two operations read and write
- 6:23:37and the only thing uh the for both of
- 6:23:41those operations it needs to work with a
- 6:23:42specific memory address. So you're
- 6:23:44either reading a specific memory address
- 6:23:46or if you're writing a value in you need
- 6:23:48to know which address you're writing
- 6:23:49that into. So RAM has will look at this
- 6:23:52memory address uh register to determine
- 6:23:54what to do and then
- 6:23:57um it'll also need to uh read in from
- 6:24:01the bus directly too. So
- 6:24:08and so RAM when it wants to write a
- 6:24:12value onto the bus we also know that
- 6:24:13happens. um it has uh so we're use the
- 6:24:17same sort of uh tri-state buffer that we
- 6:24:19talked about previously. And so the
- 6:24:21output of RAM
- 6:24:23can be written onto the bus
- 6:24:25conditionally
- 6:24:27based on whether or not this output line
- 6:24:29is set. And so we have an output line
- 6:24:32here and we will call this one RAM out.
- 6:24:36So if it's set, RAM will write its value
- 6:24:38onto the bus. And if it's not set, then
- 6:24:40RAM will not write anything onto the
- 6:24:42bus. It won't write zeros onto the bus.
- 6:24:44literally would be physically
- 6:24:45disconnected from the bus. And so this
- 6:24:47will be enough for reading in values. If
- 6:24:49you wanted to read in a value, uh if you
- 6:24:51wanted to read a value from RAM, you'd
- 6:24:53put that address onto the least four
- 6:24:55significant bits. Then you'd punch this
- 6:24:58uh MAR in and so it would latch it into
- 6:25:01the register. Then RAM's always looking
- 6:25:03at whatever that memory address line is
- 6:25:05and it's trying to write the values
- 6:25:07here. And then we'd punch this RAM out
- 6:25:09and the value would come out onto the
- 6:25:10bus. Uh, and we need to make sure that
- 6:25:13in between us putting the address on the
- 6:25:15bus and us punching this RAM out, uh,
- 6:25:17whatever is writing the address onto the
- 6:25:19bus needs to stop writing it onto the
- 6:25:20bus. Or else we'd have a, uh, short
- 6:25:22circuit because two things will be
- 6:25:24writing onto the bus. The RAM would be
- 6:25:26trying to write its output onto the bus
- 6:25:28and whatever is writing the memory
- 6:25:29address to read is writing onto the bus.
- 6:25:32So that covers reading from RAM. Then
- 6:25:34the last thing is uh, writing into RAM.
- 6:25:38So if we wanted to load a value into RAM
- 6:25:41or write a value into the RAM, we need
- 6:25:43to specify the address. So we'd put the
- 6:25:45address onto the bus, we latch it into
- 6:25:48the memory address register, then we'd
- 6:25:50stop putting the address onto the bus,
- 6:25:52but then we'd put the value that we want
- 6:25:54to write in at that particular address
- 6:25:56onto the bus. And so RAM needs to always
- 6:25:59be listening to what's on the bus. And
- 6:26:02it's RAM operates in our uh in our
- 6:26:05actual computer. It's going to operate
- 6:26:07on eight bit values. So I'll denote this
- 6:26:10with an eight. And so it reads all eight
- 6:26:12bits from the bus. And uh the only thing
- 6:26:16we then need to add was the punch button
- 6:26:18we had that would perform the right
- 6:26:21operation that we saw in our in our
- 6:26:23circuitry. So I'll add one more signal
- 6:26:26called RAM in
- 6:26:30and that is used to write some value
- 6:26:33into RAM. Cool. So we uh started with
- 6:26:36our ALU then we built RAM and the last
- 6:26:38thing we just did was build this uh
- 6:26:40display register. So in our our
- 6:26:43contrived example we had in the digital
- 6:26:45software it looked at four bit values
- 6:26:47and only outputed one number uh one
- 6:26:50digit position. In reality, we're going
- 6:26:52to uh let uh this this uh display
- 6:26:58display any number of values. You
- 6:26:59understand the concept. We're not going
- 6:27:00to go and reprogram that ROM, but you
- 6:27:04can, you know, we uh have a
- 6:27:07register that looks at the entire bus
- 6:27:10and
- 6:27:12that's going to connect to a
- 6:27:21an 8 bit register. So a register
- 6:27:25and then I'll denote it with an eight
- 6:27:28and we're going to call this the uh
- 6:27:31display register um or the output
- 6:27:33register. So
- 6:27:36uh that means that we have a
- 6:27:37corresponding signal here a new line. Um
- 6:27:42we'll call this display
- 6:27:45in. So display register in. So whenever
- 6:27:49that hits a rising edge from 0 to one,
- 6:27:51we will latch in whatever values on the
- 6:27:53bus. And we'll just need to be careful
- 6:27:56to make sure that there there is a bus.
- 6:27:58And then we know from what we just built
- 6:28:00that there would be a ROM that looks at
- 6:28:04this 8bit signal and then outputs some
- 6:28:09number of control lines. And those
- 6:28:12control lines will get consumed by
- 6:28:15several
- 6:28:18uh of these seven segment displays next
- 6:28:20to each other.
- 6:28:29Pardon my bad drawings here.
- 6:28:33And tada. This is kind of what we've
- 6:28:36built uh on the software uh just
- 6:28:39conceptually laid out here. And so let's
- 6:28:42actually now talk about um some of the
- 6:28:44operations our computer is capable of
- 6:28:46doing. So the first one is let's talk
- 6:28:50about how you would load a value um how
- 6:28:54you would read a value from RAM. So to
- 6:28:57read a value from RAM
- 6:28:59we have a few steps we want to take. So
- 6:29:02uh read
- 6:29:05from
- 6:29:07RAM. The first thing we want to do is
- 6:29:10put an address onto the bus. So in order
- 6:29:13to read a particular value
- 6:29:16um onto from RAM, we'd actually need to
- 6:29:19address it. And so we need to get that
- 6:29:21value into the memory address register.
- 6:29:23So the first thing you do, I don't know
- 6:29:25why I denoted this with a one. Um we'll
- 6:29:27just say read from RAM. First thing you
- 6:29:28do is uh put the address on the bus.
- 6:29:36Then the second thing you do is once you
- 6:29:38put the address onto the bus um you'd
- 6:29:41put uh you'd go MAR in uh you'd toggle
- 6:29:45it. So you you know you'd let it go from
- 6:29:47low to high. And then the third thing
- 6:29:50you do is at that point uh the RAM is
- 6:29:53always looking at this memory address
- 6:29:54register. So it' immediately look up the
- 6:29:57value that's in that address and try put
- 6:29:59it right here. But it's blocked on this
- 6:30:01RAM out that's disconnected. So before
- 6:30:03we can put that value of RAM out onto
- 6:30:05the bus, we need to uh stop writing the
- 6:30:08address onto the bus. So stop
- 6:30:12writing
- 6:30:15address
- 6:30:17onto bus. And then finally, we could
- 6:30:21then put RAM out
- 6:30:27uh from low to high.
- 6:30:31And at that point we would uh have
- 6:30:34successfully
- 6:30:37loaded a value from RAM. And now let's
- 6:30:39talk about how we'd write to RAM. So if
- 6:30:43you want to write to RAM,
- 6:30:50the first thing you do is you put the
- 6:30:52address that you want to write into onto
- 6:30:54the bus. So put target
- 6:30:58address
- 6:31:01on bus
- 6:31:03and then mar in toggle. So you want to
- 6:31:06read that into this memory address
- 6:31:08register over here.
- 6:31:15Then now that we've loaded the address,
- 6:31:17we want to stop writing
- 6:31:23the address onto the bus. It's looking
- 6:31:25pretty similar to the read so far.
- 6:31:29And now we need to put the actual value
- 6:31:32that we want to write into the address
- 6:31:34that's now captured here onto the bus.
- 6:31:36So since we've captured the address into
- 6:31:38the memory address register, it's not
- 6:31:40imperative if it's not imperative that
- 6:31:42we keep that value on the bus, which is
- 6:31:44why how we actually free up the bus to
- 6:31:46then hold the 8 bit value that is the
- 6:31:49value that we'd like to write into that
- 6:31:51particular address stored in the M. So
- 6:31:54now we can say put value on bus
- 6:32:00and then once we've done that the only
- 6:32:02thing we need to do is pulse this RAM in
- 6:32:05signal and that'll latch the value into
- 6:32:07the corresponding register. So RAM in
- 6:32:11would need to go from low to high and
- 6:32:14just like that we've uh written to RAM.
- 6:32:17So cool.
- 6:32:20And so what I'd like to do now is
- 6:32:22actually delete everything we just drew
- 6:32:24over the past 10 minutes.
- 6:32:33And let's actually start getting back to
- 6:32:35the concrete part of this
- 6:32:36implementation. And what we're going to
- 6:32:38do for the remainder part of this
- 6:32:41segment of finishing off the CPU is
- 6:32:44tying things together. And it may not
- 6:32:46seem like we're done yet. And it's
- 6:32:48because we're not. we're kind of in this
- 6:32:49weird state where we have memory and an
- 6:32:51alou, but like no way to really tie it
- 6:32:53together or understanding of like why
- 6:32:55we'd want to tie it together. Um, so up
- 6:32:59until this point, like we started off
- 6:33:01with with binary and like all of that
- 6:33:03logic clearly stacked on top of each
- 6:33:05other on top of each other until we got
- 6:33:07to the point of a register. Then when we
- 6:33:09got past the register, we kind of had to
- 6:33:11split where we like went and built this
- 6:33:12ALOU, then we went and built this RAM,
- 6:33:14and then now we kind of recently tied
- 6:33:16those concepts back together. And
- 6:33:20unfortunately to bring this all together
- 6:33:21as a whole requires us to go into some
- 6:33:24ambiguity. It can't clearly stack. there
- 6:33:26kind of has to be some amount of uh take
- 6:33:29this for what it's worth and then when I
- 6:33:31can tie components back together it'll
- 6:33:33make sense in the end but I I think
- 6:33:35there's a way that we can do this uh
- 6:33:38that minimizes the number of head
- 6:33:40scratching that happens along the way so
- 6:33:43um what we we described some possible
- 6:33:46operations let's take one of those and
- 6:33:48try to build it out a little bit so what
- 6:33:51we're going to say now is uh we're going
- 6:33:54to build a lot of operations ations um
- 6:33:57commands we can call them for our
- 6:33:59computer and each of these commands is
- 6:34:01going to do something very small. Maybe
- 6:34:03load a value from RAM into a register uh
- 6:34:06can be one and then maybe one can be uh
- 6:34:10doing an addition and writing that value
- 6:34:11back into RAM can be another instruction
- 6:34:14or maybe one instructions taking what's
- 6:34:16in a register and writing it onto our
- 6:34:18seven segment display. Um and the idea
- 6:34:22is if we have these different
- 6:34:23instructions defined and the computer
- 6:34:26knows how to implement each of those
- 6:34:28instructions i.e it knows actually what
- 6:34:30to do which of these lines to punch at
- 6:34:32which time and in what order then us as
- 6:34:36humans can create programs by stacking
- 6:34:39these instructions together which is
- 6:34:41pretty cool. So, what I'm going to do is
- 6:34:46excuse me there. Um, we're going to
- 6:34:49create another register. Yes, one more.
- 6:34:51And we're going to call this the
- 6:34:52instruction register.
- 6:35:05And for now, don't worry about uh how a
- 6:35:09value gets into this register. But let's
- 6:35:12just say that this register
- 6:35:15uh tells us what we what the what
- 6:35:17instruction our computer should do next.
- 6:35:21And then let's suppose and I'm going to
- 6:35:24do this actually in a different color
- 6:35:25because this is is is conceptual. Um
- 6:35:34there's some part of the computer that
- 6:35:36actually looks at what's in this
- 6:35:38instruction register and it's the brains
- 6:35:41uh we can think of it as the brains that
- 6:35:43will actually go and punch each of these
- 6:35:46other lines that go and do something at
- 6:35:49different times.
- 6:35:51Um and we're going to finally make sense
- 6:35:52of how that looks like really shortly.
- 6:35:54I.e. now. So uh our instruction register
- 6:35:58is going to be an 8 bit register
- 6:36:01and here's the format of the instruction
- 6:36:04register. So let's uh let's come over
- 6:36:05here.
- 6:36:12The instruction register it's an 8 bit
- 6:36:14register
- 6:36:17and we're going to split it into two
- 6:36:19components. So it'll be one, two, three,
- 6:36:22four, five, six, seven, eight. We're
- 6:36:24gonna split it down the middle. So the
- 6:36:27the first four bits, the left four bits
- 6:36:30are going to denote the uh instruction.
- 6:36:36And then for some instructions, we might
- 6:36:39have an argument that we need to pass
- 6:36:40in. And so we'll use the last four bits
- 6:36:43for denoting the argument.
- 6:36:48So the first instruction we're going to
- 6:36:51build, so this is our instruction
- 6:36:52register. our in we're gonna build a
- 6:36:55table of instructions
- 6:37:01and
- 6:37:02um basically what I'm saying is
- 6:37:08we have four bits to note what
- 6:37:10instruction we're going to execute which
- 6:37:12means we have two to the four different
- 6:37:14values can fit into that instruction uh
- 6:37:17instruction part of the instruction
- 6:37:18register which means we have 16
- 6:37:23different instructions.
- 6:37:26That's how many instructions we'll build
- 6:37:28up to. That's as many as our computer
- 6:37:30supports. You'd imagine if this
- 6:37:32instruction register was more than 8
- 6:37:34bits, we could have a lot more
- 6:37:36instructions. For example, if it was a 9
- 6:37:38bit register and we put an extra bit
- 6:37:40towards that instruction component, we
- 6:37:42could have 32 uh 32 different
- 6:37:44instructions. For this case, we'll start
- 6:37:46with uh 16 different instructions. and
- 6:37:48we will talk a little bit about how this
- 6:37:50computer scales up to like more modern
- 6:37:51computer. Um, and we're going to build
- 6:37:54out up to 16 different instructions. It
- 6:37:56turns out we don't even actually need to
- 6:37:57use all of these to to get a functioning
- 6:37:59computer. Um, and then argument. So,
- 6:38:03what actually do we mean by argument?
- 6:38:05So, let's actually figure out what this
- 6:38:06means just by building our first
- 6:38:08instruction. So, I'm going to define
- 6:38:09what our first instruction is. Our first
- 6:38:12instruction
- 6:38:13is going to be called load a
- 6:38:20oops
- 6:38:21lda. Um let's actually put this into
- 6:38:24table format. So I will say short name,
- 6:38:34full name,
- 6:38:40op code,
- 6:38:44which I'll explain in a second, and then
- 6:38:47we'll give it a description.
- 6:38:53So basically um instruction is
- 6:38:57synonymous with op code and then for any
- 6:39:01instruction that has an argument we call
- 6:39:03it the operand
- 6:39:06or it can be also just called arg for
- 6:39:10short. You'll hear these used
- 6:39:12interchangeably. Um so let's let's
- 6:39:16define our our first instruction that
- 6:39:18we're going to implement from scratch is
- 6:39:19called load A. Short name is just LDA.
- 6:39:23Its full name is just load A. These are
- 6:39:27invented by us. This is the point where
- 6:39:29we are just inventing these
- 6:39:30instructions. Different computers have
- 6:39:32different instructions and that's
- 6:39:33something we'll also talk about and is
- 6:39:35really interesting. Our simple computer
- 6:39:37we're building right here has just
- 6:39:39enough instructions to show off the
- 6:39:41fundamentals of a computer and write non
- 6:39:44or I guess you could say non-trivial
- 6:39:46programs uh that the computer can
- 6:39:48operate. Our op code, let's just give it
- 6:39:51the number one for now. 00001.
- 6:39:54And what load A does is it is going to
- 6:39:59load into the register A of our
- 6:40:02computer. Recall register A is this uh
- 6:40:05left hand side of the operand
- 6:40:10and what it's going to load into A is
- 6:40:15RAM
- 6:40:18at the address specified by the ARG.
- 6:40:24So if you've programmed before, you know
- 6:40:25those uh these these brackets uh are
- 6:40:29kind of indexing into a structure. I'm
- 6:40:32making this video for people who have
- 6:40:33not programmed before. So what the
- 6:40:36brackets just mean is it means go to
- 6:40:39whatever's left of the brackets. So
- 6:40:41that's RAM and then this position in
- 6:40:45RAM. So it's saying pretty much whatever
- 6:40:48the argument is, if the argument is two,
- 6:40:51whatever the second value is at RAM,
- 6:40:52whatever RAM at address value two is,
- 6:40:55take that, load that from RAM and spit
- 6:40:57it into register A. So why do we care
- 6:41:00about this instruction? Well, in order
- 6:41:03for us to addition, we're going to want
- 6:41:05a value in register A and B. So the very
- 6:41:08first thing we need to do is get a value
- 6:41:09in register A. Um, and we're going to
- 6:41:12say that that value is probably going to
- 6:41:14live somewhere in RAM. So what this
- 6:41:16instruction will do is take some value
- 6:41:18in RAM, throw it on the bus, and then
- 6:41:21register A will need to at the right
- 6:41:23time read in that value from the bus.
- 6:41:33And so
- 6:41:35if I throw in O1,
- 6:41:40then the four bits that we have
- 6:41:42remaining are the operand, the argument,
- 6:41:45and that's going to tell us which
- 6:41:46address from RAM we actually want to
- 6:41:49load into register A. And so I have four
- 6:41:52bits to do that. But what's really
- 6:41:55interesting is that when we designed
- 6:41:57RAM, I also said that the memory address
- 6:42:00register is going to be four bits, which
- 6:42:03means those four bits, even though the
- 6:42:05rest of our computer is centrally
- 6:42:06designed to be eight bits, those four
- 6:42:08bits are enough to fully index every
- 6:42:11spot in RAM. And so I know when I
- 6:42:13earlier I designed RAM and I said, "Hey,
- 6:42:15it's kind of arbitrary. We're making uh
- 6:42:17the memory addresses four bits in RAM."
- 6:42:19It actually works out perfectly because
- 6:42:22it means for all of our instructions
- 6:42:23that we build here on out that need to
- 6:42:26reference a specific address in RAM,
- 6:42:28they can do so using those four bits. So
- 6:42:31our instructions can be fully complete.
- 6:42:33Um, which is also really nice. And it
- 6:42:37we'll see for the most part that uh our
- 6:42:40instructions usually if they have
- 6:42:42operands, arguments, they're going to be
- 6:42:44addresses into memory. But that's not
- 6:42:47always the case. But uh it's designed
- 6:42:49around this. So there is something it's
- 6:42:52not just coincidence that we're
- 6:42:53designing
- 6:42:55our uh instructions to use four bits for
- 6:42:58arguments and then the RAM has four-bit
- 6:43:01addresses. This is not coincidence. This
- 6:43:03is very much a a choice made with high
- 6:43:06agency. And this is again something that
- 6:43:09we designed for our own computer. So you
- 6:43:11could imagine, you know, maybe if we had
- 6:43:13a a 20 bit uh bus, maybe we'd have like
- 6:43:1810 bits uh could be used for the memory
- 6:43:20address register, which means our our
- 6:43:22instructions might be 10 bit operands
- 6:43:25and then maybe four bit instructions.
- 6:43:29Um so there that there is something
- 6:43:30pretty cool to be said about this. So uh
- 6:43:33basically if we throw in this value,
- 6:43:37let's let's try consider an actual
- 6:43:39value.
- 6:43:41If we throw into the instruction
- 6:43:43register the value 01
- 6:43:47010
- 6:43:49um a few hours ago this would have
- 6:43:52looked like nonsense to you. Uh maybe
- 6:43:55one hour ago you would be able to derive
- 6:43:57the number out of this and now we're
- 6:43:59actually saying hey this this isn't just
- 6:44:01a number in binary that we want to
- 6:44:02convert to decimal. There's more to it
- 6:44:05than this. This is actually first off
- 6:44:07it's it's two different numbers and the
- 6:44:10two numbers are not just one and two. Uh
- 6:44:13there there's actually it's an
- 6:44:14instruction. We're saying execute some
- 6:44:18instruction whose ID is one and that
- 6:44:22instruction takes an argument and the
- 6:44:23value to that argument is two. So if I
- 6:44:26come back over here uh to our scratch
- 6:44:29base um I have 00001 0 0 1 0 was what I
- 6:44:35talked about. So this means load a we're
- 6:44:39saying load a value at this address in
- 6:44:43RAM into register A and this is address
- 6:44:47two
- 6:44:48um
- 6:44:500 1 2 uh however you want to denote that
- 6:44:53third index position or just two um if
- 6:44:58you want to convert that from a binary
- 6:44:59number back to a decimal number. So,
- 6:45:01let's go ahead and see the exact
- 6:45:04specific steps we need
- 6:45:11to make this instruction happen. So, I'm
- 6:45:14going to go a little bit slow here. You
- 6:45:15might be able to figure this out faster
- 6:45:16on your own, but
- 6:45:20the first thing we're going to want to
- 6:45:22do
- 6:45:24is
- 6:45:25get this 0010
- 6:45:29and look up whatever value there is in
- 6:45:30RAM.
- 6:45:32So this instruction register has the
- 6:45:35values that we are interested in. And so
- 6:45:38in order for us to get it to the memory
- 6:45:40address register, this instruction
- 6:45:42register actually has to be able to
- 6:45:44write its value onto RAM. So it can do
- 6:45:48that. And
- 6:45:53I will denote that here. There's
- 6:45:55something interesting. Um, it only needs
- 6:45:58to write
- 6:46:00those right for bits out. It only it
- 6:46:02only needs to write its argument onto
- 6:46:03the bus. It does not need to write all
- 6:46:06eight bits onto the bus.
- 6:46:08Because the uh the left four bits are
- 6:46:11the operation code, the op code of the
- 6:46:13instruction that we're trying to to uh
- 6:46:15in uh that we're hoping the computer
- 6:46:17will execute. And the control is the
- 6:46:20only part of this computer that makes
- 6:46:22sense of the op code, the instruction
- 6:46:23code. The only the control part of our
- 6:46:26computer, which for now is just us as a
- 6:46:28human brain. It's our we are the control
- 6:46:30of the computer. um
- 6:46:34we care about that op code because it
- 6:46:36tells us what we should be doing. No
- 6:46:37other part of the computer cares about
- 6:46:38it. So uh when the instruction register
- 6:46:41writes its value onto the bus, it only
- 6:46:43would ever need to write the address
- 6:46:45onto the bus. And you can kind of see
- 6:46:47that motivated in the case here where if
- 6:46:49we have this uh 0000 one 0 one 0 uh we
- 6:46:54only need these to end up in the memory
- 6:46:57address register. So
- 6:46:59uh that's why we will have that and
- 6:47:01that'll actually be a new signal um and
- 6:47:05we will call that uh
- 6:47:09instruction register out.
- 6:47:16So assuming uh let's say our steps to
- 6:47:20implement this let's let's talk this out
- 6:47:22very clearly.
- 6:47:27So our our step zero and slash our
- 6:47:30assumption
- 6:47:33um is that we are we are assuming the
- 6:47:36instruction register
- 6:47:38has the right
- 6:47:42command in it.
- 6:47:47So we aren't going to worry about how
- 6:47:49this 0000 one 0 0 1 0 got into the
- 6:47:52instruction register yet. We'll get
- 6:47:54there in a bit. Um let's just assume for
- 6:47:56now that we some human came and punched
- 6:47:59that value into the instruction
- 6:48:00register. So that's our assumption. So
- 6:48:04now let's actually walk through the
- 6:48:05specific steps. So the first thing we
- 6:48:07need to do is put the instruction
- 6:48:10register argument onto the bus at 00 1
- 6:48:140. So we'd set instruction register out
- 6:48:21must equal one. And then
- 6:48:25after that after that instruction
- 6:48:28register out is set to one, the value of
- 6:48:32the argument 00 1 0 will be on the bus
- 6:48:34and we need to let these this m in line
- 6:48:38go from 0 to one. So it's everything
- 6:48:40we'll assume is zero. We want that M
- 6:48:43inline to go from zero to one. And what
- 6:48:47that'll do is uh latch in the uh the
- 6:48:52value um
- 6:48:56from the bus into RAM. So we'd say
- 6:49:01m a r in
- 6:49:06goes to one. So it's it's interesting
- 6:49:08because there's a strict ordering
- 6:49:10requirement here.
- 6:49:12um the instruction register has to put
- 6:49:13its value onto the bus before the memory
- 6:49:15address register can read it in. And
- 6:49:17that might seem like a trivial thing,
- 6:49:19but this is actually really important
- 6:49:20and we're going to have to make sure
- 6:49:21that we're very careful about that.
- 6:49:26In general, uh we've talked about this
- 6:49:28already. It seems trivial, but I'll
- 6:49:31restate it again because I think it
- 6:49:32can't be understated. uh if something
- 6:49:35wants to read a value from the bus then
- 6:49:37the component that it's reading the
- 6:49:39value from has to have that have to have
- 6:49:41has to have its value already written
- 6:49:44onto the bus
- 6:49:46uh before the another component can read
- 6:49:47it in. Um so we we kind of view this
- 6:49:51ideally this is atomic
- 6:49:56in reality has to be sequential. So
- 6:49:59ideally we'd say, hey, at the same time
- 6:50:01that we write the instruction registers
- 6:50:02on the on its value onto the bus, the
- 6:50:04memory address registers to read it in.
- 6:50:06Um, and that's how we'd like to think
- 6:50:08about this. That's how we'd like to
- 6:50:09think of putting a value from one
- 6:50:10component to another. Uh, in reality, we
- 6:50:13know we'll have to do it sequentially.
- 6:50:16And so we'll also come back. I'm going
- 6:50:17to leave this written on the screen. Um,
- 6:50:21and I'll also highlight it so we don't
- 6:50:24forget to come back to it in a timely
- 6:50:25manner.
- 6:50:28So once that happens the value from RAM
- 6:50:31is in. So then what I can do is we can
- 6:50:34say okay well now the value uh from the
- 6:50:38instruction register well the
- 6:50:39instruction register outline
- 6:50:42and the mar inline are both not
- 6:50:45necessary anymore. So they can go back
- 6:50:47to zero. We can reset those components
- 6:50:48to back to what they were. And so this
- 6:50:50means nothing's writing onto the bus.
- 6:50:53Um, and it means we've s we've loaded
- 6:50:55our value. Uh, the 0010 has made its way
- 6:51:00into the memory address register. And
- 6:51:02what that means is that RAM has looked
- 6:51:05up that value because RAM is always
- 6:51:07looking at what's in the contents of the
- 6:51:08memory address register and it has the
- 6:51:11output right here. So then what we'd
- 6:51:13like to do is write that value onto the
- 6:51:16bus.
- 6:51:17And then to get it into register A, we
- 6:51:19can use our register A in line.
- 6:51:22So we'd like to transport the value from
- 6:51:25RAM onto the bus into register A. So the
- 6:51:29two control lines we use to do that are
- 6:51:31RAM out. RAM out will put the value onto
- 6:51:34the bus and then after the value is
- 6:51:36written onto the bus, register A can
- 6:51:39read it in.
- 6:51:43So I will say RAM
- 6:51:46out
- 6:51:48and then
- 6:51:51register register A in. So RAM out
- 6:51:56equals 1 and register A equals 1. And
- 6:51:58then we kind of the same thing where
- 6:52:00ideally these are atomic. Um but it's
- 6:52:03important because the moment we set this
- 6:52:05RAM outline
- 6:52:08it connects it to bus to the bus and its
- 6:52:10values will be on the bus and then only
- 6:52:13based on what we know about registers
- 6:52:15only when we set a in from low to high
- 6:52:19only at the exact moment that rising
- 6:52:21edge happens are we actually going to
- 6:52:23latch in a value to register a.
- 6:52:26So
- 6:52:28once that's done, the value uh that we
- 6:52:32wanted to get into register A is done.
- 6:52:35And so we've kind of fulfilled this
- 6:52:36contract right here. Register A now
- 6:52:38equals whatever was in RAM at the
- 6:52:40address specified by the argument to the
- 6:52:42instruction, which in our hypothetical
- 6:52:44example is uh 00 1 0. And so once that's
- 6:52:48done, I can now say uh we can reset both
- 6:52:52those lines as well.
- 6:53:02Okay. So, uh this is pretty interesting.
- 6:53:05Um that doesn't seem that complicated,
- 6:53:07but let's look at it at a slightly
- 6:53:09different view. Uh where instead of
- 6:53:11listing it out in a series of steps,
- 6:53:14let's um look at it in terms of clock
- 6:53:17edges. So
- 6:53:22what I want to do is we said
- 6:53:26um
- 6:53:28we can have all the signals we used
- 6:53:30here. So IR out,
- 6:53:34M A R in,
- 6:53:38then RAM out, and register
- 6:53:44A in.
- 6:53:46And each of these starts off at low. And
- 6:53:51then to execute the instructions, they
- 6:53:53said the first thing that needs to
- 6:53:54happen is instruction register needs to
- 6:53:57write its value out. So it needs to go
- 6:53:59from zero to one and then at some point
- 6:54:03after uh it goes from one uh this memory
- 6:54:07address register can also go from zero
- 6:54:10to one. And because this is after this
- 6:54:14we know that the value on the bus will
- 6:54:15be correct. And then we said okay now
- 6:54:18that that's done uh both of these values
- 6:54:21can can kind of at the same time we can
- 6:54:24reset them to zero and that continues.
- 6:54:26And then the whole time this register
- 6:54:29this RAM out and a in lines are off. And
- 6:54:32then now that the value uh is the
- 6:54:36address has been loaded into MAR, we we
- 6:54:38can we know the value is looked up in
- 6:54:40RAM. So we wanted to get the value from
- 6:54:42RAM's output into register A. So what we
- 6:54:45did was we pulsed on this RAM out kept
- 6:54:49it up and then at some point shortly
- 6:54:51after that we can uh punch register A in
- 6:54:53and that'll latch in the value and then
- 6:54:57uh once that was done our operation was
- 6:54:59done so we just reset both these lines
- 6:55:01to zero and I can carry these because
- 6:55:04these top two lines nothing changes so
- 6:55:06you can kind of see like there's there's
- 6:55:09uh two timing signals of interest here
- 6:55:12um And in order for a like this
- 6:55:16represents a transaction of information
- 6:55:18from one component to another via the
- 6:55:20bus and this represents another
- 6:55:22transaction of information from one
- 6:55:24component to another via the bus. And
- 6:55:27what we'll find I'll spill this out is
- 6:55:29as we build more of these instructions a
- 6:55:32lot of the implementation is going to
- 6:55:34just be moving data from one component
- 6:55:36to another using the bus. So,
- 6:55:40what actually turns out happens is we're
- 6:55:44going to introduce a another component
- 6:55:46to all of this called the clock. And I'm
- 6:55:50going to draw the clock up here.
- 6:55:56And basically what the clock is doing,
- 6:56:00it's a physical uh component to the
- 6:56:02computer. And it's uh you don't need to
- 6:56:06worry about how it build how it's built,
- 6:56:08but at a fixed rate, it'll just keep
- 6:56:10going from 0 to one back to zero.
- 6:56:14And
- 6:56:16this is pretty cool. I'm not drawing
- 6:56:18this, so it's fixed rate, but uh ideally
- 6:56:21this is a fixed rate. And the same way
- 6:56:24every component's kind of hooked in uh
- 6:56:27to the bus, uh the clock is also pretty
- 6:56:30central to the computer. even though
- 6:56:31I've draw I've drawn it a little bit a
- 6:56:34little far out here.
- 6:56:36Um, but basically what we saw here is uh
- 6:56:43is is something similar to this. We had
- 6:56:45components you know we had a a a zero to
- 6:56:48a one here and then one to zero here and
- 6:56:51then a zero to one of interest here and
- 6:56:53a zero to one of interest here. So, uh,
- 6:56:57let's see how we can actually use the
- 6:56:59clock to, um, aid in some of what we
- 6:57:03just did manually.
- 6:57:07So, it turns out there's something
- 6:57:10slightly interesting
- 6:57:12about what we did here, and that when
- 6:57:15you're writing a value onto the bus, you
- 6:57:17can do it whenever because we're kind of
- 6:57:20making this guarantee that when we
- 6:57:21start, nothing is writing onto the bus.
- 6:57:23And then we're also making guarantee
- 6:57:24that like when we are done riding onto
- 6:57:26the bus, we stop writing on before we
- 6:57:27start putting the next thing on. There's
- 6:57:29clearly this nonzero gap here. So to
- 6:57:33write a value onto the bus is safe to
- 6:57:36read a value in from the bus is when
- 6:57:38things get tricky because we want to
- 6:57:39make sure the value is written out onto
- 6:57:41the bus before. So pretty much this
- 6:57:45clock here. And then the other thing is
- 6:57:47when we do need to read in, we can only
- 6:57:48read in on these rising clock edges. So
- 6:57:53uh what happens is you know when the
- 6:57:55clock is low we can put in we can put
- 6:57:58the value out on the bus any time from
- 6:58:00here to here. Let's say like from here
- 6:58:04to like right before anytime here it's
- 6:58:06fair game to read out to the bus. And
- 6:58:09then at the exact moment we go from 0 to
- 6:58:12one, we want to feed in.
- 6:58:15But um we can take this a step further
- 6:58:19and actually say well it'd be nice to
- 6:58:20just throw the in signal and the out
- 6:58:23signal at the same time. Uh because
- 6:58:25that's kind of what we want to do. We
- 6:58:27know we want to write from component A
- 6:58:30out to onto the bus and then have some
- 6:58:32component B latch that value in. So uh
- 6:58:35but you know the issue is we can't do
- 6:58:37that at the exact same time because of
- 6:58:39the issue we described. you know there's
- 6:58:41uh it's unclear if the value would be on
- 6:58:43the bus at the exact time that the
- 6:58:45register latches it in. But if we
- 6:58:48actually uh let's take the example of
- 6:58:50this M in uh if we actually and this
- 6:58:54signal with the clock
- 6:59:01and let that be the signal that goes
- 6:59:02into the register then it turns out we
- 6:59:05can throw both these values. So we can
- 6:59:07throw both um the out and the in to both
- 6:59:13equal one here. And so the out still
- 6:59:16goes onto the bus. The value goes onto
- 6:59:18the bus totally fine. In our in our case
- 6:59:20that was um the instruction register its
- 6:59:23last for this 000 goes out to the bus
- 6:59:26just fine. And the in because it's ended
- 6:59:30with uh this this clock signal stays as
- 6:59:33a zero. And that stays as a zero until
- 6:59:35the exact moment we hit this rising
- 6:59:37edge. And at that point this input uh
- 6:59:41both inputs of this endgate become a
- 6:59:42one. And so we latch in at this exact
- 6:59:44moment the uh the
- 6:59:50rising um signal. We latch in the exact
- 6:59:53value that's on the bus. So we've
- 6:59:55accomplished what we want. So then now
- 6:59:57when we're up here uh we can just you
- 6:59:59know be sure that we uh unset these
- 7:00:02signals. So we can, you know, make sure
- 7:00:04that we put both them back to zero. And
- 7:00:07then when we get down here, we can do
- 7:00:10the same thing for uh RAM out and
- 7:00:13register A in. And we could set both of
- 7:00:16these to one. So out and in, RAM out and
- 7:00:21register A in can both equal one. And as
- 7:00:23long as we have register A's in signal
- 7:00:27anded with the clock,
- 7:00:31then we can take advantage of the same
- 7:00:32trick. So let me go ahead and for all of
- 7:00:35our in signals, let me go ahead and and
- 7:00:39them with the clock so that we can make
- 7:00:41sure that's apparent for the rest of
- 7:00:43this.
- 7:00:45Okay, so I've gone ahead and for each of
- 7:00:48our in signals, I've ended them with the
- 7:00:50clock. So for our memory address
- 7:00:52register reading into RAM, reading into
- 7:00:55the A register, reading into the B
- 7:00:58register
- 7:01:00or reading into the display register
- 7:01:04and
- 7:01:06all of these are now ended with the
- 7:01:08clock. So what this means is our clock
- 7:01:11signal uh we can also pay attention to
- 7:01:15that in our control brains and us as
- 7:01:18humans as we're punching these lines we
- 7:01:20can kind of do is react to the fact that
- 7:01:23the clock is going up and down and being
- 7:01:26sure that we set lines appropriately. So
- 7:01:29if I jump back to our original example
- 7:01:31here of how we constructed this load a
- 7:01:33operation. Let's say we have our clock
- 7:01:36and it's just always going from low to
- 7:01:38high.
- 7:01:41Then basically what needs to happen is
- 7:01:45while the clock is low, we need to set
- 7:01:48IR out um equals to one.
- 7:01:53Let me
- 7:01:57and m a r in equal to one. And then we
- 7:02:02aren't changing the clock. the clock
- 7:02:04just exists and change its value on its
- 7:02:06own. But at some point, the clock will
- 7:02:08go from zero to one. And that'll have
- 7:02:10the effect of actually latching in the
- 7:02:12value into the memory address register
- 7:02:14because
- 7:02:16the me the the line for the memory
- 7:02:18address register in was one. But because
- 7:02:20we're adding it with the clock, the
- 7:02:22actual input that doesn't that goes to
- 7:02:24the register doesn't actually hit that
- 7:02:26rising edge until the clock hits a
- 7:02:28rising edge, which is pretty neat.
- 7:02:32And then when the clock is high, we can
- 7:02:35pretty much set these things back to
- 7:02:36zero.
- 7:02:52And [snorts] then when the clock falls
- 7:02:54low again, we can kind of reset and
- 7:02:56prepare our next signals, which was RAM
- 7:02:58out.
- 7:03:02equals 1 and a in equals 1. And then the
- 7:03:06next moment we have this rising clock
- 7:03:08edge, it'll latch the value from RAM
- 7:03:10that's written onto the bus into the A
- 7:03:11register. And so then when that we're at
- 7:03:14the rising clock signal and I guess for
- 7:03:16just indefinitely, we can reset all of
- 7:03:18our signals back to zero. So instruction
- 7:03:21register out or sorry RAM out
- 7:03:29equals Z and A in equals Z. So this is
- 7:03:33cool because now what it kind of means
- 7:03:36is our control here is just going to be
- 7:03:38listening to this clock signal and it's
- 7:03:41going to need to for every instruction
- 7:03:43set various control lines right before
- 7:03:46or right after a rising or falling clock
- 7:03:48edge.
- 7:03:50And
- 7:03:52this is convenient because it means the
- 7:03:54uh speed of the computer is now bound to
- 7:03:56the clock. So you can kind of see for
- 7:03:59this load a instruction we needed two
- 7:04:01clock cycles. Clock cycle meaning we
- 7:04:04needed to go from low to high back to
- 7:04:07low to high. So we hit this like low
- 7:04:10high cycle uh alternation two times and
- 7:04:13that's enough to actually implement the
- 7:04:16entire instruction. So that's pretty
- 7:04:18cool.
- 7:04:19Um before we go ahead and extend this to
- 7:04:22our second instruction, let's actually
- 7:04:24take this one step further. And uh one
- 7:04:28thing I've left ambiguous until now is
- 7:04:31how we get this instruction into the
- 7:04:34instruction register.
- 7:04:36And
- 7:04:37there's something interesting to be said
- 7:04:39about the fact that our instructions are
- 7:04:41all eight bits because that goes
- 7:04:44handinhand with everything else. you
- 7:04:46know all of our operants the ALU are 8
- 7:04:49bits the output register takes an 8bit
- 7:04:51value the bus itself is 8 bits and uh
- 7:04:55interestingly each value in RAM is 8
- 7:04:58bits so what we actually do
- 7:05:03um is store the instruction itself in
- 7:05:06RAM
- 7:05:08and then read that from RAM into the
- 7:05:10instruction register and basically the
- 7:05:13way our computer will execute is it'll
- 7:05:16look when we power it on, it'll look at
- 7:05:20whatever is in address zero of RAM and
- 7:05:23treat that not as a number or a value,
- 7:05:26but rather as an instruction
- 7:05:29and
- 7:05:31it'll load that value from RAM into this
- 7:05:34instruction register
- 7:05:36and then the computer, the control
- 7:05:38branch that we still have left ambiguous
- 7:05:41will go ahead and actually execute that
- 7:05:43con that instruction.
- 7:05:45And once that instruction is fully done,
- 7:05:47we'll then look at the next index in
- 7:05:49RAM. So we start with the first item in
- 7:05:51RAM, treat that 8 bit value as an
- 7:05:53instruction, execute it, and then look
- 7:05:56at the second item in RAM, treat that as
- 7:05:59an 8bit instruction, and execute it. So
- 7:06:02in order to keep track of where we are
- 7:06:06in our execution process, we're going to
- 7:06:08have a new instruction, a new register
- 7:06:11called the program counter. So I I've
- 7:06:14extended the bus a little bit and recall
- 7:06:17that our addresses to RAM are all four
- 7:06:19bits. So uh that means we can only index
- 7:06:22using the least four significant bits
- 7:06:25here. And we're going to have a new
- 7:06:27register called the program
- 7:06:32counter
- 7:06:34and that is a 4bit register.
- 7:06:40And
- 7:06:42there's also going to be uh so I guess
- 7:06:46it can put its value onto the bus
- 7:06:59and we will call that signal um
- 7:07:04PC out.
- 7:07:13So this program counter is going to
- 7:07:15start off as zero
- 7:07:18and it's going to point us to the first
- 7:07:19item in RAM. And then once we execute
- 7:07:21that instruction, we'd like to increment
- 7:07:23this program counter to become one. And
- 7:07:26once we execute, once we increment to to
- 7:07:28be one, then uh we'll look up whatever
- 7:07:30is in that address at one in RAM, treat
- 7:07:33that as an instruction, get it into our
- 7:07:35instruction register, and then execute
- 7:07:38it. And once we do that, we've executed
- 7:07:40the uh instructions at address zero and
- 7:07:42at address one. So we'll increment this
- 7:07:44program counter again to two. And we'll
- 7:07:47do the same thing. And so basically,
- 7:07:49this program counter
- 7:07:52um is going to be incrementing. it's
- 7:07:55when it should be counting up from zero.
- 7:07:56And you might be wondering how we do
- 7:07:58that. You know, this is just a register
- 7:08:00on itself. But uh we actually talked
- 7:08:03about this earlier when we constructed
- 7:08:04our ALOU. We showed how you could uh if
- 7:08:07you loaded some value into the left
- 7:08:10operand and then a fixed value of one
- 7:08:13into the second operand and the output
- 7:08:15will always be the the operand plus one.
- 7:08:18And so you can kind of feed that output
- 7:08:20and read that back into register A and
- 7:08:23it'll keep incrementing register A every
- 7:08:25time you latch in a new value because we
- 7:08:28fix the value of register B to be one.
- 7:08:30The output of the ALU will always be A +
- 7:08:32one. So that's one way you can uh
- 7:08:35implement this counter. It turns out in
- 7:08:37an actual computer it's not really uh
- 7:08:39pragmatic. There's a faster way uh
- 7:08:42faster meaning fewer logic gates to uh
- 7:08:45build out a a counter. We're not going
- 7:08:48to deal with that for the sake of this
- 7:08:49video because I don't think the
- 7:08:50complexity justifies the divergence
- 7:08:52here. But let's just say you already
- 7:08:55know how to build this counter. So we're
- 7:08:57going to suppose that this counter
- 7:08:58mechanism
- 7:09:00already exists. And I'm going to denote
- 7:09:02that uh with a better circle
- 7:09:07and we're going to call this like a plus
- 7:09:09one. You can imagine that could be a
- 7:09:11whole alou that takes the whatever
- 7:09:13whatever values in the program counter
- 7:09:15uh adds one to it as a fixed second
- 7:09:18operand and then feeds that back in. And
- 7:09:22we're going to have this same um
- 7:09:25kind of program counter in signal
- 7:09:30that'll kind of read in. And we can also
- 7:09:33go ahead and end it with the clock
- 7:09:35because we've done that for all of our
- 7:09:36other signals. So I'll say
- 7:09:58so
- 7:10:00now we have two new signals. But now
- 7:10:03what happens is
- 7:10:05we need to think about we know what
- 7:10:07happens uh for this load a instruction
- 7:10:09we've designed. We know what happens uh
- 7:10:12in terms of what the control logic needs
- 7:10:14to do once that operation command is in
- 7:10:19the instruction register.
- 7:10:21But now we need to take a few steps back
- 7:10:28and actually figure out how we get this
- 7:10:31instruction from RAM into the
- 7:10:34instruction register.
- 7:10:36So we know that there's a value in the
- 7:10:39program counter at any given time. And
- 7:10:41so what we'd like to do is look up treat
- 7:10:44that as an address in RAM. Look up that
- 7:10:47value from RAM and get it into the
- 7:10:48instruction register. And since
- 7:10:50everything's hooked into the bus, you
- 7:10:52might be able to guess already what we
- 7:10:54do here. The first thing we'd like to do
- 7:10:57is program counter out. So read that
- 7:11:00onto the bus. Push that onto the
- 7:11:01[snorts] bus. And then also pulse uh or
- 7:11:05set memory address register in. And then
- 7:11:08at the exact moment we have a rising
- 7:11:10clock edge because we've added the M in
- 7:11:12signal with the clock uh the value on
- 7:11:15the bus which will be the program
- 7:11:16counter address will get locked into
- 7:11:18memory address register.
- 7:11:20So that's our first clock cycle. Then
- 7:11:22our second clock cycle, we'd like to
- 7:11:24take the value that's in that address at
- 7:11:27RAM, which is here because RAM RAM is
- 7:11:30always looking up the value that's in
- 7:11:31the memory address register, put that
- 7:11:33onto the bus. So we'd set RAM out, and
- 7:11:36then to read it into the instruction
- 7:11:38register, we'd actually need a new line,
- 7:11:41uh, a new mechanism that can read from
- 7:11:44the bus into this instruction register.
- 7:11:46So, we're going to hook in the
- 7:11:48instruction register to the bus
- 7:11:52and
- 7:11:58we are going to uh kind of have that be
- 7:12:03denoted uh accordingly.
- 7:12:09And that means we have a new line that
- 7:12:11we care about which is uh instruction
- 7:12:14register in. And we're obviously going
- 7:12:15to end that with the clock because we've
- 7:12:17done that for all of our input signals
- 7:12:18so far.
- 7:12:40Cool. So basically uh we just need to
- 7:12:44add two more clock cycles here. One is
- 7:12:49to get the value from the program
- 7:12:51counter out and read it into the memory
- 7:12:52address register. That takes one clock
- 7:12:54cycle. And then the second clock cycle
- 7:12:56is putting the value from RAM out onto
- 7:12:58the bus and reading it into the
- 7:13:00instruction register. So we can come
- 7:13:03back to our original diagram here.
- 7:13:06And this we know is what happens once we
- 7:13:09have a value in the instruction
- 7:13:10register. But we're interested in uh the
- 7:13:12full steps of equations of how we get
- 7:13:13the value into the instruction register.
- 7:13:15So what we do is we set
- 7:13:22the program counter out and m in to both
- 7:13:25be one. So PC out equals 1. M in equals
- 7:13:321. Then we'll do that you know at some
- 7:13:34point here. Hold that value. Hold those
- 7:13:37two. And then on the rising clock edge,
- 7:13:39uh, that'll have the effect of moving
- 7:13:41the value in the program counter into
- 7:13:43the memory address register. And so then
- 7:13:45we're looking up the the RAM is always
- 7:13:46looking at the MAR. And so we have the
- 7:13:48value at that address ready. So we'll
- 7:13:51put that value onto the bus with RAM out
- 7:13:53and read it in with this instruction
- 7:13:56register in.
- 7:14:13And then as soon as there's that rising
- 7:14:15clock edge, we will then have the value
- 7:14:18uh latched in the instruction register.
- 7:14:21And then we can actually start the
- 7:14:23execution of the load a instruction that
- 7:14:26we've designed here. So we can literally
- 7:14:27just connect these two.
- 7:14:31And so this is the full timing sequence
- 7:14:34of how we implemented that instruction.
- 7:14:41And so you can kind of see that this
- 7:14:42takes one, two, three, four, four clock
- 7:14:48cycles.
- 7:14:50Four clock cycles
- 7:14:53to implement this instruction.
- 7:14:56And
- 7:14:58it turns out um that is also something
- 7:15:03that we will design. It'll be a design
- 7:15:05choice. We are going to give all of our
- 7:15:07instructions five clock cycles to
- 7:15:10execute. And that is because we will see
- 7:15:14that the longest of the instructions
- 7:15:16that we design, the longest instruction
- 7:15:20takes five clock cycles and so we need
- 7:15:23to kid to that longest instruction.
- 7:15:25There are some computers that could have
- 7:15:27variable length clock cycles per
- 7:15:28instruction. For us, it becomes easier
- 7:15:31to understand and reason about if we
- 7:15:32just say every five clock cycles
- 7:15:36is synonymous with the computer having
- 7:15:38executed one instruction.
- 7:15:41So for this uh command, we've used four
- 7:15:45clock cycles. This last clock cycle
- 7:15:47would just be wasted. Like it'd be a no
- 7:15:51operation, no wasted. And that's fine.
- 7:15:54It's trivial. Um, but it also turns out,
- 7:15:58we'll talk about this later, but more
- 7:15:59modern computers can actually execute uh
- 7:16:02entire instructions in a single clock
- 7:16:04cycle. And it turns out uh that you
- 7:16:07also, you would think, hey, if we just
- 7:16:10uh turn up the clock frequency. So right
- 7:16:13now we have this if we just made the
- 7:16:15clock go from high to low faster
- 7:16:18that we could uh actually you know we
- 7:16:21could just crank that the width of those
- 7:16:23intervals and have them approach zero
- 7:16:25and that would let our computer execute
- 7:16:27instructions faster and faster and you
- 7:16:30know that give the the illusion of it
- 7:16:31being just as fast as if every
- 7:16:34instruction had used one clock cycle.
- 7:16:35But it turns out you can't actually push
- 7:16:37these to zero because
- 7:16:40uh there's a delay here. there's a delay
- 7:16:43between everything you you the line you
- 7:16:44set and then it actually being received.
- 7:16:47So every time I say like this
- 7:16:48instruction like program counter out uh
- 7:16:51there's actually a slight delay in the
- 7:16:53logic gates like uh in the logic gates
- 7:16:56like physically connecting the program
- 7:16:58counter to the bus has a a delay it's
- 7:17:01very small delay uh but it turns out you
- 7:17:04have to wait for the longest delay of
- 7:17:06all components before you can pulse that
- 7:17:09clock again. So something like the ALU
- 7:17:11where if we put a value in register A
- 7:17:12and B, there's a lot of logic gates in
- 7:17:14the ALU. You kind of have to wait for if
- 7:17:16each logic gate takes like uh a
- 7:17:18millisecond, we have 50 in the slowest
- 7:17:21route, um then you have to wait 50
- 7:17:24milliseconds for the output of the ALU
- 7:17:26to be considered valid, which means your
- 7:17:28clock cycle, if you have something that
- 7:17:29depends on the result of the ALU output,
- 7:17:33has to be at least 50 milliseconds. So
- 7:17:36we can crank these pretty far and it
- 7:17:38appears that the computer runs fast but
- 7:17:40there is a true limitation and it also
- 7:17:42turns out modern computers have that
- 7:17:44clock running really really quickly.
- 7:17:48So we built the first uh implementation
- 7:17:52of load a but we've actually forgot one
- 7:17:54subtle thing and that once this load a
- 7:17:57operation is done we will correctly have
- 7:18:00the value uh denoted in the argument
- 7:18:03part of the instruction
- 7:18:06in register A. But our program counter
- 7:18:10is still going to be pulsed at zero
- 7:18:14which means if we repeat the same
- 7:18:15process we're going to execute the same
- 7:18:17instruction. we'd like to do is actually
- 7:18:20increment the program counter so that
- 7:18:23when we repeat these same set of
- 7:18:24instructions to get the value from the
- 7:18:26program counter uh stored at RAM into
- 7:18:29the instruction register we have the
- 7:18:30next instruction not the same one. So
- 7:18:32there's one subtle thing and that
- 7:18:34there's this program counter incin flag
- 7:18:37uh that'll effectively increment it and
- 7:18:41once we use the uh we only use the
- 7:18:43program counter value
- 7:18:45at this very first step. So actually at
- 7:18:48any other step along here between here
- 7:18:52to the next instruction, we can just
- 7:18:54pulse that flag on any of the rising
- 7:18:56edges and it'll have the effect of
- 7:18:58incrementing the program counter so that
- 7:19:00when we get to the next instruction,
- 7:19:02it's already ready. So I could just pick
- 7:19:04any uh any of these rising clock edges
- 7:19:07to do this and say you know program
- 7:19:10counter inc uh equals 1.
- 7:19:16And uh I'll also call this I will enable
- 7:19:19this program counter increment uh
- 7:19:23because it turns out we'll eventually
- 7:19:24want to be able to read actually a value
- 7:19:26into the program counter directly and
- 7:19:28that'll be called program counter in. So
- 7:19:30I don't want to get this confused with
- 7:19:32uh being able to increment the program
- 7:19:34counter.
- 7:19:38So what we're going to go ahead and do
- 7:19:40now is actually define all of the
- 7:19:43remaining instructions from this
- 7:19:44computer, discuss them at a high level,
- 7:19:47and then after we do that, we'll finish
- 7:19:51out by tying together what this actual
- 7:19:53control brains is. And once we have that
- 7:19:56done, we've uh completed the computer,
- 7:19:58which is a crazy thing to say. So, we're
- 7:20:00not quite there yet. Let's keep going.
- 7:20:03Um, so our second instruction is going
- 7:20:07to be called add.
- 7:20:12And, uh, the full name is also just kind
- 7:20:15of addition. Uh, this is just for our
- 7:20:17our readability here.
- 7:20:20The op code will be two. the next number
- 7:20:25and what add will do it's slightly
- 7:20:28different uh you know we've we've done
- 7:20:30addition in the ALOU and you kind of
- 7:20:32know how that works and how you kind of
- 7:20:33punch a value onto the bus hook it into
- 7:20:35some registers and
- 7:20:38uh kind of latch that value in. But what
- 7:20:41AD does is it says register A
- 7:20:47will equal whatever is in register A
- 7:20:54plus
- 7:20:55RAM at the arg specified.
- 7:20:59So there is an argument to load a. So if
- 7:21:02I uh call load a
- 7:21:07with
- 7:21:10uh address 3 as the argument, it'll take
- 7:21:14it'll go to RAM. It'll say, "Hey,
- 7:21:17whatever is in address 3, look it up,
- 7:21:21put it in register B, then take the
- 7:21:24output of that and feed it back into
- 7:21:27register A. And that will have the
- 7:21:29effect of adding whatever is in RAM at
- 7:21:33the specified argument into uh back into
- 7:21:38register A. So it'll be A equals A plus
- 7:21:41uh whatever we put in B and what we put
- 7:21:44in B is that that address and RAM.
- 7:21:47Okay.
- 7:21:49So that's how we do addition. Then you'd
- 7:21:52imagine uh the logical equivalent to
- 7:21:54that is subtraction.
- 7:21:57So sub
- 7:22:02and you could probably guess its op code
- 7:22:04is whatever comes next which is three.
- 7:22:06And you could also probably guess that
- 7:22:08the effect is register A equals register
- 7:22:12A. So we take we're always operating on
- 7:22:15whatever is in register A and we'll
- 7:22:17subtract whatever is in RAM at argu.
- 7:22:21So, it's the exact same thing we've done
- 7:22:23before, except uh when we actually get
- 7:22:27the result of the LU, we'll punch this
- 7:22:28add subtract line. When we set it to a
- 7:22:31one, uh as we learned earlier in this
- 7:22:33video, it'll have the effect of doing
- 7:22:35subtraction.
- 7:22:36Our next instruction
- 7:22:41is called STA
- 7:22:44and that stands for store
- 7:22:47A.
- 7:22:50And this has the op code of 0 1 0 0.
- 7:22:57That's four in in decimal. And what
- 7:23:01store a does is it lets us take the
- 7:23:03value
- 7:23:05that uh is in a and write it into RAM.
- 7:23:09So we we talked a lot about reading from
- 7:23:11RAM, but uh writing into RAM is also
- 7:23:14important. And the register A is kind of
- 7:23:17the design of our computer here. We
- 7:23:19actually don't have any uh commands in
- 7:23:22the default instruction set that let you
- 7:23:26specifically do something with register
- 7:23:27B. Everything that is done with register
- 7:23:30B is usually implicitly defined as part
- 7:23:31of one of these operations that works
- 7:23:33from register A. That's just by design.
- 7:23:35We could totally have these equivalent
- 7:23:36arguments for we could have you know for
- 7:23:40this AD we could have a add B which is
- 7:23:43the same same operation but for register
- 7:23:45B. So it' be like register B equals
- 7:23:46register B plus some argument into RAM.
- 7:23:50We just don't have that. uh and you know
- 7:23:53we actually could easily build it and
- 7:23:55that's something uh you could leave as
- 7:23:56an exercise to you afterwards but I
- 7:24:00digress. Store a uh it'll say RAM
- 7:24:06at whatever argument you specify it will
- 7:24:09treat that argument as an address
- 7:24:13uh equals whatever is in register A. So
- 7:24:16to implement this one, what would happen
- 7:24:19is once we get the instruction in the
- 7:24:21instruction register, we put the least
- 7:24:23four significant bits on the bus that op
- 7:24:25uh that memory address
- 7:24:28and we could hook that into the memory
- 7:24:30address register. And then what we need
- 7:24:33to do is write register A uh have a way
- 7:24:36for writing register A's value out onto
- 7:24:38the bus and then we can read that value
- 7:24:42by pulsing uh RAM in. And since we've
- 7:24:45already loaded the address that we want
- 7:24:47to write into into the memory address
- 7:24:49register, uh the moment we pulse that
- 7:24:51RAM in and have a rising clock edge,
- 7:24:53it'll lock the value from register A in
- 7:24:57to the correct uh component on the bus.
- 7:25:00And so you might be noticing, hey, we
- 7:25:03don't have a way for to actually write
- 7:25:05register A or B onto the bus. So, uh
- 7:25:08we'll go ahead and and do that. So, we
- 7:25:11could do
- 7:25:14two.
- 7:25:15And so we can call that uh A out. And
- 7:25:20then we can do the same thing
- 7:25:24if we needed to for B.
- 7:25:31And this is the the power, you know,
- 7:25:32this is the power of the bus. we can
- 7:25:34just decide to connect things and it's
- 7:25:36just as easy as connecting them versus
- 7:25:38for if we had to connect it to every
- 7:25:39other component, you know, we'd have to
- 7:25:41connect it to the the RAM in signal and
- 7:25:44then or it with a bunch of other things
- 7:25:46that already connected to the RAM in
- 7:25:47signal. So the bus really makes things a
- 7:25:49lot easier here.
- 7:25:54Okay,
- 7:25:56so that's story. The next is called LDI.
- 7:26:01That stands for load immediate
- 7:26:07and its op code is you could probably
- 7:26:09guess 4 + 1 is five. And [snorts]
- 7:26:12this one's a little bit different. So up
- 7:26:15until now, every argument here
- 7:26:19has every instruction has had an
- 7:26:21argument which is interesting in itself.
- 7:26:24Uh we will see that that's not always
- 7:26:26the case.
- 7:26:28But uh
- 7:26:31whenever there has been an argument,
- 7:26:33it's been an address into RAM. This time
- 7:26:37the argument will actually be treated as
- 7:26:39a literal number. And what it'll do is
- 7:26:42it'll load whatever the argument is into
- 7:26:47register A.
- 7:26:56So this contrasts well with our very
- 7:26:59first command, our very first
- 7:27:01instruction load A. And you can see the
- 7:27:03difference here is load A will take the
- 7:27:06argument and interpret it as an address
- 7:27:08in memory and go look up whatever is in
- 7:27:10that address of memory in RAM and feed
- 7:27:13that into register A versus load
- 7:27:15immediate will just take whatever the
- 7:27:17argument is, interpret it as a number
- 7:27:19itself and load that into RAM. So if I
- 7:27:21had load immediate with uh 011,
- 7:27:27this will load the immediate 011 into
- 7:27:29register A, which means register A will
- 7:27:31have the value of 1 + 2 + 4, which is 7.
- 7:27:36And it does mean that load A the you can
- 7:27:40only put in a value that's representable
- 7:27:42in four bits. So the the biggest value
- 7:27:44you could put in is 1 1 1, which would
- 7:27:47be 1 plus 2 + 4 + 8. 8 + 4 is 12 + 2 is
- 7:27:5114 + 1's 15. So any number 0 through 15
- 7:27:55you can load in immediately
- 7:27:59uh to register A. And so why would we
- 7:28:00want to do this is because let's say I
- 7:28:03want to load the value five into
- 7:28:06register A. If we just had load A, we'd
- 7:28:09have to waste two instructions. We have
- 7:28:11to waste two of our slots in RAM. We'd
- 7:28:13have to waste one of them to h to house
- 7:28:15the load a instruction and then the
- 7:28:19argument to the load a instruction would
- 7:28:20point to a different spot in RAM which
- 7:28:22would house a literal value five.
- 7:28:25So this uses two spots in RAM to load a
- 7:28:28value uh to load a value into register
- 7:28:30A. But with a load immediate we could
- 7:28:31just do it with one. And RAM is a
- 7:28:33constrained resource here. So we only
- 7:28:36have uh four addresses. So we have two
- 7:28:37to the four um like 16 different spots
- 7:28:42in RAM which is not a lot to work with.
- 7:28:44So we want to use it as efficiently as
- 7:28:45possible. So that's why we have this.
- 7:28:48So that's a little bit different. And so
- 7:28:52now we've seen
- 7:28:54uh
- 7:28:56four examples where the ARG is a data
- 7:28:59address in RAM.
- 7:29:06Now we've seen one where arg is a
- 7:29:09literal.
- 7:29:10There's a literal number and well let's
- 7:29:14see what comes next. The next
- 7:29:17instruction is called
- 7:29:20JC. That means
- 7:29:24jump
- 7:29:26if carry.
- 7:29:31And here's our op code for it.
- 7:29:39Oh, sorry. I jumped ahead of myself
- 7:29:41here.
- 7:29:44Next instruction is called JMP for jump.
- 7:29:48It just stands for jump.
- 7:29:52And
- 7:29:54this is an interesting one. What this
- 7:29:57says is all it'll do
- 7:30:02is set the program counter
- 7:30:08equal to the argument. So
- 7:30:11this is super interesting and it might
- 7:30:13not seem that crazy at first, but recall
- 7:30:16our program counter starts at zero and
- 7:30:18then goes to one and goes to two. And
- 7:30:20pretty much it tells us
- 7:30:24uh what instruction what position in RAM
- 7:30:27we should look at to figure out what the
- 7:30:29next instruction our computer should
- 7:30:31execute is. And this has the effect of
- 7:30:33just walking down RAM top to bottom. But
- 7:30:36what jump lets you do is it lets you
- 7:30:38jump back to a a start. So let's say my
- 7:30:43RAM had some value. Uh let's say like my
- 7:30:46RAM was organized. So at address zero we
- 7:30:48had a load immediate
- 7:30:51three and then we had a add
- 7:30:59um
- 7:31:01add uh we could address six and then at
- 7:31:05address six and RAM we had the the
- 7:31:06literal value
- 7:31:09like one.
- 7:31:12Then what would happen is our computer
- 7:31:15would uh load an immediate three into
- 7:31:19register A and then add the value one to
- 7:31:22it so it have the value four. And if we
- 7:31:25wanted to keep doing this over and over,
- 7:31:27we'd have to keep adding uh the same add
- 7:31:31command
- 7:31:33over and over in RAM. Uh, and what we'd
- 7:31:38find is that we could only do it uh oh
- 7:31:40so many times before we run out of space
- 7:31:42and RAM. But what's kind of neat here
- 7:31:46is if I have a jump command
- 7:31:50back to address one, then when when our
- 7:31:54RAM finishes this first ad instruction,
- 7:31:56it'll then the program counter will
- 7:31:58increment from one to two. We'll get
- 7:31:59here. We'll see that the value in RAM
- 7:32:02address 2, its interpretable value says
- 7:32:05jump back to address one. And so it'll
- 7:32:09reset the program counter back to one.
- 7:32:13And so our PC will now point back to
- 7:32:15one. And then we execute the next
- 7:32:16instruction and we'll load the value
- 7:32:19address one into the instruction
- 7:32:20register. And that value is the
- 7:32:22operation to add uh whatever's at
- 7:32:24address six back to the register. And so
- 7:32:27this would just increment the A register
- 7:32:29by one again. And then we do that, come
- 7:32:31back here, and we kind of keep bouncing
- 7:32:33in this loop. Um, and so our program
- 7:32:36would kind of never finish. And the
- 7:32:37value in the A register would just keep
- 7:32:39increasing by one, and it it just be
- 7:32:41counting up, which is pretty
- 7:32:42interesting.
- 7:32:45So jump lets you change the fundamental
- 7:32:48control execution scheme of your
- 7:32:49computer.
- 7:32:56Okay, we can take jump a little further.
- 7:32:59Uh, I'm actually going to
- 7:33:06I'm going to go ahead and erase this
- 7:33:16and I will clean this up here.
- 7:33:23And we have four more instructions left
- 7:33:26to build out.
- 7:33:29The first we have two more jump related
- 7:33:32instructions.
- 7:33:37JC, which stands for jump if carry
- 7:33:47and the op code is as you could guess
- 7:33:50011.
- 7:33:53And what this says is if the last
- 7:33:58result, if the last operation that
- 7:34:01happened in the ALU uh carried i.e
- 7:34:04there's that overflow then we can jump
- 7:34:07to a specific address in memory
- 7:34:09otherwise you go on. So
- 7:34:16if carry
- 7:34:18lag equals 1,
- 7:34:23PC equals arg
- 7:34:27no
- 7:34:30and
- 7:34:34When we talked about our ALOU a long
- 7:34:36time ago,
- 7:34:38we built this by chaining a bunch of uh
- 7:34:40full adders together and the carry out
- 7:34:44of one adder became the carry in of
- 7:34:47another adder. But then recall for the
- 7:34:49leftmost adder, there was a carry out
- 7:34:51flag and
- 7:34:54if that flag was a one it meant we
- 7:34:56overflowed, meaning we couldn't fit the
- 7:34:58value into eight bits.
- 7:35:01And so we've kind of ignored that in our
- 7:35:03alou here. But what we can actually do
- 7:35:06is just uh build a build a new register
- 7:35:10that uh looks at this carry flag. Um so
- 7:35:15it can take the uh it can be called the
- 7:35:18flags register and it'll whenever we do
- 7:35:22an alou operation we'll look and say hey
- 7:35:25did this last carry did the last the
- 7:35:27leftmost full adder carry out and if it
- 7:35:30did then we know that the last
- 7:35:32arithmetic operation that happened in
- 7:35:34the alou overflowed assuming we're
- 7:35:36working with positive numbers we'll just
- 7:35:38keep it simple for now and if it did we
- 7:35:41should latch that value into this flags
- 7:35:43register
- 7:35:44So,
- 7:35:46what I'll do over here is I'll have a
- 7:35:51flags register
- 7:35:54and it's going to be two bits.
- 7:35:57And
- 7:36:01what we'll need to do is also add a new
- 7:36:05control line for flags in. So this will
- 7:36:09read uh it'll interpret whatever values
- 7:36:13the state of the alou and and and latch
- 7:36:17that value in. And of course
- 7:36:21I need to end that with the clock.
- 7:36:38So why is this two bits if uh we encode
- 7:36:42if the carry out is one bit? Well, we'll
- 7:36:44see when we come back to the next
- 7:36:45instruction. But uh the other thing
- 7:36:49that's interesting to know is if the uh
- 7:36:53output of the ALU is zero. So we'll have
- 7:36:56one flag for measuring if the ALU
- 7:36:59carried uh if there was overflow carry
- 7:37:02out I guess.
- 7:37:05and then one flag for measuring if the
- 7:37:08last ALU operation was a zero. And you
- 7:37:11can detect if the last ALU operation was
- 7:37:13a zero by looking at all the output
- 7:37:14registers and uh saying that they are
- 7:37:18all zero. So you would invert each one
- 7:37:20and then add them all together. So the
- 7:37:23each bit position like bit position one
- 7:37:26not and bit position two not and bit
- 7:37:30position three not and so on and so on.
- 7:37:33So you'd assert that they're all zero.
- 7:37:35Uh so you could invert all of those and
- 7:37:38add them together and that would pretty
- 7:37:40much be your your zero flag. I won't
- 7:37:42show that logic here because I'm trying
- 7:37:44to avoid draw drawing individual logic
- 7:37:46gates. But let's see why this jump carry
- 7:37:50command might be useful. So in our
- 7:37:52original example we have here um we
- 7:37:55started with the the number three.
- 7:37:58I guess if we looked at the state of the
- 7:38:00aa register, it'd be three and then four
- 7:38:02and five and six so on. And then
- 7:38:06eventually because our register is eight
- 7:38:08bits, we'd uh we'd get to the maximum
- 7:38:12value that we can store in 8 bits. So 2
- 7:38:15to the 8, let me use my calculator right
- 7:38:17here. 2 to the 8
- 7:38:20is 256 which means we can store values 0
- 7:38:24through 255
- 7:38:26assuming we're just looking at positive
- 7:38:27numbers only but let's say we are for
- 7:38:29now. So
- 7:38:32uh your computer were to get to 250
- 7:38:36and then 251 2523
- 7:38:40254
- 7:38:43255.
- 7:38:44And if we tried to add the number one to
- 7:38:47it again, we have the binary. This is
- 7:38:50what the 255 looks like in binary. If we
- 7:38:53tried to add one to it,
- 7:38:56what actually happens is pretty
- 7:38:58interesting where you can kind of see
- 7:39:09that it'll roll all the way back to zero
- 7:39:12and then we'll have carried out. So, uh,
- 7:39:15if we let this keep running this
- 7:39:17program, what happens is we'd start at
- 7:39:20three, count to 255, and then go back to
- 7:39:22zero and keep counting from zero, back
- 7:39:26up to 1 to 2 to 3 to 4, all the way back
- 7:39:28up to 255. So, pretty much what happen
- 7:39:30is we just keep counting 255 and then
- 7:39:31resetting to zero. Maybe you once you
- 7:39:34hit 255, you don't actually want to uh
- 7:39:37count any further. So, uh, we could
- 7:39:40restructure this program and say,
- 7:39:44um,
- 7:39:45what I'll do here is we could say
- 7:39:56if once you every time you do an
- 7:39:58addition, if you carried uh, then maybe
- 7:40:01you could jump to like address 10 or
- 7:40:04somewhere further away in memory. Um
- 7:40:07otherwise you would jump back to address
- 7:40:10one and keep doing another arithmetic.
- 7:40:13Um and so that way you know every time
- 7:40:15you do an addition you don't try to do
- 7:40:17another one right away by jumping back
- 7:40:19to that same ad operation. You check hey
- 7:40:21did the last result overflow. If it did
- 7:40:24we can stop counting we're at 255 and
- 7:40:27end the program by jumping somewhere
- 7:40:29else in memory.
- 7:40:31So that's just a little bit of
- 7:40:32motivation for that.
- 7:40:38And I said we uh added two flags to our
- 7:40:42register because we wanted to know if
- 7:40:44you could carry out. We also wanted to
- 7:40:46know if the last ALOU result was a zero.
- 7:40:48So we'll go ahead and build that out
- 7:40:50too. And that's going to be called JZ.
- 7:40:54That means jump if zero.
- 7:41:00So, uh, that's going to have the op code
- 7:41:02of 1 0 0. And it pretty much says if the
- 7:41:07zero flag
- 7:41:11equals one, then the program counter can
- 7:41:16equal the argument, i.e. we jump to a
- 7:41:17new address. Otherwise, we don't do
- 7:41:19anything.
- 7:41:22And uh well, you kind of already know
- 7:41:23how that one works. It's the same thing
- 7:41:25except uh you know we need to look at
- 7:41:27the value in the uh the flags
- 7:41:31uh the flags register. So you know the
- 7:41:33first bit position is for carry and you
- 7:41:36could say the second bit position is for
- 7:41:38zero. So we just need to make sure we're
- 7:41:40looking at the right one.
- 7:41:48Okay. Our next instruction
- 7:41:52you might have noticed is we've now
- 7:41:54inter we have instructions to interface
- 7:41:55with every part of this computer except
- 7:41:58for one and that's the display that we
- 7:42:00talked about just uh just fairly
- 7:42:02recently.
- 7:42:03So let's have an instruction to actually
- 7:42:05write uh whatever value is in the A
- 7:42:09register since that's so critical to our
- 7:42:11computer
- 7:42:13um onto the bus and then latch that into
- 7:42:16the output register. So, we're going to
- 7:42:19call this command out.
- 7:42:25It's just
- 7:42:27be display. Uh, they're synonymous here.
- 7:42:30It's op code. Uh, we'll just jump around
- 7:42:34here. We can give it whatever. Let's
- 7:42:36just, uh, throw it 11 1 arbitrarily. We
- 7:42:39can kind of choose what our operation
- 7:42:40codes are. We've been sequential
- 7:42:44up to this point, but there's no harm in
- 7:42:48using the address space however we'd
- 7:42:50like or sorry, using that four bit space
- 7:42:53however we'd like to define our
- 7:42:54instructions. And so if we say formally
- 7:42:57what the
- 7:42:59uh out command does, it's going to set
- 7:43:02our output register equal to register A,
- 7:43:07which will then have the effect of
- 7:43:09displaying
- 7:43:12whatever is in register A onto this
- 7:43:15seven segment display because the way we
- 7:43:17designed that readonly memory was to
- 7:43:19just look at whatever is in this uh
- 7:43:21display register. And so you can imagine
- 7:43:23to implement this command is pretty
- 7:43:25straightforward. You just put the value
- 7:43:26of register A onto the bus with a out.
- 7:43:29And at the same time, you'd have display
- 7:43:31in. And since display ins and with the
- 7:43:33clock, as is every in signal, once you
- 7:43:36have a rising clock edge, it'll hook the
- 7:43:38value into that register. And then ROM
- 7:43:40is just a constant lookup table. So,
- 7:43:42it's always just going to be looking up
- 7:43:43whatever is it's always going to be
- 7:43:45reacting to what's in the register.
- 7:43:46It'll look up. It'll say, "Hey, this
- 7:43:48value is on the register. Like, let's
- 7:43:49just display it on the screen."
- 7:43:54And last but not least is called halt.
- 7:44:06We'll give it op code 1111. And what
- 7:44:09halt will do is it'll physically stop
- 7:44:11the computer.
- 7:44:15So if the computer sees a halt signal,
- 7:44:18if the if we uh have some address in our
- 7:44:21program counter, we look up whatever is
- 7:44:23in that address in RAM, put that in the
- 7:44:25instruction register, and our control
- 7:44:26brain sees that it's a halt, it'll stop.
- 7:44:29It literally will just break like it it
- 7:44:31the computer will not execute anything
- 7:44:33further.
- 7:44:35Um, and that'll be the end of execution
- 7:44:38here. So these are all the instructions
- 7:44:40our toy computer has.
- 7:44:44And
- 7:44:46what's uh a few things to of of note
- 7:44:48here. So we saw that for the first few
- 7:44:50arguments we for the first few
- 7:44:51instructions we built out there were all
- 7:44:54arguments. The arguments were all data
- 7:44:56addresses and RAM. Then we saw an
- 7:44:58instruction who had an argument but the
- 7:44:59argument was a literal number. And then
- 7:45:02for the three jump instructions, the
- 7:45:05argument
- 7:45:06was an instruction address,
- 7:45:13but the instruction address also lived
- 7:45:15in RAM.
- 7:45:18And so there's something interesting to
- 7:45:20be said that RAM has both our data and
- 7:45:23our instructions.
- 7:45:25And the only like the computer doesn't
- 7:45:28really care which is which. It's
- 7:45:29strictly just going to do what you tell
- 7:45:30it to do. So you could actually write uh
- 7:45:34an instruction
- 7:45:36in one position. Uh let's say if I wrote
- 7:45:39an instruction uh at address 4 in RAM
- 7:45:42and then if I called load a on address
- 7:45:464, then it would still work. It would
- 7:45:49interpret whatever the value of the
- 7:45:50address is
- 7:45:54as a literal for the load A. But then
- 7:45:56when we're our program counter equals
- 7:45:58that address, it treats this
- 7:45:59instruction. So it's pretty cool that uh
- 7:46:02it might be weird to wrap your head
- 7:46:03around but conceptually
- 7:46:06values in RAM can be both literals data
- 7:46:11literals or instructions. It just
- 7:46:14depends on the context of how it's how
- 7:46:16that value is being accessed.
- 7:46:18Whenever that value is being accessed
- 7:46:20through the program counter
- 7:46:23or one of these yeah through program
- 7:46:24counter it's definitely going to be a
- 7:46:27treat it as an instruction. But then in
- 7:46:29a lot of these other contexts, if it's
- 7:46:31like an argument to an instruction, it's
- 7:46:33going to be treated as a a literal
- 7:46:35number, which is pretty cool.
- 7:46:38And then we saw down here that there is
- 7:46:41no argument for our final two
- 7:46:43instructions. So those write four bits
- 7:46:46are actually kind of wasteless. You
- 7:46:47could set them whatever you want.
- 7:46:50Another thing to note is we have four
- 7:46:52bits of our op code. So that should be
- 7:46:5416 possible different instructions. But
- 7:46:57if I count out what I have here, I have
- 7:46:581 2 3 4 5 6 7 8 I have 10 different
- 7:47:01instructions. So we are not using our
- 7:47:04instruction space fully. So we could
- 7:47:07define more instructions. It turns out
- 7:47:09this set of instructions is nice because
- 7:47:11it lets us uh kind of define simple
- 7:47:14enough pro like complete enough programs
- 7:47:15on its own. But you know we talked about
- 7:47:18very earlier like hey like our load a
- 7:47:20add and subtract all simply operate on
- 7:47:22register A. Maybe I could use some of
- 7:47:24those extra op codes to build load B or
- 7:47:26add B or subtract B instructions.
- 7:47:29Similarly, our out command will only put
- 7:47:31whatever is in register A onto the seven
- 7:47:34segment display. Maybe I want a way of
- 7:47:36having uh an an out for B. Uh and you
- 7:47:40could imagine extending this computer in
- 7:47:42ways on your own. You could have a
- 7:47:44second output display and that second
- 7:47:46output display could have its own
- 7:47:47command where you could write in the
- 7:47:48value of register B to that uh display
- 7:47:52based on you know
- 7:47:55whatever the argument is. Uh so there
- 7:47:57there's different ways you can extend
- 7:47:59this.
- 7:48:01So now we've defined our instructions.
- 7:48:04Um we walk through load A in great
- 7:48:06detail and we'll do that for some of the
- 7:48:08others. But the last thing we need to do
- 7:48:12here is tie it together with this
- 7:48:15control brains.
- 7:48:18And it turns out we know everything we
- 7:48:21need to tie this computer together and
- 7:48:23explain how this control logic works.
- 7:48:26The very last thing I'll do that I will
- 7:48:27spill out to make it a little bit
- 7:48:29easier. Well, obviously because I'm
- 7:48:30going to explain. But [clears throat] um
- 7:48:33we discussed this instruction. The very
- 7:48:34last one we discussed was halt. And what
- 7:48:38halt should do is it should stop the
- 7:48:39computer. And so you can pretty much see
- 7:48:41that when we designed our the only one
- 7:48:43we walked through in good detail was
- 7:48:45this load a we looked at the timing
- 7:48:47diagram and the in the rising and
- 7:48:49falling edges of the clock. Um pretty
- 7:48:52much you could see that we were making
- 7:48:53every decision based on and making every
- 7:48:56setup i.e. setting different lines you
- 7:48:59know saying this component read its
- 7:49:00value in from the bus and this other
- 7:49:02while this other component is putting
- 7:49:04its value onto the bus. All that was
- 7:49:06based around the clock. And so it turns
- 7:49:09out if a very simple way to actually
- 7:49:11halt the computer and prevent it. Uh
- 7:49:14there's two things you could think of.
- 7:49:16Um my mind when I went to this was
- 7:49:18actually just stopping any instruction
- 7:49:20from getting in the program counter. So
- 7:49:22if the program counter if the program
- 7:49:24counter could never update, then no
- 7:49:26instruction, you know, could be
- 7:49:28executed. But then there's actually like
- 7:49:30something incorrect about that and that
- 7:49:32there's still a value in the program
- 7:49:33counter. So that value cannot can be
- 7:49:35interpreted as an instruction and it
- 7:49:37can't execute. And so that wouldn't
- 7:49:38work. Nor would blocking the program
- 7:49:40counter from writing out onto the bus
- 7:49:42work because uh basically we we always
- 7:49:45say that if a component is reading in
- 7:49:46from the bus, there has to be something
- 7:49:47on the bus. You get into a weird state
- 7:49:49if you have a component that tries to
- 7:49:51read on the bus and there is physically
- 7:49:52nothing on it. I.e. every other
- 7:49:54component that could write onto it.
- 7:49:56Namely, the program counter here is
- 7:49:58actually disconnected. So you might want
- 7:50:00to think let's stop the program counter
- 7:50:02from being able to write its value onto
- 7:50:04the bus and therefore when we try you
- 7:50:06know looked up that address and ram and
- 7:50:08treat as instruction it it won't work
- 7:50:10but the behavior is somewhat undefined
- 7:50:12here um what's easier it turns out and I
- 7:50:16think the only solution for the sake of
- 7:50:18our simplistic computer is just blocking
- 7:50:21the clock but we discussed earlier that
- 7:50:24the clock is always just going up and
- 7:50:26down like it's a physical circuit and
- 7:50:28that's not something we can necessarily
- 7:50:30control. So the way we circumvent this
- 7:50:33is by actually all these components that
- 7:50:36depend on the clock, they don't quite
- 7:50:38depend on just the clock. We'll actually
- 7:50:40and it with some signal. Um and
- 7:50:44basically whenever we set that signal,
- 7:50:47it'll if it is set, it'll prevent the uh
- 7:50:51the clock from actually making any
- 7:50:53progress. So it'll force it to either
- 7:50:54always stay low or always stay high. It
- 7:50:57doesn't really matter which we let it
- 7:50:58at. Um,
- 7:51:00but what we can do here and how we can
- 7:51:02build that circuit is so our instruction
- 7:51:05is called halt. So I'll just call it
- 7:51:07halt. But it'll just be quite literally
- 7:51:09the input to a logicate. We have this
- 7:51:11halt sign and this clock sign. And we
- 7:51:13also probably want uh or let's and them
- 7:51:17together.
- 7:51:20Um, what I was going to say is we
- 7:51:22probably want it such that if our halt
- 7:51:23line is zero, everything is allowed to
- 7:51:26run as normal. But then the when we set
- 7:51:28our halt line to one is when we block
- 7:51:29the clock. So uh what I'll actually do
- 7:51:33is instead of hooking in the halt line
- 7:51:35directly, I'll invert it and then feed
- 7:51:38it in here. And then this output is the
- 7:51:41clock that goes to the rest of the
- 7:51:42computer. And so it turns out that this
- 7:51:46then is another circuit for us to use.
- 7:51:49And I'll kind of move this diagram up
- 7:51:52here
- 7:51:54and we can shift it all down a little
- 7:51:55bit.
- 7:51:58Cool. So what this has the effect of
- 7:52:01doing is what normally in normal
- 7:52:03execution this hot line is zero which
- 7:52:05means we the inverted value is one and
- 7:52:07so the output of this and gate is just
- 7:52:10whatever the value of the clock is which
- 7:52:11is this circuit that's always just
- 7:52:12pulsing between zero and one so it's
- 7:52:14frequently changing it's volatile. Now,
- 7:52:16if we were to flip the halt sign to one,
- 7:52:18the inverse would be zero. And hopefully
- 7:52:20you know by now that anything ended with
- 7:52:23zero is just going to give zero itself,
- 7:52:25which blocks the clock from making any
- 7:52:26progress. And so that when we actually
- 7:52:29get to it and figure out how to
- 7:52:30implement the halt instruction, all that
- 7:52:32instruction has to do is flip this halt
- 7:52:35line to true and it'll stop. It'll
- 7:52:37actually just break anything from making
- 7:52:38further progress. the computer gets into
- 7:52:41a quite literally rec uh unreoverable
- 7:52:44state and nothing can make progress.
- 7:52:49So now we can tie this all together and
- 7:52:53figure out how our control works. And I
- 7:52:55can guarantee that
- 7:52:58you could reason about this yourself
- 7:53:00based on everything we've learned in the
- 7:53:02video so far. There is nothing I'm going
- 7:53:04to introduce here that isn't already
- 7:53:05known to you and that's pretty powerful.
- 7:53:08Um, that being said, I remember when I
- 7:53:10was learning this, this was insanely
- 7:53:12bizarre to wrap my head around and I had
- 7:53:15to have it spilled out to me. The entire
- 7:53:17time I was building the computer, I
- 7:53:18could understand how each component
- 7:53:20works. And it was like, oh, that's how
- 7:53:21the ALOU works. Oh, that's how a
- 7:53:22register works. That's how a counter
- 7:53:24works. That's how RAM work. All makes
- 7:53:26sense. And then when it gets to tying it
- 7:53:28together, you're kind of like, okay,
- 7:53:29well, I understand how each of these
- 7:53:30components work individually, but I
- 7:53:33understand how you can punch lines to
- 7:53:34kind of have them communicate with each
- 7:53:36other via this bus, but how can the
- 7:53:38computer do it all itself? And, you
- 7:53:39know, how do we remove the human element
- 7:53:41of this from the loop, assuming that we
- 7:53:43have some uh program specified in RAM?
- 7:53:46Um, so let's tie it together right now.
- 7:53:48And I'd say this is probably the crux of
- 7:53:50the past eight hours of this video. Um,
- 7:53:55it's crazy for it to be the crux because
- 7:53:57we're not going to build anything you
- 7:53:59already have not seen, but it is very
- 7:54:02powerful to see how something you have
- 7:54:03already seen can be reused again in a
- 7:54:06totally different manner to bring so
- 7:54:08much more complexity to the system. So,
- 7:54:10let's think about so far we've been
- 7:54:12serving as the control. Let's been
- 7:54:14thinking about um what we've been taking
- 7:54:17in as input to the control. So us input
- 7:54:21um
- 7:54:22and
- 7:54:24basically there's a few things. So
- 7:54:25number one is the op code from the
- 7:54:27instruction register. This you know this
- 7:54:30this line right here this arrow. Um
- 7:54:32whatever the op code is in that
- 7:54:34instruction register we use that to
- 7:54:37denote what instruction we're executing
- 7:54:38in. So our inputs are you know this op
- 7:54:41code
- 7:54:43and that's four bits.
- 7:54:47And then we also said that we were
- 7:54:49designing this computer such that oops
- 7:54:52some weird coloring happened here. Um
- 7:54:56such that each instruction that we
- 7:54:59defined in our table took five clock
- 7:55:00cycles to add. And when we walked
- 7:55:03through the load a instruction, you
- 7:55:04know, we went through the little timing
- 7:55:05diagram and showed, hey, we'd set this
- 7:55:07here and you know, clear it here and
- 7:55:08then set these next thing here and clear
- 7:55:10it here. Um and so we were internally
- 7:55:13keeping track of our clock cycles. Um,
- 7:55:17turns out we're going to want to have a
- 7:55:19counter. And so we can we want to count,
- 7:55:21you know, just from
- 7:55:23uh zero to to one um or sorry 0 through
- 7:55:28five, I guess, 0 through four here. So
- 7:55:30what we do is um
- 7:55:34we have to represent five values. So
- 7:55:36we'll build a simple counter on the side
- 7:55:40here. And the counter we build is going
- 7:55:43to be very similar to the program
- 7:55:45counter up here. Except the difference
- 7:55:48is is it's always just going to be
- 7:55:50counting one to five. 0 to four to be
- 7:55:53correct here. It's going to count in
- 7:55:55cycles of five and then reset on its own
- 7:55:57based on the clock at any given time. So
- 7:56:00instead of it needing to be explicitly
- 7:56:01set by anything, we already know that
- 7:56:04each instruction is going to use five
- 7:56:05clock cycles. when we get to clock cycle
- 7:56:08number five and do our work, we should
- 7:56:10reset to zero because now we're counting
- 7:56:12for the the start of the next
- 7:56:13instruction. So, we kind of have this
- 7:56:16counter circuit
- 7:56:18um counter and it has this same plus one
- 7:56:25except it's input signal is just always
- 7:56:28going to be the clock.
- 7:56:33So I'll highlight that too for sake of
- 7:56:36consistency.
- 7:56:40So the output for our counter our
- 7:56:43counter is actually going to be three
- 7:56:44bits. The reason is um we need to count
- 7:56:48each instruction takes five steps. We
- 7:56:49need to count 1 2 3 4 5. If we do that
- 7:56:52in binary, you know, it starts with 0 0
- 7:56:550
- 7:56:581 0 0 1 0 0 1 1 and then 1 0 0. These
- 7:57:05are the uh five different values we use
- 7:57:07to denote whatever step we're currently
- 7:57:09executing of the current instruction
- 7:57:11we're on. So not different instructions.
- 7:57:13Instruction is an entire one of these
- 7:57:15commands right here. But to implement
- 7:57:17each of these instructions, we use five
- 7:57:19steps. and five steps would be five
- 7:57:22clock cycles here because we're counting
- 7:57:24up one every clock cycle. And so this is
- 7:57:27three bits. So, uh that was a little bit
- 7:57:31of a side tangent, but that is to say
- 7:57:35that uh this counter goes into our um
- 7:57:40you know, it's part of our control
- 7:57:41brains. You know, we'll just call it
- 7:57:43like step number represents the step
- 7:57:45number. What step are we on of the
- 7:57:47current instruction? So each time we're
- 7:57:49setting lines, it matters how far along
- 7:57:51we are in our current instruction. So
- 7:57:53that's also something we've been
- 7:57:54interpreting as an input to our control.
- 7:57:57And we haven't explicitly designed this
- 7:57:58as a counter. But you know, when we've
- 7:58:00been doing it, we've been looking at the
- 7:58:02timing sequences, looking at, hey, the
- 7:58:04clock's low and it's about to go high or
- 7:58:06vice versa and then setting control
- 7:58:07lines appropriately. as we shift the uh
- 7:58:10discretion away from us mainly punching
- 7:58:13lines uh into the computer, the computer
- 7:58:16needs a way of knowing what step number
- 7:58:18is on. Is it on one two three four five?
- 7:58:20And so the easiest way to do that is
- 7:58:22just to have a register that is a
- 7:58:23counter and then feed that as input to
- 7:58:26our control. And our control then can
- 7:58:27say rather than us as a human on step
- 7:58:30five, we could just look at what the
- 7:58:31output is on that step number line to
- 7:58:34figure out where we are in terms of
- 7:58:35execution of the current instruction. So
- 7:58:39that's the second step or sorry second
- 7:58:42input step number
- 7:58:45and that's three bits
- 7:58:49and then the last thing that might you
- 7:58:52might think that's all but recall the uh
- 7:58:56two jump the two conditional jump
- 7:58:58statements um those perform a jump
- 7:59:02operation based on the last output of
- 7:59:06the alou
- 7:59:07which is stored in this flags register.
- 7:59:09So that flags register we also need to
- 7:59:12know what's in it for us to make our
- 7:59:14decisions. Um so that's also something
- 7:59:16we've been considering as input when
- 7:59:18we've been implementing the control
- 7:59:20ourselves. And so you know we have the
- 7:59:22zero flag which is one bit and then the
- 7:59:26carry flag which is one bit.
- 7:59:30And so these are all the inputs we've
- 7:59:33needed to then look at a timing diagram
- 7:59:35and figure out what inputs uh or what
- 7:59:38control things need to be set at any
- 7:59:39given time. So what are the outputs now?
- 7:59:46So any step we've been looking at, hey,
- 7:59:49this is the instruction in the
- 7:59:50instruction register. Here's what step
- 7:59:52number we're on. And for two of our
- 7:59:54instructions, our conditional jump uh
- 7:59:55instructions, we're also looking at this
- 7:59:58flag register. we for the most part we
- 8:00:00aren't really looking at it but we you
- 8:00:01know we are for two instructions. So it
- 8:00:02turns out for the bulk of them we ignore
- 8:00:04them but you know we can't just turn
- 8:00:06things on and off for what our control
- 8:00:08looks at when it's the brains. Uh so
- 8:00:11we'll have to just have the input be
- 8:00:12fixed all the time. You know you
- 8:00:13couldn't pick up a wire and throw it
- 8:00:14away. That defeat the purpose because
- 8:00:16then you'd have a human be intervening.
- 8:00:18um the control itself will just know
- 8:00:21like if you're doing a load a
- 8:00:23instruction or a subtract instruction or
- 8:00:26something of the sort and it doesn't
- 8:00:28matter what's in those flag uh in that
- 8:00:30in that flag register it has no effect
- 8:00:32on the output of uh how you implement
- 8:00:35that instruction.
- 8:00:36So then that's what we've been looking
- 8:00:39at. I'm calling that as our input to
- 8:00:40make each of the decisions as to what
- 8:00:43outputs we set. And so outputs are
- 8:00:46pretty much uh if I've drawn this
- 8:00:47correctly and completely should just be
- 8:00:50everything that's yellow here. So you
- 8:00:53know we've been serving as the human but
- 8:00:55ideally the control would look at the
- 8:00:57state of the machine based on these
- 8:00:59inputs and then just know what outputs
- 8:01:02to set. So let's actually go ahead and
- 8:01:05enumerate over all of our outputs. Um
- 8:01:08and then we can you know tie it together
- 8:01:10in a more concrete place. So we just
- 8:01:12discussed the halt line that'll stop the
- 8:01:15clock from executing. So the moment the
- 8:01:17computer puts that out, it's actually
- 8:01:18doomed. Uh the moment it puts that out
- 8:01:21and um means the clock cannot make any
- 8:01:23further progress, which means the state
- 8:01:26of the machine just freezes pretty much.
- 8:01:28Um then uh looking below it, we have the
- 8:01:33memory address register in I'll just
- 8:01:35call that, you know,
- 8:01:37mar in. I don't want to write the full
- 8:01:39thing out. After that uh we had RAM in
- 8:01:44which reads the value
- 8:01:47uh on the bus
- 8:01:49into the whatever address is stored in
- 8:01:51the memory address register. Then we
- 8:01:53have RAM out. And to recall what RAM out
- 8:01:57does is whatever address is stored in
- 8:02:00the memory address register, it'll
- 8:02:01always be looked up in RAM and that
- 8:02:04value will always be on this side of the
- 8:02:06line. When we toggle RAM out, it'll just
- 8:02:08let that value flow to the bus. So in
- 8:02:10short, RAM outputs whatever value is in
- 8:02:13RAM at the address denoted by the memory
- 8:02:14address register onto the bus.
- 8:02:17Then we have uh this instruction
- 8:02:19register instruction register out
- 8:02:22because sometimes we want to jump to a
- 8:02:24specific address. So we need to get that
- 8:02:26argument of the address or anytime we
- 8:02:28just need to put the argument uh for an
- 8:02:30instruction that has an argument onto
- 8:02:31the bus you know we write instruction
- 8:02:33register out
- 8:02:36and then we also have instruction
- 8:02:38register in because we obviously need to
- 8:02:39get whatever instruction we're executing
- 8:02:40from RAM into that register. So IR in
- 8:02:46and
- 8:02:49after that um we can jump to the top of
- 8:02:52our computer.
- 8:02:54Uh for the ALOU we have register A in
- 8:02:57and then register A out. Register A in
- 8:02:59will just latch whatever is on the bus
- 8:03:01into register A and A out will write
- 8:03:03whatever is on the in register A to the
- 8:03:05bus.
- 8:03:07So we have A in and I'll denote that A
- 8:03:10out.
- 8:03:12Then we have
- 8:03:14the uh alou out. Whatever the output is,
- 8:03:17whatever the current output of the alou
- 8:03:18is, write that onto the bus.
- 8:03:21AL out.
- 8:03:25Then we have uh this add subtract line.
- 8:03:29If we're doing it for any instruction
- 8:03:31that's not an add or a subtract, it
- 8:03:32doesn't matter what it is because we
- 8:03:33don't care what's what the output of the
- 8:03:35ALU is. We're not going to interpret it.
- 8:03:37Um, for add and subtract is the only
- 8:03:39time the value on this line matters.
- 8:03:41When we're adding, we just leave it as a
- 8:03:43zero. When we're subtracting, uh, is the
- 8:03:45only time we'd ever need to set it to a
- 8:03:47one.
- 8:03:51So, we can just call that sub uh, sub
- 8:03:54because it's always going to be zero.
- 8:03:56The only time we need to turn it on is
- 8:03:57for doing subtraction. So, let's just
- 8:03:58call it sub subtraction. Um then we have
- 8:04:04uh B register in and B register out. It
- 8:04:09turns out for the instructions we've
- 8:04:11defined here and you'll see this as we
- 8:04:13I'll go through and we'll implement each
- 8:04:14of these instructions
- 8:04:16B does not ever actually need to write
- 8:04:18onto the bus. If we were to expand the
- 8:04:21computer then it would. So I'll actually
- 8:04:23for the sake of keeping this diagram as
- 8:04:25minimal as possible erase that. But you
- 8:04:28can imagine we could add more
- 8:04:29instructions here. We talked about this
- 8:04:31like not too long ago. You know the out
- 8:04:33instruction for example writes whatever
- 8:04:35is in the register A to the seven
- 8:04:38segment display. We could have a similar
- 8:04:39command for outb just takes whatever's
- 8:04:42in the register B and writes that to the
- 8:04:44seven segment display. So uh it's not
- 8:04:46like it's useless but for the
- 8:04:48instruction set we've defined here it's
- 8:04:50actually not necessary. So I'll just
- 8:04:52keep it out for uh simplicity. But we do
- 8:04:54have BN.
- 8:04:56I'll denote that be I and then we're
- 8:04:59just talking about the output register.
- 8:05:00So we should uh talk about that. Uh the
- 8:05:03output register in it's called display
- 8:05:05in here. I'll just call it oi. Output
- 8:05:07register in. Then um I I should have
- 8:05:12started up here. We have the program
- 8:05:14counter. So we we want program counter
- 8:05:17in if we're going to read a value uh or
- 8:05:20increment the program counter. Sorry.
- 8:05:22and then uh program counter out
- 8:05:28for writing that program counter uh
- 8:05:30value onto the bus.
- 8:05:36So we have counter
- 8:05:41increment
- 8:05:44and then counter out.
- 8:05:50And as I'm writing this, I realize we
- 8:05:53have a little mistake here where uh we
- 8:05:57know for our jump instructions. What the
- 8:06:00jump instruction does is it tells the
- 8:06:02computer, hey, like if the program
- 8:06:03counter says the next instruction
- 8:06:05executes at address five,
- 8:06:07ignore it and jump to actually this
- 8:06:09other address. So right now we actually
- 8:06:12can't support that because our PC inc
- 8:06:15will actually only increment the program
- 8:06:17counter. But we also want
- 8:06:20um a way to read a value from the bus
- 8:06:23into the program counter. So you can
- 8:06:25imagine we could just update our little
- 8:06:27circuit here because it's just a little
- 8:06:28alou. um and one line is doing the
- 8:06:32increment. Uh another line could
- 8:06:34actually just read a value into the
- 8:06:36underlying register that's the operand
- 8:06:38of the alou. And so we can call that um
- 8:06:41J. We'll call that jump because that's
- 8:06:44the only time we ever need to to write a
- 8:06:46direct value into the program counter.
- 8:06:49So sorry for the confusion there. We
- 8:06:51actually weren't fully complete. Jump.
- 8:06:54And then the very last output we might
- 8:06:56ever set uh is back here. Whenever we do
- 8:06:59an add or subtract, if we do an alou
- 8:07:02operation, we need to update the flags
- 8:07:04register because if there's an add or
- 8:07:06subtract and then there's either a jump
- 8:07:07carry or a jump zero afterwards, uh that
- 8:07:10means we would need to have known what
- 8:07:12the output of the last ALOU operation
- 8:07:14was. And so basically whenever we do an
- 8:07:16ALOU operation we will terminate it or
- 8:07:18just along the process look at the
- 8:07:21output and conditionally set these jump
- 8:07:23and carry flags which we talked about
- 8:07:24how to build those sep those um
- 8:07:27circuits. They're relatively simple.
- 8:07:30And so um these are all of our inputs
- 8:07:33and all of our outputs and I've kind of
- 8:07:35listed them out and we've talked about
- 8:07:37these uh so I'll stop explaining them
- 8:07:38because I think most of these should be
- 8:07:40clear by now. But the uh the crux of all
- 8:07:45of this is I claimed uh several times
- 8:07:48now that you already know how to build
- 8:07:50this control. And the reason is is
- 8:07:54because the input
- 8:07:57i.e. the combination of whatever
- 8:07:58instruction you're executing, what step
- 8:08:01of that instruction you're on, and then
- 8:08:04maybe the ALU flags will tell you
- 8:08:07exactly
- 8:08:09everything you need to know to determine
- 8:08:11which output lines to set. So basically
- 8:08:14we know that output
- 8:08:19is clearly some function of the input
- 8:08:23and we also know that each input
- 8:08:26combination has a well- definfined
- 8:08:28output combination because we've defined
- 8:08:30every instruction
- 8:08:32and we know that the program counter uh
- 8:08:35we also know that each instruction our
- 8:08:36counter over here is only going to go up
- 8:08:38to five up to one 0 0 uh binary Okay.
- 8:08:44And then we know that the zero flag and
- 8:08:47carry flag can either be zeros or ones.
- 8:08:50And so basically every time there's an
- 8:08:53input, the output will be the same. So
- 8:08:56output is always the same for the same
- 8:09:00input. So f of input equals output will
- 8:09:03always be true. Which means we basically
- 8:09:06have a deterministic input output
- 8:09:08sequencing here. The output can entirely
- 8:09:11be computed strictly looking at these
- 8:09:13input flags. And for a given combination
- 8:09:16of input flags, the output will never
- 8:09:19change. It'll always be the same. And so
- 8:09:22how we can encode this is the same way
- 8:09:25we built out the seven segment display.
- 8:09:28The readon memory that took in that we
- 8:09:31built earlier took in a value on a
- 8:09:34register denoted by eight bits and
- 8:09:37figured out which of the output lines
- 8:09:40for these four dis for I mean we built a
- 8:09:42one segment display or one unit of a
- 8:09:44seven segment display figured out which
- 8:09:46of the seven lines need to be set and so
- 8:09:48we had like a eight input um followed by
- 8:09:52I think that's four five six seven
- 8:09:54dimension output um and we said hey you
- 8:09:57So depending on what the input is for
- 8:09:59each of the input values we know oh
- 8:10:02sorry this also not uh this was whatever
- 8:10:05we could fit in in
- 8:10:08two digits I think it was four bits
- 8:10:10sorry but points taken here that um I'll
- 8:10:14say four or eight I don't remember off
- 8:10:15the top of my head but the point is
- 8:10:17taken that for this readonly memory it's
- 8:10:19core service was if you have a
- 8:10:22effectively would like to build a lookup
- 8:10:24table so for any for every combination
- 8:10:27of inputs has a clear output and then
- 8:10:31for any input combination the output
- 8:10:32should always be the same. Those two
- 8:10:35properties are what we discussed that
- 8:10:36made a readonly memory appropriate here.
- 8:10:39And so it turns out our control
- 8:10:43is none other
- 8:10:48than
- 8:10:52a read only memory. It is a ROM.
- 8:10:56and it takes in
- 8:10:594 + 3 + 2, that's nine inputs.
- 8:11:05And then it has however many outputs we
- 8:11:08have right here. And
- 8:11:12this is pretty powerful because it means
- 8:11:14if we set up this control ROM correctly,
- 8:11:17it means that the computer can be fully
- 8:11:20autonomous. And for every instruction,
- 8:11:23it'll start, it'll take the value in the
- 8:11:26program counter,
- 8:11:27look it up in RAM, get it in the
- 8:11:30instruction register itself, and then
- 8:11:32the control knows what values in the
- 8:11:34instru what instruction we're executing
- 8:11:36on. Uh, it also has this counter that's
- 8:11:38telling it what step of the instruction
- 8:11:39we're on. And then it can keep setting
- 8:11:41the correct outputs to execute the
- 8:11:43current command. And then since we have
- 8:11:46a line that increments the program
- 8:11:47counter when the current instruction is
- 8:11:49finally done, we can just repeat the
- 8:11:51same process because now our program
- 8:11:53counter points to the next address in
- 8:11:54memory. And this is the crux of of tying
- 8:11:58the computer together. You have now gone
- 8:12:01from individual components to actually a
- 8:12:04full computer that's uh fully
- 8:12:06independent and can execute instructions
- 8:12:09in comma uh sequentially and has the
- 8:12:12ability to do complex logic where it's
- 8:12:14not just instru uh not just executing
- 8:12:17instructions top down but it has the
- 8:12:19ability to jump to other addresses in
- 8:12:21memory i.e interrupt its own control
- 8:12:23flow. And not only can it jump anywhere
- 8:12:26in memory, it can also do conditional
- 8:12:28jumping, which means your programs that
- 8:12:30you can publish into this computer can
- 8:12:32have some some amount of logic that
- 8:12:34requires uh a forking control. So if do
- 8:12:38some operation, if the output of that
- 8:12:40operation was this, do something else or
- 8:12:43continue on the current path. Um, so
- 8:12:46this is pretty cool, but you're probably
- 8:12:48scratching your head a little bit where
- 8:12:50uh we walk through the load a command.
- 8:12:51And so we we looked at a timing diagram,
- 8:12:53but we we didn't actually see what the
- 8:12:55inputs and outputs would look like for
- 8:12:56this control ROM. And we also have a
- 8:12:58whole bunch of other instructions we
- 8:12:59haven't talked at at all. So to tie this
- 8:13:02together, what I'm actually going to do
- 8:13:04is we're going to go build out this ROM
- 8:13:07um and look at what the output should be
- 8:13:10for every possible input combination.
- 8:13:13And you've probably seen enough of me
- 8:13:15drawing to know that my handwriting is
- 8:13:17bad. So I'm going to switch to my
- 8:13:18computer and we're just going to do it
- 8:13:19on a Google Sheets and keep it simple.
- 8:13:21um in neat there. But um once we do
- 8:13:26that, we'll jump back to this one more
- 8:13:28time and we can reiterate how this all
- 8:13:30sums together. But this is pretty
- 8:13:32powerful. Um we are now like I think
- 8:13:35just like shy north of eight hours of
- 8:13:38this video and if you did some
- 8:13:40handwaving or if you somehow understand
- 8:13:42how you could set up the control
- 8:13:43entirely by yourself, you know how a
- 8:13:46computer works. Now this is actually it.
- 8:13:48This is the true fundamentals.
- 8:13:49Obviously, this is a toy computer, but
- 8:13:51this is a fully functioning independent
- 8:13:53computer. Uh, and that's pretty
- 8:13:55powerful, but we're not quite done yet
- 8:13:57because I haven't explained how this
- 8:13:58control ROM works. So, what we're going
- 8:14:00to do next, uh, I said we'll swap to my
- 8:14:02computer. We'll build out what the
- 8:14:03inputs and outputs for this ROM should
- 8:14:05look like, and then, um, we'll come back
- 8:14:08here, tie it all together, and then
- 8:14:11we'll talk about how we go from like
- 8:14:12this to an actual more modern computer.
- 8:14:14Okay. So what I've gone ahead and done
- 8:14:17is constructed a table that shows what
- 8:14:20our hypothetical RAM would look like.
- 8:14:23And so let me walk through the structure
- 8:14:25here. So first um our inputs are going
- 8:14:30to be uh this column through this column
- 8:14:35and then our outputs are going to be
- 8:14:36this column these columns. So remember
- 8:14:39our input we had the first op code which
- 8:14:42was the leftmost four bits of the um
- 8:14:48instruction register that tells us which
- 8:14:50argument we're currently executing or
- 8:14:52should be executing. Then we have the
- 8:14:54step number. We had that special counter
- 8:14:57that was uh specifically for the control
- 8:15:00that we just added in last minute that
- 8:15:02counts zero and then up to uh it counts
- 8:15:05up to four in binary or realistically
- 8:15:09five um
- 8:15:13sorry yeah five different operations
- 8:15:14zero through four and then that's here.
- 8:15:18Then we also had uh the zero flag and
- 8:15:20the carry flag for our two conditional
- 8:15:24jump instructions where we need to see
- 8:15:25that. So these are our inputs. Recall
- 8:15:28this is still binary. It's a ROM. So all
- 8:15:31of our inputs are going to be zeros and
- 8:15:32ones as will all of our outputs.
- 8:15:36Then our outputs were all the uh control
- 8:15:39lines that we had highlighted yellow in
- 8:15:40our original diagram. And uh we'll walk
- 8:15:44through this again real quick. So I can
- 8:15:45make this a little bigger for now. Um,
- 8:15:48I've uh added like acronyms here just
- 8:15:51because it'll be easier to say rather
- 8:15:53than having to specify, you know, memory
- 8:15:55address register in, you know, MI is
- 8:15:57probably easier to say once we once we
- 8:16:00work through these because these will
- 8:16:01get a bit repetitive. But HLT is halt.
- 8:16:04Remember, this stops the clock. MI
- 8:16:06stands for latch a value from the bus
- 8:16:08into the memory address register. That's
- 8:16:10a four-bit register. recall cuz all of
- 8:16:12our instructions and arguments are or so
- 8:16:15all of our RAM addresses and arguments
- 8:16:18all of our addresses are just four bits.
- 8:16:21RA stands for RAM in reads whatever
- 8:16:24value is on the bus into RAM at whatever
- 8:16:28value address is denoted in the memory
- 8:16:30address register. RAM out, it'll say
- 8:16:33whatever the uh memory address register
- 8:16:35is, that's an address. Look up that
- 8:16:38value in RAM and write it out onto the
- 8:16:39bus. Instruction register out IO. Take
- 8:16:43the value that is in the instruction
- 8:16:45register and put it onto the bus. I I is
- 8:16:48instruction register in. So take
- 8:16:50whatever value is on the bus and read it
- 8:16:52into the instruction register. 8 bit
- 8:16:54register. By the way, our arguments, our
- 8:16:56op codes are four bits and our arguments
- 8:16:58are four bits. But the register itself
- 8:16:59is eight bits because an instruction has
- 8:17:01an op code and may be an argument. So 4
- 8:17:03plus 4 means we need at least eight bits
- 8:17:05to represent a maximally utilized
- 8:17:08instruction.
- 8:17:09AI stands for read a 8 bit value from
- 8:17:13the bus into the A register. AO says A
- 8:17:17out. It say put whatever 8 bit value is
- 8:17:20in the A register out onto the bus.
- 8:17:23EO um stands for ALU out. I actually am
- 8:17:28not sure why it is EO. Um, I think, you
- 8:17:31know, we already have AO used, so uh I
- 8:17:35think they they could have found a
- 8:17:36better acronym. This was the way I was
- 8:17:37taught, so I'll stick with it just
- 8:17:39because my mind is so wired to say EO
- 8:17:42that if I tried to change that letter,
- 8:17:44I'd probably accidentally still say EO,
- 8:17:46and that would confuse you. Um, SU is
- 8:17:50subtract. This is the line on the ALU
- 8:17:52that dictates if the output is either
- 8:17:54going to be register A plus register B
- 8:17:57or if it's register A reg minus register
- 8:17:59B. Um BI stands for B in read whatever 8
- 8:18:05bit value is onto the B on the bus into
- 8:18:07the B register.
- 8:18:10Oi stands for output register in. So
- 8:18:14whatever value is in the output register
- 8:18:17or sorry whatever value is on the bus
- 8:18:19read it into the output register. Then
- 8:18:22CE this stands for counter enable which
- 8:18:26is synonymous to incrementing the
- 8:18:27program counter. So it'll add one to
- 8:18:30whatever values in the program counter
- 8:18:32and because of overflow we talked about
- 8:18:33this earlier the program counter is a
- 8:18:354-bit register. So the highest value we
- 8:18:37get to is 1111. And because of what we
- 8:18:40discussed earlier, when you call program
- 8:18:42counter enable at that maximal value, it
- 8:18:45doesn't crash the computer or anything
- 8:18:46because of overflow, it'll actually
- 8:18:48reset it to 000000. Which means if
- 8:18:52somehow you have a a program that spans
- 8:18:54your entire memory, when you get to the
- 8:18:56end of it, then it'll actually
- 8:18:58effectively restart it by going back to
- 8:19:00address zero and starting again from the
- 8:19:02top. Um, which you know, if you don't
- 8:19:05have a halt instruction, that is what
- 8:19:07will happen. You should probably end for
- 8:19:09correctness your programs with a halt
- 8:19:11instruction. But, you know, I'm not here
- 8:19:13to tell you what to do and we haven't
- 8:19:15made any programs yet. We'll we'll talk
- 8:19:16about that a little bit too. CO stands
- 8:19:19for program counter out. So, this takes
- 8:19:21whatever uh four bit value in the
- 8:19:23program counter and uh writes it onto
- 8:19:26the bus.
- 8:19:28J stands for jump. that takes uh
- 8:19:31whatever uh four-bit value, the
- 8:19:33rightmost four-bit value uh four-bit
- 8:19:36values plural, sorry, uh reads those in
- 8:19:40and that's useful for jump instructions.
- 8:19:42As I'm actually looking at the diagram I
- 8:19:44drew, I realized my diagram makes it
- 8:19:46appear as though it's reading eight bits
- 8:19:47from the bus. That's a uh incorrect
- 8:19:50statement on my part. I apologize. That
- 8:19:51should be four bits. And last but not
- 8:19:54least is FI which is the flags register
- 8:19:57that we discussed that looks at
- 8:19:59continually [snorts]
- 8:20:00uh looks at the value of the output of
- 8:20:03the ALOU and and determines if the
- 8:20:05output is either carried overflowed or
- 8:20:08if that value is equal to zero and then
- 8:20:10whenever we do an ALU operation we need
- 8:20:11to pulse that to latch the value in.
- 8:20:14That was a mouthful and that's very
- 8:20:15similar to what we discussed. Um, and so
- 8:20:19basically now what we're going to do is,
- 8:20:24uh, implement all of our instructions
- 8:20:26and we're going to start with load A. So
- 8:20:29from the table we originally had, we
- 8:20:31said load A's op code was 00001.
- 8:20:34And so if I look at the inputs,
- 8:20:37001
- 8:20:39um, and you might be wondering, well,
- 8:20:41hey, hey, what's up with, you know, all
- 8:20:43the outputs up until there? So basically
- 8:20:46what's interesting here is we just know
- 8:20:48that those are never going to be hit
- 8:20:51because assuming the user puts in a
- 8:20:53correct program there's no instruction
- 8:20:55we define that has the op code 000000.
- 8:20:59So conceptually that should never end up
- 8:21:01in the instruction register itself. But
- 8:21:04uh we discussed a property of the ROM
- 8:21:06and that it's for every input
- 8:21:08combination there must be a
- 8:21:09deterministic output. Uh and it turns
- 8:21:12out we can still guarantee that. It just
- 8:21:14doesn't matter what it is because we
- 8:21:15know that like the input will never be
- 8:21:17this because this is a malformed op
- 8:21:19code. Uh the output never really matters
- 8:21:22because it it conceptually should not be
- 8:21:23reachable. You know, it'd be user error
- 8:21:25if the user put in an instruction into
- 8:21:29RAM uh and had the op code 000000.
- 8:21:33That'd be a bad instruction. But if that
- 8:21:35happens, it doesn't really matter what
- 8:21:37happens because we don't support that
- 8:21:38use case. So pretty much the output for
- 8:21:41all of these lines does not matter. Um,
- 8:21:43and what we'll default to is that if a
- 8:21:46line is not set in this diagram, uh,
- 8:21:48there's going to be a lot more zeros
- 8:21:49than ones at times, most things will not
- 8:21:52be set. So, I'm just going to say if I
- 8:21:54leave something blank, it means zero for
- 8:21:56these first uh, entries. Actually, you
- 8:21:59could actually totally get by
- 8:22:02and uh, press in uh, ones if you wanted
- 8:22:05to as well. The only thing you just want
- 8:22:07to be a little careful of is if you you
- 8:22:08don't want to trigger this halt line
- 8:22:10because we saw earlier that if you did
- 8:22:13pulse that then the program would stop.
- 8:22:15Um it wouldn't matter cuz again we don't
- 8:22:18support the user putting in this op code
- 8:22:20but you know if we wanted to be a little
- 8:22:21bit defensive. This is not the uh the
- 8:22:24worst thing to do here. So um I'm not
- 8:22:27going to like read this out. Uh we just
- 8:22:29kind of know that like hey these like
- 8:22:31these addresses like this is not
- 8:22:33reachable. Um so I you know I could
- 8:22:36denote that here but most a lot of
- 8:22:38things you'll see are unreachable. Um
- 8:22:43are you know there's we don't define all
- 8:22:45of our op codes as we discussed earlier.
- 8:22:47You know we have two to the four I think
- 8:22:49that's 16 possible op codes represented
- 8:22:52in four bits and we just do not have 16
- 8:22:54instructions and that's totally fine. So
- 8:22:56a good amount of our space here is
- 8:22:57actually going to be unreachable um with
- 8:23:00a technical asterisk that you could
- 8:23:02reach it if you just put in a incorrect
- 8:23:03program or incorrect instruction into
- 8:23:06RAM. But um we start with
- 8:23:11uh this part is reachable. Sorry, that's
- 8:23:13not true. We start with uh op code 00001
- 8:23:18which was this load a. And uh we'll also
- 8:23:21assume that our our flags uh we're just
- 8:23:24going to ignore those for now because we
- 8:23:25know it doesn't matter for this
- 8:23:26instruction. So it turns out as we
- 8:23:30discussed uh the very first thing that
- 8:23:32happened for load A is we actually don't
- 8:23:35even know we're executing the load A
- 8:23:37yet. So,
- 8:23:40um, what we actually need to do is get,
- 8:23:44uh, because it's the first step of the
- 8:23:46instruction, that's how we start, our
- 8:23:48step counter starts at zero, and that's
- 8:23:50how we know we're executing a new
- 8:23:52instruction. And so, we don't even know
- 8:23:54what we're executing yet. So, basically,
- 8:23:56we need to take the instruction
- 8:23:59um, we need to figure out what the
- 8:24:00instruction is and get it into the
- 8:24:01instruction register. And the way we do
- 8:24:03that is we start with the program
- 8:24:04counter because the program counter has
- 8:24:06the address of the instruction that
- 8:24:07we're about to execute. So what we
- 8:24:09actually do to start our instruction is
- 8:24:12put the program counter value onto the
- 8:24:14bus and then at the same time read that
- 8:24:17into the memory address register.
- 8:24:20And so then this is what happens on our
- 8:24:22first clock cycle. The clock will go
- 8:24:24from low to high. Uh we set these values
- 8:24:28um you know this is our output. So our
- 8:24:30steps our step counter our little
- 8:24:32incrementer circuit that connects just
- 8:24:34to the control will start at zero. And
- 8:24:37so we know that's the start of an
- 8:24:38instruction. So our a our uh control
- 8:24:41should just output these two lines
- 8:24:43because this is what we need to do to
- 8:24:44get the value from the program counter
- 8:24:46into the memory address register so we
- 8:24:48can look it up in RAM. And then the
- 8:24:50clock is low this entire time. The clock
- 8:24:53will then go from 0 to one which will
- 8:24:55latch in the value to the memory address
- 8:24:57register. And then because our our
- 8:24:59little incrementer is connected to the
- 8:25:02clock, it'll have the side effect of
- 8:25:03automat automatically incrementing it,
- 8:25:05which means we're we end up at the row
- 8:25:07below here because our op code's not
- 8:25:10changing and we're ignoring these flags
- 8:25:11for now. They're not changing. Um, and
- 8:25:14so that's pretty neat. And so then we're
- 8:25:16looking, okay, when this we know the
- 8:25:18first step was getting the address from
- 8:25:20the program counter into their memory
- 8:25:22address register. Now that we've done
- 8:25:24that, uh, we want to take the output
- 8:25:26from RAM because that's the actual
- 8:25:28instruction we want to execute and then
- 8:25:30put it into the instruction register. So
- 8:25:32what I do is RAM out
- 8:25:36and instruction register in.
- 8:25:40And um, we're going to do one other
- 8:25:43thing here. We're just going to choose.
- 8:25:45We talked about this earlier. At some
- 8:25:47step in each instruction, we need to
- 8:25:50increment our program counter so that we
- 8:25:52get to the next instruction. We're going
- 8:25:54to do that right here.
- 8:25:56Um, we're going to choose the second
- 8:25:58step. It could have happened at any of
- 8:26:00the next steps after this before the
- 8:26:01counter over here resets to zero. I'd
- 8:26:04rather just get it done early so we
- 8:26:06don't forget about it. Um, and then so
- 8:26:09what what effectively happens is the
- 8:26:11clock will pulse. it'll go from low to
- 8:26:13high and that'll take the value that's
- 8:26:15on on the bus which is the instruction
- 8:26:17we actually want to execute and it's
- 8:26:19going to latch it into the instruction
- 8:26:21register and then also as a byproduct of
- 8:26:23what we defined uh we've incremented the
- 8:26:25program counter but uh that that's a
- 8:26:27different thing than this this is this
- 8:26:28is a step counter used to used as a
- 8:26:31counter just for control the program
- 8:26:33counter is actually keeping track of
- 8:26:35what instruction the computer should
- 8:26:36execute next um but that has no side
- 8:26:39effect because we actually don't look at
- 8:26:41the program counter until we get to the
- 8:26:43next instruction. It's useless for us
- 8:26:45for now, for this instruction too
- 8:26:47specifically. That's not true for some
- 8:26:49of the jump instructions uh that
- 8:26:51actually need to modify the program
- 8:26:52counter, but we will get there. So now
- 8:26:56that we've loaded the value into load A,
- 8:26:59we've loaded load A into the instruction
- 8:27:01register. Sorry. Now, uh the control
- 8:27:04unit would get this as its input. Um
- 8:27:07this would be the op code. And so it it
- 8:27:09finally know after these first two clock
- 8:27:11cycles, hey, this is the the op code
- 8:27:14line is actually saying
- 8:27:16um what instruction we're going to be
- 8:27:18executing. And that's pretty cool. Um it
- 8:27:23turns out as we did kind of hinted at,
- 8:27:25it's pretty explicit now though that for
- 8:27:27the first two steps of every
- 8:27:29instruction, the op code is actually not
- 8:27:32going to be matter. It's not going to
- 8:27:33matter. We know that the op code is
- 8:27:36because it's looking at the instruction
- 8:27:37register. we haven't put the right
- 8:27:39instruction into the instruction
- 8:27:40register. So the op code is nonsense. So
- 8:27:42it actually it can ignore it and it will
- 8:27:44for the first uh every time you know our
- 8:27:47step number is 0000 or 001. We know that
- 8:27:50for every instruction we need to do the
- 8:27:52lookup of the program counter value in
- 8:27:54RAM and then get that into the
- 8:27:56instruction register. But once that
- 8:27:58happens, we get to step 010. That's
- 8:28:01binary 2. Um and now we have the op code
- 8:28:06here. And so now the control knows we're
- 8:28:08executing a load A. And so what did load
- 8:28:11A need to do? It needed to take the
- 8:28:14argument of the instruction
- 8:28:18um and look that up in RAM and then
- 8:28:21write that into register A. So we
- 8:28:23discussed this earlier. So I'm going to
- 8:28:25go you know a little quickly here. But
- 8:28:27you know we need to take our our
- 8:28:29instruction uh is eight bits. The left
- 8:28:31four bits are this 00001 that denote the
- 8:28:33load A. The right four bits are actually
- 8:28:36the address that we of RAM that we want
- 8:28:38to lo whose value we want to load into
- 8:28:40register A. So what we do is we want to
- 8:28:42put the instruction register out onto
- 8:28:45the bus.
- 8:28:51And then
- 8:28:56we also want to read that value into the
- 8:29:00memory address register.
- 8:29:06And so then we the the clock will pulse
- 8:29:08from low to high. The clock's low here
- 8:29:10goes to high. Um and it'll latch that
- 8:29:13value from the a uh from the the
- 8:29:15rightmost 4 bit to the instruction
- 8:29:17register into the memory address
- 8:29:18register which is great. Um
- 8:29:23because uh we've you know kind of looked
- 8:29:26up that value now. Um oops sorry I have
- 8:29:30a typo here. This should be instruction
- 8:29:32register out. We take whatever values in
- 8:29:34the instruction register, the right four
- 8:29:35bits, put them out and read that into
- 8:29:37the memory address register. And then
- 8:29:40the very last thing we need to do is
- 8:29:43take whatever value we get from RAM. So
- 8:29:45put RAM's value back onto the bus and
- 8:29:48then read it into the A register. Um,
- 8:29:51and once we've done this, the clock
- 8:29:53pulses, we then looked at that value
- 8:29:54from RAM and stored it in the A
- 8:29:55register. And we've actually completed
- 8:29:58the load A. So this is the original
- 8:29:59timing diagram. we drew by hand and we
- 8:30:02were originally just punching those
- 8:30:03values by hand saying hey you know you
- 8:30:05need to put like a in to high at the
- 8:30:07same time you put RAM out to high and
- 8:30:09then wait for a rising clock edge so the
- 8:30:11value gets latched in because of the way
- 8:30:13we've defined this in a in the uh ROM
- 8:30:16readon memory we don't have to do that
- 8:30:18anymore the computer will do it for us
- 8:30:20because we have now programmed you know
- 8:30:22hey when you know you're executing a
- 8:30:23load a and you're on the third step then
- 8:30:26this is what you need to do and then
- 8:30:28when you're on the fourth step this is
- 8:30:29what you need to do. Um, and it turns
- 8:30:32out for load A, we got it done in four
- 8:30:34steps and we said all of our
- 8:30:36instructions take five steps. So for the
- 8:30:38very last step, uh, one Z on the program
- 8:30:42counter, um, on the step counter, uh, we
- 8:30:45don't do anything. We actually just zero
- 8:30:47zero it out. Um,
- 8:30:49and then we also know uh that so that
- 8:30:53concludes our load a we've executed our
- 8:30:56first instruction here and we we
- 8:30:58specified the microode. You can see two
- 8:31:01things I want to talk about here. Um the
- 8:31:03first is we say first of four copies.
- 8:31:06You might be wondering well why is that
- 8:31:07true? you know we we discussed uh you
- 8:31:11know for this step for these two it
- 8:31:13doesn't matter for these these first
- 8:31:14instructions the opaque doesn't matter
- 8:31:16but we know hey for the first two steps
- 8:31:18the instructions will always be the same
- 8:31:19and then afterwards we actually resolve
- 8:31:21the instruction which is a load a and so
- 8:31:23we've done the the two the two clock
- 8:31:25cycles worth of work to go look up some
- 8:31:27value in RAM and get that into the A
- 8:31:29register uh so why do we need to do this
- 8:31:31four times and it turns out uh I told
- 8:31:34you to ignore the zero and carry flags
- 8:31:37uh and I part of me wanted to ignore
- 8:31:38them for the entire video, but I didn't
- 8:31:40think it'd be fair because it wouldn't
- 8:31:41explain how conditional logic worked.
- 8:31:43But
- 8:31:45um
- 8:31:48this logic, this load a instruction
- 8:31:52should be the same. We would want to
- 8:31:54take these same steps no matter what the
- 8:31:56value is in our flags register. But we
- 8:32:00actually don't know what the value in
- 8:32:01the flags register is. Maybe some
- 8:32:03operation happened uh some add or
- 8:32:05subtract happened before this load a and
- 8:32:08the carry flag is zero and the load flag
- 8:32:11is one. Um well those technically are
- 8:32:14input to the control logic. And so that
- 8:32:18actually means when when the let's say
- 8:32:20the zero flag is set to one, we aren't
- 8:32:23over here and we aren't here in our
- 8:32:25lookup address. We're somewhere way
- 8:32:26further down. um but it still would
- 8:32:29resolve to a load a um and similarly if
- 8:32:31if the carry flag was one you know it
- 8:32:34wouldn't change what we do here cuz we
- 8:32:36don't care about it but because ROM
- 8:32:39doesn't really know that ROM just like a
- 8:32:40naive lookup table it doesn't we have to
- 8:32:44program that four times effectively
- 8:32:45because hey there's two there's two one
- 8:32:48bit flags so your combinations of of of
- 8:32:52the two uh zero flag and carry flag is
- 8:32:54either 001
- 8:32:56one 1 zero or 1 one. So for each of
- 8:33:00these four combinations
- 8:33:03of the flags inputs to the ROM, we'd
- 8:33:05want the same out output because the
- 8:33:07flags just don't matter for load A. So
- 8:33:11it turns out we have four four copies of
- 8:33:13load A. Um and so if I if I jumped to
- 8:33:17let me first off replace these back with
- 8:33:19zero.
- 8:33:22If uh and if anyone ever watches this,
- 8:33:24I'm happy to
- 8:33:27uh include this sheet. I'm fairly
- 8:33:29confident no one will ever watch this,
- 8:33:31but especially not this far in, but who
- 8:33:34knows? Hopefully, I'll be wrong. Um
- 8:33:38if I actually go where were to jump uh
- 8:33:41to the row in this table, uh it it
- 8:33:46you can see that it exists. way further
- 8:33:50down here would be if the zero flag is
- 8:33:53zero and the carry flag is one then this
- 8:33:57would be our same instruction obviously
- 8:33:58the op code doesn't matter for the first
- 8:33:59two clock cycles but then these three
- 8:34:01would represent the execution of load a
- 8:34:05uh if that if that flag was set so it
- 8:34:08turns out we actually need to specify
- 8:34:10that this microode four times here um so
- 8:34:14you know what I've defined here
- 8:34:19will need to get defined here. And you
- 8:34:22can literally just paste it. And then
- 8:34:24here's the the third time where zero
- 8:34:27flag is one and carry flag is zero.
- 8:34:32And then
- 8:34:34here's the very last one where both the
- 8:34:36zero flag and the carry flag are one. So
- 8:34:39that's why uh yeah, that's where this
- 8:34:41this first of four copies come from. And
- 8:34:43then over here we'll just take some
- 8:34:45notes and then we'll recap we'll recap
- 8:34:47what we did here. So the very first
- 8:34:49thing we did is we said the program
- 8:34:51counter has the instru the address of
- 8:34:54the instruction we're trying to execute.
- 8:34:55So we need to go look up that value in
- 8:34:58RAM. So the value in the program counter
- 8:35:00is not the instruction itself. It's the
- 8:35:02address of the instruction. So what we
- 8:35:03want to do is we want to get the program
- 8:35:05counter to the memory address register
- 8:35:07in the first step. Then what we do is we
- 8:35:10have that value. It's looked up in RAM.
- 8:35:12we take the um the RAM and put it into
- 8:35:17the instruction register. Then we also
- 8:35:20incremented the program counter. So
- 8:35:22program counter equals program counter +
- 8:35:24one. Then the third thing we did was now
- 8:35:27that we know that we're executing a load
- 8:35:29A, we put the uh address component
- 8:35:33of the um of the instruction onto RAM
- 8:35:39onto uh onto the bus and read it into
- 8:35:43the memory address register and then
- 8:35:45that looks up the actual uh argument in
- 8:35:48memory. And so the last thing we do is
- 8:35:50we say RAM the output of RAM goes into
- 8:35:54uh register A and then we said we only
- 8:35:56so that after that fourth clock cycle we
- 8:35:59execute our instruction. Uh so we do
- 8:36:01nothing um no op it's a wasted cycle for
- 8:36:04the fifth one. Uh we just say you know
- 8:36:06every clock cycle takes five
- 8:36:08instructions. So that's the first thing
- 8:36:09of discourse I want to talk about. The
- 8:36:11second thing is our next op code is 00 1
- 8:36:170
- 8:36:18but there's actually because our input
- 8:36:21uh just counts sequentially. This is
- 8:36:22just counting as if it as though it was
- 8:36:24binary. Um 0 0 1 0 doesn't start to
- 8:36:27here. So we have
- 8:36:30three rows that uh are in between this
- 8:36:34the load a instruction and then our add
- 8:36:36instruction which comes next. Um, and it
- 8:36:41turns out those are also just
- 8:36:42unreachable. And here's why. We
- 8:36:45discussed our step counter that counted
- 8:36:47from zero up until four and then reset.
- 8:36:50So, we know that based on our
- 8:36:52construction of the step counter, when
- 8:36:54it goes from 1 0 0, which is binary 4,
- 8:36:57and we increment it, uh, it'll it'll
- 8:36:59carry back over to zero, it'll reset to
- 8:37:010 0. If you were counting in regular
- 8:37:03binary, what you get next is not zero.
- 8:37:06you'd get 101 which is five because
- 8:37:08that's what comes after four. But we
- 8:37:10know that because of the way the counter
- 8:37:11is constructed uh that will never be
- 8:37:13possible. So these three addresses right
- 8:37:16here are not reachable. And so the same
- 8:37:18way we said that these over here are not
- 8:37:21reachable. So it doesn't matter what the
- 8:37:22output is of the ROM. The same goes for
- 8:37:25these addresses right here. And we can
- 8:37:27actually take uh this a little further
- 8:37:30and say that these are definitively not
- 8:37:31reachable because we know that
- 8:37:36um it's not possible for our step
- 8:37:38counter to reach five. As soon as it
- 8:37:40reaches four and it tries to increment,
- 8:37:42it'll roll back to zero based on our
- 8:37:44construction the circuit. And that's
- 8:37:46different than what we had up here. This
- 8:37:48is technically reachable if uh someone
- 8:37:50tries to interpret someone tries to
- 8:37:53execute an instruction with op code
- 8:37:55000000 because we can't stop what they
- 8:37:57put in the RAM. It just wouldn't do
- 8:37:59anything. So that's the load a
- 8:38:01instruction. So the next instruction is
- 8:38:04add. Recall that add um takes has an
- 8:38:08argument. The argument is an address in
- 8:38:10memory. And what it does is it'll say
- 8:38:12register A equals register A plus
- 8:38:16whatever is in RAM at the uh address
- 8:38:19specified by the argument. So um the
- 8:38:22first thing we need to do though we
- 8:38:24don't know it's our first clock cycle.
- 8:38:26We don't know that we're executing an ad
- 8:38:28yet or the computer doesn't know that.
- 8:38:30So it actually needs to take whatever's
- 8:38:31in the program counter look that up as
- 8:38:33the instruction and get that into the
- 8:38:35instruction register and then the input
- 8:38:37to the uh the readonly memory would
- 8:38:39actually you know or the readon memory
- 8:38:41that is control would be able to see the
- 8:38:44op code over here and derive semantic
- 8:38:47interpretation of the instruction that
- 8:38:50the user i.e. uh I guess the machine uh
- 8:38:53wants to execute. So the the first two
- 8:38:56steps are actually identical uh between
- 8:38:58what we did in load A and what we're
- 8:39:00going to do in add. So the first thing
- 8:39:02we need to do is get the address that is
- 8:39:05stored in the program counter out onto
- 8:39:06the bus and read that into the memory
- 8:39:08address register. So we'll read into the
- 8:39:10memory address register and then we will
- 8:39:12also put the uh program counter out.
- 8:39:16[snorts]
- 8:39:18And then now that we have the uh address
- 8:39:22of the instruction we're trying to
- 8:39:23execute in the memory address register,
- 8:39:25that value is looked up in RAM. Um
- 8:39:27because that's RAM's always just
- 8:39:28observing what's in that register and
- 8:39:30putting it out. So we actually want to
- 8:39:31put that value onto the bus RAM out and
- 8:39:34then get it into the instruction
- 8:39:36register. Instruction register in. And
- 8:39:40now uh what we've done is we've
- 8:39:42effectively taken the uh we've
- 8:39:44effectively taken the found instruction
- 8:39:47we're trying to execute and gotten it
- 8:39:48into the instruction register. So now
- 8:39:51the actual op code that our um control
- 8:39:54sees is 00 1 0 because that is the
- 8:39:57operation code. Uh that's how we denoted
- 8:39:59add in the table we constructed earlier.
- 8:40:02Again that was our decision here. Um and
- 8:40:05so now that we've fetched the
- 8:40:07instruction, we actually need to execute
- 8:40:09it. So recall that add um I can add this
- 8:40:13over here. You know, add
- 8:40:16is saying register a
- 8:40:20equals register a plus whatever is in
- 8:40:23RAM at uh the argument.
- 8:40:32So what we need to do is take the
- 8:40:33argument that's in the instruction
- 8:40:35register uh and look it up in RAM and
- 8:40:38then we can put that into the ALOU. So
- 8:40:40what we need to do is write the
- 8:40:41instruction register out onto the bus
- 8:40:44and feed that back into the memory
- 8:40:46address register. Uh recall that when we
- 8:40:48put the instruction register out onto
- 8:40:50the bus, it only puts out the rightmost
- 8:40:52four bits, the argument. Uh and then
- 8:40:54RAM, the memory address register is four
- 8:40:57bits. So there's a perfect match there.
- 8:40:59Now we've have the uh RAM that's looked
- 8:41:01up the value. So let's put that out onto
- 8:41:03the bus for our next in our next clock
- 8:41:05cycle. And uh because our operation says
- 8:41:10register A equals register A plus RAM
- 8:41:12arg uh our two operants of the ALU are
- 8:41:14register A and register B. So we kind of
- 8:41:17just want to put the value in register B
- 8:41:19because we're adding something to
- 8:41:20register A. So why would we change
- 8:41:22what's in register A? um you know that's
- 8:41:25our first operand is already correctly
- 8:41:27wired in to the ALOU. So uh we will
- 8:41:31write that value from that we're putting
- 8:41:34out from RAM uh into the B register
- 8:41:37and then uh now that we've actually
- 8:41:40moved the argument into the B register
- 8:41:43we have our correct arguments to the ALU
- 8:41:46in register A and B. So the output is of
- 8:41:49the alou after through this clock cycle
- 8:41:51is equal to this uh register a plus ram
- 8:41:55of arg this right hand side of this
- 8:41:57expression. So what we need to do is
- 8:41:59take the output of the alou and write it
- 8:42:01back into register a and so we can do
- 8:42:04that with um alou out this eo signal. Uh
- 8:42:10take the output of the alou um and then
- 8:42:13we want to read it into the a register.
- 8:42:16So it will read a in. And there's
- 8:42:18something else that we uh need to do
- 8:42:20here. Um not to execute this
- 8:42:23instruction. This technically would
- 8:42:24correctly execute this instruction, but
- 8:42:28um we also need to update our flag
- 8:42:31register because we need to know our our
- 8:42:34guarantee for our jump zero and jump
- 8:42:36carry instructions is it's looking uh
- 8:42:39it's making a decision based on the last
- 8:42:42ALU operation we performed. So now we're
- 8:42:44performing an operation. We don't know
- 8:42:46when a jump a conditional jump
- 8:42:47expression if it ever exists will happen
- 8:42:51next in the instruction. We don't know
- 8:42:52you know which of the following
- 8:42:53instructions will actually look at this
- 8:42:55flag but we play it safe just by always
- 8:42:57updating the flags. And we discussed the
- 8:42:59circuits for checking those flags. And
- 8:43:01so those are always looking at the
- 8:43:02output of the ALOU and always feeding in
- 8:43:04as the input to this flags register. So
- 8:43:06all we actually need to do is pulse
- 8:43:08flags in um to get that there. So uh
- 8:43:13that implements our add instruction. But
- 8:43:16we've actually forgotten one thing and
- 8:43:18that after we execute this instruction
- 8:43:21uh the way it's it's executed right here
- 8:43:24the control logic uh the program sorry
- 8:43:27the computer itself would actually
- 8:43:28execute the same instruction again
- 8:43:30afterwards and it keep getting stuck on
- 8:43:32this instruction because we have not
- 8:43:33incremented our program counter. And so
- 8:43:36we could do that at any of these clock
- 8:43:38cycles. Uh any of them work. uh we
- 8:43:41always are just going to do it early so
- 8:43:43we don't forget like I I just did right
- 8:43:45here. Um so we can walk through and type
- 8:43:48out what we did. So the very first thing
- 8:43:50we did was we took the value in the
- 8:43:51program counter and got it the memory
- 8:43:53address register. Then we took whatever
- 8:43:55was in RAM at that address and put it in
- 8:43:58the instruction register and then we
- 8:43:59also incremented the program counter.
- 8:44:03Afterwards we took the uh address of the
- 8:44:06instruction register
- 8:44:08to the memory address um register. So we
- 8:44:11wanted to look up the argument in RAM
- 8:44:13and then we put RAM to register B
- 8:44:17and then we actually performed um you
- 8:44:20know ALU to register A
- 8:44:24and then also update flags.
- 8:44:29And so that uh completes our our ad
- 8:44:32instruction. There's a few things I want
- 8:44:33to talk about before we move on. So
- 8:44:35first is this ad instruction actually
- 8:44:38used all five clock cycles meaningly.
- 8:44:42Our load a recall the last one we were
- 8:44:44able to do in four clock cycles. So that
- 8:44:45fifth clock cycle went wasted. Here we
- 8:44:48were actually able to get it done in
- 8:44:49five clock cycles. Um and it turns out
- 8:44:51every instruction we created in our uh
- 8:44:54instruction set earlier
- 8:44:57um
- 8:44:59can be executed in five or fewer
- 8:45:00instructions. This is the lengthiest of
- 8:45:02them. So we just forced like hey because
- 8:45:05you know all these instructions are the
- 8:45:08longest instruction uses five clock
- 8:45:09cycles. We just designed this such that
- 8:45:12uh every instruction will take five
- 8:45:14clock cycles. And you could imagine
- 8:45:16that's not super efficient. We don't
- 8:45:18want to waste clock cycles uh especially
- 8:45:20as we're trying to speed up our
- 8:45:21computer. So we talked about making the
- 8:45:24computer run faster by making our clock
- 8:45:26just move faster. But then there is some
- 8:45:27limitation there because we have to you
- 8:45:29know wait for logic gates to settle
- 8:45:30whenever we change inputs to them. Um so
- 8:45:33the other natural thing to do is okay
- 8:45:35maybe like make instructions use fewer
- 8:45:37clock cycles. There's there's two things
- 8:45:39to make the computer faster. You make
- 8:45:40the clock run faster or you make the
- 8:45:42instructions more efficient in
- 8:45:44themselves. Um so we could have designed
- 8:45:46this computer uh to you know as soon as
- 8:45:49that load a instruction was done to move
- 8:45:50on to the next instruction.
- 8:45:53We just for sake of simplicity uh aren't
- 8:45:55going to do that. Um, it's actually not
- 8:45:57that trivial. All you need to have the
- 8:45:58instruction do is just move on to the
- 8:46:01next instruction address, like reset
- 8:46:03that uh the the controls uh internal
- 8:46:07step counter, and you know, that kind of
- 8:46:10have the effect. But yeah, we're not
- 8:46:11going to worry about that for now. Um,
- 8:46:13the second thing I want to talk about
- 8:46:14before we move on to the next
- 8:46:16instruction is the fact that these two
- 8:46:18instructions uh that we've done, load A
- 8:46:20and AD, look pretty similar. In
- 8:46:23particular, uh we can actually see that
- 8:46:25the first two steps are identical. Um
- 8:46:28and that's because we have to figure out
- 8:46:31what instruction we're executing before
- 8:46:33we can actually make the you know
- 8:46:35personalized or conditional logic of
- 8:46:38executing that instruction. Um it turns
- 8:46:41out this will be true for every
- 8:46:43instruction. the first two clock cycles
- 8:46:45will always be the same
- 8:46:48um to figure out what the instruction
- 8:46:49actually is before we can go about
- 8:46:51executing it. And this is called a fetch
- 8:46:54decode execute cycle. So we kind of see
- 8:46:57that like the first two clock cycles are
- 8:47:00used to fetch the instruction and then
- 8:47:04the decoding would be actually deriving
- 8:47:06the uh like you know we have the
- 8:47:09instruction what is it actually trying
- 8:47:10to do and then executing it would
- 8:47:12actually just be executing it. We don't
- 8:47:14really have a decode process here
- 8:47:15because the way we've set up our control
- 8:47:17logic it's it's just kind of
- 8:47:19deterministically responding to the
- 8:47:20input. So decoding it is effectively
- 8:47:22just looking it up in the ROM, but you
- 8:47:25don't really see that on the timing
- 8:47:26sequence because it happens so quickly.
- 8:47:28Um, so you kind of see like the fetching
- 8:47:30is clear and then the executing is clear
- 8:47:33and then the decoding is kind of
- 8:47:34inherently implicit given to us for free
- 8:47:37because we're using a readonly memory.
- 8:47:39The decoding is actually taking whatever
- 8:47:42uh instruction or inputs we have to the
- 8:47:44control logic and looking at the
- 8:47:46corresponding outputs which is just a uh
- 8:47:48readon memory read operation. Yeah. So
- 8:47:51our decoding our fetching involves
- 8:47:53actually moving data between registers.
- 8:47:55Our decoding is just a lookup in ROM and
- 8:47:57then our execution is actually the
- 8:47:59interesting part where we perform the
- 8:48:00operations. Um and the third interesting
- 8:48:04thing uh before we move on to the next
- 8:48:05instruction is um I've also said for our
- 8:48:10ad instruction this is the first of four
- 8:48:11copies and that is because uh our zero
- 8:48:15and carry flags
- 8:48:17don't change what we do for our ad
- 8:48:19operation but we do need a handle that
- 8:48:21those values might be different. So
- 8:48:23especially after this uh like let's
- 8:48:25suppose we do this add operation um and
- 8:48:28then there's a load a afterwards
- 8:48:30because we set the flags register in
- 8:48:32this ad operation uh it doesn't affect a
- 8:48:35load a operation the load a operation
- 8:48:36doesn't care what's in those flags but
- 8:48:38it does mean that the input to the ROM
- 8:48:40can change uh and so that's why we had
- 8:48:42the we talked about copying this load a
- 8:48:44four times uh we actually have to do the
- 8:48:46same thing for add um and we'll see that
- 8:48:49that also is true for most other
- 8:48:50instructions. So yeah, that's uh that's
- 8:48:54our add instruction. Let's move on to
- 8:48:56the subtract instruction which is very
- 8:48:59similar to the add instruction with the
- 8:49:01difference being that you know instead
- 8:49:04of register A equals
- 8:49:07instead of register A
- 8:49:11equaling register A
- 8:49:14plus RAM of arg ram at the address
- 8:49:17specified by the argument. Uh it's the
- 8:49:19exact opposite. We just subtract. And so
- 8:49:21you can kind of imagine before we even
- 8:49:23spill this out that the uh the
- 8:49:26instructions, the microode that we're
- 8:49:28putting out for of the ROM are going to
- 8:49:29be very similar to this ad with the only
- 8:49:32difference being that we're going to
- 8:49:33have to just uh set the ad subtract line
- 8:49:36in our ALOU. So I'm actually just going
- 8:49:40to copy over everything we've done.
- 8:49:47And all we have to do is make one very
- 8:49:49trivial choice change, sorry. Um,
- 8:49:54which is we want to set the subtract
- 8:49:57line
- 8:50:01right here. So basically everything
- 8:50:05stays the same
- 8:50:10and
- 8:50:12we are uh just telling the ALU because
- 8:50:15the ALU is always looking at the it's
- 8:50:17always just taking whatever the inputs
- 8:50:19are which are these values in the
- 8:50:21register and it's always just doing an
- 8:50:22add or subtract on them and that's
- 8:50:24always available on the output line. So
- 8:50:26when we put the output onto the bus and
- 8:50:28necessarily read it back into register
- 8:50:29A, uh, we can pretty much just get the
- 8:50:33output we want by flipping the add
- 8:50:34subtract line before we reinterpret the
- 8:50:36value of the ALOU. So because the ALOU
- 8:50:39is just always responding to the add or
- 8:50:40subtract line, we can just flip it. And
- 8:50:42there's no issue with timing here that
- 8:50:44the line is not really a register. So,
- 8:50:46it's safe for us to just uh flip the
- 8:50:49line and then read that value pretty
- 8:50:51quickly afterwards because it's always
- 8:50:53going to be, you know, it's not
- 8:50:56dependent on a clock cycle to like latch
- 8:50:58in that line. Like, we don't need to
- 8:50:59tell the ALU before we do an add or
- 8:51:01subtract, we're going to do an add or
- 8:51:02subtract. We can just tell it as it uh
- 8:51:05does the computation to consider
- 8:51:08whatever is on that line. Um,
- 8:51:13and yeah, everything else is exactly the
- 8:51:15same. Uh and then similar to what we
- 8:51:17described before, this is replicated
- 8:51:19four times in memory or sorry four times
- 8:51:22in this readon memory.
- 8:51:25Okay, let's hop on to the next
- 8:51:27instruction
- 8:51:29store a. So
- 8:51:32um this will take an argument and it'll
- 8:51:36basically say RAM at the argument should
- 8:51:39equal whatever is in register A. So
- 8:51:42basically we need to take whatever
- 8:51:43values in register A, get it on the bus
- 8:51:45and throw it into RAM. Um it lets us
- 8:51:47move data. We've talked about moving
- 8:51:49data from RAM into the ALOU. We are now
- 8:51:52going to talk about moving data from the
- 8:51:54ALOU into RAM. And because everything is
- 8:51:56connected to this this central bus unit,
- 8:51:58uh we have all the control signals uh
- 8:52:00available to implement that uh
- 8:52:02instruction with what we have defined
- 8:52:04here. So uh let's start. First, as
- 8:52:08usual, we don't know what we're
- 8:52:10executing. So, we need to look up the
- 8:52:11instruction uh based on the value that's
- 8:52:13in the program counter. So, we put the
- 8:52:16uh the address, we put the value from
- 8:52:19the program counter out onto the bus and
- 8:52:20read it into the memory address
- 8:52:21register.
- 8:52:25And then we take the uh output of RAM,
- 8:52:28read that into the instruction register.
- 8:52:30And then we also increment our program
- 8:52:32counter so that uh we will move on to
- 8:52:34the next instruction uh by the time that
- 8:52:36the our internal control uh step counter
- 8:52:40goes from four to zero or from five to
- 8:52:43back to zero.
- 8:52:47And now that we've uh that's our fetch
- 8:52:49process again that's the same for all
- 8:52:51three instructions we've implemented so
- 8:52:53far. Uh what we now need to do is take
- 8:52:56the argument of our instruction that's
- 8:52:59telling us what address we'd like to
- 8:53:01write the value into and get that into
- 8:53:03the memory address register. So I'll
- 8:53:05I'll read into the memory address
- 8:53:07register and what I'm reading is I'm
- 8:53:10putting the value uh of the instruction
- 8:53:12registers argument out onto the bus the
- 8:53:14right the right uh rightmost four bits
- 8:53:17sorry. And then this one's pretty simple
- 8:53:21because now that we've loaded the uh
- 8:53:22address into the memory address
- 8:53:24register, what we'll do is we put the a
- 8:53:26register a value onto the bus, read it
- 8:53:30into RAM,
- 8:53:32and that's quite literally all we have
- 8:53:34to do. And then we have a wasted clock
- 8:53:36cycle afterwards because we've we've uh
- 8:53:38we've already finished our instruction.
- 8:53:40So I'll copy over uh our explanations
- 8:53:44here. And then what we did here was
- 8:53:47address of IR to the memory instruction
- 8:53:50register. And then all we do here is uh
- 8:53:53register A's
- 8:53:55value
- 8:53:58reg a into RAM. And after that uh we
- 8:54:02finished our we finished implementing
- 8:54:04what we said the store a instruction
- 8:54:05would do. That's pretty straightforward.
- 8:54:08Um let's move on to our next instruction
- 8:54:11which is this load immediate. So recall
- 8:54:14uh that load immediate was the first
- 8:54:17instruction we saw where the argument
- 8:54:19was not an address in RAM an address in
- 8:54:21memory sorry uh so not a miss but
- 8:54:24instead the argument was an intended to
- 8:54:26be interpreted as an immediate binary
- 8:54:28value. So uh what the argument what the
- 8:54:32instruction does is it takes register A
- 8:54:35and it writes uh into register A
- 8:54:38whatever the argument to the instruction
- 8:54:39is. So this one's actually easier for us
- 8:54:42to implement internally because we get
- 8:54:44to skip having to go through RAM. Uh we
- 8:54:46get to skip that indirection and instead
- 8:54:48just take whatever value the argument
- 8:54:50is, treat it as a binary number, not as
- 8:54:53an address, and uh throw that into the A
- 8:54:56register. So let me go ahead and copy.
- 8:54:58We already know the first two
- 8:55:00instructions are the same. I don't want
- 8:55:01to keep repeating that, so I won't
- 8:55:03anymore. Um
- 8:55:06now all we have to do for this one to
- 8:55:08implement it once we know it once we
- 8:55:09know we're uh executing a load immediate
- 8:55:12um all we need to do is take the
- 8:55:13argument that's stored in the
- 8:55:15instruction register put it onto the bus
- 8:55:18and then also just read it into the A
- 8:55:20register um and then we're done. So then
- 8:55:26IR to register A is what we're doing
- 8:55:28here. And then our last two clock cycles
- 8:55:30are wasted.
- 8:55:33there no ops and I can denote that for
- 8:55:35the ones above as well.
- 8:55:38Um,
- 8:55:39and this one's interesting because it's
- 8:55:42so simple to execute. Uh, we actually
- 8:55:44have two wasted clock cycles. So only
- 8:55:46three of the allocated five clock cycles
- 8:55:48here are being used meaningfully and the
- 8:55:50others are are are useless. So you can
- 8:55:52imagine that's it's pretty inefficient.
- 8:55:53You know, we have like a 60% utilization
- 8:55:56as measured by clock cycles for actually
- 8:55:59doing work that we need to. Um, and
- 8:56:01yeah, that's a that's a bad that's a bad
- 8:56:03one. And the reason we have two instead
- 8:56:06of one like the previous instructions
- 8:56:08that had a wasted one is because we get
- 8:56:10a skip uh skip a RAM lookout a RAM
- 8:56:12lookup sorry because rather than the
- 8:56:14argument being a address that we needed
- 8:56:17to go decode in RAM which would take an
- 8:56:18extra clock cycle to do we can just we
- 8:56:21got to circumvent that for free just by
- 8:56:22being able to use the argument literally
- 8:56:25without having any indirection through
- 8:56:26memory. So you can kind of see that uh
- 8:56:29because of that looking up a value in
- 8:56:31RAM is slow. So operating with these
- 8:56:34registers is really fast but then
- 8:56:36operating with RAM is a is a is
- 8:56:39meaningfully slower. Uh and so it turns
- 8:56:43out uh modern computers will have many
- 8:56:45registers not just two that feed into
- 8:56:47the ALOU but you know a set of registers
- 8:56:49for you to use for scratch work and
- 8:56:51there will be dedicated instructions for
- 8:56:54reading and writing values into each of
- 8:56:56those registers. And that makes it
- 8:56:58easier for the it makes it faster for
- 8:57:00the computer to implement instructions
- 8:57:03and do work because it can skip every
- 8:57:06time you're operating with uh a register
- 8:57:08value instead of a RAM value. It's
- 8:57:10faster to access that value so the
- 8:57:12computer can execute the instruction
- 8:57:13faster which overall improves the uh
- 8:57:16performance of whatever program you're
- 8:57:18running.
- 8:57:20If you've written code before, then
- 8:57:24certain programming languages, maybe
- 8:57:25you've seen it, have a keyword. I'm
- 8:57:27thinking about C specifically here, uh,
- 8:57:29called register. And so you can kind of
- 8:57:31tell the computer like, hey, this value
- 8:57:33is going to be worked with a lot. Um, so
- 8:57:36put it in a register. Uh, and you know
- 8:57:38the there's something called a compiler
- 8:57:40which will take that English code you've
- 8:57:43written and translate it into these
- 8:57:45machine code instructions that we bu
- 8:57:46we're implementing right now. Uh, and
- 8:57:49maybe that's a hint to that program
- 8:57:51saying, "Hey, don't put this value in
- 8:57:52RAM. Put this value in a register." But,
- 8:57:55uh, I get ahead of myself here.
- 8:57:57Um, let's talk about jump next. So,
- 8:58:01jump's a little interesting because the
- 8:58:03argument to jump and I guess recall
- 8:58:05whatever all jump does is rather than
- 8:58:08the program counter executing
- 8:58:10sequentially, it just keeps counting uh,
- 8:58:13from address one, treat that as an
- 8:58:14instruction, execute it. then it'll say
- 8:58:16look at address two treat that as an
- 8:58:17instruction and execute it. Then look at
- 8:58:19address three treat it as an instruction
- 8:58:21and execute it. Uh instead
- 8:58:24jump lets us tell the pro lets us tell
- 8:58:26the program counter to like not break it
- 8:58:28lets us break that sequential ordering
- 8:58:30and say hey if maybe I'm on instruction
- 8:58:33five right now don't go to instruction
- 8:58:35six uh jump to maybe instruction 10 or
- 8:58:38zero or any of them. So all it's doing
- 8:58:41to implement that is just setting the PC
- 8:58:44equal to the argument. The argument is
- 8:58:47uh an address, but it's not an address
- 8:58:49we need to go look up. It's an address
- 8:58:51we just need to change control execution
- 8:58:53to after this current instruction. So uh
- 8:58:56our first two clock cycles for the
- 8:58:58decode part are the exact same.
- 8:59:02And then uh this one's also pretty
- 8:59:05straightforward where all we need to do
- 8:59:07is take the instruction registers
- 8:59:10argument, the instructions argument
- 8:59:12which is in the instruction register,
- 8:59:14put it out onto the bus and then read it
- 8:59:16in to the program counter
- 8:59:20which we have this J line for. Um and
- 8:59:23that's all. And then our last two clock
- 8:59:25cycles are wasted.
- 8:59:28So all this does is say program counter
- 8:59:31equal uh sorry instruction register to
- 8:59:35program counter. Um and there's
- 8:59:38something interesting here and that this
- 8:59:40instruction touches the program counter
- 8:59:41twice because first we actually
- 8:59:44increment it because that's what we've
- 8:59:46been doing for every other instruction
- 8:59:47and then we update the value that's in
- 8:59:49here. So it turns out because it's a
- 8:59:52jump instruction and
- 8:59:55um we know that the program incrementing
- 9:00:00the program counter is useless because
- 9:00:02we're changing control flow to go
- 9:00:03somewhere else immediately afterwards.
- 9:00:05Uh it it's possibly a little redundant
- 9:00:07to be incrementing the program counter
- 9:00:08here, but um we could so we're
- 9:00:12conceptually we could avoid incrementing
- 9:00:13the program counter here. Um but uh the
- 9:00:17thing is we know we don't know until
- 9:00:20after this clock cycle because this is
- 9:00:22the fetch that we're executing a jump.
- 9:00:24So it's we don't we can't know that
- 9:00:26we're executing a jump. So we can't
- 9:00:28decide to skip incrementing the program
- 9:00:31counter here. So if we had designed our
- 9:00:34implementations for all these
- 9:00:35instructions to increment the program
- 9:00:37counter at the very end of your
- 9:00:39instructions implementation
- 9:00:41then we could safely omit it here like
- 9:00:43we did on the fifth clock cycle. then we
- 9:00:45could emit it here. Um,
- 9:00:48because we're choosing to do it at the
- 9:00:49start, we can't make that mission, but
- 9:00:51it also doesn't break anything because
- 9:00:52it's safe to increment the program
- 9:00:54counter because it happens before we
- 9:00:56update the value uh that we're jumping
- 9:00:58to. So, what would be bad is if the user
- 9:01:00was saying if the user had jumped to
- 9:01:02address 5 and we wrote address 5 into
- 9:01:05the program counter and then afterwards
- 9:01:07we incremented it. That'd be bad because
- 9:01:08it'd actually end up jumping them to six
- 9:01:10because that's what the value in the
- 9:01:12program counter would be when the CPU
- 9:01:14goes to execute the next instruction. Uh
- 9:01:17we don't have to worry about that
- 9:01:18because you can do whatever you want to
- 9:01:20the value in the program counter if
- 9:01:21you're going to eventually write in the
- 9:01:23intended value afterwards. So uh just
- 9:01:26wanted to have a little bit of
- 9:01:27discussion there.
- 9:01:29Um, this instruction as is the case for
- 9:01:32load immediate and store a also has to
- 9:01:34be repeated four times and it's
- 9:01:36identical for each of the combinations
- 9:01:38of the zero flag and the carry flag. Up
- 9:01:41would be jump carry. So recall that jump
- 9:01:44carry is the same thing as jump. We only
- 9:01:46perform the uh updating the program
- 9:01:49counter. I we only do anything if the
- 9:01:51carry flag is one. So this in in
- 9:01:54interpretation means if the last ALOU
- 9:01:57output had a carry out on the most
- 9:02:00significant bit of the ALOU then we will
- 9:02:03perform this jump otherwise we will do
- 9:02:06nothing. So our fetch and decode are the
- 9:02:09exact same
- 9:02:14and also copy over this for just
- 9:02:17completeness.
- 9:02:20Now, if we know we're going to jump,
- 9:02:24it's pretty straightforward. All we know
- 9:02:26we have to do is uh put the instruction
- 9:02:29register out and read it into the
- 9:02:30program counter. And that way you know
- 9:02:32that uh when you get to the next
- 9:02:34instruction, i.e. when this our internal
- 9:02:37counter for the step number uh internal
- 9:02:40counter meaning internal to the control
- 9:02:41logic
- 9:02:43resets back to zero it'll go and fetch
- 9:02:46the PC value which is now the address
- 9:02:49that we intended to jump to. So uh it
- 9:02:52just sets us up for executing the next
- 9:02:54instruction correctly. And
- 9:02:57for jump carry though, uh we want to
- 9:03:00know if the carry flag was set from our
- 9:03:03ALU's flags register. And that is why we
- 9:03:07need this context to know what control
- 9:03:10lines to set, which is why we have these
- 9:03:14uh this carry flag here included as one
- 9:03:16of the inputs to the control logic ROM.
- 9:03:19And that's because we as we were doing
- 9:03:21this as humans, we know that we're
- 9:03:23making a conditional decision. Hey,
- 9:03:25based on the value in the carry
- 9:03:27register, we will make a decision about
- 9:03:30whether or not to actually jump. When
- 9:03:31we're automating this and letting the
- 9:03:33computer make the decisions itself, we
- 9:03:35need to feed this as input to the read
- 9:03:37only memory. So
- 9:03:40for this specific
- 9:03:43uh instruction, it actually does matter
- 9:03:45what the zero sorry what the carry flag
- 9:03:47is. And uh it doesn't matter what the
- 9:03:50zero flag is, but similar to the way we
- 9:03:53had to repeat all of our previous
- 9:03:55instructions four times based on the
- 9:03:57combination of the zero flag and carry
- 9:03:59flags. We're also going to have to
- 9:04:00repeat this for four times because
- 9:04:02there's four combinations of the zero
- 9:04:04flag and carry flag. But it turns out
- 9:04:06that the value of the carry flag uh
- 9:04:08actually influences what we do here. So
- 9:04:12it's not going to be a straight copy
- 9:04:14four times across the ROM to account for
- 9:04:16all four possible permutations. Um it
- 9:04:19will appear for all four permutations,
- 9:04:21but the microode will actually be
- 9:04:22different based on the value of the the
- 9:04:24carry flag here. So in this case, the
- 9:04:27carry flag is zero. So we actually don't
- 9:04:30do anything. Um and so we just do
- 9:04:33nothing for the we waste the the
- 9:04:35remaining three clock cycles of this
- 9:04:37instruction.
- 9:04:38Now if I jumped to uh the spot in the
- 9:04:43RAM address in the ROM address table
- 9:04:45where the carry flag was one. If this
- 9:04:47was a one here then we would do the
- 9:04:49jump. So we'd have the instruction
- 9:04:51register write its value into the
- 9:04:52program counter.
- 9:04:56But in this case it's not actually. Uh
- 9:04:58so we'll undo that. I would say let's go
- 9:05:00hunt for the correct address that would
- 9:05:03match up to this for the other
- 9:05:04permutations. But the the sheet I'm
- 9:05:06making with is non-exhaustive and and it
- 9:05:08doesn't have that. Um so instead let's
- 9:05:11actually uh look to jump zero implement
- 9:05:14that and then we actually will look at
- 9:05:16all the permutations. So jump zero just
- 9:05:18as a reminder what the instruction does
- 9:05:20is the same thing as jump carry but our
- 9:05:22condition to make the jump is if the
- 9:05:24last alou operation equal zero. Um, and
- 9:05:28recall we implemented this by looking at
- 9:05:31the output of the ALOU and oring
- 9:05:34together the inverse of all of the
- 9:05:36output bits. So if all of the um output
- 9:05:40bits
- 9:05:42are are all zeros, sorry, we and them
- 9:05:44all together. So we we if all the output
- 9:05:46bits are zero, then the inverse of all
- 9:05:48of them would be ones across the board.
- 9:05:51And then if we and those together, the
- 9:05:53only way for that output to be one is if
- 9:05:56all of those inputs are one, which
- 9:05:59pre-inverter means all of the inputs are
- 9:06:01zero. Um,
- 9:06:04so the fetch and decode process is the
- 9:06:06exact same.
- 9:06:11But, uh, now we have to look at the zero
- 9:06:13flag. And the zero flag uh, the
- 9:06:16interpretation is could be a little
- 9:06:19misleading here. the zero flag uh if
- 9:06:22it's zero it means the last alou output
- 9:06:25was not equal to zero. It's only if it's
- 9:06:28set to one does it mean that the last
- 9:06:29ALU output was actually zero. In this
- 9:06:32case uh the zero flag is zero which
- 9:06:34means the last ALU operation was not a
- 9:06:37zero. So we don't actually do the jump.
- 9:06:39So we also similar to the jump carry we
- 9:06:42just saw we end up wasting all the
- 9:06:44remaining clock cycles.
- 9:06:47Um but let's go see a more interesting
- 9:06:49case. So this is how jump zero behaves
- 9:06:51if the zero flag is zero. Uh we're kind
- 9:06:55of interested in the what the output
- 9:06:57looks like if the zero flag is one.
- 9:07:00And so I would copy this.
- 9:07:11Here's another jump zero. So our first
- 9:07:13two instructions will be the same. Our
- 9:07:15zero flag is still zero. So we actually
- 9:07:18do nothing. So we still waste the
- 9:07:20remaining three clock cycles.
- 9:07:22Not as interesting. Let's keep going.
- 9:07:26Here's Oh, here's another jump zero. And
- 9:07:29we know it's jump zero because the op
- 9:07:31code is one 0 0. That's how we defined
- 9:07:33in the table. So I'll copy over the
- 9:07:35first two clock cycles of the fetch
- 9:07:37process. Oh, those are gone. Um,
- 9:07:46so these two are always the same. This
- 9:07:48time though, the zero flag is one. So we
- 9:07:50perform the jump. And so what that means
- 9:07:53is we actually take the argument stored
- 9:07:54in the instruction register, throw it
- 9:07:56out onto the bus, and then read it into
- 9:07:58the program counter, and then we waste
- 9:08:00the last two clock cycles. So this says
- 9:08:03PC
- 9:08:05PC uh instruction register to PC. Uh put
- 9:08:10the argument instruction register out
- 9:08:11into the program counter. Um and there's
- 9:08:14something interesting because it may not
- 9:08:17be very apparent but it is also probably
- 9:08:19worth calling out. Uh this right here is
- 9:08:21the same micro code for the regular jump
- 9:08:24instruction that unconditionally makes
- 9:08:26the jump. So uh every time we are making
- 9:08:30a jump carry or jump zero and the
- 9:08:32correct flag is one the microode
- 9:08:35uh i.e how we uh implement the
- 9:08:38instruction is called microode uh
- 9:08:40setting each of these lines output
- 9:08:42lines. Um the microode the control
- 9:08:45output is always the same and so it's
- 9:08:49based on uh the inputs that actually
- 9:08:52determine which of the uh which of these
- 9:08:55control lines will be set for the
- 9:08:56output. Um, so it means we do replicate
- 9:08:58this this instruction four times like
- 9:09:01every other instruction is replicated to
- 9:09:02handle for every permutation of the zero
- 9:09:05and carry flags. But unlike every other
- 9:09:07instruction we've seen so far that
- 9:09:09ignores it, this one actually has to
- 9:09:11look at those flags to make a uh
- 9:09:13well-informed decision to know what it
- 9:09:15should or should not do. So that's
- 9:09:16pretty interesting because this is kind
- 9:09:18of how we make decisions in our in our
- 9:09:20control. um you know everything else
- 9:09:24everything else in terms of instructions
- 9:09:26we discussed so far uh it's easy to tell
- 9:09:28the control what to do strictly based on
- 9:09:30you know for hey this op code represents
- 9:09:33this instruction the steps are always
- 9:09:34the same but then for the the jump carry
- 9:09:37and jump zero instructions
- 9:09:39uh they aren't necessarily the same uh
- 9:09:41and we'd actually need to look at it so
- 9:09:43as a human we said uh I'm going to look
- 9:09:45at what's in the flags register to
- 9:09:46determine if I make this jump uh and we
- 9:09:49how we bridge that gap of us making a
- 9:09:52decision conditionally uh was feeding it
- 9:09:54as input to the readonly memory and
- 9:09:57generating different outputs based on
- 9:09:59the different input combinations. And so
- 9:10:01because a readonly memory has to be we
- 9:10:03have to fully map out every input and
- 9:10:05output combination we can pretty much
- 9:10:07say hey for each of these input
- 9:10:09combinations this is what you should do.
- 9:10:11So we are we give the readonly memory a
- 9:10:13very verbose yet complete and necessary
- 9:10:17uh set of [snorts] input output
- 9:10:19combinations to handle for this. Um so
- 9:10:21for every other instruction if we wanted
- 9:10:23to add more conditional instructions to
- 9:10:25this computer uh you kind of have to
- 9:10:27find a way to incorporate that logic uh
- 9:10:30into the readonly memory by adding in an
- 9:10:32extra input um that represents the
- 9:10:36decision state for what you're making
- 9:10:38that instructionally do. And then it'd
- 9:10:41also have to be replicated however many
- 9:10:43times. Um, cool. So that's interesting.
- 9:10:46Uh, let's see if I
- 9:10:49So the remaining jump zero one 0 0. Um,
- 9:10:53the jump flag is set. So we also perform
- 9:10:56the the jump operation. So I can
- 9:10:59actually literally just copy the
- 9:11:01implementation for jump because it's the
- 9:11:03same.
- 9:11:10Cool. Okay. So, that's how we implement
- 9:11:13our conditional logic onto our final two
- 9:11:16instructions. Uh, I know this has
- 9:11:18probably gotten a little bit repetitive,
- 9:11:20but I wanted to be as complete as
- 9:11:21possible because I part of the video is
- 9:11:23I do not want to leave out otherwise
- 9:11:24meaningful information as I explain
- 9:11:26things from scratch. Uh, so I want to
- 9:11:28minimize the amount of handwaving I do
- 9:11:30until we have the barebone CPU working.
- 9:11:33And then as we talk about how this
- 9:11:34translates to a more modern CPU, more
- 9:11:37modern computer, uh then I'll do a
- 9:11:39little more handwaving. But
- 9:11:41um our second to last instruction was
- 9:11:44out and all it does is put the value in
- 9:11:47register A into the output displays
- 9:11:49register. And that has the effect of
- 9:11:52updating the seven segment display to
- 9:11:55show whatever's in the A register. Even
- 9:11:57uh in future instructions change the
- 9:11:59value of the A register. um it won't
- 9:12:02update the display explicitly. So the
- 9:12:04display is not always just hardcoded to
- 9:12:06the A register. Remember we built a new
- 9:12:07register uh and the display is hardcoded
- 9:12:10to that register. Um
- 9:12:13so our fetch decode execute cycle starts
- 9:12:16with fetch. We do the same thing that
- 9:12:19we've done for every instruction.
- 9:12:21Oh well that's interesting.
- 9:12:30Okay. Um, and for this one, it's also
- 9:12:33pretty trivial. All we need to do is get
- 9:12:35the value in the A register into the
- 9:12:37displays register. So, I'm going to put
- 9:12:39the A register out onto the bus and then
- 9:12:42I'm going to read it into the uh display
- 9:12:45register.
- 9:12:51And uh once we do that, uh I'll mark
- 9:12:54that as register a into display reg. um
- 9:12:59our remaining two clock cycles can be
- 9:13:01wasted here. So that's a pretty simple
- 9:13:03instruction. And then this brings us
- 9:13:07um to the halt instruction which is the
- 9:13:10last one of them all but worthy of
- 9:13:12instruction worthy of discussion. Uh and
- 9:13:15for both the output and the display
- 9:13:18instructions obviously these are
- 9:13:19repeated four times uh based on whatever
- 9:13:21the inputs uh for the zero flag and
- 9:13:24carry flag are don't affect what these
- 9:13:26operations do. But we still need to
- 9:13:28define them because that is input to the
- 9:13:30ROM. Um, I display should do the same
- 9:13:33thing uh if if the zero flag is one and
- 9:13:36the carry flag is zero as as it should
- 9:13:38as if both of those flags are zero. But
- 9:13:40we actually need to go specify that in
- 9:13:42the ROM um for completeness. So our halt
- 9:13:47instruction is pretty interesting where
- 9:13:50all we have to do is set the halt line.
- 9:13:55And
- 9:13:56recall that the moment we do this
- 9:14:00because the halt line is is connected to
- 9:14:03the clock, the halt line is inverted and
- 9:14:06then connected to the clock. So the
- 9:14:08moment we set halt one, the inverted
- 9:14:11value of halt is zero. And since the
- 9:14:14clock is anded with this, it means the
- 9:14:17clock output that we connect to the rest
- 9:14:19of the computer is just going to get
- 9:14:21stuck at zero because zero and anything
- 9:14:23anded with zero is zero. So even if the
- 9:14:26clock itself is going high to low, high
- 9:14:27to low, uh when we end it with this
- 9:14:29inverted halt signal, it'll block that
- 9:14:32from actually carrying through out of
- 9:14:33the endgate. Um and so as soon as we get
- 9:14:37here, the computer cannot make any
- 9:14:39progress. So it actually doesn't matter
- 9:14:41what we specify for the remaining two
- 9:14:43clock cycles here because not none of
- 9:14:45it's conceptually possible for it to get
- 9:14:47executed. The only way to get the
- 9:14:50computer out of this state would be to
- 9:14:52physically turn it off, turn it back on,
- 9:14:54reprogram uh your memory and then things
- 9:14:57will be good to go again. Um, cool. So
- 9:15:00that concludes us implementing each of
- 9:15:03the instructions. What I'd like to do
- 9:15:05next is uh define a program with the
- 9:15:10instructions we've created.
- 9:15:13So I'll switch over to this other tab
- 9:15:15here. And what I've copied over is all
- 9:15:18of our instructions and their op codes.
- 9:15:20We know what they do. So I don't carry
- 9:15:21over a description. And then uh a
- 9:15:23conceptual layout of RAM
- 9:15:26um where here's our 16 different
- 9:15:28addresses starting from zero uh in
- 9:15:31decimal. And then this is the binary
- 9:15:33representation i.e. if we wanted to you
- 9:15:35know lo access that value either read or
- 9:15:39writing into it. Uh this is what we need
- 9:15:40to put in the memory address register.
- 9:15:42So it's just the the binary equivalence.
- 9:15:44And what I'd like to do is let's write a
- 9:15:47simple program that just
- 9:15:50starts with 15 uh and keeps counting
- 9:15:53down by one and displaying that on the
- 9:15:56uh our seven segment display and then
- 9:15:58once we hit zero we stop. Uh it's a
- 9:16:00trivial program and you'll probably see
- 9:16:02why I pick 15 very very shortly. Um but
- 9:16:07if we think about what we need to do to
- 9:16:09get this program in RAM, there's a few
- 9:16:10things. First, we need to you know for
- 9:16:13our our primary loop, it's going to be
- 9:16:16doing subtraction by one each time.
- 9:16:18Assuming we get the value 15 into the a
- 9:16:21register and we get the value one uh
- 9:16:23somewhere else in memory then we can
- 9:16:25keep calling the subtract instruction
- 9:16:27with wherever the one resides in memory
- 9:16:30and then we know every time after we do
- 9:16:32the subtract instruction we want to
- 9:16:34write the display to write to the output
- 9:16:36display and then we check if we're at
- 9:16:38zero or not. Uh if we're not at zero we
- 9:16:41could jump back to our same uh
- 9:16:42subtraction instruction. uh otherwise if
- 9:16:45we are at zero we need to jump and and
- 9:16:48have this um halt command. So let's kind
- 9:16:52of think about the very first thing we
- 9:16:54need to do. Um the first thing we'd want
- 9:16:57to do is get this the value one
- 9:17:00somewhere in memory so that we can
- 9:17:02always use that as our thing that we're
- 9:17:04subtracting from. And if I if we were to
- 9:17:06count down from two, we would need the
- 9:17:08value two somewhere in memory. And
- 9:17:10that's because the subtract instruction
- 9:17:12uh the operand is not the value you want
- 9:17:15to subtract from whatever's in the A
- 9:17:16register. It's the address to something
- 9:17:18in memory and that value at that address
- 9:17:22is what you want to subtract from the A
- 9:17:23register. So uh the first thing I want
- 9:17:26to do is actually get um a load
- 9:17:29immediate of a one into the A register.
- 9:17:32So
- 9:17:34the reason I'm doing this uh is that in
- 9:17:37the only way we can write something to
- 9:17:39RAM is with our store a instruction. So
- 9:17:42if we want to get the value one
- 9:17:44somewhere into RAM, we'd actually first
- 9:17:46need to get that value into the A
- 9:17:48register and then we can write it from
- 9:17:50the A register into RAM. And so the load
- 9:17:52immediate is what does exactly that. It
- 9:17:54treats the argument as a literal 4bit
- 9:17:57integer and then it'll put that into the
- 9:17:59A register. So uh we can comment this
- 9:18:03you know register a equals 1 and then uh
- 9:18:06the actual RAM value the actual value we
- 9:18:09put in RAM to do this is the load
- 9:18:11immediate argument. So 0 1 01 and then
- 9:18:14the argument here I'll do a space to
- 9:18:16separate the the op code the operation
- 9:18:19code the instruction code and then the
- 9:18:21argument to that instruction just for
- 9:18:23our readability purpose. Um, and the
- 9:18:26argument we want to load into the val
- 9:18:28into the A register is just one. So now
- 9:18:31that we've loaded the A register with
- 9:18:33the value one, we want to store that
- 9:18:35somewhere in memory. And here's where we
- 9:18:36get interesting. So like our computer
- 9:18:38will start at address zero in terms of
- 9:18:40execution when we power it up. The
- 9:18:42program counter will always start at
- 9:18:43zero just by assumption. Um, we kind of
- 9:18:46you get to use RAM however we want. So
- 9:18:49it's kind of us up to us to figure out
- 9:18:51where we want to put the uh the the
- 9:18:54constant one in memory and we designed
- 9:18:56the program knowing that okay if we
- 9:18:58store the constant one in memory at this
- 9:19:00address then every time we do our
- 9:19:01subtraction instruction this is the
- 9:19:03address we need to feed it. What I like
- 9:19:06to do and what you'll probably see if
- 9:19:07you poke into this further um since RAM
- 9:19:10can contain both instructions and data
- 9:19:13people generally like to separate the
- 9:19:15two. Uh but it's not actually a strict
- 9:19:17requirement. It's totally up to you. And
- 9:19:18I think this is where some amount of
- 9:19:20like creative expression comes into
- 9:19:22play. Uh cuz you'll also see that
- 9:19:24there's probably a different way to
- 9:19:25implement the same exact program. You
- 9:19:27might actually have a different thought
- 9:19:28of how you can get this countdown
- 9:19:30program. Um and I'd encourage you to try
- 9:19:32it out. And we'll we'll show you how to
- 9:19:34try it out shortly, but I'm going to go
- 9:19:36down the route I have. So I've loaded
- 9:19:38the register uh a with the value one.
- 9:19:41And I'm going to say that uh address 15
- 9:19:44is where we're going to store that into.
- 9:19:45So, what I'd like to do then is store uh
- 9:19:48the value in the A register into address
- 9:19:51um 15. And so, what that does is it says
- 9:19:56mem 15= 1.
- 9:20:00And I guess I'll just use RAM at address
- 9:20:0215als 1 uh for the comment here. And
- 9:20:04then the actual binary value that we
- 9:20:07need to load into RAM at address one to
- 9:20:09signal that instruction to the computer
- 9:20:11is the store a command which is 010 and
- 9:20:15then our argument is 1111.
- 9:20:18Okay. So basically when we power up the
- 9:20:21computer if we had if we ran uh ran the
- 9:20:24the instructions uh this in this value
- 9:20:28followed by this value the output is
- 9:20:30that uh the value in RAM at this address
- 9:20:33would look like this. Um if we let that
- 9:20:36program run but that's not what we want
- 9:20:38to do. That's just getting started. So
- 9:20:40now that we have uh this this value
- 9:20:42address that we're going to say so like
- 9:20:44this will just be like a hard-coded one
- 9:20:47is kind of how we will the the value I
- 9:20:49mean we don't specify that our program
- 9:20:50will put that in there. Um there's an
- 9:20:53alternative where we could have skipped
- 9:20:55these two steps if we had just punched
- 9:20:58the value
- 9:21:01the uh this value one into that RAM
- 9:21:03value to begin with. Uh but I'm just
- 9:21:05going to work with just what we can
- 9:21:07express with instructions for now. Um,
- 9:21:10so now that we've uh gotten our one,
- 9:21:13which might still a little bit be might
- 9:21:15still be a little bit ambiguous as to
- 9:21:16why we've done these two instructions,
- 9:21:17but you'll see very shortly. Um, we
- 9:21:20simply want to start with the value 15
- 9:21:22and count down from it. So, basically,
- 9:21:26uh, what we need to do is load the value
- 9:21:2815 into the A register.
- 9:21:31So, load immediate 1111. Uh, ooh, this
- 9:21:35is actually, um, Oh, that's fine. That's
- 9:21:38fine. So it what's interesting here is
- 9:21:401111 in this uh instruction is an
- 9:21:43argument that actually points to this
- 9:21:44address in memory because that's how we
- 9:21:46interpret the argument for the store
- 9:21:48instruction. But as we discussed earlier
- 9:21:50the 1111 in this load immediate argument
- 9:21:53is actually referring to the literal
- 9:21:55binary value um 15 if you were to
- 9:21:58translate that from binary back to
- 9:21:59decimal. So uh the effect of this
- 9:22:02instruction is that register a will now
- 9:22:03equal 15. And so the actual RAM value
- 9:22:06that we need to put in to encode that
- 9:22:08instruction is load immediate 0 1 01 and
- 9:22:11then 11 one1.
- 9:22:13Okay. So now we have 15. Um we need to
- 9:22:16think about what the user expected
- 9:22:18behavior of this program is. And what
- 9:22:20that is is that they should see the
- 9:22:22number 15 and then they should see the
- 9:22:24number 14 and then 13 and it should go
- 9:22:26all the way down until they see the
- 9:22:27number three then the number two then
- 9:22:29the number one and then the number zero
- 9:22:31and then it stops. Let's not think about
- 9:22:32the end conditioner yet. But uh let us
- 9:22:35think that the fact that we have 15 in
- 9:22:37the A register, let's go ahead and show
- 9:22:38that to display. So all we'll do is an
- 9:22:41out for our next instruction. Um and
- 9:22:43recall that the argument is useless. So
- 9:22:46to encode that in binary
- 9:22:48um we will say
- 9:22:52uh
- 9:22:54the operation code for the out
- 9:22:56instruction is 1 1 0 and then the
- 9:22:58argument does not matter. There's no
- 9:22:59argument for this instruction. And as we
- 9:23:01discussed earlier when we looked at how
- 9:23:03we implemented the ROM over here since
- 9:23:05we handle um
- 9:23:08like yeah it doesn't actually matter
- 9:23:10what the uh argument is here. This could
- 9:23:12be anything. We just actually don't even
- 9:23:14use it um for for our our implementation
- 9:23:18of the microode. So it doesn't even
- 9:23:19really matter. Uh I'll just keep it
- 9:23:21zeros for for clarity. Um okay. So now
- 9:23:24we're going to say display 15. Okay. So
- 9:23:28now we've displayed 15. we got to get to
- 9:23:3114. So all we need to do since we have
- 9:23:3415 in the A register is subtract one.
- 9:23:37And recall that by the time we get to
- 9:23:39this instruction right here, by the time
- 9:23:40our program counter equals the value
- 9:23:42four, we were guaranteed to have a
- 9:23:45hard-coded one at RAM address 15. So all
- 9:23:49we need to do is subtract one from the A
- 9:23:51register. So we could just do sub and
- 9:23:54then recall the argument is the address
- 9:23:57uh which contains the value you want to
- 9:23:58subtract. So we're going to do 15 here,
- 9:24:00which is binary 1111. Um, and so this
- 9:24:04has the effect of of a equals a minus
- 9:24:07one. And so the binary value that we
- 9:24:10need to put into RAM to encode that
- 9:24:11instruction. Uh, the operation code for
- 9:24:14sub is 0011. And our argument is address
- 9:24:1715. So 1 2 3 4. Cool. Um, so now that
- 9:24:21we've subtracted one, we are at 14. So
- 9:24:25let's go ahead and show that to the
- 9:24:26user. So it's the same thing we've done
- 9:24:28up here. Um so we will say uh display a
- 9:24:35um and then
- 9:24:38uh the operation code is 11 1 0 0. So
- 9:24:42now that we've subtracted a value and
- 9:24:44shown it to the user, we need to make
- 9:24:47the decision. Do we go subtract another
- 9:24:49value and repeat this process again and
- 9:24:51show that value to the user? um or are
- 9:24:55we at zero and should we end the
- 9:24:57program? So naively what you might think
- 9:25:00is uh let's just ignore the termination
- 9:25:03condition of the program is all we once
- 9:25:06we have gotten to the state all we'd
- 9:25:08like to keep doing is subtracting the
- 9:25:09val subtracting one from whatever's in
- 9:25:11the A register and then showing that to
- 9:25:13the user and subtracting one from the A
- 9:25:15register and then showing that to the
- 9:25:16user. Um, and so what we what you might
- 9:25:20be tempted to do here is just jump uh to
- 9:25:22this address 4, which is 0 1 0 0. And
- 9:25:26that would work. Uh, but this wouldn't
- 9:25:28stop correctly. When we got to zero, uh,
- 9:25:30this would jump right back to this
- 9:25:32instruction. And then you get a weird
- 9:25:34result in the ALOU because, you know,
- 9:25:35you're subtracting
- 9:25:37uh, one from zero, so you'd get negative
- 9:25:39one. Um, but we said we wanted to stop
- 9:25:42the program at zero. So what we'd
- 9:25:44actually need to do is check uh if we
- 9:25:46have a zero from our last result, which
- 9:25:48is the exact purpose of this jump carry
- 9:25:50instruction. And if we hit if we do, we
- 9:25:53should if we jump carry to zero, uh we
- 9:25:56can jump to an address that will end the
- 9:25:59program uh by just having the halt
- 9:26:02instruction at that address. So what I
- 9:26:04mean by that is let's put a halt
- 9:26:07instruction just somewhere random in
- 9:26:08memory. Um
- 9:26:13and there's no argument to the
- 9:26:14instruction and so this is just halt. Uh
- 9:26:18and then basically what we can then do
- 9:26:20here is like if we uh jump if our if the
- 9:26:24result of the last ALU operation i.e.
- 9:26:26the subtract at address 4 was a zero to
- 9:26:29this address 10 which is binary 1 0 1 0.
- 9:26:33Um and so if we think about where we
- 9:26:37start here, uh we display 15, subtract
- 9:26:40one. So we just and then we have 14 and
- 9:26:42then we display 14. This jump carry 14
- 9:26:45is not equal to zero. So it just
- 9:26:47continues uh execution. And so then we
- 9:26:50know that if we make it to this address
- 9:26:527 that it means we actually are not done
- 9:26:55with our program. So we should jump back
- 9:26:57up to here to do the subtraction uh
- 9:26:59again. So I can just jump to address 0 1
- 9:27:030 0. Um so basically uh check if done
- 9:27:10and then otherwise
- 9:27:12um loop. We're pretty much doing a loop
- 9:27:14here. You know we loop back to the top
- 9:27:16where our loop is a pretty
- 9:27:17straightforward just uh subtract by one.
- 9:27:20So the last thing I need to do is go
- 9:27:21ahead and specify what the RAM values
- 9:27:23for both of these instructions are. So
- 9:27:25this jump carry is 0 1 1 and then our
- 9:27:28argument is 1 0 1 0 and then regular
- 9:27:30jump has the operation code 0 1 1 0 and
- 9:27:34then our argument is 0100.
- 9:27:37So um if you believe what I'm saying
- 9:27:40then let's walk through our program. We
- 9:27:43start we load the value one into
- 9:27:45register A and then we store that at
- 9:27:47address 15 in RAM. Then we load the
- 9:27:50value 15 into register A. Show that to
- 9:27:52the user. So the user then sees 15. We
- 9:27:55subtract one from the register and then
- 9:27:59display that user. So the user sees 14.
- 9:28:02We check if the result was zero. 14 is
- 9:28:04not zero. So we move on to this
- 9:28:06instruction. This jump just says go back
- 9:28:09to right here. And so then we have 14
- 9:28:12and then we subtract one from it. So we
- 9:28:13get 13. We show 13 to the user. 13 does
- 9:28:16not equal to zero. So we continue. And
- 9:28:18then we jump back up here. And now we
- 9:28:21have 13. We subtract one to get 12 in
- 9:28:23the A register. Show 12 to the user. 12
- 9:28:26does not equal zero. And so we jump back
- 9:28:28up here. And the process will continue
- 9:28:30until we eventually get to uh having one
- 9:28:33in the A register. Then we subtract one
- 9:28:35from it to get zero. We show the zero to
- 9:28:38the user. Then we check if the last
- 9:28:40result was zero. It was this time. So we
- 9:28:42jump to this address in memory. And this
- 9:28:45address in memory just has to halt the
- 9:28:46program. So nothing continues
- 9:28:48afterwards. So, I've invented this
- 9:28:50hypothetical program. Um, but like how
- 9:28:53can we actually verify that it's
- 9:28:54correct? Uh, it turns out I've built the
- 9:28:56simulator for the computer we've
- 9:28:58designed. So, we can go go ahead and
- 9:29:00punch this program, this this value into
- 9:29:02RAM, um, and let it run and see if the
- 9:29:06behavior is exactly what we expect. So,
- 9:29:08let me go ahead and tab out and let's do
- 9:29:10that. Uh, a few years ago when I first
- 9:29:13built this computer, I guess 6 years ago
- 9:29:15now, uh, I also built a simulator
- 9:29:17afterwards. This is publicly available
- 9:29:19if you want to play around with it. Um
- 9:29:21there's instructions on how to set it up
- 9:29:23and how to use it here. Um I won't focus
- 9:29:26too much on that. We'll just show how
- 9:29:27how do you actually play around with it
- 9:29:29to show what we the program we just
- 9:29:31made. Um so what I've gone through and
- 9:29:34done is uh let's look at the simulator
- 9:29:36itself. So at any point you can see the
- 9:29:40contents of RAM. Uh this is the
- 9:29:42addressing and you can just click on any
- 9:29:44value to change it and it'll show you
- 9:29:45every time. There's like kind of a a log
- 9:29:47here of every every time something about
- 9:29:49the computer changes, it is shown here.
- 9:29:52So if I just set this value to zero, you
- 9:29:53can see memory address 15 changed to
- 9:29:55zero. Uh or if I punch it to one, memory
- 9:29:57address 15 changed to one. Um and so
- 9:30:01this is RAM. And then you can see for
- 9:30:04you can see the value that's on the bus
- 9:30:06at any time. You can see this value
- 9:30:08that's in the A register or the B
- 9:30:10register. And you can see the output of
- 9:30:12the ALU at any time. And then you can
- 9:30:14also see what's in the instruction
- 9:30:16register, what's in the program counter,
- 9:30:18what's in the output displays register,
- 9:30:21what's in the memory address register,
- 9:30:23and then recall that each instruction on
- 9:30:26our uh computer takes five clock cycles
- 9:30:28to execute. So you can see what uh each
- 9:30:31of the steps are. And then it'll also
- 9:30:33show you for each of the steps
- 9:30:36um what control lines like what the
- 9:30:38output of the control lines uh are. and
- 9:30:41then also what the value of our carry
- 9:30:43flag and zero flag are. Um there's a few
- 9:30:46other things. We don't need to touch on
- 9:30:47all of it. Uh and you can also see
- 9:30:49here's the value of the seven segment
- 9:30:50display. Um the fictitious one we
- 9:30:53constructed with just one of these
- 9:30:54units, but I explained you could
- 9:30:56probably reason through how the same
- 9:30:58logic can be expanded for chaining
- 9:31:00several seven segment displays together
- 9:31:02to show uh multi-digit numbers rather
- 9:31:05than the zero through nine that we were
- 9:31:07fairly constrained to. And then what
- 9:31:09I've done is I've gone ahead and punched
- 9:31:12in our entire program. There is one
- 9:31:14thing I caught. Um I used jump carry
- 9:31:17here. Uh but our end condition is we
- 9:31:19don't want to end when our result
- 9:31:21carries because it doesn't make sense
- 9:31:22because we're counting down. We want to
- 9:31:24end the program when we hit a zero as
- 9:31:26the last output of our our ALU
- 9:31:28operation. So this should not be a jump
- 9:31:30carry. This should be a jump zero.
- 9:31:32Apologies for the confusion. And then
- 9:31:34the jump zero uh operation code is 10.
- 9:31:38So, uh, I fixed that. And then you can
- 9:31:40see I've kind of, um, incorporated that,
- 9:31:45uh, in the program here. There's one
- 9:31:47other cool thing, uh, that this computer
- 9:31:50simulator has, and that is, uh, there's
- 9:31:53this button I built called analyze
- 9:31:55program. And you can kind of see that
- 9:31:56the contents of RAM are nonsensical. Um,
- 9:31:59but if I click this analyze program,
- 9:32:01it'll actually go through and show you
- 9:32:03what each of the instructions are, um,
- 9:32:06or what the decimal value of that
- 9:32:09address in RAM is. It has to do both
- 9:32:11because the computer is naive. Uh, it
- 9:32:14can't know if you're using a certain
- 9:32:16address to denote an instruction or to
- 9:32:18hold a hold a value. Um, and it turns
- 9:32:21out any particular address can actually
- 9:32:23be both. Um, but that's why I do that.
- 9:32:27So you can see that our instructions
- 9:32:29here we have load a a store a 15 a load
- 9:32:33immediate 15 an out subtract 15 and out
- 9:32:37a jump zero to address 10 a jump to
- 9:32:40address 4 two empty instructions a halt
- 9:32:45and then um at the very end we have
- 9:32:48nothing down here and our address 15 is
- 9:32:51zero because we have not run the program
- 9:32:53yet. the first two instructions would
- 9:32:55get the value one into RAM. Um, so this
- 9:32:58is identical to what we uh created over
- 9:33:00here. So that looks good. Let's go ahead
- 9:33:03and toggle the clock and uh we can walk
- 9:33:07through the very first instruction super
- 9:33:09closely. So uh the very first thing we
- 9:33:12have is this load immediate one. Let me
- 9:33:14jump back to our other sheet and we can
- 9:33:17see what our our
- 9:33:19uh instructions our micro code should be
- 9:33:22for this load immediate. So um the first
- 9:33:26thing that every instruction should do
- 9:33:29is get look up the value of the program
- 9:33:31counter in RAM and get that uh get that
- 9:33:34value. So we want to put the value of
- 9:33:36the program counter onto the bus and
- 9:33:38then read that into the memory address
- 9:33:39register. If I tab over here, I can see
- 9:33:42since we're on the first step here, uh,
- 9:33:44those exact things are set. The program
- 9:33:46counter is going out onto the bus. The
- 9:33:48memory address register is reading that
- 9:33:49in. Our clock is low right now. So, if I
- 9:33:52pulse the clock from high, from low to
- 9:33:54high, um, we should see that happen. Uh,
- 9:33:57it's kind of uninteresting because all
- 9:33:58the values are zero. The program counter
- 9:34:00is zero. So, we're kind of putting zero
- 9:34:02on the bus here. And, um, the memory
- 9:34:04address register is already zero, so
- 9:34:06when we read it in, uh, nothing really
- 9:34:08changes. Um,
- 9:34:11so, uh, let me go ahead and pulse the
- 9:34:14clock from low to high. Nothing really
- 9:34:16happens. But then when I let the clock
- 9:34:18go back down, um, we are, we should end
- 9:34:20up on step two. And we should see that
- 9:34:22the next set of operations is getting
- 9:34:25that output of RAM onto the bus and
- 9:34:28reading it into the instruction
- 9:34:29register, looking up the instruction
- 9:34:31effectively, and then also incrementing
- 9:34:32our program counter. So uh let me go
- 9:34:35ahead and put the clock down and you can
- 9:34:38see exactly those three lines are set.
- 9:34:40Uh we increment our program counter and
- 9:34:42then we are look taking whatever value
- 9:34:44we got from RAM which should be this 01
- 9:34:48and putting it into the instruction
- 9:34:50register. And so there's this other
- 9:34:51thing about this uh simulator where this
- 9:34:54button right here will let us highlight
- 9:34:57uh whatever the address in the memory
- 9:34:59address register is on the RAM. So
- 9:35:02memory address register has zero. So we
- 9:35:04can see zero is highlighted uh as we
- 9:35:06trace through the program. It's
- 9:35:08interesting. You'll see that uh move a
- 9:35:11lot. Um and so that now we we have done
- 9:35:14the second step here. So what I need to
- 9:35:17do is get the clock to be low again. So
- 9:35:19I'll post uh back down. And the next
- 9:35:22thing the very last thing we need to do
- 9:35:24uh for load immediate is take the
- 9:35:26argument because now we've decoded the
- 9:35:27instruction at this point. We know it's
- 9:35:29load immediate. So we know the argument
- 9:35:31just needs to go out onto the bus, which
- 9:35:33is what the instruction out does, and
- 9:35:35read it into the A register. So
- 9:35:39um let's go ahead and do that. And you
- 9:35:42can see that on that rising clock edge,
- 9:35:45the value gets latched in. So the
- 9:35:47program counter is now one. And then our
- 9:35:50instruction register has the uh value
- 9:35:53and address zero, which is the
- 9:35:54instruction we're trying to execute. And
- 9:35:56that looks great. And so if I toggle the
- 9:35:59clock, uh, we fall back low. And we can
- 9:36:01see that our next set of operations that
- 9:36:03we're going to do is exactly that. Move
- 9:36:04the argument from the instruction
- 9:36:06register, which is this 00001,
- 9:36:08uh, into the A register. So when I pulse
- 9:36:10the clock from low to high, this O1, uh,
- 9:36:13should go into register A. Uh, and we
- 9:36:16can see that's on the bus already, too.
- 9:36:18So more interesting non-zero values to
- 9:36:20work with. We can make some sense of it
- 9:36:22now.
- 9:36:24And cool. So the clock went from low to
- 9:36:26high. And um you can see that the bus
- 9:36:30now has the bus still has the same value
- 9:36:32but register A has that immediate one
- 9:36:34in. And then uh interestingly enough the
- 9:36:37ALU is just always adding or subtracting
- 9:36:39what's in the two registers A and B. So
- 9:36:42we don't care about the ALU output for
- 9:36:44this instruction but it is a correct
- 9:36:45sanity check that like 0 + 1 is one. um
- 9:36:49we know that and then we know from here
- 9:36:52that after three clock cycles we've
- 9:36:55implemented we've done all we need to do
- 9:36:56for the load immediate instruction. So
- 9:36:58the last two clock cycles are kind of
- 9:36:59wasted. Um
- 9:37:02and there's also some detail here. This
- 9:37:05uh log will pretty much show you
- 9:37:06everything that we just said. So like we
- 9:37:08just had the rising clock edge where we
- 9:37:10read the a registers value in from the
- 9:37:12bus. Um, so that that happens as well.
- 9:37:14And that's just a nice English
- 9:37:16interpretation of what the computer is
- 9:37:17doing with each clock edge. So if I
- 9:37:20toggle the clock to low, um, you can see
- 9:37:22it's a falling clock edge. Step counter
- 9:37:24updated the four. Since it's a load
- 9:37:26immediate, we've done our
- 9:37:27implementation, so nothing happens. And,
- 9:37:30um,
- 9:37:32oops, I accidentally reset our SAP. Uh,
- 9:37:34I clicked the reset button. So we've
- 9:37:36we've gone back to to reset the state of
- 9:37:38our computer. If I just toggle it to get
- 9:37:40back to where we were. Um,
- 9:37:42there's there's nothing crazy to it. So,
- 9:37:45we're at step count five. We hit the
- 9:37:47rise and clock edge and when I fall when
- 9:37:50I fall, we're done with our instruction.
- 9:37:52So, now we go our internal counter used
- 9:37:54for the control resets its step count to
- 9:37:57one. And now we know we're on the next
- 9:37:59instruction. And uh that next
- 9:38:01instruction, if I analyze our program,
- 9:38:04was the storing that value into address
- 9:38:0715. So, I'm not going to walk through
- 9:38:08each of the five clock cycles here. What
- 9:38:10I will do is I'll pulse the clock five
- 9:38:12times until we get back to step counter
- 9:38:14one. And what you'd expect to see if
- 9:38:16everything's correct is that afterwards
- 9:38:18the value in RAM at this address 1111
- 9:38:22should equal um the value in the A
- 9:38:25register which is just one. So, let's go
- 9:38:28ahead. I'll pulse the clock five times.
- 9:38:33And you can see that that's exactly
- 9:38:35what's happened. the value in the uh
- 9:38:38address 15 of our RAM is now that one.
- 9:38:41Um so that looks good. Then
- 9:38:45so I'm gonna say this looks good. This
- 9:38:49looks good. Um now we need to load the
- 9:38:52value 15 into register A. Let me pulse
- 9:38:54the clock five more times to do that.
- 9:38:59And so now we can see register A has
- 9:39:01this value 1111. And then that looks
- 9:39:05good. Then we display it to the user. So
- 9:39:06let's pulse the clock five times. And
- 9:39:08we'd expect the value 15 to be visible
- 9:39:10here.
- 9:39:13Uh, cool. What I should have done when I
- 9:39:15built the simulator is add an option uh
- 9:39:18not to just toggle the clock, but maybe
- 9:39:19to toggle the clock five times or
- 9:39:21through five clock cycles so I don't
- 9:39:22have to, you know, keep punching it. But
- 9:39:25uh, it's fine. It gets the job done, I
- 9:39:26guess. Um, so that looks good.
- 9:39:29Now we get into the the loop part here
- 9:39:31where we subtract one display it and
- 9:39:34then after that we either repeat that
- 9:39:36that those two instructions or we end
- 9:39:38the program. So uh basically what we're
- 9:39:41going to do is we're going to do the
- 9:39:43sub. So this should end with uh a being
- 9:39:45one less than 15. So uh 1111 is 15. We'd
- 9:39:51expect 11 1 0 to represent 14. And then
- 9:39:54since we're doing 15 minus one, we'd
- 9:39:56also expect that the value one should
- 9:39:58probably get loaded into V register uh
- 9:40:00to do the subtraction. So let me pulse
- 9:40:03the clock five times.
- 9:40:06And you can see both these things are
- 9:40:07true. So we have 11 1 in the A register
- 9:40:11which is 14. Uh we accomplish that by
- 9:40:14loading one into the B register and
- 9:40:15subtracting it. And uh that looks good.
- 9:40:20And then
- 9:40:22now we check this display a. So we
- 9:40:24should expect 14 to just end up on the
- 9:40:26display register because we've done our
- 9:40:28subtraction. Uh we've done our
- 9:40:29subtraction. So we should show this to
- 9:40:30the user. So let's pulse the clock
- 9:40:34through this next instruction. And you
- 9:40:36can see that's the exact case. We have
- 9:40:3814. And now uh let's do a little bit of
- 9:40:40checking. Um now we should expect uh
- 9:40:44this jump zero to not to be a noop. uh
- 9:40:47we should not end up jumping to this
- 9:40:49address right here. So if I pulse the
- 9:40:52clock five times uh what the what should
- 9:40:54happen afterwards is the program counter
- 9:40:57should equal 0 uh 1111.
- 9:41:01And that 011
- 9:41:03is going to tell us to just jump back up
- 9:41:05and repeat the loop. So let me pulse the
- 9:41:07clock five times.
- 9:41:12And we can see our program counter is
- 9:41:14011 as we expect. So we uh did nothing
- 9:41:18with this jump zero instruction. And
- 9:41:20then this this 011 0 or sorry this 0111
- 9:41:27011. Yes. Sorry. I was like did I say
- 9:41:29one too many ones? Uh is just a jump
- 9:41:31back up to
- 9:41:34uh our
- 9:41:36our subtract loop. So I'd expect the
- 9:41:39program counter to go to um
- 9:41:43address 4 afterwards of this. Let's
- 9:41:46pulse it and see ourselves.
- 9:41:49And we can see exactly that our program,
- 9:41:50our program counter is address 4. And so
- 9:41:53then we repeat this uh this loop cycle.
- 9:41:56So I also built an auto play because I
- 9:41:57don't want to trace through this entire
- 9:41:58program. I built an auto play that'll
- 9:42:01just keep pulsing the clock like really
- 9:42:03fast, low, and high. Uh and you can
- 9:42:05control the speed here.
- 9:42:07Um and basically I'm just going to crank
- 9:42:09the speed all the way up. And we should
- 9:42:10see that we just count down all the way
- 9:42:13to zero.
- 9:42:20one and we get to zero and we end up
- 9:42:24executing this halt instruction which
- 9:42:27remember it just blocks the program from
- 9:42:29doing anything further. So you can kind
- 9:42:30of see if I scroll to the bottom of the
- 9:42:32logs here. Um, we set this halt line and
- 9:42:35then there's a rising edge of the clock,
- 9:42:36but because the clock is connected to
- 9:42:39the value of the halt line, it actually
- 9:42:41blocks the the clock the true clock
- 9:42:43value from propagating out to the rest
- 9:42:45of the computer. And so that's how we
- 9:42:47block execution.
- 9:42:49Okay, so this is pretty cool. We wrote a
- 9:42:52simple program uh and it actually does
- 9:42:54something. uh it it it we chain together
- 9:42:58these very simple operations
- 9:43:01and uh use that to build a program that
- 9:43:03does something. And this is cool because
- 9:43:06not only like we started from scratch
- 9:43:08and that we implemented these micro
- 9:43:10instructions ourselves and each one of
- 9:43:13those required like very granular uh
- 9:43:16changes to the state of our system. But
- 9:43:19then when you cycle change uh bundle a
- 9:43:22few of those changes into what we called
- 9:43:23an instruction, the instruction can do
- 9:43:25something a little bit powerful. Not
- 9:43:27really that meaningful on its own, but
- 9:43:29something just a little bit like one
- 9:43:31action of like move this value from here
- 9:43:33to here or you know show this value on
- 9:43:36the display or or maybe jump to this
- 9:43:38other instruction instead of executing
- 9:43:39the one that's below me. Um, and so on
- 9:43:42on their own, each of those instructions
- 9:43:44are kind of trivial, but then when we
- 9:43:46chain them together, we were actually
- 9:43:48able to write a program
- 9:43:50um that actually does something
- 9:43:52interesting and and has a termination
- 9:43:54condition. And what's also pretty cool
- 9:43:56about it is like that program is encoded
- 9:43:59with literally just zeros and ones. And
- 9:44:02a few hours ago, this would have been
- 9:44:04gibberish to you. Uh this this these
- 9:44:07combinations of zeros and ones would
- 9:44:08have had no intrinsic value. But it
- 9:44:11turns out for this specific computer
- 9:44:13we've designed, this exact ordering of
- 9:44:16zeros and ones produces a program that
- 9:44:18does something very interesting to us.
- 9:44:21We've constructed is trivial, but it
- 9:44:23paints a very interesting uh portrait of
- 9:44:26the capabilities of our computer. And
- 9:44:29what I'd like to do is you can probably
- 9:44:31imagine the full set of what we can
- 9:44:33really do with these eight or so
- 9:44:35instructions is fairly limited,
- 9:44:37especially because we only have 16
- 9:44:39different spots in RAM. So the programs
- 9:44:41you write are inherently constrained um
- 9:44:45by the the limitations of how we've
- 9:44:47constructed our computer. More modern
- 9:44:49computers have a lot more RAM and a lot
- 9:44:51more instructions, and we'll talk about
- 9:44:53that shortly. But, uh, I'd like to try
- 9:44:56build out something that does something
- 9:44:58a little more complicated than counting
- 9:45:01down from 15. Let's see what the most
- 9:45:03complicated thing we can do with this
- 9:45:05instruction set that we have is. So, um,
- 9:45:08let's go over here to Wikipedia. So, a
- 9:45:11sequence, just as a quick definition,
- 9:45:13uh, a sequence in mathematics, a
- 9:45:16sequence is a sequence of integers. Uh,
- 9:45:19that's kind of a circular definition,
- 9:45:21but it's literally just a list of
- 9:45:22numbers. And um there's one sequence in
- 9:45:26in particular that's fairly interesting
- 9:45:29and it's called the Fibonacci sequence.
- 9:45:31So let's read the definition. In
- 9:45:33mathematics, the Fibonacci sequence is a
- 9:45:36sequence in which each element is the
- 9:45:39sum of the two elements that precede it.
- 9:45:42So basically we start with the number
- 9:45:45zero and one and then every element
- 9:45:48after that is just the sum of the
- 9:45:51previous two elements. So here we have 0
- 9:45:54and one. The sum of that is one. So
- 9:45:56that's our next number. And then if we
- 9:45:58have 1 + 1 as the last two elements, the
- 9:46:01sum of those is two. And then the last
- 9:46:03two elements becomes one and two. The
- 9:46:05sum of which is three. And then the last
- 9:46:08two elements are now two and three. The
- 9:46:10sum of which becomes five. And you can
- 9:46:12see that it keeps going. We have 3 + 5
- 9:46:15is 8. 8 + 5 is 13. 13 + 8 is 21. 21 + 13
- 9:46:20is 34. And uh it keeps going. It grows
- 9:46:24unbounded. And what I'd like to do is
- 9:46:27build a program on our computer that can
- 9:46:30actually count out the Fibonacci
- 9:46:31sequence for us. And it turns out the
- 9:46:34instruction set that we have with our
- 9:46:36computer is totally capable of doing
- 9:46:38exactly this. Um and let's also tab out
- 9:46:42and think about uh something more
- 9:46:44abstract in mathematics and computer
- 9:46:47science. Uh like what is an algorithm? I
- 9:46:50remember when I was learning
- 9:46:51computation, kept on hearing talks about
- 9:46:53algorithms. There's classes you take
- 9:46:55with the computer science degree.
- 9:46:57There's one that most people take called
- 9:46:59data structures and algorithms. Um, and
- 9:47:01I remember like we we kind of talk about
- 9:47:04like you know like what are social media
- 9:47:05algorithms? Like like what's what's the
- 9:47:08logic behind that? Um, and an algorithm
- 9:47:11has a surprisingly simple definition.
- 9:47:14It is a process or set of rules to be
- 9:47:17followed in calculations or other
- 9:47:18problems solving operations, especially
- 9:47:20by a computer. I like the Wikipedia
- 9:47:22definition a little bit better. So, I'm
- 9:47:23going to go over here. Um, Wikipedia
- 9:47:27says, "In mathematics and computer
- 9:47:29science, an algorithm is a finite
- 9:47:32sequence of mathematically rigorous
- 9:47:34instructions typically used to solve a
- 9:47:36class of specific problems or to perform
- 9:47:38a computation.
- 9:47:41Algorithms are used as specifications
- 9:47:42for performing calculations and data
- 9:47:44processing. More advanced algorithms can
- 9:47:47use conditionals to divert the code
- 9:47:49execution through various routes and
- 9:47:52deduce valid inferences. So this is an
- 9:47:54interesting definition. Uh I think it's
- 9:47:57a more interesting one for a few
- 9:47:58reasons. Um first off we saw that uh we
- 9:48:03just performed a computation of what we
- 9:48:05decided earlier. the counting down was
- 9:48:07just a series of computations. And then
- 9:48:11uh that was a form of data processing,
- 9:48:13but like that's not really what the
- 9:48:14definition is poking at here. But what's
- 9:48:16also interesting is uh it says advanced
- 9:48:19algorithms can divert execution through
- 9:48:21various routes. And
- 9:48:24um this is kind of the branching we
- 9:48:26discovered with our our jump zero and
- 9:48:29our jump carry instructions that allow
- 9:48:31us to introduce some like decision
- 9:48:33making into our code. So what I want to
- 9:48:36do is write an algorithm for
- 9:48:38implementing this Fibonacci sequence and
- 9:48:41then go ahead and actually implement it.
- 9:48:43Um I think a good starting point is
- 9:48:46coming back to this very simple program
- 9:48:48that we had earlier and and writing an
- 9:48:50algorithm for it. So uh if we if we
- 9:48:53wrote an algorithm for this program uh
- 9:48:55what would it look like about exactly
- 9:48:58what we did to implement our our
- 9:49:01instructions here? um we have to be very
- 9:49:04concrete and formal with what we said
- 9:49:07and uh specify everything very clearly.
- 9:49:09We have to tell the computer because the
- 9:49:10computer uh especially the one we built
- 9:49:13is kind of quote unquote dumb and it'll
- 9:49:15only tell you it'll only do exactly what
- 9:49:17you tell it to do. So what we kind of
- 9:49:19did is we said um we had some variable
- 9:49:22called the counter. We'll just say like
- 9:49:24let counter equals 15. And in the
- 9:49:28algorithm, the algorithm is kind of
- 9:49:29independent of the hardware of the
- 9:49:31computer itself. When we went to
- 9:49:33implement this algorithm in machine
- 9:49:35code, uh our counter was kind of the A
- 9:49:38register. That was kind of the register
- 9:49:39that held the primary state of the
- 9:49:42program at any given time. And we pretty
- 9:49:45much said while the counter was greater
- 9:49:48than or equal to um sorry while the
- 9:49:51counter is greater than zero
- 9:49:54what we did is we subtracted one from
- 9:49:56the counter. So we said counter equals
- 9:49:58counter minus one and then display
- 9:50:01counter
- 9:50:03and basically this this syntax I'm using
- 9:50:06here is an indentation. So like every
- 9:50:08time this condition is true, everything
- 9:50:10that's executed after it or everything
- 9:50:12that's indented after it will be
- 9:50:13executed and then it'll check the
- 9:50:16condition again. It'll come back up
- 9:50:17here. Um that's similar to the the
- 9:50:19jumping we have in our code. And then
- 9:50:22once we get out of this while loop, so
- 9:50:24well after the only way we can get out
- 9:50:26of this while loop is if the counter is
- 9:50:28not greater than zero. And since we're
- 9:50:30counting down by one, that means it
- 9:50:32necessarily is equal to zero. And so
- 9:50:34that means once we get past here, we
- 9:50:36just end and we're done. So this is a
- 9:50:38very formal specification
- 9:50:41um of our counter program. Let's try
- 9:50:43doing for the Fibonacci sequence. So let
- 9:50:45me clear it out here.
- 9:50:47So in general we said the Fibonacci
- 9:50:50sequence like for any number it is the
- 9:50:53sum of the previous two numbers. So like
- 9:50:57if we let uh let's define like f of i to
- 9:51:01be the i
- 9:51:05uh number in the Fibonacci sequence.
- 9:51:09So we can pretty much say that uh let's
- 9:51:13say it's zero. We've been learning
- 9:51:14everything starting with zero. So f of
- 9:51:16zero is zero. The first number in the
- 9:51:19sequence is zero and the second number
- 9:51:21in the sequence is one. And then for
- 9:51:23every other number, we pretty much say
- 9:51:25that f of n is equal to the sum the nth
- 9:51:29fibonacci number is equal to the sum of
- 9:51:32the number behind it and the number
- 9:51:34that's two behind it.
- 9:51:38And so this is kind of what we call a
- 9:51:39recursive definition where the value of
- 9:51:42the Fibonacci sequence, the value of f
- 9:51:44of n depends on recursive calls to f of
- 9:51:48n. Um, so that makes sense for like us
- 9:51:50to rebound English, you know, this is
- 9:51:52just saying start with the numbers 0 and
- 9:51:54one and then after that for any other
- 9:51:57arbitrary position in the Fibonacci
- 9:51:59sequence, go figure out what the two
- 9:52:01Fibonacci numbers before are and then
- 9:52:03add those together and that tells you
- 9:52:05what the current Fibonacci number is.
- 9:52:07Assuming Ed is the nth number in the
- 9:52:10sequence that you're interested about.
- 9:52:12Um, our computer we've built here
- 9:52:14obviously can't deduce that. uh we kind
- 9:52:16of have to spill that out in a slightly
- 9:52:18different way. So what we're going to do
- 9:52:22um is let's go figure out how we can
- 9:52:24actually build this. So we know that we
- 9:52:26have these instructions to work with and
- 9:52:29we also have uh spots in data memory. So
- 9:52:31I'm going to go ahead and clear out our
- 9:52:33old program here.
- 9:52:36And basically
- 9:52:39I'm going to define I'm going to reserve
- 9:52:41two spots in memory. Let's just do the
- 9:52:43last two spots in RAM to represent um
- 9:52:46like
- 9:52:54the f of n minus one and the f of n
- 9:52:57minus2 here. So like the last two values
- 9:53:00in RAM will always represent uh the last
- 9:53:02two numbers in the Fibonacci sequence.
- 9:53:04And then if we can get those correctly,
- 9:53:07uh if we can always guarantee that to be
- 9:53:09true, then this means to find the next
- 9:53:12Fibonacci sequence. Well, to start, we
- 9:53:14need to load the values like zero and
- 9:53:17one into RAM here. And you can imagine
- 9:53:19that's pretty straightforward to do. But
- 9:53:21then afterwards to get the next
- 9:53:23Fibonacci number, all we need to do is
- 9:53:25add the values at these two addresses
- 9:53:27together. That gives you the next
- 9:53:29Fibonacci number. You can display that.
- 9:53:32And then once you have the next
- 9:53:33Fibonacci number, the n minus one's
- 9:53:36number becomes the n minus2 number. So
- 9:53:39you can replace this number right here
- 9:53:42with what's there because we no longer
- 9:53:43care about this one for the next
- 9:53:44Fibonacci sequence uh number. So we'd
- 9:53:48like pretty much say that this becomes a
- 9:53:50one and then this value here becomes
- 9:53:54what the result of the alou was which
- 9:53:56also happens to be one because that is
- 9:53:58what 0 plus one is. And so let's do one
- 9:54:01more practice of that. Um to get if this
- 9:54:04is our n minus2 and n minus one numbers
- 9:54:07then the current the f of n i i.e. the
- 9:54:10next Fibonacci sequence number would be
- 9:54:121 + one. So we could add these two
- 9:54:14values together. Um we get the value
- 9:54:17two. We can store that somewhere else in
- 9:54:20RAM temporarily. And then this number
- 9:54:23would need to we want to throw this away
- 9:54:25and shift this one up. And then now
- 9:54:28write our two into this spot right here.
- 9:54:32And so now we have one two as our last
- 9:54:34two numbers in the Fibonacci sequence.
- 9:54:36And we obviously want to display that to
- 9:54:37the user in there as well. Um
- 9:54:41and so now if we do that one more time
- 9:54:43just for sake of tying it together
- 9:54:45because we worked with zeros and one so
- 9:54:46maybe the shifting is not clear. But we
- 9:54:49would to get uh if we have these as our
- 9:54:51last two numbers in the Fibonacci
- 9:54:52sequence for wherever our program's at,
- 9:54:54we add these two values in RAM together
- 9:54:56using the add instruction. Um and then
- 9:55:00we'd get three as the result. We can
- 9:55:02store that somewhere arbitrary in
- 9:55:03memory. And then we need to wipe this
- 9:55:06one away and shift this two up and then
- 9:55:10bring this three down because that's now
- 9:55:12our last Fibonacci number. Um, so if we
- 9:55:15kind of think about how we want to
- 9:55:17specify this as an as an algorithm, um,
- 9:55:21let's just call this value like a and
- 9:55:25this value b. And a and b are always the
- 9:55:29last two numbers in the Fibonacci
- 9:55:31sequence. So what we'd want to do is
- 9:55:34pretty much start by getting the values
- 9:55:37zero and one into these spots and rams.
- 9:55:41Um because this is uh the the first two
- 9:55:44numbers in the Fibonacci sequence,
- 9:55:47we kind of know that RAM is all zeroed
- 9:55:49out. So the value here will already be
- 9:55:51zero because of like how our program
- 9:55:53instantiates. Like we're just going to
- 9:55:55say that RAM is all zeros.
- 9:55:57But we need to get a one into here. So
- 9:56:00that's pretty straightforward. Um
- 9:56:04like pretty much we can say a is already
- 9:56:06zero. Then we can say B becomes one. And
- 9:56:10then what we'd like to do is uh
- 9:56:16add at any step the two values together.
- 9:56:19So we make a new value called C and C is
- 9:56:23equal to A plus B.
- 9:56:25And then we can display C to the user
- 9:56:29because that's the next Fibonacci
- 9:56:30number. And then we need to say that uh
- 9:56:33A becomes B and B becomes C. And that's
- 9:56:37how we kind of shift up one here. And um
- 9:56:41after that we can pretty much jump back
- 9:56:45to uh jump back to uh the C= A plus B
- 9:56:51instruction. Um and so what we do here
- 9:56:54is we we get our first two Fibonacci
- 9:56:56values and then we begin a cycle of
- 9:56:59calculating uh the next Fibonacci
- 9:57:02number. So our every time we loop
- 9:57:04through and jump back up to this, we're
- 9:57:06trying to find the next Fibonacci
- 9:57:07sequence, assuming A and B are the last
- 9:57:10two Fibonacci numbers we worked with. So
- 9:57:12by definition of the Fibonacci sequence,
- 9:57:14we can trivially compute the next value
- 9:57:16just by adding A and B together. And
- 9:57:19then that's the next Fibonacci number.
- 9:57:21We display that to the user. And then
- 9:57:24now that we have three Fibonacci
- 9:57:25numbers, we throw away the oldest. The
- 9:57:28oldest is A. And so then B becomes the
- 9:57:31older one. Now, so uh what was
- 9:57:34previously in the Bcomes assigned to A
- 9:57:37and then what was in B is now our newest
- 9:57:41Fibonacci number which is the one we
- 9:57:42just calculated up here. So we can set
- 9:57:44that equal to the value of C. Um and so
- 9:57:47this is pretty straightforward. Uh let's
- 9:57:51actually go ahead and this is like kind
- 9:57:53of our formal algorithm. Um so I guess
- 9:57:56like if we wouldn't make this fully
- 9:57:58algorithm uh we could say like uh wall
- 9:58:02like one is equal to one. So just this
- 9:58:07is wall one is always equal to one. So
- 9:58:09this will always be true
- 9:58:11and
- 9:58:15this is kind of what the uh the the code
- 9:58:17would look like. So this would keep
- 9:58:18counting Fibonacci sequence numbers
- 9:58:20forever. We start with uh like you can
- 9:58:23say like let a start with zero, let b
- 9:58:26start with one and then wall one equals
- 9:58:28one is just kind of a little hack around
- 9:58:32like the algorithm specification to say
- 9:58:34like do this over and over. And what we
- 9:58:36do over and over is add our previous two
- 9:58:37Fibonacci numbers together.
- 9:58:40Show that to the user and then update
- 9:58:43what our last two Fibonacci numbers are.
- 9:58:45So throw away that now that we have
- 9:58:46three numbers A, B, and C. uh shift it
- 9:58:50so that what was previous like uh what's
- 9:58:53currently B and C becomes into A and B.
- 9:58:55So we set A to B and then B to C. So
- 9:59:00let's think about how we can implement
- 9:59:02this using our instruction set that we
- 9:59:04have available to us on this computer.
- 9:59:06So we already know by assumption just
- 9:59:09that the value in uh in a uh is zero. So
- 9:59:14what we need to do is get the value one
- 9:59:16here. So I'm going to load an immediate
- 9:59:18one
- 9:59:20um into the A register. So this just
- 9:59:22says let me not bold here. Register a
- 9:59:25equals 1. And then
- 9:59:29uh
- 9:59:30afterwards we can go ahead and get
- 9:59:34straight into the um branching logic. So
- 9:59:40what that would look like is we need to
- 9:59:43uh sorry we actually need to take the
- 9:59:44value we have and store it into register
- 9:59:47uh store it into this address value. So
- 9:59:50we take the one that we have and store
- 9:59:52that into address 15. So this would just
- 9:59:55say like b equals 1.
- 10:00:00And then now what we can do is go ahead
- 10:00:02and start the sequence of adding these
- 10:00:05two numbers together. So to add two
- 10:00:07values in RAM, we need to load one of
- 10:00:09the values into the A register and then
- 10:00:12load one of the other and then do an add
- 10:00:14operation with uh the second value. So
- 10:00:17what we can do is load a with 14
- 10:00:21and then so it just says like register a
- 10:00:25equals a. Uh there's a differentiation
- 10:00:28here. Uh register A, you already know
- 10:00:29what register A is. The A down here is
- 10:00:32just a variable that we are calling. uh
- 10:00:34variable meaning uh we will say whatever
- 10:00:36is in this uh we're going to call a and
- 10:00:39that value can change it can vary so
- 10:00:42it's called a variable um apologies I
- 10:00:45probably use that several times without
- 10:00:46necessarily clarifying what a variable
- 10:00:48is but uh forgive me for that and then
- 10:00:52now we can add whatever is in 15
- 10:00:56so then it pretty much says that
- 10:00:58register A is equal to A plus B so
- 10:01:02that's exactly what we want and And that
- 10:01:03that's a plus b is the c value we've
- 10:01:06described here. So let's denote let's
- 10:01:09let c equal this equal um address 13 in
- 10:01:13RAM. So let's go ahead and just uh we
- 10:01:16want to take that value uh the output
- 10:01:18here and store it in C. But before we do
- 10:01:20that we want to show this to the user.
- 10:01:22So we can do an out here and then we can
- 10:01:25store the value C into the correct
- 10:01:27memory address that we want which is
- 10:01:291101.
- 10:01:32And
- 10:01:34um the ordering between these two
- 10:01:36operations actually does not matter.
- 10:01:38It's kind of up to us that's how we want
- 10:01:39it. Uh so you know you could have done
- 10:01:41you could have stored it and then
- 10:01:42written the out. Uh and the reason we
- 10:01:44can do that is because uh store a and
- 10:01:48out neither of those change what's in
- 10:01:51the A register. They just do some action
- 10:01:53based on what's in the A register. So
- 10:01:55this add instruction over here actually
- 10:01:58mutates the value in the A register. The
- 10:02:00following two have no effect to the A
- 10:02:02register. They're independent operations
- 10:02:04we'd like to do based on whatever was
- 10:02:06the outcome of this ad result here. So
- 10:02:08the ordering is trivial. It's it's not
- 10:02:10perceivable to the human and does not
- 10:02:12affect the runtime correctness of our
- 10:02:14program. Um assuming everything else is
- 10:02:16right here. Um so now we have our like
- 10:02:20last three uh Fibonacci numbers like A
- 10:02:23is the oldest, B is the second like in
- 10:02:27the middle and then C is the newest. Um
- 10:02:31and so what we need to do then is kind
- 10:02:33of throw away this A, move the value in
- 10:02:35B into A and then move the value from C
- 10:02:38into B. So let's start by uh taking the
- 10:02:42value here and then getting it into
- 10:02:44here. So all we can need to do to get
- 10:02:46the value from B into A is do a load A
- 10:02:51uh of 15. So get the value that's in B
- 10:02:53into the A register and then a store A
- 10:02:55where we store it into this address. Uh
- 10:02:57so that's how we move the value that's
- 10:02:59how we effectively move the value which
- 10:03:01overwrites the A with B. Um so what we
- 10:03:05do to do that is a load A5.
- 10:03:09So we say like register a equals b and
- 10:03:12then uh we can store a into 14 and that
- 10:03:17just says a equals what was like a is
- 10:03:21now what b uh is and then the last thing
- 10:03:24we need to do is get the value from c
- 10:03:28into the into the b address bot. So I
- 10:03:31can load into register a this address
- 10:03:3413. So it says register A equals C. And
- 10:03:38then I can use the same trick that we
- 10:03:40did to overwrite A uh to overwrite B. So
- 10:03:43I can store that into 15.
- 10:03:56Um and then the last thing we need to do
- 10:03:59to continue this loop is to we've so
- 10:04:01this is calculated given Fibonacci
- 10:04:04numbers A and B. Um everything we've
- 10:04:07done here
- 10:04:09uh
- 10:04:13calculates
- 10:04:15the next Fibonacci number. So now that
- 10:04:18we've calculated one Fibonacci number,
- 10:04:20let's just jump back up here and jump to
- 10:04:23instruction two and execute the next uh
- 10:04:26the same set of operations to figure out
- 10:04:29the next Fibonacci number. So I can just
- 10:04:31jump to two
- 10:04:33uh one zero
- 10:04:37and then this says continue. Um so if I
- 10:04:40kind of map that out, these are our
- 10:04:42instructions.
- 10:04:44Um we can kind of see that we let a we
- 10:04:47get this first one for free. This a is
- 10:04:49equal to zero. We get that for free just
- 10:04:51because we already know that RAM
- 10:04:53defaults to zero values. So then the
- 10:04:56next one that we have to do ourselves is
- 10:04:57getting the value letting B equal one.
- 10:04:59And that's exactly what we're doing um
- 10:05:02in these two instructions right here.
- 10:05:03We're getting the value one into
- 10:05:05register A and then writing that into B.
- 10:05:08That's how we do this. We have to do two
- 10:05:09instructions because of how restrictive
- 10:05:11our instructions that we have defined
- 10:05:13are. But they exist like there's enough
- 10:05:15instructions to do what we want to do.
- 10:05:17And then you can kind of see that uh
- 10:05:20this is our loop part. But so C equals A
- 10:05:23plus B is implemented right here because
- 10:05:26we load A into one of the ALU operands
- 10:05:28and then B into the other ALOU operands
- 10:05:30and we add those together and we get the
- 10:05:33value C and then we store that uh into
- 10:05:36the value C. Sorry. So this is these
- 10:05:39three instructions implement C equals A
- 10:05:41plus B. Then the display C is trivially
- 10:05:44implemented with the out instruction.
- 10:05:47And then
- 10:05:50these four instructions implement the
- 10:05:53shifting um of replacing
- 10:05:57um A and B uh with B and C.
- 10:06:02And this um program if we let it run
- 10:06:06will count Fibonacci numbers for us. So,
- 10:06:09what I've already gone ahead and done is
- 10:06:11kind of loaded some of these values into
- 10:06:13RAM. Let me go ahead and clear
- 10:06:16uh this because that's not correct.
- 10:06:20And if I reset everything here, let's go
- 10:06:22ahead and run the analyze program and
- 10:06:25see what we have. And so, uh, if I'm
- 10:06:28matching up what is over here with over
- 10:06:30here, I see a load immediate one, a
- 10:06:33store a 15, a load a 14, an ad with 15,
- 10:06:37a store with 13, a display, a load a
- 10:06:41with 15, a store a with 14, a load a of
- 10:06:4613, and a store a with 15, and then a
- 10:06:48jump back up to two. So, this is the
- 10:06:51correct program. I didn't specify the
- 10:06:52RAM values here, uh, but they are
- 10:06:55punched in here. Um,
- 10:06:58so let's go ahead and just let it rip.
- 10:07:00Uh, I'll autoplay this, but uh, the
- 10:07:03Fibonacci sequence, we can I'll type out
- 10:07:05some of the numbers so we know what to
- 10:07:06expect. Um, we know that we start with
- 10:07:08zero and one. So, we'd expect to see
- 10:07:10like one and then, uh, like a a two and
- 10:07:15then three, five, five, 8, 13, 21, 34,
- 10:07:2455.
- 10:07:2589. Uh, and so on and so on. Um, so
- 10:07:28let's just let it rip and see what
- 10:07:30happens. Uh, one, that looks good. Two,
- 10:07:34that looks good. Three looks good.
- 10:07:38Five looks good.
- 10:07:41Eight looks good.
- 10:07:4313 looks good.
- 10:07:4621.
- 10:07:4834 looks good. 55 looks good. 89 looks
- 10:07:54good. And um what we're kind of doing is
- 10:07:58is verifying the program's correctness
- 10:07:59just by letting it run and see. Uh
- 10:08:01that's not the most sophisticated
- 10:08:04method. Uh but you know, for the sake of
- 10:08:06not boring and I can already verify that
- 10:08:08it does look correct. Uh that's fine. Um
- 10:08:12so
- 10:08:14what's interesting here is I don't have
- 10:08:15any end condition. I intentionally did
- 10:08:18not add a halt here uh just for fun
- 10:08:21because I want to see like kind of what
- 10:08:22happens with our computer. So we know
- 10:08:24that we operate on 8bit values and the
- 10:08:28biggest value uh we can represent in 8
- 10:08:30bits um is the value 1111 1111 and
- 10:08:36that's equal to 1 + 2 + 4 + 8 + 16 + 32
- 10:08:42+ 64 + 128. So 255
- 10:08:46if every bit position is enabled that
- 10:08:49gives us the binary string of all ones
- 10:08:52and that is the maximum value we can
- 10:08:54represent here and that's 255. So what's
- 10:08:57interesting is our program
- 10:09:00will work up to 233. If I continue it uh
- 10:09:04there should be no issue but then the
- 10:09:05next value after 233 is 144 + 233 which
- 10:09:10gets you 377.
- 10:09:12But we actually can't represent that in
- 10:09:14eight bits. Um, and so it turns out what
- 10:09:18happens is there's like overflow. But
- 10:09:20the computer we saw when we built the
- 10:09:22ALOU, uh, if you have an ALOU operation
- 10:09:26that can't be stored in eight bits,
- 10:09:29it'll only capture the rightmost eight
- 10:09:31bits there. So,
- 10:09:34um, what this means is that our program
- 10:09:36will not break. the computer will not
- 10:09:37somehow explode or anything crazy like
- 10:09:40that, but we won't see 233. Uh we will
- 10:09:43go from 144 to 233 to something that is
- 10:09:48less than 377. Um and it's unclear just
- 10:09:51based on whatever the binary string is,
- 10:09:53the rightmost 8 bits of 377. Um what
- 10:09:57that is. So if I let this rip a little
- 10:09:59bit longer, uh let's go ahead and see
- 10:10:02exactly that.
- 10:10:0789 144 233 and this is where we should
- 10:10:13fail. 121 is what we just happen to oops
- 10:10:16happen to get back to. Um and the the
- 10:10:18computer won't break. It's just a matter
- 10:10:20of fact that we say like for our ALU the
- 10:10:23way it is designed is such that it
- 10:10:25assumes that the result is always
- 10:10:27storeable in uh an 8bit value but that's
- 10:10:31not guaranteeable. Um and we have the
- 10:10:34carry flag for detecting this entirely.
- 10:10:37So when we did go from
- 10:10:40um 233 to 377, if I had paused the
- 10:10:44program, we would have seen that the
- 10:10:45carry flag was set. So what we could
- 10:10:47have done is recognize that hey, this is
- 10:10:49the largest Fibonacci value our computer
- 10:10:52can handle. And so we could have done uh
- 10:10:54similar to how we used the jump zero to
- 10:10:56end the program in the previous uh
- 10:10:59program uh in the counting sequence.
- 10:11:02What we could have done is used a jump
- 10:11:03carry to end the program here when we
- 10:11:05know we get to the biggest value that is
- 10:11:07represented uh representable. I just
- 10:11:10chose not to do that because RAM was
- 10:11:11running out of space. Um
- 10:11:14but you know, you can imagine if this
- 10:11:16was something more defensible, uh you
- 10:11:18would probably want to do that. Um but I
- 10:11:21think this is probably one of the more
- 10:11:23complicated programs our simple computer
- 10:11:25can make. Um, but I'd also like to
- 10:11:28remark on the fact that
- 10:11:30uh this is pretty powerful. Like we saw
- 10:11:32a combination of zeros and ones for a
- 10:11:34counting program. And it turns out when
- 10:11:37you interpret those as instructions for
- 10:11:38this computer, they do something
- 10:11:40interesting. And now we're seeing
- 10:11:41something pretty interesting here where
- 10:11:43this combination of zeros and ones does
- 10:11:46something totally unrelated that's also,
- 10:11:48you know, a little more powerful and
- 10:11:50very interesting. So this is really
- 10:11:53cool. um like something that was just a
- 10:11:56few hours ago nonsense to you is now
- 10:11:59something that you can you know you can
- 10:12:00look at each of these positions in RAM
- 10:12:02and figure out what the what the
- 10:12:05interpretation is and if RAM was loaded
- 10:12:08to that value on some hypothetical
- 10:12:10computer uh that's what the computer
- 10:12:12would execute. Um,
- 10:12:16so that technically concludes the
- 10:12:18explanation of how we built this
- 10:12:20computer and everything should be clear
- 10:12:22from a like ground up like and we'll
- 10:12:24recap everything we've done eventually,
- 10:12:26but um it it wouldn't be right for me
- 10:12:29just to end here. Like I think there's a
- 10:12:31lot of questioning around like we've
- 10:12:33invented this computer but like why do
- 10:12:35we design the instructions the way they
- 10:12:36are and like why do we architect it the
- 10:12:38way we architected it and like how did I
- 10:12:41know to build this computer? Um, these
- 10:12:44are all interesting questions and I
- 10:12:47actually built this computer physically.
- 10:12:49So, uh, the simulator I have here is
- 10:12:52cool and all, but I was very interested
- 10:12:54when I learned this in school. And I
- 10:12:56found the series online of someone who
- 10:12:58has a full instructional set, which I'll
- 10:13:00link because it's an awesome series that
- 10:13:02I highly recommend watching. And in this
- 10:13:04series, uh, Ben Eer, his name is, uh,
- 10:13:08builds this computer, this conceptual
- 10:13:10computer, uh, from scratch. So, uh, I
- 10:13:13actually built one and I can show it
- 10:13:16here. This is what mine looks like in
- 10:13:18person. Um, it's a bit messy and there's
- 10:13:20a lot going on. So, let's let me give a
- 10:13:23few, uh, few bits few minutes of context
- 10:13:25to explain what's happening here. So, if
- 10:13:28you look just on the display, uh, you
- 10:13:30can see this program is just doing
- 10:13:32counting down. Um, my video, I guess I
- 10:13:35just happen to start it at the number
- 10:13:3671. And then by the time it loops
- 10:13:39around, uh, looks like it's down to like
- 10:13:41something like what was that? 59. Um,
- 10:13:44but there's a lot of components here.
- 10:13:46So, let's break it down.
- 10:13:49The first is this clock up here. Um, and
- 10:13:53I guess as you as I walk through this,
- 10:13:55you'll see that the way this is
- 10:13:56physically built, i.e. the layout of all
- 10:13:58the components is virtually identical to
- 10:14:01what I drew on my iPad uh throughout the
- 10:14:04video. And we'll see that like that also
- 10:14:07came from somewhere. Um, I guess the
- 10:14:09ordering of the components physically
- 10:14:10doesn't matter, but I I kept the
- 10:14:12continuity there to help uh make the
- 10:14:14understanding easier. So, this is the
- 10:14:17clock module. Uh, you can kind of see
- 10:14:20this is the value of the clock and it's
- 10:14:22just constantly pulsing. This thing up
- 10:14:25here is a little dial and if I were to
- 10:14:27twist it, I could increase or decrease
- 10:14:29the uh speed of the clock. And then this
- 10:14:32clock is just always pulsing up and
- 10:14:34down. um kind of like the uh you know
- 10:14:37the autoplay mode I had in our
- 10:14:38simulator, but you don't always want to
- 10:14:41auto play. Sometimes you want to step
- 10:14:43through specific high low clock cycles.
- 10:14:45So there's a switch over here and if you
- 10:14:48switch that it turns off the automatic
- 10:14:50clock and lets you just pulse the clock
- 10:14:52using this button right here. Um so
- 10:14:54every time you push the button it'll go
- 10:14:56from low to high and vice versa. So
- 10:14:57that's pretty cool. That's the clock.
- 10:15:00Here's our program counter right here.
- 10:15:02You can kind of see it's counting up. uh
- 10:15:04if you repeat those binary numbers and
- 10:15:06then it jumps uh back down. So it's
- 10:15:08probably like the subtracting loop is a
- 10:15:11loop. We saw that in our subtracting
- 10:15:12program. And then these are the flags
- 10:15:15registers. So uh the wiring gets tricky
- 10:15:18to trace here, but uh you can kind of
- 10:15:20see that there's this these wires here.
- 10:15:22Uh this is a register chip and that's
- 10:15:24the it seems to be the output of the
- 10:15:26register chip and the input on top comes
- 10:15:28from this wire right here. Um and this
- 10:15:31is the ALU. So let's talk about that
- 10:15:33next. This is the mass of ALOU. We have
- 10:15:37uh the A register right here. And these
- 10:15:39lights show the value of the A register.
- 10:15:41And then we have the
- 10:15:43um B register should be right here. And
- 10:15:48then this light right here. Uh I can't
- 10:15:51quite recall if it's showing whatever's
- 10:15:52on the B register or the output of the
- 10:15:54ALU. And then you can kind of see that
- 10:15:57this thing in the middle is the bus. So
- 10:15:59the same way, here's our connection of
- 10:16:00the ALU to the bus, the B register to
- 10:16:03the bus. Here's the ALU to the bus.
- 10:16:05Here's the A register to the bus. And
- 10:16:07here's the program counter to the bus.
- 10:16:08And then these lights up here show you
- 10:16:11the value in binary that's on the bus at
- 10:16:13any given time.
- 10:16:15Below the ALOU, we have our output
- 10:16:17display. So we have four seven segment
- 10:16:19displays chained together. This is the
- 10:16:21readonly memory and this is the
- 10:16:23register. Um so the value in the
- 10:16:26register feeds into this read only
- 10:16:27memory which decodes which lines it
- 10:16:29should set on each of the displays to
- 10:16:31show the value that we want. Um and
- 10:16:34similarly that also connects uh into the
- 10:16:36bus.
- 10:16:38So then let's jump over here. This is
- 10:16:42our memory address register the 4bit
- 10:16:44memory address register and that reads
- 10:16:45in from the bus. And um this is our
- 10:16:49entire RAM unit right here. And then
- 10:16:52this would be the uh output of the RAM
- 10:16:54unit. And then there's something
- 10:16:56interesting where in our simulator we
- 10:16:58were kind of just literally clicking
- 10:16:59values to punch in updates to the
- 10:17:01memory. Uh in real world, we actually
- 10:17:03have these these manual switches up
- 10:17:05here. And I can swap. Uh so if I if I if
- 10:17:08this light is green, it means the
- 10:17:10computer's in execution mode. If I flip
- 10:17:12the switch, uh, it'll actually instead
- 10:17:14of looking at the value in the memory
- 10:17:16address register, um, or the value on
- 10:17:18the bus, I can use these these blue
- 10:17:21switches over here to punch in a
- 10:17:23specific address and then punch in a
- 10:17:25specific value. And then if I pulse this
- 10:17:27button over here, it'll latch that value
- 10:17:29into a specific address in RAM. Um,
- 10:17:32these are really small and honestly a
- 10:17:34very big pain to use. Um, but that is
- 10:17:37how I loaded the program into memory. I
- 10:17:39kind of have to flip the switch so it's
- 10:17:41on human program mode and then pulse
- 10:17:44through cycle through every address that
- 10:17:45was used uh for my program, load the
- 10:17:48value and then punch it in and then swap
- 10:17:50the address and rinse and repeat. And
- 10:17:52then once that's I could flip the switch
- 10:17:54back uh and then also flip the clock to
- 10:17:56automatic mode and just let it rip. Um
- 10:18:00this will show you the output. Uh so for
- 10:18:02whatever address is on the memory
- 10:18:04address register, the ALU is always
- 10:18:06looking it up. So this is just always
- 10:18:08showing the output. You can kind of see
- 10:18:09like every time the value changes on the
- 10:18:12input side, the value on the output side
- 10:18:14changes as well. Unsurprisingly,
- 10:18:17um here is our instruction register. So
- 10:18:20the instruction register is eight bits,
- 10:18:21but the left four bits are the argument
- 10:18:24and the right four bits, sorry, the left
- 10:18:25four bits are the operation code, i.e.
- 10:18:28which instruction we're executing at any
- 10:18:29moment in time. And the right four bits
- 10:18:32are the uh argument to that instruction.
- 10:18:35So I used separate color lights to
- 10:18:37denote the two. Um but you can see it's
- 10:18:39just backed by register and that also
- 10:18:41connects to the bus. And then here is
- 10:18:44the meat uh of our computer, the brains
- 10:18:47that tie it all together. And that's the
- 10:18:49control logic. So this is the control
- 10:18:51logic. These are readon memory chips
- 10:18:53that I literally have to take apart out
- 10:18:55of the computer and program and then
- 10:18:56punch them back in here. If we look at
- 10:18:58what the inputs are here, um you can see
- 10:19:03that um we have the uh four bits of the
- 10:19:09instruction register. So the operation
- 10:19:11code and then we also have this
- 10:19:13five-step uh counter that represents
- 10:19:16which step of the current instruction
- 10:19:17we're on. The way it's implemented in
- 10:19:19person is a little bit different than
- 10:19:21the way I explained it. Uh but the
- 10:19:22concept is roughly the same or it's it's
- 10:19:24it's fundamentally the same. So it
- 10:19:26doesn't matter. I didn't want to
- 10:19:27introduce this technically uses a
- 10:19:29different type of counter. And the way
- 10:19:30it's visualized is whatever step you're
- 10:19:32on, uh, that light will be off. The
- 10:19:35clock's going so fast that you can't
- 10:19:36really tell. It just kind of looks like
- 10:19:37they're flicker. But if I were to tune
- 10:19:39down the clock speed, you'd watch a left
- 10:19:42to right pattern and then it' reset uh
- 10:19:44in terms of which one is the quote
- 10:19:46unquote off. And then the uh the value
- 10:19:49from the flags register is also hooked
- 10:19:52in here. Um, and then we can see that
- 10:19:56these yellow wires are just going
- 10:19:57everywhere because that's the the
- 10:19:59control output like when we say like RAM
- 10:20:02out or memory address in or program
- 10:20:04counter increment like that has to go to
- 10:20:06each of the components. So you can see
- 10:20:07like some of these yellow wires going to
- 10:20:09the program counter, some going to the
- 10:20:10memory address register control, uh some
- 10:20:13to the ALU operands, uh some to the
- 10:20:15output display, and then for debugging
- 10:20:18purposes, I also duplicated it so I
- 10:20:21could actually see at any step what
- 10:20:23lines were being set by the control
- 10:20:25logic. So that's right here. Um can't
- 10:20:27really tell, but there's a label. So
- 10:20:29like this leftmost light is on if maybe
- 10:20:32like the program counter increment line
- 10:20:33is on. um in the simulator we built that
- 10:20:36roughly controls to being able to
- 10:20:38visualize this right here.
- 10:20:40So this is the computer. Um I built it
- 10:20:43over the pandemic. And the reason I even
- 10:20:46came across this is I I learned about it
- 10:20:48in school for a class I took for my
- 10:20:49computer science degree.
- 10:20:51And uh the class uh we didn't build this
- 10:20:55computer as part of the class. But we
- 10:20:56did learn how this computer architecture
- 10:20:58worked uh as a significant portion of
- 10:21:01the class. But the professor of that
- 10:21:04class is also not the one who invented
- 10:21:05this computer. Um this computer has a
- 10:21:08name. I've probably let it slip a few
- 10:21:10times and maybe you could have seen it
- 10:21:12already over here in the naming. This
- 10:21:14computer is called SAP 1 SAP1. Um, let's
- 10:21:19go ahead and Google it.
- 10:21:22Go straight to Wikipedia because we've
- 10:21:24been using that. And this says, "The
- 10:21:26simplest possible computer is a
- 10:21:29simplified computer architecture
- 10:21:30designed for educational purposes and
- 10:21:33described in the book digital computer
- 10:21:35electronics by Albert Paul Molino. Um
- 10:21:39the SAP architecture serves an as
- 10:21:42uh for building and analyzing complex
- 10:21:44logical systems with digital
- 10:21:46electronics. So this is an old book. Um,
- 10:21:50and then, uh, interestingly enough, this
- 10:21:51Wikipedia also talks about, uh, Ben Eer,
- 10:21:54the individual whose video I watched to
- 10:21:57learn how to build my computer here. Um,
- 10:22:01but let's actually, uh, go ahead. If
- 10:22:04you, Turns out, if you Google the book
- 10:22:06name, um, it's old enough that it's just
- 10:22:09online,
- 10:22:12uh, on the, uh, archive. Um, and I mean,
- 10:22:15you can see this is kind of an old book
- 10:22:16here. Uh it seems as though this came
- 10:22:19from 1993 or at least this version of
- 10:22:22the book. Um so this is old here but uh
- 10:22:25what's really cool is this book kind of
- 10:22:28does a lot of what we did in the video
- 10:22:29from scratch which is taking no
- 10:22:31understanding of how computation works
- 10:22:33and building a fully functioning
- 10:22:35computer that demystifies a lot of the
- 10:22:37blackbox of like what is happening on
- 10:22:39your phone or on your computer under the
- 10:22:41screen or like in the internals. So if I
- 10:22:43skim through the chapters here before he
- 10:22:46even gets to talking about the computer
- 10:22:48architecture um you see it it starts
- 10:22:51with number systems and that's where
- 10:22:53this video started. We started with you
- 10:22:54know binary how do we convert from
- 10:22:56binary to decimal um and you can kind of
- 10:22:59see that a lot of that is here like
- 10:23:00decimal to binary and vice versa. And
- 10:23:03then after that we talked about logic
- 10:23:05gates you know we we know about the
- 10:23:06inverter gate the orgate andgate um the
- 10:23:10some of these other logic gates we also
- 10:23:11covered like we know about NAND or the
- 10:23:14exclusive orgate because we needed them
- 10:23:15to all build this computer.
- 10:23:18Then uh we talked about some of these
- 10:23:21without naming them. Um but like
- 10:23:23multiplexers we came across for our
- 10:23:24computer and same for here uh like some
- 10:23:29of our implementation our intuition for
- 10:23:31implementing the ROM was using actually
- 10:23:33some of products I just didn't formally
- 10:23:34say it cuz I didn't want to bog down
- 10:23:36with terms um and once we had an
- 10:23:39understanding of logic gates we went
- 10:23:40ahead and built the ALU uh and that was
- 10:23:42able to support bi binary addition
- 10:23:45subtraction and we learned about we
- 10:23:47started with half adders and then
- 10:23:49chained those together um or we got half
- 10:23:51adders and we chain those with full
- 10:23:53adders to build our ALU.
- 10:23:56Um, and then once we had the ALU
- 10:23:58working, we moved into sequential logic.
- 10:24:01Everything we had been looking up until
- 10:24:02that point was deterministic. Uh,
- 10:24:04sequential logic was flip-flops and
- 10:24:06latches and how we actually hold data.
- 10:24:08And you can kind of see that's like a
- 10:24:10fundamental necessity to implement our
- 10:24:12computer because that's just like the
- 10:24:13crux of RAM and register is the need to
- 10:24:16be able to persist data. um that was
- 10:24:19possibly the output of some other
- 10:24:21deterministic circuit. After that uh you
- 10:24:24know these are some of the other
- 10:24:25registers. We didn't really go into too
- 10:24:27much there but then we talked about
- 10:24:28memories. We talked about uh RAM for
- 10:24:31sure. We talked about readonly memories
- 10:24:33and then we also talked about the
- 10:24:35history of some of the readonly memory
- 10:24:36types. We talked about programmable
- 10:24:38readonly memories and electronically
- 10:24:40programmable readonly memories and then
- 10:24:42EROMs
- 10:24:44and that was like the foundation of all
- 10:24:46and then SAP one is the computer we
- 10:24:49actually built and that's where our
- 10:24:51context cuts off. The book keeps going
- 10:24:53and there's a lot more here. Um I've
- 10:24:56never read this book but it's probably
- 10:24:59pretty great. Um, it's very impressive.
- 10:25:01But the reason it's called SAP one
- 10:25:04instead of just SAP, SAP standing for
- 10:25:05simplest possible, uh, is that the
- 10:25:08author finishes the computer we
- 10:25:10constructed and then builds two more
- 10:25:12variants that are just more complicated
- 10:25:14and get you closer to more modern
- 10:25:16computers. And we'll talk about some of
- 10:25:19those changes at a high level. Um but if
- 10:25:22we actually jump to the chapter uh
- 10:25:24starting on page 140 for SAP one
- 10:25:27um
- 10:25:29here is what we see uh and you know
- 10:25:31skimming this I didn't read this too
- 10:25:33closely either but uh the architecture
- 10:25:35is is pretty identical like we have the
- 10:25:37program counter we have memory address
- 10:25:38register we have a RAM um and you can
- 10:25:41see the diagram is even identical to the
- 10:25:43one we designed when constructing our
- 10:25:45computer like you have two operants to
- 10:25:47the ALU we had a program counter we had
- 10:25:49a memory address register hooking into
- 10:25:51RAM and then we had an instruction
- 10:25:52register down here uh with the readonly
- 10:25:54memory to decode uh whatever the input
- 10:25:57is to it and then an output register
- 10:25:59with a display. Um and one thing that I
- 10:26:03do find interesting is if we hop down to
- 10:26:05the instruction set of the computer uh
- 10:26:07the author here only implemented few
- 10:26:10instructions. So there's quite literally
- 10:26:12only a load a an add subtract an out and
- 10:26:16then a halt. We have implemented uh far
- 10:26:18more instructions
- 10:26:20than what is presented here and some of
- 10:26:23them are very interesting. Specifically,
- 10:26:25the jump instructions and the
- 10:26:26conditional jumping instructions are
- 10:26:29what allowed us to build out uh both the
- 10:26:31the counting down program and the
- 10:26:33Fibonacci sequence. But what's cool is
- 10:26:35that we were able to implement those
- 10:26:37instructions without making any real
- 10:26:39changes to the hardware. Like we didn't
- 10:26:41add new components that aren't in this
- 10:26:42architecture specified up here. you
- 10:26:45know, we were just able to manipulate
- 10:26:47with incremental changes to what we had
- 10:26:49already built uh to get the computer uh
- 10:26:51the instructions that we wanted. So,
- 10:26:54this is super interesting. Um I don't
- 10:26:57think it's probably worth reading the
- 10:26:58entire book here, especially since we've
- 10:27:00covered most of what in my opinion is
- 10:27:02the fundamentals. Um, but I felt like
- 10:27:05credit was due because I did not invent
- 10:27:07this computer and uh it's very
- 10:27:09impressive that this computer exists and
- 10:27:12I'd say it's very effective um for its
- 10:27:15goal of building like educational
- 10:27:17purposes and explaining how computers
- 10:27:18work from scratch. The computer we
- 10:27:21designed is great for educational
- 10:27:24purposes that we as we just talked
- 10:27:25about, but it's still pretty abstract
- 10:27:28and there's a pretty big gap if I ended
- 10:27:30the video right here of like how does
- 10:27:32this actually scale to a modern
- 10:27:34computer. So, what I want to use the
- 10:27:36rest of the video for is showing like
- 10:27:38what a lot of this looks like in
- 10:27:39actuality and how we take this
- 10:27:41hypothetical hypothetical computer we
- 10:27:43invented and scale it up to something
- 10:27:45more modern. Um, I want to start by
- 10:27:48taking a look at the very first iPhone.
- 10:27:51Uh, I remember when the original iPhone
- 10:27:54came out and the first time I played
- 10:27:55around with it, I was amazed. And I
- 10:27:58think iPhones are interesting to look at
- 10:27:59because they have a lot of computing
- 10:28:02constraints, uh, but are still pack an
- 10:28:05impressive amount of technology into
- 10:28:06something that fits in the size of your
- 10:28:08hand. um you know they're striking
- 10:28:10things like battery life and then
- 10:28:13limited storage but then also pack a lot
- 10:28:15of rich features like very high quality
- 10:28:18displays and they appear to be very
- 10:28:19responsive and you can do several things
- 10:28:22at the same time. You can take a call
- 10:28:24while you're browsing the internet and
- 10:28:26uh for that I think iPhones are pretty
- 10:28:28interesting. So, I'm going to hop over
- 10:28:30to the uh
- 10:28:32the Wikipedia for the first generation
- 10:28:35iPhone, and I'm going to make a claim
- 10:28:38that this iPhone and every computer
- 10:28:41iPhone out there has a processor that is
- 10:28:44not too fundamentally different from
- 10:28:46what we've designed. You can imagine
- 10:28:49that these phones are obviously capable
- 10:28:50of a lot more. uh the only output our
- 10:28:53toy computer has is a simple seven
- 10:28:55segment display versus you know iPhones
- 10:28:58have an entire screen they can draw to.
- 10:29:00So I want to compare the instruction set
- 10:29:02of the computer we built with that of
- 10:29:04the iPhone um and see like what about
- 10:29:07that instruction set is different that
- 10:29:08lets like lets us scale up from a toy
- 10:29:11computer to something that's that's
- 10:29:12actually tangible. Um so looking at this
- 10:29:16Wikipedia page there's a few things that
- 10:29:18stand out. The first is um this iPhone
- 10:29:22has the original iPhone has 128
- 10:29:25megabytes of RAM. So what is a megabyte?
- 10:29:29Let's start off with a bite. We know
- 10:29:30what a bite is. A bite is just eight
- 10:29:32bits. And um our our RAM that we
- 10:29:37designed had two to the four uh
- 10:29:39different slots. We had four bit
- 10:29:40addressing. So we had 16 bytes of RAM in
- 10:29:43our computer. Now a kilobyte is a
- 10:29:47thousand bytes. the hence the kilo
- 10:29:49prefix. A megabyte is then a thousand
- 10:29:52kilobytes which equals a million bytes.
- 10:29:55So we have roughly I'm saying roughly
- 10:29:58here 128 million bytes of address base
- 10:30:03in our RAM compared to the 16 that our
- 10:30:05toy computer had. So two things come to
- 10:30:08mind. Um in one dimension this is a lot
- 10:30:12of memory. You know, we saw that the
- 10:30:14programs we built used almost the
- 10:30:16entirety of the memory of the SAP
- 10:30:17computer, but that's not going to be as
- 10:30:20much of a concern if we have 128 million
- 10:30:23uh slots of RAM. The second thing uh is
- 10:30:27that the same amount of RAM, we could
- 10:30:30argue that it's a lot relative to the
- 10:30:31computer we've constructed, but it's
- 10:30:33also trivial when you compare it to to
- 10:30:36more modern phones. um or the fact that
- 10:30:39if I take a picture on my iPhone and I
- 10:30:41took one right before this just for sake
- 10:30:42of illustration the size of that picture
- 10:30:45is 2.5 megabytes which is a lot you know
- 10:30:49this on one hand we want to say this is
- 10:30:51a lot of memory but given how much
- 10:30:53memory is scaled up in modern phones
- 10:30:55this is no longer a lot and your phone
- 10:30:57has uh several gigabytes of RAM which is
- 10:31:00an order higher uh on on the dimension
- 10:31:02scale a gigabyte would be uh thousand
- 10:31:05megabytes Um, scrolling down though,
- 10:31:09that's just one thing I wanted to call
- 10:31:10out. Scrolling down, there's a lot of
- 10:31:13um, a lot more technology packed into
- 10:31:15this phone. So, for example, we
- 10:31:17obviously know there's a touchcreen, but
- 10:31:19then there's also a microphone, which
- 10:31:21you need to make calls. Then there's
- 10:31:24Wi-Fi and Bluetooth. Wi-Fi for accessing
- 10:31:26the internet, Bluetooth for connecting
- 10:31:28to other devices like headsets. Um, and
- 10:31:31our computer that we designed doesn't
- 10:31:33have any of these. So, if I'm making the
- 10:31:36claim that the processor of the iPhone
- 10:31:38is not too fundamentally different than
- 10:31:40the processor we described, uh, one of
- 10:31:43the questions I would eventually like to
- 10:31:44answer is how do we bridge the gap and
- 10:31:47get these things like how do we get
- 10:31:49internet connectivity? How can we even
- 10:31:50draw to a screen? How do we know when a
- 10:31:52user touches on the screen? Um, and
- 10:31:55these are questions that I want to get
- 10:31:56to in the remainder of this video. But
- 10:31:58let's keep poking a little bit further
- 10:32:00and let's actually look at the processor
- 10:32:02that's on this phone. Um, so the second
- 10:32:05sentence here says it features a Samsung
- 10:32:07S5L8900
- 10:32:09SOC. Um, and SOC just stands for system
- 10:32:13on chip and it generally means that you
- 10:32:15have a lot of functionality baked into
- 10:32:17one chip rather than having uh several
- 10:32:20isolated components. So one chip could
- 10:32:23have the CPU, i.e. everything we've
- 10:32:26built thus far in the video and maybe uh
- 10:32:29the networking chip, the chip needed to
- 10:32:31like make internet requests versus more
- 10:32:34traditional computers would have these
- 10:32:36things be totally separate and they just
- 10:32:38be connected via wires. Um so let's read
- 10:32:41into the the system on chip that this
- 10:32:43early iPhone used. And um
- 10:32:47we can a few things stand out here. Um
- 10:32:51obviously these Wikipedias are very
- 10:32:52informationrich. The first thing I
- 10:32:54wanted to call out is that let's read
- 10:32:56from here. The default clock rate of the
- 10:32:59CPU is normally 666 MHz but has been
- 10:33:02lowered by Apple to about 12 412 MHz. So
- 10:33:08what is a megahertz? Let's start with
- 10:33:10what a hertz is. A hertz is just a unit
- 10:33:13of measurement for frequency. And
- 10:33:15roughly speaking or actually precisely
- 10:33:17speaking uh a hertz just means a cycle
- 10:33:19per second. So in the computer we built
- 10:33:23you know the the clock we can crank it
- 10:33:25up or down to make the computer run
- 10:33:26faster. And I think roughly in its uh in
- 10:33:30the maximal video I showed demonstration
- 10:33:33it was probably running at like two or
- 10:33:35three hertz. Uh I think we we're just
- 10:33:37going through a few few clock cycles
- 10:33:39every second. Um a megahertz actually is
- 10:33:43equ one megahertz is equivalent to a
- 10:33:45million hertz. So, what this is saying
- 10:33:48is that um the chip itself that's used
- 10:33:51in the original iPhone can can hit
- 10:33:53roughly 666 million clock cycles per
- 10:33:56second. Um and Apple has toned that down
- 10:34:00to about 412 uh million clock cycles per
- 10:34:03second. A logical question might be why
- 10:34:05would they ever lower this? You would
- 10:34:07assume that by making the clock run
- 10:34:09faster, it can execute more instructions
- 10:34:12in the same amount of time. So there is
- 10:34:14an incentive to make the phone feel as
- 10:34:16fast as possible by cranking up the the
- 10:34:19clock frequency. But it turns out uh
- 10:34:22there's nothing free, no free lunch. And
- 10:34:24that applies to computation as well. And
- 10:34:27that phones are constrained and one of
- 10:34:30the obvious constraints is battery life.
- 10:34:33Yes, cranking up the clock frequency
- 10:34:34will let you do more instructions per
- 10:34:36unit time, but uh it also means that the
- 10:34:40computer is going to be doing overall
- 10:34:42more work per unit time, which means it
- 10:34:44has to consume more battery to do so per
- 10:34:46unit time. These logic gates at the end
- 10:34:48of the day that we're challen
- 10:34:52you can crank the clock frequency up,
- 10:34:54but it's going to eat at battery. So,
- 10:34:56there's a happy medium where you want to
- 10:34:58push it lower low enough where it's not
- 10:35:01uh too slow for the user. Um,
- 10:35:05at the point where we can try and
- 10:35:06maximize battery life for the phones.
- 10:35:09Um, but that's just something I wanted
- 10:35:11to call out. The other thing which isn't
- 10:35:13labeled explicitly here is our SAP used
- 10:35:16five clock cycles per instruction.
- 10:35:20more modern processors, including likely
- 10:35:22this one right here, even though it's no
- 10:35:24longer considered modern by any
- 10:35:25standard. Modern in the scale of
- 10:35:27computing. How about that? Um, they
- 10:35:30actually beat this. They can do one
- 10:35:31instruction per clock cycle. And
- 10:35:35uh I don't want to make things too
- 10:35:36confusing because this might not even be
- 10:35:38uh easy to wrap your head around, but a
- 10:35:40lot of modern processors can actually do
- 10:35:42multiple instructions per clock cycle.
- 10:35:45Um, so that's pretty interesting. But
- 10:35:48let's continue and in and looking at the
- 10:35:50CPU itself. So
- 10:35:53um the first thing is that uh let's just
- 10:35:56read the start of the sentence. And
- 10:35:58there's a lot of tech like technical
- 10:35:59terms going on here. So I'm just going
- 10:36:02to read these first uh five or six
- 10:36:03words. The SL S5 L8900 contains a 32bit
- 10:36:10ARM V6 compatible CPU core. What does
- 10:36:15this mean? So, let's start with the
- 10:36:1732-bit. Um, our computer that we built
- 10:36:21was an 8-bit computer, which means
- 10:36:23fundamentally every value we reason
- 10:36:26about is 8 bits. So, all of our
- 10:36:28instructions were 8 bits. The bus itself
- 10:36:30was 8 bits and every value in RAM was 8
- 10:36:34bits. But we saw how this could be
- 10:36:35pretty limiting because it meant you had
- 10:36:37four bits to represent all your
- 10:36:39instructions, which is not that many
- 10:36:40different instructions. That's 16
- 10:36:42different instructions. And then every
- 10:36:45uh instruction that took an argument
- 10:36:46used four bits to represent the argument
- 10:36:49which meant you were pretty limited in
- 10:36:51how much you could express. 32 bits uh
- 10:36:55is a lot more. So if I uh 2 to the 4 our
- 10:36:59our 8bit computer um had 256 different
- 10:37:02values it could represent. Uh it's if we
- 10:37:06raise this to the 30 32nd power this is
- 10:37:08incomprehensibly large. Um that would be
- 10:37:124 bill294,967,296
- 10:37:18uh you know different values we can
- 10:37:19represent in in RAM alone specifically.
- 10:37:23Um, so a lot bigger. But then again,
- 10:37:27this might feel big relative to the
- 10:37:29computer we've constructed, which is 8
- 10:37:30bits, but a lot of modern computers
- 10:37:33actually use more than this 64-bit
- 10:37:35architectures or 128-bit architectures.
- 10:37:39But as we saw with the case with um
- 10:37:42clocks, you might think like, hey, why
- 10:37:44would we not just try to scale this up
- 10:37:46and use as much as possible? But phones
- 10:37:48aren't just constrained by battery,
- 10:37:50they're also constrained by memory. So,
- 10:37:53um, if a a computer that uses 64-bit
- 10:37:56architecture
- 10:37:58versus a computer that uses 32-bit
- 10:38:00architecture, well, in a 64-bit
- 10:38:02architecture, each instruction is 64
- 10:38:04bits. But in a 32-bit architecture, each
- 10:38:07instruction is 32bits. So, with the same
- 10:38:10amount of space, you can represent twice
- 10:38:12as many instructions on a 32-bit
- 10:38:14architecture compared to a 64-bit
- 10:38:16architecture. So there's there's also
- 10:38:17this trade-off of like more higher bit
- 10:38:20architectures mean you can be more
- 10:38:22expressive and you have more data
- 10:38:24available or more memory available to
- 10:38:26work with but it also comes at the cost
- 10:38:28at like an increased cost of complexity.
- 10:38:30Uh which pairs poorly with the fact that
- 10:38:32just phones are inherently constrained.
- 10:38:35Um but what is ARMv6? Uh and that's an
- 10:38:40interesting question. Um let's Google
- 10:38:42it.
- 10:38:44So ARM
- 10:38:47Let's read this together. ARM is a
- 10:38:50family of risk instruction set
- 10:38:52architectures for computer processors.
- 10:38:54Okay. Well, so ARM is not a single
- 10:38:57instruction set architecture. It's a
- 10:38:59family of instruction set architectures.
- 10:39:01But what does this risk mean? Risk
- 10:39:04stands for reduced instruction set
- 10:39:06computer. And if we read the definition
- 10:39:08here, it's an architecture designed to
- 10:39:10simplify the individual instructions
- 10:39:12given to the computer to accomplish
- 10:39:14tasks.
- 10:39:16Um and what this means is that a reduced
- 10:39:18instruction set computer might require
- 10:39:20more machine code to accomplish a task
- 10:39:22because the individual instructions
- 10:39:24perform simpler operations. So risk
- 10:39:27generally is something that you see a
- 10:39:28lot of uh phones or just resource
- 10:39:32constrained devices such as like
- 10:39:33embedded systems use uh because they're
- 10:39:36they're generally more compact uh but
- 10:39:39that also means they're less expressive
- 10:39:40and less powerful compared to to
- 10:39:42non-risk architectures. Um, but
- 10:39:48due to their low cost, let's jump back
- 10:39:49to the ARM Wikipedia. Due to their low
- 10:39:52cost, low power consumption, and low
- 10:39:53heat generation, ARM processors are
- 10:39:56useful for light portable batterypowered
- 10:39:58devices including smartphones, laptops,
- 10:40:01and tablet computers as well as embedded
- 10:40:04systems. So, ARM is very intentional.
- 10:40:07the architectures, the instruction set
- 10:40:09architectures that they introduced are
- 10:40:11specifically meant for resource
- 10:40:13constraint environments and they
- 10:40:15explicitly call out smartphones as being
- 10:40:17one such relevant use cases. Um so if
- 10:40:21ARM is a family of instruction set
- 10:40:23architectures,
- 10:40:24let's see how many there actually are.
- 10:40:26If I scroll down here, you can see uh
- 10:40:29things obviously or things maybe you
- 10:40:30would have guessed started with ARM v1
- 10:40:32and then we went to ARMv2, V3, V4 and it
- 10:40:36keeps going and these these keep coming
- 10:40:38out. I guess the uh I guess the latest
- 10:40:41is ARM ARMv9. Um but these
- 10:40:45architectures, these instruction set
- 10:40:47architectures are all technically
- 10:40:49different uh but are somewhat related to
- 10:40:52each other and they're usually
- 10:40:53compatible. And the original iPhone uses
- 10:40:57an ARM v6 architecture. And this is the
- 10:41:00actual instruction set uh that the
- 10:41:03iPhone uses. So, this original iPhone, I
- 10:41:06guess just any of them, um, if you're
- 10:41:09running any application or doing
- 10:41:11anything, the code for, let's say, like
- 10:41:13if you were running Twitter on your
- 10:41:16original iPhone first generation, um,
- 10:41:20all the code that builds up the Twitter
- 10:41:22app is just a combination of ARM v6
- 10:41:25instructions and
- 10:41:28as is the case for everything that your
- 10:41:30phone does. So all the code that
- 10:41:32represents the ability for you to send
- 10:41:34texts or make phone calls or uh browse
- 10:41:37the web all boils down to ARM v6 uh
- 10:41:40instructions. So you might think like
- 10:41:43hey like this must mean that like ARM v6
- 10:41:47must have a ton of instructions and you
- 10:41:49know maybe there's an instruction to uh
- 10:41:52send an internet request out or an
- 10:41:54instruction to make a phone call. Uh but
- 10:41:57it turns out when we actually look at
- 10:41:58the architecture uh we don't see any of
- 10:42:00that. So what I'd like to do is actually
- 10:42:03take a stab and go ahead and look at the
- 10:42:06architecture. And I also want to keep
- 10:42:09things uh not too abstract. I guess
- 10:42:13everything we've done so far has been
- 10:42:14pretty abstract. I've showed you the
- 10:42:16computer we built, but we weren't able
- 10:42:17to verify that in the video itself
- 10:42:19because I don't have access to that old
- 10:42:20computer. Um, so what I do have is
- 10:42:25something called a Raspberry Pi Pico.
- 10:42:29And it is a small little microprocessor.
- 10:42:33It's like this. It's about the size of
- 10:42:35my pinky. Um, and something interesting
- 10:42:39about it is that its CPU also runs uh
- 10:42:43the same instruction set as the original
- 10:42:45iPhone. So this this also runs ARM v6.
- 10:42:50So, what I'd like to do is let's go
- 10:42:52ahead and take a look at the uh ARMv6
- 10:42:56instruction set. It gets very
- 10:42:58complicated. Let's just take a poke at a
- 10:43:00high level and then let's actually write
- 10:43:02some code for ARMv6 and run it on this
- 10:43:05processor and and see if we can actually
- 10:43:08get some code to execute that does
- 10:43:10something that we can see with our own
- 10:43:11eyes. gone ahead and found the technical
- 10:43:15reference manual, which is pretty much
- 10:43:17just a guide for the processor that this
- 10:43:20Raspberry Pi Pico has. And um just you
- 10:43:24can see how old it is. This was
- 10:43:26published in 2009, had two
- 10:43:28modifications, and hasn't really been
- 10:43:30updated since because we're on to much
- 10:43:32more modern processors, but this is
- 10:43:35still a great example. So, we're not
- 10:43:37going to go too deep into this, but I do
- 10:43:39want to poke at the instruction set. Um
- 10:43:41let's start with the introduction about
- 10:43:43the processor.
- 10:43:45The Cortex M0 processor is a very low
- 10:43:48gate count highly energyefficient
- 10:43:50processor that is intended for
- 10:43:52microcontroller and deeply embedded
- 10:43:54applications that require an area
- 10:43:57optimized processor. So very low gate
- 10:44:00count. Gate count is literally referring
- 10:44:02to the logic gates that we use to build
- 10:44:04our computers. Generally speaking, the
- 10:44:07more logic gates a computer has, the
- 10:44:09more complexity and more battery
- 10:44:11consumption uh you can expect it to
- 10:44:13have. So having a low gate count is
- 10:44:16especially enticing for um these like
- 10:44:19constrained environments and that goes
- 10:44:21hand inhand with being highly energy
- 10:44:23efficient. Um, it is designed to use as
- 10:44:25little as little electricity as
- 10:44:28possible, which makes perfect sense for
- 10:44:30a phone. Uh, where, you know, especially
- 10:44:32back in 2008 when this first generation
- 10:44:34iPhone was released, uh, 2007, sorry.
- 10:44:38Um, discontinued in 2008. Uh, you know,
- 10:44:41you could imagine batteries, they're not
- 10:44:43even great today. Um, so they're quite
- 10:44:46quite worse back then. But, um, let's
- 10:44:51jump back to the docs. Uh so let's look
- 10:44:53at this and
- 10:44:55see
- 10:44:57the instruction set summary. So
- 10:45:01let's read this. This processor
- 10:45:03implements the ARMv6 thumb instruction
- 10:45:05set. And ARMv6 is the architecture we
- 10:45:09saw earlier. And the thumb means that uh
- 10:45:13it's actually a even more compact. ARMv6
- 10:45:16is already designed to be pretty
- 10:45:18minimal. Thumb makes it even more
- 10:45:20minimal by reducing a number of
- 10:45:22instructions that are always 30 32-bit
- 10:45:26on general ARMv6 architectures down into
- 10:45:2916. So our computer had straight 8-bit
- 10:45:33instructions. This computer has a
- 10:45:35combination of 16-bit instructions and
- 10:45:3732-bit instructions. And this is pretty
- 10:45:39interesting because our computer was
- 10:45:42designed to assume that everything we
- 10:45:44worked with was always 8 bits. But
- 10:45:46that's not strictly the case. Uh this
- 10:45:48computer is a great counter example
- 10:45:50here. Instructions aren't always the
- 10:45:52same number of bits. They can actually
- 10:45:53vary. You could imagine some
- 10:45:55instructions that don't have any
- 10:45:57arguments or have minimal arguments need
- 10:45:59not use 32 full bits. Um and so that's
- 10:46:03there's some use cases where we can get
- 10:46:05away with 16 bits or just fewer than 32
- 10:46:07bits. Um
- 10:46:10and
- 10:46:13if we scroll down, we can actually see
- 10:46:15the instructions. So, I'll just scroll
- 10:46:16all the way to the bottom. And you can
- 10:46:19see there's actually not a ridiculous
- 10:46:20number of instructions. I want to say
- 10:46:22there's like something around like 50 if
- 10:46:25I'm guessing here. And let's kind of
- 10:46:28comb through and see. So,
- 10:46:31ARM in general and I guess a lot of more
- 10:46:34just instruction sets in general operate
- 10:46:36with many more registers than our
- 10:46:38computer. Our computer had an A register
- 10:46:41and a B register, but really we only had
- 10:46:44instructions to operate on the A
- 10:46:45register. And a lot of the instructions
- 10:46:47that touch the B register were just to
- 10:46:49satisfy A register operations or things
- 10:46:52we'd like to do with the A register.
- 10:46:55Registers are really fast to access. As
- 10:46:57you saw, they literally just existed.
- 10:46:59you know, registers, you could literally
- 10:47:00put a value on the bus immediately or
- 10:47:02read a value in from the bus immediately
- 10:47:04versus RAM requires you to kind of put
- 10:47:06an address in the memory address
- 10:47:07register and decode that, which is just
- 10:47:10slower. So, RAM is still fast, don't get
- 10:47:12me wrong, but registers are even faster.
- 10:47:15So, for that reason, we generally like
- 10:47:17to work with registers just because
- 10:47:18they're really quick and easy to read
- 10:47:20and write from and don't require that
- 10:47:22much like clock that many clock cycles
- 10:47:24to do to interact with. So ARM has a lot
- 10:47:28more registers and they're general
- 10:47:30purpose registers meaning you can do
- 10:47:31whatever you want with them. Uh but it
- 10:47:34just gives you more room for scratch
- 10:47:35work. So when we built our Fibonacci
- 10:47:37program we had a lot of intermediate
- 10:47:39values like we like to store the
- 10:47:41previous Fibonacci number and the the
- 10:47:44second to last Fibonacci number. And it
- 10:47:46would have been nice if we could have
- 10:47:47held those in registers, but instead we
- 10:47:49kind of had to keep on reserving spots
- 10:47:51in memory and writing those values to
- 10:47:53those addresses in memory when we wanted
- 10:47:55to update them and then reading them
- 10:47:57back into the A register when we needed
- 10:47:58to operate with them. Um, you can
- 10:48:01imagine if we just had more registers,
- 10:48:02we could just denote, hey, like this
- 10:48:04register will just for our program will
- 10:48:06always just hold the the n minus one
- 10:48:09number and this second other register
- 10:48:10will hold the n minus n minus2 number.
- 10:48:13Um so a lot of what the arguments you'll
- 10:48:16see are actually operating on registers.
- 10:48:20So
- 10:48:22um if I look at this add instruction uh
- 10:48:24it's saying
- 10:48:26you can pretty much add the values of
- 10:48:29two registers these two registers into
- 10:48:32the and it'll store the result in this
- 10:48:34third register. Um or you can kind of
- 10:48:38see that this move instruction. It'll
- 10:48:40move the value from one reg from this
- 10:48:43register into this register.
- 10:48:46And
- 10:48:48that's kind of a bit of a different
- 10:48:49mental model. In our computer, we kind
- 10:48:51of only saw for the most part
- 10:48:52instructions being addresses and RAM.
- 10:48:55But here we're seeing that an argument
- 10:48:58can actually be just another register
- 10:49:00itself, like the the name of another
- 10:49:02register. Um, and then you can also see
- 10:49:05we still have some things that are
- 10:49:06similar. So like we had a load immediate
- 10:49:08that would load a immediate value into
- 10:49:11our A register where the value was
- 10:49:13encoded in the instruction itself. We
- 10:49:15still have that something pretty similar
- 10:49:17here. So you can see like this IMM just
- 10:49:19means an immediate and you can see that
- 10:49:21there's a register that you could want
- 10:49:23to load that immediate value into. Um,
- 10:49:26same same with some of our ads. So you
- 10:49:29could say, you know, add the value
- 10:49:32that's in a register, take that value,
- 10:49:34add it to some add some immediate value,
- 10:49:37constant value to it, and then store it
- 10:49:38in a destination register. Um, so you
- 10:49:42know, we can kind of see like there's
- 10:49:43move operations to move values from
- 10:49:46registers to other registers. You can
- 10:49:48see there's uh this one's interesting.
- 10:49:50Move any to PC. So the pro PC is per
- 10:49:53program counter as we saw earlier. That
- 10:49:56still exists here. We still have this
- 10:49:57mental model of the program counter
- 10:49:59tells us an address in memory and the
- 10:50:02computer will interpret that address and
- 10:50:04the value at that address in memory is
- 10:50:06an instruction and try to execute it. Um
- 10:50:08so we have operations for moving data
- 10:50:11between registers. We have operations
- 10:50:14for doing addition. Similarly we have
- 10:50:17operations for doing subtraction. So you
- 10:50:19can kind of see like uh you can subtract
- 10:50:23um take the value in one reg in one
- 10:50:26register subtract it from another
- 10:50:27register and store store the result back
- 10:50:29into a destination register or you could
- 10:50:32have a immediate variant where you take
- 10:50:34the value in a register subtracted some
- 10:50:37constant value from it and write the
- 10:50:38result back into a different register or
- 10:50:40maybe the same register. Um
- 10:50:44you can see there's like a you can
- 10:50:45negate values. There's also a
- 10:50:47multiplication. We never built
- 10:50:49multiplication in our computer, but the
- 10:50:52way we built the ALOU uh for handling
- 10:50:55addition and subtraction, you can
- 10:50:57imagine there's another component on
- 10:50:59more modern computers that can also do
- 10:51:00multiplication. What's interesting is
- 10:51:03this architecture does not actually have
- 10:51:06any support for division. So if you
- 10:51:08wanted to divide numbers, you'd actually
- 10:51:09need to write a algorithm using a
- 10:51:12combination of these instructions uh to
- 10:51:15to to get to to have division. you have
- 10:51:18to implement division yourself. Um you
- 10:51:21also have instructions to compare the
- 10:51:23values uh in two registers or compare
- 10:51:26the value in a register to an immediate
- 10:51:28and this CPU has the same concept of
- 10:51:31flags. So the same way we had this jump
- 10:51:34zero and jump carry instruction on our
- 10:51:37computer that looked at the flags
- 10:51:39register that was determined based on
- 10:51:40the last ALU operation, we have
- 10:51:43something similar where you know there's
- 10:51:45flags and certain instructions can
- 10:51:47update the flags.
- 10:51:50We also have something called logical
- 10:51:52instructions which are like the logic
- 10:51:55gates that we designed earlier but
- 10:51:57they're actually instructions. Um and we
- 10:51:59didn't have this in our computer. So
- 10:52:01let's take a look at this ands andds
- 10:52:04instruction. What this does is it'll
- 10:52:06take two registers as arguments and
- 10:52:10those are 32-bit values in each register
- 10:52:12because this is a 32-bit computer and
- 10:52:15you'll get a final value that it'll
- 10:52:17write into a different register. And
- 10:52:19what the final value is is also a 32-bit
- 10:52:22number where each bit position is the
- 10:52:27bitwise and of the two bits in the same
- 10:52:30positions of the operand argu uh
- 10:52:32registers. So uh the rightmost bit
- 10:52:36position in the output will be the
- 10:52:38rightmost the rightmost bit position of
- 10:52:41this register bitwise and with the
- 10:52:44rightmost bit position of this register.
- 10:52:47um and that's like the andgate and we
- 10:52:49have analogous versions for the
- 10:52:51exclusive or the bitwise or um or even
- 10:52:55negation.
- 10:52:57Then we also have a family of
- 10:52:58instructions for shifting. Um
- 10:53:02we haven't really talked about shifting
- 10:53:04so I'll kind of leave it alone for now
- 10:53:05but we'll actually see a program where
- 10:53:07it's kind of useful. Um but pretty much
- 10:53:09you could imagine I can explain that
- 10:53:10like shifting uh if we had like some
- 10:53:14binary value uh 0 1 1 0 if we left
- 10:53:17shifted it once it would actually just
- 10:53:20shift all the bits over one to the left
- 10:53:22and then add a new zero. So we'd end up
- 10:53:24with 1 1 0 0 that'd be a left shift by
- 10:53:28one. Similarly if we started with a 0 1
- 10:53:301 0 and right shifted we'd end up with
- 10:53:33just 011 which is the equivalent of 0
- 10:53:35011.
- 10:53:37So that's interesting. Um, and then we
- 10:53:40also have these load instructions which
- 10:53:43will let us load values from RAM into
- 10:53:45registers. And uh, what's interesting,
- 10:53:49we'll see this again shortly. The
- 10:53:52arguments could be literal addresses in
- 10:53:55memory or you could actually have that a
- 10:53:58value um, stored in a different register
- 10:54:01is meant to be an argument. And so you
- 10:54:04should take that argument uh take that
- 10:54:07register who is the argument go look up
- 10:54:09its value and treat that as an address
- 10:54:11in RAM. Look that up and then write that
- 10:54:13back into some other register. Um so
- 10:54:15these are kind of our loads and you'll
- 10:54:17also see there's like there's some
- 10:54:19syntax differences here. So we have
- 10:54:21three arguments for this one. And uh
- 10:54:24pretty much what this is saying is it's
- 10:54:25saying take the at treat the value
- 10:54:28that's in register RN as an address and
- 10:54:31then add some immediate value to it. So
- 10:54:33maybe you want to like look two
- 10:54:35addresses after that. So you could add
- 10:54:37two and then it'll go look up that value
- 10:54:39at Rn plus two in RAM. Uh read that and
- 10:54:42write that into this register. Um then
- 10:54:45we also have very similar variants for
- 10:54:47storing storing values in registers to
- 10:54:50RAM. Um we have a push and a pop which
- 10:54:53we'll ignore for now. Uh and then we
- 10:54:55also have branching. So unconditional
- 10:54:58just means you will always branch. So
- 10:55:01that's the equivalent of our just jump.
- 10:55:03You will no matter what the state of the
- 10:55:04computer is, you will jump to this other
- 10:55:06address. Then we also have conditional
- 10:55:08ones where you know you can imagine like
- 10:55:10there's like branch if two values are
- 10:55:12equal or branch if value is zero and
- 10:55:14that's kind of how we implemented our
- 10:55:16those are the equivalents of our jump
- 10:55:18carry and jump zero instructions. Um,
- 10:55:21and then we have a few more down here.
- 10:55:24And these are kind of a little bit weird
- 10:55:25like what is a supervisor call? What is
- 10:55:28an interrupt? Uh, what is an event? What
- 10:55:30is the concept of sending an event and
- 10:55:32waiting for an event? What is the
- 10:55:33concept of yielding? We have no op,
- 10:55:35which we already saw previously, which
- 10:55:37just does nothing. Um,
- 10:55:41and yeah, we're actually going to ignore
- 10:55:42these for now. Uh there's no way to not
- 10:55:46look at this processor and see a ton of
- 10:55:48new stuff that we haven't already seen.
- 10:55:50But that's um this is this is more
- 10:55:52advanced and we're not going to probably
- 10:55:54get into it uh for the scope of what
- 10:55:56we're doing right now. But it is
- 10:55:57possible that a separate video will
- 10:55:59actually cover this specifically. So
- 10:56:02this is kind of an overview of the
- 10:56:03instruction set. You might be scratching
- 10:56:06your head where these instructions,
- 10:56:08yeah, I guess semantically they're a
- 10:56:10little bit different than what we built
- 10:56:11for our computer, but they're not that
- 10:56:13different. Uh so like where is the
- 10:56:15instruction to you know write something
- 10:56:17to the display of the phone or something
- 10:56:19like that? Uh and it turns out that
- 10:56:21there's just not an instruction for
- 10:56:22that. So you're probably even more
- 10:56:25confused now wondering well how does my
- 10:56:28the processor in my iPhone actually draw
- 10:56:30to the screen of the iPhone? And we're
- 10:56:33going to turn out uh we're going to do
- 10:56:35some keep poking this a little further.
- 10:56:37Turns out these instructions are
- 10:56:39actually capable of doing everything
- 10:56:41that we actually need to draw on the
- 10:56:43display or know when the user touches
- 10:56:46the screen at a particular location. And
- 10:56:49I'm going to jump back to my iPad and
- 10:56:51we're going to explain two concepts and
- 10:56:54then we'll jump back to the computer and
- 10:56:55those two concepts will actually start
- 10:56:57bridging the gap of how our processor
- 10:57:00can do things that aren't just mappy.
- 10:57:02Like everything we see right here is
- 10:57:03just kind of some variation of math or
- 10:57:06moving data. So we can implement very
- 10:57:08pure algorithms, but we're not seeing
- 10:57:10how we translate that to very practical
- 10:57:12things that we'd want a phone to do,
- 10:57:13like drawing a shape or, you know,
- 10:57:16showing some notification in a visual
- 10:57:17manner. Um, so let's go over the iPad.
- 10:57:20Uh, it's a little I don't mean to be
- 10:57:22very jumpy, but there are two different
- 10:57:23concepts that I like to explain. Um, and
- 10:57:25then we'll be able to jump back and
- 10:57:27actually write some code for our
- 10:57:29Raspberry Pi Pico.
- 10:57:33Okay, so I'm back on my iPad and I said
- 10:57:35there's two concepts I want to teach you
- 10:57:36about. Number one is called Hex. So, uh,
- 10:57:41the instruction set architecture where
- 10:57:43we've been working with that we
- 10:57:44designed, uh, right up here was all 8
- 10:57:47bits. You know, our bus was 8bit, our
- 10:57:48RAM was all 8 bits, all of our registers
- 10:57:50were 8 bits. Uh, but now we're looking
- 10:57:52at a 32-bit system. And
- 10:57:56binary totally works for 8 bits for
- 10:57:59saying, "Hey, our value is 1 0 1 1 0 0
- 10:58:03just fictitious number." This works for
- 10:58:068 bits. It's fine. It's a little tedious
- 10:58:08to write out all eight bits, but oh
- 10:58:09well, we have to do it. When it's 32
- 10:58:12bits, uh, that's a big pain to represent
- 10:58:1532 digits for every number. And we'll
- 10:58:18see that not only is this pretty ver
- 10:58:20verbose, it's just not as readable. um
- 10:58:22the more ones and zeros you have chained
- 10:58:24together the the less the interpretate
- 10:58:25the interpret interpretability becomes.
- 10:58:28So instead of writing everything out in
- 10:58:30binary, what we're going to see as we
- 10:58:32look into this further and look at
- 10:58:34actual uh code for this architecture is
- 10:58:38something called hex. Um hex is base 16.
- 10:58:44And recall from earlier uh we speak in
- 10:58:47base 10.
- 10:58:49And what this means is that there's 10
- 10:58:52different values that can go into every
- 10:58:54digit position. And those are zero, one,
- 10:58:56two, three, four, five, six, seven,
- 10:59:00eight, and nine. Then we learned about
- 10:59:03base 2, which is binary. And two
- 10:59:07different values can go into this slot,
- 10:59:09zero and one. So I feel like if I told
- 10:59:12you about base 3, base 4, or anything up
- 10:59:15to base 9, you'd be able to reason about
- 10:59:17how to count and it wouldn't be that
- 10:59:19complicated. But when I'm saying base
- 10:59:2216,
- 10:59:25this has some implication that there's
- 10:59:2716 different values that could go in any
- 10:59:29digit position, but there's only 10
- 10:59:33different digits that we know. Like
- 10:59:35every number we know is made up of of
- 10:59:37the the digits 0 through nine. So how
- 10:59:40can we represent 11 different digits,
- 10:59:43let alone 16 [snorts]
- 10:59:46uh if we don't have that many digits?
- 10:59:48Um, and it turns out we start using
- 10:59:50numbers. So, let's count in base 16 and
- 10:59:53see what it turns out, sorry, that we
- 10:59:54start using letters. So, let's count in
- 10:59:57base 16 and see what this looks like.
- 10:59:59So, we have 0 1 2 3 4 5 and everything
- 11:00:06up through nine is going to be the same.
- 11:00:10We'd like to write the number 10 here,
- 11:00:11but that is not onedigit position.
- 11:00:13That's twodigit positions. But we have
- 11:00:15to we're looking at single digit
- 11:00:17positions. So if we run out of every
- 11:00:19number, the next logical thing that we
- 11:00:22can use is other symbols. And letters
- 11:00:25are an easy symbol. We could start
- 11:00:26drawing shapes, but let's just stick
- 11:00:28with letters. So we're going to say A.
- 11:00:33And we sort of implicitly know that A
- 11:00:36maps to 10. And then B maps to 11,
- 11:00:41C maps to 12,
- 11:00:44D can map to 13,
- 11:00:48E can map to 14,
- 11:00:51and F can map to 15. And if we say that
- 11:00:55these are this is the set of digits in B
- 11:01:0116, that is 16 different digits. Um, and
- 11:01:07it might be weird to reason about
- 11:01:09numbers and letters mixed
- 11:01:10interchangeably, but it pretty much
- 11:01:12means let's just look at an example of a
- 11:01:14a hex number. Let's say we have um
- 11:01:19a e this hex number and I'll also say
- 11:01:24for binary for for base 10 we just write
- 11:01:26out our numbers kind of we say like 762
- 11:01:29the example number for binary uh we kind
- 11:01:32of prefix it sometimes with this 0B and
- 11:01:35then we say all of our binary digits.
- 11:01:37You'll see that for hex we prefix with
- 11:01:400x.
- 11:01:42So if you see zero x it means you have a
- 11:01:44hex number. So let's say we have ae.
- 11:01:47Well, uh we just need to figure out what
- 11:01:49the contribution of each digit position
- 11:01:52is to our overall sum. So if we were
- 11:01:55looking in base 10, we had the number
- 11:01:5756. Recall that this is 6 * 10 ^ of 0
- 11:02:04and then 5 * 10 ^ of 1. Um so our
- 11:02:09analogous equivalent here is this is a *
- 11:02:1516 to the^ of 1 plus e * 16 ^ of 0. And
- 11:02:23we know a is 10. So that's 10 * 16. And
- 11:02:27then we know e is 14. And 16 to the 0 is
- 11:02:30just one. So we have 160
- 11:02:35and 14. when we add those together, it's
- 11:02:37just 174.
- 11:02:40So, this is not fundamentally too new
- 11:02:42from anything we've already seen, but I
- 11:02:44thought it warranted an example to show.
- 11:02:46Um, and yeah, pretty much that means
- 11:02:50that for example, if I just say 0x 9,
- 11:02:54that's still 9. But if I say 0xd, that's
- 11:02:58equivalent to the value of 13 in base
- 11:03:0010. Base 10 being what we reason about
- 11:03:02as humans. So we can see that with a uh
- 11:03:06each digit in base 16
- 11:03:10holds one of 16 different values. Which
- 11:03:13means if we think about this um we know
- 11:03:15that 2 to the 4 is equal to the^ of 16.
- 11:03:19So one hex digit
- 11:03:23equals four bits.
- 11:03:27you need four bits to represent discrete
- 11:03:31values for each of these uh digits in
- 11:03:34the vocab. Um
- 11:03:36but this makes you makes things better
- 11:03:38because it means we have a 1 to4
- 11:03:40mapping. So when our computer works with
- 11:03:4232 bits,
- 11:03:44it's actually just eight hex digits.
- 11:03:47So every address in our computer is
- 11:03:54eight hex digits, which plays pretty
- 11:03:57well because that's the same number of
- 11:03:58digits that we had to to use to reason
- 11:04:00about our um our SAP computer. So that's
- 11:04:05concept number one. Concept number two
- 11:04:09is called MMIO.
- 11:04:14And I would actually say this is the
- 11:04:17crux of how the computer interacts with
- 11:04:20components that are not itself. So let's
- 11:04:22say that our computer um and this this
- 11:04:25Raspberry Pi Pico that I'm holding in my
- 11:04:27hand, which you can't see cuz I'm screen
- 11:04:29sharing has um an LED on it. So there's
- 11:04:34this CPU and we know everything about
- 11:04:36the CPU and then there's this LED. LED
- 11:04:39just stands for light emmitting diode.
- 11:04:41It's literally just a light. Um,
- 11:04:46and the question is, how could we
- 11:04:49possibly have our processor with the
- 11:04:52instructions we know turn that LED on
- 11:04:55and off? And so, let's break down what
- 11:04:59mmio stands for.
- 11:05:04The first M stands for memory,
- 11:05:06then mapped,
- 11:05:09input, output.
- 11:05:13So, mm IO stands for memory mapped input
- 11:05:16output. What does this possibly mean?
- 11:05:18That doesn't put us any closer. Um,
- 11:05:21well, input output is kind of this arrow
- 11:05:23here. In our case, we're just concerned
- 11:05:25about output. You know, we just like
- 11:05:27we'd like our CPU to be able to uh turn
- 11:05:30the LED on and off, but who knows? Maybe
- 11:05:32this is maybe we'd also like to be able
- 11:05:34to read if the LED is on or not. Uh, so
- 11:05:37there could be input. Um, and so I guess
- 11:05:40the crux of this is the memory mouth
- 11:05:42part. And with the instructions we saw
- 11:05:46in the computer we built and in the ARM
- 11:05:48V6 manual that we just combed through,
- 11:05:51there's no way to possibly turn on this
- 11:05:53LED or something that's just totally
- 11:05:55external to the processor itself. Um,
- 11:05:59and it turns out we use something called
- 11:06:01a memory mapped IO which is abstracts
- 11:06:03parts of memory to interact with third
- 11:06:06party components. So, we're just going
- 11:06:08to pick an a random address.
- 11:06:11Let's just say 0x.
- 11:06:19And I'm just inventing some 32-bit hex
- 11:06:21address. And pretty much what happens
- 11:06:24is, let's say you write a one to this
- 11:06:29value in memory, then it'll turn on the
- 11:06:32light.
- 11:06:35And if you write a zero to this value in
- 11:06:37memory, it'll turn off the light.
- 11:06:42And
- 11:06:44how could that be possible? Uh it turns
- 11:06:46out the CPU is just designed these these
- 11:06:49addresses are just determined
- 11:06:51arbitrarily. There's usually some
- 11:06:53consistency across like processors in
- 11:06:55the world. But um the CPU will interpret
- 11:06:59any attempt to write. So any storing of
- 11:07:02register val at uh any storing of a
- 11:07:05value to that address um instead of
- 11:07:08actually storing it to that address in
- 11:07:10RAM it'll have a comp connection to this
- 11:07:14external component and it'll use that as
- 11:07:16the signal to go and turn on that
- 11:07:18component like give it power or not. So
- 11:07:21this is really powerful and I think very
- 11:07:23interesting um because it does mean that
- 11:07:26the the implementation of the CPU has to
- 11:07:28be updated but you can kind of guess how
- 11:07:30this would be done. You saw how
- 11:07:32instructions were decoded. So you can
- 11:07:34pretty much imagine that any storing
- 11:07:36instruction has some extra complexity
- 11:07:39now where it'll check uh you know if you
- 11:07:44do some sort of store
- 11:07:47then what happens is it goes one of two
- 11:07:49ways. you have to check the address and
- 11:07:52it'll either write to RAM
- 11:07:57or it'll you know uh connect to some
- 11:08:01peripheral and we'll say operate on a
- 11:08:06peripheral
- 11:08:08and a peripheral here just refers to any
- 11:08:12component of the computer that is
- 11:08:14external but still part of the computer
- 11:08:16as a whole external to the CPU um
- 11:08:19something that can be interacted with
- 11:08:21via the CPU. So
- 11:08:24in this hypothetical example, we'd say
- 11:08:27that if you write to this FFF AAA
- 11:08:29address, uh a one will turn will cause
- 11:08:32nothing to actually be written into that
- 11:08:34address in RAM. Uh but it'll actually
- 11:08:36cause the light to be turned on. Um or a
- 11:08:38zero will cause it to be turned off. And
- 11:08:40then we can just pick a different
- 11:08:41address. Uh let's just say like fff FF
- 11:08:45uh O.
- 11:08:46And we'll say that if you try read any
- 11:08:50read
- 11:08:51will give
- 11:08:54one if light on
- 11:08:57zero if light off.
- 11:09:01So if we wanted in the CPU in our
- 11:09:04program code to know if the light was
- 11:09:06on, we would literally just load we
- 11:09:08perform a load of this specific address
- 11:09:11in memory to a register, any register of
- 11:09:14our choosing. And when the computer sees
- 11:09:16that we are trying to access this
- 11:09:19specific address, it won't actually go
- 11:09:21look it up in RAM, it'll talk with the
- 11:09:23light component, figure out if it's on
- 11:09:25or not, and then put the corresponding
- 11:09:27value into that register. So this is
- 11:09:30super powerful because it gives the
- 11:09:32illusion that we are just working with
- 11:09:35memory um but we're actually now using
- 11:09:38memory to interact with things that are
- 11:09:40not just RAM. We've kind of violated
- 11:09:42this assumption that we had previously
- 11:09:44where anytime we write or write uh a
- 11:09:47value to or from RAM, it would actually
- 11:09:50do some operation on memory. But this is
- 11:09:52not the case. In actuality, uh only
- 11:09:54subsets of addresses uh will truly
- 11:09:57update RAM or read from RAM and then
- 11:10:00plenty of others will be used to
- 11:10:02interface with external parts of the
- 11:10:04computer. So if we explain um how this
- 11:10:09might look so we know you know this is
- 11:10:11just one example of one specific address
- 11:10:14maybe let's say uh a display
- 11:10:18a display on a phone um can maybe be
- 11:10:21broken up into a grid of pixels.
- 11:10:27I'm I'm just ignore my dimensions here.
- 11:10:29Let's also just for simplicity assume
- 11:10:31that um each pixel it's a black and
- 11:10:34white display display. So each pixel
- 11:10:39is either on
- 11:10:43or off. Then what we might do is say uh
- 11:10:47start with a specific address in memory.
- 11:10:49Let's say just hex um
- 11:10:57just this is maybe our starting address
- 11:10:59and then
- 11:11:02our code would say if you want to turn
- 11:11:03on this pixel write on to this address
- 11:11:06and then the next address uh in memory
- 11:11:09would correspond to the next pixel. So
- 11:11:11that'd be o o
- 11:11:15a1 and then this would be a2 and a3 and
- 11:11:20a4. So there'd be a like whole
- 11:11:23continuous chunk if there's like let's
- 11:11:25say there's 50 different pixels here.
- 11:11:28There could be 50 regions in memory um
- 11:11:32consecutive starting at this base
- 11:11:33address of hex a z. and your code could
- 11:11:38draw an image or draw a line or anything
- 11:11:42by figuring out which of these pixels to
- 11:11:44turn on. So if it uh were to to write
- 11:11:48ones into the first five addresses,
- 11:11:50you'd see like a line appear at the top
- 11:11:52of your screen. And so that's how our
- 11:11:55our program code can actually turn on
- 11:11:59the display. Uh so this is kind of how
- 11:12:01your phone display would work. And then
- 11:12:04conversely there could be there's
- 11:12:06several different implementation ways to
- 11:12:08actually figure out when a user touches
- 11:12:09on the screen. Um but perhaps one simple
- 11:12:14way is just the computer can decide some
- 11:12:16address. Let's say ff
- 11:12:20a621
- 11:12:22just making up random addresses. and uh
- 11:12:25whenever your program code reads this
- 11:12:28address, it'll have uh maybe encoded in
- 11:12:32there the coordinates of the last place
- 11:12:34the user touched the screen. So you
- 11:12:37could constantly be reading from this
- 11:12:38address and see whenever it changes to
- 11:12:40detect if the user just touched the
- 11:12:42screen somewhere. Um so this is what
- 11:12:45memory mapped IO does. IO stands for
- 11:12:47input output. It means pretty much
- 11:12:50communicating with the external world or
- 11:12:52other components that are part of this
- 11:12:54computer but not physically part of the
- 11:12:56CPU. And this mm memory mapped is means
- 11:13:00that it it appears to the computer to
- 11:13:02all be under the guise of memory read
- 11:13:03and writes. Uh but in actuality your
- 11:13:06processor is redirecting a subset of
- 11:13:08those around uh to accomplish this
- 11:13:10pretty neat behavior. So this is super
- 11:13:13cool. Um and unlocks the door to do a
- 11:13:16lot of things. You could imagine like um
- 11:13:19the CPU, you know, can now interact with
- 11:13:23not only a screen,
- 11:13:25but it might also have a a some sort of
- 11:13:29uh separate processor um that has
- 11:13:33internet access and then you know the
- 11:13:35CPU can now make internet requests. it
- 11:13:37could write uh the address of a a URL in
- 11:13:42some register and then this it would get
- 11:13:44routed to the internet chip and then
- 11:13:45maybe the internet chip could return
- 11:13:46some data about like what's at that
- 11:13:48internet address. So it's pretty
- 11:13:50powerful. Um let's actually write a
- 11:13:53program on the Raspberry Pi I have that
- 11:13:56will turn on an LED using memory mapped
- 11:13:59IO. So here's the microprocessor I've
- 11:14:02been talking about for the past 20
- 11:14:04minutes. And you'll have to bear with me
- 11:14:06because my computer webcam quality is
- 11:14:08not that great. But you can see this is
- 11:14:10the actual CPU. So it's analogous to
- 11:14:13what we just spent the past several
- 11:14:14hours building. And one of the other
- 11:14:17things to note is all these pins coming
- 11:14:19off the bottom. And uh a natural first
- 11:14:21question is like what are these? So
- 11:14:24again, the the image quality is just not
- 11:14:26great here. If I put this close to the
- 11:14:28camera, you'll see that they're all
- 11:14:30labeled. And many of them have the
- 11:14:34prefix GP and then some number following
- 11:14:37it. And what this actually is, these are
- 11:14:40GPIO pins, which stands for general
- 11:14:43purpose input output. So each of these
- 11:14:46pins programmatically via memory mapped
- 11:14:49IO um can either be used to read in data
- 11:14:53from that pin either a zero or a one or
- 11:14:55put out a value onto that pin a zero or
- 11:14:58one. And this is using real electricity.
- 11:15:01So what I could do is take a specific
- 11:15:03pin, figure out what address in memory
- 11:15:06corresponds to controlling that pin, and
- 11:15:09then write a one to it. And then if I
- 11:15:11have like a physical wire right here, I
- 11:15:13could literally connect that pin
- 11:15:17and then plug this into a separate
- 11:15:18device. So maybe if I had like a light,
- 11:15:20I could connect it to to this other the
- 11:15:22other end of this wire right here and it
- 11:15:23would turn it on. Um, and there's more
- 11:15:26interesting things that would be if you
- 11:15:27wanted to use a pin for outputting.
- 11:15:29Maybe if we had a temperature sensor,
- 11:15:31um, or some sort of other device, uh,
- 11:15:34like a button or something that when
- 11:15:35pressed, we could read in that signal.
- 11:15:38Um, it all works with memory mapped IO.
- 11:15:40So, in your code, even though you know
- 11:15:42that, hey, this pin's connected to a
- 11:15:44light or a button or a temperature
- 11:15:46sensor, uh, it appears as though you're
- 11:15:48just reading an address in memory. And
- 11:15:51one of the more interesting things, um,
- 11:15:53that I just happen to have with me as
- 11:15:55well is an actual display
- 11:15:58that, uh, has a bunch of holes for
- 11:16:01various GPIO pins to connect to. And
- 11:16:04there's some protocol which we won't get
- 11:16:06into here, but it lets you uh via memory
- 11:16:10address manipulation in the Raspberry Pi
- 11:16:13write contents to a screen. So I have
- 11:16:15some text drawn on the screen here. Um
- 11:16:17I'm building a subway tracker, but
- 11:16:19that's an independent project. And the
- 11:16:21code all exists on this Raspberry Pi and
- 11:16:24it'll go to the internet, figure out
- 11:16:26when the subways are coming from my
- 11:16:27station. Um, and then by writing certain
- 11:16:31contents to various uh addresses in
- 11:16:33memory, it can actually uh cause uh text
- 11:16:36to appear on the display of the screen.
- 11:16:38So that's pretty neat. Um, so we have
- 11:16:40all these GPIO general purpose input
- 11:16:43output pins. And if I actually flip this
- 11:16:45around, there's one other thing that's
- 11:16:47pretty interesting and it's this this
- 11:16:49copper like thing up here. And above it,
- 11:16:52it says LED, which stands for light
- 11:16:54emmitting diode. And this is just a
- 11:16:57light that we can use to turn on and off
- 11:16:59in our code however we want. Um, it's
- 11:17:02nice because we could, you know, write
- 11:17:04to a wire and then have that wire
- 11:17:06connect to a light. I just don't have
- 11:17:07one. So, this computer, this
- 11:17:09microprocessor, sorry, conveniently has
- 11:17:12a light built in. So, what we're going
- 11:17:14to do now is take a peek at figuring out
- 11:17:16how we can get code to run on this um
- 11:17:19that would turn on the light. And then
- 11:17:21the last thing we need to bridge is that
- 11:17:22there's this USB port right here. So
- 11:17:25that's how I can connect it to my
- 11:17:26computer and actually get code that I
- 11:17:28have on my computer, machine code
- 11:17:30binary, uh, onto the device. It's a
- 11:17:32pretty intricate process in itself, and
- 11:17:34we're not going to concern ourselves too
- 11:17:35much with it here. Um, but it is worth
- 11:17:37calling out like if I'm typing code on
- 11:17:39my computer, how do I actually get it
- 11:17:40onto this microprocessor itself? So, let
- 11:17:42me go ahead and tab back to my computer.
- 11:17:44So, back on my computer and I'm actually
- 11:17:47going to start with the solution. And I
- 11:17:49will claim that if you run this set of
- 11:17:52instructions on your computer on this
- 11:17:54processor that I'm holding in my hand,
- 11:17:57it will boot up the computer and turn on
- 11:17:59the light. Um, so let's take a look at
- 11:18:01what this is. These are various
- 11:18:03addresses.
- 11:18:05Recall that the computer's 32-bit uh
- 11:18:07addresses. And so these are actually hex
- 11:18:10addresses because they're more compact
- 11:18:12but equally as representative. So two,
- 11:18:14three, four, five, six, seven, eight.
- 11:18:18Eight hex characters in each address
- 11:18:20where you know each hex character
- 11:18:21represents four bits of data means 8 * 4
- 11:18:24is 32. So these are equivalent to 32-bit
- 11:18:27addresses. So that's consistent with our
- 11:18:29expectations. And then what we have
- 11:18:31right here is the literal value that is
- 11:18:33stored at each of these addresses.
- 11:18:36And it's also again in hex. Um but this
- 11:18:39is a little uninterpretable because it's
- 11:18:42we know the binary uh is not necessarily
- 11:18:44intended to be interpreted as a number
- 11:18:46but rather as some instruction that
- 11:18:48encodes an operation with some possible
- 11:18:50arguments. Um so there's semantic
- 11:18:52meaning outside of the digit uh
- 11:18:55numerical interpretation and that's
- 11:18:57exactly what we have over here on the
- 11:18:59the right column. We have uh a bunch of
- 11:19:02uh instructions. So we haven't seen any
- 11:19:04of these instructions because we only
- 11:19:06skimmed through the uh instruction set
- 11:19:08architecture but we'll give some
- 11:19:09motivation as we walk through these. So
- 11:19:11you can see like this is an instruction,
- 11:19:13LDR is an instruction, bic's
- 11:19:16instruction. You can see R1 uh and R2
- 11:19:19and R3 and so on are all different
- 11:19:22registers that we have accessible to us.
- 11:19:24Some things look familiar like PC we
- 11:19:26know is the program counter. Um and then
- 11:19:29these are all instructions.
- 11:19:31We can kind of see down here uh where it
- 11:19:33says this word. We'll see this shortly,
- 11:19:36but these are actually used to store
- 11:19:38values. Um so the same way in our
- 11:19:40Fibonacci program we stored values in
- 11:19:43certain addresses in RAM, we do the same
- 11:19:45thing here because sometimes an
- 11:19:47instruction can't be uh with as many
- 11:19:50bits as we have can't represent a full
- 11:19:52op code and a 32-bit argument uh in the
- 11:19:55constraint of a 32-bit instruction
- 11:19:56itself. So we'll see similar tricks
- 11:19:59where we store uh addresses in certain
- 11:20:01addresses in certain part uh positions
- 11:20:03in RAM or arguments that we can't encode
- 11:20:06instructions themselves. Um but if I ran
- 11:20:09this on the computer, it wouldn't be
- 11:20:10that satisfying because we haven't
- 11:20:11really explained what we've done. So
- 11:20:15there's two questions. Um one is what is
- 11:20:17this code doing? And two is if we
- 11:20:20understand what the code is doing, how
- 11:20:22did I know to write this code out? And
- 11:20:25to answer those questions, I actually
- 11:20:27turned to the uh documentation for this
- 11:20:31processor. And at a brief glance, if I
- 11:20:34look at the table of contents
- 11:20:36and scroll all the way to the bottom, we
- 11:20:38can see this is 640 pages. So this um
- 11:20:43pretty small processor
- 11:20:45somehow has a lot of complexity going on
- 11:20:48uh to justify that much documentation.
- 11:20:51And it turns out this is a pretty
- 11:20:52featurerich chip. And we're only going
- 11:20:54to touch this scratch the surface here.
- 11:20:56Um, but this documentation has explains
- 11:21:00everything we need to do to actually
- 11:21:01turn on the LED we're interested in. So,
- 11:21:04I'm not going to read everything in too
- 11:21:05much granularity here, but what I will
- 11:21:07do is jump around the various sections.
- 11:21:09So, the very first thing we need to do,
- 11:21:12um, if you read this is
- 11:21:15come over to this chapter and let's read
- 11:21:19this. The reset controller allows
- 11:21:21software control of the resets to all
- 11:21:23peripherals that are not critical to
- 11:21:24boot the processor. Um, and this is a
- 11:21:29lot of jargon. What this means is that
- 11:21:31when we turn on the computer, uh, only a
- 11:21:33subset of functionality is enabled and
- 11:21:35that subset of functionality is exactly
- 11:21:37what it needs to get the computer
- 11:21:39booted. You can imagine that that LED is
- 11:21:42not necessary for it to start up. So
- 11:21:45most external things that aren't
- 11:21:47strictly necessary for the computer to
- 11:21:48get running are actually turned off by
- 11:21:51default. So
- 11:21:54there's a um particular address in
- 11:21:57memory that we can write data to that
- 11:21:59will let us turn things on. So the first
- 11:22:02thing we need to do is tell that our
- 11:22:03processor like hey we actually do want
- 11:22:05to interact with these GPIO pins. Um,
- 11:22:09and we can see that the documentation
- 11:22:11says three registers are defined and
- 11:22:12there's this reset one. This register
- 11:22:15contains a bit per each peripheral that
- 11:22:16can be reset. If the bit is set to one,
- 11:22:18then the reset is asserted. If the bit
- 11:22:20is clear, then the re the reset is
- 11:22:22deasserted. So what this means is we
- 11:22:24have a 32-bit register somewhere. Some
- 11:22:26address in memory can be interpreted as
- 11:22:28the address by which we can interface
- 11:22:30with this register. And each bit
- 11:22:32position in that 32-bit value lets us
- 11:22:35turn on or off some peripheral.
- 11:22:38If I actually come up here, I can see
- 11:22:41the one we're interested in is IO bank
- 11:22:43zero. Um, that's just me telling you.
- 11:22:45You wouldn't have known that on your own
- 11:22:47without more reading of this
- 11:22:48documentation. And you can see it's the
- 11:22:50uh fifth bit position um from this this
- 11:22:54reset register. So, we'd like to figure
- 11:22:56out where the reset register is in
- 11:22:58memory. And if I scroll down here, um,
- 11:23:03we can see that it says the reset
- 11:23:05controller registers. So there's several
- 11:23:06registers. The one we're interested in
- 11:23:08is just the reset one. Start at a base
- 11:23:10address of this hex value. And then
- 11:23:13we're interested in this reset. So it
- 11:23:15says offset 0x0. What this means is that
- 11:23:19you take the base address and add an
- 11:23:20offset and that gives you the true
- 11:23:22destination address. In our case, we're
- 11:23:24adding zero. So it means the reset
- 11:23:26register is quite literally at this
- 11:23:27address. If we wanted to interface with
- 11:23:29this reset done register, we'd look at
- 11:23:32offset hex 8. So we'd act add hex 8 to
- 11:23:35this value and that would let us
- 11:23:37interface with this reset done register.
- 11:23:39So the very first thing we need to do is
- 11:23:42write to this reset register
- 11:23:44and um
- 11:23:47set the bit position for IO bank zero
- 11:23:49which is the fifth bit position. set it
- 11:23:51to zero and that'll let us tell the
- 11:23:54computer that hey like we actually do
- 11:23:56want to do some IO. So let's jump back
- 11:23:58to the instructions and see what the
- 11:24:00first few set of instructions are doing
- 11:24:02that let us accomplish this. I'm going
- 11:24:04to tell you what each of these
- 11:24:05instructions does. Um this very first
- 11:24:08one move s is moving a literal value of
- 11:24:1232 into the register R1. So after this
- 11:24:16instruction runs, register 1 will have
- 11:24:19the literal value 32. But let's actually
- 11:24:21spell that out in binary. Uh so we can
- 11:24:23see why that's happening.
- 11:24:33So this is 32 in hex. Um and the reason
- 11:24:3632 is interesting is because where we
- 11:24:40see uh what we see is all the all the
- 11:24:42bits are zero except one. And that one
- 11:24:46is actually the fifth bit position from
- 11:24:48the right. Uh which is interesting
- 11:24:50because we know that we needed to
- 11:24:52eventually find some address in memory
- 11:24:54uh of this resets register and set that
- 11:24:57specific bit position uh to zero. So
- 11:25:01that's just a little hint at where we're
- 11:25:03going. So after uh this first
- 11:25:06instruction executes, this is the state
- 11:25:08of the machine. The next instruction um
- 11:25:11is LDR which stands for load a value
- 11:25:14into a register. And we're loading a
- 11:25:16value into the register 2. And where
- 11:25:20what the value we're loading into is
- 11:25:22actually what uh whatever the program
- 11:25:24counter plus 36 is. Look at that address
- 11:25:27in memory um and get the value from
- 11:25:30there. If we do the math, the program
- 11:25:33counter because we're executing this
- 11:25:35instruction has to be at this address.
- 11:25:37So if we add 36 to it, uh we get this
- 11:25:40address right here. And if we come down
- 11:25:42here, we actually see that that
- 11:25:44corresponds to this address right here.
- 11:25:47And this should look very familiar
- 11:25:49because that is the base address of the
- 11:25:51reset register. So that's the value we
- 11:25:53actually want to uh write into. So if I
- 11:25:57copy that,
- 11:25:59then the state of our computer. Oops.
- 11:26:03Um, after the first instruction,
- 11:26:06I've done something wrong here. I' gone
- 11:26:08to a weird state there. Um, fix this up.
- 11:26:11So, R2 now holds the address of this
- 11:26:14reset register,
- 11:26:16uh, where it's memory mapped to. The
- 11:26:18next thing we actually need to do is
- 11:26:19read what the value in is. And so that's
- 11:26:21exactly what this next instruction does
- 11:26:24where LDR says load into register 3
- 11:26:28whatever uh the address in register 2
- 11:26:32points to. So register 2 points to the
- 11:26:34address of this this resets register. So
- 11:26:37we're actually going to load the
- 11:26:38contents of that register into R3. So R1
- 11:26:42and R2 are the same after this command.
- 11:26:44R3
- 11:26:47is going to look something like this.
- 11:26:49It's a 32-bit value. We don't really
- 11:26:52know what each of the bit positions are
- 11:26:55except for the fact that we do know that
- 11:26:57since the uh this LED is turned off at
- 11:27:00boot, um this fifth bit position right
- 11:27:03here is going to be a one. And what we'd
- 11:27:06like to then do is actually rewrite that
- 11:27:09value um keeping every other bit
- 11:27:11position the same but flipping this one
- 11:27:13to a zero. And so that's exactly what
- 11:27:17this bic instruction will do. Um it'll
- 11:27:21say this is the bitwise and of register
- 11:27:253 and the inverse of register 1. So
- 11:27:28let's break that down. Um let me go
- 11:27:30ahead and we know that register one has
- 11:27:34this value. The inverse of register one
- 11:27:37would be if we flip every zero to a one
- 11:27:39and every one to a zero. And so that
- 11:27:41looks exactly like that. And then we are
- 11:27:43doing um a bitwise and with register 3.
- 11:27:49So what effect would this have? Let's
- 11:27:50just think about this reasonably. We
- 11:27:52said that register 3,
- 11:27:55register 2 and register 3 are still the
- 11:27:57same. Um register three, I'm just going
- 11:28:00to move this out of the way so we can
- 11:28:01look at these next to each other.
- 11:28:03Register three, we know that we don't
- 11:28:05really want to change the values in any
- 11:28:07of the bit positions. So a bitwise and
- 11:28:10of any either a zero or a one with a one
- 11:28:14is just going to return the same value
- 11:28:15that's already in x. So in every place
- 11:28:18that we are bitwising bitwise and an x
- 11:28:21with a one, it's just going to remain
- 11:28:23the same.
- 11:28:24The interesting thing is this fifth bit
- 11:28:27position when we bitwise and it with
- 11:28:29zero it's actually just going to turn
- 11:28:31off that one bit position because
- 11:28:34anything and zero through a logic gate
- 11:28:37is necessarily zero. So R3 becomes this
- 11:28:40register where every bit position is
- 11:28:42unchanged except the fifth posit fifth
- 11:28:45bit position becomes a zero and that is
- 11:28:49the value that we'd like to write back
- 11:28:51into this address in memory to tell our
- 11:28:54CPU hey we actually uh are we actually
- 11:28:57do want to interact with these GPIO pins
- 11:28:59and so we've constructed the value that
- 11:29:02we'd like to write back and it's in
- 11:29:03register 3 but we actually need to write
- 11:29:05it back to this address in memory uh for
- 11:29:08it to be usable. And that's what the
- 11:29:10next instruction does. It says store
- 11:29:15um the contents of register 3, I what
- 11:29:19we'd like to write into the resets
- 11:29:20register into the address held by
- 11:29:23register 2. And this is saying you can
- 11:29:25just add zero to it. So it's just the
- 11:29:26same as not specifying anything. So what
- 11:29:29this will then do is actually um write
- 11:29:33this value this binary value into the
- 11:29:37resets register. And so we've if we jump
- 11:29:39back to our docs here um we can see that
- 11:29:43you know if the bit is set to one then
- 11:29:44the resets asserted. If the bit is
- 11:29:46cleared i.e set to zero then the reset
- 11:29:48is deasserted. So now this means that
- 11:29:51we've written this value back in and
- 11:29:53have turned off the fifth fifth bit
- 11:29:55position. it tells the computer that we
- 11:29:57actually do want to use IO bank zero. So
- 11:30:00that's our first step done. And I'm
- 11:30:01actually going to clear out all the
- 11:30:03instructions we've seen until now just
- 11:30:04to keep things cleaner. Um so we've made
- 11:30:07sense of those instructions, but when we
- 11:30:10tell the computer that we want to turn
- 11:30:11on IO bank zero, it actually takes some
- 11:30:14time to do so. And so we need to wait
- 11:30:17until the computer fully acknowledges
- 11:30:18our request before we try to write to
- 11:30:21the LED. If we simply wrote this value
- 11:30:23of saying, "Hey, I want to use IO bank
- 11:30:25zero," and then immediately turned on
- 11:30:27the light, it might not actually work
- 11:30:29because the computer needs to do some
- 11:30:30stuff to actually enable IO bank zero.
- 11:30:33And so if I come here, there's this
- 11:30:36reset bit reset done register, and it's
- 11:30:40the same structure where it says there's
- 11:30:41a bit for each peripheral except the
- 11:30:44difference is that it gets set once the
- 11:30:46peripheral is out of reset. And there's
- 11:30:48an explicit comment that says this
- 11:30:50allows software, i.e. the bite code that
- 11:30:52we are writing to wait for this status
- 11:30:54bit in case the peripheral has some
- 11:30:56initial initialization to do before it
- 11:30:59can be used. So in our specific case
- 11:31:01there is some stuff that needs to happen
- 11:31:03before we can just use the uh the LED.
- 11:31:06So we need to wait um for the bit
- 11:31:09position five in this reset done
- 11:31:11register to tell us uh that it get that
- 11:31:15it we are safe to proceed. So
- 11:31:19the next question is where is this
- 11:31:21resets done register and if we scroll
- 11:31:24back up uh oops or maybe it's down um we
- 11:31:29see that it is right here we get the
- 11:31:31address. So it starts at the same base
- 11:31:34address that the resets register is at
- 11:31:36but this time it's hex 8 further away
- 11:31:39from uh the base address. So now we'd
- 11:31:41expect the uh the address of this
- 11:31:43register to be 400C
- 11:31:47008.
- 11:31:49And if I tab back to our code, we can
- 11:31:52see that that is exactly somewhere in
- 11:31:55memory. Uh that address is stored
- 11:31:57somewhere in memory. So we can probably
- 11:31:59expect our code's going to try uh try
- 11:32:01access that address in memory. So let's
- 11:32:03go ahead and do that. Um let's figure
- 11:32:07out what this next instruction does.
- 11:32:09This next instruction says uh we are
- 11:32:12going to load the same fifth bit
- 11:32:15position mask into R2. So that's the
- 11:32:19same little cheeky hack we did to get
- 11:32:22every bit zero except this fifth
- 11:32:23position index. Um because we're going
- 11:32:27to do the same thing where we actually
- 11:32:28try wait and keep reading for that fifth
- 11:32:30bit position in this new register to
- 11:32:32figure out when it becomes a one. And
- 11:32:34then we're going to see that we're going
- 11:32:36to load uh our next instruction says
- 11:32:40load into register 1 whatever is 28
- 11:32:43memory addresses below this current one.
- 11:32:45And that is actually right here
- 11:32:48which is that exact address of this
- 11:32:50register that we're interested in
- 11:32:52interfacing.
- 11:32:54So this is the address of the reset done
- 11:32:58register.
- 11:32:59Then what we do is we actually that's
- 11:33:02our register one has the address that we
- 11:33:04need to read from memory. So we actually
- 11:33:06need to go read that value from memory
- 11:33:08into another into another another
- 11:33:10register sorry. So that's what our next
- 11:33:12instruction does. It says load into
- 11:33:15register 3 whatever the contents is at
- 11:33:18the address held in register one which
- 11:33:20is just the reset done register. And
- 11:33:24that will look something like
- 11:33:27we don't really know. It may or may not
- 11:33:29be done by the time we read it. So
- 11:33:33we can say maybe it looks something like
- 11:33:35this. Um
- 11:33:38except this one right here could be a
- 11:33:40one or a zero. So I'm going to write it
- 11:33:42as a question mark. We don't know if
- 11:33:43it's going to be done or not. And so the
- 11:33:45next thing we need to do is actually
- 11:33:46read that fifth bit position and figure
- 11:33:49out if it's if it's one or zero because
- 11:33:51if it's one that means we are
- 11:33:53initialized and we can actually turn on
- 11:33:55the light. Otherwise we need to wait and
- 11:33:57check again. So this tst instruction
- 11:34:02um is what will do that and it's called
- 11:34:04test bits. It'll do a bitwise and
- 11:34:07between the two arguments. In this case
- 11:34:09that's register two and register three.
- 11:34:11And similarly it won't spit out a value
- 11:34:14but it'll set flags the same way in our
- 11:34:17CPU doing an addition wouldn't would it
- 11:34:19would spit out a value but it also
- 11:34:20implicitly update the flags register.
- 11:34:23This CPU architecture has the same thing
- 11:34:24where it has its own concept of a flags
- 11:34:26register. So we already know that um bit
- 11:34:30like R2 bitwise anded with R3
- 11:34:35uh it's either going to be zero if the
- 11:34:39um if the LED is not ready
- 11:34:43or it'll be one um if it is ready
- 11:34:47because this question mark would be a
- 11:34:48one. So one bit wise ended with one
- 11:34:50would imply that it is turned on one if
- 11:34:54ready. So we make that comparison and
- 11:34:57then this branch uh this this next
- 11:35:01instruction says beq.n
- 11:35:05and
- 11:35:07this pretty much means if the if the bit
- 11:35:10was a zero i.e. if the output of the
- 11:35:13last instruction was a zero we aren't
- 11:35:15ready yet. So we need to branch um back
- 11:35:20to this address right here. So pretty
- 11:35:22much we'll check what the output of the
- 11:35:24last instruction was and if it is a zero
- 11:35:29then we will jump to this address right
- 11:35:31here which is actually the one we just
- 11:35:33came up from right here. So if it is
- 11:35:36zero what it'll try to do is actually
- 11:35:38just read that same register again and
- 11:35:40do the same bitwise and check. Um and if
- 11:35:43it is a one then we just fall through
- 11:35:45this instruction as expected and we end
- 11:35:47up here. So pretty much what this effect
- 11:35:50has is it'll keep checking the value of
- 11:35:54the reset done register until it spits
- 11:35:57back a one which means at this point
- 11:35:59that we reach this uh this code right
- 11:36:01here the the LED is ready to use.
- 11:36:06Let me go ahead and now clear out this
- 11:36:08code
- 11:36:10since we know what it does and we're
- 11:36:12getting near the end but we still
- 11:36:13haven't done anything to turn on the
- 11:36:14light. Um, and so now that we've told
- 11:36:17the computer that we actually want to
- 11:36:18use the GPIO pins, we need to go tell
- 11:36:21the computer how we actually want to use
- 11:36:24the LED specifically. So the LED, if you
- 11:36:28read the documentation, corresponds to
- 11:36:30GPIO pin number 25. And there's several
- 11:36:34different ways to interface with the
- 11:36:35GPIO pins besides reading or writing
- 11:36:37values to them directly from code. But
- 11:36:40we aren't going to get into that in this
- 11:36:41video for the sake of our video. All we
- 11:36:44do want to be able to do is read and
- 11:36:45write values to these as if they were
- 11:36:47just addressable regions in our RAM. So
- 11:36:50we need to go tell the code that that's
- 11:36:52exactly how we want to use these. That
- 11:36:54is called SIO. Since we're single cycle
- 11:36:57IO um and it's required, we need to tell
- 11:37:00the CPU that for GPO GP IO pin number
- 11:37:0425, we'd like to be able to interface it
- 11:37:06with SIO, single cycle IO. And that'll
- 11:37:10just pretty much allow us to get the
- 11:37:12remainder code running that lets us
- 11:37:15write uh to a particular address in
- 11:37:17memory to actually turn on the LED. So
- 11:37:19I'll jump back to the documentation
- 11:37:22and we'll see that there is a uh a
- 11:37:26register called GPIO25 control and it is
- 11:37:31a control including function select and
- 11:37:33overrides. So uh again I'm not going to
- 11:37:36spell out how I knew to do this uh just
- 11:37:38for the sake of time but we pretty much
- 11:37:40just want to write the number five into
- 11:37:41this register and the system will
- 11:37:43interpret that number five as uh SiO. So
- 11:37:47we need to figure out where this
- 11:37:48register lives in memory. And we can see
- 11:37:51that uh the user bank IO register start
- 11:37:55at this base address. And then R number
- 11:37:5825 has an offset of 0C8 or sorry 0cc. If
- 11:38:05I jump back in the code, coincidentally
- 11:38:07enough, this address lives right here.
- 11:38:11So we'll probably expect our code to uh
- 11:38:13to do that pretty pretty to read that uh
- 11:38:16specific address and RAM pretty shortly.
- 11:38:18Let's keep tracing what this does. So
- 11:38:20this will load uh the first instruction
- 11:38:22will load the literal value five um into
- 11:38:27R2 because that's the value that we'd
- 11:38:29like to write into this register. And
- 11:38:31then the next instruction will load into
- 11:38:35R3 whatever the value in RAM is at
- 11:38:40program counter i.e. current instruction
- 11:38:42plus 24 that turns out to be this
- 11:38:44address that ends in 304 which is the
- 11:38:47address that we just identified of the
- 11:38:49specific GPIO25 controller. So that's
- 11:38:52what R3 will look like. And then the
- 11:38:55last thing we do is we'll say store
- 11:38:58write whatever is in R2. So write the
- 11:39:00number five to some address in memory
- 11:39:03and that address in memory is held in
- 11:39:06the value of R3. So this will actually
- 11:39:08do the writing um write five into the
- 11:39:12GPIO25
- 11:39:14control line. And so this will now tell
- 11:39:17the computer we intend to use uh this
- 11:39:21GPIO25 which is the LED um in the normal
- 11:39:24quote unquote way of being able to read
- 11:39:27and write from it as if it was just
- 11:39:28random or specific addresses in memory.
- 11:39:31So let me go ahead and clear that code
- 11:39:33out.
- 11:39:37That the IO and GPIO stand for input
- 11:39:41output which means that each of the pins
- 11:39:44can be used to either put in put out a
- 11:39:46value. So write a logical one or a
- 11:39:48logical zero or it can be used to read
- 11:39:51in a value. So if it's connected to some
- 11:39:53circuit that outputs a value, it can
- 11:39:55read in a logical one or a logical zero.
- 11:39:58In our case, we need to specify that um
- 11:40:01the computer doesn't know how we're
- 11:40:02going to use each pin. So, we need to go
- 11:40:04tell it, hey, for this GPIO pin, we're
- 11:40:06going to use it either as input or
- 11:40:07output. For GPIO 25 specifically, that
- 11:40:11is the LED. We know that it can only be
- 11:40:15used for output because it's literally
- 11:40:17connected to a light. So, we can either
- 11:40:18turn that light on or off. But for
- 11:40:21consistency with how every other GPIO
- 11:40:23pin works, we need to go tell the uh
- 11:40:25processor that we intend to use use it
- 11:40:27as output. So if I jump back to the docs
- 11:40:30here, there is this register um GPIO
- 11:40:34output enable set. And if I jump into
- 11:40:37it, uh it kind of gives this implication
- 11:40:40that uh it's similar to the previous
- 11:40:42registers we worked with where it's one
- 11:40:44register and each bit in it corresponds
- 11:40:48to one of the GPIO pins. So in our case,
- 11:40:51we need to go ahead and tell uh the 25th
- 11:40:55bit position, i.e. the bit position that
- 11:40:58corresponds with GPIO number 25
- 11:41:01that we intend to use it as an output.
- 11:41:03And we do that just by writing um
- 11:41:07writing a logical one to it. And so we
- 11:41:10need to figure out where this register
- 11:41:11is. We can see they started a base
- 11:41:13register of hex D followed by a bunch of
- 11:41:15O's. And then this specific one ends
- 11:41:18with
- 11:41:20has the offset hex 024. So if we add
- 11:41:23those together, we'd get D 000000
- 11:41:27several zeros and then 24. So, if I jump
- 11:41:30back to code, I can see that that
- 11:41:31address lives right here. And what I'm
- 11:41:34actually going to do is come down here
- 11:41:37and clear out these three addresses
- 11:41:38because we're not going to read them
- 11:41:40anymore. The code that that used them
- 11:41:42once has already been executed. By the
- 11:41:44time we get to this top instruction, we
- 11:41:46know that we're not going to read those
- 11:41:47values again since we've accomplished
- 11:41:49what we needed to.
- 11:41:51What we will do, though, is load um
- 11:41:55128 into R3.
- 11:41:58So if I do that, this is what the binary
- 11:42:01looks like. Notice that there's one bit
- 11:42:03position on followed by seven zeros.
- 11:42:06We're not done with this. Uh it kind of
- 11:42:07is an arbitrary value for now, but we'll
- 11:42:09come back to that. Then what we'll do is
- 11:42:11we'll load
- 11:42:13into register 2.
- 11:42:16um whatever address is hex 20 below what
- 11:42:20we're at right now, which corresponds to
- 11:42:22this address ending in 308, which is the
- 11:42:25address of that GPIO um output set
- 11:42:30register.
- 11:42:32Then what we'll do is we know we need to
- 11:42:36turn on the uh 25th bit but right now
- 11:42:41the bit mask we have in register R3
- 11:42:44corresponds to the uh seventh bit.
- 11:42:48There's notice how there's seven zeros
- 11:42:49after here. Um so we end up doing is we
- 11:42:52want to left shift this content. I left
- 11:42:55shift means um chop off a zero at the
- 11:42:59end and move it over to the right. We
- 11:43:02want to left shift 18 times. And that's
- 11:43:04exactly what this instruction right here
- 11:43:06does. It'll say, "Hey, take register R3,
- 11:43:09its contents, left shift them 18 times,
- 11:43:12and then write that result back into
- 11:43:13register R3." And so if I copy what R3
- 11:43:19looks like after and R2 is unaffected by
- 11:43:21this instruction, we can see that um
- 11:43:24this actually is masking the 25th bid
- 11:43:28position uh the one that corresponds to
- 11:43:31our GPIO number 25. And so what we end
- 11:43:34up doing in this next instruction is
- 11:43:37storing
- 11:43:39the value in R3 into RAM at the address
- 11:43:43specified by R2. So this writes into
- 11:43:47this um GPIO
- 11:43:50outset register. And so now we've told
- 11:43:54the computer, hey, we want to use this
- 11:43:56specific register for output or this
- 11:43:59specific GPIO pin for output. The very
- 11:44:02last thing we can finally do now is
- 11:44:04actually write a one to that pin so
- 11:44:08it'll turn on the light. So what we need
- 11:44:11to do is jump back to the docs. And the
- 11:44:16register we actually want to write into
- 11:44:18is this GPIO outset. And the structure
- 11:44:23is pretty much the same where each bit
- 11:44:26position corresponds to a GPIO pin. In
- 11:44:30our case, the 25th pos 25th bit position
- 11:44:34corresponds to the 25th um GPIO pin. And
- 11:44:37if we write a one to that specific bit
- 11:44:40position, it'll turn on the LED.
- 11:44:45So, oh, the last thing we need to do is
- 11:44:47figure out where the address of this
- 11:44:48register is. We see it has the same base
- 11:44:51address of hex D followed by zeros. And
- 11:44:54then in this case,
- 11:44:57the offset is hex14. So, we'd expect the
- 11:45:01uh address to be d some number of zeros
- 11:45:04ending in 14. If I tab back, that's
- 11:45:07exactly what this address and uh this
- 11:45:11this value and this address has right
- 11:45:13here. So we see we in our next
- 11:45:16instruction, we load into register 2
- 11:45:18that specific address uh hex 20 below
- 11:45:21where we are in the program counter.
- 11:45:26And then that's all that instruction
- 11:45:28does. Then this store uh does the same
- 11:45:35write of this bit mask. And I apologize,
- 11:45:38I deleted R3, but it actually never
- 11:45:40changed from the code above. So I'll add
- 11:45:41that back in.
- 11:45:45It'll store the same value that just has
- 11:45:47a 25th bit position set to the address
- 11:45:50held in the R2 register, which is
- 11:45:53specifically the GPIO out set um
- 11:45:56register. And so what this will actually
- 11:45:59do is after everything we've done, it'll
- 11:46:01actually finally go ahead and turn on
- 11:46:03the light. But after we do this, the
- 11:46:06computer's
- 11:46:07trivial or I guess naive is a better
- 11:46:10word in the sense that it executes this
- 11:46:12instruction. We want to end the program
- 11:46:14here, but the program counter is just
- 11:46:16going to increment and keep executing
- 11:46:18what comes below it in memory. We want
- 11:46:20to halt our program effectively. Just
- 11:46:22leave the LED on. So, this last
- 11:46:24instruction we have, I'll delete these
- 11:46:26two since we don't need them. Um,
- 11:46:29is just a branch, an unconditional
- 11:46:31branch, meaning it'll always just branch
- 11:46:33no matter what, uh, to this address
- 11:46:35right here. But this address is the one
- 11:46:37we're executing. So, pretty much all
- 11:46:40this line will do is keep jumping to
- 11:46:42itself, which means the program counter
- 11:46:44can never make it further than what
- 11:46:46we're at. Um, which effectively is a
- 11:46:48halt. The code can never make it to any
- 11:46:51other instruction in memory. So, what
- 11:46:54will happen if we put this computer uh
- 11:46:56this program on our on our little
- 11:46:57microprocessor is it'll set up all the
- 11:47:00initialization needed to turn on the
- 11:47:03LED. It'll turn it on and then it'll get
- 11:47:06stuck on this instruction. So, as long
- 11:47:08as it has power, it'll never do anything
- 11:47:10else. So, what we can go ahead and do is
- 11:47:13actually put that program um onto the
- 11:47:16computer. And let me switch back to my
- 11:47:17camera and let's see how it runs.
- 11:47:21So, I've gone ahead and installed the
- 11:47:24program on this uh microcontroller. I'll
- 11:47:27skip the part of how I actually
- 11:47:28installed it because uh it's a pretty
- 11:47:31interesting side discussion, but
- 11:47:32unfortunately with the timing
- 11:47:34constraints, I'm not going to be able to
- 11:47:35get to it in this video. But what I
- 11:47:38should expect if the program we built is
- 11:47:40fully correct that as soon as I plug
- 11:47:42this in via the USB port and give it
- 11:47:45electricity, the only thing that we
- 11:47:47should be able to perceive with our
- 11:47:48eyes, there's a lot more going on. We
- 11:47:50obviously can't see instructions getting
- 11:47:52executed um in the same way we could
- 11:47:54with the old computer because it's it's
- 11:47:56just so much smaller and there's not
- 11:47:57like all these these lights for our
- 11:47:59human interpretability. But what I would
- 11:48:02expect is the LED right here that you
- 11:48:05can't see that well, that copper looking
- 11:48:07uh circle should just turn on. And
- 11:48:09that's all that should happen. It
- 11:48:10shouldn't turn off. It should just turn
- 11:48:12on. Um, and so I have power. Let's go
- 11:48:16ahead and do that. I'm going to go ahead
- 11:48:17and plug it in.
- 11:48:20And you can see uh it just turns on. And
- 11:48:23if I unplug it, it kills power to the
- 11:48:25program. It's done. Obviously, it can't
- 11:48:26turn on the light without electricity as
- 11:48:28a source. But if I plug it back in, it
- 11:48:30should rerun the exact same bite code
- 11:48:32that we programmed onto it in the past
- 11:48:34half hour. Uh, which means that the LED
- 11:48:36should just once again turn on. And this
- 11:48:39is cool. The computer will hold the
- 11:48:41program forever until it's rewritten. So
- 11:48:44no matter what power source I connect
- 11:48:46this into, as long as it gets
- 11:48:47electricity, that light will just turn
- 11:48:48on. Obviously, this is a pretty trivial
- 11:48:51program. Um, but we could make this more
- 11:48:54interesting. For example, let's say we
- 11:48:56wanted to blink the light. How would we
- 11:48:57update our program to do that? One
- 11:48:59natural way is just pretty much we know
- 11:49:02how to turn it on and we know how to
- 11:49:04turn it off by writing a zero to that
- 11:49:06same register effectively. Um, turns out
- 11:49:08there's actually a separate register,
- 11:49:09but that's a separate discussion. Uh,
- 11:49:11the the concept is fundamentally the
- 11:49:13same. What we could do is just load a
- 11:49:16value, a really large value into a
- 11:49:18register and keep subtracting it down by
- 11:49:20one and then once it gets to zero, turn
- 11:49:24off the light and then start the same
- 11:49:26cycle uh the same sequence where you
- 11:49:28load a really high number, count it down
- 11:49:30to zero one at a time and once it hits
- 11:49:32zero, turn the light back on. And the
- 11:49:35computer, I mean, it runs at a pretty
- 11:49:37fast clock speed, but if we're dealing
- 11:49:38with very large numbers, counting down
- 11:49:39by one will actually take hundreds of
- 11:49:42milliseconds. um which means that it
- 11:49:44gives the illusion of this light
- 11:49:45blinking and pretty much changing that
- 11:49:47number from lower to higher will mean
- 11:49:50that the it'll slow down the blink cycle
- 11:49:52and if I make that countdown number
- 11:49:53lower it'll make it blink faster and
- 11:49:55faster. Um so unfortunately we just got
- 11:49:59around to looking at this computer and
- 11:50:00there's a ton of interesting stuff we
- 11:50:01can do. If I had more time, I would have
- 11:50:03loved to continue playing around with
- 11:50:04the GPIO pins and see how we can
- 11:50:07interface with external sensors or even
- 11:50:10write, you know, text to a screen as
- 11:50:11I've done here. But, uh, unfortunately,
- 11:50:15I'm bounded by YouTube's 12-hour upload
- 11:50:17limit. Um, and so this feels like the
- 11:50:19best stopping place I could reach for
- 11:50:21this video. I wanted to take just a
- 11:50:23little bit to recap everything we've
- 11:50:24done. Uh, on one hand, we culminated
- 11:50:28nearly 12-hour video with just turning
- 11:50:29on a light. Um, but the more you know
- 11:50:33about it, the more you realize like
- 11:50:34that's a trivial way to look at things
- 11:50:35and there's actually so much more
- 11:50:36happening under the hood. So just as a
- 11:50:39recall of everything we've done, we
- 11:50:41started off looking at binary. Uh,
- 11:50:43humans reason in base 10. We have the
- 11:50:45digits 0 through 9. Computers only have
- 11:50:48the presence or absence of electricity.
- 11:50:50So we dumb our we we dumb it down to
- 11:50:53base 2, which leaves the only digits
- 11:50:55available us to zero and one. But it
- 11:50:57turns out this is just as expressive as
- 11:50:59decimal. Any number that we can
- 11:51:01interpret as humans can be converted to
- 11:51:03binary and vice versa. There's a one to
- 11:51:05one mapping of decimal numbers and
- 11:51:07binary numbers. Once we had binary
- 11:51:10understood, we started looking at logic
- 11:51:11gates and how we can make decisions by
- 11:51:14chaining logic gates together. And then
- 11:51:16we started looking at how we could store
- 11:51:18data. We built the concept of a
- 11:51:19flip-flop and a register. So rather than
- 11:51:21a circuit just taking some inputs and
- 11:51:24yielding an output, we could actually
- 11:51:26hold in a value. And then we started
- 11:51:28figuring out how we could chain both of
- 11:51:29these ideas together to build more
- 11:51:30interesting things. We started off by
- 11:51:32building registers and then RAM. Um we
- 11:51:36also built an ALU. We built the ability
- 11:51:38to add and subtract binary numbers using
- 11:51:40just logic gates.
- 11:51:43And then we chain it together uh by
- 11:51:45adding a bus throwing in more registers
- 11:51:47and then the ability to interpret uh
- 11:51:50instructions or values in memory as
- 11:51:53instructions and then physically with
- 11:51:56more logic gates in a readonly memory
- 11:51:58execute those instructions sequentially.
- 11:52:01And then once we had that, we looked at
- 11:52:03a more modern processor which is uh not
- 11:52:06too dissimilar from the original iPhone
- 11:52:09and saw how we could we looked at its
- 11:52:11instruction set and then also saw how we
- 11:52:13could write programs for that computer.
- 11:52:15And um if we had more time, what I'd
- 11:52:18like to look into next is a few things.
- 11:52:21Number one, how can a computer actually
- 11:52:23write to a display? I think you have a
- 11:52:25highle understanding, but we didn't get
- 11:52:26to see it in practice, so I think it
- 11:52:28might be a little bit confusing. Number
- 11:52:29two is what actually happens when you
- 11:52:31power on a computer. We said that RAM's
- 11:52:34kind of initialized as all zeros or
- 11:52:35random memory. So how is a program
- 11:52:37physically stored on this chip and how
- 11:52:39is it such that when we actually give
- 11:52:42the computer power, it just starts
- 11:52:43executing that program. Turns out
- 11:52:45there's a several really interesting
- 11:52:46things that happen early and this is
- 11:52:48called like the boot sequence. Um and
- 11:52:51the third and last thing that I'd like
- 11:52:52to look into if I had more time in this
- 11:52:54video is how computers run multiple
- 11:52:57programs at once. your computer, you can
- 11:52:59multitask, you can have a video playing
- 11:53:01um while texting someone, while browsing
- 11:53:03the web. And uh the the computer we've
- 11:53:06architected here can only run one
- 11:53:09program at a time. Uh but computers have
- 11:53:11this clever little trick that actually
- 11:53:13allows them to um give the illusion of
- 11:53:16running multiple programs at once by
- 11:53:18quickly swapping between separate
- 11:53:20programs uh in quick succession so they
- 11:53:22each get a little bit of runtime. Um,
- 11:53:26this video ended up being way longer
- 11:53:27than I expected. I'm not sure if anyone
- 11:53:29will ever watch it, but it was awesome
- 11:53:32for me to make this. I am sure there's
- 11:53:34some gaps in parts of the videos. It's
- 11:53:36my first time doing something like this,
- 11:53:37so if there's any questions, um, feel
- 11:53:41free to leave a comment. I promise I'll
- 11:53:43monitor the comments and respond to
- 11:53:44anything that's ambiguous. And uh if
- 11:53:47time permits, uh maybe one day I can get
- 11:53:50around to making a follow-up video if
- 11:53:52there's uh any number of people that
- 11:53:54actually watch this and have interest.
- 11:53:56Um I don't know if I could do a whole
- 11:53:57another 12-hour video if no one's going
- 11:53:59to watch it. But yeah, uh thank you
- 11:54:02everyone or anyone is probably a better
- 11:54:04word who made it this far. And I hope
- 11:54:07you learned something. This was probably
- 11:54:08the most interesting part of my computer
- 11:54:10science degree and I think a lot of
- 11:54:12software developers out there don't have
- 11:54:14a good enough understanding of what's
- 11:54:15happening at a low level. Um, but to
- 11:54:17take something that's very like foreign
- 11:54:19and actually break it down and see
- 11:54:21what's happening down to the flow of
- 11:54:22electricity is very powerful. And now
- 11:54:25you know that uh this computer I hold
- 11:54:27and most computers that you interface
- 11:54:29with are nothing more than logic gates
- 11:54:32chained together in very interesting
- 11:54:33ways to manipulate electricity to do
- 11:54:36very interesting things. Um yeah, thanks
- 11:54:38everyone.
About this transcript
This page contains the full transcript of How do computers work? (from scratch, no prior knowledge needed) by Milen Patel, generated from the public captions YouTube serves with the video. The transcript has 122,012 words across 16,693 segments, with the original timestamps preserved so you can click any line to jump to that moment in the embedded player.
What you can do with it
Use the transcript to take notes, quote the speaker, build a study guide, generate a summary with ChatGPT or Claude via the YouTube Summary tool, or export it as a timed subtitle file with YouTube to SRT. You can also re-open it in the transcriber to translate the transcript into 100+ languages.
Free YouTube transcript tool
YouTube2Text is a free YouTube transcript generator — no signup, no daily limit. Paste any YouTube link and get the full transcript instantly, with timestamps, click-to-jump, translation to 100+ languages, AI prompts for ChatGPT, Claude, and Gemini, and exports to TXT, SRT, VTT, or Markdown.