这是“Moku Cloud Compile with MathWorks HDL Coder”教程的第 2 部分。 可以找到第 1 部分 开始现在,我们将使用 MathWorks 的 Simulink 在 Moku:Pro 上构建和部署一个双通道施密特触发器。MATLAB 脚本方法和 Simulink 模型方法的工作流程大致相同,但 Simulink 提供了额外的即用型第一方 DSP 和测试模块。基于框图的设计方法提供了一种更直观的 DSP 工作流程构建方法,尤其适用于更复杂的系统。在本教程中,我们将通过混合 MATLAB-Simulink 设计构建第一个通道,并使用 Simulink 库构建第二个通道。


概述

Moku 云编译 (MCC) 让用户能够设计可以部署在 Moku 硬件上的自定义算法。 与基于 DSP 方式的 CPU 和专用集成电路 (ASIC) 相比,FPGA 提供 ASIC 同级的输入到输出延迟,同时又像 CPU 一样具有软件定义和可编程性。 FPGA 编程一般使用硬件描述语言 (HDL) 实现。 与软件编程语言相比,HDL 编码的学习不易,但有一些工具可以用来将其他编程语言的脚本转换为 HDL。 在本系列教程的第一部分中,我们介绍了如何使用 MathWorks HDL 编码器将 MATLAB 脚本转换为 HDL 代码以在 Moku:Pro 上实现,在本部分中,我们将演示如何通过 Simulink 模型来生成 HDL 代码。

Simulink 是由 MathWorks 开发的基于图形的建模工具。 基于框图的设计理念简化了将手绘数字信号处理 (DSP) 系统转换为基于计算机的模型的过程。 诸如波形发生器和示波器等虚拟测试和测量仪器提供了一种更直观的方式来构建测试平台并验证 DSP 模型。 此外,用户还可以选择使用 Simulink 从头开始​​构建定点系统。 一些逻辑操作更容易用 MATLAB 函数实现,在这种情况下,用户可以将 MATLAB 函数模块添加到他们的设计中。 对于更复杂的系统,同时使用这两种工具可以显着简化设计过程。

在本教程中,我们将构建一个双通道施密特触发器。 施密特触发器的基础知识和概念设计可以在教程的第一部分找到。 对于第一个通道,我们将使用教程第一部分中完全相同的 MATLAB 函数来构建 DSP。 对于第二个通道,我们将使用 Simulink 内置的 DSP 模块来实现相同的功能。

图 1:Moku Cloud Compile + HDL Coder DSP 设计的建议操作流程。

图 1:Moku Cloud Compile + HDL Coder DSP 设计的建议操作流程。

申请条件

在开始构建和实现施密特触发器之前,请确保您的系统满足以下要求。要从 Simulink 模型生成 VHDL 代码,您需要安装包含 Simulink、HDL Coder 和 Fixed-Point Converter 的 MATLAB。注意:Mac 用户还需要安装 XCode 才能使用 MATLAB 生成 VHDL 代码。要编译 VHDL 代码,您需要访问 Moku Cloud Compile。要实现编译后的仪器比特流,您需要拥有运行固件版本 601 或更高版本的 Moku:Pro、Moku: 应用程序以及访问 多仪器并行模式 在您的 Moku:Pro 上。

设计和构建 DSP

选取合适的模板

创建模型的第一步是调整并选取适合我们 DSP 设计的 Simulink 模板。 由于我们的设计是双通道系统,因此我们只需要 InputA、InputB、OutputA 和 OutputB 这四个端口。

图 2:删除多余通道端口

图 2:移除冗余通道。

浮点 DSP 设计

在本节中,我们将构建两个施密特触发器,第一个通道使用 MATLAB 函数模块,第二个通道使用 Simulink 触发器模块。

我们可以在 simulation 选项卡下的“Library Browser”中找到 Simulink 创建模块。 使用搜索功能是查找所需元素的最佳方式。 需要注意,并非所有 Simulink 模块都支持 HDL 代码生成。 对于 DSP 子系统中的所有内容,我们建议仅使用“HDL Coder”或“HDL Support”目录下的模块。

图 3:可以通过 Library Browser 找到 Simulink 创建模块。

图 3:可以通过 Library Browser 找到 Simulink 创建模块。

对于第一个通道,我们将在模型中放置一个 MATLAB 函数模块。 由于 MATLAB 函数是浮点模型,Simulink 模板已经为所有端口预定义了数据类型,所以数据类型不匹配。 我们通过在 MATLAB 函数模块前后放置两个“convert”模块来解决这个问题。 用户可以使用定点算法设计模型,但我们发现在模型中实现 MATLAB 函数模块时,从浮点设计开始会更容易。 需要注意,可能需要在 HDL 转换步骤之前删除第一个转换模块。

要将施密特触发器函数添加到 MATLAB 函数模块块,请双击该模块。 我们将使用与教程第一部分相同的 MATLAB 函数,函数命名除外(因此我们不会为 MATLAB 函数和 Simulink 子系统使用相同的命名)。

图 4:基于 MATLAB 函数的施密特触发器的框图设计。

图 4:基于 MATLAB 函数的施密特触发器的框图设计。

function OutputA = Schmitt_Trigger(InputA)
%#codegen
persistent persistent out0; %在函数调用过程之间维持变量值不变。
if isempty(out0) %初始化第一次函数调用时的值。
     out0 = 0;

end

upperThreshold = floor(2^15/10); %将阈值上限设置为正值范围的 1/10。
lowerThreshold = -floor(2^15/10); %将阈值下限设置为负值范围的 1/10。

if InputA >upperThrehold %激活施密特触发功能的逻辑判定条件。
     out0 = 2^15-1; %将最大正值赋值给 outXNUMX。
elseif elseif InputA <lowerThreshold
     out0 = 0;

end

OutputA = out0; %将变量 out0 赋值给 OutputA 并输出。

对于第二个通道,我们将使用 Simulink 的“Relay”模块来执行施密特触发器逻辑判定。 我们将 relay 模块放在 InputB 和 OutputB 之间,然后双击“Relay”模块以将打开和关闭阈值分别映射到 floor(2^15/10) 和 – floor(2^15/10)。 在“Signal Attributes”选项卡中,将信号输出设置为 fixdt(1, 16,0) 以匹配输出。

图 5:“Relay”模块设置为与第一个通道上施密特触发相同的逻辑判定。

图 5:“Relay”模块设置为与第一个通道上施密特触发相同的逻辑判定。

创建测试平台

Simulink 内置了信号发生器、示波器和其他常用测试测量设备模块。 这使我们能够以更直观的方式设计测试平台。 请注意,HDL Coder 不需要支持 DSP 系统之外的创建模块,因为它们仅仅用来仿真。

为了创建测试台,我们使用了一个“Signal Generator”模块来产生一个信号,这与第 16 部分中用于测试台的信号相同。我们重新调整并转换了来自信号发生器的信号,以匹配我们系统的 XNUMX 位有符号输入。 在将信号馈送到输入端口之前,添加了一个额外的“Convert”模块以将浮点数转换为定点数。 然后,我们将信号发生器生成的信号、OuputA 和 OutputB 的输出信号输入示波器以观察系统响应。

图 6:基于 Simulink 的测试平台框图

图 6:基于 Simulink 的测试平台的框图。

一旦测试系统创建完成后,我们将运行测试模拟并验证其输出。 我们可以观察到输出信号符合设计预期。

图 7:示波器上观察到 DSP 子系统的输出信号。

图 7:示波器上 DSP 子系统的输出。

定点转换

在为我们的 DSP 子系统生成 VHDL 代码之前,我们需要将浮点 MATLAB 函数模块转换为定点函数模块。 我们使用 MathWorks 下“Apps”选项卡中的 Fixed-Point Tool 和“Iterative Fixed-Point Conversion”方法来实现。 请注意,如果我们从一开始就使用定点 DSP 构建 Simulink 模型,则不必运行定点转换。

图 8:迭代定点转换可以通过 Simulink Apps 选项卡调用。

图 8:迭代定点转换可以通过 Simulink Apps 选项卡调用。

接下来,我们选中 MATLAB 函数,并通过单击“Collect Ranges”启动转换过程。 Simulink 使用测试台的数据作为转换模型的参考。

图 9:MATLAB 函数被选为“设计中的系统”。

图 9:MATLAB 函数被选为“设计中的系统”。

然后,我们可以使用“Propose Data Types”让 Simulink 决定最佳定点精度。 底部的直方图可以显示每个信号的范围。 如果需要,我们可以手动重选任何信号的精度。 一旦确定精度后,我们可以使用“Apply Data Types”来进行转换。

图10:(1)根据测试台数据由软件自动推荐信号精度; (2) 用直方图观察信号范围; (3) 继续将模型转换为定点设计。 (4) 删除第一个“convert”模块。

图10:(1)根据测试台数据由软件自动推荐信号精度; (2) 用直方图观察信号范围; (3) 继续将模型转换为定点设计。 (4) 删除第一个“convert”模块。

定点转换后,需要移除第一个“Convert”模块; 因为新的“MATLAB Function”模块采用定点数而不是浮点数/双精度数。

定点模型验证

模型转换完成后,重要的是要执行另一轮仿真以确保函数表现和精度损失符合预期。

VHDL 代码生成

单击 HDL Code 选项卡下的“Generate HDL Code”来生成 HDL 代码。 HDL Coder 的生成设定已经在 Simulink 模板中进行了预配置,因此我们无需在此处调整设置。

图 11:“Generate HDL Code”位于 HDL Code 应用选项卡下方。

图 11:“Generate HDL Code”位于 HDL Code 应用选项卡下方。

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

单击 HDL 代码应用选项卡下的“Generate Testbench”可以生成 VHDL 测试台文件。 验证步骤与第 XNUMX 部分的 MATLAB 示例相同。

 图 12:“Generate Testbench”位于 HDL Code 应用选项卡下方。

图 12:“Generate Testbench”位于 HDL Code 应用选项卡下方。

为 DSP 生成 VHDL 代码、编译并部署

Moku Cloud Compile 内置了一个标准封装器,允许自定义功能与 Moku:Pro 上的其他仪器进行交互。 标准封装器使用所有四个输入通道和输出通道; 这与我们的施密特触发器示例不匹配,该示例具有两个输入和两个输出。 因此,我们需要根据提供的模板为仪器创建一个自定义封装器。

请注意,即使选择了“Minimize clock enables”选项,有时 HDL Coder 仍会生成带有 clock_enablece_out 端口的 VHDL 代码(如本教程中所示)。 我们将连接 clock_enable 到恒定的高电平,如果这些端口是在 VHDL 转换过程中创建的,则保持 ce_out 端口常开。

ARCHITECTURE HDLCoderWrapper OF CustomWrapper IS
-- 声明信号变量
SIGNAL ConstantHigh:std_logic. :='1';
--声明组件
COMPONENT DSP
PORT(Clk : IN std_logic;
     Reset : IN std_logic;
     clk_enable : IN std_logic;
     InputA : IN signed(15 DOWNTO 0); -- sfix16_En16
     输入 B                           : IN signed(15 DOWNTO 0); -- sfix16_En16
     ce_out_0 : OUT std_logic;
     ce_out_1 : OUT std_logic;
     OutputA: OUT signed(15 DOWNTO 0); -- sfix16_En14
     OutputB: OUT signed(15 DOWNTO 0); -- sfix16_En14
     );

END COMPONENT;

BEGIN
     u_DSP:DSP
          PORT MAP(Clk => Clk,
               Reset => Reset,
               clk_enable => ConstantHigh,
               InputA => InputA,
               InputB => InputB,
               ce_out_0 => open,
               ce_out_1 => open,
               OutputA => OutputA,
               OutputB => OutputB
          );
END HDLCoderWrapper;

编译和部署施密特触发器

有关如何使用 Moku 云编译创建自定义仪器 bitstream 和如何部署的详细说明,请参见我们的 Moku 云编译入门指南.

要编译施密特触发器,请在 Liquid Instruments 的 Moku Cloud Compile 上创建一个新项目。在此项目中,创建一个 DSP_fixpt.vhd 文件,该文件是施密特触发器的 VHDL 代码;同时,为上一节中的自定义包装器创建一个包装器文件。选择带有 4 个插槽的 Moku:Pro 作为目标设备,并构建项目。比特流构建完成后,您就可以使用网页界面和 Moku: 应用程序在您的 Moku:Pro 上部署施密特触发器了。

为了证明施密特触发器符合我们的设计初衷,我们使用 Moku 应用程序连接 Moku:Pro,并使用多仪器并行模式来部署不同的仪器功能。 在插槽 1 上,我们放置了一个任意波形发生器以生成我们在测试台中使用的相同信号作为施密特触发器的输入信号。 在插槽 2 上,我们放置了施密特触发器。 在插槽 3 中,我们放置了一个示波器来比较施密特触发器和任意波形发生器的输出信号。

我们首先验证使用 MATLAB 函数块设计的通道 A 中的施密特触发器。我们可以确认,当输入信号高于 110 mV 时,施密特触发器的输出切换到高电平,直到信号降至 -110 mV 以下时才切换到零电平。

图 13:(a) 多仪器并行模式下,用于测试使用 MATLAB 函数模块创建的施密特触发器的系统配置。 (b) 用于验证施密特触发器是否按设计运行的示波器测量界面。

图 13:(a) 用于测试 MATLAB 函数块施密特触发器的多仪器系统配置。(b) 示波器测量验证施密特触发器是否按设计运行。

我们还验证了通道 B 上的施密特触发器,它是使用 Simulink 触发器模块设计的,我们可以观察到相同的行为表现。

图 14:(a) 多仪器并行模式下,用于测试使用 Simulink 触发器模块创建的施密特触发器的系统配置。 (b) 验证施密特触发器是否按设计运行的示波器测量界面。

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

最后,我们将两个输出通道放在一起进行比较,可以验证它们是否在同一点切换为高电平或者低电平。

图 15:使用 MATLAB 函数模块设计的和使用触发器模块设计的施密特触发器均具有相同的行为表现。

图 15:使用 MATLAB 函数模块设计的和使用触发器模块设计的施密特触发器均具有相同的行为表现。

结语

在本系列教程的第二部分中,我们介绍了如何使用 MathWorks 的 Simulink 和 HDL Coder 在 Moku:Pro 上构建、验证和部署 DSP 模型。 与仅使用 MATLAB 的方法相比,使用 Simulink 让您可以选择通过其内置的 DSP 库设计 DSP,并使用定点模型从头开始构建模型。 我们推荐在构建复杂的 DSP 系统时使用 Simulink。

获取源代码

该项目的源代码可以下载 开始.


仍有疑问或是需要电子文档?

请通过 support@liquidinstruments.com 与我们取得联系,谢谢!


在演示模式下试用 Moku

您可以下载适用于 macOS 和 Windows 的 Moku: 应用程序 开始.


获取常见问题的答案

在我们的网站上查找有关设备和仪器的问题和答案 知识库.


与 Moku 用户联系

即刻加入 用户论坛 请求新功能、分享支持提示并与我们的全球用户社区联系。

其他推荐的应用笔记

返回所有应用笔记