Restructured register system
[Mograsim.git] / plugins / net.mograsim.machine / src / net / mograsim / machine / registers / HighLevelStateBasedRegister.java
1 package net.mograsim.machine.registers;
2
3 import java.util.Arrays;
4 import java.util.HashMap;
5 import java.util.Map;
6 import java.util.function.Consumer;
7
8 import net.mograsim.logic.core.types.BitVector;
9 import net.mograsim.logic.model.model.components.ModelComponent;
10
11 public class HighLevelStateBasedRegister extends SimpleRegister implements ModelComponentBasedRegister
12 {
13         private final String[] hlsIDsToConcat;
14         private final int[] hlsWidthes;
15
16         private final Map<Consumer<BitVector>, Consumer<Object>> modelListenersPerRegisterListener;
17
18         public HighLevelStateBasedRegister(String id, String hlsID, int logicWidth)
19         {
20                 this(id, new int[] { logicWidth }, hlsID);
21         }
22
23         public HighLevelStateBasedRegister(String id, int[] hlsWidthes, String... hlsIDsToConcat)
24         {
25                 super(id, Arrays.stream(hlsWidthes).sum());
26                 if (hlsIDsToConcat.length != hlsWidthes.length)
27                         throw new IllegalArgumentException();
28                 this.hlsIDsToConcat = Arrays.copyOf(hlsIDsToConcat, hlsIDsToConcat.length);
29                 this.hlsWidthes = Arrays.copyOf(hlsWidthes, hlsIDsToConcat.length);
30
31                 this.modelListenersPerRegisterListener = new HashMap<>();
32         }
33
34         @Override
35         public BitVector read(ModelComponent component)
36         {
37                 BitVector result = BitVector.of();
38                 for (int i = 0; i < hlsIDsToConcat.length; i++)
39                 {
40                         BitVector hls = (BitVector) component.getHighLevelState(hlsIDsToConcat[i]);
41                         if (hls.length() != hlsWidthes[i])
42                                 throw new IllegalArgumentException();
43                         result = result.concat(hls);
44                 }
45                 return result;
46         }
47
48         @Override
49         public void write(ModelComponent component, BitVector value)
50         {
51                 if (value.length() != getWidth())
52                         throw new IllegalArgumentException();
53                 for (int i = 0, off = 0; i < hlsIDsToConcat.length; i++)
54                 {
55                         int oldOff = off;
56                         off += hlsWidthes[i];
57                         component.setHighLevelState(hlsIDsToConcat[i], value.subVector(oldOff, off));
58                 }
59         }
60
61         @Override
62         public void addListener(ModelComponent component, Consumer<BitVector> listener)
63         {
64                 if (modelListenersPerRegisterListener.containsKey(listener))
65                         return;
66
67                 Consumer<Object> modelListener = v -> listener.accept(read(component));
68                 for (String hlsID : hlsIDsToConcat)
69                         component.addHighLevelStateListener(hlsID, modelListener);
70         }
71
72         @Override
73         public void removeListener(ModelComponent component, Consumer<BitVector> listener)
74         {
75                 Consumer<Object> modelListener = modelListenersPerRegisterListener.get(listener);
76                 if (modelListener == null)
77                         return;
78
79                 for (String hlsID : hlsIDsToConcat)
80                         component.removeHighLevelStateListener(hlsID, modelListener);
81         }
82 }