Class Subcircuit

java.lang.Object
io.zucchini.circuitsimtester.api.Subcircuit

public class Subcircuit extends Object
Represents and wraps the subcircuit to test.

Holds a CircuitSim CircuitBoard (also known as a "subcircuit") and the CircuitSim instance used to simulate it.

Your tests shouldn't need to touch this, since it mainly provides methods for loading a subcircuit from a file and poking at its internal state to find components to test — all things CircuitSimExtension handles for you. Nevertheless, these APIs are public and documented for fun and for the benefit of those hacking on the CircuitSim tester. Just beware that they may not be stable APIs.

  • Method Details

    • getName

      public String getName()
      Returns the name of this subcircuit as written in the test file.
      Returns:
      a String holding the subcircuit name. Not normalized, so represents exactly what the test file specified.
      See Also:
    • getCircuitSim

      public com.ra4king.circuitsim.gui.CircuitSim getCircuitSim()
      Returns the CircuitSim instance simulating the circuit.

      This exposes an internal CircuitSim API. Do not use unless you know what you are doing.

      Returns:
      the CircuitSim instance used for simulation
    • getSimulator

      public com.ra4king.circuitsim.simulator.Simulator getSimulator()
      Returns the CircuitSim Simulator running the circuit.

      This exposes an internal CircuitSim API. Do not use unless you know what you are doing.

      Returns:
      the Simulator instance used for simulation
    • getCircuitBoard

      public com.ra4king.circuitsim.gui.CircuitBoard getCircuitBoard()
      Returns the CircuitSim CircuitBoard for this subcircuit. This is a GUI-side thing.

      This exposes an internal CircuitSim API. Do not use unless you know what you are doing.

      Returns:
      the CircuitBoard of this subcircuit
    • getCircuitManager

      public com.ra4king.circuitsim.gui.CircuitManager getCircuitManager()
    • getCircuit

      public com.ra4king.circuitsim.simulator.Circuit getCircuit()
      Returns the CircuitSim Circuit for this subcircuit. This is a simulation-side thing.

      This exposes an internal CircuitSim API. Do not use unless you know what you are doing.

      Returns:
      the Circuit of this subcircuit
    • getCircuitState

      public com.ra4king.circuitsim.simulator.CircuitState getCircuitState()
      Returns the CircuitSim CircuitState of this subcircuit.

      This exposes an internal CircuitSim API. Do not use unless you know what you are doing.

      Returns:
      the CircuitState of top level state of this subcircuit
    • fromPath

      public static Subcircuit fromPath(String simFilePath, String subcircuitName) throws Exception
      Loads the subcircuit named subcircuitName from the .sim file simFilePath.

      Note that for the sake of students' stress levels, subcircuitName is normalized to a lowercase alphanumeric string before searching the .sim file for it, as are the names of subcircuits in the file. So "1-bit adder!" will match "1 Bit Adder", "1bit adder", "1bitadder", "1 B I T A D DD E R", and so on.

      Parameters:
      simFilePath - path to the subcircuit. Usually relative, like "adder.sim"
      subcircuitName - name of the subcircuit. Normalized as described above before lookup.
      Returns:
      a new Subcircuit simulating the requested subcircuit
      Throws:
      Exception - specified by CircuitSim.loadCircuits() in violation of all good taste on Earth
    • resetSimulation

      public void resetSimulation()
      Resets the simulation for this subcircuit.

      The same thing as clicking Simulation → Reset Simulation in CircuitSim.

    • getPinCount

      public int getPinCount()
      Returns the number of Input Pin or Output Pin components in this circuit. Does not include subcircuits.
      Returns:
      the total pin count of this subcircuit
    • lookupComponentCounts

      public Map<String,Integer> lookupComponentCounts(Collection<String> componentNames, boolean inverse, boolean recursive)
      Finds if components with the given names or in the given component categories exist in this subcircuit.
      Parameters:
      componentNames - an iterable of component names, component category names, or some mixture
      inverse - true if you want to invert the search, else false
      recursive - true if you want to search subcircuits, else false
      Returns:
      a map of distinct component names matching the given criteria to their number occurrences
    • lookupPin

      public BasePin lookupPin(String pinLabel, boolean wantInputPin, int wantBits, boolean recursive)
      Finds a Pin component labelled pinLabel in this subcircuit and returns a wrapper around it.

      To make sure the tester is deterministic, this method requires the subcircuit contain exactly one pin with a matching label. The algorithm checks this before verifying if a match has the right bit size or direction (input/output).

      Also for the sake of students' stress levels, pinLabel is normalized as described for lookupSubcircuit(CircuitSim,String) before lookup.

      Parameters:
      pinLabel - the label of the pin, or null to say this should be the only pin
      wantInputPin - whether the pin found should be input or output
      wantBits - how many bits the pin found should have
      recursive - whether or not to recursively search subcircuits
      Returns:
      either an InputPin or OutputPin depending on wantInputPin
      Throws:
      IllegalArgumentException - if the subcircuit does not contain exactly one matching pin
      See Also:
    • lookupRegister

      public Register lookupRegister(String regLabel, int wantBits, boolean recursive)
      Finds a Register component labelled regLabel in this subcircuit and returns a wrapper around it.

      To make sure the tester is deterministic, this method requires the subcircuit contain exactly one register with a matching label, or if regLabel is null, only 1 register period.

      Also for the sake of students' stress levels, regLabel is normalized as described for lookupSubcircuit(CircuitSim,String) before lookup.

      Parameters:
      regLabel - the label of the register, or null to say this should be the only register
      wantBits - how many bits the register found should have
      recursive - whether or not to recursively search subcircuits
      Returns:
      a Register wrapping the internal CircuitSim register component
      Throws:
      IllegalArgumentException - if the subcircuit does not contain exactly one matching register
      See Also:
    • lookupMemory

      public BaseMemory lookupMemory(String label, int wantBits, boolean recursive, Subcircuit.MemoryType type)
      Finds a RAM/ROM component labelled label in this subcircuit and returns a wrapper around it.

      To make sure the tester is deterministic, this method requires the subcircuit contain exactly one pin with a matching label. The algorithm checks this before verifying if a match has the right bit size or direction (input/output).

      Also for the sake of students' stress levels, pinLabel is normalized as described for lookupSubcircuit(CircuitSim,String) before lookup.

      Parameters:
      label - the label of the RAM/ROM, or null to say this should be the only RAM (or only ROM)
      wantBits - how many bits the RAM/ROM found should have
      recursive - whether or not to recursively search subcircuits
      type - whether to look for a Subcircuit.MemoryType.RAM or Subcircuit.MemoryType.ROM
      Returns:
      either an Ram or Rom depending on type
      Throws:
      IllegalArgumentException - if the subcircuit does not contain exactly one matching RAM/ROM
      See Also:
    • snitchTunnel

      public OutputPin snitchTunnel(String label, int wantBits)
      Add an OutputPin that spys on the value of the specified tunnel.

      Sadly, a recursive search is not currently supported, but it could be added within the next 10-15 years — watch this space!

      For the sake of students' stress levels, pinLabel is normalized as described for lookupSubcircuit(CircuitSim,String) before lookup.

      Parameters:
      label - the label of the tunnel. Must not be null
      wantBits - how many bits the tunnel found should have
      Returns:
      an OutputPin wrapping an Pin component attached to the specified tunnel
      Throws:
      IllegalArgumentException - if label is null
    • mockRegister

      public MockRegister mockRegister(com.ra4king.circuitsim.simulator.components.memory.Register reg)
      Mocks a CircuitSim register in this subcircuit by replacing it with input and output pins. Useful for testing the combinational logic in a sequential circuit with exactly one register. For more details on the motivation behind MockRegisters, see MockRegister.

      Each register port will be disconnected from anything else and replaced with a new Pin component reconnected to everything like before.

      Normally this will be called by Register.mock() and you won't need to call it directly.

      Parameters:
      reg - A CircuitSim register component to mock out
      Returns:
      a MockRegister which effectively acts a collection of input and output pins
      See Also:
    • mockPulser

      public MockPulser mockPulser(String label, boolean recursive, Subcircuit.PulserType type)
      Mocks a CircuitSim Button or Clock component (i.e., a "pulser") in this subcircuit by replacing it with an input pin. Useful for manipulating the clock when grading combination circuits. For more details, see MockPulser.

      The button/clock will be disconnected from anything else and replaced with a new input Pin component reconnected to everything like before. You can call MockPulser.pulse() to send a pulse (note Button and Clock have their own methods that call MockPulser.pulse()).

      Parameters:
      label - the label of the button/clock, or null if this should be the only button or only clock in the circuit
      recursive - whether or not to recursively search subcircuits
      type - whether to look for a clock or button
      Returns:
      a Button or Clock (depending on type) wrapping an InputPin which allows you to send pulses into the student's circuit
      See Also: