当前位置:网站首页>吃透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里面还提供了更多的组件和控制抽象,能让我们在描述一个组合电路的时候更优雅,相关内容后面详细说!
边栏推荐
- 锐成芯微冲刺科创板:年营收3.67亿拟募资13亿 大唐电信是股东
- MySQL version 8 installation Free Tutorial
- 博士申请 | 西湖大学学习与推理系统实验室招收博后/博士/研究实习等
- 分布式BASE理论
- find命令报错: paths must precede expression(转)
- 2022KDD预讲 | 11位一作学者带你提前解锁优秀论文
- BLOB,TEXT GEOMETRY or JSON column 'xxx' can't have a default value query 问题
- C语言职工管理系统
- [C question set] of VII
- C语言程序设计选题参考
猜你喜欢

结合案例:Flink框架中的最底层API(ProcessFunction)用法

逆向调试入门-PE结构-资源表07/07

Detailed explanation of Fisher information quantity detection countermeasure sample code

锐成芯微冲刺科创板:年营收3.67亿拟募资13亿 大唐电信是股东

Flet教程之 03 FilledButton基础入门(教程含源码)(教程含源码)

Five "potential errors" in embedded programming

The only core indicator of high-quality software architecture

2022G3锅炉水处理考试题模拟考试题库及模拟考试

安装trinity、解决报错

高质量软件架构的唯一核心指标
随机推荐
源码编译安装MySQL
高质量软件架构的唯一核心指标
Lick the dog until the last one has nothing (state machine)
华昊中天冲刺科创板:年亏2.8亿拟募资15亿 贝达药业是股东
CommVault cooperates with Oracle to provide metallic data management as a service on Oracle cloud
Gorm 读写分离(转)
WS2811 M是三通道LED驱动控制专用电路彩灯带方案开发
205. 同构字符串
C array supplement
【C 题集】of Ⅶ
In 2022, it will be es2022 soon. Do you only know the new features of ES6?
C语言小型商品管理系统
动画与过渡效果
易周金融 | Q1保险行业活跃人数8688.67万人 19家支付机构牌照被注销
Worried about "cutting off gas", Germany is revising the energy security law
Fs7867s is a voltage detection chip used for power supply voltage monitoring of digital system
[C question set] of VII
DGraph: 大规模动态图数据集
Introduction to reverse debugging PE structure resource table 07/07
Cors: standard scheme of cross domain resource request