whenever we're running a program on our
computer the program is stored in RAM as
a list of instructions and in order to
execute each instruction we have to
fetch it from RAM so for example in the
8-bit computer that we're building a
program will normally start at address 0
and we'll fetch that and execute
whatever instruction is in address 0
then we'll go to address 1 and fetch
that and execute that an address to
address 3 4 5 and so on so we've got to
have a way to keep track of which
address we're on and the way that we do
that is with the program counter so this
video I'm going to talk about what the
program counter is how it works and
we'll go ahead and build it so of course
as the name implies the program counter
needs to be able to count and of course
we've seen in previous video that we can
build a binary counter using JK
flip-flops so a counter like this that
counts in binary is definitely going to
be an important part of our program
counter and in fact our program counter
is going to be a 4-bit counter
similar to this because our the memory
that we built it has a 4-bit address but
in many ways the program counter also
works a lot like a register like a
register or B register you know it
stores a value unlike you know they
register general purpose register light
like a register that is the value that
the program counter stores is always has
a specific meaning it's the address of
the next instruction we're executing but
like any other register you know it
needs to be able to put that value out
on the bus we might want to be able to
read a value from the bus and instead of
just counting in order be able to jump
to a different address arbitrarily by
putting some other value into the
program counter and so the program
counter has a few control signals going
into it so one is this program counter
out and that works just like the a
register out or the B register out it
tells the program counter put your
whatever value you're storing onto the
bus when I say storing you know the
counter like this you see well it's
counting it but if if we stop the
counting by disconnecting the clock you
see it's storing a value with storing in
this case the value 3 0 0 1 1 is 3 in
binary so you know the program counter
is going to store a value
and of course we want to be able to put
that value out on the bus using this
program counter out so when whenever we
enable that signal the contents of that
program counter will be will be asserted
out onto the bus and then some other
part of the computer for example the
memory address register can then latch
in whatever that that address or
whatever that value is into that memory
address register we also want the
program counter to be able to read
values from the bus because we don't
just want to count we don't always want
to execute instruction 0 1 2 3 4 5 in
order in some cases we might want to
jump around if we want to have a loop in
our program for example maybe we want to
execute instruction 0 1 2 3 and then
when we get to instruction 4 we want to
go back to instruction 0 and just run a
loop like that so we need to have some
way of not just counting but being able
to put some other value into the program
counter and so to do that it works very
similarly to any other register where we
have some sort of in control signal that
says take whatever is on the bus and
latch it into the value that you're
storing so in this case that's the the
jump signal and so whenever we enable
this jump signal it says take whatever
is on the bus or at least 4 bits worth
of it - for least significant bits of
the bus because this is a 4-bit counter
not an 8-bit register like these other
things
take those 4 bits and put it into the
program counter and then that'll be the
next address that we execute so this
jump signal works a lot like the a
register in signal is B register in
signal instruction register in signal
RAM in anything like that taking the
value from the bus and putting it into
this register if you will so the program
counter does work a lot like a register
but of course it's also a counter so it
does need to be able to count just like
this and of course we don't want it to
count on every clock cycle so if this is
caught every time every time there's a
clock pulse this is counting and we
don't want the program counter to do to
count every clock pulse we just want it
to count or essentially increment it
once per instruction cycle and an
instruction might take multiple clocks
to to execute
so this last signal here this count
enable input signal allows us to enable
the program counter to to count so
whenever this is is active the program
counter will will actually increment on
each clock cycle and so we can we can
activate this this input when we want to
advance to the next instruction let the
program counter count up by one and then
disable it so that it doesn't continue
to increment while we're executing that
instruction then when we're ready to
execute the next instruction we can go
ahead and increment it again
so our program counter is going to be
based on this simple binary counting
circuit using four JK flip-flops but
we're also going to need some additional
logic to to handle our output in our
jump you know their ability to load in a
value from the bus and this and this
enable option so to make things a little
bit simpler I'm going to use the 74 LS
161 which is a 4-bit binary counter
synchronous 4-bit binary counter
synchronous just means it counts using a
clock and if we look at what's inside
the 74 LS 161 and we've got these four
JK flip-flops very similarly to what we
have in the binary counter that we built
before but we've also got a bunch of
other logic which turns out to be quite
useful for what we're trying to do so so
one thing that's kind of nice is that
the clock that comes in is positive edge
triggered remember a master/slave JK
flip-flop the clock is is inverted here
because the the output changes after the
the clock goes high and then goes low so
it the output changes on the falling
edge of the clock so there's an inverter
here that means that with 74 LS 161 the
output changes on the rising edge of the
clock which which is is a little bit
nicer for us because we want everything
in our computer to to happen on the
rising edge of the clock the other nice
thing that this gives us is a lot of
this logic helps us load a value into
here so rather than just counting 0 1 2
3 4 and so on we have the ability to
load a specific value in using this data
a data B data C and data D inputs so if
we put some value on ABC and D some
4-bit value and then we enable this load
signal then that value will show up how
or on the output and then subsequently
when the counter counts it will count
from that value and so that helps us
implement this this jump function where
we want to be able to load a new address
in from the bus to jump to an address
out of order for loops and that sort of
thing and the other thing that 74 LS 161
gives us is it gives us enable and
enabled input and these enable input
essentially enable whether the counter
is counting or not and so these
basically implement for us this count
enable function so this allows us to
when this when this is not active the
program counter just holds on to
whatever value is in it but then when we
activate this enable then with each
clock pulse it counts and so that's
that's built in for us very nicely in
the 74 LS 161 using these enable signals
and so just to go over the functionality
of the 74 LS 161 it's pretty
straightforward it's got the four
outputs that we want and it's got four
inputs that we can use to load an
arbitrary value into those outputs using
the load signal it's got these enable
signals that allow us to enable whether
it's counting or not and then of course
the clock which each clock pulse
if the navels are active then it counts
and then the other thing that hasn't has
a clear which just resets it to zero
which which will be kind of handy but
not you know not critical and then this
ripple-carry output would be you know
this is a 4-bit counter if we wanted an
8-bit counter or or more bits we can we
can cascade these by taking this ripple
carry out and feeding it into the clock
of the next of the next one so this chip
the 74 LS 161 gives us almost everything
that we need for a program counter it
gives us the ability to control whether
it's counting or not with that enable it
gives us the ability to to load a value
in to implement this jump functionality
by using this load pin but it doesn't
give us the this program counter out
because that that we need some tri-state
logic to interface to the bus here so
that we can control whether the value
that's coming from the outputs of this
chip is actually going out on the bus
for that we can use the same chip we've
been using for for all of our other
registers the 74 LS 245 and so that
again has it has these tri-state buffers
that allow us to enable or or isolate
those bits of course this is an 8 bit
thing we're only going to use four of
them but that's fine this is a same chip
we've been using in our a register B
register Ram using the instruction
register we've used we've used this a
number of times so we'll use this again
for our program counter