Floorplanner :
在 FPGA (Field-Programmable Gate Array) 设计流程中,Floorplanner 是一个重要的工具,用于进行物理设计阶段的布局规划。Floorplanner 工具可以帮助设计者优化 FPGA 设计的物理布局,以满足特定的性能指标,如时序、功耗和面积等。
Floorplanner 的功能包括:
- 布局规划:Floorplanner 用于决定设计中各个模块的位置,包括硬核 IP、软核 IP、用户逻辑等。
- 资源分配:Floorplanner 可以帮助分配 FPGA 内部资源,如查找表 (LUTs)、寄存器、DSP 块、BRAM 和 IOB 等。
- 约束管理:设计者可以通过 Floorplanner 应用物理约束,例如时序约束、功率约束、面积约束等。
- 手动调整:Floorplanner 允许设计者手动调整布局,以解决时序问题或优化性能。
- 时序分析:Floorplanner 可以与时序分析工具集成,以确保布局符合时序要求。
- 迭代优化:Floorplanner 通常会与综合工具和布线工具协同工作,通过多轮迭代来优化布局。
- 使用 Floorplanner 的步骤可能包括:
- 定义约束:定义设计的物理约束,包括时序、功率和面积要求。
- 初始布局:生成设计的初始布局。
- 优化布局:通过迭代调整布局来优化性能指标。
- 验证布局:使用时序分析工具验证布局是否满足约束。
- 最终布局:生成最终布局,并准备比特流文件用于编程 FPGA。
示例:
假设你正在使用一个特定的 FPGA 开发工具,比如 Xilinx Vivado 或 Altera Quartus II,Floorplanner 会是这些工具套件的一部分,用于完成物理设计阶段的工作。
例如,在 Vivado 中,Floorplanner 工具允许你放置和固定 IP 核心、定义区域和 IO 位置、设置时序约束等,从而帮助优化设计的性能。
总之,Floorplanner 是 FPGA 设计流程中用于物理设计布局的重要工具,有助于确保设计满足所有必要的性能要求。
GPA
千兆性能分析(Giga Performance Analysis),是一种工具或服务,例如,支持22nm器件的GPA
FTDI设备
FTDI(Future Technology Devices International)是一家专注于 USB 和串行接口技术的半导体公司。FTDI 设备通常指的是该公司生产的集成电路(IC)和其他相关的产品,这些产品主要用于实现 USB 和串行通信。例如 FT232 系列芯片
Timing Constraints Editor
Timing Constraints Editor 是一个工具,用于编辑和查看 FPGA 设计中的时序约束。时序约束是一种描述 FPGA 设计中时序关系的方法,它定义了设计中各个模块之间的时序关系,如时序路径、时序路径延迟、时序路径延迟范围等。
功能包括:
- 定义时钟:指定设计中的时钟信号及其属性,如周期、占空比等。
- 路径组:定义时序路径的组别,有助于组织和管理复杂的时序路径。
- 时序约束:
- 建立时间约束(Setup Time Constraint):定义数据到达触发器之前必须稳定的时间。
- 保持时间约束(Hold Time Constraint):定义数据在时钟边沿之后必须保持稳定的时间。
- 最大时延约束(Max Delay Constraint):限制信号从一个点到另一个点的最大传播时间。
- 最小时延约束(Min Delay Constraint):定义信号传播的最小时延。
- 多周期路径(Multi-Cycle Path):定义需要多个时钟周期才能完成的路径。
- 时序例外:定义不需要考虑时序分析的路径,如非关键路径或不关心的路径。
- 时序报告:生成时序分析报告,显示设计是否满足约束条件。
- 编辑和管理:提供界面来添加、修改和删除时序约束。
使用步骤:
- 打开编辑器:在 FPGA 开发软件中找到 Timing Constraints Editor 并打开。
- 定义时钟:使用时钟列表来定义设计中的时钟信号。
- 编辑约束:为每个时钟指定相应的时序约束,如建立时间、保持时间等。
- 查看和修改:在编辑器中查看已有的约束,并进行必要的修改。
- 应用约束:保存更改并应用到设计中。
- 分析报告:运行静态时序分析来验证设计是否满足约束。
IBIS
IBIS(I/O Buffer Information Specification)文件是FPGA设计和验证中非常重要的组成部分。IBIS 文件是一种标准格式的文本文件,用于描述 FPGA 芯片 I/O 缓冲器的电气特性,特别是输入输出缓冲器的电压电流特性。
内部信息包括但不限于:
- 电压电流关系:描述在不同电压水平下流过缓冲器的电流。
- 电压时间关系:描述缓冲器输出电压随时间的变化。
- 缓冲器模型:包括缓冲器的静态和动态特性。
- 器件和管脚信息:描述 FPGA 芯片上的各个管脚及其电气特性。
包含以下几个主要部分:
-
文件头信息:
版本信息:定义 IBIS 文件的版本。
文件名:文件的名称。
日期:文件创建或最后修改的日期。
生成厂家:制造商或供应商的名称。
版权声明:版权信息。
-
器件描述:
元件名称:定义 IBIS 文件中所包含的元件。
器件名称:描述该 IBIS 文件对应的具体器件。
厂商信息:制造商的详细信息。
-
模型描述:
模型名称:定义缓冲器模型的名称。
模型类型:指示模型是输入、输出还是双向缓冲器。
管脚信息:描述与模型相关的管脚。
-
I/V 数据:
电压/电流曲线:提供电压与电流之间的关系数据点,用于模拟缓冲器的行为。
电流模式:定义电流随时间的变化模式。
-
时序信息:
建立时间(Setup Time):数据必须在时钟边沿之前稳定的最小时间。
保持时间(Hold Time):数据必须在时钟边沿之后稳定的最小时间。
传播延迟(Propagation Delay):信号从输入到输出的传播时间。
上升时间和下降时间(Rise Time / Fall Time):信号从低电平到高电平或从高电平到低电平所需的时间。
-
封装寄生参数:
电容(Capacitance):描述芯片封装的等效电容。
电阻(Resistance):描述芯片封装的等效电阻。
电感(Inductance):描述芯片封装的等效电感。
-
其他信息:
功耗信息:描述缓冲器的功耗特性。
温度范围:定义缓冲器工作的温度范围。
电压范围:定义缓冲器工作的电压范围。
IP Core
IP Core(集成式处理器核心)是一种计算机系统设计方法,它将多个独立模块组合成一个整体,以实现更高级别的功能。IP Core 是一种可重用的、可配置的、可移植的、可扩展的、可复用的计算机系统设计元素,它通常由多个模块组成,这些模块可以独立使用,也可以与其他模块组合在一起。
分为三类:
- 软 IP:以高级描述语言(如 Verilog 或 VHDL)的形式提供,没有经过综合,通常只包含功能描述而没有具体的物理实现细节。
- 固 IP:已经过综合,提供了布局布线前的门级网表,但还没有具体的物理实现。
- 硬 IP:提供了最终的物理实现,例如掩膜版图,可以直接用于制造。
应用场景:
- 微处理器和控制器:例如 ARM Cortex 系列处理器。
- 存储器接口:如 DDR SDRAM 控制器。
- 通信协议接口:如 USB、PCI Express、Ethernet 等。
- 多媒体处理:如图像处理单元、音频编解码器。
- 加密引擎:用于数据安全的加密算法实现。
- 模拟和混合信号 IP:如 ADC(模数转换器)、DAC(数模转换器)。硬件加速:IP Core 可以实现硬件加速,如加密、解密、压缩、解压缩等。
硬连线
硬连线(Hard-Line)是一种在 FPGA 设计中用于连接两个逻辑单元的连接方式。它通过直接连接两个逻辑单元的端口来建立逻辑连接,而不需要通过其他中间逻辑单元。硬连线通常用于连接两个逻辑单元之间的信号,如输入和输出端口、内部信号等。
特点:
- 固定性:硬连线是预先定义好的,不能被重新配置。
- 高效性:由于硬连线是直接连接,因此信号传播速度较快,延迟较低。
- 不可重配置:一旦 FPGA 被制造出来,硬连线就无法改变。
应用:
- 高速路径:对于需要非常快速响应的信号路径,硬连线可以提供低延迟的连接。
- 专用功能:某些 FPGA 包含硬连线的专用功能块,如乘法器、除法器、RAM 和 ROM 单元等。
- 时钟网络:FPGA 中的时钟信号通常通过专用的硬连线时钟网络来分布,以确保时钟信号的精确性和一致性。
IOLOGIC
IOLOGIC(Input/Output Logic)是一种用于 FPGA 设计中输入输出逻辑单元的逻辑单元。它包含一个输入端口和一个输出端口,用于处理输入和输出信号。
功能:
- 输入/输出缓冲器 (IOBs, I/O Buffers):用于连接 FPGA 内部逻辑与外部世界的接口。这些缓冲器可以根据需要配置为不同的电平标准(如 LVCMOS、LVDS 等)。
- 时钟管理:包括时钟缓冲器、时钟分配网络以及相关的时钟控制逻辑,用于确保时钟信号的正确分布和管理。
- 数据速率转换:例如,使用 ISERDES (In-System Serializer/Deserializer) 或 IDDR (Input Dual Data Rate) 等功能来处理高速串行数据的串行化和解串行化。
- 数据对齐和同步:用于确保数据在不同时钟域之间的正确对齐和同步。
- 时序控制:包括建立时间、保持时间等时序约束的管理。
- 延迟控制:例如 IDELAY (Input Delay) 和 ODELAY (Output Delay) 用于调整信号的传播延迟。
示例,假设您正在设计一个 FPGA 项目,其中需要与外部设备进行高速数据交换。在这种情况下,您可能会使用 IOLOGIC 中的以下功能:
- ISERDES:用于处理高速串行数据的串行化和解串行化
- IDDR 和 ODDR:用于双倍数据速率 (DDR) 信号的输入和输出
- IDELAY 和 ODELAY:用于微调信号的传播延迟,以满足严格的时序要求。
原语
"原语"(Primitive)指的是 FPGA 芯片内部预定义的、最基本的硬件功能单元。这些原语通常是不可再分割的,可以直接在硬件描述语言(如 VHDL 或 Verilog)中实例化使用,而不需要额外的综合或映射步骤。
示例:
- GSR 原语:指的是 "Global Set Reset",它是 FPGA 中的一个原语,用于实现全局复位功能。当激活 GSR 时,它可以将 FPGA 中的大部分逻辑单元(如触发器)置为已知状态,这对于初始化 FPGA 的状态非常有用。
- GSR 实例化: 指的是在 FPGA 设计中使用 GSR 原语的过程。这通常涉及到在硬件描述语言中声明和使用 GSR 原语,以便在 FPGA 内部实现全局复位功能。
不同 FPGA 厂商提供的原语可能有所不同,而且使用方式也会有所差异。例如,在 Xilinx 的 FPGA 中,全局复位功能可能通过特定的原语或配置选项来实现。
原语的实例化步骤:
- 了解原语:首先需要了解所使用的 FPGA 厂商提供的 GSR 原语的详细信息,包括其名称、参数和使用方法。
- 实例化原语:在设计中实例化 GSR 原语,通常需要在代码中声明该原语,并将其与相应的信号相连。
- 配置原语:根据设计需求,可能还需要配置 GSR 原语的参数,如是否使能全局复位、复位信号的极性等。
- 验证功能:完成实例化后,需要通过仿真和测试来验证 GSR 原语的功能是否符合预期。
注意:原语实例化的名字在一个模块中不可以重复,不同模块中可以重复
菊花链
在FPGA设计中,"菊花链"(Daisy Chain)通常指的是通过JTAG接口将多个FPGA或其他可编程逻辑器件(如CPLD)串联起来的一种连接方式。这种连接方式允许使用单个JTAG接口来访问和控制菊花链中的所有器件。
JTAG菊花链的工作原理:
- 接口定义:JTAG接口通常包括TCK(时钟)、TMS(模式选择)、TDI(数据输入)、TDO(数据输出)和TRST#(可选的复位信号)等信号线。
- 链路建立:第一个器件的TDI与外部JTAG接口相连,而其TDO则连接到第二个器件的TDI,依此类推,直到最后一个器件的TDO连接回外部JTAG接口的TDO。
- 数据传输:数据通过TDI进入第一个器件,然后依次传递给下一个器件,最终从最后一个器件的TDO输出。
SRAM
SRAM (Static Random Access Memory) 是 RAM (Random Access Memory) 的一种类型,因此讨论 SRAM 和 RAM 的区别实际上是在讨论 SRAM 和 DRAM (Dynamic Random Access Memory) 的区别,因为 RAM 主要分为这两种类型。
用途:
- SRAM: 通常用于高速缓存(如 CPU 的 L1 和 L2 缓存),因为它速度快但容量较小且成本较高。
- DRAM: 通常用于主内存(RAM),因为它容量大且成本低。
原理:
- SRAM: 不需要定期刷新数据。每个存储单元由几个晶体管组成,通常是一个六晶体管的单元,可以保持数据状态而不需要额外的电源。
- DRAM: 需要定期刷新数据以维持存储的信息。每个存储单元由一个晶体管和一个电容器组成,电容器会随时间逐渐放电,因此需要周期性地重新充电以保持数据的准确性。
SVF文件
SVF (Serial Vector Format) 文件在 FPGA (Field-Programmable Gate Array) 领域中主要用于存储 JTAG (Joint Test Action Group) 接口的测试向量序列。不过,在 FPGA 的上下文中,SVF 文件通常与 FPGA 的配置和编程相关联。
用途/内容/工具:
- 配置 FPGA:SVF 文件可以包含用于配置 FPGA 的指令序列,这些指令通过 JTAG 接口发送到 FPGA。通常用于批量生产环境中的 FPGA 配置,特别是在需要通过 JTAG 接口进行编程的情况下。
- 边界扫描测试:可以用于边界扫描测试,通过 JTAG 接口对 FPGA 中的电路进行测试。测试向量可以被编码在 SVF 文件中,并通过 JTAG 接口加载到 FPGA 中,以验证电路的功能性和连接性。
- 内容:指令集、测试向量、配置数据
- 使用工具(都是Xilinx的):ISE Project Navigator(用于创建和管理 FPGA 项目)、iMPACT(将 BIT 文件转换为 SVF 文件)
创建和使用过程:
- 编译源文件:使用 Verilog 或 VHDL 等硬件描述语言编写 FPGA 设计,并使用 ISE Project Navigator 编译生成 BIT 文件。
- 生成 BIT 文件:编译过程完成后,会生成一个包含 FPGA 配置信息的 BIT 文件。
- BIT 文件转 SVF 文件:使用 iMPACT 工具将 BIT 文件转换为 SVF 文件。
- 通过 JTAG 下载 SVF 文件:使用 iMPACT 或其他支持 JTAG 的工具通过 JTAG 接口将 SVF 文件下载到 FPGA 中。
FIFO HS
"High-Speed First-In, First-Out"(高速先进先出)缓冲器,这是一种专门设计用于高速数据传输的 FIFO(First-In, First-Out,先进先出)缓冲器。
- 特点:高速数据传输、 内部存储结构、 可配置性、 同步或异步操作
- 场景:高速数据缓冲、 数据流控制、 时钟域转换
- 设计考虑:深度设置、 性能优化
- 实现方式:硬件实现、 IP核
异步时钟域
异步时钟域(Asynchronous Clock Domain)是指在 FPGA 设计中,多个逻辑单元(如寄存器、门、逻辑单元等)之间没有直接的时钟信号连接,而是通过信号转换器(如 BUFG、BUFGCE、BUFR 等)进行时钟信号的转换。这种时钟域称为异步时钟域,因为它没有直接的时钟信号连接,而是通过信号转换器进行时钟信号的转换。
特点:
- 时钟频率:不同域的时钟频率可能不同。
- 时钟相位:不同域的时钟相位可能不一致。
- 独立性:每个时钟域通常是独立控制的,不受其他时钟域的影响。
常见问题:
- 亚稳态(Metastability):当信号从一个时钟域传递到另一个时钟域时,接收端的触发器可能会进入一个不稳定状态,在逻辑0和逻辑1之间波动,这种现象称为亚稳态。
- 数据一致性:由于时钟不同步,数据在两个时钟域之间的传递可能会导致数据不一致或丢失。
约束文件
约束文件(Constraint File)是 FPGA 设计中用于约束电路布局和资源分配的重要文件。约束文件包含 FPGA 布局的约束条件,如端口位置、资源分配、时钟频率、时钟相位、时钟信号的驱动方式等。约束文件的作用是确保电路在指定的约束条件下运行,并尽可能地满足设计需求。
作用:
- 时序约束:定义设计的时序要求,例如最大和最小时钟周期、设置和保持时间等。
- 管脚约束:指定FPGA芯片上特定的I/O引脚,用于连接外部设备。
- 布局布线约束:指导综合工具和布局布线工具如何在FPGA内部放置和连接逻辑单元。
文件类型:
- UCF (User Constraints File):Xilinx的约束文件格式,用于在设计输入阶段定义时序、管脚和布局布线约束。
- PCF (Placement Constraints File):早期Xilinx工具中使用的约束文件格式,主要用于定义管脚分配。
- NCF (Netlist Constraints File):由综合工具生成的约束文件,它包含了综合后的设计约束信息。
使用流程:
- 设计输入阶段:用户编写UCF文件,定义各种约束。
- 综合阶段:综合工具会根据UCF文件生成NCF文件,该文件包含了综合后的设计约束。
- 实现阶段:在布局布线过程中,工具会生成PCF文件,用于最终的物理实现。
always块
是Verilog HDL中的一种过程块,它允许你描述电路的行为。每当敏感列表中的信号发生变化时,always块内的代码就会被执行。
类型:
- 时序逻辑:使用posedge或negedge关键字来指定触发条件,例如时钟的上升沿或下降沿。
- 组合逻辑:使用@*敏感列表来表示任何输入变化都会立即触发always块的执行。
和main的区别:
- 模型:基于事件驱动,当敏感列表中的信号发生变化时执行。非顺序执行。
- 并发性:可以同时执行多个always块,模拟并行操作。
- 目的:描述硬件的行为,用于综合成实际的电路。
- 循环:没有显式的循环结构,而是通过不断监听信号的变化来重复执行。
- 数据类型:使用硬件描述语言的数据类型,如wire、reg等。
- 作用范围:通常位于模块内,用于描述模块内部的行为。
Synthesize
"Synthesize"(合成)是指将高层次的硬件描述语言(HDL)代码转换成低层次的逻辑门或基本单元的过程。这个过程通常由专门的EDA(电子设计自动化)工具完成,这些工具被称为综合器(Synthesizer)。
含义:
- 将高级描述转换为低级逻辑:将Verilog或VHDL等HDL语言编写的代码转换成逻辑门、触发器和其他基本硬件组件。
- 优化设计:综合器会对设计进行优化,以满足时序要求、面积限制和功耗目标。
- 生成网表(Netlist):综合完成后,会生成一个网表文件,描述了设计中各个组件之间的连接关系。
assign
在FPGA设计中,assign语句用于组合逻辑电路的描述,它用来定义信号间的持续赋值关系。assign语句是非阻塞式的,这意味着它可以被综合工具识别,并且通常用来连接信号或者计算表达式的值并将其赋给一个wire类型的变量。assign语句属于组合逻辑,不涉及时序逻辑(如触发器)。
LVDS
LVDS (Low-Voltage Differential Signaling)(低电压差分信号) 是一种用于高速数据传输的技术标准,主要用于短距离、高速度的数据通信。LVDS 通过使用差分信号来减少电磁干扰 (EMI),提高信号完整性和可靠性。
特点:
- 低电压摆幅:LVDS 使用较低的电压摆幅(大约 350mV),这有助于降低功耗。
- 差分信号:LVDS 使用差分对传输数据,即一对线路上传输相反极性的信号,这有助于减少电磁干扰和提高信号质量。
- 高速传输:LVDS 支持高速数据传输速率,最高可达数 Gbps。
- 低功耗:由于低电压摆幅,LVDS 设备通常具有较低的功耗。
真LVDS和模拟LVDS的比较:
- 信号类型:真 LVDS 专为数字信号设计,而模拟 LVDS 则用于传输模拟信号。
- 标准遵循:真 LVDS 严格遵循 IEEE 644-2002 标准,而模拟 LVDS 可能会有所变通以适应模拟信号的特性。
- 应用场景:真 LVDS 更多应用于高速数字通信领域,而模拟 LVDS 通常用于视频和音频信号传输等场景。
- 信号处理:真 LVDS 通常不需要额外的信号处理电路,而模拟 LVDS 可能需要模拟信号处理电路来处理模拟信号的转换和传输。
Buffer缓冲器
在FPGA设计中,缓冲器(Buffer)是一种非常重要的组件,它们被广泛应用于信号处理和时钟管理中。
用途:
- 信号增强和分配:缓冲器可以增强信号的驱动能力,确保信号能够稳定地驱动后续的逻辑门或电路。可以将一个信号复制并分配给多个接收端。这对于需要将信号发送到多个目的地的情况非常有用,例如时钟信号需要分发到整个芯片的不同部分。
- 隔离:电气隔离(减少信号间的相互干扰,避免信号反射和串扰)、逻辑隔离(防止前一级电路的状态被后一级电路改变)
- 时钟管理:时钟缓冲(用于管理和优化时钟信号的传播和分配、用于同步电路设计)、时钟树合成(时钟信号通常通过精心设计的时钟树进行分配,以最小化时钟偏移和抖动)
- 总线收发器/缓冲器:总线驱动(提高驱动能力)、三态输出(避免同时驱动导致的冲突)
输入查找表 LUT
FPGA(Field-Programmable Gate Array,现场可编程门阵列)中,查找表(Look-Up Table,简称LUT)是一种基本的可编程逻辑单元,用于实现各种逻辑功能。
查找表(LUT)定义:
- 基本概念:LUT可以被视为一个小容量的只读存储器(ROM)。它接受多个输入信号,并基于这些输入信号的组合,从预先配置好的存储单元中查找并输出相应的值。
- 实现原理:LUT内部包含一个存储区域,每个可能的输入组合对应一个存储单元。当输入信号发生变化时,LUT通过这些输入信号作为地址来访问存储单元,并输出该单元中的值。
- 灵活性:由于LUT的存储单元可以通过编程来设置,所以它可以实现几乎所有的布尔逻辑函数,这使得FPGA具有高度的灵活性和可重构性
SOPC
SOPC(System On a Programmable Chip)设计是指在一片可编程逻辑器件(如FPGA------Field-Programmable Gate Array)上实现一个完整的系统。这种设计方法允许设计师在一个单一的FPGA芯片内集成多种硬件模块,包括但不限于微处理器、存储器接口、外围设备接口以及其他用户自定义的硬件加速器或IP(知识产权)核。
- 特点:可编程性 集成度高 定制化 快速原型验证
- 应用场景:嵌入式系统 数字信号处理 通信系统 图像处理
- 和soc区别:soc内部组件一般是固定的
FPGA的PS和PL设计
FPGA(Field-Programmable Gate Array)是一种可编程逻辑器件,可以被用来实现各种数字逻辑电路。在某些现代FPGA设备中,特别是那些被称为SoC(System on Chip)FPGA的设备,如Xilinx的Zynq系列,它们不仅包含可编程逻辑(PL, Programmable Logic),还集成了一个或多个处理器核心和其他硬件加速器,这些通常被称为PS(Processing System)。
PS(Processing System):
- 定义: PS部分通常指的是与FPGA逻辑无关的、预定义的硬件,如ARM处理器核、内存控制器、外设接口等。
- 功能: PS部分提供了类似于传统微控制器的功能,可以运行操作系统,执行高级软件任务,并管理整个系统的操作。
- 用途: PS部分可以用来执行那些不适合用硬件逻辑实现的任务,如复杂的算法、软件栈管理和用户界面控制等。
PL(Programmable Logic):
- 定义: PL部分指的是FPGA内部的可编程逻辑资源,这些资源可以被配置成实现任何所需的数字逻辑电路。
- 功能: PL部分可以用来实现自定义的硬件加速器、专用的接口逻辑或其他任何需要高速并行处理能力的功能。
- 用途: PL部分非常适合于实现那些需要高度并行处理的任务,如图像处理、信号处理、网络处理等
PS与PL的交互:
- 通信机制: PS和PL之间可以通过预定义的总线接口(如AXI4-Lite)进行通信。例如,在Zynq SoC中,PS和PL之间可以通过AXI总线进行数据交换。
- 数据处理: 在某些应用场景下,PS可以作为系统的控制中心,负责调度任务并将数据传递给PL进行高速处理;处理完成后,结果再返回给PS。
- DMA(Direct Memory Access): 在需要高效数据传输的情况下,PS和PL之间可以利用DMA机制来减少CPU的负担,直接在内存和PL之间传输数据。
fpga的module和c语言的函数有什么异同
在FPGA设计中,module 是Verilog HDL(硬件描述语言)中的一个基本结构单位,用于描述硬件的行为和结构。而在C语言中,函数 是程序的基本组成单元之一,用于描述软件的行为。虽然两者都具有一定的相似性,但它们在目的、使用环境和实现方式上有显著的不同。
相似点:
- 封装性: 无论是Verilog中的module还是C语言中的函数,都可以被视为封装了一定功能的独立单元。
- 参数传递: module 和 函数 都支持输入参数和输出参数的概念。
- 可重用性: 它们都可以被多次调用或实例化,提高了代码的可重用性。
不同点:
- 目的不同
- Verilog module: 用于描述硬件的行为和结构,最终会被综合成实际的硬件电路。
- C函数: 用于编写软件程序,描述的是软件的行为,最终会被编译成机器码运行在处理器上。
- 并发性
- Verilog module: 可以描述并发的操作,多个信号或寄存器可以同时发生变化。
- C函数: 默认是顺序执行的,除非使用多线程或多进程技术,否则不能同时执行多个操作。
- 时间模型
- Verilog module: 经常涉及对时间的精确控制,比如时钟边沿触发的行为。
- C函数: 没有内置的时间模型,除非显式地使用延时函数。
- 数据类型
- Verilog module: 支持多种数据类型,包括位向量类型(如wire, reg),这些类型更接近硬件的实际表示。
- C函数: 数据类型丰富,但更偏向于软件抽象,如int, float等。
- 实现细节
- Verilog module: 包含了组合逻辑和时序逻辑的描述,可以使用always块来描述时序逻辑。
- C函数: 主要描述算法流程,通常不涉及底层硬件细节。
- 调用方式
- Verilog module: 通过module实例化的方式调用,可以指定端口映射。
- C函数: 通过函数调用的方式执行,可以传递参数。
辅助信号
在FPGA(Field-Programmable Gate Array,现场可编程门阵列)设计中,"辅助信号"通常指的是那些不直接参与主要数据路径的数据传输,而是用来控制或标识数据某些特性的信号。这些信号通常用于帮助数据的正确处理或传输。
如:控制信号、握手协议信号、标志信号、数据掩码或保持信号、地址或控制总线上的辅助信号
数组和向量
- 向量是指数据的位宽,即一个信号有多少位组成。向量可以作为整体进行赋值或操作。
- wire [7:0] my_vector;这里的my_vector就是一个8位宽的向量,它可以作为一个整体来处理,也可以单独处理每一位。向量在Verilog中用方括号表示位宽,如 [7:0] 表示从最高位7到最低位0。
- 数组是指一组具有相同数据类型的元素集合,每个元素可以通过索引来访问。数组中的每个元素可以是向量。
- reg [7:0] my_array [0:9]; 这里的my_array就是一个数组,其中每个元素都是8位宽的。数组在Verilog中通过索引访问,索引通常是整数。
规约操作符
在FPGA设计中,归约操作符(reduction operators)用于对多位宽的数据进行某种形式的归约操作,例如求"与"、"或"、"异或"等。这些操作符通常用于将多位宽的数据简化为单个位的结果。
forever begin和always begin区别
在Verilog HDL中,forever 和 always 都是常用的并发语句,用于描述不同的行为。它们之间的主要区别在于执行的时机和触发条件。下面详细介绍两者的区别和应用场景。
forever 语句:
- forever 语句用于创建一个无限循环,该循环会在仿真启动时开始执行,并持续执行直到仿真结束。
- forever 语句主要用于生成周期性的信号或定时任务。
always 语句:
- always 语句用于描述敏感列表中的信号发生变化时的行为。
- always 语句通常用于描述组合逻辑、时序逻辑或混合逻辑。
顺序块
顺序块用关键字 begin 和 end 来表示。
顺序块中的语句是一条条执行的。当然,非阻塞赋值除外。
顺序块中每条语句的时延总是与其前面语句执行的时间相关。
并行块
并行块有关键字 fork 和 join 来表示。
并行块中的语句是并行执行的,即便是阻塞形式的赋值。
并行块中每条语句的时延都是与块语句开始执行的时间相关。
嵌套块
顺序块和并行块还可以嵌套使用。
并行块中最长的执行时间后执行顺序块内容
命名块
命名的块中可以声明局部变量,通过层次名引用的方法对变量进行访问。
命名的块也可以被禁用,用关键字 disable 来表示。
disable 可以终止命名块的执行,可以用来从循环中退出、处理错误等。
与 C 语言中 break 类似,但是 break 只能退出当前所在循环,而 disable 可以禁用设计中任何一个命名的块。
timescale
timescale 是 Verilog HDL 中的一个预编译指令,用于定义仿真环境中的时间单位和时间精度。这对于理解仿真波形文件以及仿真结果至关重要,因为它影响了仿真器如何解释仿真中的时间延迟。
`timescale <time_unit> / <time_precision> : 其中 <time_unit> 表示时间单位,而 <time_precision> 表示时间精度。时间单位和时间精度可以是 1, 10, 或者 100 与不同的时间单位组合,如 s (秒), ms (毫秒), us (微秒), ns (纳秒), ps (皮秒), fs (飞秒) 等。
使用 timescale 的注意事项:
- timescale 指令应该放在模块的顶部,这样它会对整个模块生效。
- 时间精度不能大于时间单位,但可以等于时间单位。
- 如果在一个设计中没有显式地定义 timescale,那么默认的 timescale 可能会根据不同的仿真工具有所不同,这可能导致仿真结果不一致。
- timescale 指令只影响仿真,并不影响实际硬件的行为。
预编译指令
- define - 宏定义,用于定义常量或字符串替换。
- ifdef, ifndef, else, endif - 条件编译指令,允许根据是否定义了特定的宏来包含或排除代码段。
- include - 文件包含,用来引入其他Verilog文件中的定义。
- timescale - 定义仿真时间单位和精度。
- undef - 删除宏定义。
- verilog_version - 返回当前Verilog标准版本号。
repeat循环
repeat 的功能是执行固定次数的循环,它不能像 while 循环那样用一个逻辑表达式来确定循环是否继续执行。repeat 循环的次数必须是一个常量、变量或信号。如果循环次数是变量信号,则循环次数是开始执行 repeat 循环时变量信号的值。即便执行期间,循环次数代表的变量信号值发生了变化,repeat 执行次数也不会改变。
和for循环的区别:
应用范围:for 循环可以用于生成硬件结构,而 repeat 循环主要用于仿真。
综合能力:for 循环可以综合成硬件逻辑,而 repeat 循环则不能。
循环控制:for 循环提供了更多的控制选项(初始化、条件、更新),而 repeat 循环仅指定循环次数。
automatic 函数
在 Verilog 中,一般函数的局部变量是静态的,即函数的每次调用,函数的局部变量都会使用同一个存储空间。若某个函数在两个不同的地方同时并发的调用,那么两个函数调用行为同时对同一块地址进行操作,会导致不确定的函数结果。
Verilog 用关键字 automatic 来对函数进行说明,此类函数在调用时是可以自动分配新的内存空间的,也可以理解为是可递归的。因此,automatic 函数中声明的局部变量不能通过层次命名进行访问,但是 automatic 函数本身可以通过层次名进行调用。
3段式状态机
在FPGA设计中,三段式状态机是一种常见的状态机实现方式,它将状态机的设计分解为三个主要部分:当前状态、下一个状态和输出逻辑。这种分离有助于提高设计的清晰度,并且可以使状态机更容易理解和维护。
假设我们要设计一个简单的状态机,该状态机有三个状态:IDLE、WORK 和 DONE。这个状态机将在接收到一个启动信号后从 IDLE 转换到 WORK,并在完成一定工作后转换到 DONE。
$random
$random 是一个内置的系统函数,用于生成伪随机数。这个函数可以用来生成一个随机的32位整数,通常用于仿真和测试环境中,以便于生成不可预测的数据模式,帮助验证设计的正确性
integer rand_val; rand_val = $random();
$random 使用一个内部的随机种子,这个种子默认是固定的,这意味着如果不改变种子,每次运行仿真时产生的随机数序列将是相同的。为了得到不同的随机数序列,可以在仿真开始时调用 $srandom 函数来设置随机种子: s r a n d o m ( srandom( srandom(time);
竞争
竞争是指在电路中,当两个或多个输入信号同时发生变化时,由于信号通过不同路径到达同一逻辑门的时间不同,导致输出结果的不确定性。这种不确定性可能导致输出产生瞬时的错误状态。
假设一个简单的组合逻辑电路,包含两个输入信号 A 和 B,以及一个与门(AND gate)和一个或门(OR gate):output = (A & B) | (!A & !B);
如果 A 和 B 同时从0变到1,由于信号传播延迟的不同,可能会导致输出在一段时间内表现出错误的状态。
冒险
冒险是竞争导致的一种特定现象,指的是在竞争条件下,电路输出可能会产生瞬时的错误脉冲或尖峰。这些瞬时错误通常被称为"冒险脉冲"。
静态冒险:当输入信号稳定不变时发生的冒险。
动态冒险:当输入信号发生变化时发生的冒险。
在FPGA设计中,使用现代EDA工具(如综合工具和形式验证工具)可以帮助识别潜在的竞争和冒险问题。此外,良好的设计实践,如避免长链的组合逻辑和使用同步复位信号,也可以减少这些问题的发生。
格雷码
格雷码(Gray code),又称为反射二进制码或循环二进制码,是一种二进制数的排列方式,其特点是任意两个连续的数值之间仅有一位二进制位不同。这种编码方式最初由Frank Gray在1953年提出,并因此得名。格雷码在数字通信和计算机科学中有许多应用,尤其是在FPGA(Field-Programmable Gate Array,现场可编程门阵列)设计中,因为它可以减少由于多位同时变化带来的错误。
1、减少毛刺:在数字系统中,当从一个数转换到另一个数时,如果多位同时变化,可能会引起电路的不稳定,产生毛刺信号。格雷码通过确保每次只有一位变化,可以降低这种风险。
2、提高可靠性:在计数器、编码器和其他数字系统中使用格雷码可以提高系统的可靠性。
3、简化逻辑设计:在某些情况下,使用格雷码可以简化逻辑电路的设计,因为每次只需要处理一位的变化。
二进制转格雷码
将二进制码转换为格雷码的方法很简单。格雷码的最高位直接复制二进制码的最高位,其余位是二进制码的当前位与其更高一位的异或(XOR)结果。
格雷码转二进制码
将格雷码转换回二进制码的过程稍微复杂一些,需要逐位计算。二进制码的最高位直接复制格雷码的最高位,其余位是当前格雷码位与之前生成的二进制码位的异或结果。
例如,将格雷码 1010 转换成二进制码:
最高位 1 直接复制。
第二位 0 是 1 XOR 0。
第三位 1 是 0 XOR 1。
第四位 1 是 1 XOR 1。
因此,1010 的二进制码为 1011。
多输入门
多输入门只有单个输出,有单个或多个输入端。Verilog 内置多输入门如下:
and(与门) nand(与非门) or(或门) nor(或非门) xor(异或门) xnor(同或门)
使用基本的逻辑门单元去实现一些简单的逻辑功能时,使用模块例化的方式即可。
门级单元第一个端口是输出,后面端口是输入,例化调用时需要注意。
门级单元实例调用的时候,也可以不指定实例的名字,这为代码编写提供了方便。
当输入端口超过 2 个时,只需将输入信号在端口列表中继续排列即可,Verilog 可自动识别。
多输出门
多输出门只有单个输入,有单个或多个输出端,又可称之为 buffer,起缓冲、延时作用。
和多输入门类似,可以使用模块例化的方式对多输出门进行调用。
门级单元第一个端口是输出,最后一个端口是输入。当输出端口超过 1 个时,需将输出信号在最后一个输入端口前排列。
例化时也可以不指定实例的名字。
三态门
Verilog 中还提供了 4 个带有控制端的 buffer 门单元,称为三态门。只有当控制信号有效时,数据才能正常传递,否则输出为高阻抗状态 Z。
例化时,三态门第一个端口为输出端,第二个端口为数据输入端,第三个端口为控制输入端。例化时信号排列顺序要一致。
三态门不支持输出端口超过 1 个,但例化时可以不指定实例的名字
其它专用术语(网上找的,具体用到再查)
-
系统级描述
定义:使用高级语言对电路模块的外部性能进行设计和描述。
用途:在设计初期阶段,用于定义系统的总体架构和功能。
-
算法级
定义:使用高级语言结构设计算法。
用途:确定算法的逻辑流程和数据处理方式。
-
RTL 级
定义:描述数据在寄存器之间流动以及如何处理这些数据。
用途:实现具体的数字逻辑功能,是 FPGA 设计中最常见的描述级别。
-
门级
定义:描述逻辑门以及逻辑门之间的连接。
用途:用于实现基本的逻辑功能,如 AND、OR、NOT 门等。
-
HDL (Hardware Description Language)
定义:用于描述硬件电路的语言。
用途:编写 FPGA 设计的源代码,常用的 HDL 包括 VHDL 和 Verilog。
-
LCA (Logic Cell Array)
定义:逻辑单元阵列,内部包括可配置逻辑模块 CLB、输出输入模块 IOB 和内部连线 Interconnect。
用途:构成 FPGA 的基本逻辑单元。
-
CLB (Configurable Logic Block)
定义:可配置逻辑块,是 FPGA 内部的基本逻辑单元之一。
用途:实现逻辑功能,如组合逻辑和时序逻辑。
-
IOB (Input Output Block)
定义:输入输出模块,用于连接 FPGA 内部逻辑与外部世界。
用途:提供信号的输入输出缓冲功能。
-
Interconnect
定义:内部连线,用于连接 FPGA 内部的 CLB 和 IOB。
用途:实现信号在 FPGA 内部的传递。
-
LUT (Look-Up Table)
定义:查找表,用于实现组合逻辑功能。
用途:在 FPGA 中实现基本的逻辑门功能。
-
DMA (Direct Memory Access)
定义:直接存储器访问。
用途:在 FPGA 中用于高效地在存储器和其他硬件资源之间传输数据。
-
FrameBuffer (帧缓冲)
定义:用于存储图像数据的数据结构。
用途:在视频处理和图形显示应用中存储像素数据。
-
DSP (Digital Signal Processor)
定义:数字信号处理器。
用途:在 FPGA 中实现数字信号处理功能。
-
PLL(Phase-Locked Loop,锁相环)
PLL 是一种用来同步输入信号和输出信号频率和相位的相位同步电路,也可用来实现时钟信号的倍频(产生输入时钟整数倍频率的时钟)。在 FPGA 芯片上,PLL 用来实现对主时钟的倍频和分频,并且 PLL的输出时钟之间保持同步。与基于延迟的 DLL 原理不同,PLL 采用 VCO(压控振荡器)来产生和输入时钟相似的时钟信号。
-
DLL(Delay-Locked Loop,延迟锁定环)
DLL 的基本功能和 PLL 的相同:可以实现零传输延迟;可以为分散逻辑门阵列)。
-
CPLD(Complex PLD,复杂可编程逻辑器件)
CPLD 是指将多个小规模 SPLD 作为基本逻辑块,再通过开关连接而成的中规模(大规模)PLD,因为单纯扩大AND-OR 阵列规模会导致资源浪费。CPLD逻辑部分的延迟时间和开关部分的延迟时间比较固定, 因此设计较为容易。
-
LVDS(Low Voltage Differential Signaling,低电压差分信号)
LVDS 是一种使用差分方式传输低电压、小振幅信号的接口技术。该数字传输标准可以达到数百 Mbit/s 信号传输速度。
-
SERDES(Serializer-Deserializer,串行器-解串器)
SERDES 通过用串行、并行相互转换模块,来实现使用高速串行接口连接并行接口的功能。最近的高速通信接口以串行为主流,因此不需要考虑并行通信中布线长度不一所导致的传输位间的时间偏移问题。
-
反熔丝(anti-fuse)
反熔丝在通常状态下绝缘,加以高电压时绝缘层会打开通孔熔通成为连接状态。由于它和合金熔丝的特性相反,因此被称为反熔丝。反熔丝形成的内部连接阻抗低,可用来实现高速电路。虽然反熔丝具有非易失性,但是编程写入的操作只能进行一次。
-
嵌入式阵列(embedded array)
嵌入式阵列的开发流程是在用户决定好所需的硬宏单元时就先行投放晶圆进行生产,硬宏单元之外的用户逻辑部分先部署门阵列。用户完成逻辑设计后,只要在金属层工序实施用户逻辑的布线即可完成生产。这样,就可以同时具有标准单元 ASIC 中硬宏单元的高性能,以及堪比门阵列的短开发周期这两方面的优势。
-
时钟树(clock tree)
大规模 LSI 中的布线延迟会导致各个信号到达时间不一致。特别是同步电路设计中电路的动作由时钟控制,这种信号传播上的时间差会带来不好的影响。因此需要时钟树这种时钟专属的布线和驱动电路来改善信号的偏差和传播速度。
-
门阵列(Gate Array,GA)
门阵列是一种除布线之外所有掩膜工序都提前完成,用户只需要进行片上门电路之间的金属布线工程就能完成生产的芯片开发方式。这种方式具有开发周期短的优势。门阵列分为门电路区域和布线区域固定的通道(channel)型,以及门电路遍布整个芯片的门海(sea-of-gate)型。
-
结构化ASIC(structured ASIC)
结构化 ASIC 是指为了缩短开发周期,在门阵列基础上加以 SRAM、时钟 PLL、输入 / 输出接口等通用功能模块,将需要定制开发的部分降低到最小限度的芯片开发方式。例如制造方预先在专用布线层设计好时钟电路等方法,可以有效减轻用户的设计成本。
-
标准单元ASIC(cell-based ASIC)
在基于标准单元库基础之上,提供更大规模电路模块(巨型单元、宏单元等)的 IC 开发方式。在使用标准单元实现的随机逻辑之上,提供 ROM、RAM、微处理器等巨型单元。系统 LSI 是在标准单元 ASIC的基础上多功能化和大规模化而来的产物。
-
软核处理器(soft-core processor)
软核处理器是可以通过逻辑综合来实现的微处理器核,在 FPGA 领域得到了广泛的应用。软核具有很多优势,例如可以在不同 FPGA 系列中使用,可以根据需要定制搭载必要数量的周边电路和 I/O,还可以根据需要自由装载多个处理器(多核化)等。
-
动态部分重配置(dynamic partial reconfiguration)
部分重配置是指在可重构设备上实现的电路中,只对其中一部分进行重新配置。动态部分重配置则是指在其他部分正常工作的情况下,动态地对某一部分进行重新配置。使用动态部分重配置功能可以卸载无须同时工作的电路,从而得到面积和功耗上的改进。
-
动态可重构处理器(Dynamically Reconfigurable Processor,DRP)
动态可重构处理器是可重构系统的一种,商品化的产品通常是将粗粒度的 PE(Processing Element,处理单元)和分散的内存模块按二次元阵列型放置,各个 PE 的指令和 PE 之间的连接可以动态地(在工作时)改变。
-
硬宏单元(hard macro)
硬宏单元是指 FPGA 内部嵌入的固定的硬件电路模块。虽然可以使用 FPGA 的基本门来实现乘法器这类电路,但消耗的资源非常多,开销会增大。而如果使用硬宏单元,就不会对应用的性能有过多的影响。
-
乘积项(product term)
所有逻辑表达式都可以变换为与项(AND)的逻辑或(OR),也就是积之和的形式。由 AND 阵列和 OR 阵列组成的 AND-OR 构造称为乘积项形式。乘积项是 SPLD 和 CPLD 中代表性的基本结构。
-
粒度(granularity)
这里的粒度指电路规模。通常"粒度"一词用来描述粉状物体颗粒的大小程度,比如颗粒的粗糙程度、细腻程度。目前主流 FPGA 中基本逻辑块的粒度位于门阵列(晶体管级别)和 CPLD(乘积项)之间,但通常也被称为细粒度(fine grain)。而粗粒度(coarse grain)通常指具有4~32 位 PE(Processing Element)阵列的动态可重构处理器。
-
逻辑综合(logic synthesis)
逻辑综合是指从 Verilog HDL 或 VHDL 等硬件描述语言编写的 RTL电路转换为 AND、OR、NOT 等门级网表(门间连线信息)的过程。
-
逻辑块(logic block)
逻辑块是指用来实现逻辑的电路块。CPLD 中的逻辑块是乘积项结构的宏单元。FPGA 中的逻辑块虽然叫法因厂商而异,但大致都是由LUT 和触发器组成的基本单元,再加上一些提高性能的附加电路构成的。
-
PE (Processing Element,处理单元)
PE 是 FPGA 中最基本的逻辑单元,它由 LUT、触发器、时钟、复位、输出、输入等组成。PE 的数量是 FPGA 的重要参数之一。
注意事项
- 目前选的这款内部不含flash,下载的时候如果要掉电保存,要下载到外部flash中,下载完成后注意启动配置,通过修改引脚指定启动顺序;
- SoC 封装后缀是"G"的器件,如 QN48G,内嵌 NOR FLASH;QN48G尺寸要比QN48P大;
- 字符串是由双引号包起来的字符队列。字符串不能多行书写,即字符串中不能包含回车符
- #100表示等待100个时间单位、宽度一般为64bit,通过调用系统函数 $time 获取当前仿真时间
- 整型变量使用integer来声明
- 实物变量使用real来声明,可用十进制或科学计数法来表示,声明不带范围,默认为0
- 参数用来表示常量,用关键字 parameter 声明,只能赋值一次,局部参数用 localparam 来声明
- 在编译阶段,
define 用于文本替换,类似于 C 语言中的 #define。一旦
define 指令被编译,其在整个编译过程中都会有效。在另一个文件中也可以直接使用。 - `timescale 的时间精度设置是会影响仿真时间的。时间精度越小,仿真时占用内存越多,实际使用的仿真时间就越长。所以如果没有必要,应尽量将时间精度设置的大一些
timescale 可以进一步传递,为保证当前的
timescale 在局部有效,避免timescale 的错误继承,可以将
resetall 加到模块最后- Verilog 中还支持使用电平作为敏感信号来控制时序,即后面语句的执行需要等待某个条件为真。Verilog 中使用关键字 wait 来表示这种电平敏感情况。例如: wait (start_enable); //等待start信号
- 当组合逻辑输入变量很多时,那么编写敏感列表会很繁琐。此时,更为简洁的写法是 @* 或 @(),表示对语句块中的所有输入变量的变化都是敏感的。例如:always @() begin
- 用户可以声明 event(事件)类型的变量,并触发该变量来识别该事件是否发生。命名事件用关键字 event 来声明,触发信号用 -> 表示。
- for循环中i=i+1不能写成i++的形式,i=i-1不能写成i--的形式
- 函数只能是逻辑运算,不能含有时间或者时序相关的逻辑操作,函数不能单独使用,只能放到赋值语句的右端
- 注意FPGA中任务的定义使用和C语言的大不一样,和C语言的函数概念差不多
- 注意传入、传出参数时的wire和reg信号的区别
- 注意在各种情况下,对阻塞和非阻塞延时的使用
- 巧用数字代表英文字母,例如 2 代表 to, 4 代表 for : reg clk4test, sig_uart2spi ;
- 建议一般功能模块的名称、端口、信号变量等全部使用小写,parameter 使用大写,一些电源、pad 等特殊端口使用大写
- 寄存器变量一般加后缀 _r, 延迟打拍的变量加后缀 _r1、_r2等
- 其他尾缀:_d 可以表示延迟后的信号,_t 可以表示暂时存储的信号,_n 可以表示低有效的信号,_s 可以表示 slave 信号,_m 可以表示 master 信号等
- 避免使用关键字对信号进行命名,例如 in, out, x, z 均不建议作为变量
- 文件名字保持与设计的 module 名字一致,文件内尽量只包含一个设计模块
- 为避免操作符优先级问题导致设计错误,建议多多使用圆括号
- 条件语句尽量使用 case 语句代替 if 语句。当同级别的条件判断语句过多时,使用 case 语句综合后的硬件结构,往往比 if 语句消耗更少的资源,拥有更好的时序
- 端口信号保证每行一个信号,逗号紧跟在端口声明之后
- 一行代码内容过长时,尽量换行编写,无需使用换行符
- 尽量使用 begin + end 的方式保证执行语句间的层叠关系。begin 与关键字同行,end 另起一行
- 尽量使用 tab 键和空格,保证语句按照层级结构对齐,变量、关键字、操作符之间也应该留有空隙,便于逻辑判断
- 模块例化时,端口信号尽量与连接信号隔开,并各自对齐。连接信号为向量时指明其位宽
- 变量声明时不要对变量进行赋初值操作。如果变量声明时设置初始值,仿真时变量会有期望的初值,但综合后电路的初始值是不确定的
- 赋初值操作应该在复位状态下完成,也建议寄存器变量都使用复位端,以保证系统上电或紊乱时,可以通过复位操作让系统恢复初始状态
- 建议设计时,时钟采用正边沿逻辑,复位采用负边沿逻辑
- 不到万不得已不要在 2 个 always 块中分别使用同一时钟的上升沿和下降沿逻辑,否则会引入相对复杂的时钟质量和时序约束的问题
- 禁止在一个 always 块中同时将时钟的双边沿作为触发条件
- 禁止在 2 个 always 块中为同一个变量赋值
- 一个 always 块中不要存在多个并行或不相关的条件语句,使用多个 always 分别描述
- 设计中尽量使用同步设计,必须要使用异步逻辑时,一定要对不同时钟域之间的信号进行同步处理,不能直接使用相关信号,否则会产生亚稳态电路
- 尽量不要直接将时钟信号与普通变量信号做逻辑操作,或对时钟信号进行电平信号的检测判断
- 不同条件下对时钟进行选择时,不能直接使用选择逻辑,否则会出现毛刺现象
- 一般情况下信号变量不要直接使用乘法 *、除法 /、求余数 % 等操作。这些操作符被综合后,结构和时序往往不易控制。应该使用相关优化后的 ip 模块或工艺库中的集成模块。但是 parameter 类型的常量就可以使用此类操作符,因为在编译之初编译器就会计算出常量运算的结果,不会消耗多余的硬件资源。
- 组合逻辑的条件语句中条件补充完整,组合逻辑的 always 语句中敏感信号要罗列完全,以避免不期望的 Latch 产生
- 例化时,连接输入端的信号可以是 reg 型或 wire 型变量,连接输出端的信号一定是 wire 型变量。但是端口信号声明时,输入信号必须是 wire 型变量,输出信号可以是 reg 型或 wire 型变量。
- 多个模块例化时,模块名字在前,例化名字在后,且例化名字不能相同