-
Notifications
You must be signed in to change notification settings - Fork 7
/
HardMap.scala
63 lines (53 loc) · 2.02 KB
/
HardMap.scala
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
package spinal.core
import spinal.idslplugin.Location
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
class HardMap extends MultiData {
val storage = mutable.LinkedHashMap[NamedType[Data], Data]()
var elementsCache : ArrayBuffer[(String, Data)] = null
def keyToName(key : Any) = key match {
case n: Nameable if n.isNamed => n.getName()
}
def update[T <: Data](key : NamedType[T], value : T): Unit = {
assert(elementsCache == null)
assert(!storage.contains(key.asInstanceOf[NamedType[Data]]))
storage(key.asInstanceOf[NamedType[Data]]) = value
if(OwnableRef.proposal(value, this)) value.setPartialName(keyToName(key), Nameable.DATAMODEL_WEAK)
}
def add[T <: Data](key: NamedType[T]) : Unit = {
this(key) = key()
}
def apply[T <: Data](key: NamedType[T]): T = {
storage(key.asInstanceOf[NamedType[Data]]).asInstanceOf[T]
}
override def elements: ArrayBuffer[(String, Data)] = {
if(elementsCache == null) {
elementsCache = ArrayBuffer[(String, Data)]()
for ((k, d) <- storage) {
val name = keyToName(k)
elementsCache += name -> d
}
}
elementsCache
}
def hardMapAssign(that: HardMap)(f: (Data, Data) => Unit): Unit = {
for ((name, element) <- elements) {
val other = that.find(name)
if (other == null) {
LocatedPendingError(s"Bundle assignment is not complete. $this need '$name' but $that doesn't provide it.")
}
else {
f(element, other)
}
}
}
protected override def assignFromImpl(that: AnyRef, target: AnyRef, kind: AnyRef)(implicit loc: Location): Unit = {
that match {
case that: HardMap =>
if (!this.getClass.isAssignableFrom(that.getClass)) SpinalError("HardMap must have the same final class to" +
" be assigned. Either use assignByName or assignSomeByName at \n" + ScalaLocated.long)
hardMapAssign(that)((to, from) => to.compositAssignFrom(from, to, kind))
case _ => throw new Exception("Undefined assignment")
}
}
}