• verilog_基本概念


    2016.9.2

    目标:

         1.理解操作符、注释、空白符、数字、字符串、和标识符放入词法约定

         2.定义逻辑值集合和数据类型

         3.学习使用用于显示和监视信息、暂停和结束仿真的系统任务

         4.学习用于宏定义、文件包含的基本编译指令

    1词法约定

    1.1空白符

    由空格()、制表符( )和换行符组成

    1.2注释

    单行注释(\)

    多行注释(/**/)

    1.3操作符

    单目、双目、三目

    a= ~ b;//单目
    a=b && c;//双目
    a=b ? c : d//三目

    1.4数字声明

    指明位数声明和不指明位数声明

    指明位数声明格式:<size>'<base format><number>

    <size>数字的为宽度

    <base format>

    'd或'D 

    'h或'H 

    'b或'B

     'o或'O

     不指明位数的数字

    没指定基数,则默认为十进制数,

    没指定位宽,则默认与仿真器和计算机有关(最小为32位)

    X和Z值

    X代表不确定值

    Z代表高阻值

    16进制中,X和Z代表4位;

    8进制中,X和Z代表3位;

    2进制中,X和Z代表1位。

    负数

     在表示位宽的数字前面增加一个减号来表示它是一个负数。

    而将减号放在基数和数字之间是非法的

    2.数据类型

    2.1值的类型

    四值逻辑和八种信号对实际硬件进行建模

       四值电平逻辑                                                                                                                           

    值的级别

    硬件电路的条件

    0

    逻辑0,条件为假

    1

    逻辑1,条件为真

    x

    逻辑值不确定

    y

    高阻,浮动状态

       强度等级                                                                                                                               

    强度等级 类型 程度
    supply 驱动

    最强

    最弱

    strong 驱动
    pull 驱动
    large 存储
    weak 驱动
    medium 存储
    small 存储
    highz 高阻

    不同强度的信号驱动同一线网,则竞争结果为高强度信号的值;同等强度的信号驱动同一线网,则结果为不确定值

    2.2线网

    线网表示硬件单元之间的连接。

    一般用wire进行声明

    线网的默认值为z(trireg类型的线网例外,其默认值为x)

    线网值由驱动源确定,如果没有,则线网的值为z

    2.3寄存器

     寄存器用来表示存储器件,它保持原有数值,直到被改写。

    关键字为reg,默认值为x。

    reg reset;//声明能保持数值的变量reset
    initial //这个结构以后讨论
    begin
        reset = 1'b1;//把reset初始化为1,使数字电路复位
        #100 reset = 1'b0;//经过100个时间单位后,reset置逻辑0
    end

    也可以声明为带符号(signed)类型的变量,这样的寄存器就可以用于带符号的算术运算

    reg signed [63:0] m;  //64位带符号的值
    integer i ; //32位带符号的值

    2.4向量

    线网和寄存器类型的数据均可以声明为向量(位宽大于1)。若没指定,则默认为标量(1位)

    wire a;/ /标量线网变量,默认
    wire [7:0]  bus //8位的总线
    wire[31:0] busA,busB,busC;//3条32位宽的总线
    reg clock;//标量寄存器,默认
    reg [0:40] virtual_addr;//向量寄存器,41位宽的虚拟地址(最高有效位是它的第0位)

     方括号中左边的数总是代表向量的最高有效位。

    向量域选择

    我们可以在向量中指定它的某一位或若干相邻位,但要注意高位依然要写在左侧

    可变的向量域选择

    可以通过for循环来动态地选取向量的各个域。

    专用操作符

    [<starting_bit>+:width]:从起始位开始递增,位宽为width。

    [<starting_bit>-:width]:从起始位开始递减,位宽为width。

     起始位可以是变量,但位宽必须是常量。

    reg[255:0] data1; //
    reg[0:255] data2;//
    reg[7:0] byte;
    //
    byte = data1[31-:8]; //从31位算起,宽度为8位,相当于data2[31:24]
    byte = data1[24+:8];//从24位算起,宽度为8位,相当于data2[31:24]
    byte = data2[31-:8]; //从31位算起,宽度为8位,相当于data2[24:31]
    byte = data2[24+:8];//从24位算起,宽度为8位,相当于data2[24:31]
    //起始位可以是变量,但宽度必须是常数。因此可以通过可变域选择
    //用循环语句选取一个很长的向量的所有位
    for(j=0;j<=31;j=j+1)
    byte = data1[(j*8)+:8];//次序为[7:0],[15:8]...[255:248]
    
    //用于初始化向量的一个域
    
    data1[(byteNum*8)+:8] =8'b0;//如果byteNum = 1,共有8位被清零,[15:8]

     2.5整数、实数和时间寄存器数据类型

    除reg类型之外,verilog还支持integer,real,和time寄存器数据类型。

    整数(integer)

    通用的寄存器数据类型,用于对数量进行操作。

    声明一个整数类型的变量来完成计数等功能显然比reg更为方便。

    位宽为宿主机的字的位数,最小应为32位。

    reg类型的寄存器变量为无符号数,而整数类型的变量则为有符号数。

    实数(real)

    实常量和实数寄存器数据类型,可以使用十进制或科学计数法。实数声明不能带有范围,默认值为0;

    如果将一个实数赋给一个整数,那么实数将会被取整为最接近的整数

    时间寄存器(time)

    时间变量通过time来声明,宽度与具体实现有关,最小为64位。

    通过调用系统函数$time可以得到当前的仿真时间。

    2.6数组

    允许声明reg,integer,time,real,realtime及其向量类型的数组,对数组维数没有限制。

    形如<数组名>[<下标>],对于多维数组需要说明其每一维的索引

    赋值

    integer count[0:7];//8个计数变量组成数组
    reg bool[31:0];//32个1位的布尔寄存器变量组成数组
    time chk_point[1:100];//100个时间检查变量组成数组
    reg [0:4] port_id[0:7];//8个端口标识变量组成数组,端口位宽为5
    integer matrix[4:0][0:255];//二维的整数型数组
    reg [63:0] array_4d [15:0] [7:0] [7:0] [255:0];//四维64位寄存器型数       组
    wire [7:0] w_array2 [5:0];//声明8位向量数组
    wire w_array1 [7:0] [5:0];//声明1位线型变量的二维数组
    //赋值
    count[5]=0;//count中第五个整数型单元(32位)复位
    chk_point[100] = 0;//第100个时间型单元(64位)复位
    port_id[3] = 0;//第3个寄存器型单元(5位)复位
    marix[1][0] = 33339;//第1行第0列的整数型单元(32位)置为33339
    array_4d[0][0][0][0][15:0] = 0;//把四维数组中索引号为[0][0][0][0]的寄存器型单元的0~15位都置于0

    2.7存储器

    对寄存器,RAM和ROM建模。使用寄存器的一维数组来表示存储器,数组每个元素称为一个元素或一个字(Word),由一个数组索引来指定,每一个字的位宽为1位或多维。

    2.8参数

    使用parameter在模块内定义常数。参数代表常数,不能像变量那样赋值,但是每一个模块实例的参数值可以在编译阶段被重载。通过参数重载使得用户可以对模块实例进行定制。

    局部参数使用关键字localparam来定义,其作用等同于参数,区别在于它的值不能改变,不能通过参数重载语句(defparam)或通过有序参数列表或命名参数赋值来直接修改。

    2.9字符串

    字符串保存在reg类型的变量中,每一个字符占用8位(一个字节)。左补左截。

    特殊字符

    转义字符 显示的字符
    换行
    tab(制表空格)
    %% %
    \
    " "
    ooo 1到3个八进制数字字符

    3系统任务和编译指令

    3.1系统任务

    为某些常用操作提供了标准的系统任务(系统函数),包括屏幕显示、线网值动态监视、暂停和结束仿真。

    所有系统任务都具有$<keyword>的形式

    显示信息($display)

    用于显示变量、字符串或表达式的主要系统任务

    用法:$display(p1,p2,p3,...,pn);

    p1,p2,p3,...,pn是双引号括起来的字符串、变量或者表达式,会自动在字符串结尾插入一个换行符。

    字符串格式说明

    格式  显示 
     %d或%D

    用十进制显示变量 

    %b或%B 

    用二进制显示变量 

    %s或%S 

    显示字符串 

    %h或%H 

    用十六进制显示变量 

    %c或%C 

     显示ASCII字符

    %m或%M 

    显示层次名 

    %v或%V 

    显示强度 

    %o或%O 

    用八进制显示变量 

    %t或%T 

    显示当前时间 

    %e或%E 

    用科学记数法格式显示实数 

    %f或%F 

    用十进制浮点数格式显示实数 

    %g或%G  用科学记数法或十进制格式显示实数,显示较短的格式 

     监视信息

    通过系统函数$monitor,提供了对信号值变化进行动态监视的手段。

    用法:$monitor(p1,p2,p3,...,pn);

    p1,p2,p3,...,pn可以是变量、信号名或双引号括起来的字符串。其对参数列表中的变量值或信号值进行不间断监视。因此在任意仿真时刻只有一个监视列表有效,也就是只有最后一次的调用有效

     两个用于控制监视的系统任务:$monitoron和$monitoroff

    用法:$monitoron;(允许监视任务的执行)

             $monitoroff;(暂停监视)

    在$monitor中使用系统函数$time来取得系统仿真时间。

    暂停和结束仿真

    用法:$stop;

             $finish;

    3.2编译指令

    使用方法'<keyword>;

    'define

    用于定义文本宏

    'include

    可以在编译期间将一个Verilog源文件包含在另一个源文件中,作用类似于C语言中的#include结构。

  • 相关阅读:
    ssh -vT git@github.com get “ No such file or directory” 错误
    提高Bash使用效率的方法
    mybatis的update使用选择
    Ping 的TTL理解
    为什么要使用oath协议?
    Rest Client插件简单介绍
    idea中查看java类继承图
    CSS单行文本溢出显示省略号
    js里父页面与子页面的相互调用
    css font的简写规则
  • 原文地址:https://www.cnblogs.com/fxygrzb/p/5913379.html
Copyright © 2020-2023  润新知