编码规范
简介
SpinalHDL 中使用的编码规范与 Scala 风格指南 中的规定相同。
一些额外的细节和案例将在下几页中解释。
类与样例类
当您定义一个 Bundle
或 Component
时,最好将其声明为案例类。
原因是:
它避免使用
new
关键字。在某些情况下,永远不必使用它比有时使用它要好。case class
提供了clone
函数。当需要克隆Bundle
时,该函数非常有用。例如,当您定义新的Reg
或某种新的Stream
时。构造参数从外部直接可见。
样例类/类
所有类名称都应以大写字母开头
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 bits), 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 {
...
}
例外情况可能是:
可以在关键字前添加一个点,例如方法
.elsewhen
和.otherwise
。如果可以提高代码可读性,可以将
if
/when
语句压缩到一行中。
switch
SpinalHDL中的 switch
通常应按以下方式编写:
switch(value) {
is(key) {
}
is(key) {
}
default {
}
}
如果可以提高代码可读性,可以将 is
/default
语句压缩到一行中。
参数
在样例类中对 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 bits)
val g = UInt(c.gWidth bits)
val b = UInt(c.bWidth bits)
}
但这不应该适用于所有情况。例如:在 FIFO 中,将 dataType
参数与 fifo 的 depth
参数分组是没有意义的。因为一般情况下, dataType
与设计相关,而 depth
则与设计的配置有关。
class Fifo[T <: Data](dataType: T, depth: Int) extends Component {
}