官方论坛
官方淘宝
官方博客
微信公众号
点击联系吴工 点击联系周老师
您的当前位置:主页-old > 新闻中心 > FPGA技术教程 > VERILOG >

【文章】私人总结版Verilog语法笔记

发布时间:2021-06-29   作者:admin 浏览量:

1.1 概述


1.2 模块Module


1.3 数据类型

1.3.1 wire/reg线网

wire和reg都是线类型,工程上没区别;只是always/initial模块中输出定义需要为reg型;
注意:不要将reg类型与D触发器混淆,reg理解为因为代码所产生的。例如:

wire [7:0] a;  //定义了8位的wire型数据

wireb;   // 定义了1位的wire型数据

reg [3:0]sum//定义了一个4位的reg型数据

1.3.2 常量


类型

格式

说明

parameter

parameter数据名= 表达式

parameterMSB = 7
//定义参数MSB为常量7;推荐大写;

常量

<位宽><进制><数字>

二进制:Bb

十进制:Dd

八进制:Oo
十六进制:Hh

8b1010_1100 (b表示二进制)
下画线“_,提高阅读性。

<数字>

默认十进制;

4值逻辑

0Logic Low

低电平;

1Logic High

高电平;

xUnknow

不确定;

zHigh Impedance

高阻态; //三态门

1.4 运算符

1.4.1 概述

运算符

说明

算术运算符

()-(减),*(乘),/(除),%(取模);

每个运算符在电路中都是个模块,如加法器,减法器;

!注意:除法,除2^n,是移位运算,

浮点运算就复杂了,因此浮点运算要专用除法器;

关系运算符

>, <, >=, <===(相等), !=(不相等);

逻辑运算符

&&(逻辑与). ||(逻辑或), !(逻辑非);

条件判断语句中,为避免歧义,逻辑运算符二边推荐为1bit

位运算符

&(与),|(或), ~(非), ^(异或); ~^(同或);

移位运算符

<<(左移),>>(右移);

归约操作

&~&|~|^, ~^;//unary reduction

条件运算符

?:

拼接运算符

{}

//{3{a[0]}}:代表3根同样的a[0]线,{a[0],a[0],a[0]}

1.5 设计语句

1.5.1 assign(连续赋值)


1.1.1 always(过程块)

赋值方式

说明

=,阻塞赋值

always @a or b or C or …)

begin

语句块(=if语句, case语句)

end

实现:组合逻辑电路;(注意!禁止用于时序逻辑电路)

always块内,阻塞赋值:是顺序执行(类似C);

敏感表:@*//*”自动添加相关输入信号;

避免出现Latch(锁存器)

分支语句(if语句,case语句)条件不满时,会在电路中自动生成锁存器来保存不满足条件的值,因此要补全if-else,和casedefalut语句;

<=,非阻塞赋值

always @posedge clk or negedge rst_n

begin

语句块(<=if语句, case语句)

end

实现:时序逻辑电路;(注意!禁止用于组合逻辑电路)

always块内,阻塞赋值:并行执行;

if语句

条目

说明

格式1

if(条件)begin

        语句1;

        语句2

end

else begin

        语句1

        语句2

end

格式2

if(条件)begin

        语句1;

        语句2

end

else if begin

        语句1

        语句2

end

else begin

        语句1

        语句2

end

特点

分支语句,各个分支条件不同;顺序执行判断;

注意

if-else成对使用;

case语句

条目

说明

格式

case(表达式)

常量表达式1:begin

语句;

        end

常量表达式2:begin

语句;

        end

常量表达式3:begin

语句;

        end

       default

语句;

endcase

特点

分支语句,各个分支条件相同;并行执行判断;

注意

default语句不可省略;

代码&硬件

1.5.3 模块例化
作用

系统设计时,建议遵循以下设计原则:

1.5.4 全加器

描述方式

描述方式

说明

位置关联

AND u1(a, b, and_out);

名字关联

AND u1(.a(a), .b(b), .oand_out); //推荐使用

1.6.1 结构

1.6.2 特殊符号

语句

说明

`<标识符>

表示:

编译引导语,用于指导仿真编译器在编译时采取一些特殊处理;

编译引导语句一直保持有效,直到被取消或重写;

`timescale

`timescale <时间单位>/<时间精度>

1

`timescale 1ns/1ns  //时间单位1ns;时间精度1ns

#2    //延时2 ×1=2ns

#2.1//延时2.1 × 1 = 2.1ns,精确到1ns,为2ns

2

`timescale 1ns/100ps  //时间单位1ns;时间精度100ps

#2    //延时2 ×1= 2ns

#2.1//延时2.1 × 1 = 2.1ns,精确到100s,为2.1ns

`define

 

`include

`include global.v

包含另一个文件,完整拷贝过来;

`restall

把所有设置的编译引导恢复到缺省状态;

 

#<num>;

#10; //延迟10个时间单位

1.6.3 语句

语句

说明

initial

块语句:只执行一次,always循环执行;不可综合;

作用:

产生激励信号;

检查输出波形;

赋初值;

forever

//产生周期信号:

intial begin

clk = 0

forever

 #10 clk = ~clk;  //时钟信号

end


1.6.4 系统任务和函数

条目

说明

$<标识符>

表示Verilg的系统任务和函数

$time

当前的仿真时间

$display

显示信号值变化:只执行一次,打印当前时刻;

$display($time, b% %b %b”, rst,clk,dout);

$monitor

监视信号值变化:所有过程时刻;

$monitor($time, b% %b %b”, rst,clk,dout);

$stop

暂停仿真

$finish

结束仿真,释放电脑资源;

1.7.1 组合逻辑电路

条目

说明

assign

assign add_cnt = flag==1; //用于简单的组合逻辑电路;

always

always  @(*)begin//统一采用“*”为敏感列表;

=,if,case)语句;//只能使用“=”赋值

end

1.7.2 时序逻辑电路


计数器模板1

3段式模板

模板1

1

计数段

always @( posedge cllk or negedge rst_n) begin

if (!rst_n)

     cnt <= 0;           //初值规定为0

else if (add_cnt)begin//【位置1

if(end_cnt)

            cnt <= 0;

else

               cnt <= cnt + 1;

end

end

2

1条件

assingadd_cnt = d==1;   //d==1: 什么时候开始数脉冲

3

结束条件

assing end_cnt = add_cnt&& cnt == X-1; // X:数多少个脉冲

计数器模板2

3段式模板

模板1

1

计数段

always @( posedge cllk or negedge rst_n) begin

if (!rst_n)

     cnt <= 0;           //初值规定为0

else if (add_cnt)  begin//【位置1

if(end_cnt)

            cnt <= 0;

else

               cnt <= cnt + 1;

end

else

  cnt <= 0;    //不连续,需要清0时,使用模板2

end

2

1条件

assingadd_cnt = d==1;   //d==1: 什么时候开始数脉冲

3

结束条件

assing end_cnt = add_cnt&& cnt == X-1; // X:数多少个脉冲

模板4段式状态机

段号

代码

1

// 初始化,次态赋值给现态,明确当前状态;

always @(posedge clk or negedge rst_n) begin

    if(!rst_n)

        state_c <= S00;//初始状态

    else

        state_c <= state_n;

end

2

always @( * ) begin  //组合逻辑,描述状态转换目标

    case(state_c)

S00: begin

            if(s00_s20_start)  // 条件名 S00->S20

                state_n = S20;

            else

                state_n = state_c; // 方便拷贝

        end

S20: begin

            if(s20_s21_start)

                state_n = S21;

            else

                state_n = state_c;

        end

S21: begin

            if(s21_s00_start)

                state_n = S00;

            else

                state_n = state_c;

        end

default: begin

            state_n = S00;

        end

    endcase

end

3

//具体的转换条件内容

assign s00_s20_start = state_c==S00&& (条件)

assign s20_s21_start = state_c==S20&& (条件);

assign s21_s20_start = state_c==S21&& (条件);

4

根据转态设计输出:

1always 设计1个输出信号;

1.7.3 Testbench
框架


条目

内容

模块名

`timescale 1 ns/1 ns

module testbench_name();

信号定义

reg clk  ;  //时钟

reg rst_n;  //复位

reg[3:0]  din0  ; //uut的输入信号 ,定义为reg型,在initial

reg       din1  ;

wire      dout0;//uut的输出信号, 定义为wire

wire[4:0] dout1;

parameter CYCLE    = 20; //参数定义,方便修改;

parameter RST_TIME = 3 ;

待测模块例化

module_name uut(   //统一采用名字关联

       .clk          (  clk     ),

       .rst_n        (  rst_n   ),

       .din0         (  din0    ),

       .din1         (  din1    ),

       .dout0        (  dout0   ),

       .dout1        (  dout1   )

);

激励产生

//复位,时钟 ,等

显示输出结果

$display   //类似printf

复位

复位

initial begin

       rst_n = 1;

       #2;

       rst_n = 0;

       #(CYCLE*RST_TIME);

       rst_n = 1;

 end

仿真时钟

仿真时钟

initial begin

     clk = 0;

     forever

     #(CYCLE/2)

     clk=~clk;

 end


激励信号

激励信号

 initial begin

      #1;//方便观测

      din1 = 0; //赋初值  

      #(10*CYCLE);

//开始赋值

 end

以上就是本人总结的Verilog语法相关知识点,当然明德扬还有很多比较简便的模板给我们使用,感兴趣的朋友可以进入明德扬论坛(http://www.fpgabbs.cn/)进行更多FPGA 或者语法相关讨论!





   拓展阅读