机器学习处理器(MLP)——针对AI优化的机器学习加速单元设计
本文档介绍了一系列基于Speedster®7t机器学习处理器(MLP)的参考设计。本设计展示了MLP的灵活配置能力,以及其与配套的块随机存取存储器(BRAM)和本地随机存取存储器(LRAM)结合,构建高性能、多模式矩阵与向量乘法系统的实现方式。
Speedster7t、 经典深度学习网络、二维卷积、机器人学习处理器、矩阵-向量乘法
引言
本文档介绍了一系列基于Speedster®7t机器学习处理器(MLP)的参考设计。本设计展示了MLP的灵活配置能力,以及其与配套的块随机存取存储器(BRAM)和本地随机存取存储器(LRAM)结合,构建高性能、多模式矩阵与向量乘法系统的实现方式。
设计方案
本设计套件包含四款设计方案:
-
二维卷积:对图像执行AlexNet网络的二维卷积运算。
-
拆分式MLP与共享BRAM:演示如何在两个MLP之间共享一个BRAM,使剩余BRAM可用于其他任务。
-
点积运算:演示如何通过两个向量相乘得到点积结果。
-
矩阵-向量乘法(MVM):演示如何实现矩阵与向量的乘法运算。
二维卷积
引言
MLP二维卷积设计(mlp_conv2d)是一款全功能设计,可同时对二维输入图像与多个卷积核执行卷积运算。该设计充分利用MLP和BRAM模块,单个MLP可在一个时钟周期内完成12次8位整数(int8)乘法运算。此外,MLP模块通过级联路径相互连接,实现图像数据在MLP列中的高效传输;BRAM模块也采用相同的级联方式,支持多个卷积核的并行处理。
设计通过片上网络(NoC)的访问点(NAP)从外部读取数据,并通过另一个NAP写入处理结果。NoC与Speedster7t器件中的GDDR6控制器相连,实现与外部存储器的通信。本设计展示了如何通过NAP大幅简化与外部存储设备间的数据读写操作。
设计中包含Octave脚本文件,可用于生成测试图像、卷积核示例,以及用于对比设计运算结果的校验文件。
注:本参考设计并非AlexNet网络处理的完整量产解决方案,而是作为高效实现二维卷积的设计指南,其设计原理可适配其他二维卷积的应用需求。
AlexNet网络适配
MLP_Conv2D设计虽初始配置为适配AlexNet网络的图像和卷积核尺寸,但二维卷积是通用运算过程,因此该设计可重新配置和调整,以实现多种不同的二维卷积算法。
二维卷积的基本原理是将卷积核(二维矩阵)在输入图像(本质为另一二维矩阵)上进行滑动运算。每次计算时,将卷积核中心与输入图像的一个像素对齐,对每个卷积核权重值与对应位置的图像像素值执行乘法运算,所有乘法结果的和即为该图像像素对应的卷积结果。随后将卷积核滑动至下一个像素,重复上述运算过程。
使用训练完成的卷积核时,二维卷积会生成输出特征图,突出输入图像的特定特征,如竖线、横线、不同角度的斜线和不同曲率的曲线等。这些特征可传入后续处理层(包括更多二维卷积层)进行特征融合,最终通过软件识别为具体目标。因此,二维卷积并非图像识别的完整解决方案,而是整个图像处理流程中的关键组成部分。
乘法运算密度
二维卷积的核心挑战在于需要执行大量乘法运算,而搭载专用乘法器阵列的MLP恰好能发挥其运算优势。在AlexNet配置下,单个卷积核的尺寸为11×11,包含121个权重值;且卷积实际为三维运算(输入图像为RGB三通道,卷积核也对应为三维结构),因此生成单个输出结果需要完成363次乘法和同等次数的加法运算。
AlexNet的输入图像尺寸为227×227,卷积步长设为4(即卷积核每次滑动4个像素),最终生成的输出特征图尺寸为54×54,共2916个结果。因此,处理单张图像需要完成363×2×2916=2117106次运算,即超过200万次乘累加运算。
MLP_Conv2D设计支持单次对单张图像并行处理60个卷积核,单次运算可完成超过1.2亿次乘累加操作。
性能指标
MLP_Conv2D设计的目标工作频率为600MHz。在此配置下,单个MLP处理一张227×227的RGB输入图像与11×11卷积核的卷积运算仅需170微秒,运算性能达124亿次/秒(GOPS)。
该设计采用60个MLP并行架构,可同时对60张输入图像执行卷积运算,性能可达803GOPS。当单颗Speedster7t器件中实例化40个MLP_Conv2D设计单元时,能充分发挥其架构的极致性能:每个设计单元通过独立NAP与GDDR6存储器传输数据,且因设计优化,图像数据仅从存储器读取一次并在单元内重复使用,支持40个单元全并行运行,综合性能达29684GOPS(即30万亿次/秒,TOPS),相当于每秒处理23.5万张图像。
资源占用
MLP_Conv2D设计基于MLP和BRAM模块的性能特性构建,利用其级联路径实现大数据流传输,同时通过NAP实现外部存储器与设计单元的直接数据路由。这些特性大幅降低了额外逻辑和布线资源的需求,具体资源占用如下表所示:
表1:单个MLP_Conv2D设计单元的资源占用
| Resource | Quantity | Percentage of the Device |
|---|---|---|
| MLP | 60 | 2.5% |
| BRAM | 62 | 2.5% |
| LUT | 1210 | < 1% |
| DFF | 4060 | < 1% |
表2:40个MLP_Conv2D设计单元的资源占用
| Resource | Quantity | Percentage of the Device |
|---|---|---|
| MLP | 2400 | 94% |
| BRAM | 2480 | 97% |
| LUT | 50K | 8% |
| DFF | 165K | 12% |
如上所示,即使是能提供32TOPS性能的40单元设计,器件中仍有大部分DFF和LUT逻辑资源可用于其他功能。
设计说明
配置参数
MLP_Conv2d设计的多项参数可在顶层文件…/src中配置,参数命名遵循TensorFlow二维卷积的规范,具体见下表:
表3:MLP_Conv2d设计配置参数
| Parameter | Default | Function |
|---|---|---|
| BATCH | 4 | Number of simultaneous kernels being convolved, which equates to the number of MLP blocks used. Range is 2-60. As the design uses the MLPs in fixed columns, the legal values are 2-12, 28, 44, 60. If the parameter is set to a value between the legal values, it will be rounded up to the next legal value. |
| IN_HEIGHT | 227 | Number of lines in the input image. |
| IN_WIDTH | 227 | Number of pixels in an input image line. |
| IN_CHANNELS | 3 | Number of layers of the input image; Default is 3 for RGB images. |
| FILTER_HEIGHT | 11 | Number of lines of each kernel. |
| FILTER_WIDTH | 11 | Number of weights in a kernel line. |
| OUT_CHANNELS | 1 | Number of output channels (not used). |
| INF_DATA_WIDTH | 144 | Data width of the input FIFO (2 × 72 bits). |
| BRAM_ADDR_WIDTH | 10 | Address width of MLP BRAM; each is 1K deep. |
卷积步长
当前设计中,卷积步长(卷积核两次运算间的滑动像素数)固定为4,后续版本将支持更多步长配置。
框图
MLP_Conv2D的架构框图如下:
图1 MLP_Conv2D架构框图
数据流程
单个MLP的数据流程
每个MLP均配有紧密耦合的BRAM,本设计中该BRAM用于存储卷积核,并多次向MLP输出卷积核数据。初始化阶段,通过输入NAP读取每个BRAM对应的卷积核数据,并写入相应BRAM;BRAM写端口位宽配置为72位,读端口为144位,实际仅使用96位(卷积核权重按4个权重×3通道×8位读取)。
初始图像数据通过NAP读入输入FIFO,该FIFO按行存储图像数据,虽为FIFO架构,但支持数据重复读取(即可多次读取行数据)。输入FIFO由两个72K容量的BRAM组成,总位宽144位,实际仅使用96位,每个数据字包含4个像素×3通道×8位。
初始化时,读取的图像初始行数为卷积核行数+垂直步长,即:
初始读取行数 = 卷积核高度 + 步长
当初始数据和卷积核均加载完成后,开始执行计算
从输入FIFO读取第一行图像数据,读取像素数与卷积核的水平尺寸一致,同时读取对应的卷积核权重值;MLP将96位数据流按12个int8值进行乘法运算,并对结果进行累加。
输入FIFO读取第二行图像数据,读取行首像素并与卷积核第二行的对应权重值相乘,重复此过程直至卷积核所有行均与输入图像左上角的对应像素完成乘法运算;此时MLP完成累加,输出该位置的16位二维卷积结果。
输入FIFO按步长参数(当前固定为4)在图像行上滑动,重复上述运算,直至生成该行所有卷积结果。
输入FIFO按步长向下滑动行数,重复运算以生成图像下一行的卷积结果;滑动过程中,FIFO中不再需要的初始行数据将被释放,同时与MLP计算并行加载图像的下一组步长行数据。
从外部存储器的带宽需求来看,图像和卷积核数据仅从存储器读取一次,后续在BRAM中重复使用,大幅降低了外部存储器的带宽负载。
多MLP并行的数据流程
MLP的核心优势之一是支持同一列中上下相邻的MLP/BRAM之间直接进行数据和结果的级联传输。MLP_Conv2D设计利用该级联路径,将MLP及其配套BRAM按列分组排布。
向BRAM加载卷积核时,通过级联路径将数据流水线式传输至每个BRAM,并通过BRAM模块的地址模式选择目标写入的BRAM。
计算阶段,输入图像数据沿MLP列向上级联传输,每个MLP比下方相邻的MLP晚一个时钟周期接收数据;同时,控制卷积核读取的BRAM读地址也沿BRAM列向上级联,同样延迟一个时钟周期。由此,每个MLP均比前一个MLP晚一个时钟周期接收相同的图像数据和卷积核读地址,而不同MLP的配套BRAM存储不同的卷积核数据,最终实现单张图像与多个卷积核的并行卷积运算,并行卷积的数量即为BATCH参数值。
结果输出
如前所述,每个MLP对卷积核与对应图像区域的每次卷积运算均输出16位结果。MLP按16个为一列排布,因此每列MLP可生成一个256位的数据字(包含列中所有MLP的运算结果),并将该数据字写入输出NAP。
此排布方式使卷积结果在存储器中按同一图像的通道层存储,与输入时RGB三通道存储在单个数据字的格式保持一致,支持将卷积结果并行传入激活层(激活函数可对256位结果执行16路并行运算);同时,256位结果通过输出NAP写回存储器后,可再次读入后续的二维卷积电路进行处理。
布局规划
MLP_Conv2D的设计布局与Speedster7t的架构相匹配:在Speedster7t架构中,每个NAP对应32个MLP,本设计优化为使用两个NAP(一个读、一个写),对应64个MLP。
输入和输出FIFO各需两个72K容量的BRAM,以构建256位宽的组合存储器,因此会占用64个MLP资源位中的4个用于数据输入输出。
设计布局采用与两个NAP关联的四列MLP,其中第一列和最后一列各使用14个MLP资源位,分别为输入和输出FIFO预留2个资源位,中间两列则使用全部16个可用的MLP资源位。布局中,底部带有输入FIFO存储器的第一列紧邻NAP排布,以优化时序性能。
下图为使用最大可用60个MLP处理模块的设计布局示例(含布线高亮):
图2 60-MLP平面图
设计构建
本设计支持两种构建方式:基于Makefile的脚本化流程和工具图形用户界面(GUI)流程。脚本化构建流程的详细说明见参考设计构建章节,建议用户根据自身的脚本化构建环境修改和适配该流程。
使用GUI流程构建时,/src/syn和/src/ace目录中分别提供了适用于Synplify Pro和ACE工具的GUI项目文件,用户需先通过Synplify Pro GUI完成设计综合,再通过ACE GUI执行布局和布线。
Makefile脚本化流程支持两种构建选项:
-
单单元构建:使用两个NAP和60个MLP,命名为mlp_conv2d_b60(批处理数60),为脚本化构建的默认选项,同时支持GUI构建流程。
-
全芯片构建:实例化40个b60设计单元,命名为mlp_conv2d_b60x40。该构建利用Speedster7t器件的片上网络(NoC)特性,每个设计单元通过NAP与存储器独立通信,因此增加实例化数量不会导致最高工作频率(FMAX)下降;全芯片构建将使用器件中全部80个NAP,以及94%的MLP和72K BRAM资源。
注:根据构建环境的不同,全芯片构建的耗时约4-8小时,建议硬件配置的最小内存为24GB。
可通过修改/build/makefile中的variant参数选择构建类型,全芯片构建(b60x40)的布局如下图所示。
图3 2400MLP平面图
仿真验证
仿真支持两种流程,可通过仿真Makefile中的FLOW变量定义:
-
独立仿真(STANDALONE):使用NAP的行为模型,该模型包含模拟NoC外接存储的行为存储器模型;输入NAP存储器由包含输入图像和卷积核的激励文件配置,输出NAP模型由预期结果文件配置。仿真执行时,从输入NAP读取数据并处理,将结果写入输出NAP,并实时与预期结果对比。
-
全芯片总线功能模型仿真(FULLCHIP_BFM):使用包含NoC、NAP和GDDR6子系统行为模型的ac7t1500器件模型;初始化相关GDDR6子系统,通过设计中实例化的NAP经NoC从GDDR6模型读取数据(用户逻辑中的NAP在测试平台中与ac7t1500模型中的NAP绑定),数据写入流程同理(用户逻辑NAP通过ac7t1500模型将数据传输至GDDR6子系统模型),测试平台实时对比数据以完成验证。
激励文件
激励文件和结果文件由.m脚本生成,可通过Octave或Matlab等主流数学软件处理,具体流程:
读取PNG格式的输入图像,转换为指定格式的int8数值。生成多个卷积核并格式化,与输入图像一同写入输入激励文件/src/oct/nap_in.txt。同时将每个卷积核与输入图像的卷积结果写入输出NAP文件/src/oct/nap_out.txt。将上述两个文件的副本放入/src/mem_init_files目录,供仿真调用。
注意:若修改输入激励文件,使用与参考设计不同尺寸的图像或卷积核,需相应修改MLP_Conv2D设计的配置参数。
存储器映射
生成输入激励文件的存储器映射必须与MLP_Conv2D设计中编码的存储器映射一致,参考设计的存储器映射详见输入激励存储器映射,具体如下:
表4:输入激励存储器映射
| Base Address | Content |
|---|---|
| 0x0000_0000 | Kernel 0 |
| 0x0001_0000 | Kernel 1 |
| 0x0002_0000 | Kernel 2 |
| 0x003b_0000 | Kernel 60 |
| 0x0040_0000 | Input image |
若用户需修改存储器映射,必须同时修改激励源文件和寄存器传输级(RTL)代码:激励文件由/oct/convolve_2d_debug.matrix.m编写,地址映射定义在该文件顶部;输入NAP的读取由/rtl/dataflow_control.sv控制,地址映射由该文件顶部的参数定义。
存储器格式
NAP向外部存储器输出的数据位宽为256位,卷积核和输入图像数据仅使用每个存储器数据字的96位,格式如下表:
表5:输入激励数据字格式
| - | [255:128] | [95:88] | [87:80] | [79:72] | [71:64] | [63:56] | [55:48] | [47:40] | [39:32] | [31:24] | [23:16] | [15:0] | [7:0] |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Pixel / Weight | reserved | 3 | - | - | 2 | - | - | 1 | - | - | 0 | - | - |
| Layer | - | 2 | 1 | 0 | 2 | 1 | 0 | 2 | 1 | 0 | 2 | 1 | 0 |
仿真运行
仿真从/sim目录执行,该目录中包含用于运行Mentor QuestaSim和Synopsys VCS仿真器的Unix Bash脚本。运行仿真前,需确保仿真器已添加至系统环境变量路径。
参考设计仿真的配置和运行详细说明见仿真参考设计。对于本参考设计,仿真器编译完成后,运行200微秒即可完成卷积核加载、图像处理和结果写入存储器;若仿真成功,仿真控制台将输出“TEST PASSED”提示。
拆分式MLP与共享BRAM堆叠设计
引言
在Speedster7t AC7t1500器件中,MLP和BRAM资源位相邻排布,二者间有直接连接以节省布线资源。该布局便于将MLP的输入数据存储在配套BRAM中,尤其适用于数据需要多次使用的场景;但如果每个MLP均独占其配套BRAM,将无剩余BRAM用于通用存储和缓冲。
拆分式MLP与共享BRAM堆叠(split_mlp_shared_bram_stack)设计提供了一种解决方案:构建MLP与配套BRAM的堆叠架构,让每个BRAM由两个MLP共享,该设计可释放器件中近一半的BRAM资源,用于其他功能。
概述
本参考设计将MLP配置为多个并行点积(即乘累加)引擎,充分利用每个MLP的运算能力(单个MLP含16路并行int8×int8乘法器)。BRAM和MLP按下图堆叠并连接(MLP数量可在2-64之间调整),右侧截图为ACE工具中的布局效果(黄点为额外逻辑,主要为寄存器)。
点积运算的形式为A×B,其中向量A来自底部的单个“A”BRAM,数据通过堆叠架构的级联路径传输;向量B来自由两个MLP共享的“B”BRAM,未使用的BRAM资源位可用于任何读写位宽≤72位的BRAM应用。以点积为基础运算,该设计可实现矩阵乘法、多层二维卷积等多种运算。
图4 拆分式 MLP 共享 BRAM 堆叠的高层框图
架构组织
每个MLP拆分为两个运算引擎,各含8路并行int8×int8乘法器和独立的累加器,每个引擎独立计算一个点积结果。为给8路并行乘法器提供数据,每个引擎每个时钟周期需64位的A输入和64位的B输入,这些输入均来自A、B BRAM。
BRAM的读端口位宽配置为128位,每次读取的数值拆分为两个64位数据字(高位为“h”、低位为“l”)。由此,从A BRAM连续读取可生成Ah和Al两个64位数据流,二者为独立向量,仅在存储地址上存在关联;同理,每个B BRAM生成Bh和Bl两个数据流。
设计由多个“1个B BRAM+2个MLP”的分组构成,每个MLP含E0和E1两个引擎,因此每个分组共4个运算引擎,数据流Ah、Al、Bh、Bl的分配如下表:
表6:数据流分配表
| - | Ah | Al | Output Result |
|---|---|---|---|
| Bl | M1E0 | M1E1 | result_1 |
| Bh | M0E0 | M0E1 | result_0 |
每个数据流由两个引擎使用,但各引擎计算不同的点积结果(例如M0E0计算若干时钟周期内Ah×Bh的和)。
点积运算完成后,结果存储在每个MLP内部的LRAM FIFO中;E0和E1引擎并行运算,且E0的结果在FIFO中优先于E1存储。结果位宽为48位,每个FIFO最多可存储32个结果。
存储器组织
拆分式MLP与共享BRAM堆叠设计为所有BRAM提供并行的写输入(数据和地址),BRAM可在引擎计算过程中随时写入数据。例如,设计人员可采用“乒乓缓冲”策略:一半BRAM存储当前计算数据,另一半写入下一次计算的待处理数据。
注意:用户需自行避免读写冲突。
读地址为共享模式:A BRAM有一个读地址i_bram_a_rdaddr,B BRAM有一个读地址i_bram_b_rdaddr;向量A的数据以脉动(流水线)方式传输至所有MLP,同时向量B的地址以相同方式传输至所有B BRAM,确保A、B数据同时到达每个MLP。
由于读写地址均由用户生成,实际的存储器组织方式可灵活定制,通过重复发送相同的读地址可实现数据的多次使用,该特性也支持矩阵乘法、二维卷积等多种运算。
存储器组织存在两项限制:
-
所有B BRAM接收相同的读地址序列,因此需在相同地址存储等效数据;
-
相互独立的“h”和“l”数据必须存储为单个128位数据字。
A BRAM的写端口位宽为64位,写地址位宽10位(对应1024个64位数据字),Al数据存储在偶地址,Ah数据存储在奇地址,读端口按128位宽同时读取Ah和Al;B BRAM的写端口位宽为128位,写地址位宽9位(对应512个128位数据字),[63:0]位为Bl数据,[127:64]位为Bh数据,读端口位宽128位。
输入时序控制
每个时钟周期,一个运算引擎对8组(A,B)数据执行SUM(A[i]×B[i])运算;若向量包含超过8个元素,则需多个时钟周期完成完整的点积运算。用户设计需生成两个向量的A、B读地址序列,以及三个控制信号:
-
i_first:点积运算第一个时钟周期置高,与第一个读地址同步,用于重置引擎的累加器;
-
i_last:点积运算最后一个时钟周期置高,与最后一个读地址同步,用于将累加结果存入LRAM FIFO;
每个向量都必须以 i_first 开头;即便该向量紧跟在前一个向量之后(此情况下,i_first 会紧随 i_last 之后),这一规则依然适用。
每个向量的运算必须以i_first置高开始,即使紧邻前一个向量的运算(即i_first紧随i_last置高)。i_pause信号适用于处理过程中无输入数据的场景(如数据需从外部存储器读取),由于点积运算由i_first和i_last界定,向量间无需置高i_pause。
i_first、i_pause、i_last控制信号的输入始终与对应的i_bram_a_rdaddr和i_bram_b_rdaddr对齐,设计中包含内部流水线,确保控制信号在正确的时间到达累加器。
向量A的数据沿堆叠架构向上传输时,每个MLP产生一个时钟周期的延迟,向量B的数据和控制信号也做同等延迟以匹配向量A,最终每个MLP的运算比下方相邻的MLP晚一个时钟周期执行。
图5 split_mlp_shared_bram_stack 设计的详细模块框图
结果输出
每个MLP均包含一个LRAM FIFO用于存储运算结果,FIFO中按E0、E1交替存储结果(以E0开头),结果位宽48位,单个MLP最多存储32个结果。
拆分式MLP与共享BRAM堆叠设计为所有结果FIFO提供并行数据输出,但仅有一个控制信号i_result_rden启动FIFO读取,该信号沿堆叠架构向上传输,MLP间有一个延迟阶段;除堆叠延迟外,FIFO自身还有一个时钟周期的延迟。为便于读取并行输出,每个结果输出端配有一个result_valid信号,在读取请求后数据可用时置高一个时钟周期。
由于仅有一个i_result_rden信号,因此也仅有一组FIFO状态信号(空、满、几乎空、几乎满),对应底部的FIFO;当i_result_rden信号传输至其他FIFO时,其状态与底部FIFO一致。
结果存储在FIFO中,无需在数据可用时立即读取;为实现最高性能,第二个输入向量的运算可在第一个输入向量的结果输出前启动。FIFO的读取时机需遵循一项重要限制:置高i_result_rden将自动视为置高i_pause,即当前运算被忽略。
注:该特性由底层实现导致,因FIFO和B BRAM共享一条总线。
这意味着若在点积运算过程中(i_first和i_last之间)置高i_result_rden,当前读地址和控制信号将被忽略,需在下一个时钟周期重新发送。建议仅在向量运算间隙(i_last之后、i_first之前)置高i_result_rden,以规避该限制;读取请求发出后,即使尚未从FIFO接收数据,运算也可立即继续。由于单个MLP并行计算两个结果,每次(i_first,i_last)序列的结果读取开销为两个时钟周期。
注:该限制仅适用于读请求信号i_result_rden。
配置参数
表7:拆分式MLP与共享BRAM堆叠设计参数
| Parameter | Supported Values | Default | Description |
|---|---|---|---|
| num_groups | 1…32 | 4 | Number of groups in the stack, where each group has 2 MLPs. |
| bram_a_wr_width | 64, 72 | 64 | Write width for the “A” BRAM (72 may be useful if the design is converted to block floating point). |
| bram_a_wraddr_width | 1…10 | 10 | Address width for the “A” BRAM. Use 10 to access all 1024 words. |
| bram_b_wr_width | 64, 72, 128, 144 | 128 | Write width for the “B” BRAM. Can be changed to 64, which would require twice as many writes (72 and 144 may be useful if the design is converted to block floating point). |
| bram_b_wraddr_width | 1…10 | 9 | Address width for the “B” BRAM. Use 9 to access all 512 words of 128 bits. |
| mlp_dout_width | 2…48 | 48 | Result width. Internal integer results are 48 bit; smaller values cause truncation. |
| result_afull_threshold | 0…15 | 1 | Almost full threshold. See the LRAM2K_FIFO documentation (write_width is 144). |
| result_aempty_threshold | 0…31 | 2 | Almost empty threshold. See the LRAM2K_FIFO documentation (read_width is 72). |
| bottom_mlp_location | MLP site name | “” | Specify an MLP site name to fix the placement of the bottom MLP. This parameter also determines the placement of the other MLPs and the BRAMs. |
端口定义
端口名以i_开头为输入端口,以o_开头为输出端口;部分端口(如i_bram_b_din)为向量数组,数组元素数与分组数一致;若端口(如i_bram_b_wren)为1位值的数组,在Verilog中声明为同维度的向量(更便于实现)。
表8:拆分式MLP与共享BRAM堆叠设计端口表
| Name | Vector Width | Array Size | Description |
|---|---|---|---|
| i_clk | 1 | - | Clock |
| i_bram_a_din | bram_a_wr_width | - | Write data for “A” BRAM |
| i_bram_a_wraddr | bram_a_wraddr_width | - | Write address for “A” BRAM |
| i_bram_a_wrmsel | 1 | - | Select for write “remap” mode; see BRAM72K_SDP documentation |
| i_bram_a_wren | 1 | - | Write enable for “A” BRAM |
| i_bram_a_we | bram_a_wr_width/8 | - | Byte enables for write to “A” BRAM |
| i_bram_b_din | bram_b_wr_width | num_groups | Write data for “B” BRAM, per group |
| i_bram_b_wraddr | bram_b_wraddr_width | num_groups | Write address for “B” BRAM, per group |
| i_bram_b_wrmsel | 1 | num_groups | Select for write “remap” mode; see BRAM72K_SDP documentation, per group |
| i_bram_b_wren | 1 | num_groups | Write enable for “B” BRAM, per group |
| i_bram_b_we | bram_b_wr_width/8 | num_groups | Byte enables for write to “B” BRAM, per group |
| i_bram_a_rdaddr | 9 | - | Read address for “A” BRAM (128-bit words) |
| i_bram_b_rdaddr | 9 | - | Read address for “B” BRAM (128-bit words), passed to each group |
| i_first | 1 | - | Set high to indicate first input for dot-product |
| i_pause | 1 | - | When high, read address and i_first/i_last are ignored |
| i_result_rden | 1 | - | Read one result from the FIFO; passed to each FIFO in pipelined fashion |
| i_result_rstn | 1 | - | Resets the FIFO pointers, discarding any stored values. At power-up, the FIFO is already in its reset state, but this signal can be used to interrupt operation later. To ensure flushing of pending operations, i_result_rstn should be asserted for 7 cycles. |
| o_result_empty | 1 | - | Indicates the FIFO is empty and cannot be read |
| o_result_full | 1 | - | Indicates the FIFO is full, and must be read before new results are written |
| o_result_almost_empty | 1 | - | High if the FIFO has ≤ result_aempty_threshold values |
| o_result_almost_full | 1 | - | High if the FIFO has ≤ result_afull_threshold empty slots |
| o_result_1 | mlp_dout_width | num_groups | Output of the FIFO of MLP1 of each group |
| o_result_1_valid | 1 | num_groups | High when o_result_1 is valid (per group), following i_result_rden |
| o_result_0 | mlp_dout_width | num_groups | Output of the FIFO of MLP0 of each group |
| o_result_0_valid | 1 | num_groups | High when o_result_0 is valid (per group), following i_result_rden |
示例设计
核心设计为split_mlp_shared_bram_stack,为适配ACE工具运行和简化仿真,在其外围添加了简易的封装层:所有输入输出均添加寄存器,便于ACE工具报告时序;为减少输入输出引脚数量,对并行输入输出进行了精简:
-
取消B BRAM的并行写输入,改为单个输入并通过索引(
i_bram_b_group)指示目标写入的BRAM; -
并行结果输出接入流水线,按单序列输出结果。
注:以上两种方式仅用于简化测试设计,不建议在实际设计中使用;尤其是结果串行化会导致结果收集的耗时超过运算耗时。设计应设置为“evaluation”流模式,让ACE工具自动分配所有输入输出引脚。
如前所述,存储器组织方式、读地址序列均由用户定制,即用户可控制设计实现的具体运算。在提供的测试平台中,将一个矩阵写入A BRAM,另一个矩阵分布式存储在多个B BRAM中,然后生成读地址序列计算两个矩阵的乘积,并验证运算结果的正确性。
为演示方便,测试平台在运算过程中读取结果;如《结果输出》章节所述,运算中读取将自动触发暂停状态,可能需要测试平台重复发送相同的读地址。实际应用中,建议在运算间隙读取结果。
点积运算
点积运算参考设计套件演示了如何执行向量乘法,其结果为两个向量对应元素相乘后的和(即点积),向量乘法公式如下:
图6 加速点积运算
和 S 由各向量元素相乘后再求和得到,因此:S = a1xb1 +a2xb2 + a3*b3 …
注:在点积参考设计中,i_a和i_b输入可互换,因最终结果为向量对应元素相乘的和。
设计配置
点积设计套件利用MLP72实现多种不同配置,展示了MLP72支持的数值类型和乘法器配置范围,各设计的详细说明见对应/src目录中的README.txt文件。
dot_product_N_8x8
描述
演示N路int8数值序列的点积运算,每个时钟周期对N路int8输入和N路int8输入执行乘法并求和,结果经累加后在输入两个时钟周期后输出;累加过程由i_first和i_last输入控制:i_first置高表示开始累加的第一组输入,同时将累加器置零;i_last置高表示结束累加的最后一组输入,同时将结果加入累加器,最终结果由o_valid信号置高指示有效。
配置参数
表9:dot_product_N_8x8配置
| Input Format | Output Format | Parallel Multiplications | Number of MLP72 |
|---|---|---|---|
| int8 | int48 | N | 1 |
端口定义
表10:dot_product_N_8x8端口表
| Port | Direction | Description |
|---|---|---|
| i_clk | Input | Clock input |
| i_a | Input | “a” input to multiplication. Array of N × int8 (N × 8 bits). |
| i_b | Input | “b” input to multiplication. Array of N × int8 (N × 8 bits). |
| i_first | Input | Indicates first group of inputs to sum and start accumulation. Sets internal accumulator to 0. |
| i_last | Input | Indicates last group of inputs to sum and accumulate. |
| o_sum | Output | 48b integer accumulated output. |
| o_valid | Output | Validates o_sum output. |
表注:i_first和i_last不可同时置高,但可在相邻时钟周期置高。
时序图

图7 dot_product_N_8x8时序图
Where:
dot_product_bfloat16_4mlp
描述
演示多组脑浮点16位(bfloat16)输入的点积运算(下文说明脑浮点与块浮点的区别)。设计由4个通过级联路径连接的MLP72组成,每个MLP72对两路并行的fp16e8输入×fp16e8输入的乘法结果求和,每个MLP72的结果沿MLP72列向上级联至上方的下一个模块,最终在最后一个MLP72中完成每时钟周期8路并行fp16e8乘法的求和。
最终结果为多个输入时钟周期的累加和,累加过程由i_first和i_last输入控制:i_first置高表示开始累加的第一组输入,累加器置零;i_last置高表示结束累加的最后一组输入,完成累加;最终结果在i_last置高6个时钟周期后输出,由o_valid信号指示有效。
脑浮点(bfloat16)与块浮点(blockfp)的区别
bfloat16(脑浮点)是TensorFlow框架推出的16位浮点格式,包含1位符号位、8位指数位、7位尾数位,精度为8位(7位尾数位+“隐藏位1”,所有尾数默认以1开头)。
Achronix同时支持块浮点(blockfp)运算方式,块浮点与bfloat16无任何关联,为避免混淆,Achronix在指代数值格式时使用fp16e8而非bfloat16。
配置参数
表11:dot_product_bfloat16_4mlp配置
| Input Format | Output Format | Parallel Multiplications | Number of MLP72 |
|---|---|---|---|
| fp16e8 | fp16e8 | 8 | 4 |
延迟特性
输出延迟从i_last置高的时钟周期开始计算,结果在i_last置高12个时钟周期后有效,由o_valid信号指示。
端口定义
表12:dot_product_bfloat16_4mlp端口表
| Port | Direction | Description |
|---|---|---|
| i_clk | Input | Clock input |
| i_a | Input | “a” input to multiplication. Array of 4 × 2 × fp16_e8 (128 bits). |
| i_b | Input | “b” input to multiplication. Array of 4 × 2 × fp16e8 (128 bits). |
i_first |
Input | Indicates first group of inputs to sum and start accumulation. Sets internal accumulator to 0. |
i_last |
Input | Indicates last group of inputs to sum and accumulate. |
| o_sum | Output | fp16e8 accumulated output. Output latency is 12 cycles from i_last being asserted |
| o_valid | Output | Validates o_sum output. |
时序图

图8 dot_product_bfloat16_4mlp时序图
Where:
dot_product_fp16_4mlp
描述
该设计展示了一系列 16 位浮点值的点积运算。该设计由四个 MLP72 组成,通过它们的级联路径连接。每个 MLP72 对两个并行乘法的结果进行求和,其中每个乘法运算均为输入 i_a 与输入 i_b(均为 fp16 浮点值)的乘积。每个 MLP72 的求和结果通过 MLP72 列向上级联至上方的下一个模块。每个时钟周期内,最后一个 MLP72 会计算出八个并行 fp16 乘法运算的总和。
最终结果为多个输入时钟周期的累加和,累加过程由i_first和i_last输入控制:i_first置高表示开始累加的第一组输入,累加器置零;i_last置高表示结束累加的最后一组输入,完成累加;最终结果在i_last置高6个时钟周期后输出,由o_valid信号指示有效。
注:fp16格式与IEEE-754“binary16”格式一致,通常称为“半精度浮点”,包含1位符号位、5位指数位、10位尾数位,精度为11位(10位尾数位+“隐藏位1”,所有尾数默认以1开头);在Achronix浮点库中,该格式也称为fp16e5。
配置参数
表13:dot_product_fp16_4mlp配置
| Input Format | Output Format | Parallel Multiplications | Number of MLP72 |
|---|---|---|---|
| fp16e5 | fp16e5 | 8 | 4 |
延迟特性
输出延迟从i_last置高的时钟周期开始计算,结果在i_last置高12个时钟周期后有效,由o_valid信号指示。
端口定义
表14:dot_product_fp16_4mlp端口表
| Port | Direction | Description |
|---|---|---|
| i_clk | Input | Clock input |
| i_a | Input | “a” input to multiplication. Array of 4 × 2 × fp16_e5 (128 bits). |
| i_b | Input | “b” input to multiplication. Array of 4 × 2 × fp16e5 (128 bits). |
i_first |
Input | Indicates first group of inputs to sum and start accumulation. Sets internal accumulator to 0. |
i_last |
Input | Indicates last group of inputs to sum and accumulate. |
| o_sum | Output | fp16e5 accumulated output. Output latency is 12 cycles from i_last being asserted |
| o_valid | Output | Validates o_sum output. |
时序图

图9 dot_product_fp16_4mlp时序图
Where:
设计构建
所有点积参考设计均使用统一的构建环境,目标器件为AC7t1500,构建环境的详细说明见参考设计构建章节。
每个点积设计均提供顶层芯片级文件/src/rtl/<design_name>_top.sv,该文件为信号输入输出添加了本地寄存器,形成输入输出与MLP之间的时序路径,因此用户可通过该构建确定点积设计集成到周边逻辑后的时序收敛性和性能。
可通过修改通用文件/build/Makefile中的VARIANT参数选择不同的构建设计。
由于点积参考设计的规模较小,构建耗时相对较短,所有设计的目标时序收敛频率为700MHz。
仿真验证
所有点积参考设计采用统一的仿真方法,仿真脚本结构一致,详细说明见仿真参考设计章节。
每个点积设计均将MLP的计算结果与该数学运算的SystemVerilog行为模型结果对比。 对于dot_product_N_8x8设计,验证模型位于/src/tb/test_sequence.vh,实现整数运算,将其结果与点积设计的输出对比;
对于浮点型点积设计,使用库文件/src/tb/acx_fp_sim.sv执行浮点运算(包括公共指数调整、舍入和截断),该库函数由对应的test_sequence.vh调用,生成浮点验证结果并与MLP的输出实时对比,同时打印有用的中间结果和调试信息,辅助用户调试或设计基于MLP的其他浮点运算。
所有点积设计的验证均为实时执行,每个计算结果将在仿真中显示“正确”或“错误”。
矩阵-向量乘法(MVM)
矩阵-向量乘法设计(mvm_8mlp_16int8_earlyout)实现256×256的int8矩阵与256×1的int8向量的乘法运算,使用8个MLP72和8个72K BRAM实例;256×256的矩阵存储在BRAM中,可多次使用;256×1的输入向量无需额外存储,直接存储在与MLP72紧密耦合的LRAM中。
配置概述
概述
设计由8个BRAM和8个MLP组成的堆叠架构构成,数据从堆叠底部输入,结果从顶部输出;同时使用MLP/BRAM的内部级联连接和BRAM与MLP间的直接连接,大幅减少了架构布线资源的使用,同时简化了时序设计,核心连接方式:
-
BRAM的写数据(权重矩阵)、写地址、读地址通过BRAM的级联路径分布式传输;
-
向量数据通过MLP的输入级联路径传输至LRAM(LRAM物理上集成在MLP内部);
-
BRAM的数据通过直接连接传输至对应的MLP;
-
MLP的输出级联路径用于收集和累加各阶段的运算结果。

图10 BRAM and MLP互联
MLP运算细节
每个MLP使用16路int8×int8乘法器,通过全整数加法树完成求和,单个MLP的运算延迟设为3个时钟周期。
MLP的A输入为相邻BRAM的输出(代表矩阵的一行),B输入为内部LRAM的输出(代表向量);向量和矩阵的每行均包含256个元素,拆分为16个块(每块16个元素)。每个时钟周期,MLP对一组向量块和矩阵行块执行乘法并求和(通过并行乘法器和加法树);要完成一个完整的向量×行点积运算,需对16组块的乘积结果求和。
本设计将该求和过程分布式在多个MLP中完成:向量块v[i]和矩阵行块r[i]的乘积结果沿MLP堆叠向上传输时,由8个MLP完成8组乘积的累加;由于需要累加16组乘积,顶部MLP的额外累加器用于将两组累加和再次相加,最终每两个时钟周期输出一个结果值。
以底部MLP为例,完成v0×r0和v8×r8两组乘积后,下一个时钟周期将再次计算v0×r0(此时r0为下一个矩阵行的块数据)。底部MLP的LRAM仅需存储向量的两个块v0和v8(共32个值),所有MLP均遵循此规则,每个MLP仅存储两个向量块;BRAM的组织方式与LRAM的向量块分布相匹配,确保矩阵行块与向量块对齐。
图11 矩阵-向量乘法模块框图
计算流程
在MLP7的第一个加法器输出端,首次计算得到的值为:
r 0 × v 0 + r 1 × v 1 + . . . + r 7 × v 7 r0×v0 + r1×v1 + ... + r7×v7 r0×v0+r1×v1+...+r7×v7
下一个时钟周期计算得到的值为:
r 8 × v 8 + r 9 × v 9 + . . . + r 15 v 15 r8×v8 + r9×v9 + ... + r15v15 r8×v8+r9×v9+...+r15v15
MLP7中的累加器将这两个值相加,最终每两个时钟周期输出一个完整的点积结果:
r × v = r 0 × v 0 + r 1 × v 1 + . . . + r 15 × v 15 r×v = r0×v0 + r1×v1 + ... + r15×v15 r×v=r0×v0+r1×v1+...+r15×v15
LRAM配置
LRAM从级联路径接收128位宽的输入,从架构接收fwdi_multa_h/l输入(LRAM0专属);每个LRAM在架构中均有独立的地址计数器,由于每个LRAM仅存储两个块,地址仅在0和1之间切换。LRAM的输出寄存器禁用(读操作为组合逻辑),直接由LRAM输出驱动MLP的第一级寄存器。
BRAM配置
BRAM配置为“深度写、宽度读”模式:wradd、wren、rdaddr均从架构输入至BRAM0,再通过前向级联路径传输至其他BRAM;读数据直接传输至对应的MLP。
矩阵按行优先顺序输入宏模块,内部通过计算写地址将数据分布式存储在多个BRAM中,与LRAM中的向量块分布匹配;利用深度存储模式(块地址)可轻松实现数据块的重排序。若需并行写入所有BRAM(可大幅提升速度),实时重排序将存在挑战,建议在外部存储器中提前完成。
接口说明
矩阵加载时序

图12 Loading the Matix时序图
矩阵数据输入由i_matrix_wren信号触发,所有数据按行优先顺序输入,每个时钟周期输入8个值,因此写入256×256的矩阵需要8192个时钟周期。i_matrix_wrpause信号置高时可暂时暂停写入(无数据输入时),此时i_matrix_wren信号被忽略。
注:i_matrix_wren信号需保持置高直至整个矩阵写入完成;若i_matrix_wren置低(=1’b0),i_matrix_wrpause将被忽略,该特性支持i_matrix_wrpause与其他模块共享(i_matrix_wren作为模块选择信号)。
矩阵-向量乘法执行时序

图13 Matrix-Vector输入时序图
向量需按16个值为一个块连续输入(共16个块),第一个块由i_first置高标记,最后一个块由i_last置高标记;若数据暂时不可用,可置高i_pause暂停写入,此时i_v信号被忽略。i_last置高后,矩阵-向量乘法将自动启动。
注:i_pause仅可在i_first和i_last之间置高(不可与i_first或i_last同时置高)。
结果输出时序

图14 Matrix-Vector输出时序图
共输出256个结果(s0~s255),协议与向量输入一致:第一个结果输出时o_first置高,最后一个结果输出时o_last置高,中间o_pause置低时o_sum有效。下一个输入向量(i_first置高)可在o_last置高后启动。
性能指标
该矩阵包含 256 × 256 = 64k 个 int8(8 位整型)数值。当配置为 64 位位宽时,每个 BRAM(块随机存取存储器)的深度为 8k,因此该矩阵恰好能填满 8 个 BRAM。BRAM 的写入速率为每时钟周期 64 位,因此写入整个矩阵需要64k/8 = 8192 个时钟周期。此外,该设计可轻松修改为每次写入 128 位数据,从而将总写入时间缩短一半。本文假定 BRAM 中存储的数据会被多次使用;若该假设不成立,则可改为并行写入 BRAM,使写入时间缩短至原来的 1/8,这种方案可能更合理。
该向量包含 256 个数值,写入速率为每时钟周期 16 个数值,因此写入需耗时 256/16 = 16 个时钟周期。每两个时钟周期生成一个计算结果,因此生成包含 256 个数值的结果向量共需 512 个时钟周期。
图15 Matrix-Vector整体时序图
Theoretical Performance of MLP
单个MLP每时钟周期完成16次乘法+16次加法运算,8个MLP在538个时钟周期内的总运算量为:
32 × 8 × 538 = 137728 次运算 32 × 8 × 538 = 137728 \text{次运算} 32×8×538=137728次运算
Mathematically
从数学运算本质来看,矩阵的一行与向量的点积包含256次乘法和255次加法,因此256行矩阵的总运算量为:
256 × ( 256 + 255 ) = 130816 次运算 256 × (256+255)=130816 \text{次运算} 256×(256+255)=130816次运算
Operational Efficiency
运算效率 = 130816 / 137728 = 95 % \text{运算效率}=130816/137728=95\% 运算效率=130816/137728=95%
有效运算速率 = 130816 / 538 = 243 次运算/时钟周期 \text{有效运算速率}=130816 / 538=243 \text{次运算/时钟周期} 有效运算速率=130816/538=243次运算/时钟周期
@750 MHz = 243 × 750 = 182 effective rate in giga operations per second (GOPS) for the mvm design
Speedster7t AC7t1500器件搭载2560个MLP,若全部用于该MVM设计实例化,整体性能可达:
182 × 2560 / 8 = 58 TOPS 182 × 2560 / 8=58 \text{ TOPS} 182×2560/8=58 TOPS
注:只需对cycle_count的限制条件做少量修改,该电路即可处理1/4尺寸的矩阵(128×128),且耗时也缩短至1/4。其他尺寸的矩阵也可适配本设计,但效率会有所下降——虽能因计算结果减少节省时间,但因矩阵块无法均匀分配至各MLP,或矩阵行无法均匀拆分,会导致MLP利用率降低。此类场景下,采用不同BRAM/MLP数量的相似配置方案效果更佳。
内部控制信号
以下时序图展示了向量数据读写的内部控制信号时序,其中cycle_count寄存器用于确定o_first和o_last的置高时机,以及运算完成的时间节点。
图16 Matrix-Vector内部写入控制信号时序图
图17 Matrix-Vector内部读取控制信号时序图
使用说明
参考设计安装说明
下载方式
本设计可从Achronix自助FTP站点(https://secure.achronix.com)下载,存放路径为/public/Achronix/Reference_Designs/Speedster7t。
打包格式
设计以ZIP压缩包形式提供,命名格式为:
<design_name>_<design_version>_<date_of_packaging>.zip
压缩包包含所有源代码、设计构建脚本、仿真脚本文件,部分设计还提供基于GUI的项目文件;压缩包根目录包含发布说明,记录设计的版本更新历史。
支持的操作系统
Linux系统
设计脚本和构建流程基于Linux系统原生开发,已在CentOS 7和Ubuntu 16.04LTS系统中完成测试验证;流程采用Makefile实现,与Linux终端类型无关。
Windows系统
若需在Windows 10系统中运行脚本化仿真或实现流程,用户需安装以下工具之一:
-
基于Windows的Linux环境(如Cygwin,官网:www.cygwin.com),需包含Tcl解释器和make可执行文件;
-
适用于Windows的Tcl解释器和make可执行文件(提供免费和授权版本,种类繁多)。
若无法安装上述工具,仍可通过以下方式运行部分流程:
-
实现流程:提供适用于Synplify和ACE的GUI项目文件,可直接通过工具GUI完成构建;
-
仿真流程:提供Tcl脚本,可在QuestaSim的Tcl控制台中执行,实现Windows系统下的仿真(详细说明见仿真章节)。
注:为保证脚本流程正常运行,ACE需安装在路径无空格的目录中(示例:C:\achronix\8.3\Achronix_CAD_Environment);同时环境变量ACE_INSTALL_DIR需使用/作为路径分隔符,而非\,示例:
ACE_INSTALL_DIR = C:/achronix/8.3/Achronix_CAD_Environment/Achronix
工具版本要求
所有设计均通过以下工具版本测试,为最低版本要求:
表15:工具最低版本要求
| Software | Version |
|---|---|
| ACE | 8.3 |
| Device Simulation Model | 8.2.1 |
| Synplify Pro | Q-2020.03X |
| Mentor Questa | 10.7c-1 |
| Synopsys VCS | O-2018.09-SP1-1 |
环境变量配置
ACE_INSTALL_DIR
为支持项目的可移植性,设计通过ACE_INSTALL_DIR环境变量定位ACE安装目录(ace/ace.exe的安装路径);该变量同时用于综合和仿真流程,以正确加载ACE库文件。
注:为保证所有脚本流程正常运行,ACE 必须安装在路径名称不含空格的目录中。以下是合规路径的示例:
-
Windows:C:
\achronix\8.3\Achronix_CAD_Environment -
Linux:
/opt/achronix/ace/8.3
此外,在 Windows 系统下安装时,环境变量 ACE_INSTALL_DIR 必须使用 “/” 作为路径分隔符,而非 “”,示例如下:
ACE_INSTALL_DIR = C:/achronix/8.3/Achronix_CAD_Environment/Achronix
目录结构
设计采用清晰的目录结构,实现源文件与生成文件的分离,便于导航和维护;用户可根据自身习惯修改目录结构,但若修改,需同步调整对应的Makefile和构建脚本。为保证可移植性,目录均采用相对路径,通过环境变量指定根目录。
表16:设计目录结构说明
| Directory/File | Description |
|---|---|
| <design_name> | Root directory. Contains release notes. |
| /build | Synthesis and place-and-route building directory |
| /doc | Documentation and user guide |
| /scripts | Scripts used for building and simulation |
| /sim | Simulation area |
| /sim/vcs | Synopsys VCS simulation files |
| /sim/questa | Mentor QuestaSim simulation files |
| /src | Source code |
| /src/ace | ACE GUI project |
| /src/acxip | ACE .acxip configuration files |
| /src/constraints | Placement and timing constraint files |
| /src/include | RTL include files |
| /src/ioring | ACE generated ioring files |
| /src/rtl | RTL source files |
| /src/syn | Synplify Pro GUI project |
| /src/tb | RTL testbench files |
| filelist.tcl | Filelist used for building and simulation |
语言支持
参考设计支持Verilog、SystemVerilog、VHDL三种RTL语言,均可用于设计构建和独立仿真;若使用全芯片BFM仿真流程,要求顶层测试平台为Verilog/SystemVerilog,但被测设计(DUT)可采用VHDL编写。
约束文件
设计提供完整的约束文件集,存放于/src/constraints目录,演示了各类约束和指令的应用方式,具体文件说明如下:
表17:约束文件详细说明
| File Name | Usage |
|---|---|
| ace_constraints.sdc | Timing constraints used by ACE. More than one SDC file can be included in an ACE project. |
| ace_options.sdc | Control ACE settings, such as flow mode, speed grade, reporting of unconstrained paths. |
| ace_placements.pdc | Fix locations of elements within the ACE fabric, and creation of placement regions. 注:架构与I/O环之间的引脚布局由I/O环设计工具自动生成,存放于ioring PDC文件中 |
| synplify_constraints.fdc | Synplify FPGA design constraints. Set attributes such as compile points, or default memory styles. |
| synplify_constraints.sdc | Synplify timing constraints. Clock and timing constraints. Should match those set in ace_constraints.sdc. |
| synplify_options.tcl | Control Synplify settings, such as top module. Create synthesis specific parameters, generics and defines. |
I/O环约束文件
除上述约束文件外,I/O环会生成专属约束文件,用于架构核心与包含接口子系统的I/O环之间的连接;此类文件可由ACE从.acxip文件自动生成,为简化构建流程,设计为需要配置I/O环接口的项目提供了预生成文件,存放于/src/ioring目录,具体说明如下:
表18:I/O环约束文件详细说明
| File Name | Usage |
|---|---|
| <design_name>_ioring.sdc | I/O timing constraints for direct connection interfaces, between the fabric and the I/O ring. |
| <design_name>_ioring.pdc | Placement of the fabric I/O pins, to assign them to the direct connection interfaces in the I/O ring. |
| <design_name>_ioring_util.xml | Used by ACE to generate a combined utilization report, combining the fabric and I/O ring resources. |
器件仿真模型(DSM)
多数设计需要一个名为**器件仿真模型(DSM)**的仿真叠加层,该包整合了片上网络(NoC)的完整RTL代码,以及环绕NoC和FPGA架构的接口子系统总线功能模型(BFM)。通过将NoC的真实RTL与硬核接口的模型结合,该仿真环境可在保证NoC接口周期精确、硬核接口响应接近真实的前提下,为用户提供快速、高响应性的设计开发环境,支持设计的快速迭代与调试。
模型描述
DSM提供NoC的完整RTL代码和周边接口子系统的BFM模型,所有模块封装为与器件对应的SystemVerilog模块(如ac7t1500),用户需在顶层测试平台中实例化一个该模块。
此外,DSM提供绑定宏,用于将用户设计中的元件与器件内部的对应元件绑定。例如,若设计中实例化了NoC访问点(NAP),需通过ACX_BIND_NAP_SLAVE、ACX_BIND_NAP_MASTER、ACX_BIND_NAP_HORIZONTAL或ACX_BIND_NAP_VERTICAL宏(根据设计需求选择),将该NAP实例与NoC中对应位置的NAP绑定。
同理,设计的端口需与接口子系统的直接连接接口(DCI)绑定:器件中的每个DCI均与一个SystemVerilog接口相连,用户可在顶层测试平台中直接访问该接口,并在SystemVerilog接口与设计端口之间完成信号分配。
版本控制
DSM采用版本控制,同一主版本中可能新增功能,或弃用/替换旧功能;版本信息同时体现在包名(ACE_<major>.<minor>.<patch>_IO_BFM_sim_<update>.zip/tgz)和包根目录的readme文件中。
为保证使用兼容的I/O环仿真包版本,设计测试平台中需包含版本兼容性验证任务,实例化方式如下:
// 示例:DSM实例为ac7t1500
initial begin
// 确保使用的DSM版本不低于8.3.1
ac7t1500.require_version(8, 3, 1, 0);
end
require_version()任务参数
该任务包含四个参数,顺序如下:
-
主版本号(Major Version):与发布版本的主版本号一致;
-
次版本号(Minor Version):与发布版本的次版本号一致;
-
补丁版本号(Patch):与发布版本的补丁版本号一致(可选,无则设为0);
-
更新号(Update):与发布版本的更新号一致(可选,无则设为0)。
若补丁版本号(patch)或更新号(update)未指定,则应将其设为 0;例如,对于 8.3 正式版,参数应设为 8,3,0,0。
注:参数值可表示为数字(0-9)、字符串(“0”-“9”)或字母(“a/A”/“b/B”,分别代表alpha/beta测试版);版本优先级规则为数字版本高于字母版本,例如8.3.alpha(8,3,“a”,0)早于正式版8.3(8,3,0,0)。
示例设计
下图展示了用户测试平台的典型结构(同时实例化DSM和被测设计),包含从设备仿真模型的NAP绑定宏,以及两个GDDR6子系统的DCI;其他类型的NAP或DCI(如DDR)的绑定方式,可参考绑定宏章节和直接连接接口章节的表格。
图18 示例仿真结构
在上述示例中,包含两个 NAP(网络附着点),分别为 my_nap1 和 my_nap2;此外还有两个直连接口(direct-connect interface),即 my_dc0_1 和 my_dc0_2。在顶层测试平台(testbench)中,通过 ACX_BIND_NAP_SLAVE 宏定义将设计中的 NAP 与器件内置的 NAP 建立绑定关系。该宏支持传入 NAP 在 NoC(片上网络)中的坐标信息,从而使仿真环境与 NAP 在芯片上的物理布局保持一致。
DCI(直连接口)是用户设计中的端口;这些端口随后会被映射到器件直连 SystemVerilog 接口内对应的信号上。
用于例化上述模块的 Verilog 代码如下所示。本示例基于 ac7t1500 器件编写。
// 实例化Speedster7t1500器件
ac7t1500 ac7t1500(
.FCU_CONFIG_USER_MODE (chip_ready ) // 连接芯片就绪端口
);
// 注:ac7t1500的所有端口均已定义,可根据需求直接连接
// 设置消息的详细程度(调用内置set_verbosity()任务)
initial begin
ac7t1500.set_verbosity(3);
end
// 绑定NAP:将my_nap1绑定至位置(4,5),my_nap2绑定至位置(2,2)
`ACX_BIND_NAP_AXI_SLAVE(dut.my_nap1,4,5);
`ACX_BIND_NAP_AXI_SLAVE(dut.my_nap2,2,2);
// 连接直接连接(DC)接口
// 1. 创建与DC接口连接的信号
logic my_dc0_1_clk, my_dc0_1_awvalid, my_dc0_1_awready;
logic [ADDR_WIDTH-1:0] my_dc0_1_awaddr;
logic my_dc0_2_clk, my_dc0_2_awvalid, my_dc0_2_awready;
logic [ADDR_WIDTH-1:0] my_dc0_2_awaddr;
// ... 其他信号定义
// 2. 将信号连接至ac7t1500器件的gddr6_xx_dc0接口(输入至器件)
assign ac7t1500.gddr6_xx_dc0.awvalid = my_dc0_1_awvalid;
assign ac7t1500.gddr6_xx_dc0.awaddr = my_dc0_1_awaddr;
// 从器件输出
assign my_dc0_1_awready = ac7t1500.gddr6_xx_dc0.awready;
// 3. 将信号连接至ac7t1500器件的gddr6_yy_dc0接口(输入至器件)
assign ac7t1500.gddr6_yy_dc0.awvalid = my_dc0_2_awvalid;
assign ac7t1500.gddr6_yy_dc0.awaddr = my_dc0_2_awaddr;
// 从器件输出
assign my_dc0_2_awready = ac7t1500.gddr6_yy_dc0.awready;
// ... 其他信号分配
// 4. 时钟连接(必须操作)
assign my_dc0_1_clk = ac7t1500.gddr6_xx_dc0.clk;
assign my_dc0_2_clk = ac7t1500.gddr6_yy_dc0.clk;
注:使用绑定宏时,用户需指定目标NAP的列/行坐标;为保证仿真与硅片实现的一致性,需在ACE布局文件(.pdc)中添加匹配的布局约束,示例:
// 仿真中
`ACX_BIND_NAP_AXI_SLAVE(dut.my_nap1,4,5);
// 布局布线中
set_placement -fixed {i:my_nap} {s:x_core.NOC[4][5].logic.noc.nap_s}
set_verbosity()任务
除指定仿真包版本和实例化器件外,用户可通过set_verbosity()任务控制器件仿真模型的输出日志详细程度,调用示例见上述代码,日志级别定义如下:
表19:日志详细程度级别
| Verbosity Level | Description |
|---|---|
| 0 | Print no messages |
| 1 | Print messages from master and slave interfaces only |
| 2 | Print messages from level 1 and from each NoC data transfer |
| 3 | Print messages from level 2 and NoC performance statistics |
芯片状态输出
仿真启动后,器件的运行逻辑与硅片一致:初始化阶段处于复位状态(对应硬件中加载比特流的配置阶段),初始化完成后,器件将置高FCU_CONFIG_USER_MODE信号,指示进入用户模式,设计开始正常运行。
建议顶层测试平台监控该信号,仅在信号置高后向器件输入激励(上述示例中通过chip_ready信号实现)。
绑定宏
DSM提供以下绑定宏,用于器件内部元件的绑定:
表20:绑定宏说明
| Macro | Arguments | Description |
|---|---|---|
| ACX_BIND_NAP_HORIZONTAL | user_nap_instance, noc_column, noc_row | To bind a horizontal streaming NAP, instance ACX_NAP_HORIZONTAL. |
| ACX_BIND_NAP_VERTICAL | user_nap_instance, noc_column, noc_row | To bind a vertical streaming NAP, instance ACX_NAP_VERTICAL. |
| ACX_BIND_NAP_AXI_MASTER | user_nap_instance, noc_column, noc_row | To bind an AXI master NAP, instance ACX_NAP_AXI_MASTER. |
| ACX_BIND_NAP_AXI_SLAVE | user_nap_instance, noc_column, noc_row | To bind an AXI slave NAP, instance ACX_NAP_AXI_SLAVE. |
直接连接接口(DCI)
DSM支持以下直接连接接口,用于设计端口与器件接口子系统的连接:
表21:直接连接接口说明
| Subsystem | Interface Name | Physical Location | GDDR6 Channel | Interface Type | Address Width | Data Width |
|---|---|---|---|---|---|---|
| GDDR6 | gddr6_1_dc0 | West | 1/0 | t_ACX_AXI4 | 512 | 33 |
| GDDR6 | gddr6_1_dc1 | West | 1/1 | t_ACX_AXI4 | 512 | 33 |
| GDDR6 | gddr6_2_dc0 | West | 2/0 | t_ACX_AXI4 | 512 | 33 |
| GDDR6 | gddr6_2_dc1 | West | 2/1 | t_ACX_AXI4 | 512 | 33 |
| GDDR6 | gddr6_5_dc0 | East | 1/0 | t_ACX_AXI4 | 512 | 33 |
| GDDR6 | gddr6_5_dc1 | East | 1/1 | t_ACX_AXI4 | 512 | 33 |
| GDDR6 | gddr6_6_dc0 | East | 2/0 | t_ACX_AXI4 | 512 | 33 |
| GDDR6 | gddr6_6_dc1 | East | 2/1 | t_ACX_AXI4 | 512 | 33 |
| DDR | ddr4_dc0 | South | - | t_ACX_AXI4 | 512 | 40 |
注:并非所有器件都支持上述全部接口,具体请参考对应器件的数据手册。
时钟频率配置
除接口绑定外,用户可通过set_clock_period函数控制接口生成的时钟频率;为保证设计完整性,仿真中设置的时钟频率需与设计目标工作频率一致。
设计实现时,时钟频率在ACE IO Designer工具中配置;仿真中通过set_clock_period函数配置,示例如下(将GDDR6东部1号控制器配置为1GHz工作频率,适配16Gbps传输,DC接口为控制器频率的1/2,即500MHz):
// 定义GDDR6控制器时钟周期为1000ps(对应1GHz)
localparam GDDR6_CONTROLLER_CLOCK_PERIOD = 1000;
// 配置GDDR6 E1的NoC接口为1GHz
ac7t1500.clocks.set_clock_period("gddr6_5_noc0_clk", GDDR6_CONTROLLER_CLOCK_PERIOD);
// 配置GDDR6 E1的DC接口为500MHz(时钟周期为NoC接口的2倍)
ac7t1500.clocks.set_clock_period("gddr6_5_dc0_clk", GDDR6_CONTROLLER_CLOCK_PERIOD*2);
注:set_clock_period函数属于ac7t1500模型,该模型的默认时间单位为1ps,因此无论调用模块的时间单位如何,指定的时钟周期均以皮秒为单位。
以下是可用的时钟频率接口:
表22:时钟频率接口
| Subsystem | Interface Name | Physical Location | GDDR6 Channel |
|---|---|---|---|
| GDDR6 | gddr6_0_noc0_clk | West 0 NoC | 0 |
| GDDR6 | gddr6_0_noc1_clk | West 0 NoC | 1 |
| GDDR6 | gddr6_1_noc0_clk | West 1 NoC | 0 |
| GDDR6 | gddr6_1_noc1_clk | West 1 NoC | 1 |
| GDDR6 | gddr6_2_noc0_clk | West 2 NoC | 0 |
| GDDR6 | gddr6_2_noc1_clk | West 2 NoC | 1 |
| GDDR6 | gddr6_3_noc0_clk | West 3 NoC | 0 |
| GDDR6 | gddr6_3_noc1_clk | West 3 NoC | 1 |
| GDDR6 | gddr6_4_noc0_clk | East 0 NoC | 0 |
| GDDR6 | gddr6_4_noc1_clk | East 0NoC | 1 |
| GDDR6 | gddr6_5_noc0_clk | East 1 NoC | 0 |
| GDDR6 | gddr6_5_noc1_clk | East1 NoC | 1 |
| GDDR6 | gddr6_6_noc0_clk | East 2 NoC | 0 |
| GDDR6 | gddr6_6_noc1_clk | East 2 NoC | 1 |
| GDDR6 | gddr6_7_noc0_clk | East 3 NoC | 0 |
| GDDR6 | gddr6_7_noc1_clk | East 3 NoC | 1 |
| GDDR6 | gddr6_1_dc0_clk | West 1 DCI | 0 |
| GDDR6 | gddr6_1_dc1_clk | West 1 DCI | 0 |
| GDDR6 | gddr6_2_dc0_clk | West 2 DCI | 0 |
| GDDR6 | gddr6_2_dc1_clk | West 2 DCI | 1 |
| GDDR6 | gddr6_5_dc0_clk | East 1 DCI | 0 |
| GDDR6 | gddr6_5_dc1_clk | East 1 DCI | 1 |
| GDDR6 | gddr6_6_dc0_clk | East 2 DCI | 0 |
| GDDR6 | gddr6_6_dc0_clk | East 2 DCI | 1 |
| DDR | ddr4_noc0_clk | South NoC | - |
| DDR | ddr4_dc0_clk | South DCI | - |
| PCIe | pciex16_clk | Gen5 PCIe ×16 | - |
| PCIe | pciex16_dc_clk | Gen5 PCIe ×16 DCI | - |
| PCIe | pciex8_clk | Gen5 PCIe ×8 | - |
| Configuration | cfg_clk | System wide configuration clock | - |
子系统配置
多个接口子系统需要在上电时完成配置。在实际硬件器件中,该配置由比特流对相关配置寄存器进行预编程来实现;而在仿真环境中,可通过相关任务读取配置文件,并将配置应用到对应的接口子系统中。配置应用的示例如下方代码片段所示。
// 配置GDDR6子系统(fork-join实现并行配置,节省仿真时间)
initial begin
fork
ac7t1500.fcu.configure( "ethernet_cfg.txt", "ethernet0" );
ac7t1500.fcu.configure( "ethernet_cfg.txt", "ethernet1" );
join
end
启动流程
在 fcu.configure() 任务处理配置过程中(包括等待轮询操作返回有效值的阶段),芯片状态输出信号不会被置位。该行为与实际硬件器件的表现完全一致:器件仅会在配置完成后,才进入用户模式。
仿真测试平台可按上述方式执行配置流程,一旦芯片状态输出信号被置位,测试平台即可确认器件已完成正确配置,随后便可施加所需的测试激励。
fcu.configure()任务参数
该任务包含两个参数,格式为:
fcu.configure ( <configuration filename>, <interface subsystem name> );
支持的接口子系统名称如下:
表23:配置子系统名称
| Subsystem | Interface Subsystem Name[^1] | Physical Location |
|---|---|---|
| GDDR6 | gddr6_0 ~ gddr6_7 | West 0~3, East 0~3 |
| DDR | ddr4 | South |
| Ethernet | ethernet0 | North |
| Ethernet | ethernet1 | North |
| GPIO North | gpio_n | North |
| GPIO South | gpio_s | South |
| PCIe ×8 | pcie_0 | North |
| PCIe ×16 | pcie_1 | North |
| All subsystems | full[^2] | - |
表注:1. 子系统名称不区分大小写;2. 使用full时,配置文件中需使用42位完整地址;选择单个子系统时,仅需28位地址(详见下文配置文件格式)。
配置文件格式
配置文件采用以下格式编写,支持写、读、读验证三种操作:
# ------------------------------------------
# Config file
# Supports both # and // comments
# ------------------------------------------
# A comment line
// Another comment line
# Format is <cmd> <addr> <data>
# Commands are
"w" - write
"r" - read
"v" - read and verify
# Address is either 28-bit, (7 hex characters), or 42-bit, (11 hex characters).
# 28-bits supports the configuration memory space of an single interface subsystem# 42-bits supports the full configuration memory space
# Data is 32-bit, (8 hex characters).
# For reads, put 0x0 for the data
# For verify put the expected data value
# Examples
# Writes
w 00005c0 76543210
w 0000014 00004064
# Reads
r 00005c0 00000000
r 0000014 00000000
# Verify
v 00005c0 76543210
v 0000014 00004064
地址位宽规则
-
操作单个子系统时,仅使用地址的低28位,高14位由子系统名称自动推导;
-
操作全配置空间(子系统名称设为
full)时,需使用42位完整地址,且地址的[41:34]位必须设为8’h20(与NoC全局存储器映射+控制状态寄存器(CSR)存储区对齐),该模式下单个配置文件可配置多个接口子系统(详细说明见《Speedster7t片上网络用户指南》UG089)。
并行配置
fcu.configure()为SystemVerilog自动任务,支持重入和并行运行,因此可通过fork-join结构实现多个接口子系统的并行配置,参考设计的测试平台中提供了相关示例。
SystemVerilog接口定义
DSM定义了以下 SystemVerilog接口,用于DCI分配。
**注:**下述接口仅在仿真环境中可用。对于需要进行综合的代码,用户需自行定义专属的 SystemVerilog 接口,或使用参考设计中预先定义的一个接口。:
interface t_ACX_AXI4
#(DATA_WIDTH = 0,
ADDR_WIDTH = 0,
LEN_WIDTH = 0);
// 时钟参考
logic clk;
// AXI写地址通道
logic awvalid, awready;
logic [ADDR_WIDTH -1:0] awaddr;
logic [LEN_WIDTH -1:0] awlen;
logic [7:0] awid;
logic [3:0] awqos, awsize, awregion;
logic [1:0] awburst, awprot;
logic awlock;
logic [3:0] awcache;
// AXI写数据通道
logic wvalid, wready, wlast;
logic [DATA_WIDTH -1:0] wdata;
logic [(DATA_WIDTH/8) -1:0] wstrb;
// AXI写响应通道
logic bvalid, bready;
logic [1:0] bresp;
logic [7:0] bid;
// AXI读地址通道
logic arvalid, arready;
logic [ADDR_WIDTH -1:0] araddr;
logic [LEN_WIDTH -1:0] arlen;
logic [7:0] arid;
logic [3:0] arqos, arsize, arregion;
logic [1:0] arburst, arprot;
logic arlock;
logic [3:0] arcache;
// AXI读数据通道
logic rvalid, rready, rlast;
logic [DATA_WIDTH -1:0] rdata;
logic [1:0] rresp;
logic [7:0] rid;
// 全局复位
logic aresetn;
// 主模式模端口(输出至从机)
modport master (
input awready, bresp, bvalid, bid, wready, arready, rdata, rlast, rresp, rvalid, rid,
output awaddr, awlen, awid, awqos, awburst, awlock, awsize, awvalid, awregion,
bready, wdata, wlast, rready, wstrb, wvalid,
araddr, arlen, arid, arqos, arburst, arlock, arsize, arvalid, arregion
);
// 从模式模端口(输入至主机)
modport slave (
output awready, bresp, bvalid, bid, wready, arready, rdata, rlast, rresp, rvalid, rid,
input awaddr, awlen, awid, awqos, awburst, awlock, awsize, awvalid, awregion,
bready, wdata, wlast, rready, wstrb, wvalid,
araddr, arlen, arid, arqos, arburst, arlock, arsize, arvalid, arregion
);
endinterface : t_ACX_AXI4
安装
每个器件对应一个 DSM(器件仿真模型)包,Linux 和 Windows 系统均提供适配版本。其中,Linux 版本的包命名格式为<device>IO_BFM_Sim<version>.tgz,Windows 版本则为<device>IO_BFM_Sim<version>.zip。这些包可从 Achronix 自助 FTP 站点secure.achronix.com获取,具体存放路径为 / Achronix/ACE/Speedster7t 文件夹。由于各器件包相互独立,用户可根据需求仅下载目标器件对应的包,也可下载所有器件包。
任一器件包仅需安装一次 — 所有基于该器件开发的设计均可共用此包。
ACE集成安装
升级现有安装
若ACE中已安装旧版本DSM,建议先删除旧版本(路径:<ACE_INSTALL_DIR/system/data/yuma-alpha-rev0/sim),再安装新版本,以保证完整性。
首次安装
推荐将安装包内容合并至当前ACE安装目录:安装包包含根目录/system,将该目录下的所有文件合并至ACE安装目录的/system文件夹即可。
警告:仿真包包含ACE基础安装中没有的文件,不会覆盖现有文件;但如果已下载旧版本仿真包,安装时需选择覆盖,以保证使用最新的仿真文件。
独立安装
在某些情况下,用户可能无法修改已安装的 ACE 环境。此时可单独安装该器件仿真包,并结合此仿真包中的文件与ACE 原有仿真文件共同完成仿真操作。
若需以独立模式安装,只需将该压缩包解压至合适的目录即可。
注: 所有参考设计均默认配置为将该仿真包集成至 ACE 环境内使用。若选择独立安装的方式,则用户需在参考设计的 Makefile 文件中修改必要的环境变量。
环境变量补充
DSM的安装位置由两个环境变量共同控制,仿真前必须提前设置:
ACE_INSTALL_DIR
指向ace/ace.exe可执行文件的安装目录,用于综合和仿真流程定位器件库文件;
ACX_DEVICE_INSTALL_DIR
指向DSM包中器件文件的基础目录(如ac7t1500器件为yuma-alpha-rev0),设置规则:
-
ACE集成模式:
ACX_DEVICE_INSTALL_DIR = $ACE_INSTALL_DIR/system/data/yuma-alpha-rev0 -
独立安装模式:
ACX_DEVICE_INSTALL_DIR = <location of standalone package>/system/data/yuma-alpha-rev0
参考设计仿真
支持的仿真器
设计提供统一的仿真环境,为Mentor QuestaSim和Synopsys VCS仿真器编写了专用脚本。
仿真文件位置
所有设计的根目录下均包含/sim目录,该目录下分/vcs和/questa子目录,分别存放对应仿真器的脚本文件。
仿真流程
设计支持多种仿真流程选项,在仿真速度和精度之间做了不同权衡,并非所有设计都支持全部流程,具体可配置的流程见对应的Makefile,核心流程如下:
独立仿真(STANDALONE)
-
设计中的NAP使用独立行为模型,绑定至本地存储器模型,模拟存储器行为;
-
优点:仿真速度最快;
-
缺点:周期精度最低,NAP仅与自身的存储器模型交互,不支持多个NAP访问公共存储器;
-
启用方式:在仿真Makefile中设置
FLOW = STANDALONE。
全芯片BFM仿真(FULLCHIP_BFM)
该模式采用全芯片模型,搭配周期精准的 NoC(片上网络)。NoC 周边所有硬化接口均配置了总线功能模型(BFM),这些 BFM 带有典型延迟参数,使得该模式能够实现
接近周期精准的仿真效果。此模式无需接口子系统执行初始化和校准流程,相比全周期精准仿真,迭代耗时更短。
全芯片 BFM 仿真需预先下载并安装 IO Ring 仿真包。若要在官方提供的参考设计中启用该模式,需将仿真 Makefile 文件中的FLOW变量设置为FULLCHIP_BFM。
全芯片RTL仿真(FULLCHIP_RTL)
该模式采用子系统完整的 RTL(寄存器传输级)代码,并在必要时结合所需外部器件的周期精准模型(如存储器)共同运行。此配置下的仿真为全周期精准仿真,能够完全复现芯片最终量产版本的运行行为。对于这类仿真中的大多数场景,需通过官方提供的配置文件对相关子系统进行配置。由于此类仿真调用了子系统的完整 RTL 代码,其运行速度相比等效的 BFM(总线功能模型)仿真更慢,但能提供完全精准的时序结果。
注: 若需获取 GDDR/DDR 或 PCIe 子系统的加密 RTL(寄存器传输级)代码,需额外获取一个授权版仿真包。请联系 Achronix 技术支持团队,办理该包的授权事宜并获取访问权限。
若要在官方提供的参考设计中启用该模式,需将仿真 Makefile 文件中的 FLOW 变量设置为 FULLCHIP_RTL。
构建选项
每个仿真器目录下均包含Makefile,用户可通过编辑该文件配置仿真参数,核心配置变量如下:
-
FLOW:仿真流程选择,可选
STANDALONE/FULLCHIP_BFM/FULLCHIP_RTL; -
TOP_LEVEL_MODULE:顶层模块名,参考设计已预设,若用户将设计移植至自定义测试平台,需更新该变量;
-
ACX_DEVICE_INSTALL_DIR:指向ACE中目标器件文件的目录(示例:
$ACE_INSTALL_DIR/system/data/yuma-alpha-rev0),详细说明见I/O环仿真安装指南。
仿真前提条件
运行任何仿真前,需确保以下配置完成:
-
已设置ACE_INSTALL_DIR环境变量,指向ACE可执行文件的安装目录;
-
已将仿真器的路径添加至系统环境变量(VCS还需设置VCS_HOME环境变量)。
自动文件列表生成
仿真文件列表由../../src/filelist.tcl自动生成,生成脚本为../../scripts/create_sim_project.tcl,脚本通过模板文件(../scripts/sim_template.f或../../scripts/sim_template_bfm.f)定义通用仿真选项。生成脚本由仿真器的Makefile调用,最终生成的sim_filelist.f文件融合了模板文件的配置和../../src/filelist.tcl中的文件列表。
仿真核心文件
每个/sim/vendor目录下包含以下核心脚本/文件:
-
makefile:支持多种仿真流程的Makefile,默认目标为编译并运行仿真;
-
system_files_bfm.f:仅全芯片BFM流程使用,包含BFM流程的系统文件列表,可添加用户自定义宏;
-
system_files_rtl.f:仅全芯片RTL流程使用,包含RTL流程的系统文件列表,以及将仿真模块从BFM切换为全RTL的宏定义(格式为<子系统名>_FULL,如GDDR6_2_FULL),可添加用户自定义宏;
VCS专属文件:
-
fullchip_bfm_vcs_waiver.cfg:BFM流程的告警豁免文件,屏蔽无影响的告警;
-
session.sim_output_pluson.vpd.tcl:DVE波形查看器的会话文件;
QuestaSim专属文件:
-
wave.do:波形配置文件; -
qsim_<design_name>.do:非Makefile的GUI仿真脚本,跨平台兼容。
RTL仿真定义
编译并运行全芯片RTL仿真时,需为仿真编译启用SystemVerilog宏定义:当Makefile中FLOW = FULLCHIP_RTL时,编译命令行将自动包含system_files_rtl.f文件。
将仿真模块从BFM切换为全RTL的宏定义需在system_files_rtl.f中启用,示例(将GDDR6_1控制器切换为全RTL,其余保持BFM):
# Define GDDR Data Rate
+define+GDDR6_DATA_RATE_16 # <----- For GDDR6 RTL simulation the user must enable one of the data rates.
//+define+GDDR6_DATA_RATE_14
//+define+GDDR6_DATA_RATE_12
# Turn on GDDR RTL
# Enable the desired GDDR memory controllers below
# Any undefined controllers will use their BFM model
//+define+ACX_GDDR6_0_FULL
+define+ACX_GDDR6_1_FULL # <--- User enables this define
//+define+ACX_GDDR6_2_FULL
//+define+ACX_GDDR6_3_FULL
//+define+ACX_GDDR6_4_FULL
//+define+ACX_GDDR6_5_FULL
//+define+ACX_GDDR6_6_FULL
//+define+ACX_GDDR6_7_FULL
<-------- User does not need to change any options below here ---->
# ACE libraries must be defined first as they are referenced
# by the fullchip files that follow
+incdir+$ACE_INSTALL_DIR/libraries/
$ACE_INSTALL_DIR/libraries/device_models/7t_simmodels.v
# Fullchip include filelist
# This must be placed before the user filelist as it defines
# the binding macros and utilities used by the user testbench.
$ACX_DEVICE_INSTALL_DIR/sim/ac7t1500_include_bfm.v
用于启用各模块使用全 RTL 而非 BFM 模型的可用宏定义列表,如下表所示:
表24: Simulation RTL defines
| Module | Define |
|---|---|
| GDDR6 Controller 0 | ACX_GDDR6_0_FULL |
| GDDR6 Controller 1 | ACX_GDDR6_1_FULL |
| GDDR6 Controller 2 | ACX_GDDR6_2_FULL |
| GDDR6 Controller 3 | ACX_GDDR6_3_FULL |
| GDDR6 Controller 4 | ACX_GDDR6_4_FULL |
| GDDR6 Controller 5 | ACX_GDDR6_5_FULL |
| GDDR6 Controller 6 | ACX_GDDR6_6_FULL |
| GDDR6 Controller 7 | ACX_GDDR6_7_FULL |
| DDR4 Controller | ACX_DDR4_FULL |
| Ethernet Subsystems (both) | ACX_ETHERNET_FULL |
| PCIe Controller 0 (×8) | ACX_PCIE_0_FULL |
| PCIe Controller 1 (×16) | ACX_PCIE_1_FULL |
| GPIO North Block | ACX_GPIO_N_FULL |
| GPIO South Block | ACX_GPIO_S_FULL |
| All SerDes Lanes | ACX_SERDES_FULL |
**表注:**上述各接口子系统的位置与名称,可在 ACE 的 IP 配置透视图中查看,方法是选择 I/O 布局图。
警告:启用模块的全RTL仿真将显著增加仿真时间,若同时启用多个模块,仿真耗时会大幅延长。
仿真运行命令
所有仿真器流程的/sim/vendor目录下均包含Makefile,支持以下构建命令:
VCS仿真器
code
$ make : Default flow. Compile with no debug options, run in batch mode writing the
output to a VPD file.
$ make run : Same as "make".
$ make debug : Build with debug options (increased visibility of lower level variables).
Run in batch mode writing to a VPD file.
$ make open_dve : Open the DVE waveform viewer and load the VPD file and viewing session file.$ make clean : Delete all generated and temporary files.
QuestaSim仿真器
code
$ make : Default flow. Compile with no debug options, run in batch mode writing the
output to a WLF file.
$ make run : Default flow. Same as "make".
$ make debug : Build with debug options (increased visibility of lower level variables).
Open GUI with wave.do and allow user to run interactively.
$ make open_wave : Open the GUI waveform viewer. Load the generated WLF file and viewing wave.do file.
$ make clean : Delete all generated and temporary files.
QuestaSim非Makefile流程(适配Windows)
为支持无Makefile的环境(如Windows),QuestaSim提供基于.do脚本的非Makefile流程,步骤如下:
-
进入
sim/questa目录; -
启动QuestaSim GUI(命令:
vsim);在GUI的Tcl控制台执行脚本
do qsim_<design_name>.do
**注:**QuestaSim 脚本会调用ACE_INSTALL_DIR环境变量。为确保该脚本(或其他任意脚本)流程正常运行,ACE 需安装在路径名无空格的目录下,例如:C:\achronix\8.2.1\Achronix_CAD_Environment。此外,环境变量ACE_INSTALL_DIR必须使用/作为路径分隔符,而非"",示例如下:ACE_INSTALL_DIR = C:/achronix/8.2.1/Achronix_CAD_Environment/Achronix
**注:**该.do脚本默认配置为全芯片总线功能模型(FULLCHIP_BFM)流程。如需适配独立仿真(STANDALONE)流程,可通过启用脚本中已加注注释的对应选项完成修改。
结果验证
所有设计均采用自校验测试平台,将RTL生成的结果与验证输出对比,验证输出的来源包括:数学软件计算结果、软件模型结果、RTL行为模型结果;各设计的具体验证来源见对应设计的详细说明。
参考设计构建
设计采用统一的构建环境,通过Makefile和脚本实现Synplify Pro和ACE的批处理运行,支持批处理流程和GUI流程两种方式。
构建前提条件
运行任何构建前,需确保以下配置完成:
-
已设置ACE_INSTALL_DIR环境变量,指向ACE可执行文件的安装目录;
-
已将ACE添加至系统环境变量(最简单方式:将$ACE_INSTALL_DIR添加至PATH);
-
已将Synplify Pro添加至系统环境变量。
批处理流程
设计根目录下的/build目录包含核心Makefile,需在该目录下运行(若移动或在外部调用,需修改路径)。
运行Makefile(默认选项)将完成以下操作:
-
生成
/build/results/syn目录:Synplify Pro批处理综合设计,生成网表文件/results/syn/rev_1/<design_name>.vm;若综合失败,可查看/results/syn/rev_1/<design_name>.srr文件获取失败详情;综合项目的配置由/src/constraints/synplify_options.tcl控制。 -
生成
/build/results/ace目录:综合完成后,ACE以evaluation模式运行(无需指定I/O引脚);ACE项目的配置由/src/constraints/ace_impl_options.tcl控制。
Makefile构建选项
code
$ make : Default flow. Synthesize and build a single implementation with ACE
$ make run : Same as "make"
$ make syn_only : Synthesis only
$ make pnr_only : Run ACE place and route only. This requires synthesis to have previously been run.
$ make run_mp : Run multiprocess. Synthesize and build multiple implementations with ACE
multiprocess.
$ make clean : Delete all generated and temporary files
约束文件补充
除前文所述的约束文件外,构建流程还会使用其他约束文件,所有文件均存放于/src/constraints,核心补充如下:
-
ace_timing.sdc、<design_name>.sdc:综合和ACE均使用的时序约束文件;
-
<design_name>.fdc:Synplify Pro的FPGA约束文件,设置非时序相关的指令和属性(如编译点);
-
<design_name>.pdc:ACE的布局约束文件。
具体流程使用的文件列表,可参考对应的/src/filelist_xx.tcl文件。
GUI流程
设计为ACE和Synplify Pro提供预生成的GUI项目文件,分别存放于/src/ace和/src/syn目录,用户可直接打开文件,以交互式方式编辑或运行构建。
注:使用GUI流程时,所有生成的文件将存放于GUI项目文件的目录下:
-
Synplify Pro:修订目录(如rev_1)生成在
/src/syn/rev_1; -
ACE:实现目录生成在
/src/ace/impl_<name>;若使用I/O Designer生成新的约束文件,默认存放于/src/ace/ioring_design。
当通过批处理流程执行构建操作时,该流程会将相关工程文件全部输出至/build/results目录下。此目录中包含为 ACE 和 Synplify Pro 生成的工程文件,用户可在图形界面(GUI)模式下打开这两类工程文件,以交互方式重新运行构建流程或编辑构建内容。
所发布的内容经achronix官方允许
参考设计完整工程在个人下载中心,可根据个人需求前往下载,如有问题可私信博主
更多推荐


所有评论(0)