Chisel(Constructing Hardware In a Scala Embedded Language)是UC Berkeley开发的一种开源硬件构造语言。它是建构在Scala语言之上的领域专用语言(DSL),支持高度参数化的硬件生成器。
原本以为在了解了chisel基本语法之后,在运用chisel的大道上就可以畅通无阻了。没想到在chisel的高阶应用中一脸懵逼。看来学习一下scala是十分必要的。
本文为《快学scala》的学习笔记,和chisel相同部分不再记录,仅记录笔者认为对chisel有用的部分。其中序号与书中序号一致,方便查找。
1.5 调用函数和方法
数学函数 用如下语句引入:
import scala.match._
sqrt(2) //1.414213
pow(2,4) //16.0
min(3,pi) //3.0
2.2 语句终止(换行符)
如果需要分2行来写,要确保第一行以一个不能用做语句结尾的符号结尾
s = s0 + (v - v0)*t +
0.5*(a - a0)*t
2.6 高级for循环和for推导式
(1) 可以以“变量<-表达式”的形式提供多个生成器,用分号将它们隔开,eg:
for(i<-1 to 3; j <- 1 to 3) print((10 * i + j) + "")
// 11 12 13 21 22 23 31 32 33
(2) 每个生成器都可以带一个守卫
for(i<-1 to 3; j <- 1 to 3 if i!=j) print((10 * i + j) + "")
// 12 13 21 23 31 32
注意:在if之前没有分号
(3) 可以使用任意多的定义,引入可以在循环中使用的变量
for(i<-1 to 3; from=4-i; j <- from to 3) print((10 * i + j) + "")
// 13 22 23 31 32 33
(4) 如果for循环的循环体以yield开始,则该循环会构造出一个集合,每次迭代生成集合中的一个值
for(i<- 1 to 10) yield i % 3
// 生成Vector(1,2,0,1,2,0,1,2,0,1)
2.7 函数
要定义函数,需要给出:函数名称、参数、函数体
def abs(x : Double) = if(x>=0) x else -x
必须给出所有参数的类型。如果函数不是递归的,就不需要指定返回类型,scala可以推断。
如果函数体需要多个表达式完成,可以用代码块,块中最后一个表达式的值就是函数的返回值。
def fac(n: Int) = {
var r = 1
for(i<- 1 to n) r = r * I
r
}
对于递归函数,则必须指定返回类型
def fac(n : Int): Int = if (n <= 0) 1 else n * fac(n - 1)
2.8 默认参数和带名参数
函数的一些参数可以使用默认值
def decorate(str: String, left: String = "[", right: String = "]") =
left + str + right
调用 decorate("hello"),会得到"[hello]"
默认值可以被覆盖。
decorate("hello","<<<",">>>"),会得到"<<<hello>>>"
decorate("hello","<<<",">>>") //得到"<<<hello>>>"
若给出的值不够,会从后往前应用
decorate("hello","<<<"),会得到"<<<hello]"
带名传参
decorate("hello",right = "]<<<"),会得到"[hello]<<<"
2.9 变长参数
eg:
def sum(args: Int*) = {
var result = 0
for (arg <- args) result += arg
result
}
调用时:
val s = sum(1,4,9,16,25)
函数得到的是一个类型为Seq的参数
如果已经有一个值的序列,则不能直接传入上述函数,参数必须是单个整数,而不是一个整数区间。例如以下写法不对:
val s = sum(1 to 5)
修改为:
val s = sum(1 to 5: _*)
2.10 过程
过程没有返回值,调用它仅仅是为了它的副作用
eg:
def box(s: String) { //过程没有=号
var border = "-" * s.length + "--\n"
println(border + "|" + s + "|\n" + border)
}
2.11 懒值 lazy
当 val被声明为lazy时,它的初始化会被推迟,直到我们首次对它取值。例如:
lazy val words = scala.io.Source.fromFile("./words").mkString
//在words被首次使用时取值
val words = scala.io.Source.fromFile("./words").mkString
//在words被定义时取值
def words = scala.io.Source.fromFile("./words").mkString
//在每一次words被使用时取值
懒值对于开销较大的初始化语句十分有用
3.1 定长数组
可以使用 Array
val nums = new Array[Int](10)
//10个整数的数组,所有元素初始化为0
val a = new Array[String](10)
//10个元素的字符串数组,所有元素初始初始化为null
val s = Array("Hello","Word")
//长度为2的Arrayp[String],类型是推断出来的
//已提供初始值就不需要new
3.2 变长数组:数组缓冲 ArrayBuffeer
import scala.collection.mutable.ArrayBuffeer
val b = ArrayBuffeer[Int]()
//或new ArrayBuffeer[Int]
//一个空的数组缓冲。准备存放整数
b += 1
//ArrayBuffeer[1]
//用+=在微端添加元素
3.3 遍历数组和数组缓冲
for循环遍历数组和数组缓冲:
for(i <- 0 until a.length)
如果想要以2做步长
0 until (a.length, 2)
从数组的尾端开始遍历:
(0 until a.length).reverse
3.4 数组转换
这些转换动作不会修改原始数组,而是产生一个全新的数组。
(1) val a = Aarray(2,3,5,7,11)
val result = for(elem <- a ) yield 2 * elem
//result是Array(4,6,10,14,22)
for (…) yield循环创建了一个类型与原始集合相同的新集合。
也可以写作:
a.filter(_ % z == 0).map(2 * _)
a.filter{_ % z == 0}.map(2 * _)
3.5 多维数组
Double的二位数组类型为Array[Array[Double]]。要构造这样一个数组,可以用ofDim方法:
val matrix = Array.ofDim[Double](3,4) //3行,4列
访问其中的元素:
Matrix(row)(column)
4.1 构造映射
不可变映射:
val scores = Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8)
可变映射:
val scores = scala.collection,multable.Map("Alice" -> 10, "Bob" -> 3, "Cindy" -> 8)
定义一个空映射,需给出类型参数
val scores = new scala.collection,multable.HashMap
4.2 更新映射中的值
更新或新增:
scores("Bob") = 10
添加多个:
scores += ("Bob" -> 10, "Fred" ->7)
移除:
scores -= "Alice"
不可变映射不能更新,但是可以获取包含所需要更新的新映射:
val newScores = scores + ("Bob" -> 10, "Fred" ->7)
//更新Bob,新增Fred
4.7 元组
元组是不同类型的值的聚集。
元组的值是通过单个的值包含在圆括号中构成的。例如:
(1, 3.14, "Fred")
可以用 _1、_2、_3访问元组单元
val t = (1, 3.14, "Fred")
val second = t._2 //second = 3.14
数组、字符串的位置从0开始,元组从1开始
可以使用模式匹配来获得元组的组元:
val (first,second ,third) = t
在不需要的位置上用_
val (first,second, _) = t
4.8 拉链操作
将多个值绑在一起,以便他们能够被一起处理,可用zip来完成:
val symbols = Array("<","-",">")
val counts = Array(2,10,2)
val pairs = symbols.zip(counts)
输出:
Array(("<",2),("-",10),(">",2))
一起处理:
for ((s,n) <- pairs) Console.print(s * n) //打印<<---------->>