At BCIT, two of the courses I took were Discrete Mathematics and Computer Architecture. Both of those courses got into the Boolean logic and gates. We talked about a few different circuits: adders, multiplexers and decoders, memory circuits, an ALU. Inevitably, one of the tasks I had to do was trace the path a signal took through a circuit and identify which outputs would be asserted. It felt very tedious, it had very strict set of rules, and it was error-prone. Perfect job for a computer to do.
So I started building a program to calculate the output of circuits for me, with some interactive possibilities. This required some way to represent the different circuits to the computer, so I decided to take it farther and make a reusable node API for circuits. After some though about what I wanted it to be able to do, I came up with this set of goals for what the user would be able to do:
- See a graphical representation of each gate and the links
- Indicate which gates/wires were activated
- Pan across the circuit
- Zoom in and out
- Click an input to activate/deactivate it
- Switch between prebuilt circuits via a drop-down menu
- Auto-focus (zoom/pan) on the circuit based on the area of interest it covers
Programmatically, I wanted to be able to write a circuit by typing something like:
- andgate = new GateAnd(x, y)
- input1 = new Input(x, y)
- input2 = new Input(x, y)
- output1 = new Output(x, y)
- Link(input1, andgate)
- Link(input2, andgate)
- Link(andgate, output1)
So I set that as my mission and started programming. The resulting function signatures were a little longer, to be able to specify specific gate ports, scale factors, and link path shapes. The actual code equivalent to the above, looks like this:
- input1 = new GateInput(0, 0, 3, GateState.OFF);
- input2 = new GateInput(0, 100, 3, GateState.ON);
- andgate = new GateAnd(150, 50, 3);
- output1 = new GatePin(300, 50, 3);
- Gate.connect(input1, -1, andgate, 0, Link.HVH);
- Gate.connect(input2, -1, andgate, 1, Link.HVH);
- Gate.connect(andgate, -1, output1, -1);
- output1.setLabel("Output");
- output1.setLabelSide(GatePin.NW);
Specifying my goal at the outset really helped me achieve what I wanted, and design something usable. I feel proud of the API I ended up with, and I reused it once already creating a binary tree visualizer.
Download the jar file here