/*******************************************************************************
* This file is part of logisim-evolution.
*
* logisim-evolution is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* logisim-evolution is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with logisim-evolution. If not, see <http://www.gnu.org/licenses/>.
*
* Original code by Carl Burch (http://www.cburch.com), 2011.
* Subsequent modifications by :
* + Haute École Spécialisée Bernoise
* http://www.bfh.ch
* + Haute École du paysage, d'ingénierie et d'architecture de Genève
* http://hepia.hesge.ch/
* + Haute École d'Ingénierie et de Gestion du Canton de Vaud
* http://www.heig-vd.ch/
* The project is currently maintained by :
* + REDS Institute - HEIG-VD
* Yverdon-les-Bains, Switzerland
* http://reds.heig-vd.ch
*******************************************************************************/
package com.cburch.logisim.std.memory;
import java.awt.Font;
import java.util.Arrays;
import java.util.List;
import java.util.WeakHashMap;
import com.cburch.logisim.data.AbstractAttributeSet;
import com.cburch.logisim.data.Attribute;
import com.cburch.logisim.data.AttributeOption;
import com.cburch.logisim.data.Attributes;
import com.cburch.logisim.data.BitWidth;
import com.cburch.logisim.gui.hex.HexFrame;
import com.cburch.logisim.instance.StdAttr;
import com.cburch.logisim.proj.Project;
public class RamAttributes extends AbstractAttributeSet {
static HexFrame getHexFrame(MemContents value, Project proj) {
synchronized (windowRegistry) {
HexFrame ret = windowRegistry.get(value);
if (ret == null) {
ret = new HexFrame(proj, value);
windowRegistry.put(value, ret);
}
return ret;
}
}
/* here the rest is defined */
static final AttributeOption BUS_BIDIR = new AttributeOption("bidir",
Strings.getter("ramBidirDataBus"));
static final AttributeOption BUS_SEP = new AttributeOption("bibus",
Strings.getter("ramSeparateDataBus"));
static final Attribute<AttributeOption> ATTR_DBUS = Attributes.forOption(
"databus", Strings.getter("ramDataAttr"), new AttributeOption[] {
BUS_BIDIR, BUS_SEP });
static final AttributeOption BUS_WITH_BYTEENABLES = new AttributeOption(
"byteEnables", Strings.getter("ramWithByteEnables"));
static final AttributeOption BUS_WITHOUT_BYTEENABLES = new AttributeOption(
"NobyteEnables", Strings.getter("ramNoByteEnables"));
static final Attribute<AttributeOption> ATTR_ByteEnables = Attributes
.forOption("byteenables", Strings.getter("ramByteEnables"),
new AttributeOption[] { BUS_WITH_BYTEENABLES,
BUS_WITHOUT_BYTEENABLES });
private static List<Attribute<?>> ATTRIBUTES = Arrays
.asList(new Attribute<?>[] { Mem.ADDR_ATTR, Mem.DATA_ATTR,
StdAttr.TRIGGER, ATTR_DBUS, ATTR_ByteEnables,
Ram.CONTENTS_ATTR, StdAttr.LABEL, StdAttr.LABEL_FONT, StdAttr.LABEL_VISIBILITY });
private static WeakHashMap<MemContents, HexFrame> windowRegistry = new WeakHashMap<MemContents, HexFrame>();
private BitWidth addrBits = BitWidth.create(8);
private BitWidth dataBits = BitWidth.create(8);
private MemContents contents;
private String Label = "";
private AttributeOption Trigger = StdAttr.TRIG_RISING;
private AttributeOption BusStyle = BUS_BIDIR;
private Font LabelFont = StdAttr.DEFAULT_LABEL_FONT;
private Boolean LabelVisable = false;
private AttributeOption ByteEnables = BUS_WITHOUT_BYTEENABLES;
private boolean SupportsByteEnables = false;
RamAttributes() {
contents = MemContents.create(addrBits.getWidth(), dataBits.getWidth());
}
@Override
protected void copyInto(AbstractAttributeSet dest) {
RamAttributes d = (RamAttributes) dest;
d.addrBits = addrBits;
d.dataBits = dataBits;
d.Trigger = Trigger;
d.BusStyle = BusStyle;
d.LabelFont = LabelFont;
d.ByteEnables = ByteEnables;
d.contents = contents.clone();
d.SupportsByteEnables = SupportsByteEnables;
}
@Override
public List<Attribute<?>> getAttributes() {
return ATTRIBUTES;
}
@SuppressWarnings("unchecked")
@Override
public <V> V getValue(Attribute<V> attr) {
if (attr == Mem.ADDR_ATTR) {
return (V) addrBits;
}
if (attr == Mem.DATA_ATTR) {
return (V) dataBits;
}
if (attr == Ram.CONTENTS_ATTR) {
return (V) contents;
}
if (attr == StdAttr.LABEL) {
return (V) Label;
}
if (attr == StdAttr.TRIGGER) {
return (V) Trigger;
}
if (attr == ATTR_DBUS) {
return (V) BusStyle;
}
if (attr == StdAttr.LABEL_FONT) {
return (V) LabelFont;
}
if (attr == StdAttr.LABEL_VISIBILITY) {
return (V) LabelVisable;
}
if (attr == ATTR_ByteEnables) {
return (V) ByteEnables;
}
return null;
}
@Override
public boolean isReadOnly(Attribute<?> attr) {
if (attr.equals(ATTR_ByteEnables)) {
return !SupportsByteEnables;
}
return false;
}
@Override
public boolean isToSave(Attribute<?> attr) {
return !attr.equals(Ram.CONTENTS_ATTR);
}
@Override
public void setReadOnly(Attribute<?> attr, boolean value) {
if (attr.equals(ATTR_ByteEnables)) {
SupportsByteEnables = !value;
} else {
throw new UnsupportedOperationException();
}
}
@Override
public <V> void setValue(Attribute<V> attr, V value) {
if (attr == Mem.ADDR_ATTR) {
BitWidth newAddr = (BitWidth) value;
if (addrBits == newAddr) {
return;
}
addrBits = newAddr;
contents.setDimensions(addrBits.getWidth(), dataBits.getWidth());
fireAttributeValueChanged(attr, value,null);
} else if (attr == Mem.DATA_ATTR) {
BitWidth newData = (BitWidth) value;
if (dataBits == newData) {
return;
}
dataBits = newData;
contents.setDimensions(addrBits.getWidth(), dataBits.getWidth());
fireAttributeValueChanged(attr, value,null);
} else if (attr == Ram.CONTENTS_ATTR) {
MemContents newContents = (MemContents) value;
if (contents.equals(newContents)) {
return;
}
if ((newContents.getLogLength() != addrBits.getWidth())
|| (newContents.getValueWidth() != dataBits.getWidth())) {
newContents.setDimensions(addrBits.getWidth(),
dataBits.getWidth());
}
contents = newContents;
fireAttributeValueChanged(attr, value,null);
} else if (attr == StdAttr.LABEL) {
String NewLabel = (String) value;
if (Label.equals(NewLabel)) {
return;
}
@SuppressWarnings("unchecked")
V Oldlabel = (V) Label;
Label = NewLabel;
fireAttributeValueChanged(attr, value,Oldlabel);
} else if (attr == StdAttr.TRIGGER) {
AttributeOption newTrigger = (AttributeOption) value;
if (Trigger.equals(newTrigger)) {
return;
}
Trigger = newTrigger;
fireAttributeValueChanged(attr, value,null);
} else if (attr == ATTR_DBUS) {
AttributeOption NewStyle = (AttributeOption) value;
if (BusStyle.equals(NewStyle)) {
return;
}
BusStyle = NewStyle;
fireAttributeValueChanged(attr, value,null);
} else if (attr == StdAttr.LABEL_FONT) {
Font NewFont = (Font) value;
if (LabelFont.equals(NewFont)) {
return;
}
LabelFont = NewFont;
fireAttributeValueChanged(attr, value,null);
} else if (attr == StdAttr.LABEL_VISIBILITY) {
Boolean newVis = (Boolean) value;
if (LabelVisable.equals(newVis))
return;
LabelVisable = newVis;
fireAttributeValueChanged(attr, value,null);
} else if (attr == ATTR_ByteEnables) {
AttributeOption NewBE = (AttributeOption) value;
if (ByteEnables.equals(NewBE)) {
return;
}
if (dataBits.getWidth() < 9) {
NewBE = BUS_WITHOUT_BYTEENABLES;
}
ByteEnables = NewBE;
fireAttributeValueChanged(attr, value,null);
}
}
}