exponenta event banner

Создание компонента DPI с помощью MATLAB

Создание функции MATLAB и испытательного стенда

Создание функции MATLAB

Кодируйте функцию MATLAB ®, которую требуется экспортировать в среду SystemVerilog. Для получения информации о кодировании функций MATLAB см. раздел «Основные сведения о функциях» в документации MATLAB.

Попробуйте добавить директиву компиляции %#codegen к вашей функции. Эта директива помогает диагностировать и исправлять нарушения, которые могут привести к ошибкам при создании кода. См. директиву компиляции% # codegen (кодер MATLAB).

При кодировании функции следует помнить об ограничениях, которые описывают различные аспекты создания компонентов DPI, которые необходимо знать. Эти аспекты включают допустимые типы данных, создаваемые файлы и способы компиляции общих библиотек.

В этом примере функция MATLAB fun.m принимает один вход и умножает его на 2. Функция включает директиву компиляции %#codegen.

function y = fun(x)
%#codegen
y = x * 2;

Процесс создания MATLAB включает в себя написание кода, создание тестового стенда и итерационный запуск тестового стенда. Если Вы удовлетворены тем, что Ваша функция выполняет то, что Вы намереваетесь сделать, перейдите к разделу Создание компонента SystemVerilog DPI.

Создание испытательного стенда

Создайте испытательный стенд для выполнения этой функции. В этом примере тестовый стенд применяет тестовый вектор к fun.m и строит график выходных данных.

function sample=fun_tb
% Testbench should not require input, however you can give an output.

% Define a test vector 
tVecIn = [1,2,3,4,5];

% Exercise fun.m and plot results to make sure function is working correctly
tVecOut = arrayfun(@(in) fun(in),tVecIn);
plot(tVecIn,tVecOut);
grid on;

% Get my sample input to use it with function dpigen.
sample = tVecIn(1);

Обратите внимание, что испытательный стенд не должен иметь входов. Испытательный стенд может загружать тестовые векторы с помощью файлов MAT или любого другого файла данных, поэтому он не требует ввода.

Выходные данные fun_tb, sample, будет использоваться в качестве входного аргумента функции для fun.m во время вызова dpigen, поэтому это единственный элемент. См. раздел Создание компонента SystemVerilog DPI.

Испытательный стенд

fun_tb
ans =

     1

Затем создайте компонент SystemVerilog DPI. См. раздел Создание компонента SystemVerilog DPI.

Создать компонент DPI SystemVerilog

Создать компонент DPI с помощью dpigen Функция

Используйте функцию dpigen для создания компонента DPI. Эта функция имеет несколько необязательных входных аргументов. Как минимум, укажите функцию MATLAB, для которой требуется создать компонент, и входные данные функции. Если также требуется создать стенд для выполнения созданного компонента, используйте -testbench вариант.

dpigen func -args input_arg -testbench test_bench_name 
  1. Определите входные данные, требуемые функцией. В этом примере: sample является скалярным значением типа double.

    sample = 1;
  2. Вызовите функцию генератора компонентов DPI:

    dpigen fun -args sample -testbench fun_tb 

    Команда, выпущенная, как показано на рисунке, выполняет следующие задачи:

    • Производит fun_dpi.sv - компонент SystemVerilog для функции fun.m. Функциональные входы для fun.m указаны в образце.

    • Производит fun_dpi_pkg.sv - файл пакета SystemVerilog. Этот файл содержит все импортированные объявления функций.

    • Создание испытательного стенда для созданного компонента.

    Для этого звонка в dpigenMATLAB выводит следующие сообщения:

    ### Generating DPI Wrapper fun_dpi.c
    ### Generating DPI Wrapper header file fun_dpi.h
    ### Generating SystemVerilog module package fun_dpi_pkg.sv
    ### Generating SystemVerilog module fun_dpi.sv
    ### Generating makefiles for: fun_dpi
    ### Compiling the DPI Component
    ### Generating SystemVerilog test bench fun_tb.sv
    ### Generating test bench simulation script for Mentor Graphics QuestaSim/Modelsim run_tb_mq.do
    ### Generating test bench simulation script for Cadence Incisive run_tb_incisive.sh
    ### Generating test bench simulation script for Cadence Xcelium run_tb_xcelium.sh
    ### Generating test bench simulation script for Synopsys VCS run_tb_vcs.sh
    ### Generating test bench simulation script for Vivado Simulator run_tb_vivado.bat
    

    Функция, показанная в предыдущем примере, создает следующие папки и файлы:

Проверка созданного файла пакета

Проверьте созданный файл пакета. Обратите внимание на заявления initialize, reset, terminate, и fun функции.

В этом примере показан код, созданный для fun_dpi_pkg.sv.

// File: C:\fun_example\codegen\dll\fun\fun_dpi_pkg.sv
// Created: 2017-12-19 09:18:00
// Generated by MATLAB 9.5 and HDL Verifier 5.4

`timescale 1ns / 1ns
package fun_dpi_pkg;

// Declare imported C functions
import "DPI" function chandle DPI_fun_initialize(input chandle existhandle);
import "DPI" function chandle DPI_fun_reset(input chandle objhandle,input real x,output real y);
import "DPI" function void DPI_fun(input chandle objhandle,input real x,output real y);


import "DPI" function void DPI_fun_terminate(input chandle existhandle);

endpackage : fun_dpi_pkg

Проверка созданного компонента

Проверьте созданный компонент, чтобы понять, как dpigen функция преобразовала код MATLAB в код SystemVerilog. Дополнительные сведения о том, что включает в себя функция, см. в разделе Сгенерированная оболочка SystemVerilog.

В этом примере показан код, созданный для fun_dpi.sv.

// File: C:\fun_example\codegen\dll\fun\fun_dpi.sv
// Created: 2017-12-19 09:18:00
// Generated by MATLAB 9.5 and HDL Verifier 5.4

`timescale 1ns / 1ns

import fun_dpi_pkg::*;

module fun_dpi(
    input bit clk,
    input bit clk_enable,
    input bit reset,
    input real x,
    output real y
);

    chandle objhandle=null;
    real y_temp;
    
    initial begin
        objhandle=DPI_fun_initialize(objhandle);
    end

    final begin
        DPI_fun_terminate(objhandle);
    end

    always @(posedge clk or posedge reset) begin
        if(reset== 1'b1) begin
            objhandle=DPI_fun_reset(objhandle,x,y_temp);
            y<=y_temp;
        end
        else if(clk_enable) begin
            DPI_fun(objhandle,x,y_temp);
            y<=y_temp;
        end
    end
endmodule

Осмотреть сформированный стенд

Проверьте созданный стенд, чтобы увидеть, как функционирует dpigen создал этот тестовый стенд из кода MATLAB. Дополнительные сведения о созданном испытательном стенде см. в разделе Сформированный испытательный стенд.

В этом примере показан код, созданный для fun_tb.sv.

// File: C:\fun_example\codegen\dll\fun\dpi_tb\fun_tb.sv
// Created: 2017-12-19 09:18:13
// Generated by MATLAB 9.5 and HDL Verifier 5.4

`timescale 1ns / 1ns
module fun_tb;
    real x;
    real y_ref;
    real y_read;
    real y;
    // File Handles
    integer fid_x;
    integer fid_y;
    // Other test bench variables
    bit clk;
    bit clk_enable;
    bit reset;
    integer fscanf_status;
    reg testFailure;
    reg tbDone;
    bit[63:0] real_bit64;
    bit[31:0] shortreal_bit64;
    parameter CLOCK_PERIOD= 10;
    parameter CLOCK_HOLD= 2;
    parameter RESET_LEN= 2*CLOCK_PERIOD+CLOCK_HOLD;
    // Initialize variables
    initial begin
        clk = 1;
        clk_enable = 0;
        testFailure = 0;
        tbDone = 0;
        reset = 1;
        fid_x = $fopen("dpig_in1.dat","r");
        fid_y = $fopen("dpig_out1.dat","r");
        // Initialize multirate counters
        #RESET_LEN reset = 0;
    end
    // Clock
    always #(CLOCK_PERIOD/2) clk = ~ clk;
    always@(posedge clk) begin
        if (reset == 0) begin
            #CLOCK_HOLD
            clk_enable <= 1;
            fscanf_status = $fscanf(fid_x, "%h", real_bit64);
            x = $bitstoreal(real_bit64);
            if ($feof(fid_x)) 
                tbDone = 1;
            fscanf_status = $fscanf(fid_y, "%h", real_bit64);
            y_read = $bitstoreal(real_bit64);
            if ($feof(fid_y)) 
                tbDone = 1;
            y_ref <= y_read;
            if (clk_enable == 1) begin
                assert ( ((y_ref - y) < 2.22045e-16) && ((y_ref - y) > -2.22045e-16) ) else begin
                    testFailure = 1;
                    $display("ERROR in output y_ref at time %0t :", $time);
                    $display("Expected %e; Actual %e; Difference %e", y_ref, y, y_ref-y);
                end
                if (tbDone == 1) begin
                    if (testFailure == 0) 
                        $display("**************TEST COMPLETED (PASSED)**************");
                    else
                        $display("**************TEST COMPLETED (FAILED)**************");
                    $finish;
                end
            end
        end
    end

    // Instantiate DUT
    fun_dpi u_fun_dpi(
    .clk(clk),
    .clk_enable(clk_enable),
    .reset(reset),
    .x(x),
    .y(y)
    );
endmodule

Затем запустите созданный стенд в имитаторе ЛПВП. См. раздел Запуск созданного тестового стенда в имитаторе ЛПВП. Если планируется перенос компонента и дополнительного тестового стенда из Windows ® в Linux ®, см. раздел Перенос сгенерированного компонента и тестового стенда в Linux.

Запуск созданного испытательного стенда в имитаторе ЛПВП

Этот раздел содержит инструкции по запуску созданного тестового стенда в одном из поддерживаемых имитаторов HDL: Mentor Graphics ® ModelSim ® и Questa ® Sim, Cadence Incisive ® и Synopsys ® VCS ®. Возможно, что этот код будет работать в других (неподдерживаемых) имитаторах ЛПВП, но он не гарантирован.

Выберите поток операций для имитатора HDL.

Испытательный стенд в симуляторах ModelSim и QuestaSim

  1. Запустите ModelSim или QuestaSim в режиме графического интерфейса пользователя.

  2. Измените текущий каталог на dpi_tb в каталоге генерации кода в MATLAB.

  3. Введите следующую команду в оболочку для запуска моделирования:

    do run_tb_mq.do

    Этот созданный сценарий содержит имя компонента и тестового стенда, а также инструкции для имитатора ЛПВП для запуска тестового стенда.

    По завершении моделирования на консоли должен отображаться следующий текст:

    **************TEST COMPLETED (PASSED)**************

    Это сообщение сообщает об успешном запуске тестового стенда для созданного компонента.

Следующее изображение формы волны из этого примера демонстрирует, что созданный стенд был успешно выполнен в имитаторе ЛПВП.

Затем импортируйте компонент. См. раздел Использование сгенерированных функций DPI в SystemVerilog.

Испытательный стенд в имитаторе резца

  1. Запустить Incisive ®.

  2. Запустите оболочку терминала.

  3. Изменение текущего каталога на dpi_tb в каталоге генерации кода в MATLAB.

  4. Введите следующую команду в оболочку для запуска моделирования:

    sh run_tb_ncsim.sh

    Этот созданный сценарий содержит имя компонента и тестового стенда, а также инструкции для имитатора ЛПВП для запуска тестового стенда.

    По завершении моделирования на консоли должен отображаться следующий текст:

    **************TEST COMPLETED (PASSED)**************

    Это сообщение сообщает об успешном запуске тестового стенда для созданного компонента.

Испытательный стенд в тренажере VCS

  1. Запуск VCS.

  2. Запустите оболочку терминала.

  3. Изменение текущего каталога на dpi_tb в каталоге генерации кода в MATLAB.

  4. Для запуска моделирования введите в оболочку следующую команду:

    sh run_tb_vcs.sh

    Этот созданный сценарий содержит имя компонента и тестового стенда, а также инструкции для имитатора ЛПВП для запуска тестового стенда.

    По завершении моделирования на консоли должен отображаться следующий текст:

    **************TEST COMPLETED (PASSED)**************

    Это сообщение сообщает об успешном запуске тестового стенда для созданного компонента.

Использование созданных функций DPI в SystemVerilog

Чтобы использовать созданный компонент DPI на тестовом стенде SystemVerilog, необходимо сначала включить файл пакета в среду SystemVerilog. В этом случае функции DPI будут доступны в рамках модуля SystemVerilog. Затем необходимо вызвать сгенерированные функции. При компиляции кода SystemVerilog, содержащего импортированные сгенерированные функции, используйте компилятор SystemVerilog с поддержкой DPI и укажите имена компонентов и файлов пакетов вместе с кодом SystemVerilog.

В следующем примере показано добавление созданного компонента DPI для fun.m в модуль SystemVerilog.

  1. Позвоните в Initialize функция.

    DPI_fun_initialize();
  2. Вызовите функцию, созданную из fun.m.

    DPI_fun(x,y);

При необходимости созданный код можно изменить.

Пример

module test_twofun_tb;

	initial begin
		DPI_fun_initialize();
	end

	always@(posedge clk) begin
		#1
		DPI_fun(x,y);
	end

Генерируемый портом компонент и тестовый стенд для Linux

Для переноса компонента и дополнительного тестового стенда из операционной системы Windows в операционную систему Linux выполните следующие инструкции.

Примечание

Необходимо иметь лицензию Embedded Coder ® для порта Windows-Linux. Хотя порт может работать без лицензии Embedded Coder, это использование не поддерживается.

Шаг 1. Задачи на хост-компьютере Windows

  1. Создание Coder™ MATLAB config объект. Измените тип оконечного аппаратного устройства на LP64 для операционной системы Linux.

    cfg=coder.config('dll');
    
    cfg.HardwareImplementation.TargetHWDeviceType='Generic->64-bit Embedded Processor (LP64)';
    
  2. Запустить dpigen команда с использованием опции -config для использования config объект, созданный на шаге 1. Использовать опцию -c таким образом, эта функция dpigen генерирует только код. Например:

    dpigen -config cfg DataTypes.m -args InputSample -c
  3. Чтобы создать zip-файл для порта в Linux, измените папку на исходную (где buildInfo.mat создается файл) и выполните следующие команды в командной строке:

    load buildInfo
    buildInfo.packNGo()
  4. Чтобы скопировать файл для переноса, вернитесь в папку верхнего уровня. Найдите zip-файл, созданный на предыдущем шаге (имя функции MATLAB). Скопируйте zip-файл на компьютер Linux.

Шаг 2. Задачи на целевой машине Linux

  1. Распакуйте файл с помощью -j позволяет извлечь все файлы с распрямленной структурой папок. Распаковку можно выполнить в любой папке. Например:

    unzip -j  DataTypes.zip
    1. Скопируйте этот общий сценарий makefile в пустой файл:

      SRC=$(wildcard *.c)
      OBJ=$(SRC:.c=.o)
      
      SHARE_LIB_NAME=DPI_Component.so
      
      all: $(SRC) $(SHARE_LIB_NAME)
      	@echo "### Successfully generated all binary outputs."
      
      $(SHARE_LIB_NAME): $(OBJ)
      	gcc -shared -lm $(OBJ) -o $@
      
      .c.o:
      	gcc -c -fPIC -Wall -pedantic -Wno-long-long -fwrapv -O0 $< -o $@
      
    2. Заменить DPI_Component.so с именем общей библиотеки, которую требуется создать.

    3. Сохранить сценарий как Porting_DPIC.mk в папке, в которую были извлечены zip-файлы.

  2. Создайте общую библиотеку с помощью следующей команды:

    make -f Porting_DPIC.mk all

    Сведения об использовании созданного компонента с SystemVerilog см. в разделе Использование сгенерированных функций DPI в SystemVerilog.

  3. (Необязательно) Запустите тестовый стенд, автоматически созданный в Windows.

    1. Копирование содержимого dpi_tb с хост-компьютера Windows на конечный компьютер Linux.

    2. Запустите испытательный стенд.

    Для запуска тестового стенда в имитаторе ЛПВП см. раздел Запуск сгенерированного тестового стенда в имитаторе ЛПВП.