Source code: engine/ContBitSelect.java
1 /* **********************************
2 File:ContBitSelect.java
3 Author: Alec(panovici@elcom.pub.ro)
4 Created on 12.02.1999 00:02:06
5 Comments: Part of the vIDE Project
6 Copyright 1999 the vIDE Team.
7 ***********************************/
8
9 package engine;
10
11 /**
12 * This is a BitSelect that continuously assings to its target.
13 * Unless BitSelect, it maintains the bits
14 * in an internal BitVector ( data ),
15 * and calls Wire's compute(), in order for it to
16 * determine its bits considering all its assignemens;
17 */
18 class ContBitSelect extends BitSelect implements Executable{
19
20 BitVector data;
21 byte[] strengths;
22
23 /**
24 * The timestamp of the last programmed update
25 */
26 long updateTime;
27 boolean active;
28
29 /**
30 * The computed data to be assigned to the target BitVector
31 */
32 BitVector newB;
33 /**
34 *The computed strengths to be assigned to target
35 */
36 byte []newStrengths;
37
38 ContBitSelect(NameSpace ns, BitVector b,
39 GenericSelectorDescription target,
40 int start, int end, byte strength)
41 {
42 super(ns, b, target, start, end);
43 data = new BitVector(start, end);
44 strengths = new byte [length];
45 for (int i = 0; i < length; i++)
46 strengths[i] = strength;
47 this.b = b;
48 b.addAssignement(this);
49 try {
50 data.attrib(start, end, b, start, end);
51 } catch (InterpretTimeException intex) {
52 xConsole.debug("InterpretTimeException into ContBitSelect<init>");
53 /*we do nothing here, because the same exception will
54 be raised later and handled accordingly*/
55 }
56 updateTime = -1;
57 active = false;
58 }
59
60 /**
61 * The implicit strength (strong1, strong0) is used here.
62 */
63 ContBitSelect(NameSpace ns, BitVector b,
64 GenericSelectorDescription target,
65 int start, int end)
66 {
67 this (ns, b, target, start, end, Strength.defaultStrength);
68 }
69
70 ContBitSelect(NameSpace ns, BitVector b,
71 GenericSelectorDescription target,
72 byte strength)
73 {
74 this (ns, b, target, b.msb, b.lsb, strength);
75 }
76
77 /**
78 * Called by @see assign with the appropriate parameters
79 */
80 synchronized void set(BitVector x, int start, int end)
81 throws InterpretTimeException
82 //TODO: this recomputation can be optimised to take place only
83 //on the start:end range
84 {
85 xConsole.debug("ContBitSelect.set(" + x + ", " +
86 start + ", " + end + "), data is:" + data +
87 " data.msb:" + data.msb + " data.lsb:" + data.lsb + " inc: " +
88 data.increment);
89 Object [] dataRes;
90 data.attrib(this.start, this.end, x, start, end);
91 updateTime = Time.oClock(); //force compute to take this chunk
92 //into account
93 dataRes = b.compute();
94 newB = (BitVector)dataRes[0];
95 if(dataRes.length > 1) { //does the target implements strength-keeping ?
96 newStrengths = (byte[])dataRes[1];
97 for (int i = 0; i < newStrengths.length; i++)
98 xConsole.debug("strength[" + i + "] = " +
99 Strength.strengthToString(newStrengths[i],
100 newB.getb(i)));
101 }
102 int delay;
103
104 try{
105 Wire w = (Wire) b;
106 delay = w.computeTransitionDelayFor(newB);
107 xConsole.debug("delay is: " + delay);
108 }catch(ClassCastException ex){
109 delay = 0;
110 }
111 if (!active) {
112 updateTime = Time.oClock()+delay;
113 active = true;
114 Time.addFinisher(delay, new GenericInstruction(this));
115 }
116 }
117
118 /**
119 * First sets the strengths, and then calls the old assign.
120 * This will cause the assigned wire to compute its value
121 * considering the new strengths
122 */
123 public void setStrengths(byte[] s, int startIndex)
124 {
125 xConsole.debug("ContBitSelect.setStrengths");
126 for(int i = 0, n = strengths.length; i < n; i++)
127 strengths[i] = s[startIndex++];
128 }
129
130 public synchronized void execute()
131 throws InterpretTimeException, SimulationStoppedException
132 {
133 if((updateTime == Time.oClock()) && active){ //updateTime > oClock means
134 //that another update has
135 //superseeded this one, so skip it
136 //active is made false after the first execution,
137 //to avoid multiple useless updates (I guess this little optimisation
138 //does not introduce bad behaviour).
139 if (target != null)
140 xConsole.trace(((GenericSelectorDescription)target).fqn +
141 " <<< " + data);
142 synchronized (b) {
143 try{
144 Wire w = (Wire)b;
145 w.attrib(newB, start, end, newStrengths);
146 }catch(ClassCastException cex){
147 //seems like data is a mere reg
148 b.attrib(newB);
149 }
150 }
151 active = false;
152 }
153 }
154
155 /**
156 * @return the strength for the specified index
157 * @param i the index in the ramge start..end
158 */
159 public byte strength(int i){
160 return start > end ? strengths[i-end] : strengths[end-i];
161 }
162
163 /**
164 * @see WireSelection.detach
165 */
166 void release() {
167 b.removeAssignement(this);
168 }
169
170 /**
171 * @see WireSelection.reatach
172 */
173 void reatach() {
174 b.addAssignement(this);
175 }
176
177
178 /**
179 * @see WireSelection.reatach
180 */
181 void breakSelection(WireSelection bits[], int startIndex) {
182 int i = start, inc = start >= end ? -1 : 1;
183 while(true) {
184 bits[startIndex++] = new ContBitSelect(ns, b, target, i, i, strengths[0]);
185 if (i == end) break;
186 i += inc;
187 }
188 }
189 }