Assignment 8, due Oct 20Solutions
Part of
the homework for CS:2820, Fall 2017
|
Consider this alternative class hierarchy:
Gate / \ LogicGate ConstGate / \ TwoOutGate NotGate / \ AndGate OrGate
a) Look at each of the fields and methods declared in classes AndGate, OrGate, NotGate and ConstGate, and identify each field or method that should be moved into class TwoOutGate in order to minimize code duplication. For each method moved, identify the class or classes it comes from and identify any challenges posed by moving the code. (0.5 points)
First note, class TwoOutGate above is stupidly misnamed, it should have been called TwoInGate, but that changes none of the answer.
Fields in1used and in2used belong in TwoOutGate. Methods registerInput and checkSanity belong there. All of the above come in identical duplicate code from classes AndGate and OrGate.
Fields in1used and in2used are private in the original code and they can remain private because the only code that references them is also moved to the same class. Changing these declarations to protected is unnecessary but creates no problems.
b) Look at each of the fields and methods declared in classes AndGate, OrGate, NotGate and ConstGate, and identify each field or method that should be moved into class LogicGate in order to minimize code duplication. Use the rules for stating your answer given above. (0.5 points)
We can move registerOutput from AndGate, OrGate and NotGate to class LogicGate. This has no associated fields and creates no interesting problems.
Assume that class ConstGate has a method outputChangeEvent(t) that is used only for the change described above, where the parameter t indicates the time at which the change occurs.
a) Where in the code for class ConstGate should the code go that schedules outputChangeEvent? In the context of the posted solution to Machine Problem 3, there are just two reasonable answers. (0.5 points)
One solution: Schedule the event immediately in the constructor.
Another solution: Schedule the event in checkSanity where it will be called after all of the model is constructed before any simulation takes place.
A solution I hadn't anticipated: Schedule the event the first time registerOutput is called connecting a wire to the true output. This solution is more than a bit clunky and complex, since it requires logic to detect that this is the first call to registerOutput on that output pin.
b) Write the code that schedules outputChangeEvent using the simulation framework at the end of the notes for Oct. 10. This code should be written so that it can be "pasted" into the location you give in part a) of this problem. (0.5 points)
For either of the two solutions I originally considered, the code is fairly simple:
Simulator.schedule( delay, (float t)->outputChangeEvent( t ) );
This assumes that outputChangeEvent for const gates knows that it only applies to the true output and that it always forces a false to true transition on that output.
A problem: There is exactly one part of nextFloat that has no usable analog that would work in the context nextInt. (It involves a feature of class Float that has no analog in the context of class Integer.) (0.5 points)
There is nothing in class Integere analogous to Float.NaN, so we need to think of a different way for nextInt to signal an error.
The code distributed on Oct. 20 (for the Oct. 19 lecture) solved this problem by throwing an exception, and nextName and nextFloat were modified to do the same.
schedule( time + delay, ... );
Assum you have written class PRNG discussed in the notes for Lecture 15, with a method randomFloat(f) that returns a value from 0.0 to f (some positive floating point scale factor).
A problem: In a real logic simulator, gate delays are not constant. Rather, they vary slightly and randomly each time a gate's output is changed. Rewrite the above code fragment so that delays vary over approximately a 10% range from 0.95 to 1.05 times the base delay for the gate. (0.5 points)
schedule( time + (delay * 0.95) + PRNG.randomFloat( delay * 0.1 ), ... );