added vhdl support for pull resistors

This commit is contained in:
hneemann 2017-08-15 11:58:15 +02:00
parent ee65b5f027
commit 3081633d5e
17 changed files with 581 additions and 73 deletions

View File

@ -47,7 +47,10 @@ public class PullDown implements Element {
public void registerNodes(Model model) {
}
static final class PullObservableValue extends ObservableValue {
/**
* Value that represents a pull resistor
*/
public static final class PullObservableValue extends ObservableValue {
private final PullResistor res;
PullObservableValue(int bits, PullResistor res) {

View File

@ -0,0 +1,110 @@
package de.neemann.digital.hdl.model;
/**
* Represets a hdl constant value
*/
public class HDLConstant {
/**
* Possiple types
*/
public enum Type {
/**
* weak high, in digital represented by a pull up
*/
weakHigh,
/**
* weak low, in digital represented by a pull down
*/
weakLow,
/**
* high z
*/
highz,
/**
* don't care value
*/
dontcare,
/**
* a normal number
*/
normal
}
private final Type type;
private final int bits;
private final long value;
/**
* Creates a new value like "don't care" or "highz"
*
* @param type the type
* @param bits number of bits
*/
public HDLConstant(Type type, int bits) {
this.type = type;
this.bits = bits;
value = 0;
}
/**
* Creates a new numeric value
*
* @param value the value
* @param bits number of bits
*/
public HDLConstant(long value, int bits) {
type = Type.normal;
this.value = value;
this.bits = bits;
}
/**
* returns a VHDL specific representation of the constant
*
* @return the string representation
* @throws HDLException HDLException
*/
public String vhdlValue() throws HDLException {
if (type == Type.normal) {
long val = value & ((1 << bits) - 1);
if (bits > 1) {
StringBuilder sb = new StringBuilder("\"");
String str = Long.toBinaryString(val);
for (int i = bits - str.length(); i > 0; i--)
sb.append('0');
sb.append(str).append("\"");
return sb.toString();
} else
return "'" + val + "'";
} else {
char c = getVHDLChar();
if (bits > 1) {
StringBuilder sb = new StringBuilder("\"");
for (int i = 0; i < bits; i++)
sb.append(c);
sb.append("\"");
return sb.toString();
} else
return "'" + c + "'";
}
}
private char getVHDLChar() throws HDLException {
switch (type) {
case weakLow:
return 'L';
case weakHigh:
return 'H';
case dontcare:
return '-';
case highz:
return 'Z';
default:
throw new HDLException("unknown constant type " + type);
}
}
}

View File

@ -3,6 +3,7 @@ package de.neemann.digital.hdl.model;
import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.ObservableValues;
import de.neemann.digital.core.element.*;
import de.neemann.digital.core.pld.PullDown;
import de.neemann.digital.draw.elements.Pin;
import de.neemann.digital.draw.elements.PinException;
import de.neemann.digital.draw.elements.VisualElement;
@ -159,7 +160,7 @@ public class HDLNode implements HDLInterface {
boolean isConstant();
long getConstant();
HDLConstant getConstant() throws HDLException;
}
private static final class ValueModel implements Value {
@ -182,8 +183,8 @@ public class HDLNode implements HDLInterface {
}
@Override
public long getConstant() {
throw new RuntimeException("invalid call");
public HDLConstant getConstant() throws HDLException {
throw new HDLException("invalid call");
}
}
@ -203,12 +204,24 @@ public class HDLNode implements HDLInterface {
@Override
public boolean isConstant() {
return observableValues.get(i).isConstant();
return observableValues.get(i).isConstant() || observableValues.get(i) instanceof PullDown.PullObservableValue;
}
@Override
public long getConstant() {
return observableValues.get(i).getValue();
public HDLConstant getConstant() throws HDLException {
int bits = observableValues.get(i).getBits();
if (observableValues.get(i) instanceof PullDown.PullObservableValue) {
PullDown.PullObservableValue obs = (PullDown.PullObservableValue) observableValues.get(i);
switch (obs.getPullResistor()) {
case pullUp:
return new HDLConstant(HDLConstant.Type.weakHigh, bits);
case pullDown:
return new HDLConstant(HDLConstant.Type.weakLow, bits);
default:
throw new HDLException("undefined pull resistor");
}
} else
return new HDLConstant(observableValues.get(i).getValue(), bits);
}
}

View File

@ -32,7 +32,7 @@ public class Port {
private int bits = 0;
private Signal signal;
private boolean isConstant;
private long constant;
private HDLConstant constant;
private String pinNumber;
/**
@ -170,7 +170,7 @@ public class Port {
*
* @param constant the value
*/
public void setConstant(long constant) {
public void setConstant(HDLConstant constant) {
isConstant = true;
this.constant = constant;
}
@ -185,7 +185,7 @@ public class Port {
/**
* @return the constant value
*/
public long getConstant() {
public HDLConstant getConstant() {
return constant;
}

View File

@ -13,7 +13,7 @@ public class Signal implements Comparable<Signal> {
private int bits;
private Port.Direction portDirection;
private boolean written = false;
private long constant;
private HDLConstant constant;
private boolean isConstant;
/**
@ -186,7 +186,7 @@ public class Signal implements Comparable<Signal> {
return ports;
}
private void setConstant(long constant) {
private void setConstant(HDLConstant constant) {
isConstant = true;
this.constant = constant;
}
@ -201,7 +201,7 @@ public class Signal implements Comparable<Signal> {
/**
* @return the constant value
*/
public long getConstant() {
public HDLConstant getConstant() {
return constant;
}

View File

@ -4,6 +4,8 @@ import de.neemann.digital.core.NodeException;
import de.neemann.digital.core.io.Const;
import de.neemann.digital.core.io.Ground;
import de.neemann.digital.core.io.VDD;
import de.neemann.digital.core.pld.PullDown;
import de.neemann.digital.core.pld.PullUp;
import de.neemann.digital.core.wiring.Splitter;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.PinException;
@ -150,10 +152,8 @@ public class VHDLExporter implements Closeable {
s.setIsWritten();
out.print(s.getName());
out.print(" <= ");
if (s.getBits() > 1)
out.print("std_logic_vector(to_unsigned(").print(s.getConstant()).print(",").print(s.getBits()).println("));");
else
out.print("'").print(s.getConstant()).println("';");
out.print(s.getConstant().vhdlValue());
out.println(";");
}
}
@ -197,6 +197,8 @@ public class VHDLExporter implements Closeable {
private boolean isConstant(HDLNode node) {
return node.is(Ground.DESCRIPTION)
|| node.is(VDD.DESCRIPTION)
|| node.is(PullUp.DESCRIPTION)
|| node.is(PullDown.DESCRIPTION)
|| node.is(Const.DESCRIPTION);
}
@ -251,27 +253,6 @@ public class VHDLExporter implements Closeable {
out.println(" );");
}
/**
* Writes a value to the given stream
*
* @param out the output code printer
* @param val the value
* @param bits the number of bits
* @throws IOException IOException
*/
public static void writeValue(CodePrinter out, long val, int bits) throws IOException {
if (bits > 1) {
val = val & ((1 << bits) - 1);
out.print("\"");
String str = Long.toBinaryString(val);
for (int i = bits - str.length(); i > 0; i--)
out.print('0');
out.print(str).print("\"");
} else
out.print("'").print(val).print("'");
}
@Override
public String toString() {
return out.toString();

View File

@ -4,6 +4,7 @@ import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.data.Value;
import de.neemann.digital.draw.elements.Circuit;
import de.neemann.digital.draw.elements.VisualElement;
import de.neemann.digital.hdl.model.HDLConstant;
import de.neemann.digital.hdl.model.HDLException;
import de.neemann.digital.hdl.model.HDLModel;
import de.neemann.digital.hdl.model.Port;
@ -150,12 +151,14 @@ public class VHDLTestBenchCreator {
out.println("wait for 10 ns;");
for (Port p : model.getPorts().getOutputs()) {
out.print("assert std_match(").print(p.getName()).print(", patterns(i).").print(p.getName()).print(")");
out.print(" OR (").print(p.getName()).print(" = ");
writeCharValue(out, 'Z', p.getBits());
out.print(" AND patterns(i).").print(p.getName()).print(" = ");
writeCharValue(out, 'Z', p.getBits());
out.print(")");
out.println().inc().print("report \"wrong value for ").print(p.getName()).println(" i=\" & integer'image(i) severity error;").dec();
out.print(" OR (")
.print(p.getName())
.print(" = ")
.print(new HDLConstant(HDLConstant.Type.highz, p.getBits()).vhdlValue())
.print(" AND patterns(i).").print(p.getName()).print(" = ")
.print(new HDLConstant(HDLConstant.Type.highz, p.getBits()).vhdlValue())
.print(")").eol();
out.inc().print("report \"wrong value for ").print(p.getName()).println(" i=\" & integer'image(i) severity error;").dec();
}
out.dec().println("end loop;");
@ -164,6 +167,7 @@ public class VHDLTestBenchCreator {
out.dec().println("end behav;");
}
/*
private static void writeCharValue(CodePrinter out, char c, int bits) throws IOException {
if (bits > 1) {
out.print("\"");
@ -172,7 +176,7 @@ public class VHDLTestBenchCreator {
out.print("\"");
} else
out.print("'").print(c).print("'");
}
}*/
private static final class LineListenerVHDL implements LineListener {
private final CodePrinter out;
@ -206,30 +210,30 @@ public class VHDLTestBenchCreator {
}
lineSep.check(out);
writeValues(values, false, 0);
} catch (IOException e) {
} catch (IOException | HDLException e) {
throw new RuntimeException(e);
}
}
private void writeValues(Value[] values, boolean isClock, int clock) throws IOException {
private void writeValues(Value[] values, boolean isClock, int clock) throws IOException, HDLException {
out.print("(");
Separator sep = new Separator(", ");
for (int i = 0; i < values.length; i++) {
sep.check(out);
Value val = values[i];
int bits = dataOrder.get(i).getBits();
switch (val.getType()) {
case NORMAL:
int bits = dataOrder.get(i).getBits();
if (isClock && dataOrder.get(i).getDirection() == Port.Direction.out)
writeCharValue(out, '-', bits);
out.print(new HDLConstant(HDLConstant.Type.dontcare, bits).vhdlValue());
else
VHDLExporter.writeValue(out, val.getValue(), bits);
out.print(new HDLConstant(val.getValue(), bits).vhdlValue());
break;
case DONTCARE:
writeCharValue(out, '-', dataOrder.get(i).getBits());
out.print(new HDLConstant(HDLConstant.Type.dontcare, bits).vhdlValue());
break;
case HIGHZ:
writeCharValue(out, 'Z', dataOrder.get(i).getBits());
out.print(new HDLConstant(HDLConstant.Type.highz, bits).vhdlValue());
break;
case CLOCK:
out.print("'").print(clock).print("'");

View File

@ -1,12 +1,12 @@
package de.neemann.digital.hdl.vhdl.lib;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.hdl.model.HDLConstant;
import de.neemann.digital.hdl.model.HDLException;
import de.neemann.digital.hdl.model.HDLNode;
import de.neemann.digital.hdl.model.Port;
import de.neemann.digital.hdl.printer.CodePrinter;
import de.neemann.digital.hdl.vhdl.Separator;
import de.neemann.digital.hdl.vhdl.VHDLExporter;
import java.io.IOException;
import java.util.HashSet;
@ -59,7 +59,7 @@ public class ROMVHDL extends VHDLEntitySimple {
Separator sep = new Separator(",\n");
for (int i = 0; i < data.length; i++) {
sep.check(out);
VHDLExporter.writeValue(out, data[i], dataBits);
out.print(new HDLConstant(data[i], dataBits).vhdlValue());
}
out.dec().println(");");
@ -72,7 +72,7 @@ public class ROMVHDL extends VHDLEntitySimple {
out.print("PORT_D <= (others => 'Z');").dec().eol();
if (data.length < (1 << addrBits)) {
out.print("elsif PORT_A > ");
VHDLExporter.writeValue(out, data.length-1, addrBits);
out.print(new HDLConstant(data.length - 1, addrBits).vhdlValue());
out.print(" then").inc().eol();
out.print("PORT_D <= (others => '0');").dec().eol();
}

View File

@ -0,0 +1,22 @@
package de.neemann.digital.hdl.model;
import junit.framework.TestCase;
public class HDLConstantTest extends TestCase {
public void testSimple() throws HDLException {
assertEquals("'0'", new HDLConstant(0, 1).vhdlValue());
assertEquals("'1'", new HDLConstant(1, 1).vhdlValue());
assertEquals("\"00\"", new HDLConstant(0, 2).vhdlValue());
assertEquals("\"10\"", new HDLConstant(2, 2).vhdlValue());
assertEquals("'Z'", new HDLConstant(HDLConstant.Type.highz, 1).vhdlValue());
assertEquals("\"ZZ\"", new HDLConstant(HDLConstant.Type.highz, 2).vhdlValue());
assertEquals("'H'", new HDLConstant(HDLConstant.Type.weakHigh, 1).vhdlValue());
assertEquals("\"HH\"", new HDLConstant(HDLConstant.Type.weakHigh, 2).vhdlValue());
assertEquals("'-'", new HDLConstant(HDLConstant.Type.dontcare, 1).vhdlValue());
assertEquals("\"--\"", new HDLConstant(HDLConstant.Type.dontcare, 2).vhdlValue());
}
}

View File

@ -91,7 +91,7 @@ public class ConstantTest extends TestCase {
"\n" +
" signal S0: std_logic_vector (2 downto 0);\n" +
"begin\n" +
" S0 <= std_logic_vector(to_unsigned(0,3));\n" +
" S0 <= \"000\";\n" +
" gate0 : XOR_GATE_BUS_2\n" +
" generic map ( bitCount => 3)\n" +
" port map (\n" +
@ -121,4 +121,73 @@ public class ConstantTest extends TestCase {
"end XOR_GATE_BUS_2_arch;\n", vhdl);
}
public void testSimple3() throws IOException, ElementNotFoundException, PinException, NodeException {
ToBreakRunner br = new ToBreakRunner("dig/hdl/const3.dig");
String vhdl = new VHDLExporter(br.getLibrary()).export(br.getCircuit()).toString();
assertEquals("-- auto generated by Digital\n" +
"\n" +
"LIBRARY ieee;\n" +
"USE ieee.std_logic_1164.all;\n" +
"USE ieee.numeric_std.all;\n" +
"\n" +
"entity main is\n" +
" port (\n" +
" PORT_Y: out std_logic_vector (2 downto 0) );\n" +
"end main;\n" +
"\n" +
"architecture main_arch of main is\n" +
"\n" +
"begin\n" +
" PORT_Y <= \"000\";\n" +
"end main_arch;\n" +
"\n" +
"-- library components\n", vhdl);
}
public void testPullUp() throws IOException, ElementNotFoundException, PinException, NodeException {
ToBreakRunner br = new ToBreakRunner("dig/hdl/constPullUp.dig");
String vhdl = new VHDLExporter(br.getLibrary()).export(br.getCircuit()).toString();
assertEquals("-- auto generated by Digital\n" +
"\n" +
"LIBRARY ieee;\n" +
"USE ieee.std_logic_1164.all;\n" +
"USE ieee.numeric_std.all;\n" +
"\n" +
"entity main is\n" +
" port (\n" +
" PORT_Y: out std_logic_vector (2 downto 0) );\n" +
"end main;\n" +
"\n" +
"architecture main_arch of main is\n" +
"\n" +
"begin\n" +
" PORT_Y <= \"HHH\";\n" +
"end main_arch;\n" +
"\n" +
"-- library components\n", vhdl);
}
public void testPullDown() throws IOException, ElementNotFoundException, PinException, NodeException {
ToBreakRunner br = new ToBreakRunner("dig/hdl/constPullDown.dig");
String vhdl = new VHDLExporter(br.getLibrary()).export(br.getCircuit()).toString();
assertEquals("-- auto generated by Digital\n" +
"\n" +
"LIBRARY ieee;\n" +
"USE ieee.std_logic_1164.all;\n" +
"USE ieee.numeric_std.all;\n" +
"\n" +
"entity main is\n" +
" port (\n" +
" PORT_Y: out std_logic_vector (2 downto 0) );\n" +
"end main;\n" +
"\n" +
"architecture main_arch of main is\n" +
"\n" +
"begin\n" +
" PORT_Y <= \"LLL\";\n" +
"end main_arch;\n" +
"\n" +
"-- library components\n", vhdl);
}
}

View File

@ -38,11 +38,19 @@ public class TestInSimulator extends TestCase {
int tested = new FileScanner(this::check).scan(examples);
// if tested is negative, ghdl was not found and tests are skipped!
if (tested >= 0) {
assertEquals(14, tested);
assertEquals(15, tested);
assertEquals(tested, testBenches);
}
}
public void testInSimulator2() throws Exception {
File examples = new File(Resources.getRoot(), "/dig/hdl");
int tested = new FileScanner(this::check).scan(examples);
// if tested is negative, ghdl was not found and tests are skipped!
if (tested >= 0)
assertEquals(26, tested);
}
public void testDistributedInSimulator() throws Exception {
File examples = new File(Resources.getRoot(), "../../main/dig/vhdl");
int tested = new FileScanner(this::check).scan(examples);

View File

@ -11,20 +11,6 @@ import java.io.IOException;
public class VHDLExporterTest extends TestCase {
public void testWriteValue() throws IOException {
CodePrinterStr out = new CodePrinterStr();
VHDLExporter.writeValue(out,0,1);
assertEquals("'0'", out.toString());
out = new CodePrinterStr();
VHDLExporter.writeValue(out,5,4);
assertEquals("\"0101\"", out.toString());
out = new CodePrinterStr();
VHDLExporter.writeValue(out,16,4);
assertEquals("\"0000\"", out.toString());
}
public void testNegSimple() throws IOException, ElementNotFoundException, PinException, NodeException {
ToBreakRunner br = new ToBreakRunner("dig/hdl/negSimple.dig");
String vhdl = new VHDLExporter(br.getLibrary()).export(br.getCircuit()).toString();

View File

@ -40,8 +40,8 @@ public class TestExamples extends TestCase {
*/
public void testTestExamples() throws Exception {
File examples = new File(Resources.getRoot(), "/dig/test");
assertEquals(97, new FileScanner(this::check).scan(examples));
assertEquals(88, testCasesInFiles);
assertEquals(98, new FileScanner(this::check).scan(examples));
assertEquals(89, testCasesInFiles);
}

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
<entry>
<string>Bits</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="800" y="300"/>
</visualElement>
<visualElement>
<elementName>Ground</elementName>
<elementAttributes>
<entry>
<string>Bits</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="780" y="320"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="780" y="300"/>
<p2 x="800" y="300"/>
</wire>
<wire>
<p1 x="780" y="300"/>
<p2 x="780" y="320"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
<entry>
<string>Bits</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="800" y="300"/>
</visualElement>
<visualElement>
<elementName>PullDown</elementName>
<elementAttributes>
<entry>
<string>Bits</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="780" y="320"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="780" y="300"/>
<p2 x="800" y="300"/>
</wire>
<wire>
<p1 x="780" y="300"/>
<p2 x="780" y="320"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
<entry>
<string>Bits</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="800" y="300"/>
</visualElement>
<visualElement>
<elementName>PullUp</elementName>
<elementAttributes>
<entry>
<string>Bits</string>
<int>3</int>
</entry>
</elementAttributes>
<pos x="780" y="280"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="780" y="300"/>
<p2 x="800" y="300"/>
</wire>
<wire>
<p1 x="780" y="280"/>
<p2 x="780" y="300"/>
</wire>
</wires>
</circuit>

View File

@ -0,0 +1,189 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>1</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>YU</string>
</entry>
</elementAttributes>
<pos x="820" y="300"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
<elementAttributes/>
<pos x="760" y="300"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>en</string>
</entry>
</elementAttributes>
<pos x="680" y="260"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>val</string>
</entry>
</elementAttributes>
<pos x="680" y="300"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>YD</string>
</entry>
</elementAttributes>
<pos x="820" y="420"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
<elementAttributes/>
<pos x="760" y="420"/>
</visualElement>
<visualElement>
<elementName>PullUp</elementName>
<elementAttributes/>
<pos x="800" y="280"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>en val YU Y YD
0 0 1 Z 0
0 1 1 Z 0
1 0 0 0 0
1 1 1 1 1
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="640" y="440"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>Y</string>
</entry>
</elementAttributes>
<pos x="820" y="360"/>
</visualElement>
<visualElement>
<elementName>Driver</elementName>
<elementAttributes/>
<pos x="760" y="360"/>
</visualElement>
<visualElement>
<elementName>PullDown</elementName>
<elementAttributes/>
<pos x="800" y="440"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="720" y="320"/>
<p2 x="760" y="320"/>
</wire>
<wire>
<p1 x="680" y="260"/>
<p2 x="720" y="260"/>
</wire>
<wire>
<p1 x="720" y="260"/>
<p2 x="760" y="260"/>
</wire>
<wire>
<p1 x="780" y="420"/>
<p2 x="800" y="420"/>
</wire>
<wire>
<p1 x="700" y="420"/>
<p2 x="740" y="420"/>
</wire>
<wire>
<p1 x="800" y="420"/>
<p2 x="820" y="420"/>
</wire>
<wire>
<p1 x="780" y="360"/>
<p2 x="820" y="360"/>
</wire>
<wire>
<p1 x="700" y="360"/>
<p2 x="740" y="360"/>
</wire>
<wire>
<p1 x="720" y="380"/>
<p2 x="760" y="380"/>
</wire>
<wire>
<p1 x="780" y="300"/>
<p2 x="800" y="300"/>
</wire>
<wire>
<p1 x="680" y="300"/>
<p2 x="700" y="300"/>
</wire>
<wire>
<p1 x="800" y="300"/>
<p2 x="820" y="300"/>
</wire>
<wire>
<p1 x="700" y="300"/>
<p2 x="740" y="300"/>
</wire>
<wire>
<p1 x="720" y="260"/>
<p2 x="720" y="320"/>
</wire>
<wire>
<p1 x="720" y="320"/>
<p2 x="720" y="380"/>
</wire>
<wire>
<p1 x="800" y="280"/>
<p2 x="800" y="300"/>
</wire>
<wire>
<p1 x="800" y="420"/>
<p2 x="800" y="440"/>
</wire>
<wire>
<p1 x="760" y="260"/>
<p2 x="760" y="280"/>
</wire>
<wire>
<p1 x="760" y="380"/>
<p2 x="760" y="400"/>
</wire>
<wire>
<p1 x="760" y="320"/>
<p2 x="760" y="340"/>
</wire>
<wire>
<p1 x="700" y="300"/>
<p2 x="700" y="360"/>
</wire>
<wire>
<p1 x="700" y="360"/>
<p2 x="700" y="420"/>
</wire>
</wires>
</circuit>