chisel的命名高级用法

2023-11-18

从历史上看,Chisel 在可靠地捕获信号名称方面遇到了麻烦。造成这种情况的原因是
(1)主要依靠反射来查找名称
(2)使用@chiselName行为不可靠的宏。

Chisel 3.4 引入了一个自定义的 Scala 编译器插件,它可以在声明信号名称时实现可靠和自动捕获信号名称。此外,此版本还大量使用了新的前缀 API,它可以更稳定地命名从函数调用以编程方式生成的信号。

本文档解释了现在在 Chisel 中如何命名信号和模块名称。有关如何解决系统名称稳定性问题的手册示例,请参阅命名手册

编译器插件

// Imports used by the following examples
import chisel3._
import chisel3.experimental.{prefix, noPrefix}
import chisel3.stage.ChiselStage

随着 Chisel 3.4 的发布,用户应该在他们的 build.sbt 设置中添加以下行以获得改进的命名:

// chiselVersion is the String version (eg. "3.4.0")
addCompilerPlugin("edu.berkeley.cs" % "chisel3-plugin" % chiselVersion cross CrossVersion.full)

这个插件将在 Scala 编译器的 ‘typer’ 阶段之后运行。它查找任何形式 为val x = yx类型为chisel3.Datachisel3.MemBase或的用户代码chisel3.experimental.BaseModule。对于符合此标准的每一行,它都会重写该行。在以下示例中,注释行是上面的行被重写的内容。

如果该行在捆绑声明中或者是模块实例化,则将其重写以将右侧替换为对 的调用autoNameRecursively,该调用命名信号/模块。

class MyBundle extends Bundle {
  val foo = Input(UInt(3.W))
  // val foo = autoNameRecursively("foo")(Input(UInt(3.W)))
}
class Example1 extends Module {
  val io = IO(new MyBundle())
  // val io = autoNameRecursively("io")(IO(new MyBundle()))
}
module Example1(
  input        clock,
  input        reset,
  input  [2:0] io_foo
);
endmodule

否则,它会被重写以包含名称作为在执行 val 声明右侧时生成的任何信号的前缀:

class Example2 extends Module {
  val in = IO(Input(UInt(2.W)))
  // val in = autoNameRecursively("in")(prefix("in")(IO(Input(UInt(2.W)))))

  val out = IO(Output(UInt(2.W)))
  // val out = autoNameRecursively("out")(prefix("out")(IO(Output(UInt(2.W)))))

  def inXin() = in * in

  val add = 3.U + inXin()
  // val add = autoNameRecursively("add")(prefix("add")(3.U + inXin()))
  // Note that the intermediate result of the multiplication is prefixed with `add`

  out := add + 1.U
}
module Example2(
  input        clock,
  input        reset,
  input  [1:0] in,
  output [1:0] out
);
  wire [3:0] _add_T = in * in; // @[naming.md 48:20]
  wire [3:0] add = 4'h3 + _add_T; // @[naming.md 50:17]
  wire [3:0] _out_T_1 = add + 4'h1; // @[naming.md 54:14]
  assign out = _out_T_1[1:0]; // @[naming.md 54:7]
endmodule

请注意,如果硬件类型嵌套在Option或 的子类型中,则命名也有效Iterable

class Example3 extends Module {
  val in = IO(Input(UInt(2.W)))
  // val in = autoNameRecursively("in")(prefix("in")(IO(Input(UInt(2.W)))))

  val out = IO(Output(UInt()))
  // val out = autoNameRecursively("out")(prefix("out")(IO(Output(UInt(2.W)))))

  def inXin() = in * in

  val opt = Some(3.U + inXin())
  // Note that the intermediate result of the inXin() is prefixed with `opt`:
  // val opt = autoNameRecursively("opt")(prefix("opt")(Some(3.U + inXin())))

  out := opt.get + 1.U
}
module Example3(
  input        clock,
  input        reset,
  input  [1:0] in,
  output [3:0] out
);
  wire [3:0] _opt_T = in * in; // @[naming.md 74:20]
  wire [3:0] opt = 4'h3 + _opt_T; // @[naming.md 76:22]
  assign out = opt + 4'h1; // @[naming.md 80:18]
endmodule

还有一个轻微的变体 ( autoNameRecursivelyProduct) 用于使用 unapply 提供的名称命名硬件:

class UnapplyExample extends Module {
  def mkIO() = (IO(Input(UInt(2.W))), IO(Output(UInt())))
  val (in, out) = mkIO()
  // val (in, out) = autoNameRecursivelyProduct(List(Some("in"), Some("out")))(mkIO())

  out := in
}
module UnapplyExample(
  input        clock,
  input        reset,
  input  [1:0] in,
  output [1:0] out
);
  assign out = in; // @[naming.md 98:7]
endmodule

请注意,编译器插件在这些情况下不会插入前缀,因为前缀应该是什么是不明确的。鼓励需要前缀的用户提供如下所述的前缀。

前缀

如上所示,编译器插件会自动尝试为您的一些信号添加前缀。但是,您作为用户也可以添加自己的前缀。这尤其适用于 ECO 类型的修复,您需要向模块添加一些逻辑但又不想影响模块中的其他名称。

在以下示例中,我们在附加逻辑前面加上“ECO”,其中Example4是 pre-ECO 和Example5post-ECO:

class Example4 extends Module {
  val in = IO(Input(UInt(2.W)))
  val out = IO(Output(UInt()))

  val add = in + in + in

  out := add + 1.U
}

class Example5 extends Module {
  val in = IO(Input(UInt(2.W)))
  val out = IO(Output(UInt()))

  val add = in + in + in

  out := prefix("ECO") { add + 1.U + in }
}
module Example4(
  input        clock,
  input        reset,
  input  [1:0] in,
  output [1:0] out
);
  wire [1:0] _add_T_1 = in + in; // @[naming.md 115:16]
  wire [1:0] add = _add_T_1 + in; // @[naming.md 115:21]
  assign out = add + 2'h1; // @[naming.md 117:14]
endmodule
module Example5(
  input        clock,
  input        reset,
  input  [1:0] in,
  output [1:0] out
);
  wire [1:0] _add_T_1 = in + in; // @[naming.md 125:16]
  wire [1:0] add = _add_T_1 + in; // @[naming.md 125:21]
  wire [1:0] _out_ECO_T_1 = add + 2'h1; // @[naming.md 127:30]
  assign out = _out_ECO_T_1 + in; // @[naming.md 127:36]
endmodule

另请注意,前缀是相互附加的(包括编译器插件生成的前缀):

class Example6 extends Module {
  val in = IO(Input(UInt(2.W)))
  val out = IO(Output(UInt()))

  val add = prefix("foo") { in + in + in }

  out := add
}
module Example6(
  input        clock,
  input        reset,
  input  [1:0] in,
  output [1:0] out
);
  wire [1:0] _add_foo_T_1 = in + in; // @[naming.md 147:32]
  assign out = _add_foo_T_1 + in; // @[naming.md 147:37]
endmodule

有时您可能想要禁用前缀。如果您正在编写库函数并且不想要前缀行为,则可能会发生这种情况。在这种情况下,您可以使用noPrefix对象:

class Example7 extends Module {
  val in = IO(Input(UInt(2.W)))
  val out = IO(Output(UInt()))

  val add = noPrefix { in + in + in }

  out := add
}
module Example7(
  input        clock,
  input        reset,
  input  [1:0] in,
  output [1:0] out
);
  wire [1:0] _T_1 = in + in; // @[naming.md 166:27]
  assign out = _T_1 + in; // @[naming.md 166:32]
endmodule

建议信号的名称(或模块的实例名称)

如果要指定信号的名称,可以随时使用.suggestNameAPI。请注意,建议的名称仍将作为前缀(包括插件)。您始终可以使用该noPrefix对象来剥离它。

class Example8 extends Module {
  val in = IO(Input(UInt(2.W)))
  val out = IO(Output(UInt()))

  val add = (in + (in + in).suggestName("foo"))

  out := add
}
module Example8(
  input        clock,
  input        reset,
  input  [1:0] in,
  output [1:0] out
);
  wire [1:0] add_foo = in + in; // @[naming.md 185:23]
  assign out = in + add_foo; // @[naming.md 185:17]
endmodule

设置模块名称

如果要指定模块的名称(而不是模块的实例名称),您始终可以覆盖该desiredName 值。请注意,您可以通过模块的参数参数化名称。这是使您的模块名称更稳定的好方法,强烈建议您这样做。

class Example9(width: Int) extends Module {
  override val desiredName = s"EXAMPLE9WITHWIDTH$width"
  val in = IO(Input(UInt(width.W)))
  val out = IO(Output(UInt()))

  val add = (in + (in + in).suggestName("foo"))

  out := add
}
module EXAMPLE9WITHWIDTH8(
  input        clock,
  input        reset,
  input  [7:0] in,
  output [7:0] out
);
  wire [7:0] add_foo = in + in; // @[naming.md 205:23]
  assign out = in + add_foo; // @[naming.md 205:17]
endmodule
module EXAMPLE9WITHWIDTH1(
  input   clock,
  input   reset,
  input   in,
  output  out
);
  wire  add_foo = in + in; // @[naming.md 205:23]
  assign out = in + add_foo; // @[naming.md 205:17]
endmodule

反射命名

无论编译器插件是否启用,在 Chisel 构造一个模块后,它都会尝试命名该模块的所有成员。这将命名作为模块类的字段的所有 val,但不会命名嵌套函数或范围中的任何 val。

如果插件成功命名一个信号,反射命名将什么都不做。我们计划在未来的 Chisel 版本中弃用所有反射命名,但保留它以允许插件命名是可选的(但推荐)。

例如,以下模块中的信号在嵌套范围内;插件成功命名它们,但反射命名不能:

class Example10 extends Module {
  {
    val in = IO(Input(UInt(3.W)))
    val out = IO(Output(UInt()))

    val add = in + in

    out := add
  }
}

@chiselName

不再推荐使用此宏,因为它的功能完全被编译器插件取代。随意从您的chisel设计中删除!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

chisel的命名高级用法 的相关文章

  • chisel快速入门(三)

    前一篇见此 chisel快速入门 二 沧海一升的博客 CSDN博客简单介绍了chisel 使硬件开发者能快速上手chisel https blog csdn net qq 21842097 article details 121418806
  • DANA简介

    Dynamically Allocated Neural Network DANA Accelerator https github com bu icsg dana spinalHDL Doc https spinalhdl github
  • Chisel 教程翻译 之 第三章 构建过程和测试 of 《Digital Design with Chisel》

    3 Build Process and Testing 21 3 1 Building your Project with sbt 21 3 1 1 Source Organization 21 3 1 2 Running sbt 23 3
  • 吃透Chisel语言.15.Chisel模块详解(二)——Chisel模块嵌套和ALU实现

    Chisel模块详解 二 Chisel模块嵌套和ALU实现 稍微复杂点的硬件设计就需要用嵌套的模块层级来构建了 上一篇文章中实现的计数器其实就是个例子 计数器内部嵌套了一个寄存器 一个Mux和一个加法器 这一篇文章就仔细讲解模块之间是怎么连
  • 【环境配置】基于Docker配置Chisel-Bootcamp环境

    文章目录 Chisel是什么 Chisel Bootcamp是什么 基于Docker配置Chisel Bootcamp 官网下载Docker安装包 Docker换源 启动Bootcamp镜像 常用docker命令 可能产生的问题 Chise
  • chisel线网(wire)和寄存器(reg)详解(更新)

    主体内容摘自 https blog csdn net qq 34291505 article details 87714172 在Verilog里 模块内部主要有 线网 wire 和 四态变量 reg 两种硬件类型 它们用于描述数字电路的组
  • Chisel入门(三)------Chisel的基本语法2

    概述 继续介绍Chisel的基本语法 3 组件 3 1 Chisel中的组件是模块 Chisel中的每个模块都拓展了class 并包含了接口的io字段 接口是由封装为IO 的Bundle所定义的 Bundle包含的字段表示模块的输入输出端口
  • chisel可选值/模式匹配实例

    一 scala可选值语法 可选值就是类型为Option T 的一个值 其中 Option是标准库里的一个密封抽象类 T可以是任意的类型 例如标准类型或自定义的类 并且T是协变的 简单来说 就是如果类型T是类型U的超类 那么Option T
  • Chisel 手册(中文part1)

    Chisel 手册 part1 作者 Jonathan Bachrach Huy Vo Krste Asanovi EECS Department UC Berkeley 译者 智能物联 CSDN 1 简介 本文为Chisel手册 Cons
  • unresolved dependency: edu.berkeley.cs#firrtl_2.12;1.2-SNAPSHOT: not found

    Machine Environment SBT sbt 1 1 1 Scala scala 2 12 4 IntelliJ IntelliJ IDEA 2018 2 5 Community Edition Build IC 182 4892
  • 第十七章 Chisel基础——数据类型

    一 Chisel的常见问题 在学习Chisel前 应该熟悉一些常见问题 这些问题在编写Chisel的任何时候都应该牢记 Chisel是寄宿在Scala里的语言 所以它本质还是Scala 为了从Chisel转变成Verilog 语言开发人员开
  • chisel-book-chinese

    chisel book chinese 蓝奏云地址 https wwu lanzoue com isdim08x8x5i
  • 吃透Chisel语言.23.Chisel时序电路(三)——Chisel移位寄存器(Shift Register)详解

    Chisel时序电路 三 Chisel移位寄存器 Shift Register 详解 上一篇文章介绍了Chisel计数器以及一些高级用法 内容很多 学下来肯定收获也会很多 除了计数器以外 还有一种寄存器的应用十分广泛 那就是移位寄存器 这一
  • 第二章 Scala入门——让你的代码跑起来

    一 Scala的安装方法 要使用Scala 首先需要保证已经安装好了Java 8 对于Linux操作系统 Java 8已经默认安装了 而使用Windows操作系统的用户 则需要在Java官网下载安装包进行安装 请在CMD PowerShel
  • chisel的命名高级用法

    从历史上看 Chisel 在可靠地捕获信号名称方面遇到了麻烦 造成这种情况的原因是 1 主要依靠反射来查找名称 2 使用 chiselName行为不可靠的宏 Chisel 3 4 引入了一个自定义的 Scala 编译器插件 它可以在声明信号
  • 第二十章 Chisel基础——生成Verilog与基本测试

    经过前三章的内容 读者已经了解了如何使用Chisel构建一个基本的模块 本章的内容就是在此基础上 把一个Chisel模块编译成Verilog代码 并进一步使用Verilator做一些简单的测试 一 生成Verilog 前面介绍Scala的内
  • 凿子3.功能模块Mux4

    我正在按照文档学习 Chisel在 Github 上 https github com ucb bar chisel3 wiki Short 20Users 20Guide 20to 20Chisel 到目前为止 一切都完美无缺 但我还是卡
  • 测试工具中的 Chisel 运行时错误

    This Chisel https chisel eecs berkeley edu 代码工作正常 chiselMainTest Array String backend c genHarness gt Module new Cache n
  • Chisel 中的矩阵运算

    Chisel是否支持加法 乘法 转置等矩阵运算 如果没有 实施它们的最佳方法是什么 向量怎么样 Chisel 不支持矩阵运算 它是一种用于编写实现此类操作的硬件生成器的 DSL 有关专用数学硬件生成器的示例 请参阅 Hwacha 硬件矢量单
  • Chisel3:对 Vector IO 的多位切片的部分分配

    可以对向量 IO 进行部分赋值 如下所示 import chisel3 class example 1 extends Module val io IO new Bundle val in1 Input Vec 4 Bool val out

随机推荐

  • Java机试题

    整理自Java经典编程50题 面试笔试机试 腾讯云开发者社区 腾讯云 1 回文数 public static boolean palindrom Integer integer String str1 String valueOf inte
  • Kibana在Centos上开机启动

    1 需要下载kibana 去官网下 2 解压到自己指定的目录下 我是放到了 usr local下 3 执行 vi usr lib systemd system kibana service 插入下面内容 Unit Description k
  • /dev/zero和/dev/null的区别

    可以通过使用dd if dev zero of archive test dbf bs 8k count 1000000 来测试磁盘的纯写入性能 使用dd if file of dev null 来测试磁盘的纯读取性能 使用dd if fi
  • 紫光同创 FPGA 开发跳坑指南(三)—— 联合 Modelsim 仿真

    Modelsim 是 FPGA 开发中重要的 EDA 设计仿真工具 主要用于验证数字电路设计是否正确 紫光 Pango Design Suite 开发套件支持联合 Modelsim 仿真 这里作简要的介绍 添加仿真库 方法一 打开 Pang
  • 实现mint操作(参考pancake)

    区块链发展越来越好 nft已经火了很久 今天写一下如何用js web3js 调用合约 实现mint nft 简单的调用 引入一些依赖 根据需要 有一些是其他功能的 import useActiveWeb3React from web3 ho
  • mysql read loop_mysql数据库游标的使用

    Mysql在5 0版本支持在存储过程中使用游标 游标声明必须出现在处理程序声明变量和条件的声明后 游标的使用如下 CREATE PROCEDURE curdemo BEGIN DECLARE done INT DEFAULT FALSE D
  • hive数据恢复

    truncate删除hive的表能恢复吗 0 jdbc hive2 localhost 10014 default gt create table test2 id int name string row format delimited
  • 在SpringBoot中利用nacos对数据源进行动态刷新

    一 重写DruidAbstractDataSource类 这里为什么要重写这个类 因为DruidDataSource数据源在初始化后 就不允许再重新设置数据库的url和userName 注意 类所在的包名必须为 com alibaba dr
  • MySQL 触发器

    文章目录 1 简介 2 行级与语句级触发器 3 触发时机 4 触发器优缺点 5 创建触发器 语法 示例 6 查看触发器 7 删除触发器 参考文献 1 简介 触发器 Trigger 是与表关联的命名数据库对象 当表发生特定事件时激活 触发器的
  • 概念解析

    注1 本文系 概念解析 系列之一 致力于简洁清晰地解释 辨析复杂而专业的概念 本次辨析的概念是 合成孔径雷达中运动补偿和自聚焦的联系与差别 概念解析 合成孔径雷达运动补偿与自聚焦的关系研究 基于二维空变运动补偿的机动平台大斜视SAR稀疏自聚
  • java.lang.ClassCastException: java.lang.Long cannot be cast to java.util.Date at org.hibernate.type.TimestampType.deepCopyNotNul

    在配置一对多的时候 OneToMany mappedBy recevier cascade CascadeType REMOVE OneToMany mappedBy sender cascade CascadeType REMOVE Ma
  • 日常学习--练手

    1 page source爬取页面源码 from selenium import webdriver import re driver webdriver Chrome driver get https www cnblogs com ca
  • mysql中如何取得分组中最大值的数据?全网最有效的方法

    大家都知道 MySQL有分组查询子句 group by 面试官就问你了 不是让你找到一个表中最大的值 而是让你找到最大值的整行数据 这个时候简单的分组是搞不定了 需要用到 inner join 子句 先说下inner join 子句的作用
  • 【MyBatis】Mybatis使用SqlSessionFactory加载xml文件

    1 概述 MyBatis框架主要是围绕着SqlSessionFactory这个类进行的 这个的创建过程如下 定义一个Configuration对象 其中包含数据源 事务 mapper文件资源以及影响数据库行为属性设置settings 通过配
  • python read函数返回值_python read()方法定义及使用(实例解析)

    今天这篇文章我们来了解一下pythonread方法 不知道没什么关系 因为今天讲的就是python之中的read 方法 以及知晓read是什么意思 所以今天我们在今天的文章之中来了解一下吧 概述 read 方法用于从文件读取指定的字节数 如
  • 数据结构——非线性结构(图)

    文章目录 一 非线性结构的概述 二 图的基本概念 1 定义 2 无向图 有向图 2 1 无向图 2 2 有向图 2 3 简单图 2 4 多重图 3 顶点的度 出度 入度 3 1 对于无向图 3 2 对于有向图 4 边的权 带权图 网 5 点
  • React + Umi + Dva + Antd 简述 及创建项目过程简述

    React 你的第一个组件 React React是前端三大主流框架之一 你可以在React里传递多种类型的参数 如声明代码 帮助你渲染出UI 也可以是静态的HTML DOM元素 也可以传递动态变量 甚至是可交互的应用组件 安装react框
  • 学校智慧校园平台管理系统小程序开发制作

    学校智慧校园平台管理系统小程序开发制作 智慧校园服务的蓝海市场正在等待开发的状态中 而小程序恰好是一体化校园平台抢占这个市场的最佳方式 学校校园平台小程序提供在校大学生和老师校园智慧服务的小程序应用 主要功能有 提供查看考勤 成绩 课表 校
  • python树莓派 是什么_想用什么域名就用什么域名,用树莓派搭建个局域网DNS服务器。...

    局域网内的设备越来越多 用ip访问就比较麻烦了 另一方面我们用的公网的dns服务器可能会被投毒 这时候搭建一个本地的DNS服务器 想用什么域名就用什么域名 岂不是很舒服 拿起我们的树莓派 说干就干 准备材料 1 树莓派 这里是安装了64位操
  • chisel的命名高级用法

    从历史上看 Chisel 在可靠地捕获信号名称方面遇到了麻烦 造成这种情况的原因是 1 主要依靠反射来查找名称 2 使用 chiselName行为不可靠的宏 Chisel 3 4 引入了一个自定义的 Scala 编译器插件 它可以在声明信号