【SpinalHDL快速入门】2、新建SpinalHDL工程,通过计数器Demo快速上手

news2024/11/28 23:56:15

文章目录

    • 新建工程
      • 各个工具版本
      • `build.sbt` 示例
      • `build.properties` 示例
      • 如何在IEDA中更新 SpinalVersion 并 Reload sbt Project
    • SpinalHDL入门例子:计数器
      • demo1
      • demo2(支持reset信号异步复位,低电平有效)
      • demo3(一个文件,支持异步复位)【个人常用这个】
    • Scala 基础
    • 饱和运算
    • 计数器Demo

新建工程

各个工具版本

配置文件主要是:build.sbtbuild.properties

  • JDK:1.8
  • scala:2.11.12
  • sbt:1.5.5
  • spinal:1.6.0 / 1.6.1(加入Enum)/ 1.8.1

在这里插入图片描述

build.sbt 示例

常见写法参考:

ThisBuild / version := "0.1.0-SNAPSHOT"

ThisBuild / scalaVersion := "2.11.12"

val spinalVersion = "1.6.0"
val spinalCore = "com.github.spinalhdl" %% "spinalhdl-core" % spinalVersion
val spinalLib = "com.github.spinalhdl" %% "spinalhdl-lib" % spinalVersion
val spinalIdslPlugin = compilerPlugin("com.github.spinalhdl" %% "spinalhdl-idsl-plugin" % spinalVersion)
lazy val root = (project in file("."))
  .settings(
    name := "scala_test",
    //    Compile / scalaSource := baseDirectory.value / "hw" / "spinal", //scala源文件不是在`src/main/scala`下,可以参考如下写法更改路径
    libraryDependencies ++= Seq(spinalCore, spinalLib, spinalIdslPlugin)
  )

fork := true

build.properties 示例

sbt.version = 1.5.5

如何在IEDA中更新 SpinalVersion 并 Reload sbt Project

在这里插入图片描述

SpinalHDL入门例子:计数器

demo1

最后生成的波形文件是test.vcd,gtkwave可以打开!

MyTopLevel.scala

package mylib

import spinal.core._
import spinal.lib._

import scala.util.Random

//Hardware definition
class MyTopLevel extends Component {
  val io = new Bundle {
    val cond0 = in  Bool()
    val cond1 = in  Bool()
    val flag  = out Bool()
    val state = out UInt(8 bits)
  }
  val counter = Reg(UInt(8 bits)) init(0)

  when(io.cond0){
    counter := counter + 1
  }

  io.state := counter
  io.flag  := (counter === 0) | io.cond1
}

//Generate the MyTopLevel's Verilog
object MyTopLevelVerilog {
  def main(args: Array[String]) {
    SpinalVerilog(new MyTopLevel)
  }
}

//Generate the MyTopLevel's VHDL
//object MyTopLevelVhdl {
//  def main(args: Array[String]) {
//    SpinalVhdl(new MyTopLevel)
//  }
//}


//Define a custom SpinalHDL configuration with synchronous reset instead of the default asynchronous one. This configuration can be resued everywhere
//定义一个自定义的SpinalHDL配置,使用同步复位而不是默认的异步复位。这个配置可以在任何地方重用。
object MySpinalConfig extends SpinalConfig(defaultConfigForClockDomains = ClockDomainConfig(resetKind = SYNC))

//Generate the MyTopLevel's Verilog using the above custom configuration.
//使用上述自定义配置生成MyTopLevel的Verilog。
object MyTopLevelVerilogWithCustomConfig {
  def main(args: Array[String]) {
    MySpinalConfig.generateVerilog(new MyTopLevel)
  }
}

对应生成的Verilog代码

// Generator : SpinalHDL v1.6.0    git head : 73c8d8e2b86b45646e9d0b2e729291f2b65e6be3
// Component : MyTopLevel



module MyTopLevel (
  input               io_cond0,
  input               io_cond1,
  output              io_flag,
  output     [7:0]    io_state,
  input               clk,
  input               reset
);
  reg        [7:0]    counter;

  assign io_state = counter;
  assign io_flag = ((counter == 8'h0) || io_cond1);
  always @(posedge clk or posedge reset) begin
    if(reset) begin
      counter <= 8'h0;
    end else begin
      if(io_cond0) begin
        counter <= (counter + 8'h01);
      end
    end
  end


endmodule

MyTopLevelSim

package mylib

import spinal.core._
import spinal.sim._
import spinal.core.sim._

import scala.util.Random


//MyTopLevel's testbench
object MyTopLevelSim {
  def main(args: Array[String]) {
    SimConfig.withWave.doSim(new MyTopLevel){dut =>
      //Fork a process to generate the reset and the clock on the dut
      dut.clockDomain.forkStimulus(period = 10)

      var modelState = 0
      for(idx <- 0 to 99){
        //Drive the dut inputs with random values
        dut.io.cond0 #= Random.nextBoolean()
        dut.io.cond1 #= Random.nextBoolean()

        //Wait a rising edge on the clock
        dut.clockDomain.waitRisingEdge()

        //Check that the dut values match with the reference model ones
        val modelFlag = modelState == 0 || dut.io.cond1.toBoolean
        assert(dut.io.state.toInt == modelState)
        assert(dut.io.flag.toBoolean == modelFlag)

        //Update the reference model value
        if(dut.io.cond0.toBoolean) {
          modelState = (modelState + 1) & 0xFF
        }
      }
    }
  }
}

demo2(支持reset信号异步复位,低电平有效)

最后生成的波形文件是test.fst,gtkwave也是也可以打开的!

Config.scala

package projectname

import spinal.core._
import spinal.core.sim._

object Config {
  def spinal = SpinalConfig(
//    targetDirectory = "hw/gen",
    defaultConfigForClockDomains = ClockDomainConfig(
//      resetActiveLevel = HIGH
      //异步复位
      clockEdge = RISING,
      resetKind = ASYNC,
      resetActiveLevel = LOW
    ),
    onlyStdLogicVectorAtTopLevelIo = true
  )

  def sim = SimConfig.withConfig(spinal).withFstWave
}

MyTopLevel.scala

package projectname

import spinal.core._

// Hardware definition
case class MyTopLevel() extends Component {
  val io = new Bundle {
    val cond0 = in  Bool()
    val cond1 = in  Bool()
    val flag  = out Bool()
    val state = out UInt(8 bits)
  }

  val counter = Reg(UInt(8 bits)) init 0

  when(io.cond0) {
    counter := counter + 1
  }

  io.state := counter
  io.flag := (counter === 0) | io.cond1
}

//main函数就在App这个类中!
object MyTopLevelVerilog extends App {
  Config.spinal.generateVerilog(MyTopLevel())
}

//object MyTopLevelVhdl extends App {
//  Config.spinal.generateVhdl(MyTopLevel())
//}

生成的Verilog代码如下:

// Generator : SpinalHDL v1.6.0    git head : 73c8d8e2b86b45646e9d0b2e729291f2b65e6be3
// Component : MyTopLevel



module MyTopLevel (
  input               io_cond0,
  input               io_cond1,
  output              io_flag,
  output     [7:0]    io_state,
  input               clk,
  input               resetn
);
  reg        [7:0]    counter;

  assign io_state = counter;
  assign io_flag = ((counter == 8'h0) || io_cond1);
  always @(posedge clk or negedge resetn) begin
    if(!resetn) begin
      counter <= 8'h0;
    end else begin
      if(io_cond0) begin
        counter <= (counter + 8'h01);
      end
    end
  end


endmodule

MyTopLevelSim.scala

package projectname

import spinal.core._
import spinal.core.sim._

object MyTopLevelSim extends App {
  Config.sim.compile(MyTopLevel()).doSim { dut =>
    // Fork a process to generate the reset and the clock on the dut
    dut.clockDomain.forkStimulus(period = 10)

    var modelState = 0
    for (idx <- 0 to 99) {
      // Drive the dut inputs with random values
      dut.io.cond0.randomize()
      dut.io.cond1.randomize()

      // Wait a rising edge on the clock
      dut.clockDomain.waitRisingEdge()

      // Check that the dut values match with the reference model ones
      val modelFlag = modelState == 0 || dut.io.cond1.toBoolean
      assert(dut.io.state.toInt == modelState)
      assert(dut.io.flag.toBoolean == modelFlag)

      // Update the reference model value
      if (dut.io.cond0.toBoolean) {
        modelState = (modelState + 1) & 0xff
      }
    }
  }
}

demo3(一个文件,支持异步复位)【个人常用这个】

package test

import spinal.core._
import spinal.lib._


case class MyTopLevel() extends Component {
  val io = new Bundle {
    val cond0 = in  Bool()
    val cond1 = in  Bool()
    val flag  = out Bool()
    val state = out UInt(8 bits)
  }
  val counter = Reg(UInt(8 bits)) init(0)

  when(io.cond0){
    counter := counter + 1
  }

  io.state := counter
  io.flag  := (counter === 0) | io.cond1
}


object MyTopLevelApp extends App{
  SpinalConfig(
  	//异步复位
    defaultConfigForClockDomains = ClockDomainConfig(
      clockEdge = RISING,
      resetKind = ASYNC,
      resetActiveLevel = LOW
    ),
    //defaultClockDomainFrequency = FixedFrequency(100 MHz),
    targetDirectory = "rtl" //生成的Verilog放到rtl目录下
  ).generateVerilog(MyTopLevel()).printPruned() //generateSystemVerilog也是可以的
}

Scala 基础

饱和运算

  • 关于饱和运算详细介绍参考:https://zh.wikipedia.org/wiki/%E9%A5%B1%E5%92%8C%E8%BF%90%E7%AE%97
  • 一句话解释就是:即当运算结果大于某上限或小于某下限时,其运算结果为该上限或下限的一种运算方式。比方说,当运算范围为 [0,255] 时:100+200的结果为255,而非300。

《SpinalHDL_docs》P53

x +| y 饱和加法运算 T(max(w(x), w(y)) bits)
x -| y 饱和减法运算 T(max(w(x), w(y)) bits)
val e = a +| U"8’x20"
assert(e === U"8’xff") //结果是最大值255.

计数器Demo

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/626534.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flume学习--1、Flume概述、Flume入门、

1、Flume概述 1.1 Flume定义 Flume是Cloudera提供的一个高可用&#xff0c;高可靠的&#xff0c;分布式的海量日志采集、聚合和传输的系统。Flume基于流式结构&#xff0c;灵活简单。 Flume最主要的作用就是实时读取服务器本地磁盘的数据&#xff0c;将数据写入到HDFS。 1.2…

C#winform多国语言应用实例

我们在开发项目中,一般需要软件支持多种语言,供不同客户使用。本文实例讲解实现办法。 1 窗体项目创建 添加控件MenuStrip、comboBox及Button,并修改对应显示文本,combobox编辑项输入英语 确定窗体的Localizable属性为true,自动创建Form1.resx,为False时,没有Form1.r…

基站机房:保障通信网络稳定,如何解决安全隐患?

基站机房作为无线通信网络的关键组成部分&#xff0c;承载着大量的网络设备和通信设施&#xff0c;对于运营商和通信服务提供商来说具有重要意义。 无论是大型运营商还是通信服务提供商&#xff0c;动环监控系统都将成为他们成功运营和管理通信网络的关键工具。 客户案例 案例…

vue使用高德地图--附带移动获取当前城市信息

高德地图 1.使用准备申请密钥vue使用 2.移动地图获取城市案例(注意事项)3.总结 1.使用准备 申请密钥 登录注册高德开放平台进入控制台 创建应用 申请key–生成key和安全密钥(2021之后key需要配合安全密钥使用) 注意&#xff1a;安全密钥需要在key之前 vue使用 首先在pubil…

一款功能强大的报表引擎-VeryReport报表引擎

在企业管理中&#xff0c;数据分析和决策制定是非常重要的环节。而报表则是这个过程中最常用的工具之一。但是&#xff0c;传统的报表设计与展现方式已经无法满足企业对于数据分析和报表展示的需求。为了解决这些问题&#xff0c;我们向大家推荐一款新一代Web报表软件——VeryR…

越是大型企业越需要企业内部知识库?

随着信息时代的到来&#xff0c;越来越多的企业开始注重知识管理。知识管理是一种通过有效地捕捉、共享和利用企业内部的知识资源&#xff0c;促进企业创新和发展的方法。而企业内部知识库作为知识管理的一种重要方式&#xff0c;对于大型企业来说尤为重要。 一、大型企业内部…

苹果相关网站和服务器状态

https://www.apple.com.cn/cn/support/systemstatus/

googlecloud谷歌云的初学体会(1)

googlecloud谷歌云入门&#xff08;1&#xff09; 一、纯小白自述二、云是个什么云三、装一个软件&#xff08;资源、服务&#xff09;四、服务器&#xff08;爷爷提供服务的电脑&#xff09;五、PGSQL的安装六、总结 一、纯小白自述 自己是个小白&#xff0c;仅仅懂得几句sql…

华为OD机试真题 Java 实现【寻找密码】【2023Q1 100分】,附详细解题思路

一、题目描述 小王在进行游戏大闯关,有一个关卡需要输入一个密码才能通过,密码获得的条件如下: 在一个密码本中,每一页都有一个由 26 个小写字母组成的若干位密码,从它的末尾开始依次去掉一位得到的新密码也在密码本中存在。 请输出符合要求的密码,如果由多个符合要求…

爬虫如何选择工具和编程语言

爬虫选择工具和编程语言需要根据具体的需求和技术水平来决定。以下是一些常用的工具和编程语言&#xff1a; 工具&#xff1a; Scrapy&#xff1a;一个基于Python的高级爬虫框架&#xff0c;可用于快速开发和部署爬虫。Beautiful Soup&#xff1a;一个Python库&#xff0c;用…

基于“三维六类”干扰分析模型进行FDD900干扰规避优化指导

1.概述 随着网络发展&#xff0c;鉴于900M覆盖上的优势&#xff0c;为增强深度覆盖及竞对提升&#xff0c;当前FDD 900M已在加快部署&#xff0c;但随之也带来了干扰问题。当前&#xff0c;干扰排查成为FDD 900M部署过程中大量存在的难题。由于干扰排查难度大&#xff0c;且排…

线程池和使用

tip: 作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#xff09; 文章目录 线程池的目的线程池的参…

360,可真小看你了:耍流氓耍到日本人身上,凌晨2点笑得我胃疼

天下苦流氓软件久矣 大厂的软件&#xff0c;都有点牛皮癣特性&#xff1a;捆绑安装广告推广&#xff0c;简直无所不用其极&#xff0c;身为用户着实无可奈何。 此处点名四大全家桶家族——360、鲁大师、金山毒霸、2345。 说来好笑&#xff0c;之前发的文章不是有关于金山的嘛…

Cefsharp-Winform-113.3.50(chromium5672)最新版体验兼容性测试

一、下载nupkg包(4个)提示:(不支持H264,支持MP3,WEBGL,WEBGL2等)支持H264最新版本109.*自行搜索 winform包地址(依赖包下载地址如下):NuGet Gallery | CefSharp.WinForms 113.3.50 https://globalcdn.nuget.org/packages/cefsharp.winforms.113.3.50.nupkg https://…

仓库拣货标签10代—电子料架

CK_Label_v10 无线电子标签拣货系统特点与效益 无线通信&#xff0c;极简快速部署 超低功耗&#xff0c;墨水屏显示 多彩指示灯&#xff0c;支持24V外接供电 按键及三色高亮LED指示灯指示 3位0.8寸高亮LED数码管显示 提升作业速度与品质 实现无纸化标准化作业 缩短操…

怎么快速掌握Python爬虫技术?

Python总的来说是一门比较容易入门的编程语言&#xff0c;因为它的语法简洁易懂&#xff0c;而且有很多优秀的教程和资源可供学习。相比其他编程语言&#xff0c;Python 的学习曲线较为平缓&#xff0c;初学者可以很快上手&#xff0c;但要想深入掌握 Python&#xff0c;还需要…

chatgpt赋能python:用Python实现ping命令:掌握网络连接的艺术

用Python实现ping命令&#xff1a;掌握网络连接的艺术 当我们需要测试网络连接的时候&#xff0c;ping命令是最经典的选择之一。然而&#xff0c;在一些情况下&#xff0c;使用命令行并不是很方便。那么&#xff0c;有没有可能用Python编写一个类似ping的功能呢&#xff1f; …

ISO21434 概念阶段网络安全(六)

目录 一、概述 二、目标 三、项目定义 3.1 输入 3.1.1 先决条件 3.1.2 进一步支持信息 3.2 要求和建议 3.3 输出 四、网络安全目标 4.1 输入 4.1.1 先决条件 4.1.2 进一步支持信息 4.2 要求和建议 4.3 输出 五、网络安全概念 5.1 输入 5.1.1 先决条件 5.1.2 …

phpMyAdmin连接MySQL,出现服务器拒绝连接解决方法

当你登录mysql的时候出现下面情况时 把config.inc.php删除就可以&#xff0c;或者修改config.inc.php里的 $cfg[Servers][$i][controluser] ; $cfg[Servers][$i][controlpass] ; 注释掉就会弹出来要求登陆。 例如我的文件位置是在C:\wamp\apps\phpmyadmin4.1.14&#xff…

dreamer-cms docker复现

dreamer-cms docker复现 前言一&#xff0c;赛题复现二&#xff0c;人生第一个jar包1 ubuntu本地复现&#xff08;1&#xff09;创建文件夹&#xff08;2&#xff09;解压资源&#xff08;3&#xff09;安装并导入数据库&#xff08;4&#xff09;使用idea自动化部署&#xff0…