+++ /dev/null
-package net.mograsim.machine;
-
-public class DefaultMainMemoryDefinition implements MainMemoryDefinition {
- private final int memoryAddressBits, cellWidth;
- private final long minimalAddress, maximalAddress;
-
- public DefaultMainMemoryDefinition(int memoryAddressBits, int cellWidth, long minimalAddress, long maximalAddress)
- {
- super();
- this.memoryAddressBits = memoryAddressBits;
- this.cellWidth = cellWidth;
- this.minimalAddress = minimalAddress;
- this.maximalAddress = maximalAddress;
- }
-
- public DefaultMainMemoryDefinition(MainMemoryDefinition definition)
- {
- this(definition.getMemoryAddressBits(), definition.getCellWidth(), definition.getMinimalAddress(), definition.getMaximalAddress());
- }
-
- @Override
- public int getMemoryAddressBits()
- {
- return memoryAddressBits;
- }
-
- @Override
- public int getCellWidth()
- {
- return cellWidth;
- }
-
- @Override
- public long getMinimalAddress()
- {
- return minimalAddress;
- }
-
- @Override
- public long getMaximalAddress()
- {
- return maximalAddress;
- }
-
-}
--- /dev/null
+package net.mograsim.machine;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class GenericMemory<T> implements Memory<T>
+{
+ private final long minimalAddress, maximalAddress;
+ private final MemoryDefinition definition;
+ private final int pageSize = 64;
+ private Set<MemoryObserver> observers = new HashSet<>();
+
+ private HashMap<Long, Page> pages;
+
+ public GenericMemory(MemoryDefinition definition)
+ {
+ super();
+ this.definition = definition;
+ this.minimalAddress = definition.getMinimalAddress();
+ this.maximalAddress = definition.getMaximalAddress();
+ this.pages = new HashMap<>();
+ }
+
+ private void inBoundsCheck(long address)
+ {
+ if (address < minimalAddress || address > maximalAddress)
+ throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d",
+ minimalAddress, maximalAddress, address));
+ }
+
+ private long page(long address)
+ {
+ return address / pageSize;
+ }
+
+ private int offset(long address)
+ {
+ return (int) (address % pageSize);
+ }
+
+ @Override
+ public void setCell(long address, T data)
+ {
+ inBoundsCheck(address);
+ long page = page(address);
+ int offset = offset(address);
+ Page p = pages.get(Long.valueOf(page));
+ if (p == null)
+ pages.put(page, p = new Page());
+ p.setCell(offset, data);
+ notifyObservers(address);
+ }
+
+ @Override
+ public T getCell(long address)
+ {
+ inBoundsCheck(address);
+ long page = page(address);
+ int offset = offset(address);
+ Page p = pages.get(Long.valueOf(page));
+ if (p == null)
+ return null;
+ return p.getCell(offset);
+ }
+
+ private class Page
+ {
+ private Object[] memory;
+
+ public Page()
+ {
+ memory = new Object[pageSize];
+ }
+
+ public T getCell(int index)
+ {
+ @SuppressWarnings("unchecked")
+ T data = (T) memory[index];
+ return data;
+ }
+
+ public void setCell(int index, T data)
+ {
+ memory[index] = data;
+ }
+
+ @Override
+ public String toString()
+ {
+ return Arrays.deepToString(memory);
+ }
+ }
+
+ @Override
+ public void registerObserver(MemoryObserver ob)
+ {
+ observers.add(ob);
+ }
+
+ @Override
+ public void deregisterObserver(MemoryObserver ob)
+ {
+ observers.remove(ob);
+ }
+
+ @Override
+ public void notifyObservers(long address)
+ {
+ observers.forEach(ob -> ob.update(address));
+ }
+
+ @Override
+ public MemoryDefinition getDefinition()
+ {
+ return definition;
+ }
+}
import net.mograsim.logic.core.types.BitVector;
-public interface MainMemory extends Memory<BitVector> {
-
+public interface MainMemory extends Memory<BitVector>
+{
public BigInteger getCellAsBigInteger(long address);
+
public void setCellAsBigInteger(long address, BigInteger word);
+
public MainMemoryDefinition getDefinition();
- public default long size()
- {
- return getDefinition().size();
- }
}
* @author Christian Femers
*
*/
-public interface MainMemoryDefinition {
-
- /**
- * The number of bits that the main memory uses to address cells. Note that this
- * does not need to equal {@link MachineDefinition#getAddressBits()}.
- *
- * @return the number of bits used to address a memory cell
- * @author Christian Femers
- */
- int getMemoryAddressBits();
-
+public interface MainMemoryDefinition extends MemoryDefinition
+{
/**
* The width in bits of an addressable memory cell/unit. This is often 8 (= one
* byte). The actual cells/lines of the memory may be a lot larger.
* @author Christian Femers
*/
int getCellWidth();
-
- /**
- * The minimal address possible to address/use. This is usually 0.
- *
- * @return the minimal possible address.
- * @author Christian Femers
- */
- long getMinimalAddress();
-
- /**
- * The maximal address possible to address/use.
- *
- * @return the maximal possible address as <b>unsigned long</b>
- * @author Christian Femers
- */
- long getMaximalAddress();
- /**
- * The size of the MainMemory as the amount of addressable memory cells.
- *
- * @return the amount of addressable memory cells
- */
- default long size()
+ public static MainMemoryDefinition create(int memoryAddressBits, int cellWidth, long minimalAddress, long maximalAddress)
{
- return getMaximalAddress() - getMinimalAddress();
+ return new StandardMainMemoryDefinition(memoryAddressBits, cellWidth, minimalAddress, maximalAddress);
}
}
*/
public void setCell(long address, T data);
- public long size();
+ public default long size()
+ {
+ MemoryDefinition def = getDefinition();
+ return Long.max(0, def.getMaximalAddress() - def.getMinimalAddress());
+ }
/**
* Registers an observer to be notified when a memory cell is modified
public void deregisterObserver(MemoryObserver ob);
public void notifyObservers(long address);
+
+ public MemoryDefinition getDefinition();
}
--- /dev/null
+package net.mograsim.machine;
+
+public interface MemoryDefinition {
+
+ /**
+ * The number of bits that the main memory uses to address cells. Note that this
+ * does not need to equal {@link MachineDefinition#getAddressBits()}.
+ *
+ * @return the number of bits used to address a memory cell
+ * @author Christian Femers
+ */
+ int getMemoryAddressBits();
+
+ /**
+ * The minimal address possible to address/use. This is usually 0.
+ *
+ * @return the minimal possible address.
+ * @author Christian Femers
+ */
+ long getMinimalAddress();
+
+ /**
+ * The maximal address possible to address/use.
+ *
+ * @return the maximal possible address as <b>unsigned long</b>
+ * @author Christian Femers
+ */
+ long getMaximalAddress();
+
+ /**
+ * The size of the MainMemory as the amount of addressable memory cells.
+ *
+ * @return the amount of addressable memory cells
+ */
+ default long size()
+ {
+ return getMaximalAddress() - getMinimalAddress();
+ }
+
+ public static MemoryDefinition create(int memoryAddressBits, long minimalAddress, long maximalAddress)
+ {
+ return new StandardMemoryDefinition(memoryAddressBits, minimalAddress, maximalAddress);
+ }
+}
+++ /dev/null
-package net.mograsim.machine;
-
-import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
-import net.mograsim.machine.mi.parameters.Mnemonic;
-
-public interface MicroInstruction {
-
- public MicroInstructionParameter getParameter(int index);
-
- /**
- * @return The amount of {@link Mnemonic}s, the instruction is composed of
- */
- public int getSize();
-}
+++ /dev/null
-package net.mograsim.machine;
-
-import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
-import net.mograsim.machine.mi.parameters.ParameterClassification;
-
-public interface MicroInstructionDefinition
-{
- /**
- * @return The {@link ParameterClassification}s of which a MicroInstruction is composed.
- */
- public ParameterClassification[] getParameterClassifications();
-
- /**
- * @return The amount of {@link MicroInstructionParameter}s in a {@link MicroInstruction} that follows this definition.
- */
- public default int size()
- {
- return getParameterClassifications().length;
- }
-
-}
+++ /dev/null
-package net.mograsim.machine;
-
-public interface MicroprogramMemory extends Memory<MicroInstruction>
-{
-}
--- /dev/null
+package net.mograsim.machine;
+
+class StandardMainMemoryDefinition extends StandardMemoryDefinition implements MainMemoryDefinition {
+ private final int cellWidth;
+
+ StandardMainMemoryDefinition(int memoryAddressBits, int cellWidth, long minimalAddress, long maximalAddress)
+ {
+ super(memoryAddressBits, minimalAddress, maximalAddress);
+ this.cellWidth = cellWidth;
+ }
+
+ @Override
+ public int getCellWidth()
+ {
+ return cellWidth;
+ }
+}
--- /dev/null
+package net.mograsim.machine;
+
+class StandardMemoryDefinition implements MemoryDefinition {
+ private final int memoryAddressBits;
+ private final long minimalAddress, maximalAddress;
+
+ StandardMemoryDefinition(int memoryAddressBits, long minimalAddress, long maximalAddress)
+ {
+ super();
+ this.memoryAddressBits = memoryAddressBits;
+ this.minimalAddress = minimalAddress;
+ this.maximalAddress = maximalAddress;
+ }
+
+ public StandardMemoryDefinition(MainMemoryDefinition definition)
+ {
+ this(definition.getMemoryAddressBits(), definition.getMinimalAddress(), definition.getMaximalAddress());
+ }
+
+ @Override
+ public int getMemoryAddressBits()
+ {
+ return memoryAddressBits;
+ }
+
+ @Override
+ public long getMinimalAddress()
+ {
+ return minimalAddress;
+ }
+
+ @Override
+ public long getMaximalAddress()
+ {
+ return maximalAddress;
+ }
+
+ public static MemoryDefinition create(int memoryAddressBits, long minimalAddress, long maximalAddress)
+ {
+ return new StandardMemoryDefinition(memoryAddressBits, minimalAddress, maximalAddress);
+ }
+}
--- /dev/null
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
+import net.mograsim.machine.mi.parameters.Mnemonic;
+
+public interface MicroInstruction {
+
+ public MicroInstructionParameter getParameter(int index);
+ public void setParameter(int index, MicroInstructionParameter param);
+
+ /**
+ * @return The amount of {@link Mnemonic}s, the instruction is composed of
+ */
+ public int getSize();
+
+ public static MicroInstruction create(MicroInstructionParameter... parameters)
+ {
+ return new StandardMicroInstruction(parameters);
+ }
+}
--- /dev/null
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
+import net.mograsim.machine.mi.parameters.ParameterClassification;
+
+public interface MicroInstructionDefinition
+{
+ /**
+ * @return The {@link ParameterClassification}s of which a MicroInstruction is composed.
+ */
+ public ParameterClassification[] getParameterClassifications();
+
+ /**
+ * @throws IndexOutOfBoundsException
+ */
+ public ParameterClassification getParameterClassification(int index);
+
+
+ /**
+ * @return The amount of {@link MicroInstructionParameter}s in a {@link MicroInstruction} that follows this definition.
+ */
+ public default int size()
+ {
+ return getParameterClassifications().length;
+ }
+
+ public static MicroInstructionDefinition create(ParameterClassification... classes)
+ {
+ return new StandardMicroInstructionDefinition(classes);
+ }
+}
\ No newline at end of file
--- /dev/null
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.Memory;
+import net.mograsim.machine.MemoryDefinition;
+
+public interface MicroprogramMemory extends Memory<MicroInstruction>
+{
+ public static MicroprogramMemory create(MemoryDefinition def)
+ {
+ return new StandardMicroprogramMemory(def);
+ }
+}
--- /dev/null
+package net.mograsim.machine.mi;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.math.BigInteger;
+
+import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.machine.MemoryDefinition;
+import net.mograsim.machine.mi.parameters.BooleanClassification;
+import net.mograsim.machine.mi.parameters.BooleanImmediate;
+import net.mograsim.machine.mi.parameters.IntegerClassification;
+import net.mograsim.machine.mi.parameters.IntegerImmediate;
+import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
+import net.mograsim.machine.mi.parameters.MnemonicFamily;
+import net.mograsim.machine.mi.parameters.MnemonicFamily.MnemonicPair;
+import net.mograsim.machine.mi.parameters.ParameterClassification;
+
+public class MicroprogramMemoryParser
+{
+ public static void parse(MicroprogramMemory memory, long startAddress, MicroInstructionDefinition definition, String input) throws IOException
+ {
+ try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(input))))
+ {
+ parse(memory, startAddress, definition, reader);
+ }
+ }
+
+ public static void parse(MicroprogramMemory memory, long startAddress, MicroInstructionDefinition definition,
+ BufferedReader input)
+ {
+ MemoryDefinition def = memory.getDefinition();
+ long minAddress = Long.max(startAddress, def.getMinimalAddress()), maxAddress = def.getMaximalAddress();
+ try
+ {
+ String line;
+ for (long i = minAddress; i < maxAddress && input.ready() && !"".equals((line = input.readLine())); i++)
+ memory.setCell(i, parse(definition, line));
+ } catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ public static MicroInstruction parse(MicroInstructionDefinition definition, String toParse)
+ {
+ int size = definition.size();
+ String[] strings = toParse.split(",");
+ if (size != strings.length)
+ throw new IllegalArgumentException(
+ "String does not match definition! The number of parameters does not match.");
+ MicroInstructionParameter[] params = new MicroInstructionParameter[size];
+ ParameterClassification[] classes = definition.getParameterClassifications();
+ for (int i = 0; i < size; i++)
+ {
+ params[i] = classes[i].parse(strings[i]);
+ }
+ return new StandardMicroInstruction(params);
+ }
+
+ public static void write(MicroprogramMemory memory, long startAddress, long endAddress, String output) throws IOException
+ {
+ try(OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(output)))
+ {
+ write(memory, startAddress, endAddress, writer);
+ }
+ }
+
+ public static void write(MicroprogramMemory memory, long startAddress, long endAddress, OutputStreamWriter output) throws IOException
+ {
+ MemoryDefinition def = memory.getDefinition();
+ long min = Long.max(def.getMinimalAddress(), startAddress), max = Long.min(def.getMaximalAddress(), endAddress) + 1;
+ for(long i = min; i < max; i++)
+ {
+ output.write(toCSV(memory.getCell(i)) + "\n");
+ }
+ }
+
+ private static String toCSV(MicroInstruction inst)
+ {
+ int max = inst.getSize() - 1;
+ StringBuilder sb = new StringBuilder();
+ for(int i = 0; i < max; i++)
+ {
+ sb.append(inst.getParameter(i).toString());
+ sb.append(",");
+ }
+ sb.append(inst.getParameter(max).toString());
+ return sb.toString();
+ }
+}
--- /dev/null
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
+
+class StandardMicroInstruction implements MicroInstruction
+{
+ private MicroInstructionParameter[] parameters;
+
+ StandardMicroInstruction(MicroInstructionParameter... parameters)
+ {
+ this.parameters = parameters;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException
+ */
+ @Override
+ public MicroInstructionParameter getParameter(int index)
+ {
+ return parameters[index];
+ }
+
+ @Override
+ public int getSize()
+ {
+ return parameters.length;
+ }
+
+ /**
+ * @throws IndexOutOfBoundsException
+ */
+ @Override
+ public void setParameter(int index, MicroInstructionParameter param)
+ {
+ parameters[index] = param;
+ }
+
+}
--- /dev/null
+package net.mograsim.machine.mi;
+
+import net.mograsim.machine.mi.parameters.ParameterClassification;
+
+class StandardMicroInstructionDefinition implements MicroInstructionDefinition
+{
+ private ParameterClassification[] classes;
+
+ public StandardMicroInstructionDefinition(ParameterClassification... classes)
+ {
+ this.classes = classes;
+ }
+
+ @Override
+ public ParameterClassification[] getParameterClassifications()
+ {
+ return classes.clone();
+ }
+
+ @Override
+ public ParameterClassification getParameterClassification(int index)
+ {
+ return classes[index];
+ }
+
+}
--- /dev/null
+package net.mograsim.machine.mi;
+
+import java.util.HashSet;
+
+import net.mograsim.machine.MemoryDefinition;
+import net.mograsim.machine.MemoryObserver;
+import net.mograsim.machine.standard.memory.MemoryException;
+
+class StandardMicroprogramMemory implements MicroprogramMemory
+{
+ private MicroInstruction[] data;
+ private MemoryDefinition definition;
+ private HashSet<MemoryObserver> observers;
+
+ StandardMicroprogramMemory(MemoryDefinition definition)
+ {
+ if(definition.size() > Integer.MAX_VALUE)
+ throw new MemoryException("Size of MicroprogramMemory must be an int, not a long");
+ this.definition = definition;
+ data = new MicroInstruction[(int) definition.size()];
+ }
+
+ private int translate(long address)
+ {
+ return (int) (address - definition.getMinimalAddress());
+ }
+
+ @Override
+ public MicroInstruction getCell(long address)
+ {
+ return data[translate(address)];
+ }
+
+ @Override
+ public void setCell(long address, MicroInstruction data)
+ {
+ this.data[translate(address)] = data;
+ }
+
+ @Override
+ public void registerObserver(MemoryObserver ob)
+ {
+ observers.add(ob);
+ }
+
+ @Override
+ public void deregisterObserver(MemoryObserver ob)
+ {
+ observers.remove(ob);
+ }
+
+ @Override
+ public void notifyObservers(long address)
+ {
+ observers.forEach(ob -> ob.update(address));
+ }
+
+ @Override
+ public MemoryDefinition getDefinition()
+ {
+ return definition;
+ }
+
+}
{
return 1;
}
+
+ @Override
+ public BooleanImmediate parse(String toParse)
+ {
+ return new BooleanImmediate("H".equals(toParse));
+ }
}
package net.mograsim.machine.mi.parameters;
+import java.math.BigInteger;
+
import net.mograsim.machine.mi.parameters.MicroInstructionParameter.ParameterType;
public class IntegerClassification implements ParameterClassification
{
return bits;
}
+
+ @Override
+ public IntegerImmediate parse(String toParse)
+ {
+ return new IntegerImmediate(new BigInteger(toParse), bits);
+ }
}
return stringValues.clone();
}
-
-
@Override
public int hashCode()
{
{
return this == obj;
}
-
-
+
+ @Override
+ public Mnemonic parse(String toParse)
+ {
+ Mnemonic parsed = get(toParse);
+ if(parsed == null)
+ throw new UnknownMnemonicException(toParse);
+ return parsed;
+ }
public static class MnemonicPair
{
* @return The number of bits of the parameters in this classification.
*/
public int getExpectedBits();
+
+ public MicroInstructionParameter parse(String toParse);
}
--- /dev/null
+package net.mograsim.machine.mi.parameters;
+
+import net.mograsim.machine.MachineException;
+
+public class UnknownMnemonicException extends MachineException
+{
+ /**
+ *
+ */
+ private static final long serialVersionUID = 701558899889830975L;
+
+ public UnknownMnemonicException()
+ {
+ super();
+ }
+
+ public UnknownMnemonicException(String message)
+ {
+ super(message);
+ }
+
+ public UnknownMnemonicException(Throwable cause)
+ {
+ super(cause);
+ }
+}
import org.eclipse.swt.graphics.Color;
-import com.google.gson.Gson;
import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
import net.haspamelodica.swt.helper.gcs.GeneralGC;
import net.haspamelodica.swt.helper.swtobjectwrappers.Font;
import net.mograsim.logic.model.modeladapter.ViewLogicModelAdapter;
import net.mograsim.logic.model.serializing.IdentifierGetter;
import net.mograsim.logic.model.serializing.IndirectGUIComponentCreator;
-import net.mograsim.machine.DefaultMainMemoryDefinition;
import net.mograsim.machine.MainMemoryDefinition;
import net.mograsim.machine.standard.memory.WordAddressableMemoryComponent;
import net.mograsim.preferences.Preferences;
private final Pin addrPin, dataPin, rWPin;
private WordAddressableMemoryComponent memory;
private final static int width = 100, height = 300;
+
+ private final static String addrKey = "addrBits", cellWidthKey = "cellWidth", minAddrKey = "minAddr", maxAddrKey = "maxAddr";
public GUIMemoryWA(ViewModelModifiable model, MainMemoryDefinition definition, String name)
{
@Override
public JsonElement getParamsForSerializing(IdentifierGetter idGetter)
{
- return new Gson().toJsonTree(new DefaultMainMemoryDefinition(definition));
+ JsonObject o = new JsonObject();
+ o.addProperty(addrKey, definition.getMemoryAddressBits());
+ o.addProperty(cellWidthKey, definition.getCellWidth());
+ o.addProperty(maxAddrKey, definition.getMaximalAddress());
+ o.addProperty(minAddrKey, definition.getMinimalAddress());
+ return o;
}
static
ViewLogicModelAdapter.addComponentAdapter(new WordAddressableMemoryAdapter());
IndirectGUIComponentCreator.setComponentSupplier(GUIAndGate.class.getCanonicalName(), (m, p, n) ->
{
- return new GUIMemoryWA(m, new Gson().fromJson(p, DefaultMainMemoryDefinition.class), n);
+ JsonObject o = (JsonObject) p;
+ int addressBits = o.get(addrKey).getAsInt();
+ int cellWidth = o.get(cellWidthKey).getAsInt();
+ long maxAddr = o.get(maxAddrKey).getAsLong();
+ long minAddr = o.get(minAddrKey).getAsLong();
+ return new GUIMemoryWA(m, MainMemoryDefinition.create(addressBits, cellWidth, minAddr, maxAddr), n);
});
}
}
package net.mograsim.machine.standard.memory;
import java.math.BigInteger;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Set;
import net.mograsim.logic.core.types.Bit;
import net.mograsim.logic.core.types.BitVector;
+import net.mograsim.machine.GenericMemory;
import net.mograsim.machine.MainMemory;
import net.mograsim.machine.MainMemoryDefinition;
-import net.mograsim.machine.MemoryObserver;
-public class WordAddressableMemory implements MainMemory
+public class WordAddressableMemory extends GenericMemory<BitVector> implements MainMemory
{
private final int cellWidth;
- private final long minimalAddress, maximalAddress;
private final MainMemoryDefinition definition;
- private final int pageSize = 64;
- private Set<MemoryObserver> observers = new HashSet<>();
-
- private HashMap<Long, Page> pages;
public WordAddressableMemory(MainMemoryDefinition definition)
{
- super();
+ super(definition);
this.cellWidth = definition.getCellWidth();
- this.minimalAddress = definition.getMinimalAddress();
- this.maximalAddress = definition.getMaximalAddress();
this.definition = definition;
- this.pages = new HashMap<>();
- }
-
- private void inBoundsCheck(long address)
- {
- if (address < minimalAddress || address > maximalAddress)
- throw new IndexOutOfBoundsException(String.format("Memory address out of bounds! Minimum: %d Maximum: %d Actual: %d",
- minimalAddress, maximalAddress, address));
- }
-
- private long page(long address)
- {
- return address / pageSize;
- }
-
- private int offset(long address)
- {
- return (int) (address % pageSize);
- }
-
- @Override
- public void setCell(long address, BitVector b)
- {
- inBoundsCheck(address);
- long page = page(address);
- int offset = offset(address);
- Page p = pages.get(Long.valueOf(page));
- if (p == null)
- pages.put(page, p = new Page());
- p.setCell(offset, b);
- notifyObservers(address);
}
@Override
public BitVector getCell(long address)
{
- inBoundsCheck(address);
- long page = page(address);
- int offset = offset(address);
- Page p = pages.get(Long.valueOf(page));
- if (p == null)
- return BitVector.of(Bit.ZERO, cellWidth);
- return p.getCell(offset);
+ BitVector data = super.getCell(address);
+ return data == null ? BitVector.of(Bit.ZERO, cellWidth) : data;
}
@Override
public BigInteger getCellAsBigInteger(long address)
{
- inBoundsCheck(address);
- long page = page(address);
- int offset = offset(address);
- Page p = pages.get(Long.valueOf(page));
- if (p == null)
- return BigInteger.valueOf(0L);
- return p.getCellAsBigInteger(offset);
+ BitVector data = getCell(address);
+ return data == null ? BigInteger.valueOf(0) : data.getUnsignedValue();
}
@Override
- public void setCellAsBigInteger(long address, BigInteger word)
- {
- inBoundsCheck(address);
- long page = page(address);
- int offset = offset(address);
- Page p = pages.get(Long.valueOf(page));
- if (p == null)
- pages.put(page, p = new Page());
- p.setCellAsBigInteger(offset, word);
- notifyObservers(address);
- }
-
- private class Page
+ public void setCellAsBigInteger(long address, BigInteger data)
{
- private BitVector[] memory;
-
- public Page()
- {
- memory = new BitVector[pageSize];
- }
-
- public BitVector getCell(int index)
- {
- BitVector b = memory[index];
- if (b == null)
- return BitVector.of(Bit.ZERO, cellWidth);
- return memory[index];
- }
-
- public void setCell(int index, BitVector bits)
- {
- if (bits.length() != cellWidth)
- throw new IllegalArgumentException(String.format(
- "BitVector to be saved in memory cell has unexpected width. Expected: %d Actual: %d", cellWidth, bits.length()));
- memory[index] = bits;
- }
-
- public void setCellAsBigInteger(int index, BigInteger bits)
- {
- setCell(index, BitVector.from(bits, cellWidth));
- }
-
- public BigInteger getCellAsBigInteger(int index)
- {
- try {
- return getCell(index).getUnsignedValue();
- }
- catch(NumberFormatException e)
- {
- throw new MemoryException(e);
- }
- }
-
- @Override
- public String toString()
- {
- return Arrays.deepToString(memory);
- }
+ setCell(address, BitVector.from(data, cellWidth));
}
@Override
{
return definition;
}
-
- @Override
- public void registerObserver(MemoryObserver ob)
- {
- observers.add(ob);
- }
-
- @Override
- public void deregisterObserver(MemoryObserver ob)
- {
- observers.remove(ob);
- }
-
- @Override
- public void notifyObservers(long address)
- {
- observers.forEach(ob -> ob.update(address));
- }
}
import net.mograsim.logic.core.types.BitVector;
import net.mograsim.logic.core.wires.Wire;
import net.mograsim.logic.core.wires.Wire.ReadWriteEnd;
-import net.mograsim.machine.DefaultMainMemoryDefinition;
+import net.mograsim.machine.MainMemoryDefinition;
class WordAddressableMemoryTest {
ReadWriteEnd dataI = data.createReadWriteEnd();
ReadWriteEnd addressI = address.createReadWriteEnd();
- WordAddressableMemoryComponent memory = new WordAddressableMemoryComponent(t, 4, new DefaultMainMemoryDefinition(64, 16, 4096L, Long.MAX_VALUE), data.createReadWriteEnd(),
+ @SuppressWarnings("unused")
+ WordAddressableMemoryComponent memory = new WordAddressableMemoryComponent(t, 4, MainMemoryDefinition.create(64, 16, 4096L, Long.MAX_VALUE), data.createReadWriteEnd(),
rW.createReadOnlyEnd(), address.createReadOnlyEnd());
Random r = new Random();