use of com.cburch.logisim.data.Value in project logisim-evolution by reds-heig.
the class CircuitBuilder method layoutGatesSub.
private static Layout layoutGatesSub(CircuitDetermination det) {
if (det instanceof CircuitDetermination.Input) {
CircuitDetermination.Input input = (CircuitDetermination.Input) det;
return new Layout(input.getName());
} else if (det instanceof CircuitDetermination.Value) {
CircuitDetermination.Value value = (CircuitDetermination.Value) det;
ComponentFactory factory = Constant.FACTORY;
AttributeSet attrs = factory.createAttributeSet();
attrs.setValue(Constant.ATTR_VALUE, Integer.valueOf(value.getValue()));
Bounds bds = factory.getOffsetBounds(attrs);
return new Layout(bds.getWidth(), bds.getHeight(), -bds.getY(), factory, attrs, new Layout[0], 0);
}
// We know det is a Gate. Determine sublayouts.
CircuitDetermination.Gate gate = (CircuitDetermination.Gate) det;
ComponentFactory factory = gate.getFactory();
ArrayList<CircuitDetermination> inputs = gate.getInputs();
// Handle a NOT implemented with a NAND as a special case
if (gate.isNandNot()) {
CircuitDetermination subDet = inputs.get(0);
if (!(subDet instanceof CircuitDetermination.Input)) {
Layout[] sub = new Layout[1];
sub[0] = layoutGatesSub(subDet);
sub[0].y = 0;
AttributeSet attrs = factory.createAttributeSet();
attrs.setValue(GateAttributes.ATTR_SIZE, GateAttributes.SIZE_NARROW);
attrs.setValue(GateAttributes.ATTR_INPUTS, Integer.valueOf(2));
// determine layout's width
Bounds bds = factory.getOffsetBounds(attrs);
int betweenWidth = 40;
if (sub[0].width == 0)
betweenWidth = 0;
int width = sub[0].width + betweenWidth + bds.getWidth();
// determine outputY and layout's height.
int outputY = sub[0].y + sub[0].outputY;
int height = sub[0].height;
int minOutputY = roundUp(-bds.getY());
if (minOutputY > outputY) {
// we have to shift everything down because otherwise
// the component will peek over the rectangle's top.
int dy = minOutputY - outputY;
sub[0].y += dy;
height += dy;
outputY += dy;
}
int minHeight = outputY + bds.getY() + bds.getHeight();
if (minHeight > height)
height = minHeight;
// ok; create and return the layout.
return new Layout(width, height, outputY, factory, attrs, sub, sub[0].width);
}
}
Layout[] sub = new Layout[inputs.size()];
// maximum width of sublayouts
int subWidth = 0;
// total height of sublayouts
int subHeight = 0;
for (int i = 0; i < sub.length; i++) {
sub[i] = layoutGatesSub(inputs.get(i));
if (sub.length % 2 == 0 && i == (sub.length + 1) / 2 && sub[i - 1].height + sub[i].height == 0) {
// if there are an even number of inputs, then there is a
// 20-tall gap between the middle two inputs. Ensure the two
// middle inputs are at least 20 pixels apart.
subHeight += 10;
}
sub[i].y = subHeight;
subWidth = Math.max(subWidth, sub[i].width);
subHeight += sub[i].height + 10;
}
subHeight -= 10;
AttributeSet attrs = factory.createAttributeSet();
if (factory == NotGate.FACTORY) {
attrs.setValue(NotGate.ATTR_SIZE, NotGate.SIZE_NARROW);
} else {
attrs.setValue(GateAttributes.ATTR_SIZE, GateAttributes.SIZE_NARROW);
int ins = sub.length;
attrs.setValue(GateAttributes.ATTR_INPUTS, Integer.valueOf(ins));
}
// determine layout's width
Bounds bds = factory.getOffsetBounds(attrs);
int betweenWidth = 40 + 10 * (sub.length / 2 - 1);
if (sub.length == 1)
betweenWidth = 20;
if (subWidth == 0)
betweenWidth = 0;
int width = subWidth + betweenWidth + bds.getWidth();
// determine outputY and layout's height.
int outputY;
if (sub.length % 2 == 1) {
// odd number - match the middle input
int i = (sub.length - 1) / 2;
outputY = sub[i].y + sub[i].outputY;
} else {
// even number - halfway between middle two inputs
int i0 = (sub.length / 2) - 1;
int i1 = (sub.length / 2);
int o0 = sub[i0].y + sub[i0].outputY;
int o1 = sub[i1].y + sub[i1].outputY;
outputY = roundDown((o0 + o1) / 2);
}
int height = subHeight;
int minOutputY = roundUp(-bds.getY());
if (minOutputY > outputY) {
// we have to shift everything down because otherwise
// the component will peek over the rectangle's top.
int dy = minOutputY - outputY;
for (int i = 0; i < sub.length; i++) sub[i].y += dy;
height += dy;
outputY += dy;
}
int minHeight = outputY + bds.getY() + bds.getHeight();
if (minHeight > height)
height = minHeight;
// ok; create and return the layout.
return new Layout(width, height, outputY, factory, attrs, sub, subWidth);
}
use of com.cburch.logisim.data.Value in project logisim-evolution by reds-heig.
the class VhdlEntity method propagate.
@Override
public /**
* Propagate signals through the VHDL component.
* Logisim doesn't have a VHDL simulation tool. So we need to use an external tool.
* We send signals to Questasim/Modelsim through a socket and a tcl binder. Then,
* a simulation step is done and the tcl server sends the output signals back to
* Logisim. Then we can set the VHDL component output properly.
*
* This can be done only if Logisim could connect to the tcl server (socket). This is
* done in Simulation.java.
*/
void propagate(InstanceState state) {
if (state.getProject().getVhdlSimulator().isEnabled() && state.getProject().getVhdlSimulator().isRunning()) {
VhdlSimulator vhdlSimulator = state.getProject().getVhdlSimulator();
for (Port p : state.getInstance().getPorts()) {
int index = state.getPortIndex(p);
Value val = state.getPortValue(index);
String vhdlEntityName = getHDLTopName(state.getAttributeSet());
String message = p.getType() + ":" + vhdlEntityName + "_" + p.getToolTip() + ":" + val.toBinaryString() + ":" + index;
vhdlSimulator.send(message);
}
vhdlSimulator.send("sync");
/* Get response from tcl server */
String server_response;
while ((server_response = vhdlSimulator.receive()) != null && server_response.length() > 0 && !server_response.equals("sync")) {
String[] parameters = server_response.split("\\:");
String busValue = parameters[1];
Value[] vector_values = new Value[busValue.length()];
int k = busValue.length() - 1;
for (char bit : busValue.toCharArray()) {
try {
switch(Character.getNumericValue(bit)) {
case 0:
vector_values[k] = Value.FALSE;
break;
case 1:
vector_values[k] = Value.TRUE;
break;
default:
vector_values[k] = Value.UNKNOWN;
break;
}
} catch (NumberFormatException e) {
vector_values[k] = Value.UNKNOWN;
}
k--;
}
state.setPort(Integer.parseInt(parameters[2]), Value.create(vector_values), 1);
}
/* VhdlSimulation stopped/disabled */
} else {
for (Port p : state.getInstance().getPorts()) {
int index = state.getPortIndex(p);
/* If it is an output */
if (p.getType() == 2) {
Value[] vector_values = new Value[p.getFixedBitWidth().getWidth()];
for (int k = 0; k < p.getFixedBitWidth().getWidth(); k++) {
vector_values[k] = Value.UNKNOWN;
}
state.setPort(index, Value.create(vector_values), 1);
}
}
new UnsupportedOperationException("VHDL component simulation is not supported. This could be because there is no Questasim/Modelsim simulation server running.");
}
}
use of com.cburch.logisim.data.Value in project logisim-evolution by reds-heig.
the class BitAdder method propagate.
@Override
public void propagate(InstanceState state) {
int width = state.getAttributeValue(StdAttr.WIDTH).getWidth();
int inputs = state.getAttributeValue(NUM_INPUTS).intValue();
// compute the number of 1 bits
// number that are definitely 1
int minCount = 0;
// number that are definitely not 0 (incl X/Z)
int maxCount = 0;
for (int i = 1; i <= inputs; i++) {
Value v = state.getPortValue(i);
Value[] bits = v.getAll();
for (int j = 0; j < bits.length; j++) {
Value b = bits[j];
if (b == Value.TRUE)
minCount++;
if (b != Value.FALSE)
maxCount++;
}
}
// compute which output bits should be error bits
int unknownMask = 0;
for (int i = minCount + 1; i <= maxCount; i++) {
unknownMask |= (minCount ^ i);
}
Value[] out = new Value[computeOutputBits(width, inputs)];
for (int i = 0; i < out.length; i++) {
if (((unknownMask >> i) & 1) != 0) {
out[i] = Value.ERROR;
} else if (((minCount >> i) & 1) != 0) {
out[i] = Value.TRUE;
} else {
out[i] = Value.FALSE;
}
}
int delay = out.length * Adder.PER_DELAY;
state.setPort(0, Value.create(out), delay);
}
use of com.cburch.logisim.data.Value in project logisim-evolution by reds-heig.
the class BitFinder method propagate.
@Override
public void propagate(InstanceState state) {
int width = state.getAttributeValue(StdAttr.WIDTH).getWidth();
int outWidth = computeOutputBits(width - 1);
Object type = state.getAttributeValue(TYPE);
Value[] bits = state.getPortValue(2).getAll();
Value want;
int i;
if (type == HIGH_ZERO) {
want = Value.FALSE;
for (i = bits.length - 1; i >= 0 && bits[i] == Value.TRUE; i--) {
}
} else if (type == LOW_ZERO) {
want = Value.FALSE;
for (i = 0; i < bits.length && bits[i] == Value.TRUE; i++) {
}
} else if (type == HIGH_ONE) {
want = Value.TRUE;
for (i = bits.length - 1; i >= 0 && bits[i] == Value.FALSE; i--) {
}
} else {
want = Value.TRUE;
for (i = 0; i < bits.length && bits[i] == Value.FALSE; i++) {
}
}
Value present;
Value index;
if (i < 0 || i >= bits.length) {
present = Value.FALSE;
index = Value.createKnown(BitWidth.create(outWidth), 0);
} else if (bits[i] == want) {
present = Value.TRUE;
index = Value.createKnown(BitWidth.create(outWidth), i);
} else {
present = Value.ERROR;
index = Value.createError(BitWidth.create(outWidth));
}
int delay = outWidth * Adder.PER_DELAY;
state.setPort(0, present, delay);
state.setPort(1, index, delay);
}
use of com.cburch.logisim.data.Value in project logisim-evolution by reds-heig.
the class Comparator method propagate.
@Override
public void propagate(InstanceState state) {
// get attributes
BitWidth dataWidth = state.getAttributeValue(StdAttr.WIDTH);
// compute outputs
Value gt = Value.FALSE;
Value eq = Value.TRUE;
Value lt = Value.FALSE;
Value a = state.getPortValue(IN0);
Value b = state.getPortValue(IN1);
Value[] ax = a.getAll();
Value[] bx = b.getAll();
int maxlen = Math.max(ax.length, bx.length);
for (int pos = maxlen - 1; pos >= 0; pos--) {
Value ab = pos < ax.length ? ax[pos] : Value.ERROR;
Value bb = pos < bx.length ? bx[pos] : Value.ERROR;
if (pos == ax.length - 1 && ab != bb) {
Object mode = state.getAttributeValue(MODE_ATTRIBUTE);
if (mode != UNSIGNED_OPTION) {
Value t = ab;
ab = bb;
bb = t;
}
}
if (ab == Value.ERROR || bb == Value.ERROR) {
gt = Value.ERROR;
eq = Value.ERROR;
lt = Value.ERROR;
break;
} else if (ab == Value.UNKNOWN || bb == Value.UNKNOWN) {
gt = Value.UNKNOWN;
eq = Value.UNKNOWN;
lt = Value.UNKNOWN;
break;
} else if (ab != bb) {
eq = Value.FALSE;
if (ab == Value.TRUE)
gt = Value.TRUE;
else
lt = Value.TRUE;
break;
}
}
// propagate them
int delay = (dataWidth.getWidth() + 2) * Adder.PER_DELAY;
state.setPort(GT, gt, delay);
state.setPort(EQ, eq, delay);
state.setPort(LT, lt, delay);
}
Aggregations