最新更新—2021.7.17
参考引用了以下两篇文章的部分内容:
1、谈谈Chisel硬件设计语言
2、Chisel语言初识及硬件设计敏捷开发趋势分析
“如果今天我要选用Java之外的一门语言,我将会选择Scala。” —— James Gosling,Java之父
在今天众多的编程语言中,Java常常是软件开发者的首选语言。而能让Java之父给出如此评价的Scala,想必有其吸引人之处。那么,Scala究竟是一门什么样的语言呢?
Scala是一门基于JVM(Java Virtual Machine)运行的语言,而且它与Java互相兼容,在设计之初就考虑了与Java的无缝衔接,两者能互相调用。但是它的设计者的目的,是想创造一门比Java更好用、更高效、更优秀的语言。从运行机制上讲,Scala会被编译成与Java一样的字节码,交由JVM运行,所以程序速度和Java一样快。从实用性来看,它的形式比Java简洁的多,语法功能更加强大,代码量往往比相同功能的Java少很多。尽管这还是一门小众的语言,但不妨你去试着学习一下。
Scala是一门面向对象的函数式语言。时至今日,面向对象已经成为编程语言必不可少的属性,其强大之处自不必过多解释。但另一方面,Scala没有选择更多人熟悉的指令式编程风格,而是选用了更为小众的函数式编程理念。对于熟悉C/C++、Java、Python等流行语言的读者来说,可能从未接触过函数式编程。请稍安勿躁,只需要基本的学习,读者便能掌握基本的函数式编程,并会逐步发现函数式编程的妙处。Scala提倡使用者使用函数式编程,但也预留了指令式编程的余地。
正如它名字取自的“Scalable”一样,这也是一门可以自由伸缩的语言:既能裁剪已有的类库,又能扩展自定义类库;既能用于完成一个简单的脚本,又足以胜任任何复杂、庞大的软件系统。它的语法比Python还简洁,它的抽象能力比C++还高级。正因此Scala的学习曲线并非平滑的,而是阶梯状的。也正因此,如果你能耐心学会Scala,并逐步掌握它提供的高级语法,深入理解其编程理念,那么你就会发现这很可能是一门让你爱不释手、相见恨晚的编程语言。
Scala最大的优势,可能就是其各种语法便利造就的强大伸缩性,进而成为一种优秀的宿主语言。换句话说,开发者可以方便地利用自定义Scala类库,快速开发出“新”语言,专门用于某一特殊用途。目前,它是公认构建DSL(domain-specific languages)最好的宿主语言(这个有待考证)。
目前,基本上有三种方法做数字电路设计。
- 一是用HDL来做,像verilog和vhdl都是常见的hdl。
- 二是HLS(high level synthesis)。
- 三是一些解释类型的高效率语言,例如system verilog 和把python翻译成verilog的解释器。
下面就分别说一下这三种方法的特点:
① Verilog/VHDL的缺点主要有以下几个方面:
1)啰嗦。 一个net可能在module port中声明一次,在变量声明中声明一次,再具体使用中还要时不时地指名它的位宽。这种明显的机器编译可以做的工作一定要人工来做,不但效率奇低而且bug频出。啰嗦的另一个缺点是代码可读性差,几乎不具有可读性,读着读着就找不到上次使用在哪里了。
2)并不和硬件电路真正对应。 这一点乍听起来很难理解,verilog不就是写电路的吗?然而,verilog在设计之初并不是这样,verilog里甚至没有明确的时钟概念,只是通常的综合器会将带沿的always模块中的敏感变量认定为时钟。这导致了一不留神忘了写异步复位端,电路结构发生变化,甚至不小心写出数字逻辑环,写出latch等等。在综合阶段,我们经常需要清理掉各种各样的奇怪问题。
3)没有自带的一致性检查。 理论上来说,一个reg或者wire,在它的所有赋值,连接,断言中,它的位宽或者其他属性都是可以由工具检查的,但verilog却从来没有,这也导致了相当数量的bug存在。
4)参数化很差。 function 和task的封装不干净,参数传递也很不清楚。导致大规模项目中代码的复用性奇差,重复劳动过多。
② HLS
HLS的概念很早就有人提出并且做出来了,但这些年一直发展不尽如人意,究其原因还是设计理念的区别。例如一个
c to verilog
的高层次综合工具,往往对c的写法有各种各样的限制。在实际使用中,熟悉c的程序员写出的代码经常是不能直接使用或者直接使用后效率奇低的,这位c的开发人员需要先学习电路知识,再学习这个工具的规范,然后才能进行开发。开发后的c已经不能称之为c了,高效率的特性一扫而光,随之带来的啰嗦,奇怪的语法随处可见。
③ SystemVerilog等解释型语言
至于高效率的解释型语言,下面会提到它们的特点。
对每个数字电路工程师而言,Verilog再熟悉不过了,也可能早就无力吐槽了。诚然,Verilog还是C语言时代的产物,现如今,开发效率低下的问题越来越明显。软件开发效率早已用其他语言突飞猛进,晶体管密度也随摩尔定律水涨船高,而我们最前端的HDL语言似乎还在原地踏步。
早在二三十年前,人们就认为Verilog/VHDL快要过时了,当时的开发者主要分成三大派:一派主张应该改进Verilog,另外两派则主张把语言转移到软件语言(一派主张C++,一派主张Java),这样就能获得开源的综合工具和仿真器。最终,Verilog的改进版获胜了,也就是Verilog的后续标准——SystemVerilog。一方面,支持改进Verilog的人占多数;另一方面,也得到了Intel的支持。
然而,SystemVerilog并不是非常好用。首先,尽管它引入了面向对象,但是却只能用于验证,因为验证更像是软件,而不是硬件设计。其次,SystemVerilog解决了一些Verilog语法瑕疵,使得硬件设计更为方便,但效果并不明显,治标不治本。再者,EDA厂商对SystemVerilog的支持不够积极,新特性到现在也不是全都实现了,使得工业界仍然偏向采用Verilog-2001。总结起来,从Verilog到SystemVerilog,并没有C到C++那样巨大的飞跃。
那么主张C++的那一派呢?也就是我们现在熟悉的SystemC。事实上,SystemC也就是用C++定义的一堆类库。SystemC的开发多数还是用在事务级,即编写硬件模型。用SystemC直接开发硬件并不多见,因为目前EDA工具支持的不够好,相比Verilog,开发出来的电路优化得很差。
那么主张Java的那些人呢?似乎我们现在才看到基于Java平台的HDL语言——Chisel出现,尽管Scala不是Java,但是基于JVM。Chisel(Constructing Hardware In a Scala Embedded Language)是一门以Scala为宿主语言开发的硬件构建语言,它是由加州大学伯克利分校的研究团队发布的一种新型硬件设计语言。据团队成员之一Krste Asanovic教授介绍,早在30多年前还没有硬件描述语言的时候,他们就已经开始构想这样一种语言了。最开始Chisel是基于Ruby的,但是后来发现Scala更适合构建Chisel。因为Scala有诸多特性适合描述电路,比如它是静态语言,以编译期为主,适合转换成Verilog/VHDL。再比如它的操作符即方法、柯里化、纯粹的面向对象、强大的模式匹配、便捷的泛型编写、特质混入、函数式编程等特性,使得用Scala开发DSL语言很方便。
① 通过firrtl编译器可以把Chisel文件转换成firrtl文件,这是一种标准的中间交换格式,也就是让各种高级语言方便地转换到Verilog/VHDL的媒介,但它其实和verilog/VHDL属于同一层次。在这里,Chisel选择了妥协,没有直接生成电路,而是借助Verilog,主要是因为没有EDA工具支持。将来也许会有EDA工具直接支持Chisel。
chisel转换成verilog的过程大致如下:
AST
中间数据;“.fir”
的文件;Verilog
代码。Firrtl编译器也并不是只针对Chisel,有兴趣和能力的读者也可以开发针对Java、Python、C++等语言的Firrtl编译器。因为Firrtl只是一种标准的中间媒介,如何从一端到另一端,完全是自定义的。
另外,Firrtl也并不仅仅是生成Verilog,同样可以开发工具生成VHDL、SystemVerilog等语言。
② chisel是一种hdl,并不是hls,这就意味着它和真实电路是唯一对应的。它有时钟的概念,有寄存器概念(verilog中的reg不一定是寄存器,但chisel中的reg就是寄存器),有net概念。
③ chisel是一个真正意义上的可综合语言。就是说只要你的代码是chisel编译成功的,那么一定是可综合为唯一电路的(这里不包括chisel为testbench专门做的poke等测试语法)。
④ 由于是基于scala的,chisel继承了它便于封装,便于扩展的特性。于是,真正意义上,我们在整个工程中只用写一个queue的可参数化类,在任意的地方都可以随意调用这个类,实现各种类型,各种深度的队列。参数化,代码复用更加方便高效。其实,Scala里的语法,在Chisel里基本都能用,比如Scala的基本值类、内建控制结构、函数抽象、柯里化、模式匹配、隐式参数等等。但是要注意这些代码不仅要通过Scala编译器的检查,还需要通过Firrtl编译器的检查。
⑤ 在互连方面,chisel设计了bundle的概念,于是成千上百的端口互联只用一句程序就可以实现,干净简单还不容易出错。
⑥ 在编译器方面,chisel的编译器可以实现功能相当强大的错误检查。基本上,如果一个reg或者wire是中间变量,chisel不建议我们声明它的位宽,编译器会在编译过程中自动推断它的位宽。在一个连接链上,编译器会检查所有的东西位宽一致。这就杜绝了很多低级人为错误的出现。
Hardware construction language (not C to Gates):硬件构建语言
Algebraic construction and wiring
Embedded in the Scala programming language:内嵌于Scala程序设计语言
Abstract data types and interfaces:抽象的数据类型和接口
Bulk connections:端口的批量连接
Hierarchical + object oriented + functional construction:分层+面向对象+函数构建
Highly parameterizable using metaprogramming in
Scala:通过使用Scala的元编程实现高度的参数化Supports layering of domain specific languages
Sizeable standard library including floating-point
units:具有包含浮点单元在内的、可以调整大小的标准库Multiple clock domains:支持多时钟域
Generates high-speed C+±based cycle-accurate software
simulator:能够产生高速的、基于C++的周期精确软件模拟器Generates low-level Verilog designed to pass on to standard ASIC or
FPGA tools:能够产生Verilog设计,从而在标准的ASIC、FPGA工具中使用Open source on github with modified BSD
license:在github上开源,使用的是改进的BSD协议Complete set of docs:完善的文档
Growing community of adopters:不断增长的社区
1、Chisel目前不支持四态逻辑里的x和z,只支持0和1。由于只有芯片对外的IO处才能出现三态门,所以内部设计几乎用不到x和z。而且x和z在设计中会带来危害,忽略掉它们也不影响大多数设计,还简化了模型。当然,如果确实需要,可以通过黑盒语法与外部的Verilog代码互动,也可以在下游工具链里添加四态逻辑。
2、Chisel会对未被驱动的输出型端口和线网进行检测,如果存在,会进行报错。报错选项可以关闭和打开,取决于读者对设计模型的需求。推荐把该选项打开,尽量不要残留无用的声明。