WEBVTT

00:00:00.729 --> 00:00:05.470
In this problem, we are going to consider
several instructions that we want to add to

00:00:05.470 --> 00:00:06.870
our beta.

00:00:06.870 --> 00:00:11.949
For each of these instructions, we will need
to decide what the minimum requirement is

00:00:11.949 --> 00:00:14.539
to add that instruction.

00:00:14.539 --> 00:00:19.859
The simplest addition would be a macro that
references a single already existing beta

00:00:19.859 --> 00:00:21.789
instruction.

00:00:21.789 --> 00:00:27.589
If our new instruction cannot be implemented
by simply defining a macro, then we want to

00:00:27.589 --> 00:00:33.270
consider whether adding a new opcode, and
producing the appropriate control ROM signals

00:00:33.270 --> 00:00:39.969
for it, will enable the new operation to be
executed on our existing Beta datapaths.

00:00:39.969 --> 00:00:46.590
Finally, if neither the macro or Control ROM
solutions work, then we need to specify that

00:00:46.590 --> 00:00:56.949
the instruction cannot be implemented without
making actual hardware changes to the Beta.

00:00:56.949 --> 00:01:02.730
The first instruction that we want to consider
adding to our Beta is a SWAPR instruction

00:01:02.730 --> 00:01:09.190
which swaps the contents of registers Rx and
Ry in a single clock cycle.

00:01:09.190 --> 00:01:13.870
The constraint that this must be done in a
single clock cycle points us to the fact that

00:01:13.870 --> 00:01:19.000
the Beta hardware does not have the ability
to write to two different registers in the

00:01:19.000 --> 00:01:20.539
same clock cycle.

00:01:20.539 --> 00:01:29.220
Thus, in order to add this instruction to
the Beta, new hardware would need to be added.

00:01:29.220 --> 00:01:34.880
The next instruction that we want to consider
adding to our beta is a NEG instruction.

00:01:34.880 --> 00:01:40.860
This instruction should take the two's complement
negation of register Rx and store it into

00:01:40.860 --> 00:01:42.789
register Ry.

00:01:42.789 --> 00:01:47.770
The first question we want to ask ourselves
is whether or not we might be able to implement

00:01:47.770 --> 00:01:51.670
this using a macro.

00:01:51.670 --> 00:01:56.289
Since all we are trying to do is produce the
negative of a given value, we can write a

00:01:56.289 --> 00:02:03.950
macro for this instruction which subtracts
Rx from R31 and stores that result into Ry.

00:02:03.950 --> 00:02:08.669
Note that this macro will not work for the
corner case which is the largest representable

00:02:08.669 --> 00:02:14.040
negative number because the negation of that
number cannot be represented using 32-bit

00:02:14.040 --> 00:02:16.569
two's complement representation.

00:02:16.569 --> 00:02:23.680
For all other cases, however, this macro works
as expected.

00:02:23.680 --> 00:02:29.420
The next instruction that we want to consider
adding to our Beta is a PC-relative store

00:02:29.420 --> 00:02:30.420
instruction.

00:02:30.420 --> 00:02:35.519
The way this instruction works is that it
writes the contents of register Rx to a location

00:02:35.519 --> 00:02:44.950
in memory whose address is computed by adding
PC + 4 + 4*SEXT(C).

00:02:44.950 --> 00:02:50.260
The only existing store operation in the beta
is a store that writes to the address that

00:02:50.260 --> 00:02:56.569
is computed by adding the contents of register
Ry and the sign extended literal C.

00:02:56.569 --> 00:03:01.420
Since this is not equivalent to the store
relative instruction's behavior that means

00:03:01.420 --> 00:03:05.310
that we cannot implement this instruction
as a macro.

00:03:05.310 --> 00:03:09.930
So next we consider whether or not we can
implement this instruction using our existing

00:03:09.930 --> 00:03:12.329
Beta datapaths.

00:03:12.329 --> 00:03:19.480
This beta diagram highlights in red the dataflow
through the existing Beta datapaths that would

00:03:19.480 --> 00:03:23.459
perform the desired PC relative store instruction.

00:03:23.459 --> 00:03:28.599
The way this instruction works is that the
extra adder under the instruction memory is

00:03:28.599 --> 00:03:36.120
used to compute the value of the effective
address which is PC + 4 + 4*SEXT(C).

00:03:36.120 --> 00:03:44.879
The ASEL, or A select signal is then set to
1 to pass that value to the ALU as the A operand.

00:03:44.879 --> 00:03:51.409
The ALUFN is then set to A to continue passing
that value through the ALU in order for it

00:03:51.409 --> 00:03:54.900
to be used as the address for the data memory.

00:03:54.900 --> 00:04:00.019
This address is labeled MA, or memory address
in the beta diagram.

00:04:00.019 --> 00:04:04.939
The value that is written to memory is the
value of register Rx.

00:04:04.939 --> 00:04:10.730
In store operations, the first operand corresponds
to register Rc.

00:04:10.730 --> 00:04:18.790
So we set RA2SEL = 1 in order to select Rc,
which is Rx in this case, as the register

00:04:18.790 --> 00:04:22.190
whose contents should be written to memory.

00:04:22.190 --> 00:04:28.060
The value of this register is made available
via the RD2 register file port which then

00:04:28.060 --> 00:04:33.640
feeds the MWD, or memory write data signal
for the memory.

00:04:33.640 --> 00:04:37.940
There are a couple other memory related signals
that we need to set appropriately.

00:04:37.940 --> 00:04:43.171
They are MWR, which stands for memory write
read, and controls the write enable of the

00:04:43.171 --> 00:04:44.530
data memory.

00:04:44.530 --> 00:04:49.650
In order to be able to write to the memory,
the write enable must be set to 1.

00:04:49.650 --> 00:04:52.700
MOE is the memory output enable.

00:04:52.700 --> 00:04:57.770
We set this to 0 to specify that no output
should be enabled from the memory.

00:04:57.770 --> 00:05:02.660
Note that you may think that MOE should be
a don't care since we are never making use

00:05:02.660 --> 00:05:06.540
of the MRD, or memory read data, signal in
our datapath.

00:05:06.540 --> 00:05:12.610
However, by setting it to 0 we allow ourselves
to potentially use the same databus for the

00:05:12.610 --> 00:05:15.260
read and write data of the memory.

00:05:15.260 --> 00:05:20.780
This is not explicitly shown in our beta diagram
but is the reason that MOE is specified as

00:05:20.780 --> 00:05:23.140
0 for us.

00:05:23.140 --> 00:05:27.790
The other control signal that we must set
to 0 is WERF, which stands for write enable

00:05:27.790 --> 00:05:29.760
register file.

00:05:29.760 --> 00:05:35.290
Setting this signal to 0 ensures that no value
will be written back into our register file.

00:05:35.290 --> 00:05:41.200
This allows us to then set WDSEL and WASEL
to don't cares.

00:05:41.200 --> 00:05:47.580
The last control signal is BSEL which is also
a don't care because the B operand is ignored

00:05:47.580 --> 00:05:50.390
by the ALU for this instruction.

00:05:50.390 --> 00:05:57.930
Finally, the PCSEL = 0 in order to increment
the PC by 4 so that the next instruction will

00:05:57.930 --> 00:06:01.860
be fetched.

00:06:01.860 --> 00:06:07.640
So our completed Control ROM for the STR operation
is shown here.

00:06:07.640 --> 00:06:14.910
The last instruction we want to add to our
beta is the BITCLR(Rx, Ry, Rz) instruction.

00:06:14.910 --> 00:06:20.550
This instruction performs a bitwise AND of
the contents of register Ry with the complement

00:06:20.550 --> 00:06:22.880
of the contents of register Rx.

00:06:22.880 --> 00:06:28.990
There is no existing beta instruction that
performs this functionality so using a macro

00:06:28.990 --> 00:06:30.530
is not an option.

00:06:30.530 --> 00:06:35.310
Next, we want to consider whether or not we
could implement this instruction using our

00:06:35.310 --> 00:06:39.470
existing datapaths with changes to our control
ROM.

00:06:39.470 --> 00:06:44.500
To answer this question, you need to realize
that the operation that you are trying to

00:06:44.500 --> 00:06:49.560
perform here is a boolean operation.

00:06:49.560 --> 00:06:55.440
In module 1, when implementing the ALU lab,
we learned that the way that the bool module

00:06:55.440 --> 00:07:04.640
works is that if you set the ALUFN to 10abcd,
then the ALU would produce the output defined

00:07:04.640 --> 00:07:11.080
by this truth table for every pair of bits
Bi and Ai.

00:07:11.080 --> 00:07:20.800
So for example, to implement the AND function,
we simply set a = 1, b = 0, c = 0, and d = 0

00:07:20.800 --> 00:07:26.120
as shown in this truth table which is the
truth table for an AND function.

00:07:26.120 --> 00:07:32.110
The truth table for the BITCLR operation is
shown here.

00:07:32.110 --> 00:07:38.420
One additional column, NOT(Rx)[i] has been
added to show the intermediate step of negating

00:07:38.420 --> 00:07:40.220
Rx[i].

00:07:40.220 --> 00:07:47.270
Then if you take the AND of the Ry[i] column
and the Not(Rx)[i] columns you get the result

00:07:47.270 --> 00:07:49.550
Rz[i].

00:07:49.550 --> 00:07:56.890
This means that the ALUFN for the BITCLR operation
is 10 followed by 0100.

00:07:56.890 --> 00:08:04.620
The rest of the control signals can be determined
by looking at this highlighted beta diagram

00:08:04.620 --> 00:08:09.290
which shows in red the paths that must be
followed in order to properly implement the

00:08:09.290 --> 00:08:10.720
BITCLR operation.

00:08:10.720 --> 00:08:17.580
The instruction memory specifies the registers
Ra and Rb, in our case Rx and Ry, that are

00:08:17.580 --> 00:08:20.540
to be used by this operation.

00:08:20.540 --> 00:08:28.810
Setting RA2SEL to 0 tells the register file
to read Rb, or Ry, as the second operand.

00:08:28.810 --> 00:08:35.249
Then setting ASEL and BSEL to 0 passes the
values of Rx and Ry to the ALU.

00:08:35.249 --> 00:08:42.649
The ALUFN is used to specify the particular
boolean operation that we are performing.

00:08:42.649 --> 00:08:49.920
Then WDSEL = 1 in order to feed the results
of the ALU back to the register file.

00:08:49.920 --> 00:08:55.779
The Rc register is Rz and it is the register
that the result should be written to.

00:08:55.779 --> 00:09:02.019
To make that happen, we set WASEL = 0, and
WERF = 1.

00:09:02.019 --> 00:09:07.730
To avoid anything being written to the data
memory, MWR is set to 0.

00:09:07.730 --> 00:09:13.240
MOE can be a don't care because we are not
using the memory for reading or writing and

00:09:13.240 --> 00:09:21.199
setting WDSEL to 1 ignores anything that is
on the MRD, or memory read data, line.

00:09:21.199 --> 00:09:28.420
Finally, the PCSEL = 0 in order to increment
the PC by 4 so that the next instruction will

00:09:28.420 --> 00:09:31.040
be fetched.

00:09:31.040 --> 00:09:35.980
So our completed Control ROM for the BITCLR
operation is shown here.