当前位置:网站首页>吃透Chisel语言.08.Chisel基础(五)——Wire、Reg和IO,以及如何理解Chisel生成硬件
吃透Chisel语言.08.Chisel基础(五)——Wire、Reg和IO,以及如何理解Chisel生成硬件
2022-07-04 12:49:00 【github-3rr0r】
Chisel基础(五)——Wire、Reg和IO,以及如何理解Chisel生成硬件
上一篇的结语中提到,UInt、SInt和Bits都是Chisel类型,它们本身是不直接表示硬件的,只有把它们封装成为Wire、Reg或IO才会生成电路。这件事可以这么理解,数字逻辑电路是由连线、逻辑门、寄存器和输入输出(包括时钟和复位信号)等组成的,其中连线对应Wire,逻辑门对应运算符,寄存器对应Reg,输入输出对应IO。那么在Chisel中它们到底怎么使用呢?又如何理解Chisel生成电路呢?这一篇文章一起学习一下。
Wire、Reg和IO
在Chisel中,Wire用于表示组合逻辑,Reg用于表示寄存器(D-触发器的集合),而IO则用于表示一个模块的接口(比如某个具体的集成电路的引脚)。前面也提到,Wire、Reg和IO可以封装任何Chisel类型,当然也包括Bundle和Vec。
在Scala中,变量分为var和val两种类型,前者是可变的,后者是不可变的。而在Chisel中,我们只需要使用val来描述电路,即不可变的Scala变量,比如:
val number = Wire(UInt())
val reg = Reg(SInt())
我们可以在声明后再将值或表达式赋值或重新赋值给Wire、Reg或IO,用到的Chisel操作符是:=:
number := 10.U
reg := value - 3.U
这里显然和Scala中的赋值操作符=是不一样的。这两种操作符怎么用呢?很简单,在创建一个硬件对象的时候我们使用Scala操作符=,而在给已经存在的硬件对象赋值或重新赋值的时候,就使用Chisel操作符:=。
组合逻辑值也是可以条件赋值的,但是需要在条件的每个分支都赋值。否则的话,会引入锁存器(latch),这是Chisel编译器不接受的。最好的办法就是在创建Wire的时候就给定一个默认值,因此,前面的代码这样写更好:
val number = WireDefault(10.U(4.W))
同理,之前提到过,Chisel会为信号和寄存器推断需要的位宽,但是最好还是在创建硬件对象的时候指定想要的位宽。在大多数场合,给寄存器一个已知的复位初始化值也是最好的:
val reg = RegInit(0.S(8.W))
RegInit和WireDefault稍有不同,前者指的是复位时的值,而后者指的是默认连接。
至于IO,用于声明一个模块的接口,用法通常如下:
val io = IO(new Bundle {
val in_a = Input(UInt(8.W))
val out_b = Output(UInt(8.W))
})
IO()里面是个bundle的实例,bundle内是输入输出接口,分别用Input和Output封装。这里仅简单介绍,后面会展开讲述。
如何理解Chisel生成硬件
我们到现在为止,已经解除了一些Chisel的基本代码,看起来跟传统的编程语言比如C和Java这种差不多。但是,Chisel和其他硬件描述语言一样,确实是定义硬件组件的。区别在哪里呢?在软件中,代码是一行一行按顺序执行的,而在硬件中所有的代码行是并行执行的。
写Chisel的时候一定要牢记Chisel确实是生成硬件的。你可以想象,或者在纸上画,一个个由我们写的Chisel电路描述生成的模块。每次创建一个组件,都会添加一个硬件,每条赋值语句,都会生成一个门电路和/或触发器。
那么从技术上来讲,Chisel在执行代码的时候,是执行的Scala程序,然后通过执行Chisel语句,集合(collect)所有的硬件组件并把这些节点连接起来。这些硬件节点构成的网络就是Chisel生成的硬件,可以生成为Verilog代码用于ASIC或FPGA综合,也可以用Chisel tester进行测试。这些硬件节点构成的网络就是完全并行执行的!
对于之前写软件的人来讲理解这种并行执行可能有点困难,因为它跟软件的并行程序还不一样,硬件就是天然并行的,不需要把程序分配给各个线程,也不需要为线程间通信搞什么加锁,就是很简单的并行执行,电流在硬件的每一部分同时运转,仅此而已。
结语
刚接触硬件描述语言的时候,我也很困惑,经常用写软件的思维来写硬件,最后写完的东西完全不是想象中的样子。只能把写软件的思维收一收,简单地把写硬件理解为搭积木,我们要做的工作就是把它们有逻辑地连接起来。
到目前为止,我们还没运行过代码,只是学习了基础的Chisel语法。下一篇文章,我们会学习如何利用sbt构建我们的Chisel项目并运行,同时也简单介绍Chisel的工具流,敬请期待。
边栏推荐
- Lick the dog until the last one has nothing (state machine)
- SCM polling program framework based on linked list management
- Variable promotion and function promotion in JS
- BLOB,TEXT GEOMETRY or JSON column 'xxx' can't have a default value query 问题
- .Net之延迟队列
- Oracle was named the champion of Digital Innovation Award by Ventana research
- 2022年山东省安全员C证考试题库及在线模拟考试
- 动画与过渡效果
- C language dormitory management query software
- 结合案例:Flink框架中的最底层API(ProcessFunction)用法
猜你喜欢

SCM polling program framework based on linked list management

Getting started with the go language is simple: go implements the Caesar password
Three schemes to improve the efficiency of MySQL deep paging query

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

安装trinity、解决报错

.Net之延迟队列

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

華昊中天沖刺科創板:年虧2.8億擬募資15億 貝達藥業是股東

英视睿达冲刺科创板:年营收4.5亿 拟募资9.79亿

数据库公共字段自动填充
随机推荐
结合案例:Flink框架中的最底层API(ProcessFunction)用法
博士申请 | 西湖大学学习与推理系统实验室招收博后/博士/研究实习等
MySQL version 8 installation Free Tutorial
Redis - how to install redis and configuration (how to quickly install redis on ubuntu18.04 and centos7.6 Linux systems)
qt 怎么检测鼠标在不在某个控件上
js中的变量提升和函数提升
Go 语言入门很简单:Go 实现凯撒密码
XML入门一
JVM 内存布局详解,图文并茂,写得太好了!
担心“断气” 德国正修改《能源安全法》
C#基础深入学习一
Interview disassembly: how to check the soaring usage of CPU after the system goes online?
FS7867S是一款应用于数字系统供电电源电压监控的电压检测芯片
安装trinity、解决报错
Openharmony application development how to create dayu200 previewer
30:第三章:开发通行证服务:13:开发【更改/完善用户信息,接口】;(使用***BO类承接参数,并使用了参数校验)
Introduction to reverse debugging PE structure resource table 07/07
sharding key type not supported
面试拆解:系统上线后Cpu使用率飙升如何排查?
C语言小型商品管理系统