1 /* 2 * Copyright (c) 2016 Helmut Neemann 3 * Use of this source code is governed by the GPL v3 license 4 * that can be found in the LICENSE file. 5 */ 6 package de.neemann.digital.core.memory; 7 8 import de.neemann.digital.core.*; 9 import de.neemann.digital.core.element.Element; 10 import de.neemann.digital.core.element.ElementAttributes; 11 import de.neemann.digital.core.element.ElementTypeDescription; 12 import de.neemann.digital.core.element.Keys; 13 import de.neemann.digital.core.stats.Countable; 14 15 import static de.neemann.digital.core.element.PinInfo.input; 16 17 /** 18 * A simple register. 19 */ 20 public class Register extends Node implements Element, Countable, ProgramCounter { 21 22 /** 23 * The registers {@link ElementTypeDescription} 24 */ 25 public static final ElementTypeDescription DESCRIPTION 26 = new ElementTypeDescription(Register.class, input("D"), input("C").setClock(), input("en")) 27 .addAttribute(Keys.ROTATE) 28 .addAttribute(Keys.BITS) 29 .addAttribute(Keys.LABEL) 30 .addAttribute(Keys.INVERTER_CONFIG) 31 .addAttribute(Keys.IS_PROGRAM_COUNTER) 32 .addAttribute(Keys.VALUE_IS_PROBE) 33 .supportsHDL(); 34 35 private final int bits; 36 private final boolean isProbe; 37 private final String label; 38 private final boolean isProgramCounter; 39 private final ObservableValue q; 40 private ObservableValue dVal; 41 private ObservableValue clockVal; 42 private ObservableValue enableVal; 43 private boolean lastClock; 44 private long value; 45 private boolean enable; 46 47 /** 48 * Creates a new instance 49 * 50 * @param attributes the elements attributes 51 */ Register(ElementAttributes attributes)52 public Register(ElementAttributes attributes) { 53 super(true); 54 bits = attributes.getBits(); 55 this.q = new ObservableValue("Q", bits).setPinDescription(DESCRIPTION); 56 isProbe = attributes.get(Keys.VALUE_IS_PROBE); 57 label = attributes.get(Keys.LABEL); 58 isProgramCounter = attributes.get(Keys.IS_PROGRAM_COUNTER); 59 } 60 61 @Override readInputs()62 public void readInputs() throws NodeException { 63 enable = enableVal.getBool(); 64 boolean clock = clockVal.getBool(); 65 if (clock && !lastClock && enable) 66 value = dVal.getValue(); 67 lastClock = clock; 68 } 69 70 @Override writeOutputs()71 public void writeOutputs() throws NodeException { 72 q.setValue(value); 73 } 74 75 @Override setInputs(ObservableValues inputs)76 public void setInputs(ObservableValues inputs) throws BitsException { 77 dVal = inputs.get(0).checkBits(bits, this); 78 clockVal = inputs.get(1).addObserverToValue(this).checkBits(1, this); 79 enableVal = inputs.get(2).checkBits(1, this); 80 } 81 82 @Override getOutputs()83 public ObservableValues getOutputs() { 84 return q.asList(); 85 } 86 87 @Override registerNodes(Model model)88 public void registerNodes(Model model) { 89 super.registerNodes(model); 90 if (isProbe) 91 model.addSignal(new Signal(label, q, (value, highZ) -> setValue(value)).setTestOutput()); 92 } 93 94 @Override isProgramCounter()95 public boolean isProgramCounter() { 96 return isProgramCounter; 97 } 98 99 @Override getProgramCounter()100 public long getProgramCounter() { 101 return value; 102 } 103 104 @Override getDataBits()105 public int getDataBits() { 106 return bits; 107 } 108 109 /** 110 * Returns the stored value. 111 * Used to improve custom testing capabilities. 112 * 113 * @return the stared value 114 */ getValue()115 public long getValue() { 116 return value; 117 } 118 119 /** 120 * Sets the stored value. 121 * Used to improve custom testing capabilities. 122 * 123 * @param v the value 124 */ setValue(long v)125 public void setValue(long v) { 126 value = v; 127 q.setValue(value); 128 } 129 130 /** 131 * Returns the used label. 132 * Used to improve custom testing capabilities. 133 * 134 * @return the label 135 */ getLabel()136 public String getLabel() { 137 return label; 138 } 139 140 /** 141 * Returns the enable input value. 142 * Used to improve custom testing capabilities. 143 * 144 * @return true if enable was set at the last clock change. 145 */ isEnabled()146 public boolean isEnabled() { 147 return enable; 148 } 149 } 150