您好,欢迎来到榕意旅游网。
搜索
您的当前位置:首页Verilog HDL 语法整理(二)

Verilog HDL 语法整理(二)

来源:榕意旅游网




前言

        本文承接前文:。本文主要介绍 Verilog 的运算符和表达式。



一、Verilog HDL 初始化

        FPGA 内主要对记忆器件(寄存器、BRAM、ROM等)进行初始化,无记忆性的单元(wire 型连线)不用初始化。

1、分布式赋初值

        在声明变量时,直接对变量赋值。例 :

reg [15:0]          I_DATA=16'ff  ; 

2、集中式赋初值

        使用 initial 块赋初值。initial 块语法:

initial
    begin
        <代码块>;
    end

        initial 语句块 仅执行一次,不涉及内部电路功能。故 赋值时使用 阻塞赋值和非阻塞赋值均可。例:

reg [7:0] I_REAL;
reg [7:0] I_IMAG;

integer K ;

initial 
    begin
        for(K=0 ;K<=99 ;K=K+1)
            begin
                I_REAL <= K;
                I_IMAG  = K+1;
            end
    end

二、Verilog 操作符号

1、Verilog 赋值运算符

1、连续赋值符号

        仅能用于 线网型(wire)型变量赋值。语法格式:

assign     <线网型变量>        =        <表达式>    ;

2、阻塞赋值符

        主要用于组合逻辑,只能对 寄存器型 变量赋值。赋值符 “ = ” 。此符号一般都出现表达组合逻辑的 always 语句块中。always 语句块中的语句顺序执行,阻塞赋值的含义:保证上一条语句执行、赋值完成后才开始下一条语句。例:

always @ (c)
    begin
        b=c;
        a=b;
    end

3、非阻塞赋值符

        主要用于组合逻辑,只能对 寄存器型 变量赋值。赋值符 “ <= ” 。此符号一般都出现表达时序逻辑的 always 语句块中。always 语句块中的语句顺序执行,非阻塞赋值的含义:上一条语句已经执行但未完成赋值时就开始下一条语句的执行。例:

always @ (posedge I_CLK)
    begin
        b <= c;
        a <= b;
    end

4、映射赋值符

        映射赋值符号 “ . ” 。此运算符常用于 模块例化时,输入输出端口的连接赋值。例:

	ASYNC_FIFO_ENCAP inst_ASYNC_FIFO_ENCAP
		(
			.I_Rst_n  (I_Rst_n),
			.I_WR_CLK (I_WR_CLK),
			.I_RD_CLK (I_RD_CLK),
			.I_DATA   (I_DATA),
			.I_VAL    (I_VAL),

			.O_DATA   (O_DATA),
			.O_VAL    (O_VAL),
			.O_FULL	  (O_FULL)
		);

5、位置赋值

        功能与映射赋值相同。一般用的很少,上例可以写为:

	ASYNC_FIFO_ENCAP inst_ASYNC_FIFO_ENCAP
		(
			I_Rst_n,
			I_WR_CLK,
			I_RD_CLK,
			I_DATA,
			I_VAL,

			O_DATA,
			O_VAL,
			O_FULL
		);

2、Verilog 按位运算符

1、~

        按位取反运算,单目运算符。对操作数的每一位进行取反。例:

wire [7:0] A,B;
assign A = 8'b0000_1111;
assign B = ~A; //B: 1111_0000

2、&

        按位 与 运算,双目运算符。对参与运算的两个操作数,按位 与 运算。例:

wire [7:0] A,B,C;
assign A = 8'b0000_1111;
assign B = ~A;     //B: 1111_0000
assign C = A & B;  //C: 0000_0000

3、|

        按位 或 运算,双目运算符。对参与运算的两个操作数,按位 或 运算。例:

wire [7:0] A,B,C;
assign A = 8'b0000_1111;
assign B = ~A;     //B: 1111_0000
assign C = A | B;  //C: 1111_1111

4、^

         按位 异或 运算,双目运算符。对参与运算的两个操作数,按位 异或 运算。例:

wire [7:0] A,B,C;
assign A = 8'b0000_1111;
assign B = ~A;     //B: 1111_0000
assign C = A ^ B;  //C: 1111_1111

5、^~

        按位 异或非(同或) 运算,双目运算符。对参与运算的两个操作数,按位 异或非(同或) 运算。例:

wire [7:0] A,B,C;
assign A = 8'b0000_1111;
assign B = ~A;      //B: 1111_0000
assign C = A ^~ B;  //C: 0000_0000

3、归约运算符

规约运算符 都是单目运算符。操作数有一定位宽。运算结果均为1bit。

1、&

        规约 与 运算符。对操作数的 所有 bit 作逻辑与操作。例:

wire [7:0] A;
assign A = 8'b0000_1111;
assign B = &A;      //B: 0

2、~&

         规约 与非 运算符。对操作数的 所有 bit 先作 规约与 操作,然后对结果取反。例:

wire [7:0] A;
assign A = 8'b0000_1111;
assign B = ~&A;      //B: 1

3、|

        规约 或 运算符。对操作数的 所有 bit 作逻辑或操作。例:

wire [7:0] A;
assign A = 8'b0000_1111;
assign B = |A;      //B: 1

4、~|

        规约 或非 运算符。对操作数的 所有 bit 先作 规约或 操作,然后对结果取反。例:

wire [7:0] A;
assign A = 8'b0000_1111;
assign B = ~|A;      //B: 0

5、^

        规约 异或 运算符。对操作数的 所有 bit 作逻辑异或操作。例:

wire [7:0] A;
assign A = 8'b0000_1111;
assign B = ^A;      //B: 0

6、~^

        规约 异或非 运算符。对操作数的 所有 bit 作逻辑异或非操作 (注:只有操作数位宽为 偶数时,异或非 运算和 同或 运算等价)。对操作数的 所有 bit 先作 规约异或 操作,然后对结果取反。例:

wire [7:0] A;
wire [2:0] C;
assign A = 8'b0000_1111;
assign C = 3'b000;
assign B = ~^A;      //B: 1
assign D = ~^C;      //D: 1

4、算数运算符

1、+

        加法运算符,双目运算符。例:

wire [2:0] A = 3'b011;
wire [2:0] B = 3'b011;
wire [2:0] C = 3'b111;

assign D = A + B ;// D:6
assign E = A + C ;// E:2 溢出

2、-

        减法运算符,双目运算符。例:

wire [2:0] A = 3'b011;
wire [2:0] B = 3'b011;
wire [2:0] C = 3'b111;

assign D = A - B ;// D:0
assign E = A - C ;// E:4 溢出

3、*

        乘法运算符,双目运算符。例:

wire [2:0] A = 3'b001;
wire [2:0] B = 3'b011;
wire [2:0] C = 3'b111;

assign D = A * B ;// D:3
assign E = B * C ;// E:5 溢出

4、/

        除法运算符,双目运算符。例:

wire [2:0] A = 3'b001;
wire [2:0] B = 3'b011;
wire [2:0] C = 3'b111;

assign D = B / A ;// D:3

5、%

        求余运算符,双目运算符。例:

wire [2:0] A = 3'b001;
wire [2:0] B = 3'b011;
wire [2:0] C = 3'b111;

assign D = B % A ;// D:0

6、**

        乘方运算符,双目运算符。例:

wire [2:0] A = 3'b001;
wire [2:0] B = 3'b011;
wire [2:0] C = 3'b111;

assign D = B ** A ;// D:3 

【注】,不建议直接用 乘方运算符号 实现乘方运算,可用相关 IP核。

5、Verilog 关系运算符

        主要用作 条件判断 通用语法格式:

<表达式 1>     <关系运算符>     <表达式 2>

主要的 关系运算符:

==     //判断表达式相等
===    //判断表达式全等(包含 X、Z 状态,仅用于 仿真)
!=    //判断表达式不等
!==   //判断表达式不全等(包含 X、Z 状态,仅用于 仿真)
<      //左表达式 小于 右表达式
>      //左表达式 大于 右表达式
<=     //左表达式 小于等于 右表达式
>=     //左表达式 大于等于 右表达式

6、Verilog 逻辑运算符

        主要用于 多个关系表达式的连接。可实现较复杂的判断条件。语法格式:

<逻辑运算符>    <关系表达式>
或
<关系表达式>    <逻辑运算符>    <关系表达式>

        主要有以下几种 逻辑运算符:

!    //单目运算符,对右边表达式 取反
&&    //左右表达式的结果 作 逻辑与运算
||    //左右表达式的结果 作 逻辑或运算

7、Verilog 迭代连接运算符

运算符:“{}”

1、连接功能

wire [2:0] A = 3'b001;
wire [2:0] B = 3'b011;
wire [2:0] C = 3'b111;

assign D = {A,B,C};//D:001_011_111

2、迭代功能

wire [2:0] A = 3'b001;
wire [2:0] B = 3'b011;
wire [2:0] C = 3'b111;

assign D = {2{C}};//D:111_111

3、混合功能

wire [2:0] A = 3'b001;
wire [2:0] B = 3'b011;
wire [2:0] C = 3'b111;

assign D = { {2{C}} , A , B };//D:111_111_001_011
assign E = { {2{ A ,B }} , C};//E:001_011_001_011_111

8、Verilog 移位运算符

运算符:

<<    //(无符号)左移运算
>>    //(无符号)右移运算

<<<    //(有符号)左移运算
>>>    //(有符号)右移运算

【注】无符号移位:移位时 空缺的位 用 1'b0 补上。

 有符号左移与无符号左移相同,右边空缺位用 1'b0 补上。有符号右移,左边空缺位用 符号位 补上。

移位算法:

<变量名>      <移位运算符>        <移位个数>

例:

wire [2:0] A = 3'b001;
wire [2:0] B = 3'b011;
wire signed [2:0] C = 3'b111;

assign D = A >> 1;//D:000
assign E = C >> 1;//E:011
assign F = C >>> 1;//F:111
assign G = C <<< 1;//G:110

移位运算 可用 连接运算符 实现。

9、Verilog 条件运算符

        基本语法:

assign <变量名> = <表达式> ? <表达式为真选择此式> :<表达式为假选择此式>

10、Verilog 运算符优先级

        多用 小括号。不要依赖运算本身的优先级。下表操作的优先级,由高到低。

!        ~        +        - (负号)
*        /        %
+        -(减号)
<<        >>
<        <=        >        >=
==        !=        ===        !==
&        ~&
^        ^~
|        ~|
&&
||
? :

参考声明

【1】夏宇闻. Verilog 数字系统设计教程 第二版.

【2】狄超. FPGA之道.

【3】IEEE Standard for Verilog Hardware Description Language 13-2005.



文末推荐

掌握了基本的Verilog语法,不去实战练习的话很难有大的突破。牛客网可以为大家提供一个免费的刷题练习的平台。非常推荐大家使用。

 链接如下:这个里面有很多代码题目练习,对于新手来说可以快速掌握Verilog编程的基本语法,对于老手来说也可以巩固自己的编程能力。不用付费免费试用哦。基本是每个即将找工作的人必备的刷题网站。快行动起来吧!

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- nryq.cn 版权所有 赣ICP备2024042798号-6

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务