From b4f6c804b77959091a7a4421f3382ffac592907c Mon Sep 17 00:00:00 2001 From: hneemann Date: Wed, 23 Jan 2019 20:59:01 +0100 Subject: [PATCH] simplified the new masked ram --- .../digital/core/memory/RAMDualPort.java | 6 +- .../core/memory/RAMDualPortMasked.java | 101 ++++++++++++++++-- src/main/resources/lang/lang_de.xml | 11 +- src/main/resources/lang/lang_en.xml | 14 +-- src/test/resources/dig/test/RAM/maskedRAM.dig | 84 +++++---------- .../resources/dig/test/RAM/maskedRAM64.dig | 92 ++++++---------- 6 files changed, 165 insertions(+), 143 deletions(-) diff --git a/src/main/java/de/neemann/digital/core/memory/RAMDualPort.java b/src/main/java/de/neemann/digital/core/memory/RAMDualPort.java index 890db056d..8fea06633 100644 --- a/src/main/java/de/neemann/digital/core/memory/RAMDualPort.java +++ b/src/main/java/de/neemann/digital/core/memory/RAMDualPort.java @@ -167,15 +167,11 @@ public class RAMDualPort extends Node implements Element, RAMInterface { addr = (int) addrIn.getValue(); if (str) - writeDataToMemory(addr, data); + memory.setData(addr, data); lastClk = clk; } - void writeDataToMemory(int addr, long data) { - memory.setData(addr, data); - } - @Override public void writeOutputs() throws NodeException { if (ld) { diff --git a/src/main/java/de/neemann/digital/core/memory/RAMDualPortMasked.java b/src/main/java/de/neemann/digital/core/memory/RAMDualPortMasked.java index 66cc175f2..41317a2ff 100644 --- a/src/main/java/de/neemann/digital/core/memory/RAMDualPortMasked.java +++ b/src/main/java/de/neemann/digital/core/memory/RAMDualPortMasked.java @@ -5,19 +5,22 @@ */ package de.neemann.digital.core.memory; +import de.neemann.digital.core.Node; import de.neemann.digital.core.NodeException; import de.neemann.digital.core.ObservableValue; import de.neemann.digital.core.ObservableValues; +import de.neemann.digital.core.element.Element; import de.neemann.digital.core.element.ElementAttributes; import de.neemann.digital.core.element.ElementTypeDescription; import de.neemann.digital.core.element.Keys; +import de.neemann.digital.draw.elements.PinException; import static de.neemann.digital.core.element.PinInfo.input; /** * A memory which allows to overwrite single bytes. */ -public class RAMDualPortMasked extends RAMDualPort { +public class RAMDualPortMasked extends Node implements Element, RAMInterface { private static final long[] MASK_TABLE = new long[256]; @@ -41,17 +44,27 @@ public class RAMDualPortMasked extends RAMDualPort { input("A"), input("Din"), input("str"), - input("C").setClock(), - input("ld"), - input("mask")) + input("C").setClock()) .addAttribute(Keys.ROTATE) .addAttribute(Keys.BITS) .addAttribute(Keys.ADDR_BITS) .addAttribute(Keys.IS_PROGRAM_MEMORY) .addAttribute(Keys.LABEL); + private DataField memory; + private final ObservableValue output; + private final int addrBits; + private final int bits; + private final String label; + private final int size; + private final boolean isProgramMemory; private final int maskBits; private ObservableValue maskVal; + private ObservableValue addrIn; + private ObservableValue dataIn; + private ObservableValue clkIn; + private boolean lastClk = false; + private long outputVal; /** * Creates a new instance @@ -59,25 +72,95 @@ public class RAMDualPortMasked extends RAMDualPort { * @param attr the elements attributes */ public RAMDualPortMasked(ElementAttributes attr) { - super(attr); + super(true); + bits = attr.get(Keys.BITS); + output = new ObservableValue("D", bits).setPinDescription(DESCRIPTION); + addrBits = attr.get(Keys.ADDR_BITS); + size = 1 << addrBits; + memory = new DataField(size); + label = attr.getCleanLabel(); + isProgramMemory = attr.get(Keys.IS_PROGRAM_MEMORY); maskBits = Math.min(8, (getDataBits() - 1) / 8 + 1); } + @Override public void setInputs(ObservableValues inputs) throws NodeException { - super.setInputs(inputs); - maskVal = inputs.get(5).checkBits(maskBits, this).addObserverToValue(this); + addrIn = inputs.get(0).checkBits(addrBits, this); + dataIn = inputs.get(1).checkBits(bits, this); + maskVal = inputs.get(2).checkBits(maskBits, this); + clkIn = inputs.get(3).checkBits(1, this).addObserverToValue(this); } @Override - void writeDataToMemory(int addr, long data) { + public void readInputs() throws NodeException { + boolean clk = clkIn.getBool(); + if (!lastClk && clk) { + int addr = (int) addrIn.getValue(); + outputVal = memory.getDataWord(addr); + int maskVal = (int) this.maskVal.getValue(); + if (maskVal != 0) { + long wData = dataIn.getValue(); + writeDataToMemory(addr, wData, maskVal); + } + } + lastClk = clk; + } + + private void writeDataToMemory(int addr, long data, int maskVal) { DataField memory = getMemory(); long old = memory.getDataWord(addr); - long mask = MASK_TABLE[(int) maskVal.getValue()]; + long mask = MASK_TABLE[maskVal]; data = data & mask; old = old & ~mask; memory.setData(addr, data | old); } + + @Override + public void writeOutputs() throws NodeException { + output.setValue(outputVal); + } + + @Override + public ObservableValues getOutputs() throws PinException { + return output.asList(); + } + + @Override + public DataField getMemory() { + return memory; + } + + @Override + public String getLabel() { + return label; + } + + @Override + public int getSize() { + return size; + } + + @Override + public int getAddrBits() { + return addrBits; + } + + @Override + public boolean isProgramMemory() { + return isProgramMemory; + } + + @Override + public void setProgramMemory(DataField dataField) { + memory.setDataFrom(dataField); + } + + @Override + public int getDataBits() { + return bits; + } + } diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index c75b17695..9ddf4c81c 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -483,17 +483,16 @@ Ein RAM Modul mit getrennten Daten-Anschlüssen für Lesen und Schreiben. Es gibt einen Eingang für das Beschreiben und einen Ausgang für das Auslesen der gespeicherten Daten. Zusätzlich wird das Überschreigen einzelner Bytes ermöglicht. Auf diese Weise kann z.B. in einem 32 - Bit Speicher ein einzelnes Byte überschrieben werden. + Bit Speicher ein einzelnes Byte überschrieben werden. Dieser RAM-Baustein aktualisiert seinen Ausgang + nur bei einer steigenden Flanke an der Clock. Das erlaubt die Verwendung von Block-RAM in einem FPGA. Die Adresse, an der gelesen bzw. geschrieben wird. - Der Takt. Eine steigende Flanke aktiviert das Speichern. + Der Takt. A rising edge activates storing and reading. Die Daten, die gespeichert werden sollen. Ausgabe der gespeicherten Daten. - Ist diese Leitung high, wird der Ausgang aktiviert, und die Daten liegen dort an. - Ist diese Leitung high, wird das Datenwort gespeichert, wenn der Takt ansteigt. - Setzt die Schreibmaske. In dieser Maske steht jewels ein Bit für ein + Setzt die Schreibmaske. In dieser Maske steht jewels ein Bit für ein Byte im Speicher, welches überschrieben werden kann. Soll also das zweite Byte im Speicherwort überschrieben werden, - muss auch das zweite Bit in der Maske gesetzt sein. + muss auch das zweite Bit in der Maske gesetzt sein. Ist kein Bit gesetzt, wird nicht gespeichert. EEPROM, getrennte Ports diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index e808e1774..58eb1c68f 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -486,19 +486,19 @@ RAM, separated ports, byte access RAM - A RAM module with separate inputs for storing and output for reading the stored data. - In addition, individual bytes can be overwritten. In this way, for example, a single byte can be overwritten in a 32-bit memory. + A RAM module with separate inputs for storing and output for reading the + stored data. In addition, individual bytes can be overwritten. In this way, for example, a single byte can be + overwritten in a 32-bit memory. This RAM only updates its output on a rising edge of the clock input. + This allows the usage of Block RAM on an FPGA. The address to read from or write to. Clock input The data to be stored in the RAM. The data output pin - If this input is high the output is activated and the data is visible at the output. - If this input is high and when the clock becomes high, the the data is stored. - Sets the write mask. In this mask there is one bit for each byte in the memory, + Sets the write mask. In this mask there is one bit for each byte in the memory, which can be overwritten. If the second byte in the memory word is to be overwritten, the second bit in - the mask must also be set. - + the mask must also be set. If no bit is set, no data is stored. + EEPROM, separated Ports EEPROM A EEPROM module with separate inputs for storing and output for reading the stored data. diff --git a/src/test/resources/dig/test/RAM/maskedRAM.dig b/src/test/resources/dig/test/RAM/maskedRAM.dig index 25387643e..bb609dfa9 100644 --- a/src/test/resources/dig/test/RAM/maskedRAM.dig +++ b/src/test/resources/dig/test/RAM/maskedRAM.dig @@ -29,7 +29,7 @@ 32 - + In @@ -43,7 +43,7 @@ 8 - + In @@ -59,16 +59,6 @@ - - In - - - Label - str - - - - Clock @@ -79,16 +69,6 @@ - - In - - - Label - ld - - - - In @@ -101,7 +81,7 @@ 4 - + Testcase @@ -109,55 +89,55 @@ Testdata - C A Din str ld mask D + C A Din mask D # no write at all, mask is zero -C 0 0xffffffff 1 0 0b0000 x -0 0 0 0 1 0b0000 0 +C 0 0xffffffff 0b0000 x +0 0 0 0b0000 0 # write bytes -C 0 0xffffffff 1 0 0b0001 x -0 0 0 0 1 0b0000 0xff +C 0 0xffffffff 0b0001 x +C 0 0 0b0000 0xff -C 0 0xffffff00 1 0 0b0010 x -0 0 0 0 1 0b0000 0xffff +C 0 0xffffff00 0b0010 x +C 0 0 0b0000 0xffff -C 0 0xffff0000 1 0 0b0100 x -0 0 0 0 1 0b0000 0xffffff +C 0 0xffff0000 0b0100 x +C 0 0 0b0000 0xffffff -C 0 0xff000000 1 0 0b1000 x -0 0 0 0 1 0b0000 0xffffffff +C 0 0xff000000 0b1000 x +C 0 0 0b0000 0xffffffff # write 16 bit words -C 1 0xffff 1 0 0b0011 x -0 1 0 0 1 0b0000 0xffff +C 1 0xffff 0b0011 x +C 1 0 0b0000 0xffff -C 1 0xffff0000 1 0 0b1100 x -0 1 0 0 1 0b0000 0xffffffff +C 1 0xffff0000 0b1100 x +C 1 0 0b0000 0xffffffff -C 1 0xaaaa00 1 0 0b0110 x -0 1 0 0 1 0b0000 0xffaaaaff +C 1 0xaaaa00 0b0110 x +C 1 0 0b0000 0xffaaaaff # write 32 bit words -C 2 0xffffffff 1 0 0b1111 x -0 2 0 0 1 0b0000 0xffffffff +C 2 0xffffffff 0b1111 x +C 2 0 0b0000 0xffffffff - + - - + + - + @@ -169,16 +149,8 @@ C 2 0xffffffff 1 0 0b1111 x - - - - - - - - - - + + \ No newline at end of file diff --git a/src/test/resources/dig/test/RAM/maskedRAM64.dig b/src/test/resources/dig/test/RAM/maskedRAM64.dig index 2ceacb73b..d7b557fc0 100644 --- a/src/test/resources/dig/test/RAM/maskedRAM64.dig +++ b/src/test/resources/dig/test/RAM/maskedRAM64.dig @@ -29,7 +29,7 @@ 64 - + In @@ -43,7 +43,7 @@ 8 - + In @@ -59,16 +59,6 @@ - - In - - - Label - str - - - - Clock @@ -79,16 +69,6 @@ - - In - - - Label - ld - - - - In @@ -101,7 +81,7 @@ 8 - + Testcase @@ -109,59 +89,59 @@ Testdata - C A Din str ld mask D + C A Din mask D # no write at all, mask is zero -C 0 0xffffffffffffffff 1 0 0b00000000 x -0 0 0 0 1 0b00000000 0 +C 0 0xffffffffffffffff 0b00000000 x +C 0 0 0b00000000 0 # write bytes -C 0 0xffffffffffffffff 1 0 0b00000001 x -0 0 0 0 1 0b00000000 0xff +C 0 0xffffffffffffffff 0b00000001 x +C 0 0 0b00000000 0xff -C 0 0xffffffffffffff00 1 0 0b00000010 x -0 0 0 0 1 0b00000000 0xffff +C 0 0xffffffffffffff00 0b00000010 x +C 0 0 0b00000000 0xffff -C 0 0xffffffffffff0000 1 0 0b00000100 x -0 0 0 0 1 0b00000000 0xffffff +C 0 0xffffffffffff0000 0b00000100 x +C 0 0 0b00000000 0xffffff -C 0 0xffffffffff000000 1 0 0b00001000 x -0 0 0 0 1 0b00000000 0xffffffff +C 0 0xffffffffff000000 0b00001000 x +C 0 0 0b00000000 0xffffffff -C 0 0xffffffff00000000 1 0 0b00010000 x -0 0 0 0 1 0b00000000 0xffffffffff +C 0 0xffffffff00000000 0b00010000 x +C 0 0 0b00000000 0xffffffffff -C 0 0xffffff0000000000 1 0 0b00100000 x -0 0 0 0 1 0b00000000 0xffffffffffff +C 0 0xffffff0000000000 0b00100000 x +C 0 0 0b00000000 0xffffffffffff -C 0 0xffff000000000000 1 0 0b01000000 x -0 0 0 0 1 0b00000000 0xffffffffffffff +C 0 0xffff000000000000 0b01000000 x +C 0 0 0b00000000 0xffffffffffffff -C 0 0xff00000000000000 1 0 0b10000000 x -0 0 0 0 1 0b00000000 0xffffffffffffffff +C 0 0xff00000000000000 0b10000000 x +C 0 0 0b00000000 0xffffffffffffffff # write 32 bit words -C 1 0xffffffff 1 0 0b00001111 x -0 1 0 0 1 0b00000000 0xffffffff +C 1 0xffffffff 0b00001111 x +C 1 0 0b00000000 0xffffffff -C 1 0xaaaaaaaa00000000 1 0 0b11110000 x -0 1 0 0 1 0b00000000 0xaaaaaaaaffffffff +C 1 0xaaaaaaaa00000000 0b11110000 x +C 1 0 0b00000000 0xaaaaaaaaffffffff - + - - + + - + @@ -173,16 +153,8 @@ C 1 0xaaaaaaaa00000000 1 0 0b11110000 x - - - - - - - - - - + + \ No newline at end of file