前言
大家好,我是jiantaoyab,这是我所总结作为学习的笔记第16篇,在本篇文章给大家介绍FPGA和ASIC。
一个四核i7的CPU的晶体管中有20亿的晶体管,需要链接起20亿的晶体管可不是一件容易的事情,所以设计一个CPU需要用年来算,但是每验证一个新的方案都需要单独生产一块新的芯片,代价太大了。
能不能设计一个硬件,通过不同的程序代码,来操作这个硬件之前的电路连线,通过“编程”让这个硬件变成我们设计的电路连线的芯片呢。于是FPGA出现了。
FPGA
现场可编程门阵列(Field-Programmable Gate Array)。
- P 代表 Programmable,说这是一个可以通过编程来控制的硬件。
- G 代表 Gate ,它就代表芯片里面的门电路。我们能够去进行编程组合的就是这样一个一个门电路。
- A 代表的 Array,叫作阵列,说的是在一块 FPGA 上,密密麻麻列了大量 Gate 这样的门电路。
- 最后一个 F,是说一块 FPGA 这样的板子,可以进行在“现场”多次地进行编程。它不像 PAL(Programmable Array Logic,可编程阵列逻辑)这样更古老的硬件设备,只能“编程”一次,把预先写好的程序一次性烧录到硬件里面,之后就不能再修改了。
通过FPGA,我们可以像软件一样对硬件编程,可以反复烧录,还有海量的门电路,可以组合实现复杂的芯片功能。
怎么样去编程这些线路呢?
用存储换功能实现组合逻辑
在实现 CPU 的功能的时候,我们需要完成各种各样的电路逻辑。在 FPGA 里,这些基本的电路逻辑,不是采用布线连接的方式进行的,而是预先根据我们在软件里面设计的逻辑电路,算出对应的真值表,然后直接存到一个叫作 LUT(Look-Up Table,查找表)的电路里面。
这个 LUT ,其实就是一块存储空间,里面存储了“特定的输入信号下,对应输出 0 还是 1”。
举个例子来帮助理解
假如现在我们要实现一个函数,这个函数需要返回斐波那契数列的第 N 项,并且限制这个 N 不会超过 100。该怎么解决这个问题呢?
斐波那契数列的通项公式是 f(N) = f(N-1) + f(N-2) 。所以,我们的第一种办法,自然是写一个程序,从第 1 项开始算。但其实还有一种办法,就是我们预先用程序算好斐波那契数量前 100 项,然后把它预先放到一个数组里面。这个数组就像 [1, 1, 2, 3, 5…] 这样。当要计算第 N 项的时候呢,我们并不是去计算得到结果,而是直接查找这个数组里面的第 N 项。
这里面的关键就在于,这个查表的办法,不只能够提供斐波那契数列。如果我们要有一个获得 N 的 5 次方的函数,一样可以先计算好,放在表里面进行查询。这个“查表”的方法,其实就是 FPGA 通过 LUT 来实现各种组合逻辑的办法。
对于需要实现的时序逻辑电路,在 FPGA 里面直接放上 D 触发器,作为寄存器
这个和 CPU 里的触发器没有什么本质不同。
不过,我们会把很多个 LUT 的电路和寄存器组合在一起,变成一个叫作逻辑簇(Logic Cluster)的东西。在 FPGA 里,这样组合了多个 LUT 和寄存器的设备,也被叫做 CLB(Configurable Logic Block,可配置逻辑块)。
我们通过配置 CLB 实现的功能有点儿像全加器。它已经在最基础的门电路上做了组合,能够提供更复杂一点的功能。更复杂的芯片功能,我们不用再从门电路搭起,可以通过 CLB 组合搭建出来。
FPGA 通过可编程逻辑布线,来连接各个不同的 CLB,最终实现芯片功能
这个可编程逻辑布线,你可以把它当成我们的铁路网。整个铁路系统已经铺好了,但是整个铁路网里面,设计了很多个道岔。我们可以通过控制道岔,来确定不同的列车线路。在可编程逻辑布线里面,“编程”在做的,就是拨动像道岔一样的各个电路开关,最终实现不同 CLB 之间的连接,完成我们想要的芯片功能。
于是,通过 LUT 和寄存器,我们能够组合出很多 CLB,而通过连接不同的 CLB,最终有了我们想要的芯片功能。最关键的是,这个组合过程是可以“编程”控制的。而且这个编程出来的软件,还可以后续改写,重新写入到硬件里。
FPGA 本质上是一个可以通过编程,来控制硬件电路的芯片。我们通过用 LUT 这样的存储设备,来代替需要的硬连线的电路,有了可编程的逻辑门,然后把很多 LUT 和寄存器放在一起,变成一个更复杂的逻辑电路,也就是 CLB,然后通过控制可编程布线中的很多开关,最终设计出属于我们自己的芯片功能。FPGA,常常被我们用来进行芯片的设计和验证工作,也可以直接拿来当成专用的芯片,替换掉 CPU 或者 GPU,以节约成本。
ASIC
ASIC(Application-Specific Integrated Circuit),专用集成电路。
因为 ASIC 是针对专门用途设计的,所以它的电路更精简,单片的制造成本也比 CPU 更低。而且,因为电路精简,所以通常能耗要比用来做通用计算的 CPU 更低。
那么,我们能不能用刚才说的 FPGA 来做 ASIC 的事情呢?当然是可以的。
我们对 FPGA 进行“编程”,其实就是把 FPGA 的电路变成了一个 ASIC。这样的芯片,往往在成本和功耗上优于需要做通用计算的 CPU 和 GPU。
那你可能又要问了,那为什么我们干脆不要用 ASIC 了,全都用 FPGA 不就好了么?
你要知道,其实 FPGA 一样有缺点,那就是它的硬件上有点儿“浪费”。这个很容易理解,我一说你就明白了。
每一个 LUT 电路,其实都是一个小小的“浪费”。一个 LUT 电路设计出来之后,既可以实现与门,又可以实现或门,自然用到的晶体管数量,比单纯连死的与门或者或门的要多得多。同时,因为用的晶体管多,它的能耗也比单纯连死的电路要大,单片 FPGA 的生产制造的成本也比 ASIC 要高不少。
当然,有缺点就有优点,FPGA 的优点在于,它没有硬件研发成本。ASIC 的电路设计,需要仿真、验证,还需要经过流片(Tape out),变成一个印刷的电路版,最终变成芯片。这整个从研发到上市的过程,最低花费也要几万美元,高的话,会在几千万乃至数亿美元。更何况,整个设计还有失败的可能。所以,如果我们设计的专用芯片,只是要制造几千片,那买几千片现成的 FPGA,可能远比花上几百万美元,来设计、制造 ASIC 要经济得多。
相比 FPGA,ASIC 在“专用”上更进一步。它是针对特定的使用场景设计出来的芯片,比如,摄像头、音频、“挖矿”或者深度学习。虽然 ASIC 的研发成本高昂,但是生产制造成本和能耗都很低。所以,对于有大量需求的专用芯片,用 ASIC 是很划算的。