diff --git a/src/main/java/de/neemann/digital/core/element/Keys.java b/src/main/java/de/neemann/digital/core/element/Keys.java index 30eb22da1..717bd4f6c 100644 --- a/src/main/java/de/neemann/digital/core/element/Keys.java +++ b/src/main/java/de/neemann/digital/core/element/Keys.java @@ -257,6 +257,12 @@ public final class Keys { public static final Key INVERT_OUTPUT = new Key<>("invertOutput", true); + /** + * inverts the output of an inverter + */ + public static final Key INVERT_DRIVER_OUTPUT + = new Key<>("invertDriverOutput", false).useTranslationOf(INVERT_OUTPUT).allowGroupEdit(); + /** * The real time frequency of the clock */ diff --git a/src/main/java/de/neemann/digital/core/wiring/Driver.java b/src/main/java/de/neemann/digital/core/wiring/Driver.java index d37ad96c6..35894d04c 100644 --- a/src/main/java/de/neemann/digital/core/wiring/Driver.java +++ b/src/main/java/de/neemann/digital/core/wiring/Driver.java @@ -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); + } } /** diff --git a/src/main/java/de/neemann/digital/core/wiring/DriverInvSel.java b/src/main/java/de/neemann/digital/core/wiring/DriverInvSel.java index 38a689432..448593fe4 100644 --- a/src/main/java/de/neemann/digital/core/wiring/DriverInvSel.java +++ b/src/main/java/de/neemann/digital/core/wiring/DriverInvSel.java @@ -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(); diff --git a/src/main/java/de/neemann/digital/draw/shapes/DriverShape.java b/src/main/java/de/neemann/digital/draw/shapes/DriverShape.java index fff2018ef..aed24f9aa 100644 --- a/src/main/java/de/neemann/digital/draw/shapes/DriverShape.java +++ b/src/main/java/de/neemann/digital/draw/shapes/DriverShape.java @@ -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); + } } } diff --git a/src/main/resources/verilog/DIG_Driver.v b/src/main/resources/verilog/DIG_Driver.v index 0a201dc16..a552a4367 100644 --- a/src/main/resources/verilog/DIG_Driver.v +++ b/src/main/resources/verilog/DIG_Driver.v @@ -21,5 +21,5 @@ module input sel, output out ); - assign out = (sel == 1'b1)? in : ; + assign out = (sel == 1'b1)? ~ in : ; endmodule \ No newline at end of file diff --git a/src/main/resources/verilog/DIG_DriverInvSel.v b/src/main/resources/verilog/DIG_DriverInvSel.v index 70d8fbb45..36a07aa9b 100644 --- a/src/main/resources/verilog/DIG_DriverInvSel.v +++ b/src/main/resources/verilog/DIG_DriverInvSel.v @@ -21,5 +21,5 @@ module input sel, output out ); - assign out = (sel == 1'b0)? in : ; + assign out = (sel == 1'b0)? ~ in : ; endmodule \ No newline at end of file diff --git a/src/main/resources/vhdl/DIG_Driver.tem b/src/main/resources/vhdl/DIG_Driver.tem index 439315def..8a2f598c5 100644 --- a/src/main/resources/vhdl/DIG_Driver.tem +++ b/src/main/resources/vhdl/DIG_Driver.tem @@ -16,5 +16,5 @@ end ; architecture Behavioral of is begin - p_out <= p_in when sel = '1' else 'Z'(others => 'Z'); + p_out <= NOT p_in when sel = '1' else 'Z'(others => 'Z'); end Behavioral; diff --git a/src/main/resources/vhdl/DIG_DriverInvSel.tem b/src/main/resources/vhdl/DIG_DriverInvSel.tem index aef56066c..a0c22b3e3 100644 --- a/src/main/resources/vhdl/DIG_DriverInvSel.tem +++ b/src/main/resources/vhdl/DIG_DriverInvSel.tem @@ -16,5 +16,5 @@ end ; architecture Behavioral of is begin - p_out <= p_in when sel = '0' else 'Z'(others => 'Z'); + p_out <= NOT p_in when sel = '0' else 'Z'(others => 'Z'); end Behavioral; diff --git a/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java b/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java index 769cbb4b8..6d6f621ee 100644 --- a/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java +++ b/src/test/java/de/neemann/digital/hdl/verilog2/VerilogSimulatorTest.java @@ -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 } diff --git a/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java b/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java index fb381c23c..b715094b0 100644 --- a/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java +++ b/src/test/java/de/neemann/digital/hdl/vhdl2/VHDLSimulatorTest.java @@ -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 } diff --git a/src/test/java/de/neemann/digital/integration/TestExamples.java b/src/test/java/de/neemann/digital/integration/TestExamples.java index 48080dafc..b46834f13 100644 --- a/src/test/java/de/neemann/digital/integration/TestExamples.java +++ b/src/test/java/de/neemann/digital/integration/TestExamples.java @@ -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); } /** diff --git a/src/test/resources/dig/test/vhdl/driver1inv.dig b/src/test/resources/dig/test/vhdl/driver1inv.dig new file mode 100644 index 000000000..48bcb8662 --- /dev/null +++ b/src/test/resources/dig/test/vhdl/driver1inv.dig @@ -0,0 +1,82 @@ + + + 2 + + + + Driver + + + invertDriverOutput + true + + + + + + In + + + Label + I + + + + + + Out + + + Label + O + + + + + + In + + + Label + S + + + + + + Testcase + + + Testdata + + S I O +0 0 Z +0 1 Z +1 0 1 +1 1 0 + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/dig/test/vhdl/driver2inv.dig b/src/test/resources/dig/test/vhdl/driver2inv.dig new file mode 100644 index 000000000..f7c95427a --- /dev/null +++ b/src/test/resources/dig/test/vhdl/driver2inv.dig @@ -0,0 +1,96 @@ + + + 2 + + + + In + + + Label + I + + + Bits + 4 + + + + + + Out + + + Label + O + + + Bits + 4 + + + + + + In + + + Label + S + + + + + + Testcase + + + Testdata + + S I O +1 0 Z +1 1 Z +0 0 0xf +0 1 0xe +0 4 0xb + + + + + + + + DriverInvSel + + + invertDriverOutput + true + + + Bits + 4 + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file