The Science of Everything Podcast - Episode 94: How Computers Work Part IV - Processor Architecture and Machine Code
Episode Date: February 4, 2018In this fourth part in our series on computers, I begin with an overview of the von Neumann architecture used in most modern computers. This leads in a discussion of the structure and operation of the... central processing unit, covering the instruction register, the program counter, main memory, the data and address buses, the ALU, and the control Unit. I then discuss the purpose and implementation of a number of key operations in the instruction set architecture, including arithmetic operations, data movement operations, and conditional branches.
Transcript
Discussion (0)
You're listening to The Science of Everything podcast, episode 94, How Computers Work, Part 4, Processor Architecture and Machine Code.
I'm your host, James Fodor.
So in this fourth part of our series on how computers work, we're going to focus on the real nuts and bolts of how the actual processor itself performs instructions that carry out the programs that the computer is running.
So we'll start by talking about von Neumann architecture, which is the basic arrangement of,
design of how modern computers work.
And then I'll go through the details about process architecture.
So this involves the main logic components
that are part of the CPU, the central processing unit,
and how they work together to actually carry out
the instructions that are part of the program that the processor is executing.
I'll then talk about the instruction set architecture,
which is the set of basic instructions
that all programs are formed out.
are formed out of and the purpose of the CPU being to carry out the programs that are written in instructions taken from the instruction set architecture.
So I recommend a pre-listing for this is obviously the previous episode on logic gates and components.
So let's make a start in looking at the von Neumann architecture.
So the von Neumann architecture is also known as the Princeton architecture and it's a computer architecture, essentially the design of a computer that was described
originally in 1945 by mathematician and physicist John von Neumann.
The basic components of the von Neumann architecture are the central processing unit, or the CPU,
which contains two key elements, a control unit and an ALU or an arithmetic logical unit.
The control unit essentially tells the other components of the processor what to do
and ensures they actually carry out those functions, and we'll look at how that happens in a moment.
The ALU is the piece of circuitry that actually performs the key computation,
arithmetic and logical operations and comparisons and things like that.
Now, the central processing unit in the Von Norman architecture is connected via buses to the memory, the main memory.
And in the main memory, is stored both data that forms the basis of the information that operations are performed upon,
and also instructions for the computer to carry out, for the processor to carry out as part of the program.
So this forms what is called the Stored Program Concept.
A stored program computer is one that keeps its program instructions
and its data also in the same read-write, random access memory, or RAM.
So stored-programmed computers are a significant advancement over what came before,
which were program-controlled computers, like ENIAC, for example,
the first digital computer,
which were programmed by essentially setting switches and moving around cables
that essentially rewind the computer every time you wanted to
have it perform a new program. A stored program computer only has to have the program read into its memory,
and then it's capable of executing the program by reading it from the memory. So this is a very
significant advancement over having to essentially redesign the machine every time you want to do something
different. The key concept behind a store program computer is that some instruction will be
fetched from the memory to the central processing unit, the CPU, where it is decoded by the control
unit, which then generates a range of signals in different wires connecting up to different
logic devices within the processor, with those signals driving appropriate operations in the
ALU and also the registers within the CPU. Remember, a register is just a bunch of flip-flops
that is able to store usually one word of data. When completed these operations, then save their
results back to the memory. So this entire instruction cycle is known as the fetch, decode,
execute store cycle because that's the order of the operations you first fetch the instruction
from the memory to the processor. The instructions decoded by the control unit, which then sends
out the signals appropriately to execute the instruction in the ALU and with the registers. The results
are then stored in back in primary memory. So that's the sequence that a von Noomin
an architecture processor goes through in order to carry out its instructions.
And every time it completes a cycle, it fetches a new instruction and keeps going around the cycle.
Part of executing an instruction always involves preparing the processor for
fetching the next instruction to be executed.
So each instruction always brings about a new one in the cycle.
So it doesn't just perform one, the processor doesn't just perform one instruction and then sort of stop.
Each instruction always includes getting ready to know where the next instruction is going to come from
and being prepared for the processor to access that from memory.
In this way, the program continues to execute in the appropriate order.
So essentially, what's happening is that the processor is constantly
at the start of each instruction cycle, sending out an address,
asking it to send the instruction from this particular location in memory.
RAM then sends the main memory then sends the contents of that address
back to the CPU, where the resulting instruction is decoded by the control unit
and the signals thus generated drive the operation of the CPU.
So that's the basic overview of how the processor works.
Now we're going to go through and talk about the details of the process
and how all the components of the processor and memory work together
and how they can be built using the logic components that I discussed in the previous episode.
The micro-architecture of a computer is the design of the logic components
within the processor that collectively allow the computer to function. So it's really the
core hardware of the machine itself. It is the level where software and hardware meet because
the micro-architecture is implemented in hardware, yet it also must be specifically designed in order
to implement a particular instruction set architecture or ISA. An instruction set architecture is a set of
instructions that a given processor can perform. So essentially, whenever a processor reads an instruction
from the memory, that instruction will always be one of a set number of instructions
from the instruction set architecture. That is essentially defined in software. It's defined
in documents that specify what instructions a given process can perform. So in other words,
the way a microarchitecture is designed is generally you start with the instruction set
architecture, the set of instructions that you want to be able to form. And in a simple
ISA, maybe you'll have a few dozen instructions, more complicated ones may have hundreds,
but there aren't millions of them there. A fairly small number of,
relatively simple instructions that can be performed.
So you start with the instructions set architecture,
and then you design the micro-architecture,
you design the exact circuitry of the processor,
so that it's capable of executing all of those different instructions appropriately.
This means that a single instruction set architecture
can be implemented in a wide range of different micro-architectures.
Therefore, understanding the micro-architecture of a processor
allows you to understand how the computer actually carries out its operations.
Even though in order to actually program the machine,
actually need to know what the instruction set architecture is so that you can tell
it what instructions to perform. You don't actually need to know the microarchitecture design
in order to program the machine. And this is again another example of the hierarchy
that I mentioned before. Here we're looking at both the micro architecture and the
level above the instruction set architecture. I should also mention that there are
two main different types of machines. There are so-called complex instruction set
architecture machines and reduced instruction set architecture machines.
And the main difference is how many different instructions are in the instruction set architecture.
Originally, machines started off only having a very few basic instructions, and then as machines got,
computers got more sophisticated, more and more were added, and they became more and more
complicated, and it did more fancy things. But then it was realized that by making the instructions
much simpler and removing a lot of the complicated ones, which, after all, weren't used very often
anyway, it was possible effectively to perform more instructions in the same period of time.
Thus, even though each individual instruction was, on average, less powerful, a processor designed
on this principle was able to perform more of them in a fixed period of time, and therefore
was, on the whole, more powerful. It was also potentially easy to program and debug,
because there were fewer really complicated, tricky instructions that were seldom used anyway.
So this subsequent design is called a reduced instruction set architecture, and
different machines these days use different versions,
either complex or reduced instruction set architectures.
But that's just the point I wanted to mention.
It's not crucial for the other points we're discussing.
Okay, so now let's go through the processor architecture
and explain the different components.
So remember, the purpose of a processor microarchitecture
is to implement, to actually physically carry out in hardware,
all of the instructions in the instruction set architecture.
The instructions in the instruction set architecture, in turn, are selected
so that the machine will be powerful enough to do everything that it needs to.
Remember that from the theory that we discussed in previous episodes,
you don't actually need that many instructions in order for the computer to be touring complete,
to be able to perform all of the possible computations.
You mainly need things like memory access instructions, branching,
and some basic arithmetic and logical operations and a few other bits and pieces
in order to get everything you need.
But we'll look at that at a bit more detail in the instruction set architecture section.
All I want to emphasize at this point is that in order to get the computer to do what we want to,
we need it to have a sufficiently rich instruction set architecture, and we need that to be able to be implemented in the hardware reliably.
And the way we do that, as we've discussed in the previous episodes, is to use logic gates which are built out of transistors.
So I've already explained how we can use transistors to build logic gates and how we can use logic gates to build them, to combine them together, to form logical components which perform useful functions.
Now I'm going to explain how combining those logic components together we can form key functional units within the processor and within the computer and how we can arrange these together in such a way as to be able to implement the instructions of the instruction set architecture.
Okay, so let's jump in and start by talking about the main memory.
The main memory of a modern computer is stored in the RAM, and that stands for random access memory, which just means that you can access.
any memory element whenever you like at any time.
A hard disk drive is not random access memory because you can only access the part of the
hard disk where the reading head is currently in that position.
You then have to move into a different position to access that region.
RAM is not like that you can access any part at any time just by providing the address.
So a simple setup for the main memory is simply to have a very long array of registers.
Remember that a register is simply a chain of flip-flops connected up to each other.
each flip-plop holding a single bit. Each register is usually the length of a single word in the ISA.
A word is just like the smallest unit that you use in processing data or instructions.
So these days it's often 32 or 64 bits long.
But it's always powers of two. So you might have a 4-bit machine, an 8-bit machine, a 16-bit machine, etc.
So however long the word is, each register will hold one word, so one unit of data essentially,
and that register will be made up of a bunch of flip-flops each holding a single bit.
Now, each register in the memory has its own unique address.
So if I have 4 gigabytes of RAM, 4 gigabytes of memory, that's about 4 billion unique addresses.
To access that particular register, what I have to do, what the process has to do is send that address along the address bus,
so the bus specifically designed to send addresses from the processor to the memory.
Suppose I have a 32-bit instruction set architecture.
That means that there will be 32 bits on the data bus, enabling 32 bits from,
each word to be exchanged from the processor to the memory and vice versa.
And the address bus will likely also have 32 bits,
which means that I can address about 4 billion registers of memory,
because I have two to the power of 32 different combinations of bits that I can send on the address bus,
which allows me to uniquely address about 4 billion different addresses.
So the processor puts a unique address consisting of 32 bits onto the address,
address bus, which is then sent over to the memory controller, which sits with the RAM.
The memory controller decodes this address, and from it generates a set of, really, you can think
of it as a set of 4 billion signals that go out and either enable or disenable the appropriate
tristate buffers, which connect each individual register in the RAM to the data bus. So each of my
registers, most of my registers obviously won't be enabled on any given read, because only a single
one of those registers will be enabled on any given address that's sent to the RAM. But I need to have
four billion separate wires coming out of my memory control chip, because I need to be able to individually
access each one of those registers, depending on what address was sent in. So the memory control chip is
just a decoder. I talked about that in the previous episode. A decoder takes in a small number of
bits and outputs, one of a large number of possible bits, according to the
signal that was put in. So we can implement that using logic gates. So the processor, the
memory control chip then takes the address, generates the appropriate signal, output signal,
which then activates the read tristate buffer, which then connects up the output of that register
to the data bus. Each one of the flip-flops in all of the registers will already be
connected up via its own wire to the corresponding bit wire along the data bus.
It's just it requires an enable signal on the tristate buffer in order to form the electrical
connection.
So generally all of them are turned off so that we're not reading any of the registers onto
the data bus.
Only when the RAM itself receives the read enable signal from the memory control chip is one
of those tricep buffers enabled and then the appropriate register puts its data onto the
data bus and then the data bus sends it back to the processor where it can be read in and operated on
as appropriate. Note that there is usually no way of addressing individual bits. So I read a whole
word at a time or no word at all. I can't read individual bits of that word. But if the processor only
wants individual bits or components of the word, then it can perform operations on the word appropriately
and extract the bits that it needs. Writing to memory works effectively the same way, except the difference
will be that in addition to providing an address to where I want to write the memory,
the processor will also need to provide the data that it wants to write to whichever register.
It provides that obviously on the data bus.
So in the case of a write operation, it needs to provide two things simultaneously,
an address and the data to write.
And then with also providing the appropriate enable signal,
it will input from the data bus to the relevant register will be enabled,
because I've turned on the appropriate enable wire,
and when the clock ticks over,
then the data will be ready
and the new data will replace the existing data on the register.
So if we're implementing registers using D flip-flops
that I discussed in the previous episode,
these are ones in which all of the flip-flops
take the value of whatever the input on the,
whatever the D input is,
but they only change upon a clock tick.
So all I have to do here is and my clock-tick wire
with the right enable signal
so that when the exact, correct, right enable signal from to this particular register is enabled by my memory controller chip,
then as soon as the next clock tick comes, it takes, this register will take, and only this register,
will take the data that is read into it from the data bus, and that sequence of bits will be written to the corresponding register.
That's how the processor accesses memory via the data and address buses.
So it needs those two different buses, plus the memory control chip, which is essentially a decoucels.
also tristate buffers to be able to connect and
deconect individual memory registers with the appropriate buses.
Now let's move on to another key component of the process architecture
which is called the instruction register.
Now the instruction register, or IR for short, it's just an ordinary register
so it holds a single word, so maybe 32 bits of data,
so it's nothing fancy, but it's particularly important
because it holds the binary sequence of the current instruction
that the computer is now executing.
So, in some sense, the instruction register is at the very heart and center of what the processor is doing,
because it holds the exact binary sequence that tells the computer precisely what to do in this present operation that it's carrying out.
In other words, when a processor begins with the instruction cycle, so fetch, decode, execute, store,
during the fetch phase, the appropriate instruction will be loaded into the instruction register.
That's what fetching means.
It means putting the right instruction into the instruction register.
All of the rest of the things that the processor does
involves extracting the information that's contained in the instruction register
in order to determine what instruction to carry out and what exactly to do.
So there are a number of different components to each instruction in the instruction register
because there are different things that need to be specified.
Usually the first part of each instruction in the instruction in the instruction.
instruction register is what's called an op code. This is a sequence of bits. The number of
bits depends on how many basic operations there are in your instruction set architecture, but maybe
it's six bits or eight bits or four bits or something like that, a relatively small number of
bits. But this op code tells the process of which operation it needs to perform now. So what
operation the current operation is. And essentially, each possible operation in the instruction
set architecture will have its own unique corresponding op code. You just specify one of these op codes,
and immediately the processor knows exactly which instruction it should be carrying out.
The other components of the instruction register usually include addresses of the registers
that the operation is going to need.
Either those registers will hold the values that the operation will be performed upon,
or perhaps those registers may hold an address, which in turn points to the place in memory
where the data that the operation will be performed on will be found.
Or perhaps those registers will be used,
will be the location where the result of the operation is placed.
So there's many different uses that these registers can be put to,
but the basic idea is that some parts of the Instruction Register
will contain a bit sequence that corresponds to
of one or more registers that are located in the processor itself.
So remember, when I talk about a register by itself,
I'm talking about a specific register with a specific function inside the process.
I'm not talking about the bunch of registers in RAM.
That we refer to as memory.
Another thing that an instruction in the instruction register can include are what's called immediate values.
Essentially this means that it's either a direct location in memory itself where the value can be found,
or perhaps it's just the value itself that the operation is performed on.
So it might be a number, for example, or a NASCII code represent.
a string that the operation then will act upon.
So an instruction can include the data that it's going to act on, or it can include an address
which points to the location where the data can be found.
Another thing that the instruction register can contain are special signals for selecting
which instruction will follow from the current one.
These are called branching signals.
Remember that I said that each instruction that the processor carries out must not only do
whatever it's supposed to do, but it must also, as part of the execution phase,
it must tell the processor what the succeeding instruction will be,
and it must ensure that the next instruction that's carried out is the correct one.
So there are often extra signals in the instruction register
that ensure that the next instruction will be the correct one.
So the op code is the bit of the instruction register that tells the processor
what instruction to do carry out now.
Branching signals and other special instruction bits tell the processor,
what instruction to carry out next ensures that that's loaded correctly.
And then there'll be additional bits in the instruction register that will specify registers
in which either values that the operation will be performed upon are taken from.
So if two numbers are to be added, they might be taken from two registers that are specified in the
instruction register.
And also, the instruction register may also contain immediate values, which could be memory addresses
or just straight-up values that the operation is to be performed on.
So that's the essence of order and instruction contains.
It essentially tells the process what to do now, what to do next, and what to do it on, in other words, what the data is or where to find the data that it needs to perform the operation on.
And that's fundamentally all it needs to do.
As long as the underlying circuitry is set up properly so that the instructions are carried out, that's all the processor needs to know with each instruction.
Another very important register that exists in the processor is called the program counter, or PC.
The program counter is just another ordinary register, like the Instruction Register, that holds a single word, but it's particularly important because it holds the address of the next instruction to be performed.
Note that there's a big difference between the Instruction Register and the Programme Counter. The Instruction Register holds an actual instruction.
So that includes an op code and an address where the operands can be found and so forth.
The program counter by contrast does not hold the next instruction to be informed. It holds an address that tells the address that tells us.
the processor where to find the next instruction.
So there's a big difference between an instruction and an address that points to an instruction.
Therefore, at each iteration of the execution cycle,
the processor will have to send off the address of the program counter to the memory as an address.
So it puts the contents of the program counter onto the address bus and sends it off to RAM,
to read that particular register, that location in the memory,
which is then sent back on the database to the instruction register,
and loaded in as the new instruction.
So you remember that I said that each instruction must ensure
that the next instruction to be performed is the correct one.
The way that it does that is just to ensure that the correct value was loaded
into the program counter-register.
If the right address is loaded in there that points to the next instruction
that you want to be performed, then all is good.
At the next round of the execution cycle,
the program count address will be loaded onto the address bus,
ensuring that the appropriate value was read from memory,
and then will be placed back onto the instruction register,
and that instruction will then be executed by the processor.
Now, usually, that is, if nothing else is done,
the program counter is incremented, essentially the value of the address increased by one,
so that the next address in the next memory cell, the next register on,
will just be loaded into the instruction register.
So that's the standard procedure.
And if you recall, this corresponds to the sequence control structure
that I mentioned in the three key control structures that we needed in order for a programming
language to be true and complete.
One of them was sequence.
The other two were iteration, so doing something as long as a Boolean condition holds and then
stopping once the condition no longer holds, and the third was essentially conditional, so do something
only if this condition holds.
So this sequence control structure is implemented by the practice of, in general, just
incrementing the program counter and therefore accessing just the next instruction in line in memory.
However, the program doesn't have to just take the next instruction in line in memory.
If it wants to, it can what's called branch, so it can jump to somewhere else in the memory.
And one way that that can be done is to just load the address directly into the program counter.
So one instruction, for example, could be, in the instruction register with the appropriate op code,
it could say, load this address value and it could provide the address as an immediate value, for example,
load this into the program counter. And so it would just load that address directly into the program
counter and then jump to the next cycle in the execution cycle. So what would happen is that it would
just jump directly to the address specified in the instruction, and the program counter would now
hold that value, and it would grab the instruction from that address, and instruction will continue
from there. You can also have conditional branches, which don't always jump to a set place,
which don't always send the program counter to a set address, but we'll send it to one place if a value is
positive and another place if the value is negative and so forth. So the point is that by
setting the address in the program counter to the right value, we can ensure that the next
instruction that the program takes is the one we want it to. In addition to the instruction
register and the program counter, a processor also typically holds a number of additional registers,
the purpose of which is to hold various values that need to be easily accessed by the processor
as it's carrying out its different instructions. So, for example, it's common.
for the ALU, the arithmetic and logical unit, to have a set of registers from which it loads its two operands.
So the ALU typically takes in two different operands, the two inputs that it will operate on and puts out at least one output.
Each of those two operands are usually taken from a specific register that specifically provides that operand for the ALU.
Another common type of register is called an immediate register, which holds constant values that can be used directly for operations.
So an instruction might specify you take the value from the immediate register and put it in a different register or load it into the ALU or something like that.
So the number and names of the different registers are usually built into the instruction set architecture directly, and thus they are visible to the programmer.
So a simple instruction set architecture might describe a machine that has a handful of registers.
The more registers you have, the more flexibility you have when programming the machine in terms of data that you can just easily access, that you don't have to specify an address for.
and go to RAM and take from memory.
When all you have to specify is a specific register,
you can usually do that with just a couple of bits
because there are only a few registers,
and so it's easy to specify which you want.
If you want to specify an address in memory,
not only does it take a lot longer to access it,
but you have to specify like 32 whole bits
to uniquely specify exactly which register in RAM you want.
So it takes a lot more space to hold their instructions.
So it's handy to have more registers to work with
just to sort of use for intermediate values
or operands or results of computations and so forth.
But it's not necessarily to have a large number of those.
It just tends to make things easier.
Now, the ALU, the Arithmetic Logic Unit,
is a special combinatorial logic circuit,
which is capable of performing basic logical
and arithmetic operations on two input operands.
Remember, it typically takes those operands
from special registers that provide them
and that in turn are loaded into by instructions
from the Instruction Register.
In addition to its input, the ALU also takes a number of control bits which select which operation to perform,
and it may also output special status bits to indicate, for example, if there's been a carry bit with an additional operation,
or if there's been overflow, or if the results of some computation is negative or zero, things like that.
These status bits are often useful for error correction or for branching operations.
For example, I might perform a comparison, and I might want to have a special bit
that tells me if the result was negative.
So say if one number was less than another,
it might give negative,
or if two numbers were the same,
the output might be zero telling me that the difference between them is the same.
So these special status bits that come out of the ALU
are useful for conditional branching operations.
The control bits of the ALU, though,
is essentially the op code, or at least a part of the op code.
Remember, the op code is the sequence of bits in the instruction register,
which tells the processor which instruction,
of the many in the Instruction Set Architecture should be performed right now.
At least part of those bits, so maybe not all of them, but some number of those bits
will go directly to the ALU to tell the ALU which operation to perform.
Not all of the instructions in the Instruction Set Architecture will actually need the ALU.
Some instructions only move data from one registered to another, for example, and that
doesn't involve the ALU.
So those won't need to send any op code to the ALU.
But many operations will require the ALU, and when it does, you'll need to
select which of the many operations that the ALU is capable of
actually should be performed on this cycle.
And so, like any combinatorial circuit, you just send a number of input bits
and depending on the exact sequence of those bits it selects what operation to perform.
And again, it's very easy to implement that by just ensuring that the
output of my ALU is connected up to a multiplexer
and that the control bits just feed into that multiplexer so that I can select
which of the various functions I actually want to
to output as a result. So for example, I might have my inputs connected up to a full adder,
which is inside the ALU to a bunch of knot gates, a bunch of and gates, and a bunch of
or gates, all of which are located inside the process. And maybe I'll put a comparator in there
as well, so I can compare the two inputs. So there's a bunch of different functions that I can
execute. I can add the numbers, I can subtract them, I can knot them, I can add them, I can
all them together, or I can compare them and see if one's bigger than the other.
So the ALU can do all of those things, and to select which of those functions I want,
I just input the appropriate control bits, the multiplexer will then select out which of the functions to perform.
So effectively actually the ALU performs all of the functions.
It's just that we'll only output one of them according to what I select using my multiplexer and my control bits.
So the appropriate result is then output from the output of the ALU and then it will be stored on some register for later used by the processor.
An ALU can be implemented as I mentioned before by just combining a number of the components that I'm discussed in the previous episode.
So there'll be a full adder in there for sure.
There'll probably be circuitry also to perform subtraction and multiplication and division.
There'll be a circuitry that's capable of performing bitwise logic operation, so not and an or.
Bitwise means it just compares each of the two corresponding bits of the inputs one at a time.
There may also be a comparator in there which allows me to compare the two inputs.
And as I said, also likely some sort of multiplexer which allows me to select which of the operations I want.
So by combining these different components together in the appropriate way,
you can build an ALU, which is capable of performing all of these different operations.
Also note that when I say that the ALU takes in two inputs and gives one output,
I mean that it takes in two words as input and gives one word as an output.
So each input might consist of, say, a 32-bit number.
So they may take in two 32-bit numbers, perform all the operations on them,
and then select one of the results of those operations to output as a single 32-bit number result.
The control bit inputs will often be much less than the word length.
There may only be a few of those needed to specify the different functions that it can perform.
The ALU is extremely important because it is the component of the CPU that performs the many computational operations necessary to actually run the program.
We now come to the control unit.
Now the control unit is, as I mentioned previously, it's part of the Von Neumann architecture.
It's also the, at least seems to me, the single component that is,
It's most often overlooked if you read many accounts of how processes work, a process or architecture.
The reason, perhaps, is because the control unit is complicated, but also the control unit's not directly involved in the transfer of data or instructions around the computer.
It's not part of the data path.
You don't send data to the control unit directly, like you transfer data between the memory and the ALU or the instruction registers, for example.
So it's often left out of diagrams that only include the data paths,
that is the lines that actually transfer the bits that the computer operates on.
The control unit is essentially a giant decoder.
Its purpose is to take in input from the instruction register.
So the main input to the control unit is just all of the bits of the instruction register.
It will also take input from the clock.
and its output is a series of control signals.
These control signals tell each component of the processor
and also parts of the RAM as well, what to do
and ensure that they do that at exactly the right time
in order to carry out the operations.
So when I used phrases before,
like the instruction register tells the processor what to do
and ensures that the processor knows what to do,
what that actually means,
obviously because the processor doesn't have an intelligence behind it,
it's just a set of logic gates and wires connecting them.
What that actually means is that the instruction register is wired directly into the decoding logic in the control unit,
such that each instruction in the instruction register will produce just the right set of control signals,
thanks to the control unit, in order to cause precisely the correct operations to happen in precisely the correct order.
So it's not so much that the instruction register or the control unit tells the rest of the computer what to do and it somehow knows how to do it.
The control signals actually cause those relevant instructions to take place.
And usually that simply consists of either sending the right input to a combinatorial circuit like the ALU or enabling a tristate buffer so as to connect a register up to a bus or something of that sort.
Usually that's what control signals consist in.
Now, there are two main ways of implementing a control unit.
You can use what's called the hard-wired or hard-coded approach,
or you can use something called microprogramming.
Hard-wire control units are implemented using combinatorial logic gates.
Essentially, this is what I discussed in the previous episode about logic gates.
Combinatorial logic circuit is just a sequence of logic gates.
The output is, of which is solely determined by the current input.
So a flip-flop is not a combinatorial logic unit,
because its output also depends on the past value that it had.
But the ALU is an example of a combinator logic unit
because it doesn't have any memory cells in it.
So a register is not a combinator logic unit, but the ALU is.
Now, hard-wide control circuits can be implemented through combinatorial logic circuits,
featuring a large number of gates that generate the specific signals that you need
based on the instructions that are sent from the instruction register.
Hard-wire control units are generally faster than microprogram designs,
and I think they're also conceptually simpler to understand,
which is why I'll focus on them here.
But I did just want to mention micro-programming,
because you might come across it if you look up
any of your own sources about this sort of thing.
Micro-programming involves,
instead of using combinatorial logic
to generate all of the signals that you need,
actually just storing all of those signals
in a special memory
that called the micro-program.
So this means that instead of generating the signals
a new each time I need to execute a particular instruction,
just storing the exact bit sequence of the signals that I need in special registers in the control unit
and then just outputting those, essentially reading them off, whenever the relevant instruction is called.
So that's often simpler to implement because you just have a big array of special registers
and write the micro program essentially as a software exercise and then just input it into the ROM.
so this is a read-only memory. Usually you can't change it after it's being manufactured.
You won't want to change the micro program, the computer would stop working.
But you just input it there as a sequence of bits, zeros and ones in the ROM memory,
and then that's it. You don't have to implement the complicated combinatorial circuitry
that you have to in a hard-coded version.
The downside, though, is that they're generally a bit slower because you have to perform
a memory access instead of just direct combinator logic.
It generally involves a few more transistors.
in the process.
I think another downside is that although they're simpler to implement,
they're conceptually more difficult because when you have a micro-programmed
processor, you have to keep track of two different memories, the main memory and then
the micro-program memory.
And therefore you need two different program counters and two different instruction registers
to keep track of either the macro-instruction or the micro-struction that's currently being
performed.
And I think that's a bit confusing.
So here I'm not going to talk any further about micro-pro.
other than just mentioning it here, and we're going to focus on the hard-coded or hard-wide approach.
So if the microprogramming stuff confused you, just forget about it.
I just wanted to mention it to highlight the fact that there are two quite different ways of doing this.
So in the hard-coded version, what we do to implement a control unit is just to build a complex combinatorial logics circuit that takes in as input,
basically all of the bits from the instruction register and sends as output the required control signals to implement the desired instructions.
And basically you can implement these fairly straightforwardly, although potentially quite tediously, by just the careful arrangement of logic gates and multiplexes to select the right outputs that are needed.
For example, suppose that a particular register is needed in operations 1, 3 and 5.
never mind what the operations are. Just suppose it needs to be read onto the main
data bus, say, in those three operations but in no others. That means that I need to output a
control bit that turns on the tri-state buffer that reads out the input of that register
onto the database in operations 1, 3 and 5, so that specific control signal will be set to 1,
only in those three operations, but in none of the other operations. I can do that,
obviously just by an appropriate combination of all gates. So that control signal is one if
I have Operation 1, Operation 3, or Operation 5, but 0 in any other case. That's a simple example
of the type of thing I mean by a combinatorial control logic sending out the right control
signals. Another example would be that I might have a certain number of control bits that I
send to the ALU to select the right function to perform, and maybe a particular control bit needs
to be one if I want to, if I want the ALU to carry out Instruction 7 or Instruction
3. It just happens to be the coding is such that a given bit is 1 only in those two cases.
Well then, again, if I want to carry out instructions 3 or 7, I just have an all-gate set-up
so that only in those two cases do I output the relevant ALU control bit as a 1.
In all other cases, the relevant ALU control bit is a 0, because I don't need that particular
control bit. That's another example of the type of control signal that the control unit needs
to output. And it needs to output all of these to all of the relevant things that compare
that have to be controlled in the processes. This includes all registers that could be read from or written to from the buses.
It also includes the ALU control bits and any bits that you need to determine where the ALU gets its input from.
If there are different places that it can select, say maybe there's different registers that it can select as input.
That will need to be, the control bits for those will need to be generated as well.
There will also need to be control bits for where the program counter takes its next value from.
Usually there'll be one control bit which will just say increment and therefore the next instruction will come from just the next location in memory or a different control bit will be sent so that the program counter say takes its value from some register in the processor so that you can jump to a different place for example.
And so the relevant control bit would need to be sent to a multiplexer, say, allowing you to select where the input into the program counter comes from.
Whenever there are different registers that can be connected up to each other, maybe the main memory connected up to different registers, or the program counter connected up to different registers, or the instruction register connected up to different registers, or whatever it be, I might need to send control signals to a multiplexer so that I can decide which of those inputs to select up.
Or I could use tri-state buffers as well. Often you can implement the system using either or of those.
So these are all of the control signals
that the sorts of control signals
that will need to be sent out.
And generally there'll be quite a few of them.
Even very simple processes
with only a few dozen instructions
may need several dozen
of these control signals
so that everything is done
when it should be in the appropriate order.
And it's the job of the control unit
to generate these appropriately
using a combinatorial circuit.
Exactly what control signals need to be generated
depends on the precise
micro-architecture of the processing.
question. So this is what I mean when I said that even if you have two
processes that are implementing the same instructions at architecture, so even
if they're carrying out the same instruction, they may need to generate
different control signals if their register layout is slightly different,
or if the ALU is configured differently, or if anything else is slightly
different, the control signals that need to be generated will be a little
bit different. So this depends on the exact micro architecture
of the processor, that specific machine.
Now, to try to make this a bit more concrete, I'm going to discuss some simple examples of a hypothetical micro-architecture,
which involves just a three-stage instruction cycle.
Fetch, decode, and execute all on the second phase, and on the third phase,
we'll have store, so storing the results back to memory.
So the way we're going to do this, and again, I emphasize that there are many different ways
that you can design the micro-architecture of a processor,
but this is just a simple example to illustrate the key ideas.
So in this example, what we'll do is say that each of these three stages will occur for every instruction that is performed by the processor.
So always there will be a fetch phase, always there will be a decode and execute phase, and always there will be a store phase.
Now, we can use a counter, remember I talked about counters in the previous episode, they just output signals to tell us which phase the processor is currently on.
So in this case, I only need to be able to count up to three, so I only need two flip-flops in my counter, and in fact I don't even need to use.
all the outputs of those. So I only need to be able to say whether I'm on phase one, phase two,
or phase three. And we just cycle through those using the output of the clock coming from the
fed into the counter and then coming out from the counter. So on phase one, always what I will
do is place the contents of the program counter onto the address bus and as well as a read-enable
signal that then reads the corresponding register from the main memory, places that on the
data bus, and then sends that back to the instruction register,
placing that, whatever the word is that it found in the corresponding register, placing that
in the instruction register. So that will be the next instruction that the processor will carry out.
That should happen whenever the counter sends one, a signal of one, indicating that we're on
the first phase of the cycle. That should happen regardless of whatever's in the instruction
register at the time. That is, for any, whatever the previous instruction was,
always at the start of the cycle, load the relevant new instruction into the instruction
register. So this is fairly simple to do. All I have to do is ensure that the phase one
signal that comes in from the counter that's connected up to the clock, it goes through the
control unit and turns off all of the other control signals except for those needed to
enable a read to occur from main memory and a right to occur into the instruction register.
So there'll be a couple of control bits probably for tricyte buffers to ensure that that can
happen, but all of the other control bits will be turned off.
Now, at the next stage, in Phase 2, I now sent the Phase 2 signal that comes from my counter into the Decode logic.
And now, in this case, we're going to have a lot more signals being activated, because this is the Decode and Execute Phase.
So what will happen here is that my control unit will take as input all of the bits of the Instruction Register and decode it.
So there'll be a decoder in there, which, according to the value of the Op code, produces a set of control.
of control bits, which it then sends around to the various components of the processor to ensure
that they perform the corresponding instruction.
So this will only happen on the appropriate second phase of the three, so I can just end all
of the outputs with the phase two bit coming from the counter if I want this to happen, so that
whenever it's not phase two, none of these control bits will be sent out.
That's one easy way of doing it.
So when there is phase two, the bits from my instruction register will be sent off to the control unit.
In fact, they'll already be there.
It's just that they'll actually be used now.
They'll be decoded using the decoder there and the appropriate control signals sent off.
So what might those control signals actually be?
Well, it will depend, obviously, on the exact operation that I've asked my processor to carry out.
One example of an operation could be a move operation, which just involves moving data from one register
to another. In computer parlance, moving data from one register to another actually means
copying it from one register from another. You don't actually delete it from the original
register, but nevertheless, it's called moving. So to perform a move operation, all I have to do
is assert an enable signal to the correct register to write the data to the bus. So the source
register, I send an enable signal to the appropriate tri-state buffer to write that register to
the data bus and send a signal to a multiplexer.
to ensure that I now load the appropriate address from some different register to the address bus,
which then sends a signal to the RAM,
enabling that data to be written from the data bus to the particular target cell,
a target register, in the main memory.
So there are going to be a few TriState Enable bus enables there,
and maybe a couple of control units, control signals to send to a multiplexer
to ensure that I select the address from the given register that I want,
and not from some other register to send off on the address bus.
But still not too much that needs to be done there.
It's basically just enabling some tristate buffers.
You want to make sure that they're the right ones corresponding to the right registers,
and of course that can in turn be specified by some other bits contained in the instruction register.
So, for example, if I specify 101 in my source register section of the instruction register,
that means that it will take the address from the register that is specified by 101,
whatever register that corresponds to.
And that will just be hard-coded into the system so that it takes that address, decodes it,
and then generates the correct source signal to enable that particular register
to load the address that it contains onto the address bus and then read that location from memory.
And if I want to read my location from a different register,
then I'll just put the appropriate bits into the road.
section of the instruction register and instead a different sequence of control bits
will be sent off and that register's address will be loaded onto the address bus.
So this is why I need to be able to specify in my instruction register not only what
operation to perform but also where to get the operands from which registers to get
it from or possibly just a full address that I will then put on the address bus
and access from main memory. So that's one example of the control signals used to
perform a move operation. What about an ALU operation? Well in this case I'll need to
enable the correct control bits for my ALU, so those will need to be sent from the control unit,
depending on what operation I wanted to perform, whether it's addition or multiplication or an and operation or something else.
I will also need to send signals to ensure that the correct source registers are used for the operands that that instruction, that that operation is carried out upon.
So again, there might be multiple different source registers that I can take my inputs from, and depending,
on which of those registers I've specified in the instruction in the instruction register,
different sets of control signals will be sent to enable those registers to write to the input,
or maybe I could use a multiplexer to select which of the inputs that I want to send to the ALU.
Again, it's the same basic idea.
I just need to ensure that I select the right registers to write into the ALU,
and the right instructions to be performed in the ALU,
and then I'll output that result onto some register.
again, and where the ALU puts its output could also be determined by control signals that are sent by the control unit,
and in turn are generated by some instruction that I've included or some sequence of bits that I've included in the instruction register.
So maybe there's a sequence of bits that tells it to put the result in register 1,
and a different sequence tells it to put the results in register 2.
And that's carried out by sending just the right control bits, which are generated by the circuitry in the control unit.
The final example of a type of operation that I might want to perform is a conditional.
branch. So in order to carry this out, once again, I'll need to send enable signals to the
correct registers to load into the ALU, and I'll need to send the right ALU op code to ensure
that it performs the right comparison on those inputs. I'll also need to send an enable signal
to the program counter to ensure that I update it properly, perhaps again sending the control
signal into a multiplexer that tells the program counter instead of just incrementing itself
to take its new value from some other register. And maybe I
I need yet another control value to specify which register that is that the program counter
will take its new value from depending on the output of the ALU's comparison operation.
So this might include using that special output of the ALU that I mentioned according
to whether the value is a positive or negative.
I might feed that into the multiplexer or something so that in one case the multiplexer
will select one place to take the new value of the program counter from and in the other case
to select another place to take the new value of the program counter from so that I can
specify that the next instruction will be X if my result is less than zero or Y if it's
greater than zero where X and Y are just arbitrary address locations in the memory. So essentially
all of these control bits that are being sent out during the decode and execute phase boil down
generally to sending out signals enable signals to tri-state buffers to load something onto a bus,
sending out control bits to the ALU to ensure that it performs the right operation, sending
control bits into multiplexes so that I select the right input
for a bus or the program counter or other registers
and a few other special control units, control signals that do this, that or the other thing
to ensure that the thing works properly. But mostly that gives you the sense of what all these control bits are doing
and we need to ensure that exactly the right combination of these control units are sent
because if even one control bit is off then the wrong register might be loaded onto the bus or
or a register will read a value from the bus at the wrong time,
or the wrong operation in the ALU will be performed,
or the computer will branch to the wrong location
because we've loaded the wrong address into the program counter
or something like this.
So we need to be sure that our decode,
our decoding unit in the control unit works perfectly,
and it always sends out the right sequence of control bits
when given a particular instruction in the instruction register.
Now, in the final phase that I mentioned,
remember I talked about three phases in this hypothetical example,
Phase 1 just involves loading in the new instruction, depending on wherever the program counter is pointing to.
The second phase is the decode and execute phase, which I just talked about, which executes the instruction.
The final phase involves storing the data somewhere and also incrementing the program counter so that it points to the location of the next instruction.
So again, the appropriate signals to do both of these things can be generated by the control unit,
just ending all the outputs with the Y signal carrying the phase three signal from my counter,
so that those signals will say to increment the program counter, for example,
will only be generated during the appropriate third phase of the cycle.
And so the reason you want to have this counter sending in phase signals to the decode logic
is so that I can ensure that different aspects of an operation occur in the right order.
For example, to ensure that I load the right instruction into the instruction register before I try to decode it and send off control signals.
So I can change the control signals that I generate not only based on the current instruction that's there,
but also on the sort of phase of the instruction cycle that I'm currently in.
Carefully designed processes, in fact, can do everything in a single phase,
but it's often easy to think about multiple phases and therefore doing operations one after the other,
in accordance with what sort of sequence we are in terms of the clocks.
cycles. Okay, so to finish out this episode, we've finished talking about the micro-architecture of
the processor. Hopefully you have some idea about how the operations are actually implemented. I now
want to talk a bit about the instruction set architecture, which is the abstract instructions
that are performed by the micro-architecture of the processor. All high-level programs in any
programming language must ultimately be reduced down to a set of instructions in the instruction
set architecture that can directly be run on a particular processor.
Now, this is the job of a compiler, which I'll talk about in a later episode, but the important
thing to realize is that the only thing that the hardware can directly execute is a sequence
of instructions from the instruction set architecture.
It can't understand anything else.
So the instruction set architecture, as I mentioned previously, must be carefully designed
so that the resulting machine is too incomplete, so that it can perform all the operations
that it needs to.
It'll also need to be designed to ensure things like that it performs relatively quickly,
so it has high performance, that it's easy to program on and other things like that.
Now, in theory, it's actually possible to build a Turing complete machine using only a single instruction,
although that one instruction has to be quite complicated.
But in practice, this isn't very practical, so usually even the most simple instruction set architectures have a few dozen instructions.
What are these instructions, you might ask?
What are the basic instructions that constitute a given instruction set?
architecture. Well, they vary obviously depending on which instructions that architecture you're
talking about, but usually they fall into a handful of main categories. First, there are data movement
instructions. Now, these involve copying data from one register to another, or from a register
to the memory, or from the main memory back to a register. Usually exactly one word is copied,
though sometimes you can copy more than one word at once. Movement instructions may sound kind
of trivial because you're just moving data from one place to another, but they're critical in ensuring that
the right data is in the right place, the right register, at the right time, because, for example,
the data might need to be in a specific register for the ALU to be able to use that as input
in order to compute some function. Another place that's an important place to have the right
data at the right time is the instruction register, which specifies what instruction to perform
now, and the program counter which specifies the address of the next instruction to be performed.
So obviously, all of these registers need to have the right data at the right time,
and data moving instructions are crucial in ensuring that that can be done.
The next type of instruction are ALU operations.
So these include arithmetic and logical operations like addition, subtraction, multiplication, division,
sometimes more complex mathematical operations as well.
Also logical operators like or and a knot.
That's the second type of instruction set architecture operation.
Obviously, there are different instructions depending on what operation I want to perform,
just as there are different data moving instructions depending on where I want to move the data to and where I get it from.
A third class of instruction is our conditional branching operations.
Now, as I mentioned before, in order to be cheering complete,
a computer must have the ability to conditionally select which instruction to perform
on the basis of some test that's performed.
Often this is done by performing a branching operation
depending on whether two numbers are equal to each other
or whether the difference between them is positive or negative
or something of that sort.
Usually the instruction will specify where to branch to
if the test fails and where to branch two if it succeeds.
So often it will, the program will just continue normally if the test fails,
if the test succeeds, so say if the two numbers are equal or one is greater than the other
or whatever the test is, then the instruction will include an address
or a register where you can find the address that specifies where the program needs to jump to now.
So that is now the program will load in the new location to the instruction register
instead of just continuing to execute the instructions in sequence.
Another type of conditional branching operation that you can perform is test to see an overflow has occurred.
So for example, if adding two numbers together I have an overflow bit or a carry bit,
that's useful for certain types of error procedures that I might do perform.
A fourth type of instruction that is crucial for most instructions that architectures are input and output operations.
So these type of instructions vary a lot between different systems,
but the basic idea is that they allow the processor to read input and also provide
provide output to input output devices, like a monitor or a keyboard or a mouse.
Typically, these are fairly similar to data movement instructions,
although there are some specific details that relate to the particular device in question.
They often involve interrupts, for example, in which the input device sends a special signal
to the CPU telling it that, hey, I've got input that you need to look at, that needs to be processed.
I'll talk more about interrupts and how that's implemented in the hardware in the next episode,
So I won't go further into that now.
But just emphasizing that sort of the four key types of operations
or four of the main types of operations
that will be included in in instruction set architecture
are data moving instructions, ALE operations,
conditional branching operations, and input-output instructions.
There will generally be other things as well,
like some error handling instructions, for example,
and various other things.
But these are some of the four most important ones.
As I've said before,
each instruction set architecture has its own unique set of operations to perform.
But that doesn't mean that each processor has its own unique set of operations because, as I mentioned, different processes will share the same instruction set architecture.
It's very costly and difficult to design a new instruction set architecture.
It also means that when you have a new instruction set architecture, you need to recompile all of your programs to work on it because they all have different instructions that the programs can call upon.
So your old programs that worked on your old ISA won't work on your new one without being rewritten.
So for this compatibility reason and also for cost reasons, it's desirable to reuse the same ISA,
perhaps adding some new instructions now and then, but making them backward compatible
so that the old programs will still work on the new systems.
A very good example of a long-running backward-compatible instruction set architecture
is the X-86 instruction set architecture.
This is used on pretty much all laptops and desktop computers that you'll get these days,
whether they're Mac or PC ones, because most of the Intel processes,
the consumer processes that you can buy,
like the core I-3 and I-5 and I-7,
all use the X-86 instruction set architecture.
So this is compatible with processes that go way back into the 1980.
So this means that even programs written for computers way back then
will still work on computers today,
because they're still using the same underlying instruction set architecture.
The processes are designed, the micro-architecture,
the way that these instructions are carried out has changed a great deal as processes have been developed,
but the instruction set architectures that the set of operations that are performed on the underlying processor
have more or less stayed the same.
Another major RSA is the ARM, which is used in many smartphones and mobile devices.
So the fact that this is different to the X-86 ISA that's used in many desktops and LAPRM,
is part of the reason why programs that work on your smartphone won't generally work on your
desktop, at least without alterations, because they're using different instruction set architectures.
And so the actual set of machine instructions that you send out to the processor on your mobile phone
will be different to those that you send out on your computer, on your desktop computer,
because they have different instruction set architectures.
A final couple of points that I want to make about instruction set architecture before
summarizing what we've discussed in this episode. One is that in many instructions
that architectures, instructions can come in different formats, where effectively they have
different lengths. So, for example, there might be a special bit in each instruction that tells
the processor what type of instruction it is, whether it's an instruction that includes, say, a
four-bit op-code and three different addresses, or maybe it includes an eight-bit op-code
and only two addresses. Or it may be a 16-bit op-code and no addresses. A different
these different types of instructions may be useful for different purposes.
If I don't specify three addresses, for example,
then perhaps I only specify the two input addresses
from where the ALU takes its input, but not the output address.
Maybe that's just left as some hard-wide default as an example.
But the point is that different instruction formats
may be useful for different purposes,
and it's possible to design your instruction set architecture in this way,
so that each instruction doesn't have to have exactly the same format.
Some can specify more addresses,
and some can specify less, some can have longer op-cos and some can have shorter op-codes.
As long as there's a clear pattern that allows the control unit to detect what type of instruction it is,
then that's perfectly fine.
The second point that I wanted to raise is that in an instruction set architecture,
there are generally many different addressing modes that can be used.
So that is when I specify an address, there are different ways that I can specify what that address refers to.
The simplest way is called immediate addressing, and this is just when an instruction includes
the value of the operand itself.
That is, I don't even include an address.
I just include the operand, like the number, or the string,
the ASCII coding of the string that I want to perform the operation on.
For this to be possible, you have to know what the value is at compile time,
that is when the program is written.
And so it can't be something that's actually computed during the course of the program.
So immediate addressing is useful only for constants, usually,
not for things that are sort of computed during the program.
Instead, it's more common to use things like direct addressing in which I don't specify the value itself,
but I specify the full memory address of where the program can find the operand.
Again, that must be known at compile time.
I don't need to know the value, but I do need to know where the value will be located in memory.
So that's useful for, say, global variables which stay the same for the whole program,
but not for things that change over the course of the program, because the location in memory.
might change. The most flexible way is called register indirect addressing, which involves
specifying the register address that in turn contains an address in memory where the operand
will be. So in this way, we don't need to know beforehand, that is at compile time, where the
operand is, or even what address it's to be found in. All we need to know is that here's the
register where you can find the address in memory that in turn contains the operand.
And so the program itself can then put the right address in accordance with whatever computations have already been performed and ensure in turn that the correct value is placed in that memory address.
Another addressing mode is called indexed addressing which involves specifying an offset from a known location in memory.
So this might be useful for, say, iterations where I say now you start from say this location in memory and then access the
register that's 10 units down from that or 15 units down from that or however many.
So there's a set offset that is accessed. In some instruction set architectures
you actually don't ever specify the operand because for every instruction the
operand always is taken from exactly the same register and you just have to
ensure that you always load the right value to that register before performing
the operation. That's called stack addressing. So that involves more move
statements but the greatest simplicity in terms of where you get your values from.
So don't worry if the different modes confused you there. I don't want to
delve into the details of that too much. The point is to simply emphasize that
there are different ways of specifying where you get your data from. You can
specify the data directly as a number or you can specify that's immediate
addressing. You can specify the address in memory directly. That's direct
addressing. Or you can specify a register which contains an address that in terms of
contains the data, that's register indirect addressing, or you can use indexed
addressing, which has a fixed offset from a known location, or you can use stack addressing,
which is effectively not providing an address and just hard-coding up your computer so
that it always takes the operands from a single-set location, a single-set register in your
processor.
So that's all I wanted to talk about today.
Just a quick summary of what we've discussed.
In this episode, we've focused on process architecture, specifically explaining how the von Neumann architecture works.
The key components of the von Neumann architecture are the arithmetic and logical unit, which actually performs the computations, like addition and logical operations and number comparisons, etc.
There is also key registers that are located in the processor, specifically the instruction register, which contains the bit sequence corresponding to the current instruction that's being performed by the processor.
and the program counter, which specifies the address in memory of the next instruction
to be performed by the processor.
Also in the processor is the control unit, which takes the bit sequence from the instruction
register, and depending on, especially the op code, also other information in that bit sequence,
generates a sequence of control signals that are connected up to all of the other components
in the processor and also memory, ensuring that the correct set of
procedures are carried out according to whatever instruction has been sent to the processor
at that particular time. The processor is connected to the main memory via two main buses, the
address bus in which an address is loaded to access a specific register in memory, and a
data bus into which the whatever data that was located on that memory is placed and then sent
back to the processor. The purpose of all of this microarchitecture is to execute the program that
specified in machine language as a sequence of instructions, all of which are taken from the instruction set architecture.
So a given process that implements a specific instruction set architecture.
This occurs in the fetch, decode, execute, store cycle.
So at each instruction cycle, the processor always fetches the instruction to be executed depending upon what address is specified in the program counter.
that's fetched from memory and loaded into the Instruction Register.
The Instruction Register then sends its bit signals out to the control unit,
which, depending upon the current phase in the instruction cycle, which comes from a counter,
but also depending on the operation and location of the operands,
all of which are specified in the Instruction Register,
it will generate all of the control bits that are needed
in order to cause the processor to carry out the relevant operation,
whether that's a comparison and a conditional branch,
which will change the program counter,
or whether it's an arithmetic operation in the ALU
or moving data from one register to another or whatever else it be.
At the end of that, once the instruction has finished being executed,
the results will then be stored into an appropriate register
or summary main memory, again with that driven by outputs from the control unit.
So the arithmetic logic unit performs the sort of core computations.
the control unit drives the whole process, ensuring that the right registers are loaded at the right times,
and the right control bits are sent to multiplexes to select inputs for buses,
and control bits sent to the ALU to select the correct operations and other things like that.
And the memory, the main memory, contains all of the key data,
including data and instructions that run the program,
which can be read to and from at will, depending on whatever addresses the process,
chooses to send out to access from the main memory.
And that, in a nutshell, is how a modern computer works.
So, hopefully you enjoyed this episode.
If you did, you may consider writing a favorable review of the podcast on an aggregate
of your choice, such as iTunes or one of the many others that exist.
If you have questions, suggestions, or feedback, you can feel free to email me.
My address is Fods12 at gmail.com.
That's FODS12 at gmail.com.
Thanks very much for listening.
and I'll talk to you next time.
