Verilog基本语法介绍(上)

文章目录

    • 注意事项
    • 模板
    • 数制的表示
    • 特殊符号
    • 数据类型
      • 四种逻辑状态(四值逻辑)
      • 两种数据类型:
    • 参数
    • 位选择和域选择
    • 存储器
    • 运算符
    • 过程语句

注意事项

定义端口时要注意以下几点:

  • 每个端口除要声明是输入、输出还是双向端口外,还要声明其数据类型,是wire型、reg型、还是其他类型。
  • 输入端口和双向端口不能声明为reg型。
  • 在测试模块中不需要定义端口。

模板

verilog模块的模板:

module <顶层模块名> (<输入输出端口列表>);
    input 输入端口列表;  //输入端口声明
    output 输出端口列表; //输出端口声明
    /*定义数据,信号的类型,函数声明,用关键字wire、reg、task、function等定义*/
    wire 信号名
    reg 信号名
    //逻辑功能定义
    assign <结果信号名>=<表达式>; //使用assign语句定义逻辑功能
    //用always块描述逻辑功能
    always @(<敏感信号表达式>)
        begin
        //过程赋值
        //if-else,case语句,for循环语句
        //task,function调用
        end
    //调用其它模块
    <调用模块名> <例化模块名> (<端口列表>);
    //门元件例化
    门元件关键字<例化元件名> (<端口列表>);
endmodule

转义标识符,以"\"开头,以空白符结尾,可以包含任何字符。

反斜线和结束空白符并不是转义标识符的一部分,因此,标识符“\out”和标识符"out"恒等。

数制的表示

整数

  • 二进制:b或B
  • 十进制:d或D或默认
  • 十六进制:h或H
  • 八进制:o或O
+/-<位宽><进制><数字>
例如:
8'b11000101
8'hd5
5'o27
4'D2

如果没有定义一个整数的位宽,则默认为32位

实数转换为整数的方法,通过四舍五入转换为最相近的整数

verilog采用reg型变量来存储字符串

例如:
reg[8*12,1] stringvar
initial
    begin
    stringvar="hello world!";
    end

特殊符号

特殊符号说明
\n换行
\tTab键
\\符号\
\"符号“
\ddd八进制数ddd对应的ASCII字符
\123       //八进制数123对应的ASCII字符是大写字母S

数据类型

四种逻辑状态(四值逻辑)

  • 0:低电平
  • 1:高电平
  • z:高阻态
  • x:不确定或未知的逻辑状态

在可综合的设计中,只有端口变量可赋值为z,因为三态逻辑仅在FPGA器件的i/o引脚中是物理存在的,可物理实现高阻逻辑。

两种数据类型:

  • net型:常用的有wire型、tri型
  • variable型:包括reg型、integer型等

net型:

net型数据相当于硬件电路中的各种物理连接,其特点是输出值紧跟输入值的变化而变化。

net型数据的值取决于驱动的值,对net型变量有两种驱动方式:

一种方式是在结构描述中将其连接到一个门元件或模块的输出端;

另一种是用持续赋值语句assign对其进行赋值。

如果net型变量没有连接到驱动,其值为高阻态z

  1. wire型

    wire型变量是最常见的net型数据变量

    verilog模块中的输入/输出信号没有明确指定数据类型时都被默认为wire型

    如果wire型变量没有连接到驱动,其值为高阻态z

  2. tri型

    tri型和wire型的功能及使用方法完全一样对于verilog综合器来说,对tri型变量和wire型变量的处理完全相同

variable型:

variable型变量必须放在过程语句(如initial、always)中,通过过程赋值语句赋值;

在always、initial等过程块内被赋值的信号也必须定义成variable型

类型功能
reg常用的寄存器型变量
integer32位有符号整型变量
real64位有符号整型变量
time64位无符号整型变量

real型和time型变量都是纯数学的抽象描述,不对应任何具体的硬件电路,real型和time型变量不能被综合。time型主要用于对模拟时间的存储和处理,real型表示实数寄存器,主要用于仿真。

  1. reg型

    reg型变量是最常见的variable型变量

    reg型变量并不意味着一定对应硬件上的寄存器或触发器,在综合时,综合器会根据具体情况来确定将其映射成寄存器还是映射成连线。

    module abc(input a,b,c
               output f1,f2);
        reg f1,f2;//在always过程块中赋值的变量需定义为reg型
        always @(a or b or c)
            begin
                f1=a|b;//f1、f2综合时不会映射为寄存器
                f2=f1^c;
            end
    endmodule
    
  2. integer型

    integer型变量多用于表示循环变量,如用来表示循环次数,与reg定义相同。

    integer i,j;
    integer[31:0] d;
    

    integer型变量不能作为位向量访问

    在综合时,integer型变量的初始值为x。

参数

  1. parameter

参数parameter,定义符号常量,即用parameter定义一个参数名来代表一个常量。参数常用来定义延时和变量的宽度。使用参数说明的常量只能被赋值一次。

parameter 参数名1=表达式1,参数名2=表达式2,...;

参数名通常用大写字母来表示,例如

parameter SEL=8,CODE=8'ha3;

采用parameter定义了数据的位宽,比较的结果有大于、等于和小于三种,改变parameter的数值,可将比较器改为任意宽度。

module compare_w(a,b,larger,equal,less)
    parameter SIZE=6;
    input[SIZE-1:0] a,b;
    output wire larger,equal,less;
    assign larger=(a>b);
    assign equal=(a==b);
    assign less=(a<b);
endmodule

parameter还具有参数传递(重载)的功能:1.用“#”号隐式地重载;2.在线显式重载参数方式;3.使用defparam语句显式地重载

  1. localparam

用于定义局部参数,只能在本模块中使用,不可用于参数传递

//采用localparam的加法器
module add_localp
    #(parameter MSB=15,LSB=0)//parameter参数定义
    (input[MSB:LSB] a,b,
     output[MSB:LSB] sum);
    localparam HSB=MSB+1;//localparam参数定义
    assign sum=a+b;
endmodule

标量:宽度为1位的变量

wire a;
reg clk;

向量:线宽大于1位的变量

[MSB:LSB]  

左边的数字表示向量的最高有效位(Most Significant Bit,MSB),最右边的数字表示向量的最低有效位(Least Signicant Bit,LSB

wire[3:0] bus;//4位总线
reg[7:0] ra,rb;//定义了两个8位寄存器,其中ra[7],rb[7]分别为最高有效位
reg[0:7] rc;//rc[0]为最高有效位,rc[7]为最低有效位

位选择和域选择

在表达式中可任意选中向量中的一位或相邻几位,分别称为位选择和域选择

A=mybyte[6];//将mybyte的第6位赋值给变量A,位选择
B=mybyte[5:2];//将mybyte的第5、4、3、2位的值赋给变量B,域选择

reg[7:0] a,b;reg[3:0] c;reg d;
d=a[7]&b[7];//位选择
c=a[7:4]+b[3:0];//域选择

用位选择和域选择赋值时,应注意等号左右两端的宽度要一致

wire[7:0] out; wire[3:0] in;
assign out[5:2]=in;

等效于

assign out[5]=in[3];
assign out[4]=in[2];
assign out[3]=in[1];
assign out[2]=in[0];

向量还分为标量类向量和向量类向量

标量类向量支持位选择和域选择,在定义时用关键字scalared说明;

向量类向量不支持位选择和域选择,只能作为一个统一的整体进行操作,在定义时用关键字vectored说明;

reg scalared [31:0] rega;//rega为32位标量类向量
wire vectored [7:0] databus;//向量类向量

标量类向量的说明可以默认,例如:

reg[31:0] rega;

凡没有注明vectored关键字的向量,都认为是标量类向量,可以对其进行位选择和域选择。

存储器

存储器可视为二维向量,或由一组寄存器构成的阵列,若干相同宽度的寄存器向量构成的阵列即构成了一个存储器。

reg[7:0] mymem[63:0];
//定义了一个有64个单元的存储器,每个单元宽度为8b,存储器名叫mymem
reg[3:0] Amem[63:0];//Amem是容量为64、字长为4位的存储器
reg Bmem[5:1];//Bmem是容量为5、字长为1位的存储器

parameter WIDTH=8,MEMSIZE=1024;
reg[WIDTH-1:0] mymem[MEMSIZE-1:0];
//用parameter参数定义存储器的尺寸
//定义了一个宽度为8b、容量为1024个存储单元的存储器

存储器赋值:只能对存储器的某一单元整体赋值

reg[7:0] mymem[63:0];//存储器的定义
mymem[8]=8'b10001001;//mymem存储器第8个单元被赋值为二进制数10001001
mymem[25]=65;//mymem存储器第25个单元被赋值为十进制数65

寄存器和存储器的区别

reg[1:8] rega;//定义了一个8位的寄存器
reg mema[1:8];//定义了一个字长为1、容量为8的存储器

赋值

rega[2]=1'b1;//对寄存器rega的第2位赋值1,合法
mema[2]=1'b1;//对存储器mema的第2个单元赋值1,合法
rega=8'b01011000;//对寄存器rega整体赋值,合法
mema=8'b01011000;//不允许对存储器的多个或所有单元一次性赋值,非法

运算符

  1. 算术运算符

    符号功能
    +
    -
    *
    /
    %取模
  2. 逻辑运算符

    符号功能
    &&逻辑与
    ||逻辑或
    逻辑非
  3. 位运算符

    符号功能
    ~按位取反
    &按位与
    |按位或
    ^按位异或
    ^~,~^按位同或
  4. 关系运算符

    符号功能
    <小于
    <=小于等于
    >大于
    >=大于等于
  5. 等式运算符

    符号功能
    ==等于
    !=不等于
    ===全等
    !==不全等
  6. 缩减运算符

    符号功能
    &
    ~&与非
    |
    ~|或非
    ^异或
    ^~,~^同或
  7. 移位运算符

    符号功能
    >>右移
    <<左移
    >>>算术右移
    <<<算术左移
  8. 指数运算符

    “******”,如2n,为2******n

  9. 条件运算符

    “? :”,三目运算符

    信号=条件?表达式1:表达式2;
    
  10. 位拼接运算符

    “{ }”,将两个或多个信号的某些位拼接起来

    {信号1的某几位,信号2的某几位,...,信号n的某几位}
    

    进行加法运算时,可将进位与和拼接在一起使用

    input[3:0] ina,inb;input cin;
    output[3:0] sum;output cout;
    assign {cout,sum}=ina+inb+cin;//进位与和拼接在一起
    

    位拼接可用来进行符号位扩展

    wire[7:0] data;
    wire[11:0] s_data;
    s_data={4{data[7]},data};//将data的符号位扩展
    

    位拼接可以嵌套使用,还可以用复制法来简化书写

    {3{a,b}}//复制3次,等价于{{a,b}{a,b}{a,b}}或{a,b,a,b,a,b}
    {2{3'b101}}//复制2次,结果为101101
    

运算符优先级

类别运算符优先级
移位运算符<< >> <<< >>>
关系运算符< <= > >=
等式运算符== !=
位运算符&
位运算符^ ^~ ~ ^
位运算符|
逻辑运算符&&
逻辑运算符||
条件运算符? :
位拼接运算符{} {{}}

过程语句

在一个模块中,使用initial和always语句的次数是不受限制的。

initial语句常用于仿真中的初始化,只执行一次;

always语句则是不断重复执行;

always过程语句

always @(<敏感信号列表>)
    begin
        //过程赋值
        //选择语句
        //循环
        //调用
        //等等
    end

参考资料:

《EDA技术与Verilog设计》(第二版)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

书阁下

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值