chisel快速入门(一)

一、概述

        Chisel(Constructing Hardware In a Scala Embedded Language)是一种嵌入在高级编程语言Scala的硬件构建语言。Chisel实际上只是一些特殊的类定义,预定义对象的集合,使用Scala的用法,所以在写Chisel程序时实际上是在写Scala程序。本文假设对Scala程序无任何了解,会通过一些Chisel的例子来说明某些重要的Scala特征,只使用本文介绍的东西也能完成一些的硬件设计。 当希望自己的代码能够更加简化或提高复用性,你会发现有必要了解Scala语言的潜力。作者也在学习中,后续文章陆续介绍。

二、Chisel硬件表达

        Chisel只支持二进制逻辑,不支持三态信号。

        由于只有芯片对外的IO处才能出现三态门,所以内部设计几乎用不到x和z。而且x和z在设计中会带来危害,忽略掉它们也不影响大多数设计,还简化了模型。当然,如果确实需要,可以通过黑盒语法与外部的Verilog代码互动,也可以在下游工具链里添加四态逻辑。

三、Chisel数据类型

        Chisel数据类型用于指定状态元素中保存的值或wire上传输的值。

        虽然硬件设计最终操作的是二进制数值向量,但对于值的其他抽象表示具有更清晰的规范,并且能够帮助工具生成更优化的电路。

        在Chisel中,原始比特集合可以用Bits类型来表示。带符号和无符号整数被认为是定点数的子集,可以用SInt和UInt来表示。带符号定点整数(包括整数)使用二进制补码格式来表示。布尔值可以用Bool类型表示。注意,这些类型与Scala的内建类型不同,例如Int或Boolean。另外,Chisel定义了Bundle用来将值进行集合(类似于其他语言中的struct),还定义了Vec用来对值的集合进行索引。

        常量或字面值使用Scala整数或传递给构造函数的字符串表示:

UInt(1)			// decimal 1-bit lit from Scala Int.
UInt("ha")		// hexadecimal 4-bit lit from string.
UInt("o12")		// octal 4-bit lit from string.
UInt("b1010") 	// binary 4-bit lit from string.
SInt(5) 		// signed decimal 4-bit lit from Scala Int. 
SInt(-8) 		// negative decimal 4-bit lit from Scala Int. 
UInt(5) 		// unsigned decimal 3-bit lit from Scala Int.
Bool(true) 		// Bool lits from Scala lits. 
Bool(false)

        下划线可以用作长字符串文字中的分隔符,以帮助可读性,但在创建值时会被忽略,例如:

UInt("h_dead_beef") // 32-bit lit of type UInt

        默认情况下,Chisel编译器将每个常量的大小设置为保存常量所需的最小位数,包括带符号类型的符号位。位宽也可以在字面上明确指定,如下所示:

UInt("ha", 8) 		// hexadecimal 8-bit lit of type UInt 
UInt("o12", 6) 		// octal 6-bit lit of type UInt 
UInt("b1010", 12) 	// binary 12-bit lit of type UInt
SInt(5, 7) 			// signed decimal 7-bit lit of type SInt 
UInt(5, 8) 			// unsigned decimal 8-bit lit of type UInt

        对于UInt类型值,值被零扩展到所需的位宽。对于类型为SInt的文字,该值被符号扩展以填充所需的位宽度。如果给定的位宽太小而不能容纳参数值,则会生成Chisel错误。

四、组合电路

        在Chisel中,电路会被表示为一张节点图。每个节点是具有零个或多个输入并驱动一个输出的硬件运算符。

        上面介绍的Uint是一种退化类型的节点,它没有输入,并且在其输出上驱动一个恒定的值。

        创建和连接节点的一种方法是使用字面表达式。例如,我们可以使用以下表达式来表示简单的组合逻辑电路:

(a & b) | (~c & d)

        语法应该看起来很熟悉,用&和|分别表示按位与和按位或,~表示按位非。a到d表示某些(未指定)宽度的命名导线。

        任何简单的表达式都可以直接转换成电路树,在叶子处使用命名的导线和操作符形成内部节点。表达式的电路输出取自树根处的运算符,在本示例中是按位或运算。

        简单表达式可以以树的形式构建电路,但是如果想以任意有向非循环图(DAG)的形式构建电路,我们需要描述扇出。在Chisel中,我们通过命名一根wire来表示一个子表达式,这样我们就可以在后续表达式中多次引用。我们通过声明变量来命名Chisel中的wire。例如,考虑如下示例的select表达式,它在后续的多选器描述中可以多次使用:

val sel = a | b
val out = (sel & in1) | (~sel & in0)

        关键字val是Scala的一部分,用于命名具有不会再更改的值的变量。 在上面的例子中它命名了wire类型的sel,保存了第一个按位或运算符的输出,以便输出可在第二个表达式中多次使用。

五、内建操作符

        Chisel定义了一组硬件操作符,如下表所示:

1、位宽接口

        用户需要设置端口和寄存器的位宽,除非用户手动设置,否则编译器会自动推测wire上的位宽。位宽推测引擎会从节点图的输入端口开始,并根据以下规则集从它们各自的输入位宽度计算节点输出位宽度:

         位宽推测过程会持续到没有位宽改变。 除了通过已知固定数量的右移之外,位宽推测规定了输出位宽度不能小于输入位宽度,因此输出位宽度增长或保持相同。 此外,寄存器的宽度必须由用户明确地或根据复位值或下一个参数的位宽指定。根据这两个要求,我们可以将位宽推测过程将收敛到一个固定点。

我们选择的运算符名称受到Scala语言的限制。所以我们必须使用===表示等于判断逻辑和=/=表示不等判断逻辑,这样可以保持原生Scala相关运算符可用。

六、功能抽象

        我们可以定义函数来分解一个重复的逻辑,这样可以在后续设计中重复使用。例如,我们可以包装一个简单的组合逻辑块:

def clb(a: UInt, b: UInt, c: UInt, d: UInt): UInt = (a & b) | (~c & d)

        其中clb是表示以a,b,c,d为参数的函数,并返回一个布尔电路的输出。 def关键字是Scala的一部分,表示引入了一个函数定义,每个语句后面跟一个冒号,然后是它的类型,函数返回类型在参数列表之后的冒号之后。(=)符号将函数参数列表与函数定义分隔开。

        然后我们就可以在其他的电路中使用了:

val out = clb(a,b,c,d)

        我们将在后面介绍许多酷炫的函数使用方法来构造硬件。

七、Bundles & Vecs

        Bundle和Vec是可以允许用户使用其他数据类型来扩展Chisel数据类型集合的类。

1、Bundles

        Bundle可以将一些不同类型的命名字段组合成一个单元,类似于C语言中的struct。用户可以通过将一个类定义为Bundle的子类来定义自己的bundle:

class MyFloat extends Bundle {val sign = Bool()val exponent = UInt(width = 8) val significand = UInt(width = 23)
}
val x = new MyFloat()
val xs = x.sign

        scala约定将新类的名称的首字母大写,所以我们建议在Chisel中也遵循这个约定。 UInt构造函数的width命名参数指定类型中的位数。

2、Vecs

        Vecs用来创建一个可索引的元素向量,其构造如下所示:

// Vector of 5 23-bit signed integers.
val myVec = Vec.fill(5){ SInt(width = 23) } 
// Connect to one element of vector.
val reg3 = myVec(3)

        注意,我们必须在花括号内指定Vec元素的类型,因为我们必须将位宽参数传递给SInt构造器。

        原始类(SInt,UInt和Bool)加上聚合类(Bundles和Vecs)都继承自一个公共的超类Data。在电路中,每个最终继承自Data的对象都可以表示为一个位向量。

        Bundle和Vec可以任意嵌套,从而构建复杂的数据结构:

class BigBundle extends Bundle {// Vector of 5 23-bit signed integers.val myVec = Vec.fill(5) { SInt(width = 23) } val flag = Bool()// Previously defined bundle.val f = new MyFloat()
}

八、端口

        端口用作硬件组件的接口。一个端口可以是任意的Data对象,但它是具有方向的。

        Chisel提供端口构造函数,以允许在构建时给对象添加(输入或输出)。原始的端口构造函数需要将方向作为第一个参数(方向为INPUT或OUTPUT),将位数作为第二个参数(除了始终为1位的布尔值)。

        端口的声明如下所示:

class Decoupled extends Bundle { val ready = Bool(OUTPUT)val data = UInt(INPUT, 32) val valid = Bool(INPUT)
}

        Decoupled被定义后,它就会变成一个新的类型,可以根据需要用于模块接口或命名的wire集合。

        对象的方向也可以实例化时确定:

class ScaleIO extends Bundle {val in = new MyFloat().asInput val scale = new MyFloat().asInput val out = new MyFloat().asOutput
}

        asInput和asOutput方法可以强制数据对象的所有模块设置成对应的方向

        通过将方向折叠到对象声明中,Chisel能够提供强大的布线能力,稍后会详细介绍。

九、Modules

        Chisel 模块与 Verilog 模块非常相似,在生成的电路中定义层次结构。 层次化的命名空间可在下游工具中访问,以帮助调试和物理布局。

        用户定义的模块被定义为一个类,它:

  • 继承自 Module,
  • 包含一个存储在名为 io 的端口字段中的接口
  • 在其构造函数中将子电路连接在一起。

         例如,将双输入多路复用器定义为一个模块:

class Mux2 extends Module {
val io = new Bundle{
val sel = UInt(INPUT, 1)
val in0 = UInt(INPUT, 1)
val in1 = UInt(INPUT, 1)
val out = UInt(OUTPUT, 1)
}
io.out := (io.sel & io.in1) | (~io.sel & io.in0)
}

        模块的接线接口是Bundle的端口集合。 模块的接口是通过名为 io 的字段定义的。 对于 Mux2,io 被定义为具有四个字段的包,每个多路复用器端口一个。

        := 赋值运算符,在定义的主体中使用,是 Chisel 中的一个特殊运算符,它将左侧的输入连接到右侧的输出。 

        我们现在可以构建电路层次,我们可以从较小的子模块开开始构建更大的模块。例如,我们可以通过将三个2输入多路选择器连接在一起,构建一个4输入多路选择器模块:

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)}val m0 = Module(new Mux2())m0.io.sel := io.sel(0)m0.io.in0 := io.in0; m0.io.in1 := io.in1val m1 = Module(new Mux2())m1.io.sel := io.sel(0)m1.io.in0 := io.in2; m1.io.in1 := io.in3val m3 = Module(new Mux2())m3.io.sel := io.sel(1)m3.io.in0 := m0.io.out; m3.io.in1 := m1.io.outio.out := m3.io.out 
}

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

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

相关文章

U盘基本处理,U盘与移动固态硬盘

一、辨别 USB2.0 和 USB3.0 1、从USB外观上来看,USB2.0通常是白色或黑色,而USB3.0则改观为“高大上”的蓝色接口。 目前,部分笔记本电脑USB接口,已同时提供对USB2.0及USB3.0的支持,我们可以通过接口颜色来区别。 2、从…

UWP_小说在线阅读器:功能要求与技术要求

注:2017年2月23日正式提上日程 学了WP开发也有一年了,也没做过什么软件的。17年进发UWP,锻炼自己一下。做一个开源的小说阅读器吧。 既然开发一个软件。所以要设计一下吧。 功能要求: 可能要用到的技术,这个吗&#xf…

chisel快速入门(二)

上一篇见此: chisel快速入门(一)_沧海一升的博客-CSDN博客简单介绍了chisel,使硬件开发者能快速上手chisel。https://blog.csdn.net/qq_21842097/article/details/121415341 十、运行和测试 现在我们已经定义了模块,…

【WPF】设置TextBox内容为空时的提示文字

原文:【WPF】设置TextBox内容为空时的提示文字<TextBox Width"150" Margin"5"><TextBox.Resources><VisualBrush x:Key"HintText" TileMode"None" Opacity"0.5" Stretch"None" AlignmentX"Le…

读书笔记之《The Art of Readable Code》Part 2

如何写好流程控制语句(if-else/switch/while/for)使得代码更可读些&#xff1f;(chap 7)* 提高条件语句的可读性(if语句, 或者bool型summary变量) if (length > 10) // Good if (10 < length) // Badwhile (bytes_received < bytes_expected) // Good while (b…

chisel快速入门(三)

前一篇见此&#xff1a; chisel快速入门&#xff08;二&#xff09;_沧海一升的博客-CSDN博客简单介绍了chisel&#xff0c;使硬件开发者能快速上手chisel。https://blog.csdn.net/qq_21842097/article/details/121418806 十四、模块的功能创建 制造用于模块构造的功能接口也…

Redis作者摊上事了:多人要求修改Redis主从复制术语master/slave

作者 | ANTIREZ、小智近日&#xff0c;Redis 作者在 GitHub 上发起了一个“用其他词汇代替 Redis 的主从复制术语”的 issue。有人认为 Redis 中的术语 master/slave &#xff08;主人 / 奴隶&#xff09;冒犯到了别人&#xff0c;要求 Redis 作者 ANTIREZ 修改这个术语&#x…

CMOS图像传感器——2021产品选谈

据Yole统计,2020年全球CMOS图像传感器(CIS)市场规模为207亿美元,出货量为70.08亿颗。跟其它半导体器件一样,CIS也因为疫情和生产周期长,以及各种市场因素,而导致采购和供应链紧张。Yole预计2021年将趋于平稳,销售额相比2020年略有增长(3.2%),将达到214亿美元,出货量…

C++匿名对象

匿名对象&#xff1a; string("hello")就是匿名对象&#xff1b; 匿名对象当做参数引用时必须加const; 转载于:https://www.cnblogs.com/achao123456/p/9634810.html

MVC源码分析 - Action查找和过滤器的执行时机

接着上一篇, 在创建好Controller之后, 有一个 this.ExecuteCore()方法, 这部分是执行的. 那么里面具体做了些什么呢? //ControllerBaseprotected virtual void Execute(RequestContext requestContext) {if (requestContext null){throw new ArgumentNullException("req…

CCIE-MPLS基础篇-实验手册

又一部前期JUSTECH&#xff08;南京捷式泰&#xff09;工程师职业发展系列丛书完整拷贝。 MPLS&#xff08;Multi-Protocol Label Switching&#xff09; 目录 1&#xff1a;MPLS 基础实验.... 3 1.1实验拓扑... 3 1.2实验需求&#xff1a;... 3 1.3实验步骤... 3 1.4校验…

RCA/BNC接口

RCA接口&#xff08;消费类市场&#xff09; RCA 是Radio Corporation of American的缩写词&#xff0c;因为RCA接头由这家公司发明的。RCA俗称莲花插座&#xff0c;又叫AV端子&#xff0c;也称AV 接口&#xff0c;几乎所有的电视机、影碟机类产品都有这个接口。它并不是专门为…

2021手机CIS技术趋势总结

手机摄像头CIS&#xff08;CMOS图像传感器&#xff09;自从突破1亿像素以后&#xff0c;再谈像素数量增大&#xff0c;似乎已经很难让市场产生激烈反应了。这两年电子工程专辑对于手机摄像头CIS&#xff0c;以及更多领域不同类型的图像/视觉传感器&#xff08;如ToF、基于事件的…

关于Unity中NGUI的背包实现之Scrollview(基于Camera)

基于UIPanel的scrollview实现方式在移动设备上的性能不如基于camera的方式。因为UIPanel的scrollview实现方式要渲染很多的道具图&#xff0c;性能自然就降低了。如果是用第二个摄像机camera的方式&#xff0c;物体并没有动&#xff0c;只是拖动第二个摄像机摄像机&#xff0c;…

YUV422/420 format

(在本文中&#xff0c;U 一词相当于 Cb&#xff0c;V 一词相当于 Cr。) YUV422 format as shown below 4:2:2 表示 2:1 的水平取样&#xff0c;没有垂直下采样 YUV420 format as shown below4:2:0 表示 2:1 的水平取样&#xff0c;2:1 的垂直下采样. YUV4:2:0并不是说只有U&…

数字后端——ECO

目录 一、概述 二、ECO分类 1、按时间节点 1&#xff09;流片前的ECO 2&#xff09;流片过程的ECO 3&#xff09;流片后的ECO 2、按网表是否改变 1&#xff09;功能ECO 2&#xff09;时序ECO 三、ECO处理内容 1、设计规则违例 1&#xff09;提升标准单元驱动力 2…

电视百科常识 九大视频接口全接触

1 射频 天线和模拟闭路连接电视机就是采用射频&#xff08;RF&#xff09;接口。作为最常见的视频连接方式&#xff0c;它可同时传输模拟视频以及音频信号。RF接口传输的是视频和音频混合编码后的信号&#xff0c;显示设备的电路将混合编码信号进行一系列分离、解码在输出成像。…

数字后端——物理单元介绍

物理单元&#xff08; physical cell&#xff09;指没有逻辑功能但是具有物理实现功能的标准单元&#xff0c; 用于抑制芯片生产过程中的各类物理效应&#xff0c; 保证芯片生产后能够正常工作 。硬核位置确 定后&#xff0c;需要插入物理单元消除影响芯片工作的物 效应&#x…

深入Java内存模型

你可以在网上找到一大堆资料让你了解JMM是什么东西&#xff0c;但大多在你看完后仍然会有很多疑问。happen-before是怎么工作的呢&#xff1f;用volatile会导致缓存的丢弃吗&#xff1f;为什么我们从一开始就需要内存模型&#xff1f; 通过这篇文章&#xff0c;读者可以学习到足…

Matlab 使用GPU加速 转载

在matlab中使用GPU加速&#xff0c;来加速矩阵运算。 首先如前面所说&#xff0c;并不是所有GPU都能在maltab中进行加速的&#xff0c;貌似只有NVDIA的显卡可以吧。 硬件&#xff1a;GeForce GTX 980 软件&#xff1a;Matlab 2015a &#xff08;Matlab 2012以后的版本才带有GP…