logic.c
. In addition to implementing the standard operations of
the LC3 machine, you will provide an implemetation for FLADD
(details to follow),
to provide a 16 bit floating point addition operation.
You will likely add many functions to the code that has been provided to you. However, many of them are likely to be very short (2 to 3 lines).
Version | Date |
1.0 | Nov 19 17:18 |
2.0 | Dec 2 10:30 |
3.0 | Dec 2 3:30 (fritz - updated instructions, added OSX files) |
cd
there.
mkdir PA6
cd PA6
.tar
file for your OS to the PA6
directory.
tar
file. WARNING: this tar ball will spew
files into the current directory. It does not unpack into a subdirectory.
tar -xvf *.tar
mysim
make
You should see the following (the warning about write_DR is expected).
./fixPath install.c mysim-tk /bin/chmod 500 mysim-tk touch .path /usr/bin/gcc -g -Wall -c -std=c99 -DFLADD_OP install.c /usr/bin/gcc -g -Wall -c -std=c99 -DFLADD_OP logic.c logic.c:32:13: warning: 'write_DR' defined but not used [-Wunused-function] /usr/bin/gcc -o mysim mysim.a install.o logic.o
./mysim-tk -norun
or
./mysim -norun
if you prefer the command line version.0x200
. The is the LC-3 operating
system code. Note that you see labels, but NO code. What is
happening is that the main program is loading the object code for the LC-3
operating system and storing it in memory by calling
logic_write_memory()
. Because you have not yet implemented
this function, nothing is actually stored in memory!logic_write_reg()
, but you
have not implemented this yet.logic_write_memory()
and logic_write_reg()
. Study
the code for logic_read_reg()
and
logic_read_memory()
and the functions documented in
hardware.h
. Review all the provided source code and plan
what you need to do before writing code. You will NEED to use the
functions in hardware.h
and definitions in logic.h
.
The field functions (see documentation in field.h
) are
avaiable. Read that documentation carefully.
When you are prepared, do the following:
logic_write_reg()
and
logic_write_memory()
.make
and re-build your simulator../mysim-tk -norun
or
./mysim -norun
..0x200
.logic_fetch_instruction()
logic_fetch_instruction()
logic_decode_instruction()
logic_execute_instruction()
You will complete the first function and then work incrementally on the other two to complete your assignment.
The function logic_fetch_instruction()
is quite similar to the
function logic_read_memory()
, but the value needs to end
up in the instruction register (IR). Look at the functions documented in
hardware.h
. Also read the documentation of this function to see
what else it must do.
To test this, use the single instruction LC-3 program:
.ORIG x3000
ADD R0,R1,R2
HALT
.END
Create the program with an editor and assemble it using lc3as
. You
can now test whether your implementation works. To test it, do the following:
make
to rebuild the simulator.-norun
).logic_fetch_instruction()
is correct, you will see the
ADD
instruction in the IR.ADD
instructionADD
instruction work. This involves
adding code to both logic_decode_instruction()
and
execute_ADD()
.
Looking at the code for
logic_execute_instruction()
, note that the switch
is
based on the field opcode
. This implies that the function
logic_decode_instruction()
MUST set that field at a minimum.
In setting the fields of this data structure, the field functions (
see documentaion for field.h
) will be very useful.
Look at the simple LC-3 program above and figure out what additional pieces of
information the instruction will require. Add code to
logic_decode_instruction()
to determine those values. Note that in
this program, no immediate value is used, so you can delay implementing that
portion of the code. If you wrote the assembler programming project, you
will find that the logic_decode_instruction()
is essentially doing
the inverse of what pass_two()
did.
At this point, you are going to take a little detour to make
completing the code
for execute_ADD()
easier. Look at the function
write_DR()
. Many methods write to a destination register.
So, if you decide to
implement this method, it will prove useful for other instructions as well.
As its
name implies, the function stores a value in a register.
It does one other thing.
Look at the LC-3 ISA operation descriptions in appendix A in the book
and determine what else every store
into a register does. Add
code for this operation. Alternatively, you can delay writing code for this
second operation. It will not be needed until you work on BR
.
Now return to the execute_ADD()
function. The ADD
instruction adds two values and stores the result in a register. The two values
come from SR1OUT
and the SR2MUX
. These values can
be filled in during logic_decode_instruction()
. Note that
SR2MUX
is an array of two values. Think about how bit5
is defined and how it might be used as an index into SR2MUX
.
In summary:
logic_decode_instruction()
to get the
opcode
.logic_decode_instruction()
to get the
register values needed for ADD
.write_DR()
. inst_fields
struct (see its comments), you may wish to add code to logic_decode_instruction()
to get the
SR1OUT
and SR2MUX[0]
values.execute_ADD()
to do the add and store the
value. Make sure the function returns OK
.make
and fix any problems.ADD
instruction, you will need to
handle immediate
values. This requires only a very small change in decoding and execution. Make
those changes and test it with another simple test program.
Congratulations, you are done with one instruction. You are really a lot
further along that that. You should be able to finish the AND
and
NOT
instructions with minimal effort. And you have a nice utility
routine that will be used elsewhere as well.
The computation of the effective address will use the ADDR1MUX
and
ADDR2MUX
. Look at the documentation for the data structure
inst_fields
under the data structures tab of the assignment webpage..
The MUXs are modeled as arrays.
MUXs do not actually store anything, but simply take multiple inputs and select one
of the inputs as the output, depending on the select lines. In this model,
the array holds the inputs and the select is actually an index into the array.
The array values are set as part of logic_decode_instruction()
and
used in logic_MARMUX()
.
You will now implement code for decoding/executing a single LC-3 instruction at a time. The following sequence may be useful:
LD
).logic_decode_instruction()
to set these values
in the data structure inst_fields
.logic_MARMUX()
to handle this
instruction.For this assignment, you can assume that all input programs are correct in the following ways:
TEST! TEST! TEST! Once you are happy, execute the simulator without the
-norun
. The OS will now load and print out the welcome message.
This is a good test of your work because many (but not all) of the LC-3
instructions are used in the OS. You can also set up regression tests
that compare the output of ~cs270/lc3tools/lc3sim with mysim.
field.c
, but
not the other parts.
You may find it useful to run your simulator and the class simulator (from ~cs270/lc3tools) side by side and single step both of them and compare what you see.
If you like to do debugging with printf()
, you may do so, but you
will NOT be able to use the GUI version of the simulator. This is
because printf()
is used to to send data from the simulator to
the GUI and your printf()
may cause the GUI to die.
The command line version of the simulator (mysim
) has no
problems with additional output. However, grading WILL be affected,
so you must turn off any degugging in the code you submit!
Even though you do not have all the source code, you may use gdb for debugging.
If you are comfortable with the console lc3 simulator, you may use gdb as you were shown in earlier recitations. Simply do the following:
gdb mysim
logic.c
. This is the only file you are modifying for this
assignment. The general gdb syntax is break functionName
run -norun
This start the lc3 simulator, but does not
execute any LC3 code. The lc3 simulator program is running, but will halt
at any mysim breakpoints you have set.continue
to return control to the LC3 console.If you prefer the GUI version of the lc3 simulator, you may still use gdb but you will need to do several additional steps.
mysim-tk
).
ps -fu yourLogin | grep mysim
and you will see several processes listed. One will be the grep
,
one will be the mysim-tk
and the third will be the actual
simulator mysim
. The process ID will be the first number on the
line.logic.c
. This is the only file you are modifying for this
assignment. The general gdb syntax is break functionName
continue
This resumes the lc3 simulator.continue
to return control to the LC3 GUI.logic_write_reg() logic_write_mem()
workingADD, AND, NOT
working with/without immediate valueLD, LDI, LDR, LEA
(4 instructions * 2 pts each)ST, STI, STR
(3 instructions * 2 pts each)BR
working in various formsJSR, JSRR
workingJMP, RET
workingFLADD
working for normal valuesFLADD
working for non-normal valueslogic.c
using the
checkin
program. Use the name PA6. At the terminal
type:
~cs270/bin/checkin PA6 logic.c
The above command submits your assignment. For a sanity check, type the following to get the file you checked in and make sure it compiles and runs properly with the provided files:
mkdir sanityCheck cd sanityCheck tar -xvfRelax, you are done with your assignment! The semester is almost over. :)/lc3sim-start-XXX.tar ~cs270/bin/peek PA6 logic.c > logic.c make // Do LOTS of test cases.