深入理解FPGA Verilog HDL语法(一)


深入理解FPGA Verilog HDL语法(一)

时间:2025-03-13  作者:Diven  阅读:0

 

今天给大侠带来的是一周掌握FPGA Verilog HDL 语法,今天开启第一天,下面咱们废话就不多说了,一起来看看吧。
 在学习中,学习任何东西都有一个过程,一个初步认识到慢慢了解再到精通掌握的过程,当然,学习Verilog HDL语法也是一样,首先你要了解什么是Verilog HDL,然后结合实践再遵从理论,你才可能理解的更加迅速更加透彻。   Verilog HDL是一种用于数字逻辑电路设计的语言。用Verilog HDL描述的电路设计就是该电路的Verilog HDL模型。Verilog HDL既是一种行为描述的语言也是一种结构描述的语言。这也就是说,既可以用电路的功能描述也可以用元器件和它们之间的连接来建立所设计电路的Verilog HDL模型。Verilog模型可以是实际电路的不同级别的抽象。这些抽象的级别和它们对应的模型类型共有以下五种。
  • 系统级(system):用高级语言结构实现设计模块的外部性能的模型。

  • 算法级(algorithm):用高级语言结构实现设计算法的模型。

  • RTL级(Register Transfer Level):描述数据在寄存器之间流动和如何处理这些数据的模型。

  • 门级(gate-level):描述逻辑门以及逻辑门之间的连接的模型。 

  • 开关级(switch-level):描述器件中三极管和储存节点以及它们之间连接的模型。

     

 

 

一个复杂电路系统的完整Verilog HDL模型是由若干个Verilog HDL模块构成的,每一个模块又可以由若干个子模块构成。其中有些模块需要综合成具体电路,而有些模块只是与用户所设计的模块交互的现存电路或激励信号源。利用Verilog HDL语言结构所提供的这种功能就可以构造一个模块间的清晰层次结构来描述极其复杂的大型设计,并对所作设计的逻辑电路进行严格的验证。Verilog HDL行为描述语言作为一种结构化和过程性的语言,其语法结构非常适合于算法级和RTL级的模型设计。这种行为描述语言具有以下功能:

  • 可描述顺序执行或并行执行的程序结构。 
  • 用延迟表达式或事件表达式来明确地控制过程的启动时间。 
  • 通过命名的事件来触发其它过程里的激活行为或停止行为。 
  • 提供了条件、if-else、case、循环程序结构。 
  • 提供了可带参数且非零延续时间的任务(task)程序结构。 
  • 提供了可定义新的操作符的函数结构(function)。 
  • 提供了用于建立表达式的算术运算符、逻辑运算符、位运算符。 

 

 

 

Verilog HDL语言作为一种结构化的语言也非常适合于门级和开关级的模型设计。因其结构化的特点又使它具有以下功能: 

  • 提供了完整的一套组合型原语(primitive); 
  • 提供了双向通路和电阻器件的原语; 
  • 可建立MOS器件的电荷分享和电荷衰减动态模型。
  

 

Verilog HDL的构造性语句可以精确地建立信号的模型。这是因为在Verilog HDL中,提供了延迟和输出强度的原语来建立精确程度很高的信号模型。信号值可以有不同的的强度,可以通过设定宽范围的模糊值来降低不确定条件的影响。Verilog HDL作为一种高级的硬件描述编程语言,有着类似C语言的风格。其中有许多语句如:if语句、case语句等和C语言中的对应语句十分相似。如果读者已经掌握C语言编程的基础,那么学习Verilog HDL并不困难,我们只要对Verilog HDL某些语句的特殊方面着重理解,并加强上机练习就能很好地掌握它,利用它的强大功能来设计复杂的数字逻辑电路。下面我们将对Verilog HDL中的基本语法逐一加以介绍。    简单的Verilog HDL模块   

 

简单的Verilog HDL程序介绍

下面先介绍几个简单的Verilog HDL程序,然后从中分析Verilog HDL程序的特性。

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
Module adder ( count,sum,a,b,cin ); input [2:0] a,b;  input cin; output count;  output [2:0] sum; assign {count,sum} = a + b + cin;endmodule
上面这个例子通过连续赋值语句描述了一个名为adder的三位加法器可以根据两个三比特数a、b和进位(cin)计算出和(sum)和进位(count)。从例子中可以看出整个Verilog HDL程序是嵌套在module和 endmodule 声明语句里的。  

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
module compare ( equal,a,b );    input [1:0] a,b; //声明输入信号a,b   output equal; //声明输出信号equal  assign equal=(a==b)?1:0;     endmodule

上面这个程序通过连续赋值语句描述了一个名为compare的比较器。对两比特数 a、b 进行比较,如a与b相等,则输出equal为高电平,否则为低电平。在这个程序中,和//.........表示注释部分,注释只是为了方便程序员理解程序,对编译是不起作用的。

 

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
module trist2(out,in,enable); input in, enable;  output out;  bufif1 mybuf(out,in,enable);   endmodule

上面这个程序描述了一个名为trist2的三态驱动器。程序通过调用一个在Verilog语言库中现存的三态驱动器实例元件bufif1来实现其功能。

 

 

 

  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
module trist1(out,in,enable); input in, enable;  output out; mytri tri_inst(out,in,enable); //调用由mytri模块定义的实例元件tri_inst endmodule 
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
module mytri(out,in,enable); input in, enable;  output out; assign out = enable? in : 'bz;endmodule

这个程序例子通过另一种方法描述了一个三态门。在这个例子中存在着两个模块。模块trist1调用由模块mytri定义的实例元件tri_inst。模块trist1是顶层模块。模块mytri则被称为子模块。 

 

 

 

通过上面的例子可以了解到:

  • Verilog HDL程序是由模块构成,每个模块的内容都是嵌在module和endmodule两个语句之间。每个模块实现特定的功能。模块是可以进行层次嵌套的。正因为如此,才可以将大型的数字电路设计分割成不同的小模块来实现特定的功能,最后通过顶层模块调用子模块来实现整体功能。

  • 每个模块要进行端口定义,并说明输入输出口,然后对模块的功能进行行为逻辑描述。

  • Verilog HDL程序的书写格式自由,一行可以写几个语句,一个语句也可以分写多行。

  • 除了endmodule语句外,每个语句和数据定义的最后必须有分号。

  • 可以用和//.......对Verilog HDL程序的任何部分作注释。一个有使用价值的源程序都应当加上必要的注释,以增强程序的可读性和可维护性。

 

 

 

模块的结构

Verilog的基本设计单元是“模块”(block)。一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能,即定义输入是如何影响输出的。下面举例说明:
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
module block (a,b,c,d);  input a,b; output c,d;  assign c= a | b ; assign d= a & b; endmodule

上面的例子,程序模块下面是一个电路图的符号。在众多时候,程序模块和电路图符号是一致的,这是因为电路图符号的引脚也就是程序模块的接口。而程序模块描述了电路图符号所实现的逻辑功能。上面的Verilog设计中,模块中的第3、第4行说明接口的信号流向,第6、第7行说明了模块的逻辑功能。以上就是设计一个简单的Verilog程序模块所需的全部内容。从上面的例子可以看出,Verilog结构完全嵌在module和endmodule声明语句之间,每个Verilog程序包括四个主要部分:端口定义、I/O说明、内部信号声明、功能定义。  

 

模块的端口定义

模块的端口声明了模块的输入输出口。

其格式如下:module 模块名(口1,口2,口3,口4, ………); 

 

 

 

模块内容 

模块的内容包括I/O说明、内部信号声明、功能定义。

1、I/O说明的格式如下:

输入口:input 端口名1,端口名2,………,端口名i; //(共有i个输入口) 

输出口:output 端口名1,端口名2,………,端口名j; //(共有j个输出口)

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

  •  
module module_name(input port1,input port2,…output port1,output port2… );

ICa Neue', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei UI', 'Microsoft YaHei', Arial, sans-serif;letter-spacing:.544px;white-sp