1 /*
2  * Copyright (c) 2017 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.flipflops;
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 
14 import static de.neemann.digital.core.ObservableValues.ovs;
15 
16 /**
17  * Base class of all flip-flops storing a single bit
18  */
19 abstract class FlipflopBit extends Node implements Element {
20 
21     private final boolean isProbe;
22     private final String label;
23     private ObservableValue q;
24     private ObservableValue qn;
25     private boolean out;
26 
27     /**
28      * Creates a new instance
29      *
30      * @param attributes  the attributes
31      * @param description the description of this flip flop
32      */
FlipflopBit(ElementAttributes attributes, ElementTypeDescription description)33     FlipflopBit(ElementAttributes attributes, ElementTypeDescription description) {
34         super(true);
35         this.q = new ObservableValue("Q", 1).setPinDescription(description);
36         this.qn = new ObservableValue("~Q", 1).setPinDescription(description);
37         isProbe = attributes.get(Keys.VALUE_IS_PROBE);
38         label = attributes.getLabel();
39 
40         long def = attributes.get(Keys.DEFAULT);
41         out = def > 0;
42         q.setBool(out);
43         qn.setBool(!out);
44     }
45 
46     /**
47      * Creates a new instance
48      *
49      * @param label the label
50      * @param q     the output
51      * @param qn    the inverted output
52      */
FlipflopBit(String label, ObservableValue q, ObservableValue qn)53     FlipflopBit(String label, ObservableValue q, ObservableValue qn) {
54         super(true);
55         this.q = q;
56         this.qn = qn;
57         isProbe = false;
58         this.label = label;
59         q.setBool(false);
60         qn.setBool(true);
61     }
62 
63     @Override
writeOutputs()64     public void writeOutputs() throws NodeException {
65         q.setBool(out);
66         qn.setBool(!out);
67     }
68 
69     @Override
getOutputs()70     public ObservableValues getOutputs() {
71         return ovs(q, qn);
72     }
73 
74     /**
75      * @return the label
76      */
getLabel()77     public String getLabel() {
78         return label;
79     }
80 
81     @Override
registerNodes(Model model)82     public void registerNodes(Model model) {
83         super.registerNodes(model);
84         if (isProbe)
85             model.addSignal(new Signal(label, q, (v, z) -> {
86                 out = v != 0;
87                 q.setBool(out);
88                 qn.setBool(!out);
89             }).setTestOutput());
90     }
91 
setOut(boolean out)92     void setOut(boolean out) {
93         this.out = out;
94     }
95 
isOut()96     boolean isOut() {
97         return out;
98     }
99 
100 }
101