Skip to content

Commit

Permalink
Merge pull request #19 from rchildre3/feature/PriorityEncoder
Browse files Browse the repository at this point in the history
#9 Priority Encoder added
  • Loading branch information
ra4king committed Oct 2, 2017
2 parents 0785c7c + 2389b5b commit 15805f7
Show file tree
Hide file tree
Showing 4 changed files with 234 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/com/ra4king/circuitsim/gui/ComponentManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import com.ra4king.circuitsim.gui.peers.plexers.DecoderPeer;
import com.ra4king.circuitsim.gui.peers.plexers.DemultiplexerPeer;
import com.ra4king.circuitsim.gui.peers.plexers.MultiplexerPeer;
import com.ra4king.circuitsim.gui.peers.plexers.PriorityEncoderPeer;
import com.ra4king.circuitsim.gui.peers.wiring.ClockPeer;
import com.ra4king.circuitsim.gui.peers.wiring.ConstantPeer;
import com.ra4king.circuitsim.gui.peers.wiring.PinPeer;
Expand Down Expand Up @@ -184,6 +185,7 @@ private void registerDefaultComponents() {
register(MultiplexerPeer.class);
register(DemultiplexerPeer.class);
register(DecoderPeer.class);
register(PriorityEncoderPeer.class);

register(RegisterPeer.class);
register(SRFlipFlopPeer.class);
Expand Down
142 changes: 142 additions & 0 deletions src/com/ra4king/circuitsim/gui/peers/plexers/PriorityEncoderPeer.java
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();
}
}
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);
}
}
Binary file added src/resources/PriorityEncoder.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 15805f7

Please sign in to comment.