第二十五章 Chisel进阶——隐式参数的应用

2023-10-30

用Chisel编写的CPU,比如Rocket-Chip、RISCV-Mini等,都有一个特点,就是可以用一个配置文件来裁剪电路。这利用了Scala的模式匹配、样例类、偏函数、可选值、隐式定义等语法。本章内容就是来为读者详细解释它的工作机制。

一、相关定义

要理解隐式参数是如何配置电路的,应该先了解与配置相关的定义。在阅读代码之前,为了能快速读懂、深入理解,读者最好复习一下模式匹配和隐式定义两章的内容。

下面是来自于开源处理器RISCV-Mini的代码:

// Config.scala
// See LICENSE.SiFive for license details.

package freechips.rocketchip.config

abstract class Field[T] private (val default: Option[T])
{
  def this() = this(None)
  def this(default: T) = this(Some(default))
}

abstract class View {
  final def apply[T](pname: Field[T]): T = apply(pname, this)
  final def apply[T](pname: Field[T], site: View): T = {
    val out = find(pname, site)
    require (out.isDefined, s"Key ${pname} is not defined in Parameters")
    out.get
  }

  final def lift[T](pname: Field[T]): Option[T] = lift(pname, this)
  final def lift[T](pname: Field[T], site: View): Option[T] = find(pname, site).map(_.asInstanceOf[T])

  protected[config] def find[T](pname: Field[T], site: View): Option[T]
}

abstract class Parameters extends View {
  final def ++ (x: Parameters): Parameters =
    new ChainParameters(this, x)

  final def alter(f: (View, View, View) => PartialFunction[Any,Any]): Parameters =
    Parameters(f) ++ this

  final def alterPartial(f: PartialFunction[Any,Any]): Parameters =
    Parameters((_,_,_) => f) ++ this

  final def alterMap(m: Map[Any,Any]): Parameters =
    new MapParameters(m) ++ this

  protected[config] def chain[T](site: View, tail: View, pname: Field[T]): Option[T]
  protected[config] def find[T](pname: Field[T], site: View) = chain(site, new TerminalView, pname)
}

object Parameters {
  def empty: Parameters = new EmptyParameters
  def apply(f: (View, View, View) => PartialFunction[Any,Any]): Parameters = new PartialParameters(f)
}

class Config(p: Parameters) extends Parameters {
  def this(f: (View, View, View) => PartialFunction[Any,Any]) = this(Parameters(f))

  protected[config] def chain[T](site: View, tail: View, pname: Field[T]) = p.chain(site, tail, pname)
  override def toString = this.getClass.getSimpleName
  def toInstance = this
}

// Internal implementation:

private class TerminalView extends View {
  def find[T](pname: Field[T], site: View): Option[T] = pname.default
}

private class ChainView(head: Parameters, tail: View) extends View {
  def find[T](pname: Field[T], site: View) = head.chain(site, tail, pname)
}

private class ChainParameters(x: Parameters, y: Parameters) extends Parameters {
  def chain[T](site: View, tail: View, pname: Field[T]) = x.chain(site, new ChainView(y, tail), pname)
}

private class EmptyParameters extends Parameters {
  def chain[T](site: View, tail: View, pname: Field[T]) = tail.find(pname, site)
}

private class PartialParameters(f: (View, View, View) => PartialFunction[Any,Any]) extends Parameters {
  protected[config] def chain[T](site: View, tail: View, pname: Field[T]) = {
    val g = f(site, this, tail)
    if (g.isDefinedAt(pname)) Some(g.apply(pname).asInstanceOf[T]) else tail.find(pname, site)
  }
}

private class MapParameters(map: Map[Any, Any]) extends Parameters {
  protected[config] def chain[T](site: View, tail: View, pname: Field[T]) = {
    val g = map.get(pname)
    if (g.isDefined) Some(g.get.asInstanceOf[T]) else tail.find(pname, site)
  }
}

二、Field[T]类

位置:6-10行

抽象类Field[T]是一个类型构造器,它需要根据类型参数T来生成不同的类型。而T取决于传入的参数——可选值default:Option[T]的类型。例如,如果传入一个Some(10),那么所

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

第二十五章 Chisel进阶——隐式参数的应用 的相关文章

  • 使用 Shapeless 记录组合任意数量的状态更改函数

    我正在尝试移植combineReducers从 Redux 到 Scala 这个想法是每个函数控制它的一小部分状态并且combineReducers创建一个控制整个状态的函数 我无法找出应该像这样工作的函数所需的签名 sealed trai
  • Scala:类型参数中的问号

    我试图理解以下代码 来自 Scalaz 库 def kleisliIdApplicative R Applicative Kleisli Id R 我假设一种形式T P0 是一个带有参数的类型构造函数 但是我无法找到解释类型参数中问号用法的
  • 如何在 Scala 2.11 中查找封闭源文件的名称

    在编译时 如何在 scala 2 11 中检索当前源文件 编写代码的位置 的名称 这是一种实际有效的方法 val srcFile new Exception getStackTrace head getFileName println sr
  • Scala 和 Python 的通行证

    我想知道 是否有相当于 python 的 pass 表达式 这个想法是编写没有实现的方法签名 并编译它们只是为了对某些库原型的这些签名进行类型检查 我能够使用以下方法模拟这种行为 def pass A A throw new Excepti
  • 在spark-kafka中使用schema将ConsumerRecord值转换为Dataframe

    我正在使用 Spark 2 0 2 和 Kafka 0 11 0 并且 我正在尝试在火花流中使用来自卡夫卡的消息 以下是代码 val topics notes val kafkaParams Map String Object bootst
  • 使用 Akka 1.3 的 actor 时,我需要注意生产者-消费者速率匹配吗?

    使用 Akka 1 3 时 我是否需要担心当生成消息的 Actor 生成消息的速度比使用消息的 Actor 的处理速度快时会发生什么 如果没有任何机制 在长时间运行的进程中 队列大小将增大以消耗所有可用内存 The doc http doc
  • 火花内存不足

    我有一个文件夹 里面有 150 G 的 txt 文件 大约 700 个文件 平均每个 200 MB 我使用 scala 来处理文件并最终计算一些汇总统计数据 我认为有两种可能的方法可以做到这一点 手动循环所有文件 对每个文件进行计算并最终合
  • 如何通过删除 Scala 中的一个元素来从列表中获取所有可能的子列表?

    我有一个清单List 1 2 3 4 并希望通过删除一个元素来获得所有子列表 List 2 3 4 List 1 3 4 List 1 2 4 List 1 2 3 做到这一点最简单的方法是什么 如果你的意思是 离开每个position在列
  • HDFS:使用 Java / Scala API 移动多个文件

    我需要使用 Java Scala 程序移动 HDFS 中对应于给定正则表达式的多个文件 例如 我必须移动所有名称为 xml从文件夹a到文件夹b 使用 shell 命令我可以使用以下命令 bin hdfs dfs mv a xml b 我可以
  • InvalidRequestException(为什么:empid 如果包含 Equal,则不能被多个关系限制)

    这是关于我从 Apache Spark 查询 Cassandra 时遇到的问题 Spark 的正常查询工作正常 没有任何问题 但是当我使用关键条件进行查询时 出现以下错误 最初 我尝试查询复合键列族 它也给出了与下面相同的问题 由以下原因引
  • 在 Scala 中扩展函数1

    在几个例子中 我看到一个对象或一个类扩展Function1 E g object Cash extends CashProduct gt String in Scala 的隐藏功能 https stackoverflow com quest
  • 函数式 Scala 中的选择排序

    我正在学习 Scala 编程 并编写了选择排序算法的快速实现 然而 由于我对函数式编程还不太了解 所以在转换为更 Scala 风格时遇到了困难 对于 Scala 程序员来说 如何使用 Lists 和 vals 来做到这一点 而不是回到我的命
  • 使用 Scala 宏或反射实例化类

    在我的 scala 代码中 我希望能够实例化一个新类 例如 假设我有以下代码 class Foo def foo 10 trait Bar val bar 20 理想情况下 我希望能够做类似的事情 def newInstance A lt
  • 伴随对象中的方法编译成scala中的静态方法?

    看起来 scala 将伴生对象中的方法编译为静态方法 这使得从 java 代码中调用它们变得更容易一些 例如 您可以编写 CompanionObject method 而不是 CompanionObject MODULE method 然而
  • 使用 Reader Monad 进行依赖注入

    我最近看到了谈话极其简单的依赖注入 http www youtube com watch v ZasXwtTRkio and 无需体操的依赖注入 http vimeo com 44502327关于 Monads 的 DI 并留下了深刻的印象
  • Spark 对 RDD 中按值排序

    我有一个火花对 RDD 键 计数 如下 Array String Int Array a 1 b 2 c 1 d 3 使用spark scala API如何获取按值排序的新RDD对 所需结果 Array d 3 b 2 a 1 c 1 这应
  • 解释一下 Scala 中 Y 组合器的实现?

    这是 Y 组合器在 Scala 中的实现 scala gt def Y T func T gt T gt T gt T T gt T func Y func T Y T func T gt T gt T gt T T gt T scala
  • Play 框架:异步与同步性能

    我有以下代码 def sync Action val t0 System nanoTime Thread sleep 100 val t1 System nanoTime Ok Elapsed time t1 t0 1000000 0 ms
  • Scala:var List 与 val MutableList

    在 Odersky 等人的 Scala 书中 他们说使用列表 我还没有从头到尾读过这本书 但所有的例子似乎都使用了 val List 据我了解 还鼓励人们使用 vals 而不是 vars 但在大多数应用程序中 使用 var List 或 v
  • 由于 UTFDataFormatException 导致 Spark 中的任务无法序列化:编码字符串太长

    我在 Yarn 上运行 Spark 应用程序时遇到一些问题 我有非常广泛的集成测试 运行时没有任何问题 但是当我在 YARN 上运行应用程序时 它将抛出以下错误 17 01 06 11 22 23 ERROR yarn Applicatio

随机推荐

  • Mybatis-Plus 实现多表联合查询+分页+查询条件

    Mybatis plus 自己只能完成单表操作 所以如果想要实现多表 需要借助 Mybatis 实现 首先引入mybatis plus依赖 这里就不演示了 返回结果集封装 传递分页以及查询的参数 主要代码在 Service 中 Reques
  • 若依微服务报错Error: Cannot find module ‘html-webpack-plugin‘解决

    遇到的问题 Error Cannot find module html webpack plugin 但是已经有html webpack plugin了 还是提示了报错 解决办法 https gitee com y project RuoY
  • LeetCode每日刷题:合并两个有序数组

    题目 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2 另有两个整数 m 和 n 分别表示 nums1 和 nums2 中的元素数目 请你 合并 nums2 到 nums1 中 使合并后的数组同样按 非递减顺序 排列 注意
  • LightGBM原理介绍

    简介 是GBDT模型的一个进化版本 其主要思想是利用弱分类器 决策树 迭代训练以得到最优模型 该模型具有训练效果好 不易过拟合等优点 备注 容易出现过拟合的风险 需要限制树的最大深度来防止过拟合 LGB是一个实现GBDT算法的框架 支持高效
  • Python学习笔记(三)

    文章目录 1 异常 2 单测 3 读写文件 3 1 读文件 3 2 写文件 3 3 操作文件和目录 4 正则表达式 4 1 贪婪匹配 5 其它 5 1 StringIO BytesIO 5 2 序列化 5 2 1 pickle 5 2 2
  • 3D光照阴影 平面阴影矩阵推导及代码实现

    3D光照阴影 平面阴影矩阵推导及代码实现 参考有关知识于是辛苦几个小时 推导出光照 平面阴影转换矩阵见图片 平面阴影矩阵推导第一页 平面阴影矩阵推导第二页 平面阴影矩阵 具体代码实现 第三页 到这里光照阴影的平面矩阵推导结束还有伪代码 参考
  • 如何使用学生账号来激活使用Jetbrains全家桶

    使用 edu邮箱注册学生账号来激活使用JetBrains全家桶 起因 之前激活过Jetbrains家的IDE 升级到2017 3 3版本 提示又要激活 试着原来的方法 结果用来激活的License Server全都失效 据称搭建本地反向代理
  • obj[‘x‘]和obj[x]的区别

    对象数据类型 由零到多组键值对 属性名和属性值 组成的属性名的类型 说法一 属性名类型只能是字符串或者Symbol 说法二 属性名类型可以是任何基本类型值 处理中可以和字符串互通 但是属性名绝对不能是引用数据类型 如果设置引用类型 最后也是
  • Python 爬虫学习笔记(二)urllib下载图片和视频

    一 urllib的1个类型和6个方法 1 response的类型 我们打印一下urllib request方法获取的response是什么类型 import urllib request url http www baidu com res
  • springboot yml文件配置Map List等数据

    springboot yml文件配置Map List等数据 配置类定义 yml 配置 使用 说明 配置类定义 import lombok Getter import lombok Setter import org springframew
  • 007 034 打印一个三角形

    例 使用输出语句输出一个三角形 include
  • 20+个小而精的Python实战案例(附源码和数据)

    公众号 尤而小屋作者 Peter编辑 Peter 大家好 我是Peter 最近小编认真整理了20 个基于python的实战案例 主要包含 数据分析 可视化 机器学习 深度学习 时序预测等 案例的主要特点 提供源码 都是基于jupyter n
  • Java实现扑克牌自动发牌系统

    利用Java的ArrayList实现随机给三个人发扑克牌 import java util ArrayList import java util List import java util Random class Card private
  • Linux 必备工具, 命令与例子

    目录 1 wget 2 screen 3 unzip gzip 4 netstat 5 git 6 composer 7 docker 8 docker compose 9 timedatectl set timezone Asia Sha
  • binfmt_misc

    一 binfmt misc是什么 binfmt misc是内核中的一个功能 它能将非本机的二进制文件与特定的解析器自动匹配起来 进行二进制解析 例如 在x86上解析arm64架构的二进制 通过binfmt misc可以注册解析器来处理指定二
  • JNI GetFieldID和GetMethodID函数解释及方法签名

    1 GetFieldID是得到java类中的参数ID GetMethodID得到java类中方法的ID 它们只能调用类中声明为 public的参数或方法 举例说明 jclass c env gt FindClass env com came
  • nodejs开发环境安装

    安装环境 win7 64位 访问nodejs官网 http nodejs org 点击Download链接 选择Windows Installer 下载安装包 直接安装即可 安装成功后 在命令窗口 cmd node 查看是否成功 若果没有成
  • UART、RS-232、RS-422、RS-485的区别

    v3学院带你一次性认清UART RS 232 RS 422 RS 485的区别 https www cnblogs com laokai p 6488910 html 通讯问题 和交通问题一样 也有高速 低速 拥堵 中断等等各种情况 如果把
  • LBP算法及其改进算法

    LBP LBP指局部二值模式 英文全称 Local Binary Pattern 是一种用来描述图像局部特征的算子 LBP特征具有灰度不变性和旋转不变性等显著优点 它是由T Ojala M Pietik inen 和 D Harwood在1
  • 第二十五章 Chisel进阶——隐式参数的应用

    用Chisel编写的CPU 比如Rocket Chip RISCV Mini等 都有一个特点 就是可以用一个配置文件来裁剪电路 这利用了Scala的模式匹配 样例类 偏函数 可选值 隐式定义等语法 本章内容就是来为读者详细解释它的工作机制