十二 · 2021年11月01日

SpinalHDL—小练习(一)

本系列适合新手在对Scala及SpinalHDL有初步了解后做练手使用。

题目

检测输入信号上升沿个数。

信号列表:
image.png

实现

import spinal.core._
import spinal.lib._
case class example1() extends Component{
  val io=new Bundle{
    val sigIn=in Bool
    val clear=in Bool
    val cnt=out UInt (32 bits)
  }
  val counter=new Area{
    val cnt=Counter(32 bits,io.sigIn.rise(False))
    when(io.clear){
      cnt.value.clearAll()
    }
    io.cnt:=cnt.value
  }
}
object example1App extends App{
  SpinalConfig(
    defaultClockDomainFrequency = FixedFrequency(100 MHz)
  ).generateSystemVerilog(example1()).printPruned()
}

Key:

  • Bool信号上升沿检测方法rise()
  • SpinalHDL中lib库提供的Counter函数

进阶一

检测固定时间段内输入信号上升沿个数,检测时长由参数配置,时钟频率提前未知。

实现:

case class example1_1(timeMs:Int) extends Component{
  val io=new Bundle{
    val sigIn=in Bool
    val clear=in Bool
    val cnt=out UInt (32 bits)
  }
  val counter=new Area{
    val timeout=Timeout(timeMs ms)
    val cnt=Counter(32 bits,io.sigIn.rise(False))
    when(io.clear){
      cnt.value.clearAll()
    }
    when(timeout){
      timeout.clear()
      cnt.value.clearAll()
    }
    io.cnt:=RegNextWhen(cnt.value,timeout,U(0,32 bits))
  }
}
object example1App extends App{
  SpinalConfig(
    defaultClockDomainFrequency = FixedFrequency(100 MHz)
  ).generateSystemVerilog(example1_1(1)).printPruned()
}

Key:

  • SpinalHDL中lib库提供的Timeout模块
  • SpinalConfig中时钟频率配置,模块内TImeMs ms自动计算相应计数器值。

进阶二

在进阶一的基础上,由初始化参数决定是检测上升沿还是下降沿。

case class example1_2(timeMs:Int,detectRise:Boolean) extends Component{
  val io=new Bundle{
    val sigIn=in Bool
    val clear=in Bool
    val cnt=out UInt (32 bits)
  }
  val counter=new Area{
    val timeout=Timeout(timeMs ms)
    val incEnable=if(detectRise) io.sigIn.rise(False) else io.sigIn.fall(False)
    val cnt=Counter(32 bits,incEnable)
    when(io.clear){
      cnt.value.clearAll()
    }
    when(timeout){
      timeout.clear()
      cnt.value.clearAll()
    }
    io.cnt:=RegNextWhen(cnt.value,timeout,U(0,32 bits))
  }
  object example1App extends App{
  SpinalConfig(
    defaultClockDomainFrequency = FixedFrequency(100 MHz)
  ).generateSystemVerilog(example1_2(1,false)).printPruned()
}

Key:

  • if else在描述电路规则中的使用。在生成Verilog文件之前,val incEnable=if(detectRise) io.sigIn.rise(False) else io.sigIn.fall(False)已经确定是检测上升沿还是下降沿。这里if else类似`ifdef的功能。

END

作者:玉骐
原文链接:https://mp.weixin.qq.com/s/KwtoEnx1_lD7NJTL2HssiA
微信公众号:
 title=

推荐阅读

更多SpinalHDL技术干货请关注Spinal FPGA专栏。
推荐阅读
关注数
1583
内容数
133
用SpinalHDL提升生产力
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息