建模和仿真如何将算法开发与 SoC 设计结合在一起
作者 Mark Corless and Eric Cigan, MathWorks
在本文中,您将了解建模如何帮助一个小型的算法和嵌入式软件工程师团队设计电机控制算法并在可编程片上系统 (SoC) 上将其实现。我们就是该团队的嵌入式工程师。我们将展示建模如何帮助我们划分设计、平衡功能行为和实现所需资源,以及在实验室中进行测试。
Xilinx® Zynq® SoCs 和 Intel® SoC FPGA 等可编程 SoC 将可编程逻辑和微处理器核整合在同一芯片上,为设计团队提供了在广泛应用中部署算法的新平台,这些应用包括嵌入式视觉、通信以及电机和电力电子的控制。这些设计团队通常有两类工程师:算法工程师和嵌入式工程师,前者负责基于数学或基于规则的算法的概念开发和阐述,后者负责细化算法并在嵌入式设备的软件或硬件中实现它们。
算法工程师通常在开发过程的前期使用建模以确保算法在功能上适合应用。而建模的好处对于嵌入式工程师来说就不是那么的明显。但是,如果这些团队没有紧密合作,可能导致错误检测滞后,造成项目延迟;过度的资源使用;或者由于设计和测试迭代不充分而影响功能。
我们来看看建模是否可以创建出效率更高、更具有协作性的设计流程,让算法工程师和嵌入式工程师都能从中受益。我们的初衷是专注于可以使用仿真对其进行探查的建模算法组件。我们将使用仿真来帮助我们作出分区决策,使用仿真和代码生成来平衡功能性行为和实现所需资源,并自动集成和部署生成的代码和手写代码,以更高效地利用实验室时间。
建议的工作流
我们建议使用同时包含由模型生成的代码和手写代码的工作流。(在此文章中,我们将称手写编码的设计部分为参考设计。)我们将从算法开发人员提供的模型开始,并通过添加实现细节的方式迭代细化模型。每个迭代我们都会仿真系统行为以确保算法模型功能性的正确,通过代码生成实现算法以获得行为类似于模型的代码,然后将其自动与我们的参考设计集成,以确保达到硬件实现的过程的可重复性(图 1)。
选择硬件平台
在本案例研究中,我们决定使用磁场定向控制 (FOC) 算法为永磁同步电机设计速度控制器,然后将其部署到 Zynq-7000 All Programmable SoC Intelligent Drives Kit II(图 2)。我们选择电机控制是因为它经常需要算法工程和嵌入式工程师一起合作。我们选择 Zynq Intelligent Drives Kit II 是因为它容易获得并能提供我们所需的 I/O 支持。
Zynq Intelligent Drives Kit II 是一个开发平台,工程师可使用该平台测试在 Zynq Z-7020 SoC 设备上运行的电机控制算法。该套件基于 ZedBoard 开发板,其中包括一个亚德诺半导体 的 FMC 电机控制模块和一个配有一个 1250 周/转编码器的 24V 无刷直流电机。由于想在一系列工况下测试电机控制算法,我们使用了带有可选测功机系统的 Zynq Intelligent Drives Kit II。
分区算法组件
选择硬件平台后,我们审核了算法工程师提供的初始系统仿真模型,并确定了部署到 SoC 所需的额外算法组件。该模型包括一个基于数据表参数的电机控制器算法。此算法由一个外部速度控制回路组成,该回路使用 FOC 调节一个内部电流控制回路。
尽管此模型反映了控制器的核心数学,但它没有考虑外设(如 ADC、编码器和 PWM)或其他工作模式(禁用、开环和编码器标定)所需算法组件的影响。我们与算法工程师一起确定了要对哪些算法组件建模,并决定了是在 ARM 上实现这些组件,还是在 SoC 的可编程逻辑上实现(图 3)。
我们细化了初始系统模型以包含新算法组件(图 4)。为了启用系统仿真,我们创建了现有与电机模型交互的外设的集总参数模型。例如,我们计划在部署的设计中重用现有的编码器外设 HDL 代码。编码器外设以 50 MHz 读取数字脉冲流,并将其转换为控制器算法以 25 kHz 读取的计数信号。如果我们直接对该脉冲流建模,我们将在系统模型中引入 50 MHz 的动态特性并显著增加仿真时间。但实际上,我们创建了编码器的集总参数模型,它会将电机模型的理想转子位置转换为算法组件适用的编码器计数信号。这种级别的建模保真度让我们能够仿真测试编码器标定组件所需的启动条件,并在保持合理的仿真时间的同时引入位置量化效应来测试速度控制组件(图 5)。
如果算法组件仅需几 kHz 或更低的速率,我们选择了在 ARM 上将其实现。之所以设置了几 kHz 速率的约束是因为我们计划在 ARM 上运行 Linux® 操作系统。需要更快速率的算法组件将在 FPGA 上实现。
我们希望尽可能在 ARM 上实现算法组件,因为我们发现设计迭代在 ARM 上比在 FPGA 上更快。以 ARM 内核为目标设计算法更容易,因为它支持原生浮点数学运算。大多数 FPGA 执行浮点数学的效率不高,因此以可编程逻辑为目标需要额外将算法转换为定点。此外,我们发现为 ARM 编译 C 代码的过程通常比为 FPGA 编译 HDL 代码更快。
我们使用仿真来确定如果执行速率很慢的话,算法组件是否能够正常运行。如果是,我们就使用 ARM,否则就使用 FPGA。例如,算法工程师最初提出以 25 kHz 运行某编码器标定例程,这样该例程就必须在 FPGA 上实现。我们用仿真测试了是否能够以 1 kHz 运行该编码器标定组件,结果发现可以,于是决定在 ARM 上实现。
平衡功能性行为和实现所需资源
有了具备所需组件速率的功能正确的模型后,我们将所有用于 C 代码生成的组件划分到 Algorithm C Model 中,并将所有用于 HDL 代码生成的组件划分到 Algorithm HDL Model 中(图 6)。然后,我们以迭代方式将实现细节添加到模型中并生成代码,直到我们认为它可以适配合理的内存量,并且可以以组件的速率执行。
我们使用了 Embedded Coder® 从算法 C 模型生成 C 代码,并生成了显示调用接口和数据内存估算使用量的报告。在查看报告时,我们意识到所有数据类型均为双精度浮点。我们希望与 FPGA 对接的数据是整数或定点数据,其余的数学数据是单精度浮点数据。我们将这些数据类型应用于模型,使用仿真来验证行为仍是可接受的,然后生成了改进的代码。至此,我们觉得代码已经可以在 ARM 上进行实现了。
我们将算法 HDL 模型实现为定点,因为定点运算在 FPGA 上占用的资源更少。为此,我们与算法工程师一起确定并界定了设计中的关键信号范围(电流、电压和速度),然后使用 Fixed-Point Designer™ 定义定点数据类型,以确保计算不会溢出。我们使用 HDL Coder™ 生成了代码和一份摘要报告。
我们查看了报告中的资源估算部分,发现数学运算量似乎过大。例如,我们最初选择的字长导致两个 34 位数的多次乘法,我们认为这将不必要地占用 FPGA 资源。我们在资源使用率报告中发现了此问题,降低了模型的精度,使用了仿真来验证功能仍正确,然后生成了改进的代码。我们使用了 Xilinx Vivado® Design Suite 来合成代码并验证了该代码满足时序要求。
实验室测试
有了候选算法实现后,我们就可以准备将其与我们的参考设计集成了。我们首先手动将生成的 C 函数与我们手写编码的 ARM 嵌入式项目集成,并将生成的 HDL 实体与我们手写编码的 Vivado 项目集成。然而,我们意识到,如果我们始终手动执行集成,那么我们就需要参与实验室中的每个设计迭代。我们使用本工作流的目标之一是让算法工程师能够自动化实验室测试的集成和部署过程。
我们使用了 HDL Coder Support Package for Xilinx Zynq-7000 Platform 将我们手写编码的 Vivado 项目注册为参考设计。之后,我们成功的自动化了生成的算法 HDL 代码与手写代码的集成,构建比特流,并将其下载到 FPGA。我们使用 Embedded Coder Support Package for Xilinx Zynq-7000 Platform 自动化了生成的算法 C 代码与 Linux 操作系统的集成,编译了可执行文件,将其下载到 ARM,并使用 Simulink® 与之交互。此支持包提供 AXI 互连,以支持 ARM 内核中的算法组件和可编程逻辑之间的通信。
在最初的系统设置过程中,算法和嵌入式工程师在实验室中合作是至关重要的。作为嵌入式工程师,我们必须把部署配置搭建好,并与算法工程师一起验证基本功能。一旦系统完成搭建,算法工程师就可以独立使用 Simulink 作为 SoC 的主要接口进行设计迭代。
算法工程师测试了部署的控制器后发现它没能提供预期的响应。通过将仿真结果和硬件结果进行比较,我们发现我们错误地计算了 ADC 计数到电流的映射。算法工程师创建了额外的测试,以更好地表征电机的扭矩常量并改进仿真和硬件之间的相关性(图 7)。
仿真结果和硬件测试结果之间的高度相关性让我们相信,我们可以在模型级别作出设计决策,并进一步缩短实验室时间。例如,有一次在实验室里,电机的转动在某些条件下变得不可控。我们推测此问题与在 FPGA 上实现的定点速度计算中的溢出有关。我们在仿真中重现了此问题,并在电机最大速度的最初假设中发现了缺陷。我们在仿真中调试和解决了此问题,并且只在验证时占用了实验室时间。
此方法的优势
上述工作流使我们能够更高效地与算法工程师合作。通过仿真,我们评估了算法分区对系统性能的影响,并验证了编码器标定组件可以从较高速率的可编程逻辑分区移至较低速率的 ARM 分区。
仿真还使我们能够在作出节省实现所需资源的决策的同时保持了功能性行为,例如减小可编程逻辑中数学运算的字长,或将通过 AXI 互连传递的数据从浮点数据类型转换为定点数据类型。最后,我们在实验室进行的原型测试帮助我们发现了 ADC 计数到电流的映射错误,并使我们的算法工程师能够运行进一步的测试来表征电机的扭矩常量。
总的来说,该工作流让我们和算法工程师合作得更加紧密,而且在节省实验室时间的同时,产生了更高效的实现。
想知道更多内容吗?
有关本文描述的工作流的详细信息,请查看永磁同步电机的磁场定向控制。此 Zynq 电机控制示例中提供了本案例中使用的 Simulink 模型和 MATLAB® 脚本,以用于运行仿真、生成代码、测试硬件以及将仿真运行结果与硬件测试结果进行比较。
如果您对电机控制算法的原型构建感兴趣,或要重现本文和示例中所示的结果,请了解 Avnet Electronics Marketing 提供的 Avnet Zynq Intelligent Drives Kit II 的更多信息。
要将 Zynq 电机控制示例扩展到不同硬件配置或者来自 Xilinx 或 Intel 的不同类的 SoC FPGA,请参考示例为 SoC 工作流定义和注册自定义板和参考设计。
要进一步了解如何生成用于 Simulink 的 PMSM 和 BLDC 电机的精确模型,请阅读文章为控制系统设计和验证创建电机的高保真模型。
2016 年发布 - 92977v00