CH01 FPGA设计Verilog基础笔记(一)

CH01 FPGA设计Verilog基础笔记(一)

一、FPGA技术背景

大规模集成电路设计制造技术和数字信号处理技术,近三十年来,各自得到了迅速的发展。这两个表面上看来没有什么关系的技术领域实质上时紧密相关的。因为数字信号处理系统往往要进行一些复杂的数学运算和数据处理,并且又有实时响应的要求,它们通常是由高速专用逻辑系统或专用数字信号处理器所构成,电路是相当复杂的。因此只有在高速大规模集成电路设计制造技术进步的基础上,才有可能实现真正有意义的实时数字信号处理系统。对实时数字信号处理系统的要求不断提高,也推动了高速大规模集成电路设计制造技术的进步。

FPGA的学习需要一定的单片机和C语言基础。对于单片机来说,它的程序代码是一条指令一条指令的执行的。CPU先通过总线,读取第一条指令,然后解析这条指令,再然后执行这条指令。我们写的C代码总是一条一条地执行。如果我们同时要处理10个子程序,那么CPU必须一个个子程序来执行。如果有些实时性较高的,如矩阵键盘的扫描,VGA刷屏都需要中断来实现。如果刷屏时间过长,就会影响到按键的灵敏度。另外还有,单片机在用串口收发数据,同时我们的单片机要处理外部的IO信号,如果我们的IO信号非常快,并且有几百个信号可能在同一时间触发,很可能单片机就没法实现。

针对以上列出的两种情况,如果用FPGA就可以很方便地解决。由于FPGA的并行性,不管是扫描键盘,还是扫描VGA,都可以把它们当作独立的模块,时间上没有冲突,每个模块可以同时进行。

FPGA的并行性是它的优点,但是顺序性控制却是它的缺点。解决办法也有,例如状态机的设计和在FPGA中运行CPU。下面介绍两个概念,软核和硬核。

软核:软核就是用代码就可以实现的CPU核,这种核配置灵活,成本低。但是占用FPGA宝贵的资源。

硬核:硬核就是一块电路,做到FPGA内部,方便使用,性能更高。比如Xilinx的DDR内存控制器,就是一种硬核,其运行速度非常高,我们只需要做配置就可以使用。

二、Verilog基础语法

单片机的开发语言是C语言,FPGA的开发语言是Verilog,两种语言十分相似,对于熟悉C语言的工程师来说,FPGA的开发语言也方便学习。但是切记不可两者混淆。

  1. 关键字

module()

endmodule

//代表一个模块,代码写在两者之间

/***************************************************/

input 关键词,模块的输入信号。

output 关键词,模块的输出信号。

inout 关键词 模块输入输出双向信号

wire 关键词,寄存器

always@()括号里面是敏感信号。这里的always@(posedge Clk)敏感信号是posedge Clk含义是在上升沿的时候有效。还可以用*表示一个符号,如果是*,则表示一直敏感。

assign用来给output,inout以及wire这些类型进行连线。例如:

wire a, b, y;

assign y = a & b;

/****************************************************/

if…else类似于C语言,这不多做介绍

case…endcase作用域用于状态机的编写

begin…end作用域范围,类似于C的大括号{ }。

parameter定义参数的功能。如:parameter a =180;

include和define都是预处理命令,用于常量阈值的阐述,不过用的时候前面都加一个点,例如:`include `define

符号部分大体根C语言类似,主要说明以下两个符号:

“<=”非阻塞赋值,或者赋值符号,在一个always模块中,所有语句一起更新。当然它也可以表示小于等于。

“=”阻塞赋值,或者给信号赋值,如果在always模块中,这条语句被立刻执行。阻塞赋值和非阻塞赋值将在后面进行详细说明。

  1. 基数表示法

[size]`[signed] base value

size是指该常量用二进制表示的位数(位宽);signed是小写s或者大写S;base为o或O(表示八进制),b或B(表示二进制),d或D(表示十进制),h或H(表示十六进制)之一;value是基于base值的数字序列。例如:

5 `o37           5位八进制数

4 `D2            4位十进制数

4 `B1x_01    4位二进制数

  1. 阻塞赋值和非阻塞赋值

非阻塞赋值比较常见,如下:

reg A;

reg B;

always @(posedge clk)

begin

         A<= 1`b1;

         B<= 1`b1;

/****或者**

         B<= 1`b1;

         A<= 1`b1;

***********/

                    end

                   这段程序里,A和B是同时被赋值的,具体是说在时钟的上升沿来的时刻,A和B同时被置1.调换A和B的上下顺序,将得到相同的结果。

         接着看另外一段程序:

                   reg A;

                   reg B;

                   always @(posedge clk)

                            begin

                                     A<=1`b1;

                            end

                   always @(posedge clk)

                                     A<=1`b1;

                            end

                   这段程序,与上一段程序也是完全等价的,A和B在同一时刻被赋值。两端程序的综合逻辑也是一样的,这就是非阻塞赋值的特点,体现了FPGA的并行性!

         接下来看阻塞赋值,它少了一个非,表示会阻塞住,那么体会下这个阻塞:

 

                   always @(posedge clk)

                            begin

                                     A = 1`b1;

                                     B <= 1`b1;

                            end  

         这个程序是阻塞和非阻塞的混合使用,一般禁止这么写。程序流程:当时钟上升沿来临时,首先A会被置1,然后B寄存器再被置1.区别就是A和B不会被同时置1,A要比B提前零点几纳秒。这样就出现了先后顺序,但这个过程还是在一个时钟内完成的,只不过A要比B提前零点几纳秒。对于低速时钟来说,这影响不大,但随着时钟速度的提高,这样的语句就要小心了。

  1. Verilog HDL 代码规范

项目架构设计:

命名规则:

1、  顶层文件

对象+功能+top

比如:video_oneline_top

2、  逻辑控制文件

介于顶层和驱动层文件之间

对象+ctr

比如:ddr_ctr.v

3、  驱动程序命名

对象+功能+dri

比如:lcd_dri.v、uart_rxd_dri.v

4、  参数文件命名

对象+para

比如:lcd_para.v

5、  模块接口命名

文件名+u

比如:lcd_dir  lcd_dir_u(……)

特征名+文件名+u

比如:mcb_read   c3_mcb_rad_u

6、  程序注释

程序注释根C语言类似,用“//”

7、  信号命名

对象+功能(+极性)+特性

8、  时钟信号

对象+功能+特性

比如:phy_txclk_i、sys_50mhz_i

9、  复位信号

对象+功能+极性+特性

比如:phy_rst_n_i、 sys_rest_n_i

10、    延迟信号

对象+功能+特性1+特征2

比如:fram_sync_i_r0、 fram_sync_r_r1

11、    特定功能计数器

对象+cnt

比如:line_cnt、 div_cnt0、 div_cnt1

功能+cnt

比如:wr_cnt、 rd_rnt

对象+功能+cnt

比如:fifo_wr_cnt、mcb_wr_cnt

对象+对象+cnt

比如:video_line_cnt

12、    一般计数器

cnt+序号

用于不容易混淆的计数器

比如:cnt0、cnt1

13、    时序同步信号

对象+功能+特性

比如:line_sync_i、fram_sync_i

14、    使能信号

功能+en

比如:wr_en、rd_en

对象+功能+en

比如:fifo_wr_en、mcb_wr_en

posted @ 2019-12-01 22:28  烟火流沙  阅读(531)  评论(0编辑  收藏  举报