C语言的编程思想和人脑思考方式接近,都是一种顺序执行结构,也就是同一时间只干一件事。而FPGA的编程思想就有些让人难以理解了,它就像一个天才人类一样,可以做到一心二用、三用,甚至一心十用,他可以左手写毛笔字的同时,右手手机打字聊天,脑子却想着某个女孩到底是不是喜欢自己。 那么,我们到底该如何学习FPGA编程思想呢? 1.弄清楚时序概念在Verilog编程的时候,我们经常会听到“时序”这两个字,想了解时序,就不得不提“时序图”了。
上图是一个SPI接口的时序图,我们会经常在一些芯片的数据手册中看到,SSEL表示片选信号,使用SSEL = 0的时候,SCK、MOSI、MISO才有效。SCK表示SPI接口的时钟信号,有上升沿和下降沿,上图中SCK下降沿的时候MOSI和MISO同时发生数据变化,所以从这个时序看,我建议用户在采样的时候,用SCK的上升沿采样MOSI和MISO的数据。 所以时序是什么呢? 我觉得在Verilog中,时序表示FPGA内部各种信号之间的关系。 2.基础Verilog语法Verilog语法比较多,但我们常用的也就那么几种,简单在此罗列一下。 (1)module(建议一个.v文件只写一个module)module “.v文件名”( “port” ); “用户Verilog程序” endmodule module模块,从软件思想上,可以理解为函数,顶层文件module就是主函数,其他文件module就是被主函数调用的函数。从硬件思想上,可以理解为电路板,顶层文件为电路主板,其他文件是从板,module中的“port”就是主从板之间的跳针。 (2)Port定义Port有三种类型,input、output、inout。很好理解,input就是外部进入module的信号,output就是module输出到外部的信号,inout表示这个端口既能接收外部信号,也能向外部发出信号。 Port在module中的定义有多种,我们在这里只介绍一种。
如图,首先声明module的port为rst_n, in_1, in_2,和out,后面再对port的属性及位宽进行定义。 (3)内部变量声明Verilog内部变量有两种:wire型和reg型。 其中wire型变量可以理解成电路板中的布线,reg型变量可以理解成电路板中的电阻元件或者电容元件等。 (4)assign语句assign语句可以给wire型变量赋值。 例如: wire out ; reg in ; assign out = 0; ///assign out = in; 上面语句表示给out变量接地,//这一行后面的东西都表示注释,表示将寄存器in的值赋值给out变量。 (5)always语句always语句经常给reg型变量赋值,内部经常有if语句和case语句,我觉得可以理解成一块电路板上的芯片元件。 例如:
out_reg为reg型变量,这个always模块可以理解成一个6bit的加法器。上述语句的总体意思为:在osc_clk这个信号上升沿的时候进行判定,若rst_n = 0,则out_reg = 0;否则,out_reg = in1 + in2。 其实always语句里还有涉及到阻塞性赋值和非阻塞性赋值的问题,这里我建议新手只要遇到always,就尽可能使用非阻塞性赋值(<=)。 (6)if语句与case语句这两个语句比较简单,相信看过c代码的人都了解,我就不再一一讲述。
|