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.wiring;
7 
8 import de.neemann.digital.core.BitsException;
9 import de.neemann.digital.core.NodeException;
10 import de.neemann.digital.core.ObservableValue;
11 import de.neemann.digital.core.ObservableValues;
12 import de.neemann.digital.core.basic.FanIn;
13 import de.neemann.digital.core.element.*;
14 import de.neemann.digital.lang.Lang;
15 
16 import static de.neemann.digital.core.element.PinInfo.input;
17 
18 /**
19  * The Multiplexer
20  */
21 public class Multiplexer extends FanIn {
22 
23     private final int selectorBits;
24     private ObservableValue selector;
25     private long value;
26 
27     /**
28      * The Multiplexer description
29      */
30     public static final ElementTypeDescription DESCRIPTION = new ElementTypeDescription(Multiplexer.class) {
31         @Override
32         public PinDescriptions getInputDescription(ElementAttributes elementAttributes) {
33             int size = 1 << elementAttributes.get(Keys.SELECTOR_BITS);
34             PinDescription[] names = new PinDescription[size + 1];
35             names[0] = input("sel", Lang.get("elem_Multiplexer_pin_sel"));
36             for (int i = 0; i < size; i++)
37                 names[i + 1] = input("in_" + i, Lang.get("elem_Multiplexer_input", i));
38             return new PinDescriptions(names);
39         }
40     }
41             .addAttribute(Keys.ROTATE)
42             .addAttribute(Keys.BITS)
43             .addAttribute(Keys.SELECTOR_BITS)
44             .addAttribute(Keys.FLIP_SEL_POSITON)
45             .supportsHDL();
46 
47     /**
48      * Creates a new instance
49      *
50      * @param attributes the attributes
51      */
Multiplexer(ElementAttributes attributes)52     public Multiplexer(ElementAttributes attributes) {
53         super(attributes.get(Keys.BITS));
54         this.selectorBits = attributes.get(Keys.SELECTOR_BITS);
55         getOutput().setDescription(Lang.get("elem_Multiplexer_output"));
56     }
57 
58     @Override
readInputs()59     public void readInputs() throws NodeException {
60         int n = (int) selector.getValue();
61         value = getInputs().get(n).getValue();
62     }
63 
64     @Override
writeOutputs()65     public void writeOutputs() throws NodeException {
66         getOutput().setValue(value);
67     }
68 
69     @Override
setInputs(ObservableValues inputs)70     public void setInputs(ObservableValues inputs) throws NodeException {
71         selector = inputs.get(0).addObserverToValue(this).checkBits(selectorBits, this);
72         ObservableValues in = new ObservableValues(inputs, 1, inputs.size());
73         super.setInputs(in);
74 
75         if (in.size() != (1 << selectorBits))
76             throw new BitsException(Lang.get("err_selectorInputCountMismatch"), this, -1, selector);
77     }
78 
79     @Override
getAddrBits()80     public int getAddrBits() {
81         return selectorBits;
82     }
83 }
84