以Vivado synthesis支持的Verilog结构来学习 Verilog语句可综合性

本文详细介绍了Vivado综合工具对Verilog设计的支持情况,包括Verilog-2001的功能、结构化描述、参数、过程性语句、系统任务与函数、基本单元和保留关键词。强调了在Vivado中哪些特性是可综合的,哪些是不支持的,例如,Vivado支持结构化Verilog、参数化、多维数组,但不支持某些过程性语句和特定的系统任务。此外,还提到了Verilog变量、初始值、数据类型、合法语句和过程性赋值的使用注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

经常看到是否可 Synthesis 的题目,网上对于Verilog 结构是否可 Synthesis 有很多分类标准,但是没有说明具体引用来源,所以学起来总感觉没有底气。
现在以Vivado IDE Synthesis 支持的Verilog 结构来具体学习 Verilog 的可综合性。具体文档是UG901。

1 Verilog 设计

复杂电路的设计通常采用自顶向下的方法。

  • 设计过程的每个阶段都需要不同的规范级别(specification level)。例如,在体系结构级别,规范可以对应于框图或算法状态机(ASM)图。
  • 一个块 或 ASM阶段 对应于一个寄存器传输块,其中的连接是n位导线,例如:
    • 寄存器(Register)
    • 加法器(Adder)
    • 计数器(Counter)
    • 乘法器(Multiplexer)
    • 内部连接逻辑(Interconnect logic)
    • 有限状态机(Finite State Machine (FSM))
  • Verilog允许用计算机语言表达诸如ASM图和电路图之类的符号。

2 Verilog 功能

Verilog提供行为(behavioral)和结构(structural)语言结构。这些结构允许在高抽象级别和低抽象级别上表达设计对象。

  • 使用Verilog设计硬件允许使用软件概念,例如:
    • 并行处理
    • 面向对象的程序设计
  • Verilog的语法类似于C和Pascal
  • Vivado synthesis 支持 IEEE 1364 Verilog
  • 在Vivado synthesis 中支持Verilog,允许以最有效的方式描述全局电路和每个块。
    • 对每个block采用最佳 synthesis 流程进行 synthesis
    • 本文中的synthesis是将高级行为和结构Verilog HDL语句编译成一个平坦的门级网表( gate-level netlist)。然后,可以使用网表对可编程逻辑设备(如Virtex设备)进行自定义编程。
    • 不同的synthesis方法用于:
      • 算数运算块
      • 内部连接逻辑
      • 有限状态机组件

2.1 对 Verilog-2001 的支持

Vivado synthesis 支持 Verilog-2001 的如下功能:

  • 生成(Generate)语句
  • 组合端口/数据类型声明
  • ANSI-style端口列表
  • 模块操作符端口列表
  • ANSI C风格的任务/函数声明
  • 逗号分隔敏感列表
  • 组合逻辑的敏感信号
  • 使用连续赋值的默认线网类型
  • 禁用默认的net声明
  • Indexed vector的部分选择
  • 多维数组
  • net和real数据类型的数组
  • 数组 位和部分选择
  • Signed reg、net和 port 声明
  • Signed-based 整数
  • Signed 算术表达式
  • 算术移位操作符
  • 自动宽度扩展超过32位
  • 幂操作符
  • 待定位宽参数(N-sized parameter)
  • 固定的局部参数
  • 增强的条件编译
  • 文件和行编译器指令
  • 变量的部分选择
    reg [3:0] data;
    reg [3:0] select; // a value from 0 to 7
    wire [7:0] byte = data[select +: 8];
    
  • 递归任务和函数
  • 常量函数

2.2 结构性Verilog

结构化的Verilog描述集合了几个代码块,并允许在设计中引入层次结构。硬件结构的相关概念及其说明如下表所示。

概念说明
Component构建或基本块
Port组件的 I/O 连接器
Signal对应于组件之间的连线

内建逻辑门包括 与(AND)、或(OR)、异或(XOR)、与非(NAND)、或非(NOR)、非(NOT)

Verilog的结构特性允许通过实例化预定义的原语,Xilinx提供的源于如BUFG、CLKDLL等

2.3 Verilog 参数

Verilog参数的作用:

  • 创建易于重用和扩展的参数化代码。
  • 使代码更具可读性、更紧凑、更易于维护。
  • 描述这样的功能:
    • 总线位宽
    • 在模型设计单元中某些重复元素的数量
  • 常数。对于参数化模块的每个实例化,可以重写默认操作符值。
  • 相当于VHDL泛型。不支持空字符串参数。

2.4 Verilog 参数与属性冲突的情况

Verilog参数和属性冲突可能会出现以下情况:

  • 参数和属性可以应用于Verilog代码中的实例和模块。
  • 同时属性也可以在约束文件中指定

2.5 Verilog使用限制

Verilog在Vivado synthesis中的使用限制包括:

  • 大小写敏感
    • Verilog大小写敏感,但是当模块名称只是大小写不同时,Vivado synthesis会出错。
  • 阻塞和非阻塞赋值
    • 不要混合使用阻塞和非阻塞赋值。虽然 Vivado synthesis 不会报错(注意只是不会报错)但是仿真会出错。
    • 错误示范
      always @(in1)
      begin
      if (in2)
          out1 = in1;
      end else
          out1 <= in2;
      
  • 整数处理
    • 在case表达式中,未设置大小的整数可能导致不可预测的结果。
    • 连接操作符中的整数处理,vivado会新建32bit临时变量在进行位拼接。

2.6 Verilog元注释

  • Translate Off and Translate On
    // synthesis translate_on
    // synthesis translate_off
    
  • Parallel Case
    // synthesis parallel_case full_case
    // synthesis parallel_case
    // synthesis full_case
    

3 Verilog 结构

下表列出了Vivado synthesis 支持的 Verilog结构:

3.1 常量

常量是否支持
Integer支持
Real支持
String不支持

3.2 数据类型

数据类型是否支持
tri0,tri1,trireg三种线网类型不支持
所有的驱动强度(Drive strength)忽略
real和realtime寄存器不支持
所有命名过的event不支持
delay忽略

3.3 过程性语句

类型是否支持
过程性assign不支持
过程性deassign不支持
force不支持
release不支持
forever语句不支持
repeat语句支持,但重复值必须是常量
for语句支持,但边界必须是静态的
delay (#)忽略
event (@)不支持
wait不支持
named events不支持
parallel blocks(fork…join)不支持
specify blocks忽略
disable支持,除了For和Repeat循环语句

3.3 设计层次结构

结构是否支持
module定义支持
macromodule定义不支持
hierarchical 名字支持
defparam支持
数组的实例支持

3.4 编译指令

指令是否支持
`celldefine `endcelldefine忽略
`default_nettype支持
`define支持
`ifdef `else `endif支持
undef, \ifndef, `elsif支持
`include支持
`resetall忽略
`timescale忽略
`unconnected_drive `nounconnected_drive忽略
`uselib不支持
`file, `line支持

4 Verilog 系统task与function

Vivado synthesis支持的系统任务或功能如下表所示。Vivado synthesis忽略不支持的系统任务。

系统任务或函数状态说明
$display不支持
$fclose支持
$fdisplay忽略
$fgets支持
$finish忽略
$fopen支持
$fscanf支持转义序列仅限于%b和%d
$fwrite忽略
$monitor忽略
$random忽略
$readmemb支持
$readmemh支持
$signed支持
$stop忽略
$strobe忽略
$time忽略
$unsigned支持
$write不支持
$clog2支持这仅在SystemVerilog中受支持
$floor限制支持仅限参数
$ceil限制支持仅限参数
$rtoi不支持
$itor不支持
all others忽略

5 转换函数的使用

使用以下语法在任何表达式上调用 s i g n e d 和 signed和 signedunsigned系统任务。
$signed(expr) or $unsigned(expr)

  • 这些调用的返回值与输入值大小相同。
  • 无论前面有任何符号,返回值的符号都是强制的。

另外,可以使用使用 r e a d m e m b 和 readmemb和 readmembreadmemh系统任务来初始化块内存。

6 Verilog 基本单元(原语)的支持

Vivado综合支持Verilog门级(gate-level)原语,除了下表:

基本单元状态
pulldown 和 pullup不支持
驱动强度与延时忽略
数组的基本单元不支持

Vivado synthesis 不支持Verilog开关级( switch-level )原语,例如:cmos, nmos, pmos, rcmos, rnmos, rpmos rtran, rtranif0, rtranif1, tran, tranif0, tranif1

7 Verilog 保留的关键词

做题目的时候遇到偏僻关键词直接搜索

alwaysandassignautomatic
beginbufbufif0bufif1
casecasexcasezcell*
cmosconfig*deassigndefault
defparamdesign*disableedge
elseendendcaseendconfig*
endfunctionendgenerateendmoduleendprimitive
endspecifyendtableendtaskevent
forforceforeverfork
functiongenerategenvarhighz0
highz1ififnoneincdir*
include*initialinoutinput
instance*integerjoinlarger
liblist*library*localparammacromodule
mediummodulenandnegedge
nmosnornoshow-cancelled*not
notif0notif1oroutput
parameterpmosposedgeprimitive
pull0pull1pullup*pulldown*
pulsestyle_ondetect*pulsestyle_onevent*rcmosreal
realtimeregreleaserepeat
rnmosrpmosrtranrtranif0
rtranif1scalaredshow-cancelled*signed
smallspecifyspecpastrong0
strong1supply0supply1table
tasktimetrantranif0
tranif1tritri0tri1
triandtriortrireguse*
vectoredwaitwandweak0
weak1whilewirewor
xnorxor

8 行为级Verilog语言结构

Vivado synthesis 支持行为Verilog硬件描述语言(HDL),除非另有说明

8.1 变量

  • 行为级Verilog中的变量声明为整数。
  • 这些声明只在测试代码中使用。Verilog为实际的硬件描述提供了reg和wire等数据类型。
  • reg和wire之间的区别取决于变量的值是在过程块(reg)中给出的,还是在连续赋值(wire)中给出的。
    • reg和wire都有一个位(标量)的默认宽度。
    • 要为声明的reg或wire指定n位宽度(向量),左位和右位位置在用冒号分隔的方括号中定义。
    • 在Verilog-2001中,reg和连接数据类型可以为有符号或无符号。

8.2 初始值

在Verilog-2001中声明寄存器时初始化它们。

  • 初始值:
    • 常数
    • 不能依赖于较早的初始值。
    • 不能是函数或任务调用。
    • 可以是传播到寄存器的 parameter 值。
    • 指定向量的所有位。
  • 当在声明中将一个寄存器赋值为初始值时,Vivado synthesis将在全局复位或上电时在寄存器的输出上设置此值。
reg arb_onebit = 1'b0;
reg [3:0] arb_priority = 4'b1011;
  • 当以这种方式赋值时:
    • 该值作为寄存器上的INIT属性携带在Verilog文件中。
    • 该值与任何本地reset无关。

给寄存器赋一个set/reset(初始)值:

  • 当寄存器重置行变为适当值时,将该值赋给寄存器。示例。
    always @(posedge clk)
    begin
    if (rst)
        arb_onebit <= 1'b0;
    end
    
  • 当你给一个变量赋初始值时:
    • 该值以一个触发器的形式实现,其输出由本地reset控制。
    • 该值作为FDP或FDC触发器在Verilog文件中携带。

8.3 reg 或 wire 数组

支持

reg [3:0] mem_array [31:0];

8.4 多维数组

Vivado synthesis 支持至多二维的多维数组类型

wire [7:0] array2 [0:255][0:15];
reg [63:0] regarray2 [255:0][7:0];
  • 多维数组可以是:
    • 任意net
    • 任意变量数据类型
  • 使用数组进行赋值和算术运算。
  • 一次不能选择数组中的多个元素。
  • 不能将多维数组传递给:
    • 系统任务或函数
    • 常规任务或函数

8.5 数据类型

bit 数据类型的Verilog表示包含以下值:

  • 0:逻辑0
  • 1:逻辑1
  • x:未知逻辑值
  • z:高阻态

支持的数据类型

  • net
    • wire
  • register
    • reg
    • integer
  • 常数
    • 参数
    • 多维数组(内存)

8.6 合法的语句

Vivado综合支持行为Verilog合法语句

  • 以下语句(变量赋值和信号赋值)是合法的:
    • variable = expression
    • if (condition)语句
    • else 语句
    • case (expression)
    • for (variable = expression; condition; variable = variable + expression) 语句
    • while (condition) 语句
    • forever 语句
    • 函数与任务
  • 所有变量都声明为integer或reg。
  • 不能将变量声明为wire。

8.7 块Block

Vivado综合支持一些块语句,如下所示:

  • 语句块
    • 将语句组织在一起。
    • begin和end关键字指定
    • 按照块中列出的顺序执行语句。
  • Vivado合成只支持顺序块。
  • Vivado合成不支持并行块。
  • 所有过程语句都发生在模块内部定义的块中。
  • 两种过程块是:
    • initial block
    • always block
  • Verilog在每个块中使用begin和end关键字来封装语句。因为在综合过程中忽略initial块,所以只描述always块。

9 过程性赋值(Procedural Assignment)

  • 行为Verilog过程性赋值:
    • 为声明为reg的变量赋值。
    • 由always块、任务和函数引入。
    • 模型寄存器和有限状态机组件
  • Vivado综合支持:
    • 组合逻辑函数
    • 组合逻辑与时序逻辑任务
    • 组合逻辑与时序逻辑always块

组合逻辑always块
组合逻辑由Verilog时间控制语句高效建模:

  • 延时控制语句[#]
    • 仅作用于仿真
    • 综合过程会忽略
  • 事件控制时间控制语句[@]
    • always组合块的敏感性列表出现在always@后面的括号中
    • 如果一个事件(值改变或边沿信号)出现在一个敏感列表信号上,一个always块将被激活。
    • 敏感列表可以包含:
      • 在条件中出现的任何信号,如if或case。
      • 任何出现在赋值函数右边的信号。
    • 通过将@(at)替换为不带圆括号的信号列表,always块将为描述的任何always块信号中的事件激活。

9.1 if-else 语句

支持

9.2 case 语句

支持

9.3 for和repeat语句

Vivado综合支持for和repeat语句。当使用always块时,重复或bit slice结构也可以使用for语句或repeat语句来描述。

repeat语句只支持常量值

9.4 while 语句

当使用always块时,使用while循环来执行重复的过程。

  • 一个while循环:
    • 如果测试表达式最初为假,则不执行。
    • 执行其他语句,直到其测试表达式变为false
  • 测试表达式是任何有效的Verilog表达式。
  • 要防止无限循环,使用-loop_iteration_limit选项。
  • while循环可以有disable语句。disable语句在标记块中使用,如下代码片段所示:disable <blockname>
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ChipWeaver

觉得有用的话点个赞吧 :)

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

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

打赏作者

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

抵扣说明:

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

余额充值