AnserCore 编程风格规范¶
目前 AnserCore 项目还处于早期开发阶段。我们希望尽可能地以一个标准和良好的风格来呈现代码,提升项目质量。但由于 Scala 是一个灵活性较强、抽象层次较高的语言,所以我们尚未找到实际模块设计与组织的最佳实践。在当前探索阶段,以下风格指南作为开发人员的基本参考,并且以相关自动化检查工具作为强约束。在未来,我们希望可以通过开发实践来不断细化并获得一个良好完整的 Chisel 风格规范。
对于风格规范中尚未涉及之处与描述模糊冲突之处,以代码呈现效果的可读性与可维护性更优为目标进行评审。
Scala 语法风格¶
AnserCore 项目的 Scala 语法风格基本遵循 Databricks Scala 编程风格指南 和 Scala 官方风格指南。
其中部分的规则约束已经反映在了项目根目录的 .scalafmt.conf 和 .scalafix.conf 中,并且可以结合相应工具进行自动格式化或风格检查。
Chisel 语法风格¶
Chisel 是嵌入于 Scala 编程语言的硬件描述语言。除了上一节提到的 Scala 语法风格外,Chisel 还遵循 Chisel 官方风格指南。
调整 1:大驼峰命名¶
与 Chisel 官方指南不同,驼峰命名中的缩写不会视为普通单词,即在大驼峰命名中全大写,在小驼峰命名中作为起始时全小写。
Prose form |
UpperCamelCase |
lowerCamelCase |
Incorrect |
|---|---|---|---|
find GCD |
FindGCD |
findGCD |
~~findGcd~~ |
state for FSM |
StateForFSM |
stateForFSM |
~~stateForFsm~~ |
mock dut |
MockDUT |
mockDUT |
~~MockDut~~ |
FIFO Generator |
FIFOGenerator |
fifoGenerator |
~~FifoGenerator~~ |
补充 2:寄存器¶
寄存器(和其类型)应该按以下格式指定:
Reg(UInt()) // good!
Reg(UInt(8.W)) // also good!
Reg(chiselTypeOf(io.my_signal) // good!
不要通过构造 Reg(x) 告诉 Reg 该类型为 x。它 不 告诉 Reg 初始值,也不会将信号添加 Delay!
Reg(UInt(0)) // bad! Returns a Reg of type UInt and unknown width.
Reg(UInt(0,15)) // bad! Returns a Reg of type UInt with width 15.
Reg(io.my_signal) // bad. This makes a Reg of type io.my_signal, but the intention is not clear!
// It can be easily misread as Reg(next=io.my_signal).
寄存器应该按以下格式初始化:
RegInit(0.U(15.W)) // good, initialized register to value 0 with width 15
Reg(0.U(15.W)) // WRONG! This will be an elaboration error
延迟一个信号(即将其接入寄存器)应该按以下格式执行:
RegNext(io.my_signal) // good
Reg(io.my_signal) // WRONG! Creates a Reg of the same type as io.a, this will be an elaboration error
Reg 的 Vec,而不是 Vec 的 Reg,例如
val lotsOfRegs = RegInit(VecInit(10, UInt(32.W)))
C/C++ 语法风格¶
对于 C/C++ 语言,AnserCore 项目将会使用 Clang 格式化工具的 LLVM 预设风格。