adds drivers with inverted output

This commit is contained in:
hneemann 2023-11-08 09:15:18 +01:00
parent 4cefc1e140
commit d65caa2c4d
13 changed files with 219 additions and 15 deletions

View File

@ -257,6 +257,12 @@ public final class Keys {
public static final Key<Boolean> INVERT_OUTPUT
= new Key<>("invertOutput", true);
/**
* inverts the output of an inverter
*/
public static final Key<Boolean> INVERT_DRIVER_OUTPUT
= new Key<>("invertDriverOutput", false).useTranslationOf(INVERT_OUTPUT).allowGroupEdit();
/**
* The real time frequency of the clock
*/

View File

@ -30,11 +30,13 @@ public class Driver extends Node implements Element, Countable {
input("sel"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
.addAttribute(Keys.INVERT_DRIVER_OUTPUT)
.addAttribute(Keys.FLIP_SEL_POSITON)
.supportsHDL();
private final ObservableValue output;
private final int bits;
private final boolean invertOut;
private ObservableValue input;
private ObservableValue selIn;
private long value;
@ -50,6 +52,7 @@ public class Driver extends Node implements Element, Countable {
output = new ObservableValue("out", bits)
.setToHighZ()
.setPinDescription(DESCRIPTION);
invertOut = attributes.get(Keys.INVERT_DRIVER_OUTPUT);
}
@Override
@ -62,8 +65,12 @@ public class Driver extends Node implements Element, Countable {
public void writeOutputs() throws NodeException {
if (isOutHighZ(sel))
output.setToHighZ();
else
output.setValue(value);
else {
if (invertOut)
output.setValue(~value);
else
output.setValue(value);
}
}
/**

View File

@ -24,6 +24,7 @@ public class DriverInvSel extends Driver {
input("sel"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
.addAttribute(Keys.INVERT_DRIVER_OUTPUT)
.addAttribute(Keys.FLIP_SEL_POSITON)
.supportsHDL();

View File

@ -27,6 +27,7 @@ public class DriverShape implements Shape {
private final boolean invertedInput;
private final PinDescriptions inputs;
private final PinDescriptions outputs;
private final boolean invertedOutput;
private Pins pins;
/**
@ -53,6 +54,7 @@ public class DriverShape implements Shape {
this.outputs = outputs;
this.bottom = attr.get(Keys.FLIP_SEL_POSITON);
this.invertedInput = invertedInput;
this.invertedOutput = attr.get(Keys.INVERT_DRIVER_OUTPUT);
}
@Override
@ -61,7 +63,10 @@ public class DriverShape implements Shape {
pins = new Pins();
pins.add(new Pin(new Vector(-SIZE, 0), inputs.get(0)));
pins.add(new Pin(new Vector(0, bottom ? SIZE : -SIZE), inputs.get(1)));
pins.add(new Pin(new Vector(SIZE, 0), outputs.get(0)));
if (invertedOutput)
pins.add(new Pin(new Vector(SIZE * 2, 0), outputs.get(0)));
else
pins.add(new Pin(new Vector(SIZE, 0), outputs.get(0)));
}
return pins;
}
@ -90,5 +95,11 @@ public class DriverShape implements Shape {
else
graphic.drawLine(new Vector(0, -SIZE), new Vector(0, -7), Style.NORMAL);
}
if (invertedOutput) {
graphic.drawCircle(new Vector(SIZE + 1, 4 - SIZE2),
new Vector(SIZE + 1 + (SIZE2 - 4) * 2, SIZE2 - 4), Style.NORMAL);
graphic.drawLine(new Vector(SIZE + 1 + (SIZE2 - 4) * 2, 0), new Vector(SIZE * 2, 0), Style.NORMAL);
}
}
}

View File

@ -21,5 +21,5 @@ module <?= moduleName ?>
input sel,
output <?= bitRange ?>out
);
assign out = (sel == 1'b1)? in : <?= zval ?>;
assign out = (sel == 1'b1)? <? if (elem.invertDriverOutput) { ?>~ <?- } ?>in : <?= zval ?>;
endmodule

View File

@ -21,5 +21,5 @@ module <?= moduleName ?>
input sel,
output <?= bitRange ?>out
);
assign out = (sel == 1'b0)? in : <?= zval ?>;
assign out = (sel == 1'b0)? <? if (elem.invertDriverOutput) { ?>~ <?- } ?>in : <?= zval ?>;
endmodule

View File

@ -16,5 +16,5 @@ end <?=entityName?>;
architecture Behavioral of <?=entityName?> is
begin
p_out <= p_in when sel = '1' else <? if (elem.Bits=1) { ?>'Z'<?} else {?>(others => 'Z')<? } ?>;
p_out <= <? if (elem.invertDriverOutput) { ?>NOT <? } ?>p_in when sel = '1' else <? if (elem.Bits=1) { ?>'Z'<?} else {?>(others => 'Z')<? } ?>;
end Behavioral;

View File

@ -16,5 +16,5 @@ end <?=entityName?>;
architecture Behavioral of <?=entityName?> is
begin
p_out <= p_in when sel = '0' else <? if (elem.Bits=1) { ?>'Z'<?} else {?>(others => 'Z')<? } ?>;
p_out <= <? if (elem.invertDriverOutput) { ?>NOT <? } ?>p_in when sel = '0' else <? if (elem.Bits=1) { ?>'Z'<?} else {?>(others => 'Z')<? } ?>;
end Behavioral;

View File

@ -11,6 +11,7 @@ import de.neemann.digital.core.extern.ProcessStarter;
import de.neemann.digital.gui.Settings;
import de.neemann.digital.hdl.model2.HDLException;
import de.neemann.digital.hdl.printer.CodePrinter;
import de.neemann.digital.hdl.printer.CodePrinterStr;
import de.neemann.digital.integration.FileScanner;
import de.neemann.digital.integration.Resources;
import de.neemann.digital.integration.TestExamples;
@ -39,7 +40,7 @@ public class VerilogSimulatorTest extends TestCase {
/*
public void testDebug() throws Exception {
File file = new File(Resources.getRoot(), "/dig/test/vhdl/pinControl/simple.dig");
File file = new File(Resources.getRoot(), "/dig/test/vhdl/driver1inv.dig");
ToBreakRunner br = new ToBreakRunner(file);
System.out.println(new VerilogGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
@ -51,8 +52,8 @@ public class VerilogSimulatorTest extends TestCase {
File examples = new File(Resources.getRoot(), "/dig/test/vhdl");
try {
int tested = new FileScanner(this::checkVerilogExport).noOutput().scan(examples);
assertEquals(68, tested);
assertEquals(58, testBenches);
assertEquals(70, tested);
assertEquals(60, testBenches);
} catch (FileScanner.SkipAllException e) {
// if iverilog is not installed its also ok
}

View File

@ -32,7 +32,7 @@ public class VHDLSimulatorTest extends TestCase {
/*
public void testDebug() throws Exception {
File file = new File(Resources.getRoot(), "dig/external/ghdl/ghdlFile.dig");
File file = new File(Resources.getRoot(), "/dig/test/vhdl/driver2inv.dig");
ToBreakRunner br = new ToBreakRunner(file);
System.out.println(new VHDLGenerator(br.getLibrary(), new CodePrinterStr(true)).export(br.getCircuit()));
@ -44,8 +44,8 @@ public class VHDLSimulatorTest extends TestCase {
File examples = new File(Resources.getRoot(), "/dig/test/vhdl");
try {
int tested = new FileScanner(this::checkVHDLExport).noOutput().scan(examples);
assertEquals(68, tested);
assertEquals(58, testBenches);
assertEquals(70, tested);
assertEquals(60, testBenches);
} catch (FileScanner.SkipAllException e) {
// if ghdl is not installed its also ok
}

View File

@ -51,8 +51,8 @@ public class TestExamples extends TestCase {
*/
public void testTestExamples() throws Exception {
File examples = new File(Resources.getRoot(), "/dig/test");
assertEquals(214, new FileScanner(this::check).scan(examples));
assertEquals(197, testCasesInFiles);
assertEquals(216, new FileScanner(this::check).scan(examples));
assertEquals(199, testCasesInFiles);
}
/**

View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>2</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>Driver</elementName>
<elementAttributes>
<entry>
<string>invertDriverOutput</string>
<boolean>true</boolean>
</entry>
</elementAttributes>
<pos x="380" y="160"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>I</string>
</entry>
</elementAttributes>
<pos x="340" y="160"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>O</string>
</entry>
</elementAttributes>
<pos x="440" y="160"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>S</string>
</entry>
</elementAttributes>
<pos x="340" y="100"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>S I O
0 0 Z
0 1 Z
1 0 1
1 1 0</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="340" y="220"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="420" y="160"/>
<p2 x="440" y="160"/>
</wire>
<wire>
<p1 x="340" y="160"/>
<p2 x="360" y="160"/>
</wire>
<wire>
<p1 x="340" y="100"/>
<p2 x="380" y="100"/>
</wire>
<wire>
<p1 x="380" y="100"/>
<p2 x="380" y="140"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>

View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<circuit>
<version>2</version>
<attributes/>
<visualElements>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>I</string>
</entry>
<entry>
<string>Bits</string>
<int>4</int>
</entry>
</elementAttributes>
<pos x="340" y="160"/>
</visualElement>
<visualElement>
<elementName>Out</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>O</string>
</entry>
<entry>
<string>Bits</string>
<int>4</int>
</entry>
</elementAttributes>
<pos x="440" y="160"/>
</visualElement>
<visualElement>
<elementName>In</elementName>
<elementAttributes>
<entry>
<string>Label</string>
<string>S</string>
</entry>
</elementAttributes>
<pos x="340" y="100"/>
</visualElement>
<visualElement>
<elementName>Testcase</elementName>
<elementAttributes>
<entry>
<string>Testdata</string>
<testData>
<dataString>S I O
1 0 Z
1 1 Z
0 0 0xf
0 1 0xe
0 4 0xb
</dataString>
</testData>
</entry>
</elementAttributes>
<pos x="340" y="220"/>
</visualElement>
<visualElement>
<elementName>DriverInvSel</elementName>
<elementAttributes>
<entry>
<string>invertDriverOutput</string>
<boolean>true</boolean>
</entry>
<entry>
<string>Bits</string>
<int>4</int>
</entry>
</elementAttributes>
<pos x="380" y="160"/>
</visualElement>
</visualElements>
<wires>
<wire>
<p1 x="420" y="160"/>
<p2 x="440" y="160"/>
</wire>
<wire>
<p1 x="340" y="160"/>
<p2 x="360" y="160"/>
</wire>
<wire>
<p1 x="340" y="100"/>
<p2 x="380" y="100"/>
</wire>
<wire>
<p1 x="380" y="100"/>
<p2 x="380" y="140"/>
</wire>
</wires>
<measurementOrdering/>
</circuit>