Chisel隐式时钟配置、复位电平处理及Scala特性使用咨询
2. 如何处理低有效/高有效复位?
Chisel 默认使用高有效复位,针对低有效复位的开发板,需手动转换电平,也可自定义扩展方法模拟你想要的toActiveLow()效果:
核心解决逻辑
开发板低有效复位的规则是:复位触发时为低电平,正常工作时为高电平。Chisel默认高电平触发复位,因此需要将输入的低有效复位取反,转为内部使用的高有效复位:
class MyModule extends Module { val io = IO(new Bundle { val activeLowReset = Input(Bool()) // 开发板低有效复位输入 }) // 转换为Chisel默认的高有效复位 val internalReset = !io.activeLowReset // 用转换后的复位驱动内部逻辑 withReset(internalReset) { val reg = RegInit(0.U(8.W)) reg := reg + 1.U // 其他逻辑... } }
自定义扩展方法实现类似写法
若需复用转换逻辑,可给Bool类型定义扩展方法:
// 定义复位转换扩展方法 implicit class BoolResetExt(b: Bool) { def toActiveHigh(): Bool = !b // 低有效转高有效 def toActiveLow(): Bool = !b // 高有效转低有效(按需使用) } class MyModule extends Module { val io = IO(new Bundle { val activeLowReset = Input(Bool()) }) // 直接使用扩展方法转换 val internalReset = io.activeLowReset.toActiveHigh() withReset(internalReset) { // 你的逻辑... } }
解决"始终处于复位状态"的问题
你当前的问题大概率是把低有效复位直接当作Chisel的高有效复位使用——开发板正常工作时复位引脚为高电平,Chisel会判定此时处于复位状态,取反后即可解决。
3. 是否有在Chisel中使用Scala Trait或Cats库的示例?
Scala Trait 在Chisel中的使用
Trait是Chisel中复用模块逻辑的常用方式,比如封装复位同步、通用接口等:
// 封装复位同步逻辑的Trait trait ResetSynchronizer { this: Module => // 限定仅能被Chisel Module继承 def syncAsyncReset(rawReset: Bool): Bool = { // 两级寄存器同步异步复位 val reg1 = RegNext(rawReset, false.B) val reg2 = RegNext(reg1, false.B) reg2 } } // 使用Trait的模块 class SyncResetModule extends Module with ResetSynchronizer { val io = IO(new Bundle { val rawReset = Input(Bool()) val count = Output(UInt(8.W)) }) val syncedReset = syncAsyncReset(io.rawReset) withReset(syncedReset) { val counter = RegInit(0.U(8.W)) counter := counter + 1.U io.count := counter } }
Cats库在Chisel中的使用
Cats是Scala函数式编程库,可用于输入验证、状态管理等场景,需先在build.sbt添加依赖:
libraryDependencies += "org.typelevel" %% "cats-core" % "2.9.0"
示例:用Cats的Validated做输入合法性验证:
import chisel3._ import cats.data.Validated import cats.syntax.all._ class ValidatedInputModule extends Module { val io = IO(new Bundle { val a = Input(UInt(8.W)) val b = Input(UInt(8.W)) val isValid = Output(Bool()) val sum = Output(UInt(9.W)) }) // 用Validated验证输入范围 val inputCheck = ( Validated.cond(io.a <= 100.U, io.a, "a exceeds max value"), Validated.cond(io.b <= 100.U, io.b, "b exceeds max value") ).mapN(_ + _) // 映射为Chisel信号 io.isValid := inputCheck.isValid.toBool io.sum := inputCheck.getOrElse(0.U) }
内容的提问来源于stack exchange,提问作者wasin
相关产品推荐
相关产品推荐

