【Verilog 语法】~ 关键字、运算符、数据类型、缩位运算、三态门设计、可综合、VHDL 的结构、VHDL:WAIT 语句格式、原语、编译预处理

1. 关键字

关键字含义
module模块开始定义
input输入端口定义
output输出端口定义
inout双向端口定义
parameter参数定义
wirewire信号定义
regreg信号定义
always产生reg信号语句的关键字
assign产生wire信号语句的关键字
begin语句的开始标志
end语句的结束标志
posedge/negedge时序电路的标志
casecase语句开始标志
defaultcase语句默认分支标志
endcasecase语句结束标志
if判断语句开始标志
else判断语句标志
for循环语句标志
endmodule模块结束标志

2. 运算符

2.1 分类

2.1.1 按其功能分类

  1. 算术运算符(+,-,×,/,%)
  2. 赋值运算符(=,<=)
  3. 关系运算符(>,<,>=,<=)
  4. 逻辑运算符(&&,||,!)
  5. 条件运算符( ? :)
  6. 位运算符(,|,,&,)
  7. 移位运算符(<<,>>)
  8. 拼接运算符({ })
  9. 其它

2.1.2 按其所带操作数的个数分类

  1. 单目运算符(unary operator):可以带一个操作数,操作数放在运算符的右边。
  2. 二目运算符(binary operator):可以带二个操作数,操作数放在运算符的两边。
  3. 三目运算符(ternary operator):可以带三个操作,这三个操作数用三目运算符分隔开。
2.1.2.1 举例

clock = ~clock; // ~是一个单目取反运算符, clock 是操作数。
c = a | b; // 是一个二目按位或运算符, a 和 b 是操作数。
r = s ? t : u; // ?: 是一个三目条件运算符, s,t,u 是操作数。

2.2 优先级

在这里插入图片描述

3. 数据类型

Verilog 中共有 19 种数据类型。
基本的四种类型: reg 型、wire 型、integer 型、parameter 型。
其他类型:large 型、medium 型、small 型、scalared 型、time 型、tri 型、trio 型、tril 型、triand 型、trior 型、trireg 型、vectored 型、wand 型和 wor 型。

1) wire 型

wire 型数据常用来表示以 assign 关键字指定的组合逻辑信号。Verilog 程序模块中输入、输出信号类型默认为 wire 型。wire 型信号可以用做方程式的输入,也可以用做“assign”语句或者实例元件的输出。wire 型信号的定义格式如下:

wire [n-1:0] 数据名 1,数据名 2,……数据名 N;
这里,总共定义了 N 条线,每条线的位宽为 n。下面给出几个例子:
wire [9:0] a, b, c; // a, b, c 都是位宽为 10 的 wire 型信号
wire d;

2) reg 型

reg 是寄存器数据类型的关键字。寄存器是数据存储单元的抽象,通过赋值语句可以改变寄存器存储的值,其作用相当于改变触发器存储器的值。reg 型数据常用来表示 always 模块内的指定信号,代表触发器。通常在设计中要由 always 模块通过使用行为描述语句来表达逻辑关系。在 always 块内被赋值的每一个信号都必须定义为 reg 型,即赋值操作符的右端变量必须是 reg 型。reg 型信号的定义格式如下

reg [n-1:0] 数据名 1,数据名 2,……数据名 N;
这里,总共定义了 N 个寄存器变量,每条线的位宽为 n。下面给出几个例子:
reg [9:0] a, b, c; // a, b, c 都是位宽为 10 的寄存器
reg d;

reg 型数据的缺省值是未知的。reg 型数据可以为正值或负值。但当一个 reg 型数据是一个表达式中的操作数时,它的值被当作无符号值,即正值。如果一个 4 位的 reg 型数据被写入-1,在表达式中运算时,其值被认为是+15。

reg 型和 wire 型的区别在于:reg 型保持最后一次的赋值,而 wire 型则需要持续的驱动。

3) integer 型

也是一种寄存器数据类型,integer 类型的变量为有符号数,而 reg 类型的变量则为无符号数,除非特别声明为有符号数。

还有就是 integer 的位宽为宿主机的字的位数,但最小为 32 位,用 integer 的变量都可以用reg 定义,只是用于计数更方便而已。reg, integer, real,time 都是寄存器数据类型,定义在 Verilog 中用来保存数值的变量,和实
际的硬件电路中的寄存器有区别。

4) parameter 型

在 Verilog HDL 中用 parameter 来定义常量,即用 parameter 来定义一个标志符表示一个常数。采用该类型可以提高程序的可读性和可维护性。

parameter 型信号的定义格式如下:
parameter 参数名 1 = 数据名 1;

下面给出几个例子:
parameter s1 = 1;
parameter [3:0] S0=4’h0

4. 缩位运算

缩减运算符是单目运算符,也有与或非运算。其与或非运算规则类似于位运算符的与或非运算规则,但其运算过程不同。位运算是对操作数的相应位进行与或非运算,操作数是几位数则运算结果也是几位数。而缩减运算则不同,缩减运算是对单个操作数进行或与非递推运算,最后的运算结果是一位的二进制数

4.1 缩减运算的具体运算过程

  1. 第一步先将操作数的第一位与第二位进行或与非运算,
  2. 第二步将运算结果与第三位进行或与非运算,
  3. 依次类推,直至最后一位。

4.1.1 例如

reg [3:0] B;
reg C;
C = &B;
相当于:
C =( (B[0]&B[1]) & B[2] ) & B[3];

5. 三态门设计

5.1 概述

三态指其输出既可以是一般二值逻辑电路(使能EN=1),即正常的高电平(逻辑 1)或低电平(逻辑 0),又可以保持特有的高阻抗状态(使能EN=0),高阻态相当于隔断状态(电阻很大,相当于开路)。

5.2 三态门的 Verilog 代码实现

module Tri(
 input din,
 input en,
 output reg dout
 );
 always @(din or en)
 if (en)
 dout <= din;
 else
 dout <= 1'bz;
// 数据流描述
// assign dout = en ? din : 1'bz;
endmodule

6. 可综合

6.1 verilog 可综合和不可综合语句

(1)所有综合工具都支持的结构:always,assign,begin,end,case,wire,tri,generate,aupply0,supply1,reg,integer,default,for,function,and,nand,or,nor,xor,xnor,buf,not,bufif0,bufif1,notif0,notif1,if,inout,input,instantitation,module,negedge,posedge,operators,output,parameter。

(2)所有综合工具都不支持的结构:time,defparam,$finish,fork,join,initial,delays,UDP,wait,force。

(3)有些工具支持有些工具不支持的结构:casex,casez,wand,triand,wor,trior,real,disable,forever,arrays,memories,repeat,task,while。

6.2 建立可综合模型的原则

要保证 Verilog HDL 赋值语句的可综合性,在建模时应注意以下要点:
(1)不使用 initial。
(2)不使用#10。
(3)不使用循环次数不确定的循环语句,如 forever、while 等。
(4)不使用用户自定义原语(UDP 元件)。
(5)尽量使用同步方式设计电路。
(6)除非是关键路径的设计,一般不采用调用门级元件来描述设计的方法,建议采用行为语句来完成设计。
(7)用 always 过程块描述组合逻辑,应在敏感信号列表中列出所有的输入信号。
(8)所有的内部寄存器都应该能够被复位,在使用 FPGA 实现设计时,应尽量使用器件的全局复位端作为系统总的复位。
(9)对时序逻辑描述和建模,应尽量使用非阻塞赋值方式。对组合逻辑描述和建模,既可以用阻塞赋值,也可以用非阻塞赋值。但在同一个过程块中,最好不要同时用阻塞赋值和非阻塞赋值。
(10)不能在一个以上的 always 过程块中对同一个变量赋值。而对同一个赋值对象不能既使用阻塞式赋值,又使用非阻塞式赋值。
(11)如果不打算把变量推导成锁存器,那么必须在 if 语句或 case 语句的所有条件分支中都对变量明确地赋值。
(12)避免混合使用上升沿和下降沿触发的触发器。
(13)同一个变量的赋值不能受多个时钟控制,也不能受两种不同的时钟条件(或者不同的时钟沿)控制。
(14)避免在 case 语句的分支项中使用 x 值或 z 值。

6.3 不可综合 verilog 语句

1、initial
只能在 test bench 中使用,不能综合。(写了 initial 虽然可以通过综合,但那个不叫“能综合”)
2、events
event 在同步 test bench 时更有用,不能综合。
3、real
不支持 real 数据类型的综合。
4、time
不支持 time 数据类型的综合。
5、force 和 release
不支持 force 和 release 的综合。
6、assign 和 deassign
不支持对 reg 数据类型的 assign 或 deassign 进行综合,支持对 wire 数据类型的 assign或 deassign 进行综合。
7、fork join
不可综合,可以使用非块语句达到同样的效果。
8、primitives
支持门级原语的综合,不支持非门级原语的综合。
9、table
不支持 UDP 和 table 的综合。
10、敏感列表里同时带有 posedge 和 negedge
如:always @(posedge clk or negedge clk) begin…end
这个 always 块不可综合。
11、同一个 reg 变量被多个 always 块驱动
12、延时
以#开头的延时不可综合成硬件电路延时,综合工具会忽略所有延时代码,但不会报错。
如:a=#10 b;
这里的#10 是用于仿真时的延时,在综合的时候综合工具会忽略它。也就是说,在综合的时候上式等同于 a=b;
13、与 X、Z 的比较
可能会有人喜欢在条件表达式中把数据和 X(或 Z)进行比较,殊不知这是不可综合的,综合工具同样会忽略。所以要确保信号只有两个状态:0 或 1。

7. VHDL 的结构

  1. 实体(Entity):描述所设计的系统的外部接口信号,定义电路设计中所有的输入和输出端口;
  2. 结构体 (Architecture) :描述系统内部的结构和行为;
  3. 包集合 (Package):存放各设模块能共享的数据类型 、常数和子程序等 ;
  4. 配置 (Configuration):指定实体所对应的结构体;
  5. 库 (Library):存放已经编译的实体 、结构体 、包集合和配置。

VHDL 基本设计单元结构:程序包说明、实体说明和结构体说明三部分:

8. VHDL:WAIT 语句格式

WAIT FOR
WAIT UNTIL
WAIT ON

9. 原语

原语,即 primitive。不同的厂商,原语不同;同一家的 FPGA,不同型号的芯片,可以也不一样;原语类似最底层的描述方法。使用原语的好处,可以直接例化使用,不用定制 IP;即可通过复制原语的语句,然后例化 IP,就可使用。

9.1 常见原语

9.1.1 IBUF 和 IBUFDS(IO)

IBUF 是输入缓存,一般 vivado 会自动给输入信号加上,IBUFDS 是 IBUF 的差分形式,支持低压差分信号(如 LVCMOS、LVDS 等)。在 IBUFDS 中,一个电平接口用两个独特的电平接口(I 和 IB)表示。一个可以认为是主信号,另一个可以认为是从信号。主信号和从信号是同一个逻辑信号,但是相位相反。

9.1.2 IDDR(Input/Output FuncTIons)

被设计用来接收 DDR 数据,避免额外的时序复杂性。

9.1.3 IBUFG 和 IBUFGDS(IO)

IBUFG 即输入全局缓冲,是与专用全局时钟输入管脚相连接的首级全局缓冲。所有从全局时钟管脚输入的信号必须经过 IBUF 元,否则在布局布线时会报错。

10. False-path

总得来说,FALSE PATH 就是我们在进行时序分析时,不希望工具进行分析的那些路径。一般不需要工具时序分析的路径指的是异步的路径,异步路径就是指的不同时钟域的路径。

11. 编译预处理

编译预处理是 VerilogHDL 编译系统的一个组成部分,指编译系统会对一些特殊命令进行预处理,然后将预处理结果和源程序一起在进行通常的编译处理。以" ’ " (反引号) 开始的某些标识符是编译预处理语句。在 Verilog HDL 语言编译时,特定的编译指令在整个编译过程中有效(编译过程可跨越多个文件),直到遇到其他不同的编译程序指令。常用的编译预处理语句如下:
(1) 'define,'undef
(2) 'include
(3)'timescale
(4)'ifdef,'else.'endif
(5)'default_nettype;
(6)'resetall
(7)'unconnect_drive,'nounconnected-drive;
(8)'celldefine,`endcelldefine

  • 2
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
设计Verilog程序比较位运算符、逻辑运算和运算符主要用于比较不同数据的大小、相等性和逻辑关系。这些运算符在编写硬件描述语言中非常常用。 位运算符主要用于操作二进制数据的位级别操作,例如AND (&)、OR (|)、XOR (^)和位取反(~)等。比如,我们可以使用位与运算符来检查两个二进制数中的每个对应位是否都为1,并返回结果。相应地,位或运算符可以检查是否有至少一个对应位为1。位异或运算符可以检查两个相应位是否不同,并返回结果。位取反运算符可以将二进制数的每个位取反。 逻辑运算符用于比较操作数之间的逻辑关系,例如相等性(==)、大于(>)、小于(<)、大于等于(>=)、小于等于(<=)和不等于(!=)等。这些运算符可以用于比较整数、浮点数、逻辑量等不同数据类型。比如,我们可以使用大于运算符来判断两个整数之间的大小,并返回结果。 运算符是一种特殊类型的逻辑运算符,例如逻辑与(&&)和逻辑或(||)。它们可以通过将多个逻辑表达式连接在一起来减少编写代码的量。比如,我们可以使用逻辑与运算符将多个条件连接在一起,只有当所有条件都满足时,结果才为真。 综上所述,设计Verilog程序时,我们可以根据需要选择合适的运算符来比较数据,以实现所需的逻辑关系。位运算符用于位级别的操作,逻辑运算符用于比较不同数据类型的逻辑关系,而运算符可以减少编写代码的量。根据具体的应用需求,我们可以合理选择和使用这些运算符

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值