Chisel(Constructing Hardware In a Scala Embedded Language)是一门以Scala为宿主语言开发的硬件构建语言,它是由加州大学伯克利分校的研究团队发布的一种新型硬件语言,它是面向对象编程的语言。
参考bootcamp
一、变量
可变变量:var
常量值(不可变的变量):val(多使用此种类型,为了减少重复使用变量的机会)
Scala一般不要求在语句的结尾加上分号。Scala在有换行的情况下会推断出分号的存在。
二、条件语句
可以不使用括号
不是每个分支都只有一行,需要加括号
Scala中if条件语句会返回一个值,这个值由分支的最后一行决定,可用于初始化函数和类的值。
这个条件语句创建了likelyCharatersSet变量,变量的值在运行时有条件的决定
三、函数
1.函数使用关键词def来定义,函数参数用逗号分隔列表来指定,需要指定函数参数的名称,类型和可选的默认值以及返回值的类型。
2.没有参数的函数不需要空括号,调用无side effect的参数函数(即调用他们不会改变任何东西,他们只是返回一个值)不需要使用你小括号,有side effect的参数函数应该需要小括号。
四、重载函数(Overloading Functions)
同一函数名可以有多种使用方式,参数和类型决定了一个签名,允许编译器找出应该调用的版本,但是需要避免重载函数。
五、递归和嵌套函数(Recursive and Nested Functions)
六、列表
Nil是空List,双冒号是追加进入
七、for循环
注意to和until的区别
八、包和引用
chisel中包的名字最好匹配目录,而且包的名字中不可以有下划线
引用示例:
第一个是引用chisel3中所有的类和方法,这里的下划线用作通配符,第二种是引用chisel3中iotesters包中的特定的类
九、Scala面向对象编程
scala和chisel的一些优点:
1.变量都是对象
2.scala中中用val声明的常量也是对象
3.文字值也是对象,函数体本身也是对象
4.对象是类的实例
面向对象编程的对象都可以被称为实例。
5.定义类时,程序员与需要指定,val和var类型的数据都与类关联,类的实例可以执行的操作被称为方法或函数
6.类可以被扩展为其他类
被扩展的类是superclass,扩展对象是子类subcalss,子类可以从超类中继承数据和方法。
有许多有用但是受限的方式可以让类扩展或者覆盖继承的属性
7.类可以从特征(traits)继承
将特征视为轻量级的类,允许特征使用特定、受限的方式从多个超类继承属性。
8.Singleton对象是一种特殊的Scala类,他们不是上述的对象,但是我们可以调用这些实例。
十、类的例子
1.类 WrapCounter -- 这是 WrapCounter 的定义。
2.(counterBits: Int) -- 创建 WrapCounter 需要一个整数参数。
3.大括号 ({}) 分隔代码块。大多数类使用代码块来定义变量、常量和方法(函数)。
val max: Long = -- 类包含一个成员变量 max,声明为 Long 类型并在创建类时初始化。
(1 << counterBits) - 1 计算可包含在 counterBits 位中的最大值。由于 max 是使用 val 创建的,因此无法更改。
var counter变量计数器被创建并初始化为 0L。 L 表示 0 是一个长值;因此,counter 被推断为 Long。 max 和 counter 通常被称为类的成员变量。
4.定义了一个类方法 inc ,它不接受任何参数并返回一个 Long 值。
方法 inc 的主体是一个代码块,它具有: 计数器 = 计数器 + 1 递增计数器。 if (counter > max) { counter = 0 } 测试计数器是否大于最大值,如果大于则将其设置回零。
counter -- 代码块的最后一行很重要。 任何表示为代码块最后一行的值都被视为该代码块的返回值。调用语句可以使用或忽略返回值。
这种应用很普遍;例如,由于 if then else 语句用代码块定义了它的 true 和 false 子句,它可以返回一个值,即 val result = if (10 * 10 > 90) "greater" else "lesser" 将创建一个val变量值为“greater”。 所以在这种情况下,函数 inc 返回 counter 的值。
5.println(s"counter created with max value $max")将字符串打印到标准输出。因为 println 直接在定义代码块中,它是类初始化代码的一部分并运行,即每次创建此类的实例时打印出字符串
6.在这种情况下打印的字符串是一个插值字符串。
第一个双引号前面的前导 s 将其标识为内插字符串。在运行时处理内插字符串。
$max 被替换为 max 的值。 如果 $ 后跟一个代码块,则任意 Scala 都可以在该代码块中。 例如,println(s"doubled max is ${max + max}")。 此代码块的返回值将插入到 ${...} 的位置。 如果返回值不是字符串,则转换为1; scala 中的几乎每个类或类型都隐式转换为已定义的字符串)。
通常应该避免在每次创建类的实例时打印某些内容,以避免淹没标准输出,除非正在调试。
十一、创建类的实例
val x = new WrapCounter(2)
创建的实例有时没有使用关键字 new,即 val y = WrapCounter(6)。这种情况经常发生,值得特别注意,但需要使用伴随对象。
思考:什么时候不用关键字new呢?
十二、代码块
代码块由大括号分隔。一个块可以包含零行或多行 Scala 代码。 Scala 代码的最后一行成为代码块的返回值(可以忽略)。没有行的代码块将返回一个特殊的类似 null 的对象,称为 Unit。代码块在整个 Scala 中使用:它们是类定义的主体,它们形成函数和方法, if 语句的子句, for 和许多其他 Scala 运算符的主体。
十三、参数化代码块
代码块可以带参数。在类和方法定义的情况下,这些参数看起来像大多数传统编程语言中的参数。在下面的示例中,c 和 s 是代码块的参数。
另一种代码块参数的声明方式
代码块被传递给 List 类的方法映射。 map 方法要求其代码块具有单个参数。为列表的每个成员调用代码块,代码块返回转换为字符串的成员。
Scala 接受这种语法的变体。这种类型的代码块称为匿名函数。
十四、命名参数和参数默认值
定义方式:
def myMethod(count: Int, wrap: Boolean, wrapValue: Int = 24): Unit = { ... }
调用:myMethod(count = 10, wrap = false, wrapValue = 23)可以看到参数化名称和传递的值。
使用命名参数可以以不同的顺序调用函数:
myMethod(wrapValue = 23, wrap = false, count = 10)
对于经常调用的方法,参数排序可能很明显。但是对于不太常见的方法,特别是布尔参数,包括调用的名称,可以使您的代码更具可读性。如果方法具有一长串相同类型的参数,则使用名称也会减少出错的机会。类定义的参数也使用这种命名参数方案(它们实际上只是类的构造函数方法的参数)
当某些参数具有默认值(不需要被覆盖)时,调用者只需(按名称)传递不使用默认值的特定参数。请注意,参数 wrapValue 的默认值为 24。
myMethod(wrap = false, count = 10)与myMethod(wrap = 24, count = 10)是一样的效果。