Сгенерируйте компонент DPI с помощью MATLAB

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

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

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

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

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

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

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

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

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

Создайте испытательный стенд для выполнения функции. В этом примере испытательный стенд применяет тестовый вектор против 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, поэтому это один элемент. См. «Генерация компонента DPI SystemVerilog».

Запуск испытательного стенда

fun_tb
ans =

     1

Затем сгенерируйте компонент DPI SystemVerilog. См. «Генерация компонента DPI SystemVerilog».

Сгенерируйте компонент 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 указаны в sample.

    • Генерирует 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 Wrapper.

В этом примере показан код, сгенерированный для 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

Затем запустите сгенерированный испытательный стенд в Симулятор HDL. См. «Запуск сгенерированных Испытательных стендов в Симулятор HDL». Если вы планируете портировать компонент и дополнительный испытательный стенд из Windows® к Linux®, см. Port Generated Component и Испытательный Стенд к Linux.

Запустите сгенерированный испытательный стенд в Симулятор HDL

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

Выберите рабочий процесс для вашего Симулятора HDL.

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

  1. Запустите ModelSim или QuestaSim в режиме GUI.

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

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

    do run_tb_mq.do

    Этот сгенерированный скрипт содержит имя компонента и испытательного стенда, а также инструкции к Симулятору HDL для выполнения испытательного стенда.

    Когда симуляция завершится, на консоли будет отображен следующий текст:

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

    В этом сообщении указывается, что испытательный стенд успешно выполнен в отношении сгенерированного компонента.

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

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

Запустите испытательный стенд в Incisive Simulator

  1. Запуск Incisive®.

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

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

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

    sh run_tb_ncsim.sh

    Этот сгенерированный скрипт содержит имя компонента и испытательного стенда, а также инструкции к Симулятору HDL для выполнения испытательного стенда.

    Когда симуляция завершится, на консоли будет отображен следующий текст:

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

    В этом сообщении указывается, что испытательный стенд успешно выполнен в отношении сгенерированного компонента.

Запуск испытательного стенда в симуляторе VCS

  1. Запуск VCS.

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

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

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

    sh run_tb_vcs.sh

    Этот сгенерированный скрипт содержит имя компонента и испытательного стенда, а также инструкции к Симулятору HDL для выполнения испытательного стенда.

    Когда симуляция завершится, на консоли будет отображен следующий текст:

    **************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. Создайте MATLAB Coder™ config объект. Измените тип целевого устройства HW на LP64 для операционной системы Linux.

    cfg=coder.config('dll');
    
    cfg.HardwareImplementation.TargetHWDeviceType='Generic->64-bit Embedded Processor (LP64)';
    
  2. Запустите dpigen команда с использованием option -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. Скопируйте этот универсальный скрипт make-файла в пустой файл:

      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. Запустите испытательный стенд.

    Чтобы запустить испытательный стенд в Симулятор HDL, см. Запуск Сгенерированные Испытательные стенды в Симулятор HDL.