【SpinalHDL快速入门】6.2、SpinalHDL语法之When/Switch/Mux

news2024/12/27 3:50:01

文章目录

    • 1.1、When
    • 1.2、Switch
      • 1.2.1、实例
      • 1.2.2、附加选项
    • 1.3、本地声明
    • 1.4、Mux
    • 1.5、位选择
      • 1.5.1、实例

1.1、When

与VHDL和Verilog一样,当满足指定条件时可以对信号进行有条件的赋值:

when(cond1) {
  // Execute when cond1 is true
}.elsewhen(cond2) {
  // Execute when (not cond1) and cond2
}.otherwise {
  // Execute when (not cond1) and (not cond2)
}

如果关键字otherwise与when条件的右括号}在同一行,则不需要加点。如下:

when(cond1) {
    // Execute when cond1 is true
} otherwise {
    // Execute when (not cond1) and (not cond2)
}

但是如果.otherwise在另一行,需要加一个点:

when(cond1) {
    // Execute when cond1 is true
}
.otherwise {
    // Execute when (not cond1) and (not cond2)
}

1.2、Switch

与VHDL和Verilog类似,当一个信号有定义值时,可以对其进行条件赋值:

switch(x) {
  is(value1) {
    // Execute when x === value1
  }
  is(value2) {
    // Execute when x === value2
  }
  default {
    // Execute if none of precedent conditions met
  }
}

可以通过用逗号将它们分开,从而得到一个子句,例如:is(value1, value2)。

1.2.1、实例

switch(aluop) {
  is(ALUOp.add) {
    immediate := instruction.immI.signExtend
  }
  is(ALUOp.slt) {
    immediate := instruction.immI.signExtend
  }
  is(ALUOp.sltu) {
    immediate := instruction.immI.signExtend
  }
  is(ALUOp.sll) {
    immediate := instruction.shamt
  }
  is(ALUOp.sra) {
    immediate := instruction.shamt
  }
}

等效:

switch(aluop) {
  is(ALUOp.add, ALUOp.slt, ALUOp.sltu) {
      immediate := instruction.immI.signExtend
  }
  is(ALUOp.sll, ALUOp.sra) {
      immediate := instruction.shamt
  }
}

1.2.2、附加选项

默认情况下,如果一个 switch 包含了一个 default 语句,并且该switch 的所有可能逻辑值已经被 is 语句覆盖,则 SpinalHDL 将生成“UNREACHABLE DEFAULT STATEMENT”错误。您可以通过指定 switch(myValue, coverUnreachable = true) { … } 来取消此错误报告。

switch(my2Bits, coverUnreachable = false) {
    is(0) { ... }
    is(1) { ... }
    is(2) { ... }
    is(3) { ... }
    default { ... } // This will be okay
}

此检查是基于逻辑值而非物理值进行的。例如,如果您有一个SpinalEnum(A,B,C)以独热码方式编码,SpinalHDL只会关心A、B、C这些值(“001”、“010”、“100”)。物理值如“000”、“011”、“101”、“110”和“111”将不被考虑。

默认情况下,如果给定的is语句多次提供相同的值,则SpinalHDL将生成“DUPLICATED ELEMENTS IN SWITCH IS(…) STATEMENT”的错误。

例如 is(42,42) { ... } 您可以通过指定switch(myValue, strict = true){ ... }来取消此错误报告。然后,SpinalHDL将负责删除重复值。

switch(value, strict = false) {
    is(0) { ... }
    is(1,1,1,1,1) { ... } // This will be okay
    is(2) { ... }
}

1.3、本地声明

可以在when/switch语句内定义新的信号:

val x, y = UInt(4 bits)
val a, b = UInt(4 bits)

when(cond) {
  val tmp = a + b
  x := tmp
  y := tmp + 1
} otherwise {
  x := 0
  y := 0
}

SpinalHDL检查在作用域内定义的信号只能在该作用域内被赋值。

1.4、Mux

如果您只需要带有Bool选择信号的 Mux,那么有两种等效的语法:

在这里插入图片描述

val cond = Bool()
val whenTrue, whenFalse = UInt(8 bits)
val muxOutput  = Mux(cond, whenTrue, whenFalse)
val muxOutput2 = cond ? whenTrue | whenFalse

1.5、位选择

一个位选择看起来像VHDL的when语法。

1.5.1、实例

val bitwiseSelect = UInt(2 bits)
val bitwiseResult = bitwiseSelect.mux(
  0 -> (io.src0 & io.src1),
  1 -> (io.src0 | io.src1),
  2 -> (io.src0 ^ io.src1),
  default -> (io.src0)
)

mux会检查是否覆盖了所有可能的值,以防止产生锁存器。如果已经覆盖了所有可能的值,则不应添加default 语句:

val bitwiseSelect = UInt(2 bits)
val bitwiseResult = bitwiseSelect.mux(
  0 -> (io.src0 & io.src1),
  1 -> (io.src0 | io.src1),
  2 -> (io.src0 ^ io.src1),
  3 -> (io.src0)
)

muxList(...)muxListDc(...)是备选的位选择器,它们将 tuples 或 mappings 序列作为输入。

在生成用例代码中,可以使用muxList直接替换mux,提供更易于使用的界面。它具有与mux相同的检查行为,要求完全覆盖并禁止在不需要时列出默认值

如果未覆盖的值不重要,则可以使用muxtListDc,并通过使用muxListDc将其保留未分配状态。如果需要,则会添加一个默认情况。如果仿真过程中遇到X,则此默认情况将生成X'smuxListDc(...)通常是通用代码的良好替代方案。

以下是将128位比特数分成32位比特数的示例:

在这里插入图片描述

val sel  = UInt(2 bits)
val data = Bits(128 bits)

// Dividing a wide Bits type into smaller chunks, using a mux:
val dataWord = sel.muxList(for (index <- 0 until 4) yield (index, data(index*32+32-1 downto index*32)))

// A shorter way to do the same thing:
val dataWord = data.subdivideIn(32 bits)(sel)

通过 muxListDc 从可配置宽度向量中选择位的示例:

case class Example(width: Int = 3) extends Component {
  // 2 bit wide for default width
  val sel = UInt(log2Up(count) bit)
  val data = Bits(width*8 bit)
  // no need to cover missing case 3 for default width
  val dataByte = sel.muxListDc(for(i <- 0 until count) yield (i, data(index*8, 8 bit)))
}

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

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

相关文章

直播问答功能(互动功能接收端JS-SDK)

功能概述 本模块主要用于展示问答模块。 初始化及销毁 在实例化该模块并进行使用之前&#xff0c;需要对SDK进行初始化配置&#xff0c;详细见参考文档。 在线文件引入方式 // script 标签引入&#xff0c;根据版本号引入JS版本。 <script src"https://websdk.vi…

【Maven】Maven入门,Java界的Anaconda!

1 Maven介绍 官方文档&#xff1a;Apache Maven 的本质是一个软件项目管理和理解工具。基于项目对象模型 (Project Object Model&#xff0c;POM) 的概念&#xff0c;Maven 可以从一条中心信息管理项目的构建、报告和文档。 就像Python和Anaconda的关系&#x1f92d; 可以帮助…

java设计模式(十三)解释器模式

目录 定义模式结构角色职责代码实现场景适用优缺点 定义 解释器模式&#xff08;Interpreter Pattern&#xff09; 提供了评估语言的语法或表达式的方式&#xff0c;它属于行为型模式。这种模式实现了一个表达式接口&#xff0c;该接口解释一个特定的上下文。这种模式被用在 S…

Linux 内存管理6——slab内存池的创建初始化过程

在上篇文章 中&#xff0c;笔者带大家从一个最简单的物理内存页开始&#xff0c;一步一步演进 slab cache 的架构&#xff0c;最终得到了一副 slab cache 完整的架构图&#xff1a; 在本文的内容中&#xff0c;笔者会带大家到内核源码实现中&#xff0c;来看一下 slab cache 在…

第三章:基本的SELECT语句

第三章&#xff1a;基本的SELECT语句 3.1&#xff1a;SQL概述 SQL背景知识 1946年&#xff0c;世界上第一台电脑诞生&#xff0c;如今&#xff0c;借由这台电脑发展起来的互联网已经自成江湖。在这几十年里&#xff0c;无数的技术、产业在这片江湖里沉浮&#xff0c;有的方兴未…

HTTP和HTTPS

目录 HTTP 告知服务器意图的HTTP方法 状态码告知从服务器端返回的请求结果 2XX 成功 3XX 重定向 4XX客户端错误 5XX服务器错误 使用Cookie的状态管理 HTTP 的缺点 HTTPS HTTP 当我们在网页浏览器的地址栏输入URL时&#xff0c;Web页面是如何呈现的吗&#xff1f; …

Linux 面试题-(腾讯,百度,美团,滴滴)

Linux 面试题-(腾讯,百度,美团,滴滴) 分析日志t.log(访问量)&#xff0c;将各个ip 地址截取&#xff0c;并统计出现次数,并按从大到小排序(腾讯) http://192.168.200.10/index1.html http://192.168.200.10/index2.html http://192.168.200.20/index1.html http://192.168.20…

Python 类和对象

一、什么是类和对象 Python和Java一样&#xff0c;都是面向对象的编程语言&#xff0c;面向对象编程其实是一种封装代码的方法&#xff0c;把一些公共的属性或者方法封装到一个类中&#xff0c;然后再通过这个类可以创建多个对象&#xff0c;最后使用这些对象去调用这些封装起…

【教程】两种免费更新iOS17测试版的方法

苹果iOS17系统已经发布&#xff0c;目前所有用户都可以免费注册成为开发者&#xff0c;升级iOS17开发者测试版 注意&#xff0c;现在不是通过描述文件来更新系统了&#xff0c;给大家带来两种更新升级方法&#xff0c;看下文操作 方法一 苹果官网注册 按照下图发消息“更新” …

java设计模式(十六)命令模式

目录 定义模式结构角色职责代码实现适用场景优缺点 定义 命令模式&#xff08;Command Pattern&#xff09; 又叫动作模式或事务模式。指的是将一个请求封装成一个对象&#xff0c;使发出请求的责任和执行请求的责任分割开&#xff0c;然后可以使用不同的请求把客户端参数化&a…

数据库篇——锁

目录 引文A——活锁 引文B——死锁 1、表锁 1.1 关于 S 锁 1.2 关于 X 锁 1.3 关于意向锁 2、行锁 2.1 关于记录锁 2.2 关于间隙锁 2.3 关于临键锁 2.4 关于插入意向锁 3、页锁 我们在谈表锁、行锁以及页锁之前&#xff0c;先聊一聊 活锁&#x1f512;与 死锁&#x1f512;的…

RabbitMQ安装、端口修改、简单的角色介绍

前提 本文介绍RabbitMQ安装的环境是CentOS7版本的Linux云服务器。 官网&#xff1a;https://www.rabbitmq.com/ RabbitMQ的安装 由于RabbitMQ是使用Erlang语言开发的&#xff0c;所以我们在安装RabbitMQ之前需要在服务器中安装Erlang语言的环境。在Linux中执行下面命令&…

Day_43插入排序

目录 一. 关于插入排序 1. 排序的定义 2. 插入排序 二. 插入排序的实现过程 三. 代码实现过程 1. 插入排序核心代码 四. 代码展示 五. 数据测试 六. 总结 一. 关于插入排序 1. 排序的定义 排序&#xff0c;就是重新排列表中的元素&#xff0c;使表中的元素满足按关键字有序…

AIGC与AidLux互联应用——AidLux端AIGC测评(二)PC端云端Stable Diffusion模型推理应用(文生图,图生图)

在这里插入图片描述 Stable Diffusion模型搭建首先下载diffusers&#xff0c;然后安装&#xff0c;命令如下&#xff1a; git clone https://github.com/huggingface/diffusers.git pip install diffusers cd diffusers pip install . ubuntu和win系统下都可以 文生图&#x…

React Hooks 组件化开发(常用)

本文章视频地址&#xff1a;视频链接 一、React组件分类 二、Hook函数概览 Hook 是 React 16.8 的新增特性&#xff01;并且只能运用到函数组件中&#xff01; 1.useState 作用&#xff1a;在函数组件中使用状态&#xff0c;修改状态值可让函数组件更新&#xff0c;类似于类…

鸿蒙初识

学习官网&#xff1a;https://www.harmonyos.com/cn/develop 准备 注册&#xff0c;安装软件(node:12, DevEco Studio)&#xff1a; 在实际开发中node最好使用nvm进行版本管理。 https://developer.harmonyos.com/cn/docs/documentation/doc-guides/software_install-00000010…

ChatGPT-Plugins-Searchable

ChatGPT Plus 用户应该都知道Plus已经开放了插件功能&#xff0c;但是在插件商店里存在一个较大的问题插件数量超过100款&#xff0c;却没有便捷的搜索功能。 而我们在查找一款插件时&#xff0c;需要从插件商店的第一页点击到最后一页一个个找&#xff0c;显然这非常的麻烦。 …

驱动开发--驱动模块

目录 1.驱动模块 hello.c Makefile 2.内核中的打印函数&#xff08;编写第一个驱动程序&#xff09; Source Insight 使用&#xff1a; 3.打印函数编写 分析 4、驱动的多文件编译 5、模块传递参数 6、安装好驱动之后如何传参&#xff1f; 7、字符设备驱动 8、字符设…

chatgpt赋能python:Python如何突破VIP限制

Python如何突破VIP限制 在这个数字内容时代&#xff0c;我们经常使用各种网站和应用程序来获取视频、音乐、软件等数字资源。但是&#xff0c;某些资源可能受到VIP限制&#xff0c;这意味着我们需要付费才能获得完整的访问权限。但是&#xff0c;如果你了解Python编程&#xf…

Agile | 聊聊敏捷开发

什么是敏捷开发 敏捷开发是一种迭代和增量的项目管理方法&#xff0c;优先考虑适应性、协作和快速交付&#xff0c;而不是遵循严格的计划[0]。它是在《敏捷软件开发宣言》和《12项原则》中表达的一组价值观和原则[1]。敏捷是基于这些价值观和原则的一组框架和实践的总称。敏捷…