spinal HDL - 01 - 环境搭建与Scala编程指南
写在前面
SpinalHDL这个语言,我是在了解了香山处理器Chisel才知道的,一直想用一用,SpinalHDL和Chisel师承一脉,都是基于Scala来进行电路描述。其本质上仍旧是HDL而非HLS,在设计之前依旧需要有清晰的电路结构,在电路描述上更加方便和快捷。
本文主要对spinal HDL的参考文档进行了翻译,后期打算应用spinal HDL进行简单的模块的改写。本文中内容主要对scala编程进行了简单的介绍。
环境搭建
参考大佬知乎文章搭建环境:
环境搭建文章参考
数据类型
在 Scala 中,有 5 种主要数据类型:
类型 | 示例 | 描述 |
---|---|---|
Boolean | true, false | |
Int | 3, 0x32 | 32位整数 |
Float | 3.14f | 32 位浮点数 |
Double | 3.14 | 64 位浮点数 |
String | “Hello world” | UTF-16 字符串 |
变量
在 Scala 中,可以使用 var
关键字定义变量:
var number : Int = 0
number = 6
number += 4
println(number) // 10
Scala 能够自动推断类型。 如果变量是在声明时分配的,则不需要指定它:
var number = 0 //'number'的类型在编译时被推断为Int。
但在 Scala 中使用 var 并不常见。 相反,通常使用 val 定义的常量值:
val two = 2
val three = 3
val six = two * three
函数
例如,如果您想定义一个函数,如果它的两个参数之和大于零,则返回 true,您可以执行以下操作:
def sumBiggerThanZero(a: Float, b: Float): Boolean = {return (a + b) > 0
}
然后,要调用此函数,可以按顺序进行传参数,或者按名字进行传参数:
sumBiggerThanZero(2.3f, 5.4f)orsumBiggerThanZero(a = 2.3f,b = 5.4f
)
Return
不需要 return 关键字。 如果没有它,Scala 将函数的最后一条语句作为返回值。返回类型推断 Scala 能够自动推断返回类型,不需要指定。
def sumBiggerThanZero(a: Float, b: Float) = {(a + b) > 0
}
如果你的函数只包含一个语句,Scala 函数不需要花括号。同时可以为函数的每个参数指定一个默认值:
def sumBiggerThanZero(a: Float, b: Float = 0.0f) = (a + b) > 0
不返回任何内容的函数 如果您希望函数不返回任何内容,则应将返回类型设置为 Unit。 它等效于 C/C++ void 类型。
def printer(): Unit = {println("1234")println("5678")
}
Apply
apply 的函数很特别,因为可以调用它们而无需键入它们的名称:
class Array() {def apply(index: Int): Int = index + 3
}val array = new Array()
val value = array(4) //array(4) is interpreted as array.apply(4) and will return 7
这个概念也适用于 Scala 对象(static):
object MajorityVote {def apply(value: Int): Int = ...
}val value = MajorityVote(4) // Will call MajorityVote.apply(4)
Object
在 Scala 中,没有 static 关键字。 取而代之的是对象。 对象定义中定义的所有内容都是静态的。
下面的例子定义了一个名为 pow2 的静态函数,它接受一个浮点值作为参数并返回一个浮点值。
object MathUtils {def pow2(value: Float): Float = value * value
}
然后你可以通过写来调用它:
MathUtils.pow2(42.0f)
入口点(main)
Scala 程序的入口点(主函数)应该在对象内部定义为名为 main 的函数。
object MyTopLevelMain{def main(args: Array[String]) {println("Hello world")}
}
class
类语法与 Java 非常相似。 想象一下,您要定义一个 Color 类,该类将三个 Float 值 (r,g,b) 作为构造参数:
class Color(r: Float, g: Float, b: Float) {def getGrayLevel(): Float = r * 0.3f + g * 0.4f + b * 0.4f
}
然后,实例化上一个示例中的类并使用其 getGrayLevel 函数:
val blue = new Color(0, 0, 1)
val grayLevelOfBlue = blue.getGrayLevel()
注意,如果你想从外部访问类的一个构造参数,这个构造参数应该定义为一个val:
class Color(val r: Float, val g: Float, val b: Float) { ... }
...
val blue = new Color(0, 0, 1)
val redLevelOfBlue = blue.r
继承
例如,假设您要定义两个类,Rectangle 和 Square,它们扩展了类 Shape:
class Shape {def getArea(): Float
}class Square(sideLength: Float) extends Shape {override def getArea() = sideLength * sideLength
}class Rectangle(width: Float, height: Float) extends Shape {override def getArea() = width * height
}
案例类
Case 类是声明类的另一种方式。
case class Rectangle(width: Float, height: Float) extends Shape {override def getArea() = width * height
}
然后 case class 和 class 之间有一些区别:
- case 类不需要 new 关键字来实例化。
- 参数可从外部访问; 您不需要将它们定义为 val。
在 SpinalHDL 中,这解释了编码约定背后的原因:通常建议使用案例类而不是类,以减少输入和提高一致性。
模板/类型参数化
想象一下,你想设计一个类,它是给定数据类型的队列,在这种情况下,你需要为类提供一个类型参数:
class Queue[T](){def push(that: T) : Unit = ...def pop(): T = ...
}
如果要将 T 类型限制为给定类型(例如 Shape)的子类,可以使用 <:Shape 语法:
class Shape() {def getArea(): Float
}
class Rectangle() extends Shape { ... }class Queue[T <: Shape]() {def push(that: T): Unit = ...def pop(): T = ...
}
函数也是如此:
def doSomething[T <: Shape](shape: T): Something = { shape.getArea() }
编程约定
类与案例类
定义 aBundle
或 a Component
时,最好将其声明为 case 类。
原因是:
- 它避免使用
new
关键字。在某些情况下,永远不必使用它比有时更好。 - 一个案例类提供了一个克隆功能。 当需要克隆 Bundle 时,这在 SpinalHDL 中很有用,例如,当您定义新的 Reg 或某种新的 Stream 时。
- 参数从外面直接可见。
[case]class
所有类名都应该以大写字母开头。
class Fifo extends Component {}class Counter extends Area {}case class Color extends Bundle {}
伴生对象
一个伴生对象应以大写字母开头。
object Fifo {def apply(that: Stream[Bits]): Stream[Bits] = {...}
}object MajorityVote {def apply(that: Bits): UInt = {...}
}
此规则的一个例外是当伴随对象用作函数时(仅apply
在内部),并且这些apply
函数不生成硬件:
object log2 {def apply(value: Int): Int = {...}
}
函数
函数应始终以小写字母开头:
def sinTable = (0 until sampleCount).map(sampleIndex => {val sinValue = Math.sin(2 * Math.PI * sampleIndex / sampleCount)S((sinValue * ((1 << resolutionWidth) / 2 - 1)).toInt, resolutionWidth bits)
})val rom = Mem(SInt(resolutionWidth bit), initialContent = sinTable)
例化
类的实例化应始终以小写字母开头:
val fifo = new Fifo()
val buffer = Reg(Bits(8 bits))
if / when
Scala if 和 SpinalHDL when 通常应按以下方式编写:
if(cond) {...
} else if(cond) {...
} else {...
}when(cond) {...
}.elseWhen(cond) {...
}.otherwise {...
}
switch
SpinalHDLswitch
通常应按以下方式编写:
switch(value) {is(key) {}is(key) {}default {}
}
如果可以使代码更具可读性,则可以将is
/default
语句压缩到一行中。
参数
通常在 case 类中对Component
/Bundle
的参数进行分组是比较实用的,因为:
- 更易于携带/操作以配置设计
- 更好的可维护性
case class RgbConfig(rWidth: Int, gWidth: Int, bWidth: Int) {def getWidth = rWidth + gWidth + bWidth
}case class Rgb(c: RgbConfig) extends Bundle {val r = UInt(c.rWidth bit)val g = UInt(c.gWidth bit)val b = UInt(c.bWidth bit)
}
但这不应该适用于所有情况。例如:在 FIFO 中,将dataType
参数与depth
fifo的参数分组是没有意义的,因为一般来说,thedataType
与设计相关,而 thedepth
与设计配置相关。
class Fifo[T <: Data](dataType: T, depth: Int) extends Component {}
spinal HDL - 01 - 环境搭建与Scala编程指南相关推荐
- 微信点餐系统01——环境搭建
微信点餐系统01--环境搭建 一.创建数据库表 微信点餐系统一共需要5个表. 商品表:商品编号.商品名称.商品价格.商品库存.商品描述.商品图片.商品情况(上架还是下架).它属于哪个类目(热销?男 ...
- 学习笔记0 Linux环境搭建与脚本编程
临近毕业方觉,自己当初凭着一腔热血选择的专业,最后似乎什么也没学到. 签了个还算凑合的工作,却莫名有种空虚,如果要给自己评个级,现在的编程水平大概不及自己大二时候,括弧笑. 于是不惜花了大价钱报了个班 ...
- Linux高并发服务器开发---笔记1(环境搭建、系统编程、多进程)
0613 第4章 项目制作与技能提升 4.0 视频课链接 4.1 项目介绍与环境搭建 4.1.1 项目介绍 4.1.2 开发环境搭建 ①安装Linux系统.XSHELL.XFTP.Visual Stu ...
- (01)ORB-SLAM2源码无死角解析-(01) 环境搭建,demo运行,ROS一键安装_清除各种疑难杂症
讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解的(01)ORB-SLAM2源码无死角解析-接如下(本文内容来自计算机视觉life ORB-SLAM2 课程课件): (0 ...
- Intellij IDEA开发环境搭建,scala配置及打包,jar包在spark中的运行
1. Intellij IDEA 开发环境搭建 最近在学习scala,除需要编写scala程序外,同时还需要创建maven工程,打成Jar包,而Eclipse在这方面显得使用的不是那么方面,同时由于I ...
- (02)Cartographer源码无死角解析-(01) 环境搭建,demo运行,ROS一键安装_清除各种疑难杂症
讲解关于slam一系列文章汇总链接:史上最全slam从零开始,针对于本栏目讲解(02)Cartographer源码无死角解析链接如下: (02)Cartographer源码无死角解析-(00)目录_最 ...
- 中科世为 Z6S Linux HMI 屏幕模组上手记录 | 01 - 环境搭建
1. 中科世为Z6S串口屏 中科世为官网 最近到手一块中科世为的串口屏,开搞! Z6S串口屏中运行的是 FlyThings OS 嵌入式物联网界面系统,FlyThings OS是中科世为基于Linux ...
- 微信小程序——聊天小程序——01环境搭建
一.环境搭建 总来的来说,初始化搭建一般有两部: 1.环境的初始化 2.基本页面的搭建 一.环境的初始化 1.1首先新建有关云函数的文件夹 编辑 1.2在project中配置云环境目录,配置完成后点保 ...
- 使用Spring boot搭建Wechat(企业微信)Demo -图文教程 -01 环境搭建
** Spring Boot-Wachat Demo [1] 环境搭建[适用小白的哥哥大白,高手跳过本节,内容主要记录个人搭建所遇到的坑和分享过程] ** Spring boot简介.特点等这里就不过 ...
最新文章
- kvm--virsh命令行下管理虚拟机
- 性能超越图神经网络,将标签传递和简单模型结合实现SOTA
- 自定义CSS博客皮肤
- Eclipse-配置workspace路径
- cake-build -.Net Core 跨平台构建自动化系统。
- spring boot中的注解
- unity, Gizmos.DrawMesh一个坑
- 《Scala机器学习》一一
- 获取数据库链接Junit
- python 桌面数据库_python数据库操作笔记
- 【odoo15】如何使用 python xmlrpc 连接 odoo
- 1-JavaScript高级程序设计-简介
- 最大流 Ford-Fulkerson 算法
- [概率论与数理统计-1]: 总体架构、知识结构、知识体系
- Ubuntu下的几种常见输入法
- cruisecontrol 持续化集成(运行bat脚本)
- 三极管实现的锁存电路
- 局域网内交换机VLAN隔离设置
- FORCESPRO的使用教程
- 成都拓嘉启远:拼多多下单后地址错误能改吗
热门文章
- vscode 程序员鼓励师_程序员鼓励师插件Rainbow Fart(彩虹屁)
- POJ2187-最远点对-旋转卡壳(怎么开心怎么读)
- 计算机教案三维目标,“三维目标”的三个问题 教学设计三维目标模板
- 【计算机网络】湖科大微课堂笔记 p7-10 计算机网络体系结构:常见的计算机网络体系结构、必要性、分层思想、专业术语
- 光纤收发器在安装使用过程所遇到的问题及解决办法
- 屏幕录像机(bb flashback pro 4)pjb v4.1.21
- Task Office for Mac(GTD办公软件)
- 解决浏览器驱动和浏览器版本不匹配的报错:This version of ChromeDriver only supports Chrome version 97
- 【SpringBoot深入浅出系列】SpringBoot之集成MyBatis-Plus
- SecureRandom的江湖偏方与真实效果