当前位置:网站首页>吃透Chisel语言.05.Chisel基础(二)——组合电路与运算符
吃透Chisel语言.05.Chisel基础(二)——组合电路与运算符
2022-07-04 12:49:00 【github-3rr0r】
Chisel基础(二)——组合电路与运算符
组合逻辑电路从数学的角度来讲,就是用布尔代数的操作符来描述的数字逻辑电路,也就是一系列布尔代数运算符的组合。Chisel中,这些布尔代数的操作符跟C、Java、Scala以及其他编程语言中定义的是类似的,比如,&是按位与操作符,|是按位或操作符。这一部分就详细介绍Chisel中基本的位运算符、算术运算符、逻辑运算符、比较运算符等,以及Chisel中的一个高阶组合电路运算符——多路选择器。
一个简单组合逻辑电路的例子
下面这一行代码,定义了一个组合电路,它用一个与门连接信号a和b,然后把这个与门的输出和信号c用或门连接在一起:
val logic = (a & b) | c
这个表达式对应的电路示意图如下:

可以看到基础语法是很简单的,需要注意的是,这个电路中与门和或门的输入信号可以是单个比特,也可以是比特向量。
Chisel中的位运算符
下面的例子分别演示了四种基本的位运算,用的是Scala中的标准运算符,他们的操作数可以是UInt、SInt和Bool:
val and = a & b // 按位与
val or = a | b // 按位或
val xor = a ^ b // 按位异或
val not = ~a // 按位取反
这几种基本的位运算都很基础,还有两个移位操作,他们的操作数可以是UInt或SInt:
val shiftleft = a << b
val shiftright = a >> b
需要注意的是,对于SInt类型的操作数,右移或会进行符号拓展,即算术右移。
总结Chisel中的位运算符如下:
| 操作符 | 描述 | 数据类型 |
|---|---|---|
& | 按位与 | UInt、SInt、Bool |
| ` | ` | 按位或 |
^ | 按位异或 | UInt、SInt、Bool |
~ | 按位取反 | UInt、SInt、Bool |
<< | 左移 | UInt、SInt |
>> | 对于UInt是逻辑右移,对于SInt是算术右移 | UInt、SInt |
Chisel中的算术运算符
下面是Chisel中使用Scala标准运算符进行的算术运算,他们的操作数可以是UInt或SInt:
val add = a + b // 加法
val sub = a - b // 减法
val neg = -a // 取相反数
val mul = a * b // 乘法
val div = a / b // 除法
val mod = a % b // 取余
需要注意这里的位宽推断:
- 对于加减法,结果宽度为操作数中最宽的那个宽度;
- 对于乘法,结果宽度为操作数的宽度之和;
- 对于除法和取余,结果宽度通常为被除数的宽度;
另外,对于加法和减法,还可以指定是否进行位宽拓展保留进位,在+或-后加上%就是不进行位宽拓展,加上&就是不保留进位,默认是不进行位宽拓展。
总结Chisel中的算术运算符如下:
| 操作符 | 描述 | 数据类型 |
|---|---|---|
+或+% | 加(不保留进位) | UInt、SInt |
+& | 加(保留进位) | UInt、SInt |
-或-% | 减(不保留进位) | UInt、SInt |
-& | 减(保留进位) | UInt、SInt |
* | 乘 | UInt、SInt |
/ | 除 | UInt、SInt |
% | 取余 | UInt、SInt |
Chisel中的逻辑运算符
逻辑运算符是针对Bool类型的值进行运算的,有逻辑与、逻辑或和逻辑非这三种,和Scala以及其他编程语言是类似的:
| 操作符 | 描述 | 数据类型 |
|---|---|---|
&& | 逻辑与 | Bool |
| ` | ` | |
! | 逻辑非 | Bool |
Chisel中的比较运算符
对于小于、小于等于、大于和大于等于,Chisel和Scala是一致的,但在等于和不等于上表示不一样。比较运算符的操作数为UInt或SInt,总结如下:
| 操作符 | 描述 | 数据类型 |
|---|---|---|
> | 大于 | UInt、SInt,返回Bool |
>= | 大于等于 | UInt、SInt,返回Bool |
< | 小于 | UInt、SInt,返回Bool |
<= | 小于等于 | UInt、SInt,返回Bool |
=== | 等于 | UInt、SInt,返回Bool |
=/= | 不等于 | UInt、SInt,返回Bool |
虽然这里的===和=/=看起来很奇怪,但千万不能弄错,设计者表示这么做是为了让Scala中原有的==和!=仍然可用。
Chisel中的规约运算符
这是Chisel中比较好用的运算符,操作数为SInt或UInt,对操作数的每一位进行规约运算,返回值为Bool类型,三个规约运算符如下:
| 操作符 | 描述 | 数据类型 |
|---|---|---|
.andR | 与规约 | UInt、SInt,返回Bool |
.orR | 或规约 | UInt、SInt,返回Bool |
.xorR | 异或规约 | UInt、SInt,返回Bool |
用法如下:
val allSet = x.andR // 与规约
val anySet = x.orR // 或规约
val parity = x.xorR // 异或规约
Chisel中的位字段操作符
我们前面提到UInt和SInt都是位向量,因此应该有一些对向量的位字段进行操作的操作符,上一部分的规约操作符就属于这类。Chisel中还有其他的位字段操作符:
比如从位向量中提取单个比特,操作符为(n),表示提取第n位,最低有效位LSB索引为0:
val xLSB = x(0) // 提取x的最低位
也可以提取一个位段,操作符为(end, start),表示提取第start位到第end位之间的字段,这个start和end是包括在内的,返回值是个UInt:
val xTopNibble = x(15, 12) // 假设x是16位的,提取x的高4位
还可以把一个位向量复制多次,操作符为Fill(n, x),n为复制次数,x为被复制的位向量,只可以是或UInt,返回值也是UInt:
val usDebt = Fill(3, "hA".U) // "hAAA".U
最后是可以拼接多个位向量的操作,操作符为##或Cat,和Verilog中的{}类似,示例如下:
val float = Cat(sign, exponent, mantissa) // 拼接三个向量,或者
val float = sign ## exponent ## mantissa
不过需要注意的是,拼接操作的操作数两边类型必须一样,而返回值为UInt,因此,如果在多个操作数上用##进行拼接的时候需要注意,比如对三个SInt进行拼接就会报错,而对两个SInt和一个UInt进行拼接就不会报错,而使用Cat就不会有这个问题。
另外还有个需要注意的是,虽然##和Cat功能是类似的,但是生成的Verilog会有所不同,比如:
a := -1.S ## -2.S
会生成:
assign a = {1'sh1,2'sh2};
而:
a := Cat(-1.S, -2.S)
会生成:
assign a = 3'h6;
一般来说使用Cat进行拼接是更好的。
总结如下:
| 操作符 | 描述 | 数据类型 |
|---|---|---|
x(n) | 提取第n位 | UInt、SInt,返回Bool |
x(end, start) | 提取第start到第end位 | UInt、SInt,返回UInt |
Fill(n, x) | 位向量x复制n次 | UInt,返回UInt |
a ## b | 位向量拼接 | UInt、SInt,返回UInt |
Cat(a, b, ...) | 位向量拼接 | UInt、SInt,返回UInt |
关于Chisel操作符的优先级
Chisel操作符的优先级并没有作为Chisel语言的一部分直接定义出来,而是取决于电路的赋值顺序,自然地遵循Scala的运算符优先级。如果实在拿不准的话,那就使用括号来表达运算优先级。
题外话,Chisel和Scala的运算符优先级和Java/C相似但不同,而Verilog和C是一样的,但是VHDL直接就是没有这个特性的。在VHDL里面,所有的运算符优先级相同,按照从左到右的顺序进行计算。
Chisel中的2-1多路选择器
多路选择器(multiplexer)是在多个输入中选择一个作为输出的组合电路,其最基本的形式就是2-1多路选择器,即二选一。下图就是一个2-1多路选择器,或者简称为Mux:

根据选择信号sel的值,输出y会表示输入信号a或b。当然,我们用逻辑门也是可以实现这个Mux的,但是Chisel标准库里面就提供了Mux作为标准的操作符,示例如下:
val y = Mux(sel, a, b)
当sel是个Chisel中的Bool类型值,为true的时候选择输出a,否则选择输出b。这里a和b可以是任意的Chisel基本类型或聚合类(比如bundle或vector,后面会详细讲),只要它俩的类型是一样的就行。
结语
有了上面的基本算术、逻辑操作和这里的多路选择器,那就可以描述所有的组合电路了。但是,硬用这些来描述显然不够优雅,比如我要实现一个3-8译码器,我总不能使用8个Mux吧?那代码可读性也太差了!而Chisel里面还提供了更多的组件和控制抽象,能让我们在描述一个组合电路的时候更优雅,相关内容后面详细说!
边栏推荐
- Gorm 读写分离(转)
- Three schemes to improve the efficiency of MySQL deep paging query
- JVM系列——栈与堆、方法区day1-2
- js中的变量提升和函数提升
- Distributed base theory
- 面试官:Redis中哈希数据类型的内部实现方式是什么?
- Don't turn down, three sentences to clarify the origin of cross domain resource request errors
- The only core indicator of high-quality software architecture
- Scripy framework learning
- C basic supplement
猜你喜欢

MySQL version 8 installation Free Tutorial

Getting started with the go language is simple: go implements the Caesar password

SCM polling program framework based on linked list management

【R语言数据科学】:交叉验证再回首

高质量软件架构的唯一核心指标

Huahao Zhongtian sprint Technology Innovation Board: perte annuelle de 280 millions de RMB, projet de collecte de fonds de 1,5 milliard de Beida Pharmaceutical est actionnaire

2022年山东省安全员C证考试题库及在线模拟考试

Openharmony application development how to create dayu200 previewer

OpenHarmony应用开发之如何创建DAYU200预览器

【Antd踩坑】Antd Form 配合Input.Group时出现Form.Item所占据的高度不对
随机推荐
Applet live + e-commerce, if you want to be a new retail e-commerce, use it!
Ws2811 m is a special circuit for three channel LED drive and control, and the development of color light strip scheme
unity不识别rider的其中一种解决方法
Flet教程之 03 FilledButton基础入门(教程含源码)(教程含源码)
Fisher信息量检测对抗样本代码详解
Secretary of Homeland Security of the United States: domestic violent extremism is one of the biggest terrorist threats facing the United States at present
CVPR 2022 | 大幅减少零样本学习所需的人工标注,提出富含视觉信息的类别语义嵌入(源代码下载)...
Byte interview algorithm question
美国土安全部长:国内暴力极端主义是目前美面临的最大恐怖主义威胁之一
MySQL45讲——学习极客时间MySQL实战45讲笔记—— 06 | 全局锁和表锁_给表加个字段怎么有这么多阻碍
js中的变量提升和函数提升
C语言职工管理系统
C语言集合运算
Distributed base theory
Three schemes to improve the efficiency of MySQL deep paging query
C#基础深入学习一
2022 hoisting machinery command examination simulation 100 questions simulation examination platform operation
安装trinity、解决报错
In 2022, it will be es2022 soon. Do you only know the new features of ES6?
C basic supplement