/*******************************************************************************
* 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.util.Arrays;
import com.cburch.logisim.data.BitWidth;
import com.cburch.logisim.data.Value;
import com.cburch.logisim.instance.InstanceData;
class ShiftRegisterData extends ClockState implements InstanceData {
private BitWidth width;
private Value[] vs;
private int vsPos;
public ShiftRegisterData(BitWidth width, int len) {
this.width = width;
this.vs = new Value[len];
Arrays.fill(this.vs, Value.createKnown(width, 0));
this.vsPos = 0;
}
public void clear() {
Arrays.fill(vs, Value.createKnown(width, 0));
vsPos = 0;
}
@Override
public ShiftRegisterData clone() {
ShiftRegisterData ret = (ShiftRegisterData) super.clone();
ret.vs = this.vs.clone();
return ret;
}
public Value get(int index) {
int i = vsPos + index;
Value[] v = vs;
if (i >= v.length)
i -= v.length;
return v[i];
}
public int getLength() {
return vs.length;
}
public void push(Value v) {
int pos = vsPos;
vs[pos] = v;
vsPos = pos >= vs.length - 1 ? 0 : pos + 1;
}
public void set(int index, Value val) {
int i = vsPos + index;
Value[] v = vs;
if (i >= v.length)
i -= v.length;
v[i] = val;
}
public void setDimensions(BitWidth newWidth, int newLength) {
Value[] v = vs;
BitWidth oldWidth = width;
int oldW = oldWidth.getWidth();
int newW = newWidth.getWidth();
if (v.length != newLength) {
Value[] newV = new Value[newLength];
int j = vsPos;
int copy = Math.min(newLength, v.length);
for (int i = 0; i < copy; i++) {
newV[i] = v[j];
j++;
if (j == v.length)
j = 0;
}
Arrays.fill(newV, copy, newLength, Value.createKnown(newWidth, 0));
v = newV;
vsPos = 0;
vs = newV;
}
if (oldW != newW) {
for (int i = 0; i < v.length; i++) {
Value vi = v[i];
if (vi.getWidth() != newW) {
v[i] = vi.extendWidth(newW, Value.FALSE);
}
}
width = newWidth;
}
}
}