Chisel Style Guide


1. Foreword

Chisel Style Guide是一份简单的代码编写指南,统一编码风格以及遵循一些Chisel的最佳实践统升团队对代码的可读性,提升代码质量。因为输入的Verilog的命名与Chisel命名有关,所以Chisel中的一些命名参考了Verilog编码规范。

2. Style

2.1. Name

2.1.1. Reg、Wire、Port、Module Instances

因为Chisel编译器在生成Verilog时,会在变量中添加下划线,所以Chisel强烈不建议用户以全小写下划线的风格命名变量。

  1. 小写驼峰命名。
  2. Reg需要用后缀标识。
  3. 输入和输出端口需要用in和out标识。
  4. 低电平有效加后缀n标识。
  5. 示例
class WriterIO(size: Int) extends Bundle {
  val inWrite = Input(Bool())
  val outFull = Output(Bool())
  val rstn = Input(Bool())          // rstn默认输入,不用特别标识,_n表示低电平复位
  val clk = Input(Bool())			       // clk默认输入,不用特别标识
  val din = Input(UInt(size.W))      // din习惯用法表示datain
  val dout = Output(UInt(size.W))    // dout习惯用法表示dataout
  var inWrdata = Input(UInt(size.W))    // wrdata习惯用法不用分开
  var outRddata = Output(UInt(size.W))  // rddata习惯用法不用分开
}

val countReg = RegInit(0.U(32.W))   // 标识是Reg类型,与时序电路相关
val grayCounter = Module(new GrayCounter())

2.1.2. Module

模块名使用大写驼峰表示,命名尽量简单清晰。示例:

class MyCustomBundle extends Bundle {
  ...
}
// Companion object to MyCustomBundle
object MyCustomBundle {
  ...
}

2.1.3. Function

函数名使用小写驼峰表示。示例:

def isEven(n: Int): Boolean = (n % 2) == 0
def isOdd(n: Int): Boolean = !isEven(n)

2.1.4. constant value

常量使用全大写,单词下划线分隔。示例:

val CONST_VALUE = 0x5A.U(8.W)
val MASK_VALUE = 0xF0.U(8.W)

2.1.5. Blackbox Parameter

Blackbox的参数与Verilog保持一直,全大写,下划线分隔。示例:

class IBUFDS extends BlackBox(Map("DIFF_TERM" -> "TRUE",
                                  "IOSTANDARD" -> "DEFAULT")) {
}

2.1.6. Package

包名与目录名保持一样,全小写,即同一目录下所有scala文件属于同一个Package。示例:

 package cmm
package utils

2.1.7. Other

关于全大写缩写词,推荐以下风格。

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.2. Comments

Chisel的注释与C/Java等一样。示例:

// This is a single-line comment
val myVar = 42 // This is also a single-line comment

/*
 * This is a
 * multi-line
 * comment.
 */
val myVar = 42

2.3. Formatting

2.3.1. indentation

Chisel的缩进保持和Scala一致,2个空格。VSCode中安装Chisel/Scala的语法插件,自动实现2空格缩进排版。

示例:

class YsCounter extends Module {
  val io = IO(new Bundle {
    val outCount = Output(UInt(32.W))
    val inSig = Input(Bool())
  })

  val countReg = RegInit(0.U(32.W))
  when (inSig) {
     countReg := 0.U
  }.otherwise {
    countReg := count_f + 1.U
      when (count_reg >= 3.U) {
        countReg := 3.U
    }
  }

  io.outCount := countReg 
}

2.4. Curly Braces

Chisel追求紧凑的代码风格,{不换行。示例:

  when (inSig) {
     countReg := 0.U
  }.otherwise {
    countReg := count_f + 1.U
      when (count_reg >= 3.U) {
        countReg := 3.U
    }
  }

2.4.1. Blank

when/switch等关键字后空一格,操作符左右各空一格。示例:

when (inSig) {
     countReg := 0.U
  }.otherwise {
    countReg := countReg + 1.U
      when (count_reg >= 3.U) {
        countReg := 3.U
    }
  }

2.5. File Name

文件和主模块名保持一致,一个文件内可以有多个模块。

3. Best Practices

3.1. Comments

添加有意义的注释,无意义的注释不要添加。注释是为了表达为什么这样做,不是表达做了什么。

3.2. Reg

Chisel的Reg默认自带Reset复位以及时钟信息上升沿取值,所以不要再手动判断上升沿来更新Reg变量。

3.3. Gray Code

在信号质量要求的场景中使用格雷码编码。

3.4. Sequential Logic

一般情况下使用同步时钟电路,优先使用非阻塞赋值方式。

3.5. Combinational Logic

组合逻辑不要太长,过长的组合逻辑增加电路延迟,影响电路稳定。可以将长组合逻辑分解为时序逻辑电路。

3.6. Delay

设计代码中不要使用延时,延时代码无法综合。

3.7. Bulk Connection

能用块连接的地方尽量使用块连接,提升效率,降低误接的风险。

3.8. Explicit Width

val cntReg = RegInit(0.U(4.W))  // Good
val cntReg = RegInit(0.U)	      // Bad

3.9. Advanced Feature

枚举、派生、参数化、函数式编程等高级特性的运用,可以提升代码的表达能力,提升编码效率。

3.10. Verification

每一个Module都要有足够的验证,并且需要生成波形文件辅助验证。

3.11. printf

多用printf打印信息来增加代码的可调试性,如:

printf(p"width: ${Reg.getWidth}\n") // 打印寄存器的宽度
printf(p"value: ${Reg}\n")          // 打印寄存器的值

3.12. Verilog

SystemVerilog的可综合性无法保证,所以默认都是生成Verilog,并且禁用随机化宏。示例:

object fsmMain extends App {
  emitVerilog(
    new SimpleFsm,
    Array(
      "--emission-options=disableMemRandomization,disableRegisterRandomization",
      "--target-dir=hdl",
      "--full-stacktrace"
    )
  )
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值