3. Functional Abstraction
반복되는 로직을 function으로 정의할 수 있다.
예)
def clb(a: UInt, b: UInt, c: UInt, d: UInt): UInt = (a & b) | (~c & d)
위 function 사용. UInt argument 네 개를 받고 return type은
UInt 이다.
예)
val out = clb(a, b, c, d)
4. Bundles and Vecs
Aggregates of other types. Bundle은 구조체라고 생각하면 되고, Vec은 배열로 생각하면 된다.
Class MyFloat extends Bundle {
val sign = Bool()
val exponent = UInt(width = 8)
val significant = UInt(width = 23)
}
val x = new MyFloat()
val xs = x.sign
width는 type의 bit수를 나타낸다.
Vecs는 indexable vector를 만든다.
// Vector of 5 23-bit signed integers.
val myVec = Vec.fill(5){ SInt(width = 23) }
// Connect to one element of vector
val reg3 = myVec(3)
primitive class들(SInt, UInt, Bool)이나 aggregate class들(Bundles, vecs)은 모두 Data라는 superclass를 상속받는다. hardware design에서 Data를 상속받는 object는 모두 bit vector로 나타낼 수 있다.
Bundle과 Vec은 nested 구조를 가질 수 있다.
class BigBundle extends Bundle {
// Vector of 5 23-bit signed integers.
val myVec = Vec.fill(5) { SInt(width = 23) }
val flag = Bool()
// Previously defined bundle.
val f = new MyFloat()
}
5. Ports
Ports는 hardware components에 대한 인터페이스이다.
Construction time에 object에 direction(input or output)을 추가하는 것을 제공한다. 다음은 port declaration의 예이다.
class Decouple extends Bundle {
val ready = Bool(OUTPUT)
val data = UInt(INPUT, 32)
val valid = Bool(INPUT)
}
Instantation time에도 object의 direction이 정해질 수 있다.
class ScalaIO extends Bundle {
val in = new MyFloat().asInput
val out = new MyFloat().asOutput
}
asInput 과 asOutput method는 direction을 가지게 하는 method이다.