应用笔记

Moku Cloud 使用 MathWorks HDL Coder 进行编译

在 Moku:Pro 上生成可部署的 VHDL 代码第 1 部分 - MATLAB

借助 Liquid Instruments 的 Moku 云编译工具,用户可以在 Moku:Pro FPGA 上部署自己的定制数字信号处理 (DSP)。 FPGA 编程通常使用硬件描述语言 (HDL) 完成。 与软件编程语言相比,HDL 编码的学习曲线可能比较陡峭,因此在本教程中,我们将介绍如何使用 MATLAB 和 Simulink 编程和构建 DSP 行为/算法,以自动生成 VHDL 代码以在 Moku 平台上实现。 在本教程的第 1 部分中,我们将演示如何将 MATLAB 脚本转换为 VHDL 代码,以及 部分2 本教程的下半部分将演示如何将 Simulink 模型转换为 VHDL 代码。

下载打印版本


概述

Moku 云编译

Liquid Instruments 的 Moku Cloud Compile (MCC) 工具使用户能够设计自定义仪器以在 Moku 平台上实施。 与基于 CPU 和专用集成电路 (ASIC) 的 DSP 方法相比,FPGA 提供 ASIC 级别的输入到输出延迟,同时像 CPU 一样是软件定义和可重新编程的。 FPGA 编程通常使用硬件描述语言 (HDL) 完成。 与软件编程语言相比,HDL 编码的学习曲线可能比较陡峭,但有一些工具可用于将其他编程语言的脚本转换为 HDL。 在本教程中,我们将演示如何使用 MathWorks HDL 编码器将您的 MATLAB 代码转换为 HDL 代码,以便在 Moku:Pro 上实现。

在本教程的第一部分,我们将只关注使用 MATLAB HDL Coder 生成 VHDL 代码。 建议已经熟悉 MATLAB 编程的用户使用此方法。 本教程的第二部分将介绍从 Simulink 模型生成 VHDL 代码。 Simulink 模型的框图格式可以更容易地可视化系统和数据流,用户还可以将 MATLAB 功能块添加到他们的设计中。 对于更复杂的系统,同时使用这两种工具可能会显着简化设计过程。

MATLAB HDL Coder 方法的设计过程可以分解为图 4 中的 1 个顶层阶段:DSP 设计、浮点仿真、HDL 生成以及 DSP 部署和验证。 我们将按照以下步骤使用 MATLAB HDL Coder 构建数字施密特触发器,以便在 Moku:Pro 上实现。


图 1:Cloud Compile + HDL Coder DSP 设计的推荐工作流程。

施密特触发器

施密特触发器是比较器电路的变体。 它根据输入是高于还是低于特定电压阈值提供 1 位数字输出。 基于标准运算放大器的比较器具有单一阈值。 对于嘈杂的输入信号,它可能会在阈值电压处跳跃,并在输入接近或超过阈值时产生不稳定的输出。 施密特触发器有两个阈值,较高的阈值用于开启,较低的阈值用于关闭。 在这种情况下,即使噪声输入超过开启阈值并跳回,较高和较低阈值之间的差距会创建一个“保护区”,保持数字输出不变。 该设备通常用作设备触发器或正弦波至方波转换器。


图 2:比较器和施密特触发器之间的比较。

岗位要求

在我们开始构建和实施施密特触发器之前,请确保您的系统满足以下要求。 要从 MATLAB 脚本生成 VHDL 代码,您需要具有带 HDL Coder 和 Fixed-Point Converter 的 MATLAB。 如果您希望在本教程的第 II 部分中使用 Simulink 构建您的系统,您还需要有 Simulink。 注意:Mac 用户还需要安装 XCode 才能使 HDL Coder 正常工作。 要编译 VHDL 代码,您需要访问 Liquid Instruments Cloud Compile。 要实现编译的乐器比特流,您需要有一个运行固件版本 551 或更高版本的 Moku:Pro,Moku: iPad 应用程序,并在您的 Moku:Pro 上访问多乐器模式。

数字信号处理器设计

概念设计

施密特触发器具有单个输入和输出。 将模拟输入信号与上限和下限阈值进行比较。 在此示例中,上限阈值是整个正输入范围的 1/10,下限阈值是整个负输入范围的 1/10。 如果输入信号高于上限阈值,则输出设置为2^15-1(输出可以产生的最大16位有符号整数); 如果输入信号低于下限阈值,则输出设置为 0; 或者,如果这些条件都不满足,则它会保持以前的状态。

浮点 DSP 设计

在本节中,我们使用持久变量和 if-elseif 语句将上述概念设计转换为 MATLAB 函数。

 

在施密特触发器 DSP 功能中,我们只需要一个输入通道 (InputA) 和一个输出通道 (OutputA)。 我们将创建一个具有单一输入和输出的 MATLAB“DSP”。 请注意 DSP 模块必须以函数格式设计。

函数 OutputA = DSP(InputA)

然后我们可以使用持久变量 out0 和用于逻辑操作的 if-elseif 语句填充该函数。

浮点模拟

仿真和验证是 FPGA 设计中的关键步骤。 通常的做法是通过构建“测试台”来验证数字系统的响应,该“测试台”输入模拟信号以观察系统的响应。 需要测试平台将浮点设计转换为定点设计。 对于原生定点设计,测试平台是可选的。 但是,强烈建议始终对任何设计运行测试台仿真。

试验台建设

在 MATLAB 中,可以将测试平台视为 MATLAB 脚本,它在具有一系列输入的循环中调用函数(即本教程中的 DSP 函数)。 在本教程中,我们将进行三轮testbench验证:浮点设计、定点设计和HDL设计。 第一个测试平台是验证浮点模型,第二个是验证定点转换后的系统行为,最后是通过 EDA 软件中的 VHDL 仿真来验证 HDL 模型。

前两轮测试台在 MATLAB 中进行,并使用相同的测试台脚本模拟输入信号。 模拟信号在动态范围和精度方面应该非常接近真实输入信号。 这将有助于 MATLAB 的定点工具确定最适合定点模型的精度。

DSP 功能测试平台通过加载一组示例数据作为输入信号来工作。 该信号与教程第二部分中的 Simulink 模型一致。 然后在 for 循环中调用 DSP 函数,输出如图 3 所示。输出确认 DSP 函数与我们想要设计的施密特触发器匹配,因此我们现在可以继续使用 MATLAB HDL Coder 生成 HDL 代码。


图 3:MATLAB 仿真的输出

HDL 代码生成

MATLAB HDL Coder 使用 Workflow Advisor 指导用户完成完整的 HDL 代码生成过程,其中包括定点转换、HDL 生成和 HDL 测试平台生成过程。 要启动将我们的 DSP 函数转换为 HDL 代码的过程,我们首先在 MATLAB 中启动 HDL Coder App 并创建一个新项目。 或者,您可以在 MATLAB 的命令行窗口中键入“hdlcoder”。


图 4:可以在 App 选项卡中找到 HDL Coder 应用程序以创建新的 HDL Coder 项目。

一旦 HDL 代码生成窗口弹出,我们就可以添加 MATLAB 功能(DSP)和相应的测试台。 我们可以在这里使用“Autodefine types”来定义函数的输入变量类型,也可以在Workflow Adviser 中完成。 在大多数情况下,输入变量可以定义为 翻番,因为我们的模型此时是浮点数。


图 5:DSP.m 和 DSP_tb.m 用作 HDL 生成的源代码。

我们现在将打开 工作流程顾问 生成施密特触发器 HDL 代码。

定点转换

软件模型和 FPGA 模型之间的一个主要区别是软件计算通常使用浮点数,而大多数 FPGA 计算需要定点数。 MATLAB 的原生格式是浮点数; 因此,我们需要将此浮点设计转换为用于 HDL 代码生成的定点模型。

MathWorks 的定点工具根据测试台输入数据范围执行自动浮点模型到定点模型的转换。 如果需要,用户可以手动覆盖自动定义的范围。 对于 Moku Cloud Compile,Input、Output 和 Control 信号类型必须与 Moku Cloud Compile 接口匹配,它们是带符号的 16 位数字。 MATLAB 将其表示为 numerictype(1,16,0),其中“1”将信号指定为有符号数,“16”将字长指定为 16 位,“0”表示我们未指定二进制小数点缩放。

要开始定点转换,我们首先单击“Analyze”按钮,让 HDL Coder 根据测试台文件确定数据类型和范围。 如果建议的类型与硬件接口要求(即 numerictype(1,16,0))不匹配,请通过单击变量的建议类型并输入 numerictype(1,16,0) 手动覆盖输入和输出数据类型). 然后,单击“Validate Types”以验证数据类型并生成定点模型。


图 6:1. 使用测试台输入信号分析数据类型。 2. 如有必要,手动覆盖数据类型。 3. 验证设计并生成定点模型。

定点模型验证

定点模型转换后,我们需要运行另一次仿真来验证定点模型是否按预期运行并评估任何精度损失。 定点模型验证是通过“测试数值”按钮完成的。 确保选择“Log inputs and outputs for comparison plots”,因为这将生成图来比较浮点模型中的变量与定点模型中的相同变量。


图 7:浮点模型和定点模型之间变量 OutputA 的比较

如果观察到不可接受的精度损失,则增加可变精度,然后重复定点转换。 请注意输入、输出和控制信号的精度必须与硬件接口匹配。

一旦定点模型通过testbench的验证,我们就可以继续为施密特触发器模型生成VHDL代码。

VHDL代码生成

进入菜单中的“Select Code Generation Target”,我们将其保留为“Generic ASIC/FPGA”。

在“HDL Code Generation”步骤中,我们需要配置“Target”和“Clocks & Ports”:

  • 目标:
    • 语言VHDL
  • 时钟和端口:
    • 重置类型同步
    • 单向阀 最小化时钟启用
    • 输入数据类型有符号/无符号
    • 输出数据类型有符号/无符号

单击“运行”后,系统的 VHDL 代码将出现在 …\代码生成\DSP\hdlsrc 文件夹中。


图 8:选择 VHDL 的目标语言并运行代码生成

使用第三方工具的 VHDL 仿真(可选)

HDL Coder 还可以生成 HDL 测试台文件,用于在 EDA 软件上运行仿真。 使用第三方 HDL 仿真器验证模型可为设计提供额外的保险层。 此步骤是可选的,但强烈建议用于复杂的系统。 testbench 文件可以在“HDL Verification”步骤中生成 工作流程顾问.


图 9:(a) HDL 测试平台文件可以在 HDL Coder 中生成。 (b) 使用 Xilinx Vivado 进行 HDL 级仿真

编译部署

现在我们有了施密特触发器的 VHDL 代码,我们准备好使用 Liquid Instruments 的 Moku Cloud Compile 编译仪器,然后部署在 Moku:Pro 上。

仪器包装

Moku Cloud Compile 内置了一个标准包装器,允许自定义乐器与 Moku 的其他部分进行交互。 标准包装器使用仪器的所有 4 个输入通道和输出通道,这与我们只有 1 个输入和 1 个输出的施密特触发器示例不匹配。 因此,我们需要为仪器创建一个自定义包装器。

本教程提供了 MATLAB 生成的 VHDL 代码的包装器模板。 提供了三种不同的包装器模板,一种设计用于 MATLAB HDL Coder 生成的 VHDL 代码(即本教程),一种设计用于 Simulink 生成的 VHDL 代码(即本教程的第 II 部分),最后一种用于您的代码包含一个 抽出 港口。 在继续选择适合您的应用程序的包装器模板之前,请检查 VHDL 代码的端口定义部分。

下面是我们将用于编译施密特触发器仪器的自定义包装器。

编译和部署工具

有关如何使用 Moku Cloud Compile 构建仪器比特流和部署仪器的详细说明,请参见我们的 Moku云编译入门指南.

要编译施密特触发器,请在 Liquid Instruments 的 Moku Cloud Compile 上创建一个新项目。 在这个项目中,为DSP_fixpt.vhd创建一个文件,这是施密特触发器的VHDL代码; 还为前面部分中的自定义包装器创建一个包装器文件。 选择目标设备作为具有 4 个插槽的 Moku:Pro 并构建项目。 构建比特流后,您将能够使用 Web 界面和 iPad 应用程序在您的 Moku:Pro 上部署施密特触发器。

为了证明施密特触发器在一开始就作为我们的概念设计发挥作用,我们在多仪器模式下使用 Moku: App 将编译后的 DSP 放入系统中。 在插槽 1 中,我们放置了一个任意波形发生器以生成我们在测试台中使用的相同信号作为施密特触发器的输入信号。 在插槽 2 中,我们放置了施密特触发器。 在插槽 3 中,我们放置了一个示波器,输入 1 显示施密特触发器的输出,输入 2 显示任意波形发生器的信号输出以比较信号。 我们可以看到,当信号超过 110 mV 时,施密特触发器的输出切换为高电平,并保持高电平,直到信号降至 -110 mV 以下。 这证实了施密特触发器按设计工作。


图 10:(a) 多仪器系统配置。 (b) 验证施密特触发器是否按设计运行的示波器测量。

结论

本教程涵盖了将 MATLAB 脚本转换为可编译以在 Moku 平台上实现的 VHDL 代码的详细过程。 该过程涉及 4 个顶层过程:DSP 设计、浮点仿真、HDL 生成以及 DSP 部署和验证。 这个过程消除了学习 HDL 编程的需要,并使用户能够直接进入设计和创建自己的定制仪器。

代码可用性

该项目的源代码可以通过以下方式下载 此链接.


问题或意见?

请与我们联系 support@liquidinstruments.com