You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I would like some help to understand how we can specify the list of input signals that shall take "INVERTER_CONFIG" option into consideration and actually have those values inverted.
I tried to understand with all those already coded components available that implement control signal logic inversion, but I don't get it, it seem implicit ?
For now, I wish I could use something like applyInverterConfig(this); to specify those control signals that need to use this inversion when used, but this method doesn't exist.
As a consequence, I don't understand how it is done in the code of RAMSinglePortSel.java.
Please help needed !
Here is the code of my new Dual Port SRAM component so far :
/*
* Copyright (c) 2017 Helmut Neemann
* Use of this source code is governed by the GPL v3 license
* that can be found in the LICENSE file.
*/
package de.neemann.digital.plugin;
import de.neemann.digital.core.*;
import de.neemann.digital.core.element.*;
import de.neemann.digital.core.memory.DataField;
import de.neemann.digital.core.memory.RAMInterface;
import static de.neemann.digital.core.element.PinInfo.input;
import static de.neemann.digital.core.element.PinInfo.output;
/**
* Dual-Port Asynchronous SRAM Component for Digital
*/
public class DualPortSRAM extends Node implements Element, RAMInterface {
private static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(DualPortSRAM.class,
input("CS_A", "Chip Select A"),
input("OE_A", "Output Enable A"),
input("R/W_A", "Read/Write A"),
input("ADDR_A", "Address A"),
input("I/O_A", "Data A"),
output("BUSY_A"),
input("CS_B", "Chip Select B"),
input("OE_B", "Output Enable B"),
input("R/W_B", "Read/Write B"),
input("ADDR_B", "Address B"),
input("I/O_B", "Data B"),
output("BUSY_B"))
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.BITS)
.addAttribute(Keys.ADDR_BITS)
.addAttribute(Keys.LABEL)
.addAttribute(Keys.IS_PROGRAM_MEMORY)
.addAttribute(Keys.INVERTER_CONFIG);
private final DataField memory;
private final ObservableValue busyA, busyB;
private final int addrBits, dataBits, size;
private final boolean isProgramMemory;
private final String label;
// Signaux de contrôle et d'adresse (non inversés pour adresse)
private ObservableValue csA, oeA, rwA, addrA;
private ObservableValue csB, oeB, rwB, addrB;
// Bus de données créés dans le constructeur (avec tri-state et bidirectionnalité)
private final ObservableValue ioA;
private final ObservableValue ioB;
public DualPortSRAM(ElementAttributes attr) {
super(true);
dataBits = attr.get(Keys.BITS);
addrBits = attr.get(Keys.ADDR_BITS);
size = 1 << addrBits;
memory = new DataField(size);
busyA = new ObservableValue("BUSY_A", 1);
busyB = new ObservableValue("BUSY_B", 1);
isProgramMemory = attr.isProgramMemory();
label = attr.getLabel();
// Instanciation des bus de données en tri-state et bidirectionnels
ioA = new ObservableValue("I/O_A", dataBits)
.setToHighZ()
.setBidirectional();
ioB = new ObservableValue("I/O_B", dataBits)
.setToHighZ()
.setBidirectional();
}
@Override
public void setInputs(ObservableValues inputs) throws NodeException {
// Pour les signaux de contrôle, on vérifie la largeur et ajoute l'observateur, puis on applique la normalisation
csA = inputs.get(0).checkBits(1, this).addObserverToValue(this).applyInverterConfig(this);
oeA = inputs.get(1).checkBits(1, this).addObserverToValue(this).applyInverterConfig(this);
rwA = inputs.get(2).checkBits(1, this).addObserverToValue(this).applyInverterConfig(this);
// Pour l'adresse, on vérifie simplement la largeur et ajoute l'observateur (sans inversion)
addrA = inputs.get(3).checkBits(addrBits, this).addObserverToValue(this);
// Les bus de données ioA et ioB ont déjà été instanciés dans le constructeur
csB = inputs.get(5).checkBits(1, this).addObserverToValue(this).applyInverterConfig(this);
oeB = inputs.get(6).checkBits(1, this).addObserverToValue(this).applyInverterConfig(this);
rwB = inputs.get(7).checkBits(1, this).addObserverToValue(this).applyInverterConfig(this);
addrB = inputs.get(8).checkBits(addrBits, this).addObserverToValue(this);
}
@Override
public void readInputs() {
// Ici, getBool() retourne la valeur normalisée grâce à applyInverterConfig().
// Une écriture est indiquée par cs actif et rw actif (pour écriture normalisée).
boolean writeA = csA.getBool() && rwA.getBool();
boolean writeB = csB.getBool() && rwB.getBool();
// Conflit si les deux ports écrivent sur la même adresse
boolean conflict = writeA && writeB && addrA.getValue() == addrB.getValue();
busyA.setValue(conflict ? 1 : 0);
busyB.setValue(conflict ? 1 : 0);
if (!conflict) {
if (writeA) {
memory.setData((int) addrA.getValue(), ioA.getValue());
}
if (writeB) {
memory.setData((int) addrB.getValue(), ioB.getValue());
}
}
}
@Override
public void writeOutputs() {
// Pour la lecture, on considère que l'inversion normalise les signaux : rw inactif signifie lecture.
ioA.setValue((csA.getBool() && oeA.getBool() && !rwA.getBool())
? memory.getDataWord((int) addrA.getValue())
: ioA.getHighZ());
ioB.setValue((csB.getBool() && oeB.getBool() && !rwB.getBool())
? memory.getDataWord((int) addrB.getValue())
: ioB.getHighZ());
}
@Override
public ObservableValues getOutputs() {
return new ObservableValues(busyA, busyB, ioA, ioB);
}
@Override
public DataField getMemory() {
return memory;
}
@Override
public int getSize() {
return size;
}
@Override
public int getDataBits() {
return dataBits;
}
@Override
public int getAddrBits() {
return addrBits;
}
@Override
public boolean isProgramMemory() {
return isProgramMemory;
}
@Override
public void setProgramMemory(DataField dataField) {
memory.setDataFrom(dataField);
}
@Override
public String getLabel() {
return label;
}
}
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello.
I would like some help to understand how we can specify the list of input signals that shall take "INVERTER_CONFIG" option into consideration and actually have those values inverted.
I tried to understand with all those already coded components available that implement control signal logic inversion, but I don't get it, it seem implicit ?
For now, I wish I could use something like
applyInverterConfig(this);
to specify those control signals that need to use this inversion when used, but this method doesn't exist.As a consequence, I don't understand how it is done in the code of
RAMSinglePortSel.java
.Please help needed !
Here is the code of my new Dual Port SRAM component so far :
Beta Was this translation helpful? Give feedback.
All reactions