很多人反馈FPGA的开发入门很难,笔者从大学到现在,学习过c/c++/python/matlab/VHDL/verilog等多种软硬件开发语言,对比一下,笔者认为硬件开发语言比软件开发语言要容易的多。以verilog为例,最多只需要记住十几个关键字就可以搞定大部分的硬件开发,根本不像软件开发需要那么多语法,同时还要数不尽的库要调用。
FPGA开发其实是硬件开发,很多没有接触过硬件的人一听就就退缩了,就是在心理上认为FPGA开发很难,那就真的很难入门了。笔者可以负责任的告诉大家,FPGA的开发其实就是和拼搭乐高积木一样,只需要掌握几个最基本的模块,就可以轻松入门FPGA,复杂的模块,不过是基本模块的组合而已,就如可以用基本的乐高模块拼搭出成亲上万种不同的造型。
FPGA开发是不是需要硬件知识,比如电路啦,模电啦,数电啦之类的?笔者的回答是学过更好,没学过也不影响开发,而且笔者会用最通俗的语言,在后续的讲解中培养大家硬件开发的思维。
硬件数字电路一般需要上电后才能运行,而且上电后会一直运行下去,这就需要有个东西支持硬件的运行,这个东西是什么呢?以我们人类为例,人之所以能活着,是因为心脏一直在跳动,从而带动血液循环。同理,数字电路想要正常运行,也需要上电后有个东西一直跳动,这个东西就是晶振,上电后产生不停跳动的时钟,FPGA的开发,就是在时钟的跳动下处理各种任务。
我们都知道,万物都需要动静结合,这是天理。时钟能让数字电路运行起来,那什么能让数字电路静下来呢?是复位!数字电路内的寄存器和查找表在上电的过程中会处于各种不确定的状态,上电后如果直接在这些不确定的状态下继续运行,很容易让电路跑飞,就是无法实现期望的效果。举个例子,就如孩子早晨起来去上学,可能会出现衣服没有穿好,书本忘带,作业忘做等各种状况,但是如果设置一个机制,就是孩子出门前把所有东西都检查一遍,保证孩子处于一个正常的上学状态。电路也是一样,上电完成了,运行正常功能前,先把所有的数字模块复位一下,让系统处于一个已知的可控状态,这样就可以正常运行实际的功能了。
以verilog语言为例,时钟和复位是怎么表述出来的呢?如下所示,一个基本模块的开头一句话里面用到了4个关键字:always,posedge,negedge和or,一个符号@,clk是自定义的时钟信号,rst_n是自定义的复位引号,_n是代表低电平有效,就是低电平复位。
详细解释一下,关键字always就是一直的意思,就是上电后这个模块会一直运行下去。@是探测变化的意思,就是小括号内的信号只要安装规定的动作变化就能被探测到。小括号的内容就是该模块运行的条件,关键字posedge是取上升沿的意思,posedge clk就是clk这个信号的上升沿是触发条件;negedge就是取下降沿的意思,negedge rst_n就是rst_n这个信号的下降沿是触发条件;or就是posedge clk和negedge rst_n这两个条件有一个达到这个模块就会运行。
上面的这个模块,上电后这个模块一直在监控clk和rst_n这两个信号的变化,如下图虚线的地方就是触发条件满足的时刻,这些时刻就可以运行模块内部的功能啦!
FPGA的硬件编程一般就是由多个always模块组成的,这些always模块是相互独立的,就是说这些模块可以同时运行,无论这些always模块写在什么位置!这就是硬件编程的并行思维,不像软件编程,必须是顺序执行的!
可能有人会问,clk一定要取上升沿吗,取下降沿可不可以?答案是肯定可以的,但是要根据实际情况来定,但是一般按照约定俗成clk都是取上升沿,除非根据实际需要取下降沿。像DDR上升沿和下降沿都要采数,这个触发条件怎么写?触发条件可以写成always @(posedge clk or negedge clk),但是最简单的方式是写成always @(clk)就是clk有一点风吹草动就会触发。
今天初步介绍了FPGA硬件编程,明天开始第一个FPGA的硬件编程——通过计数器实现流水灯,流水灯的意义就如软件编程的hello,world!