数字通信同步技术的MATLAB与FPGA实现:Altera/Verilog版(第2版)
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.5.3 Verilog HDL的程序结构

Verilog HDL的基本设计单元是模块,一个模块由两部分组成,一部分用于描述端口,另一部分用于描述逻辑功能,即定义输入是如何影响输出的。下面是一段完整的Verilog HDL程序代码。

     module block (a,b,c,d)
         input a,b;    
         output c,d;
         assign c= a | b;
         assign d= a & b;
     endmodule

在上面的例子中,模块block的第2行和第3行说明了端口的信号流向,第4行和第5行说明了模块的逻辑功能。以上就是设计一个简单的Verilog HDL程序所需的全部内容。从这个例子可以看出,Verilog HDL的程序结构完全嵌在module和endmodule之间,每个Verilog HDL程序包括四个主要部分:端口定义、I/O说明、内部信号声明和逻辑功能定义。

(1)端口定义。模块的端口声明了模块的输入/输出端口,其格式如下:

     module 模块名(端口1,端口2…)

(2)模块内容。模块的内容包括I/O说明、内部信号声明和逻辑功能定义。I/O说明的格式为:

     输入端口:input  端口名1,端口名2,…,端口名i;     //共有i个端口
     输出端口:output 端口名1,端口名2,…,端口名j;     //共有j个端口

I/O说明也可以写在端口声明语句里,其格式如下:

     module 模块名(input 端口1,input 端口2,…,output 端口1,input 端口2…);

内部信号说明是指在模块内用到的与端口有关的wire和reg变量的声明,例如:

     reg  [width-1: 0] R变量1,R变量2…;
     wire [width-1: 0] W变量1,W变量2…;

模块中最重要的部分是逻辑功能定义部分。有三种方法可以在模块中实现逻辑功能定义:采用assign声明语句、采用实例元件和采用always块。下面分别是采用三种方法实现逻辑功能定义的例子。

     //采用assign声明语句
     assign a = b & c;
     
     //采用实例元件
     and and_inst(q, a, b);
     
     //采用always块
     always @(posedge clk or posedge clr)
        begin
          if (clr)  q <= 0;
          elseif (en) q <= d;
        end

需要注意的是,如果用Verilog HDL模块实现一定的功能,首先应该清楚哪些是同时发生的,哪些是顺序发生的。上面三个例子分别采用了assign声明语句、实例元件和always块,这三个例子描述的逻辑功能是同时执行的。也就是说,如果把这三个例子写到一个Verilog HDL模块文件中,它们的次序不会影响逻辑实现的功能。这三个例子是同时执行的,也就是并发的。

然而,在always块中,逻辑是按照指定的顺序执行的。always块中的语句称为顺序语句,因为它们是顺序执行的。请注意,两个或多个always块也是同时执行的,但是always块内部的语句是顺序执行的。看一下always块内的语句,就会明白它是如何实现功能的。if…else…if必须顺序执行,否则其功能就没有任何意义。如果else语句在if语句之前执行,功能就不符合要求。为了能实现上述描述的功能,always块中的语句将按照书写的顺序执行。