Chisel新手教程之Scala语言(1)
Value & variable
Value是immutable的,当它被分配一个数据后,无法进行重新分配。用 val 表示。
Variable是mutable的,可以重复赋值。用 var 表示。示例如下:
val a = 2 // value
var i = 2 // variable
Type
所有的Scala数据都有一个类型(type),所有的Scala类型都定义为类(class)。
对于语句 val a = 2 来说,a 会被推断为整数类型 Int 。可以通过显式定义的方式来指明 a 的类型,写法是
val a: Int = 2
Tuple
Tuple用来表示一组数据的集合。例如下面的(key, value)组合,其中 _1 表示该tuple的第一个数据, _2 表示该tuple的第二个数据,以此类推。
val myTuple = ("Age", 39)
val myKey = myTuple._1 // "Age"
val myValue = myTuple._2 // 39
Tuple还可以用操作符 -> 来表示,例如上例中 myTuple 可以写成
val myTuple = "Age" -> 39
If…Else
If…Else expression block的返回值为 if 或者 else 条件满足时对应的 expression block 的返回值。例如下面代码中 x 的值为 a 和 b 的较大值。
val x = if (a > b) a else b
下式的返回值为对应条件满足的子expression block的返回值。
if (condition0) {
expression_block_0
} else if (condition1) {
expression_block_1
} else {
expression_block_2
}
Match expression
Match expression会对每个match项进行匹配,执行第一个匹配项对应的expression block。对于 default 项,可以用 _ 来表示。如下例:
val rank = score match {
case 5 => "Excellent"
case 4 => "Great"
case _ => "Good"
}
Loops
最基本的 loop 是 for 循环,下面的代码中第一行会打印 0 到 5,第二行会打印 0 到 4。
for (i <- 0 to 5) { println(s"$i") }
for (i <- 0 until 5) { println(s"$i") }
如果想让 for 表达式返回一个集合,可以用 yield 关键词
for (i <- 0 until 5) yield { s"Index $i" }
添加 if 表达式可以实现过滤功能,如下例中只对偶数的 i 进行操作。
for (i <- 0 until 64 if i % 2 == 0) { expression_block }
Chisel新手教程之Scala语言(2)
Function基本介绍
Function可以被看作一个带parameter(参数)输入的expression block(记得上一节介绍的expression block吧)。
例如,你可以定义一个名为double的函数,把输入的整形参数乘以2作为返回值。如下:
Example 1.1
def double(x: Int): Int = 2 * x
上式中 x: Int表示输入parameter是一个Int类型,之后的第二个 : Int指出函数返回值也是Int类型。等号右边是一个expression,其返回值是输入参数乘以2。
上面的代码可以简化成不包含返回类型,因为可以自动推导出返回类型是Int。如下:
def double(x: Int) = 2 * x
函数的等号右边可以是一个包含多行的expression block。例如下面代码,其返回值是 2 * y
def f(x: Int): Int = {
val y = x + 5
2 * y
}
函数可以不包含参数,或者包含多个参数,如下:
Example 1.2
def myNum = 4
def adder(x: Int, y: Int): Int = { x + y }
Higher-order function
Higher-order function指的是一个function可以做为另一个function的输入参数(parameter),或者返回值。Higher-order function是functional programming的一个重要概念,也是初学Chisel需要重点掌握的概念。
直观的想,可以和C语言对比。C函数的输入参数只能是变量,不能是函数名。但Scala则可以输入函数作为参数。
举一个简单的例子,假设我们为一个数组设计一个名为reduce的方法(method),该方法可以将该数组中的所有成员通过某种运算返回一个数作为结果。例如把所有成员加起来,或者乘起来。如下面的代码,MyArray是一个数组类,只包含两个数组成员a和b(通过参数实例化),并定义了reduce方法,该方法接受f函数(方法)作为参数。f的type是(Int, Int) => Int。
class MyArray(val a: Int, val b: Int) {
def reduce(f: (Int, Int) => Int) = { f(a, b) }
}
接下来,在下面代码中m为MyArray的一个例化,其成员a和b被赋予值2和4。并定义了两个函数add和mul分别执行加法和乘法。m在调用reduce方法时可以选择函数add或者mul作为输入参数,分别得到结果6和8。
Example 1.3
val m = new MyArray(2, 4)
def add(x: Int, y: Int): Int = { x + y }
def mul(x: Int, y: Int): Int = { x * y }
val addResult = m.reduce(add) // 6
val mulResult = m.reduce(mul) // 8
Placeholder syntax
Placeholder syntax可以让function literal看起来更加简洁,它通过将对应参数名替换为下划线_来实现。例如上面的Example 1.4代码的第二行可以改写为如下代码:
val sum = ary.reduce(_ + _)