Verilog的基本语法

      模块是设计的基本单元,在Verilog中包括行为建模(用于综合和仿真)和结构建模(用于综合)

       在Verilog中,begin和end充当了C语言中大括号的角色,在这两个关键词之间是程序的内容部分;

      模块基本结构:module   module_name(Portlist);//注意此处有分号

                           endmodule   //注意此处没有分号

       端口声明:input、output、inout表示端口数据流的方向;

                      端口的数据宽度:[width:0];    后面紧跟着端口名;

                       示例:

                             input [7:0] port1;

                             声明了一个端口数据宽度为8位,名为port1的输入端口。

     

         数据类型有网络数据类型(表示进程间的物理连接)和寄存器数据类型(表示暂时存储的变量,但不一定表示硬件电路中的物理寄存器),wire和tri都表示一个节点,但是tri表示三态节点,supply0表示逻辑0,supply1表示逻辑1;寄存器类型的变量只能在进程声明、任务或者功能中赋值reg型变量,不能是逻辑门的输出或者assign语句的输出;wire数据类型可以是input、output和inout中的任意一种,但是,寄存器类型的端口只能是output类型;

         在Verilog中默认的数据为32位的十进制数;数字可以为sized和unsized两种类型,一般来说最好要指明数字的宽度、进制,这里的宽度是指将其转化为二进制数后数据的宽度,`d表示十进制,`b表示二进制,`h表示十六进制,`o表示八进制,如果为负数,则在最前面加符负号,举例:-8`h89表示数据宽度为8的负的十六进制数,为sized的类型,可以在数字中间加”_“,提高程序的可读性;

         操作符:+、- 、*、/、&、^、|、!、&&、||、>、<、>=、<=、==、!=、>>、<<、?:、{}等;

         连续赋值语句:assign,左手侧必须是ret数据类型,右手侧可以是net、寄存器或者函数的调用,每当右手侧的操作数发生变化时就会立即更新左手侧的net型数据,在赋值号左侧加上#(time)可以模型逻辑提供仿真延迟,但不会综合成具体的硬件电路;

        进程赋值:initial模块:用于初始化仿真的行为声明,监视、波形和其他进程,会被仿真器忽略,在整个仿真中只执行一次,且是顺序执行;always模块:用于行为声明,来描述电路的功能;每个always和initial模块代表不同的进程,进程之间并行从仿真时间0开始,而进程内的语句顺序执行,注意:always模块和initial模块不能嵌套;

       在进程内部有两类赋值语句,阻塞赋值和非阻塞赋值,阻塞赋值(=)按照模块中指定的顺序执行,有先后顺序之分,而非阻塞赋值(<=)是并发执行,无先后之分;在进程中尽量要避免阻塞赋值这种方式,因为执行过程不好控制。这两种赋值语句的左手侧必须是reg寄存器类型;

       在Verilog综合后的电路中有两种电路类型,组合电路和时序电路,都是用always语句来说明要实现的功能,组合电路对组合逻辑中使用的所有输入敏感,而时序逻辑电路对时钟及控制信号敏感,要注意区分,举例:

                always@(a or b or c)会被编译器综合成组合逻辑电路,

                always@(posedge clk or negedge clk)会被编译器综合成时序逻辑电路,always@后面的括号中的内容叫做敏感信号列表,只要敏感信号一变化就会执行后面的内容;

       行为声明:行为声明有三种,一种是用if·····else来表示,另一种用case语句来表示,这两种表达方式有很大的区别,当使用if·····else语句时,内部的条件语句是顺序评估的,有先后顺序依次执行;而case语句先对执行条件进行分析评估,然后没有优先级的执行相应的内部语句,来完成相应的功能,default关键词是默认的执行状况。这两种语句必须放在always或者initial模块中;因此当自己的模块功能需要设置优先级时就用if·····else语句,否则就用case语句,执行效率最优化原则;还有一个循环声明,用于重复运算,如:forever、while、for和repeat,这几种语句都是用来仿真的,forever语句会无限次的执行,而repeat可以指定执行次数,例如:repeat(8),while和for语句会按照条件是否成立来选择性的执行,注意,在C语言中for循环中的计数变量是可以改变的,而在Verilog中,其内部的计数变量是不可以改变的,一般在电路实现时不用for循环,因为它会生成很多锁存器,并且会将语句展开,浪费FPGA的逻辑资源;

         case语句一般被译成复用器,而if·····else语句一般被译成选择器;另外还有两种case的变形形式,casez和casex,casez语句不关心z处代表的值,而casex语句会不关心z和x处的值,但一定要注意所有的case形式内部的各条件必须是唯一的表达式,不能有歧义,确保在某种状况下只有一个条件是正确的,且一定要加上default这种默认的状况,否则会生成锁存器,影响电路的功能实现;

未完待续~~~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章