zoukankan      html  css  js  c++  java
  • Verilog语法知识点总结(转)

    1.1 概述

     

    条目

    说明

    分类

    1>> 面向设计的语句; // 可综合。

    2>> 面向测试的语句; //testbench ,不可综合。

    特点

    设计语句 assign , always ,模块例化,都对应实际电路,并行执行。

    构造

    1.2 模块 Module

     

    条目

    说明

    模块名(端口列表)

    整个电路的外特性,抽象为黑盒子;

    端口方向

    input , output ; inout ;

    端口类型

    wire , reg ;

    端口类型是 wire 时可以省略。

    例: input a ; // 端口方向为输入,类型默认为 wire ;

    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 ;推荐大写;

    常量

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

    二进制: B 或 b ;

    十进制: D 或 d ;

    八进制: O 或 o ;
    十六进制: H 或 h ;

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

    < 数字 >

    默认十进制;

    4 值逻辑

    0 : Logic Low

    低电平;

    1 : Logic High

    高电平;

    x : Unknow ;

    不确定;

    z : High 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 (连续赋值)

    实例

    说明

    assigny = ~ b ;

    assign out = a==1 && c==1 ;

    assign f = sel ? a : b ;

    >> 实现可以用布尔函数描述的组合逻辑电路;

    >>“=” 后面可以是任何布尔函数;

    >> 并行执行;

    典型错误 1 :

    assigna = b + a;

    避免出现反馈电路:变为了不可知时序逻辑电路;

    1.5.2  always (过程块)

     

    a、赋值

     

    赋值方式

    说明

    = ,阻塞赋值

    always @ ( a or b or C or … )

    begin

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

    end

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

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

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

    避免出现 Latch (锁存器)

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

    <= ,非阻塞赋值

    always @ ( posedge clk or negedge rst_n )

    begin

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

    end

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

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

    b、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 成对使用;

    c、case 语句

     

    条目

    说明

    格式

    case( 表达式 )

    常量表达式 1:begin

    语句;

    end

    常量表达式 2:begin

    语句;

    end

    常量表达式 3:begin

    语句;

    end

    default :

    语句;

    endcase

    特点

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

    注意

    default 语句不可省略;

    d、代码 & 硬件

     

    条目

    说明

    映射

    赋值语句 -> 逻辑函数; // 加法器,减法器等;

    边沿型条件分支 -> D 触发器;

    条件分支 -> 多路选择器;

    示例

    1.5.3 模块例化

     

    a、作用

     

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

    b、常见的典型错误如下所示:

     

    1.5.4 全加器

     

    全加器顶层: w1 , w2 , w3 :模块之间连线;

    半加强: 2 种描述方法,如下:

    描述方式

    描述方式

    说明

    位置关联

    AND u1(a, b, and_out);

    名字关联

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

    1.6 测试语句

         

         1.6.1 结构

     

    Testbench

    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.7.1 组合逻辑电路

     

    条目

    说明

    assign

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

    always

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

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

    end

    1.7.2 时序逻辑电路

     

    a、计数器模板 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: 数多少个脉冲

    b、计数器模板 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: 数多少个脉冲

    c、 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

    根据转态设计输出:

    1 个 always 设计 1 个输出信号;

    1.7.3 Testbench

     a、框架

    条目

    内容

    模块名

    `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 ;

    b、复位

     

    复位

    initial begin

    rst_n = 1;

    #2;

    rst_n = 0;

    #(CYCLE*RST_TIME);

    rst_n = 1;

    end

    c、仿真时钟

     

    仿真时钟

    initial begin

    clk = 0;

    forever

    #(CYCLE/2)

    clk=~clk;

    end

    d、激励信号

     

    激励信号

    initial begin

    #1;// 方便观测

    din1 = 0; // 赋初值

    #(10*CYCLE);

    // 开始赋值

    end

    以上就是总结的 Verilog 语法相关知识点,转自明德扬论坛

  • 相关阅读:
    poj3255,poj2449
    poj2186
    poj3249
    poj3378
    poj3274
    poj1948
    hdu 2181暴搜
    hdu 3342
    hdu 1285
    hdu 1598
  • 原文地址:https://www.cnblogs.com/xiaoyangerlaoshi/p/13543843.html
Copyright © 2011-2022 走看看