-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #19 from rchildre3/feature/PriorityEncoder
#9 Priority Encoder added
- Loading branch information
Showing
4 changed files
with
234 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
142 changes: 142 additions & 0 deletions
142
src/com/ra4king/circuitsim/gui/peers/plexers/PriorityEncoderPeer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package com.ra4king.circuitsim.gui.peers.plexers; | ||
|
||
import java.util.ArrayList; | ||
import java.util.List; | ||
|
||
import com.ra4king.circuitsim.gui.ComponentManager.ComponentManagerInterface; | ||
import com.ra4king.circuitsim.gui.ComponentPeer; | ||
import com.ra4king.circuitsim.gui.Connection.PortConnection; | ||
import com.ra4king.circuitsim.gui.GuiUtils; | ||
import com.ra4king.circuitsim.gui.Properties; | ||
import com.ra4king.circuitsim.gui.Properties.Direction; | ||
import com.ra4king.circuitsim.simulator.CircuitState; | ||
import com.ra4king.circuitsim.simulator.components.plexers.PriorityEncoder; | ||
|
||
import javafx.scene.canvas.GraphicsContext; | ||
import javafx.scene.image.Image; | ||
import javafx.scene.paint.Color; | ||
import javafx.util.Pair; | ||
|
||
/** | ||
* @author Elliott Childre | ||
*/ | ||
public class PriorityEncoderPeer extends ComponentPeer<PriorityEncoder> { | ||
|
||
private static final byte ENABLED_INOUT_SIDE_LEN = 4; | ||
|
||
public PriorityEncoderPeer(Properties props, int x, int y) { | ||
super(x, y, ENABLED_INOUT_SIDE_LEN, 0); | ||
|
||
Properties properties = new Properties(); | ||
properties.ensureProperty(Properties.LABEL); | ||
properties.ensureProperty(Properties.LABEL_LOCATION); | ||
properties.ensureProperty(Properties.DIRECTION); | ||
properties.ensureProperty(Properties.SELECTOR_BITS); | ||
properties.setValue(Properties.SELECTOR_BITS, 3); | ||
properties.mergeIfExists(props); | ||
|
||
PriorityEncoder pEncoder = new PriorityEncoder(properties.getValue(Properties.LABEL), | ||
properties.getValue(Properties.SELECTOR_BITS)); | ||
int numInputs = 1 << pEncoder.getNumSelectBits(); | ||
int inputSideLen = numInputs + 1; | ||
setHeight(inputSideLen); | ||
|
||
GuiUtils.rotateElementSize(this, Direction.EAST, properties.getValue(Properties.DIRECTION)); | ||
|
||
List<PortConnection> connections = new ArrayList<>(numInputs + 4); | ||
int i; | ||
switch(properties.getValue(Properties.DIRECTION)) { | ||
case EAST: | ||
for(i = 0; i < numInputs; i++) { | ||
connections.add(new PortConnection(this, pEncoder.getPort(i), String.valueOf(i), 0, i + 1)); | ||
} | ||
connections.add(new PortConnection(this, pEncoder.getEnabledInPort(), "Enable In", ENABLED_INOUT_SIDE_LEN >> 1, inputSideLen)); | ||
connections.add(new PortConnection(this, pEncoder.getEnabledOutPort(), "Enable Out", ENABLED_INOUT_SIDE_LEN >> 1, 0)); | ||
connections.add(new PortConnection(this, pEncoder.getGroupSignalPort(), "Group Signal", ENABLED_INOUT_SIDE_LEN, (inputSideLen >> 1) + 1)); | ||
connections.add(new PortConnection(this, pEncoder.getOutputPort(), "Output", ENABLED_INOUT_SIDE_LEN, inputSideLen >> 1)); | ||
break; | ||
case WEST: | ||
for(i = 0; i < numInputs; i++) { | ||
connections.add(new PortConnection(this, pEncoder.getPort(i), String.valueOf(i), ENABLED_INOUT_SIDE_LEN, i + 1)); | ||
} | ||
connections.add(new PortConnection(this, pEncoder.getEnabledInPort(), "Enable In", ENABLED_INOUT_SIDE_LEN >> 1, inputSideLen)); | ||
connections.add(new PortConnection(this, pEncoder.getEnabledOutPort(), "Enable Out", ENABLED_INOUT_SIDE_LEN >> 1, 0)); | ||
connections.add(new PortConnection(this, pEncoder.getGroupSignalPort(), "Group Signal", 0, (inputSideLen >> 1) + 1)); | ||
connections.add(new PortConnection(this, pEncoder.getOutputPort(), "Output", 0, inputSideLen >> 1)); | ||
break; | ||
case SOUTH: | ||
for(i = 0; i < numInputs; i++) { | ||
connections.add(new PortConnection(this, pEncoder.getPort(i), String.valueOf(i), i + 1, 0)); | ||
} | ||
connections.add(new PortConnection(this, pEncoder.getEnabledInPort(), "Enable In", 0, ENABLED_INOUT_SIDE_LEN >> 1)); | ||
connections.add(new PortConnection(this, pEncoder.getEnabledOutPort(), "Enable Out", inputSideLen, ENABLED_INOUT_SIDE_LEN >> 1)); | ||
connections.add(new PortConnection(this, pEncoder.getGroupSignalPort(), "Group Signal", inputSideLen >> 1, ENABLED_INOUT_SIDE_LEN)); | ||
connections.add(new PortConnection(this, pEncoder.getOutputPort(), "Output", (inputSideLen >> 1) + 1, ENABLED_INOUT_SIDE_LEN)); | ||
break; | ||
case NORTH: | ||
for(i = 0; i < numInputs; i++) { | ||
connections.add(new PortConnection(this, pEncoder.getPort(i), String.valueOf(i), i + 1, ENABLED_INOUT_SIDE_LEN)); | ||
} | ||
connections.add(new PortConnection(this, pEncoder.getEnabledInPort(), "Enable In", inputSideLen, ENABLED_INOUT_SIDE_LEN >> 1)); | ||
connections.add(new PortConnection(this, pEncoder.getEnabledOutPort(), "Enable Out", 0, ENABLED_INOUT_SIDE_LEN >> 1)); | ||
connections.add(new PortConnection(this, pEncoder.getGroupSignalPort(), "Group Signal", (inputSideLen >> 1) + 1, 0)); | ||
connections.add(new PortConnection(this, pEncoder.getOutputPort(), "Output", inputSideLen >> 1, 0)); | ||
break; | ||
default: | ||
throw new RuntimeException("Unknown Direction"); | ||
} | ||
init(pEncoder, properties, connections); | ||
} | ||
|
||
public static void installComponent(ComponentManagerInterface manager) { | ||
manager.addComponent(new Pair<>("Plexer", "Priority Encoder"), | ||
new Image(PriorityEncoderPeer.class.getResourceAsStream("/resources/PriorityEncoder.png")), | ||
new Properties()); | ||
} | ||
|
||
@Override | ||
public void paint(GraphicsContext graphics, CircuitState circuitState) { | ||
GuiUtils.drawName(graphics, this, getProperties().getValue(Properties.LABEL_LOCATION)); | ||
|
||
Direction direction = getProperties().getValue(Properties.DIRECTION); | ||
graphics.translate(getScreenX(), getScreenY()); | ||
|
||
int height; | ||
int width; | ||
|
||
int inputSideLength = ((1 << getComponent().getNumSelectBits()) + 1) * GuiUtils.BLOCK_SIZE; | ||
int enabledSideLength = ENABLED_INOUT_SIDE_LEN * GuiUtils.BLOCK_SIZE; | ||
|
||
double zeroX = GuiUtils.BLOCK_SIZE >> 1; | ||
double zeroY; | ||
|
||
if(direction == Direction.EAST || direction == Direction.WEST) { | ||
height = inputSideLength; | ||
width = enabledSideLength; | ||
zeroY = GuiUtils.BLOCK_SIZE * 1.5; | ||
if(direction == Direction.WEST) { | ||
zeroX = width - GuiUtils.BLOCK_SIZE; | ||
} | ||
} else { | ||
height = enabledSideLength; | ||
width = inputSideLength; | ||
zeroY = height - (GuiUtils.BLOCK_SIZE >> 1); | ||
if(direction == Direction.SOUTH) { | ||
zeroY = GuiUtils.BLOCK_SIZE * 1.5; | ||
} | ||
} | ||
|
||
graphics.setStroke(Color.BLACK); | ||
graphics.strokeRect(0, 0, width, height); | ||
|
||
graphics.setFill(Color.WHITE); | ||
graphics.fillRect(0, 0, width, height); | ||
|
||
graphics.setFill(Color.DARKGRAY); | ||
graphics.fillText("0", zeroX, zeroY); | ||
|
||
graphics.setFill(Color.BLACK); | ||
graphics.fillText("Pri", (width >> 1) - graphics.getFont().getSize(), (height >> 1) + 0.5 * GuiUtils.BLOCK_SIZE); | ||
graphics.getFont().getSize(); | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
src/com/ra4king/circuitsim/simulator/components/plexers/PriorityEncoder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
package com.ra4king.circuitsim.simulator.components.plexers; | ||
|
||
import java.util.Arrays; | ||
|
||
import com.ra4king.circuitsim.simulator.CircuitState; | ||
import com.ra4king.circuitsim.simulator.Component; | ||
import com.ra4king.circuitsim.simulator.Port; | ||
import com.ra4king.circuitsim.simulator.WireValue; | ||
import com.ra4king.circuitsim.simulator.WireValue.State; | ||
|
||
/** | ||
* @author Elliott Childre | ||
*/ | ||
public class PriorityEncoder extends Component { | ||
private final int numSelectBits; | ||
private boolean isEnabled; | ||
|
||
public PriorityEncoder(String name, int numSelectBits) { | ||
super(name, createBitSizeArray(numSelectBits)); | ||
this.numSelectBits = numSelectBits; | ||
this.isEnabled = false; | ||
} | ||
|
||
private static int[] createBitSizeArray(int numSelectBits) { | ||
// ports = [2^numSelectBits, enableIN, enableOUT, outGroup, out] | ||
int[] portBits = new int[(1 << numSelectBits) + 4]; | ||
|
||
// all wires are width: 1 except out | ||
Arrays.fill(portBits, 0, (1 << numSelectBits) + 3, 1); | ||
portBits[portBits.length - 1] = numSelectBits; | ||
|
||
return portBits; | ||
} | ||
|
||
@Override | ||
public void valueChanged(CircuitState state, WireValue value, int portIndex) { | ||
Port out = getOutputPort(); | ||
// if enabled IN changes | ||
if(portIndex == 1 << numSelectBits) { | ||
this.isEnabled = value.getBit(0) == State.ONE; | ||
} | ||
// The only other input Port are the indexed inputs | ||
if (!this.isEnabled) { | ||
state.pushValue(getEnabledOutPort(), new WireValue(1, State.ZERO)); | ||
state.pushValue(out, new WireValue(out.getLink().getBitSize(), State.X)); | ||
state.pushValue(getGroupSignalPort(), new WireValue(1, State.ZERO)); | ||
return; | ||
} | ||
|
||
// Loop through the inputs | ||
int highest = -1; | ||
int ports = 1 << numSelectBits; | ||
for (int i = 0; i < ports; i++) { | ||
if(state.getLastReceived(getPort(i)).getBit(0) == State.ONE || (i == portIndex && value.getBit(0) == State.ONE)) { | ||
highest = i; | ||
} | ||
} | ||
|
||
if(highest == -1) { | ||
state.pushValue(getEnabledOutPort(), new WireValue(1, State.ONE)); | ||
state.pushValue(out, new WireValue(out.getLink().getBitSize(), State.X)); | ||
state.pushValue(getGroupSignalPort(), new WireValue(1, State.ZERO)); | ||
|
||
} else { | ||
state.pushValue(getEnabledOutPort(), new WireValue(1, State.ZERO)); | ||
state.pushValue(getGroupSignalPort(), new WireValue(1, State.ONE)); | ||
state.pushValue(getOutputPort(), WireValue.of(highest, out.getLink().getBitSize())); | ||
} | ||
} | ||
|
||
public int getNumSelectBits() { | ||
return numSelectBits; | ||
} | ||
|
||
public Port getEnabledInPort() { | ||
return getPort(1 << numSelectBits); | ||
} | ||
|
||
public Port getEnabledOutPort() { | ||
return getPort((1 << numSelectBits) + 1); | ||
} | ||
|
||
public Port getGroupSignalPort() { | ||
return getPort((1 << numSelectBits) + 2); | ||
} | ||
|
||
public Port getOutputPort() { | ||
return getPort((1 << numSelectBits) + 3); | ||
} | ||
} |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.