Assignment 8: Simulating Circuits
Out on:
April 2, 2008
Due by:
April 14, 2008, noon (before lecture)
Collaboration:
Pairs
Grading:
Packaging 10%, Style 10%, Design 10%,
Performance 10%, Functionality 60%
Overview
The eighth (sp?) assignment puts all the Python you know from weeks seven and nine to use for problems from week one. This whole course is apparently just one big circle! :-)
Since you are working as a pair now, it's important that you coordinate your schedules and stay in touch during the assignment. Working together (physically!), either in a lab or at a laptop in a cafe somewhere, is highly encouraged! (Most programming problems are solved by talking about them, I do the same thing myself when I can't figure out what I am doing wrong...) After the assignment is over, each of you will be asked to evaluate the contribution your partner and yourself made to the assignment. Each member of a pair will receive the same score for the product you submit together.
This is a fairly substantial assignment, and you probably have to meet in person a few times before it's done. Keep that in mind, start working on it early, and ideally set up a few meetings in advance to avoid scheduling hassles further down the road.
Problem 1: Basic Circuits (70%)
Your first task (and the main task for this assignment in fact, check the percentages) is to write a circuit simulator in Python. The simulator reads the description of a circuit in terms of inputs, outputs, logic gates, and wires connecting all of these. It outputs the truth table for the circuit, showing the values of all output signals for each possible combination of input signals.
The simulator should be invoked using
./cs
on the command line.
Obviously not all your code should be in that
file: you should write several modules that in
turn contain functions and classes
for your simulator.
If the file
example.cir
contains the description of a circuit, the command
./cs example
should run the simulator on the file
example.cir
and produce the file
example.tt
containing the truth table for that circuit.
The format of the circuit and truth table files is explained in
more detail below, but this is how we expect to be able to run
your simulator for grading.
The description of a circuit is given as a text file; each line is either a comment or it defines an input, an output, a gate, or a wire. Here is an example:
# circuit inputs and outputs a: IN b: IN c: IN d: OUT # gates making up this circuit X: AND Y: OR # wires from circuit inputs to gates A: WIRE a TO X.0 B: WIRE b TO X.1 C: WIRE c TO Y.1 # wires from gates to gates D: WIRE X.OUT TO Y.0 # wirtes from gates to circuit outputs E: WIRE Y.OUT TO d
Lines that start with a # character are
comments and should be ignored.
Lines that define parts of the circuit start with a
name for that part (can be more than
one character!), followed by a colon
and some white-space (can be more than one blank!),
followed by the actual part.
Let's do the easy cases first:
Inputs are defined by IN,
outputs by OUT,
gates by AND, OR, or NOT.
Couldn't be easier, right?
Wires are (somewhat surprisingly) the most complex part of a
circuit:
the general format is WIRE source TO destination
where both source and destination
refer to other parts of the circuit.
For circuit inputs and outputs, mentioning their name is good
enough.
For gates, however, we have to also mention which
pin of the gate we are talking about;
for now we assume that all inputs are numbered
sequentially and that gates only have one output called
OUT.
The output of your simulator is the truth table of the circuit. For the circuit above, your simulator should output (something close to) the following:
a b c | d ---------------+----- 0 0 0 | 0 0 0 1 | 1 0 1 0 | 0 0 1 1 | 1 1 0 0 | 0 1 0 1 | 1 1 1 0 | 1 1 1 1 | 1
As you can see there's nothing particularly fancy going on here, we just print out a table of inputs and outputs, and for each possible combination of inputs we list the resulting outputs (just one for this circuit).
Aside from the code for this problem, please hand in at least
eight test cases.
Describe how and why you chose those test cases in your
README file.
Each test case should consist of two files, the
input circuit and the output truth table.
Please do not use the extension .tt for
these files as they would be overwritten by the simulator; use
.tt.expected instead; you can use the diff
tool to check whether the output you're generating is really the
output you were expecting.
Problem 2: Gate Delays (20%)
We have treated gates as "infinitely fast" so far, i.e. when we change the inputs we "instantly" get a change at the output. Actual gates, however, have a certain "delay" associated with them, i.e. it takes some amount of time for a change on the input to be reflected as a change on the output. Let's measure time in abstract "ticks" and let's assume that our gates have the following delays:
- NOT: 2 ticks
- OR: 3 ticks
- AND: 5 ticks
Although the delay for a single gate may be too short to
notice, delays "add up" if we string more and more gates
together in more and more complicated ciruits.
Extend your circuit simulator to compute the delay in
ticks for each output of a circuit.
For the input file
example.cir
you should produce the output file
example.dt
containing the delay table for that circuit.
For the circuit above, your output should be (something close to)
the following:
output | delay ----------+--------- d | 8
Aside from the code for this problem, please hand in at least
four test cases that illustrate gate delays.
Describe how and why you chose those test cases in your
README file.
Each test case should consist of two files, the
input circuit and the output delay table.
Please do not use the extension .dt for
these files as they would be overwritten by the simulator; use
.dt.expected instead; you can use the diff
tool to check whether the output you're generating is really the
output you were expecting.
Problem 3: Circuit Errors (10%)
For Problem 1 you had to do some basic error checking, for
example you had to make sure that the part mentioned in a
WIRE actually exists.
However, there a plenty more errors that could occur inside
a circuit file, and now you are required to check for those
additional errors:
- Circuit outputs, gate outputs, and gate inputs must be connected appropriately. You can not allow circuits in which relevant wires are missing anywhere as it would lead to undefined behavior. All gates that contribute to any circuit output must have their inputs wired; this still allows for circuit inputs that are not wired of course.
- Inputs and outputs must be connected consistently. A circuit input or a gate output can be connected to multiple gate inputs or circuit outputs. However, a gate input or circuit output can be connected to at most one signal. For example, you can wire one circuit input to two separate gate inputs, but you cannot wire two separate circuit inputs to one and the same gate input. Furthermore, you can not allow a wire between two circuit inputs or two circuit outputs; you can not allow a wire between a gate output and a circuit input; you can not allow a wire between a gate input and a circuit output.
- Circuits must not have cycles in them. You can not allow circuits where the output of a gate is connected to its own input (or transitively to the input of an ``earlier'' gate that ``affects'' the gate).
There may even be some other error condition that would be nice to check but which I forgot to list here? In any case, if you find an error, you should display a helpful message to the user instead of trying to simulate a broken circuit.
Aside from the code for this problem, please hand in at least
four test cases (hopefully more) that illustrate the
various error conditions you check for.
Describe how and why you chose those test cases in your
README file.
Each test case is just one file, namely the messed up
input circuit; explain the error that should be triggered in a
comment inside that file.
Deliverables
Please turn in a
gzip
compressed
tarball
of your assignment;
the filename should be
cs102-assign-8-login1-login2.tar.gz
with login1 and login2
replaced by your Unix login name on ugradx.cs.jhu.edu.
The tarball should contain no derived files whatsoever
(i.e. no executable files),
but allow building all derived files.
Include a README file (a plain Unix text file) that
contains your answers to written problems, briefly explains what
your programs do, and has any other notes you want us to check
out before grading.
Grading
For reference, here is a short explanation of the grading criteria.
Packaging refers to the proper organization of the
stuff you hand in, following the guidelines for Deliverables above.
Style refers to programming style, including
things like consistent indentation, appropriate identifiers,
useful comments, suitable documentation, etc.
Simple, clean, readable code is what you should be aiming for.
Performance refers to how fast your program can
produce the required results compared to other submissions.
Design refers to proper modularization and the
proper choice of algorithms and data structures.
Functionality refers to your programs being
able to do what they should according to the specification
given above; if the specification is ambiguous and you had
to make a certain choice, defend that choice in your
README file.
If your programs cannot be built/run you will get no points whatsoever. If your programs fail miserably even once, i.e. terminate with an exception of any kind or dump core, we will take off 10%. Finally, make sure to include your name and email address in every file you turn in!
Bonus Problem
The problem you have is problem enough. :-)