chisel快速入门(三)

2023-10-27

前一篇见此:

chisel快速入门(二)_沧海一升的博客-CSDN博客简单介绍了chisel,使硬件开发者能快速上手chisel。https://blog.csdn.net/qq_21842097/article/details/121418806

十四、模块的功能创建

        制造用于模块构造的功能接口也是有用的。例如,我们可以构建一个构造函数,它将多路复用器输入作为参数,并返回多路复用器输出:

object Mux2 {
	def apply (sel: UInt, in0: UInt, in1: UInt) = {
		val m = new Mux2() 
		m.io.in0 := in0 
		m.io.in1 := in1 
		m.io.sel := sel 
		m.io.out
	}
}

        其中对象Mux2在Mux2模块类中创建一个Scala单例对象,并且apply定义了创建Mux2实例的方法。有了这个Mux2创建功能,Mux4的规格现在明显更简单。

class Mux4 extends Module { 
	val io = new Bundle {
		val in0 = UInt(INPUT, 1)
		val in1 = UInt(INPUT, 1) 
		val in2 = UInt(INPUT, 1) 
		val in3 = UInt(INPUT, 1) 
		val sel = UInt(INPUT, 2) 
		val out = UInt(OUTPUT, 1)
	}
	io.out := Mux2(io.sel(1), Mux2(io.sel(0), io.in0, io.in1), Mux2(io.sel(0), io.in2, io.in3))
}

        选择输入非常有用,以至于 Chisel 将其内置并称之为 Mux。 然而,与上面定义的 Mux2 不同,内置版本允许 in0 和 in1 上的任何数据类型,只要它们有一个共同的超类。

        Chisel提供MuxCase,其本质上是一个n-way Mux。

MuxCase(default, Array(c1 -> a, c2 -> b, ...))

十五、多态性和参数化

        Scala是一种强类型语言,使用参数化类型来指定通用函数和类。 在本节中,我们展示了Chisel用户如何使用参数化类来定义自己的可重用函数和类。

1、参数化函数

        前面我们在Bool上定义了Mux2,但现在我们展示如何定义一个通用的多路复用器功能。我们使用一个布尔条件和con和alt参数(对应于then和else表达式)来定义一个T类型的函数:

def Mux[T <: Bits](c: Bool, con: T, alt: T): T { ... }

        其中T需要是Bits的子类。Scala确保在Mux的每个使用中,它可以找到实际的con和alt参数类型的公共超类,否则会导致Scala编译类型错误。

2、参数化类

        与参数化函数一样,我们也可以参数化类,使它们可重用程度更高。例如,我们可以将Filter类概括为可以使用任何类型的链接。

        我们可以通过参数化FilterIO类和定义构造函数采取零参数类型构造函数来做到这点,如下所示:

class FilterIO[T <: Data](type: T) extends Bundle { 
	val x = type.asInput.flip
	val y = type.asOutput
}

        我们现在可以通过定义一个模块类来定义Filter,该模块类也接收一个链接类型构造函数参数,并将其传递给FilterIO接口构造器:

class Filter[T <: Data](type: T) extends Module { 
	val io = new FilterIO(type)
	...
}

        另一个例子,通用FIFO可以这样定义,并使用如下:

class DataBundle extends Bundle { 
	val A = UInt(width = 32)
	val B = UInt(width = 32)
}
object FifoDemo {
	def apply () = new Fifo(new DataBundle, 32)
}

class Fifo[T <: Data] (type: T, n: Int) extends Module {
	val io = new Bundle {
		val enq_val = Bool(INPUT) 
		val enq_rdy = Bool(OUTPUT) 
		val deq_val = Bool(OUTPUT) 
		val deq_rdy = Bool(INPUT) 
		val enq_dat = type.asInput 
		val deq_dat = type.asOutput
	}
	val enq_ptr = Reg(init = UInt(0, sizeof(n)))
	val deq_ptr = Reg(init = UInt(0, sizeof(n)))
	val is_full = Reg(init = Bool(false))
	val do_enq  = io.enq_rdy && io.enq_val
	val do_deq  = io.enq_rdy && io.deq_val 
	val is_empty = !is_full && (enq_ptr === deq_ptr)
	val deq_ptr_inc = deq_ptr + UInt(1)
	val enq_ptr_inc = enq_ptr + UInt(1)
	val is_full_next = Mux(do_enq && ~do_deq && (enq_ptr_inc === deq_ptr), Bool(true), Mux(do_deq && is_full, Bool(false), is_full)) 
	enq_ptr := Mux(do_enq, enq_ptr_inc, enq_ptr) 
	deq_ptr := Mux(do_deq, deq_ptr_inc, deq_ptr) 
	is_full := is_full_next
	val ram = Mem(n) 
	when (do_enq) {
		ram(enq_ptr) := io.enq_dat 
	}
	io.enq_rdy := !is_full 
	io.deq_val := !is_empty 
	ram(deq_ptr) <> io.deq_dat
}

        对FIFO定义通用解耦接口,可以简化IO:

class DecoupledIO[T <: Data](data: T) extends Bundle {
	val ready = Bool(INPUT)
	val valid = Bool(OUTPUT)
	val bits = data.clone.asOutput 
}

class DecoupledDemo
extends DecoupledIO()( new DataBundle )

class Fifo[T <: Data] (data: T, n: Int) extends Module {
	val io = new Bundle {
		val enq = new DecoupledIO( data ).flip() 
		val deq = new DecoupledIO( data )
	}
	... 
}

十六、多时钟域

1、创建时钟域

        为了使用多个时钟域,用户必须创建多个时钟。 在Chisel中,时钟是使用复位信号参数创建的第一级节点,定义如下:

class Clock (reset: Bool) extends Node { 
	def reset: Bool // returns reset pin
}

        在Chisel中有一个内置的隐式时钟,状态元素默认使用:

var implicitClock = new Clock( implicitReset )

        状态元素和模块的时钟可以使用名为clock的附加命名参数来定义:

Reg(... clock: Clock = implicitClock) 
Mem(... clock: Clock = implicitClock) 
Module(... clock: Clock = implicitClock)

2、跨时钟域

        有两种方式可以定义电路在时钟域之间发送数据。第一种也是最原始的方式就是使用由两个寄存器组成的同步器电路,如下所示: 

// signalA is in clock domain clockA,
// want a version in clockB as signalB
val s1 = Reg(init = UInt(0), clock = clockB) 
val s2 = Reg(init = UInt(0), clock = clockB)
s1 := signalA
s2 := s1;
signalB := s2

        由于亚稳性问题,该技术只限于在域之间传递一位数据。

        在域之间发送数据的第二种和更一般的方式是通过使用异步fifo:

class AsyncFifo[T<:Data](gen: T, entries: Int, enq_clk: Clock, deq_clock:Clock) extends Module

        当通过指定标准fifo参数和两个时钟,然后使用标准解耦ready/valid信号从时钟域clockA到clockB获取一个版本的signalA时:

val fifo =
new AsyncFifo(Uint(width = 32), 2, clockA, clockB)
fifo.io.enq.bits := signalA
signalB := fifo.io.deq.bits
fifo.io.enq.valid := condA
fifo.io.deq.ready := condB

3、后端多时钟处理

        每个 Chisel 后端都需要用户以后端特定的方式设置和控制多个时钟。 为了展示如何驱动多时钟设计,我们以具有两个模块的硬件为例进行说明,该例子使用 AsyncFifo 与不同时钟的每个模块进行通信:fastClock 和 slowClock。

        在Verilog中:

  • Chisel为每个时钟/复位创建一个新端口,
  • Chisel将所有的时钟连到顶层模块
  • 用户必须要为每个时钟i创建一个always块时钟驱动
module emulator;
	reg fastClock = 0, slowClock = 0, resetFast = 1, resetSlow = 1; 
	wire [31:0] add, mul, test;
	always #2 fastClock = ~fastClock;
	always #4 slowClock = ~slowClock; 
	initial begin
		# 8
		resetFast = 0; 
		resetSlow = 0; 
		#400
	$finish;
end
ClkDomainTest dut (
	.fastClock(fastClock), 
	.slowClock(slowClock), 
	.io_resetFast(resetFast),
	.io_resetSlow(resetSlow),
	.io_add(add), 
	.io_mul(mul), 
	.io_test(test));
endmodule
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

chisel快速入门(三) 的相关文章

  • 【HDLBits 刷题 12】Circuits(8)Finite State Manchines 27-34

    目录 写在前面 Finite State Manchines 2014 q3c m2014 q6b m2014 q6c m2014 q6 2012 q2fsm 2012 q2b 2013 q2afsm 2013 q2bfsm 写在前面 HD
  • 【从嵌入式视角学习香山处理器】四、Chisel语言基础

    文章目录 一 前言 二 Linux上对scala工程的操作 1 helloworld执行命令 2 有多个工程目录时 需要切换工程 3 编译报错 4 给vscode的scala插件设置JAVA HOME路径 三 ch4 基本组成部分 ch4
  • 电力电子转战数字IC——我的IC面试(2022.10.14更新)

    目录 感谢信 HKWS10 14面试 25mins JXC10 13面试 30mins JDSK9 23面试 42mins 快速的自我介绍 介绍一下这个MCDF的项目 你这里写SV搭建的验证环境 和UVM搭建的有什么区别吗 你这里写了覆盖率
  • Design Compiler指南——设计综合过程

    在前面一章介绍完施加约束之后 接下来要做的工作就是将设计进行综合编译 compile 本文我们将主要讨论综合编译的过程 主要分为这样几个部分 优化的三个阶段及其特点 编译的策略 编译层次化的设计 一 优化的三个阶段 这一节我们介绍Desig
  • 【HDLBits 刷题 11】Circuits(7)Finite State Manchines 18-26

    目录 写在前面 Finite State Manchines Fsm serialdata Fsm serialdp Fsm hdlc Design a Mealy FSM ece241 2014 q5a ece241 2014 q5b 2
  • 玄铁C910总览

    一 开源玄铁C910简介 玄铁C910是由平头哥设计并开源的高性能CPU 基于开源的RISC V指令集 主要面向对性能要求严格的边缘计算领域 如边缘服务器 边缘计算卡 高端机器视觉 高端视频监控 自动驾驶 移动智能终端 5G 基站等 玄铁C
  • 第二十章 Chisel基础——生成Verilog与基本测试

    经过前三章的内容 读者已经了解了如何使用Chisel构建一个基本的模块 本章的内容就是在此基础上 把一个Chisel模块编译成Verilog代码 并进一步使用Verilator做一些简单的测试 一 生成Verilog 前面介绍Scala的内
  • 八、RISC-V SoC外设——GPIO接口 代码讲解

    前几篇博文中注释了RISC V的内核CPU部分 从这篇开始来介绍RISC V SoC的外设部分 另外 在最后一个章节中会上传额外添加详细注释的工程代码 完全开源 如有需要可自行下载 目录 0 RISC V SoC注解系列文章目录 1 结构
  • 【MACOS(M1)编译Risc-v版OpenOCD】

    MACOS编译Risc v版OpenOCD 准备 1 执行顺序 常见问题 问题1 AC PROG CC C99 告警 2 问题2 texinfo 版本不匹配 问题2 libtool版本不匹配 问题3 编译错误 验证一下 准备1 Instal
  • Chisel手册之Types

    本文是Chisel手册第二篇Types Types 表示硬件设计的Chisel图包含原始节点和类型节点 Chisel类型系统与底层Scala类型系统分开维护 因此类型节点散布在原始节点之间 以允许Chisel检查并响应Chisel类型 Ch
  • 数字后端知识点扫盲——后端设计流程及使用工具

    1 DFT Design For Test 可测性设计 芯片每一步往往都自带测试电路 DFT的目的就是在设计的时候就考虑将来的测试 DFT的常见方法是 在设计中插入scan chain 将非扫描单元 如寄存器 变为扫描单元 DFT工具是sy
  • 计算数组中的个数

    我试图在 Verilog 中计算 4 位二进制数中 1 的数量 但我的输出是意外的 我尝试了几种方法 这是我认为应该有效的方法 但事实并非如此 module ones one in input 3 0 in output 1 0 one a
  • 如何用GDB调试交叉编译的QEMU程序?

    我在使用 GDB 调试 QEMU 中运行的简单程序时遇到问题 GDB似乎无法找到我在程序中的位置 因为它总是显示 作为我当前的位置 并且它永远不会达到我设置的任何断点 在一个终端中 我运行 QEMU cat add c int main i
  • Verilog 奇怪的仿真结果综合后

    我面临一个奇怪的问题 该代码适用于简单的 ALU 仅将感兴趣的代码粘贴到此处 always posedge clk or posedge rst begin if rst 1 begin mul valid shr 3 b000 end e
  • VHDL乘法器

    library IEEE use IEEE STD LOGIC 1164 ALL entity Lab3 Adder1 is Port cin in STD LOGIC a in STD LOGIC VECTOR 3 downto 0 b
  • 测试工具中的 Chisel 运行时错误

    This Chisel https chisel eecs berkeley edu 代码工作正常 chiselMainTest Array String backend c genHarness gt Module new Cache n
  • 如何生成异步复位verilog总是阻塞凿子

    Chisel 始终生成敏感度列表中仅包含时钟的块 always posedge clk begin end 是否可以将模块配置为使用异步重置并生成这样的始终块 always posedge clk or posedge reset begi
  • RISC-V 中 JAL 和 JALR 指令的偏移地址

    在 RISC V 规范中 JAL 和 JALR 指令中的立即数被转换为跳转偏移量 如下所示 将给定立即数符号扩展为 XLEN 位 将 LSB 设置为零 我对此有几个问题 问题1 对于 JAL 这给出了一个范围 000000000000 to
  • 在 C 中实现 SB 型 riscv 指令

    我遇到了一些问题 我尝试将 32 位二进制解码为 RISCV 架构集中的 SB 类型指令 我已经移动了操作码 imm rs1 rs2 和 rd 值 但未能获得正确的 IMM 值 例如对于以下 32 位二进制 1111111000000111
  • RISC-V指令集中的FENCE指令是什么意思?

    在浏览 RISC V ISA 时 我在内存模型部分看到了一条指令 FENCE 指令 它到底是什么意思 RISC V ISA 使用宽松的内存模型 其中一个线程执行的加载和存储的顺序在另一个线程看到时可能不同 这样做是为了启用提高内存系统性能的

随机推荐

  • vscode配置php环境(以phpstudy2018为例)

    首先我们需要有一个vscode 安装 无脑下一步 其次我们需要有一个phpstudy2018 安装 无脑下一步 安装路径换到自己能找到的位置就行 然后打开vscode安装下图所示四个扩展 安装完成后启用扩展重启vscode 生效 接着我们
  • selenium扫码登录操作edge

    from selenium import webdriver 导入包 from selenium webdriver common by import By from selenium webdriver common action cha
  • 计算机应用技术与物联网专业介绍,《物联网应用技术》专业简介

    物联网应用技术 专业简介 专业代码 610119 物联网 Internet of Things 被称为继计算机 互联网之后 世界信息产业的第三次浪潮 它是通过计算机嵌入技术将各种设备智能化 再通过通信技术 互联网技术将它们相互连接起来 从而
  • 删除表和截断表命令之间的区别是什么?

    删除表和截断表命令之间的区别是什么 此问题提交于2004年11月23日 表删除包括表的定义和关联对象 规则 索引 约 触发器 主键 等 很明显 一旦表被删除 那么表中包含的所有的数据行都会被一同删除 truncate table 命令则仅仅
  • 左外连接与右外连接

    左外连接 两个表在连接过程中除了返回满足连接条件的行以外 还要返回左表中不满足条件的行 这种连接称为左外连接 右外连接 两个表在连接的过程中除了返回满足连接条件的行以外 还要返回右表中不满足条件的行 这种连接称为右外连接 左外连接 from
  • java语言的动态性相关概念;动态绑定、动态连接、与虚方法

    1 动态连接 链接 java代码在进行javac编译的时候不会像c或者c 有 连接 这一步骤 而是虚拟机在加载Class文件的时候进行动态连接 也就是说在class文件中不会保存各个方法 字段最终在内存中的入口地址 也就无法被虚拟机直接使用
  • CAS实现单点登录--错误记录

    遇到的错误 生成证书 1 命令 keytool genkey alias smalllove keyalg RSA keystore C keys smallkey 错误 java lang Exception Keystore文件存在 但
  • uni——tab切换

    案例展示 案例代码
  • Jaxb annotation初步使用

    今天在阅读cxf官方文档的时候遇到一种用法主要真对Map类型的复杂对象处理 WebServicepublicinterface HelloWorld String sayHi String text Advanced usecase of
  • Keil5 点击Debug Setting 软件崩溃解决方法

    因为我我打开另外一个程序是可以仿真的 所以没有考虑keil5软件自身的问题 1 有中文路径 然后剪切到没有中文路径的文件夹 gt 未解决 2 打开注册表 Win R键呼出 运行 在框内输入 Regedit 回车打开注册表 如果弹出 是否允许
  • Python时间格式转换

    概述 strptime 与strftime 若仅转换时间格式使用strftime 若需要做时间操作则使用strptime 1 strptime 中的p指parse 解析 一般解析都是说对字符串进行解析 所以strptime 方法是将字符串解
  • Yapi接口一键生成Java代码

    文章目录 一 简介 1 这是什么 2 有啥用 3 为什么要用 二 快速开始 1 下载 2 配置 3 运行 三 版本说明 v1 0 0 v1 0 1 四 Github项目地址 一 简介 1 这是什么 这是一个Java代码生成器 2 有啥用 能
  • IDEA如何生成 serialVersionUID

    序列化和反序列化 Java是面向对象的语言 与其他语言进行交互 比如与前端js进行http通信 需要把对象转化成一种通用的格式比如json 前端显然不认识Java对象 从对象到json字符串的转换 就是序列化的过程 反过来 从json字符串
  • import-from

    1 import from可以导入什么文件 通过import from 导入时 from后的来源可以是js vue json 这个是在webpack base conf js中extensions设置的 该属性值默认是js vue json
  • 深度学习入门资料整理

    深度学习基础总结 无一句废话 附完整思维导图 深度学习如何入门 知乎 深度学习入门基础讲义 shuzfan的博客 CSDN博客 深度学习入门 神经网络15分钟入门 足够通俗易懂了吧 知乎 深度学习基础知识点梳理 知乎
  • MQ-2烟雾传感器代码(STM32单片机驱动)

    MQ 2烟雾传感器代码 STM32单片机驱动 MQ 2烟雾传感器简介 接线 三级目录 MQ 2烟雾传感器简介 MQ 2烟雾传感器所使用的气敏材料是在清洁空气中电导率较低的二氧化锡 SnO2 当烟雾传感器所处环境中存在可燃气体时 烟雾传感器的
  • 什么是 BFC?

    3 BFC的规则 BFC就是一个块级元素 块级元素会在垂直方向一个接一个的排列BFC就是页面中的一个隔离的独立容器 容器里的标签不会影响到外部标签垂直方向的距离由margin决定 属于同一个BFC的两个相邻的标签外边距会发生重叠计算BFC的
  • 在线吉他调音

    先看效果 图片没有声 可以下载源码看看 比这更好 再看代码 查看更多
  • 输电线路故障诊断(Python代码,逻辑回归、决策树、随机森林、XGBoost和支持向量机五种不同方法诊断)

    效果视频 输电线路故障诊断 Python代码 逻辑回归 决策树 随机森林 XGBoost和支持向量机五种不同方法诊断 哔哩哔哩 bilibili 项目文件 code py装载的是英文版本 图上显示英文标签及坐标 Chinese py装载的是
  • chisel快速入门(三)

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