Передача и прием FIFO

В этом примере показано, как сгенерировать HDL-код из данных передачи моделирования кода MATLAB ® между передающей и приёмной FIFO.

Давайте посмотрим на дизайн MATLAB для передачи и приема FIFO и тестбенч, который упражняет оба проекта.

design_core1 = 'mlhdlc_rx_fifo';
design_core2 = 'mlhdlc_tx_fifo';
testbench_name = 'mlhdlc_fifo_tb';

type('mlhdlc_rx_fifo');

function [dout, empty, byte_ready, full, bytes_available] = ...
    mlhdlc_rx_fifo(get_byte, store_byte, byte_in, reset_fifo, fifo_enable)
%

%   Copyright 2014-2015 The MathWorks, Inc.

%
%  First In First Out (FIFO) structure.
%  This FIFO stores integers.
%  The FIFO is actually a circular buffer.
%
persistent head tail fifo byte_out handshake

if (reset_fifo || isempty(head))
    head = 1;
    tail = 2;
    byte_out = 0;
    handshake = 0;
end

if isempty(fifo)
    fifo = zeros(1,1024);
end

full = 0;
empty = 0;
byte_ready = 0;

% Section for checking full and empty cases
if ((tail == 1 && head == 1024) || ((head + 1) == tail))
    empty = 1;
end
if ((head == 1 && tail == 1024) || ((tail + 1) == head))
    full = 1;
end

% handshaking logic
if get_byte == 0
    handshake = 0;
end
if handshake == 1
    byte_ready = 1;
end

if (fifo_enable == 1)
    %%%%%%%%%%%%%%get%%%%%%%%%%%%%%%%%%%%%
    if (get_byte && ~empty && handshake == 0 )
        head = head + 1;
        if head == 1025
            head = 1;
        end
        byte_out = fifo(head);
        byte_ready = 1;
        handshake = 1;
    end
    %%%%%%%%%%%%%put%%%%%%%%%%%%%%%%%%%%%
    if (store_byte && ~full)
        fifo(tail) = byte_in;
        tail = tail + 1;
        if tail == 1025
            tail = 1;
        end
    end
end

% Section for calculating num bytes in FIFO
if (head < tail)
    bytes_available = (tail - head) - 1;
else
    bytes_available = (1024 - head) + tail - 1;
end
    
dout = byte_out;
end

type('mlhdlc_tx_fifo');

function [dout, empty, byte_received, full, bytes_available, dbg_fifo_enable] = ...
    mlhdlc_tx_fifo(get_byte, store_byte, byte_in, reset_fifo, fifo_enable)
%

%   Copyright 2014-2015 The MathWorks, Inc.

%
%  First In First Out (FIFO) structure.
%  This FIFO stores integers.
%  The FIFO is actually a circular buffer.
%
persistent head tail fifo byte_out handshake

if (reset_fifo || isempty(head))
    head = 1;
    tail = 2;
    byte_out = 0;
    handshake = 0;
end

if isempty(fifo)
    fifo = zeros(1,1024);
end

full = 0;
empty = 0;
byte_received = 0;

% Section for checking full and empty cases
if ((tail == 1 && head == 1024) || ((head + 1) == tail))
    empty = 1;
end
if ((head == 1 && tail == 1024) || ((tail + 1) == head))
    full = 1;
end

% handshaking logic
if store_byte == 0
    handshake = 0;
end
if handshake == 1
    byte_received = 1;
end

if (fifo_enable == 1)
    %%%%%%%%%%%%%%get%%%%%%%%%%%%%%%%%%%%%
    if (get_byte && ~empty)
        head = head + 1;
        if head == 1025
            head = 1;
        end
        byte_out = fifo(head);
    end
    %%%%%%%%%%%%%put%%%%%%%%%%%%%%%%%%%%%
    if (store_byte && ~full && handshake == 0)
        fifo(tail) = byte_in;
        tail = tail + 1;
        if tail == 1025
            tail = 1;
        end
        byte_received = 1;
        handshake = 1;
    end
end

% Section for calculating num bytes in FIFO
if (head < tail)
    bytes_available = (tail - head) - 1;
else
    bytes_available = (1024 - head) + tail - 1;
end

dout = byte_out;
dbg_fifo_enable = fifo_enable;
end

type('mlhdlc_fifo_tb');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% simulation parameters
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% data payload creation

%   Copyright 2014-2015 The MathWorks, Inc.

messageASCII = 'Hello World!';
message = double(unicode2native(messageASCII));
msgLength = length(message);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% TX_FIFO core
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
numBytesToFifo = 1;
tx_get_byte = 0;
tx_full = 0;
tx_byte_received = 0;
i1 = 1;

while (numBytesToFifo <= msgLength && ~tx_full)
    % first thing the processor does is clear the internal tx fifo
    if i1 == 1
        tx_reset_fifo = 1;
        mlhdlc_tx_fifo(0, 0, 0, tx_reset_fifo, 1);
    else
        tx_reset_fifo = 0;
    end
    if (i1 > 1)
        tx_data_in = message(numBytesToFifo);
        numBytesToFifo = numBytesToFifo + 1;
        tx_store_byte = 1;
        while (tx_byte_received == 0)
            [tx_data_out, tx_empty, tx_byte_received, tx_full, tx_bytes_available] = ...
                mlhdlc_tx_fifo(tx_get_byte, tx_store_byte, tx_data_in, tx_reset_fifo, 1);
        end
        tx_store_byte = 0;
        while (tx_byte_received == 1)
            [tx_data_out, tx_empty, tx_byte_received, tx_full, tx_bytes_available] = ...
                mlhdlc_tx_fifo(tx_get_byte, tx_store_byte, tx_data_in, tx_reset_fifo, 1);
        end
    end
    i1 = i1 + 1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Transfer Bytes from TX FIFO to RX FIFO
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
i1 = 1;

tx_get_byte = 0;
tx_store_byte = 0;
tx_data_in = 0;
tx_reset_fifo = 0;

rx_get_byte = 0;
rx_data_in = 0;
rx_reset_fifo = 0;

while (tx_bytes_available > 0)
        if i1 == 1
            rx_reset_fifo = 1;
            mlhdlc_rx_fifo(0, 0, 0, rx_reset_fifo, 1);
        else
            rx_reset_fifo = 0;
        end
        if (i1 > 1)
            tx_get_byte = 1;
            rx_store_byte = 1;
            [tx_data_out, tx_empty, tx_byte_received, tx_full, tx_bytes_available] = ...
                mlhdlc_tx_fifo(tx_get_byte, tx_store_byte, tx_data_in, tx_reset_fifo, 1);
            
            rx_data_in = tx_data_out;
            
            [rx_data_out, rx_empty, rx_byte_ready, rx_full, rx_bytes_available] = ...
                mlhdlc_rx_fifo(rx_get_byte, rx_store_byte, rx_data_in, rx_reset_fifo, 1);
        end
        i1 = i1 + 1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% RX_FIFO core
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
numBytesFromFifo = 1;
rx_store_byte = 0;
rx_byte_recieved = 0;
i1 = 1;
msgBytes = zeros(1,msgLength);

while (~rx_empty)
    % first thing the processor does is clear the internal rx fifo
    if (i1 > 1)
        rx_get_byte = 1;
        while (rx_byte_ready == 0)
            [rx_data_out, rx_empty, rx_byte_ready, rx_full, rx_bytes_available] = ...
                mlhdlc_rx_fifo(rx_get_byte, rx_store_byte, rx_data_in, rx_reset_fifo, 1);
        end
        msgBytes(i1-1) = rx_data_out;
        rx_get_byte = 0;
        while (rx_byte_ready == 1)
            [rx_data_out, rx_empty, rx_byte_ready, rx_full, rx_bytes_available] = ...
                mlhdlc_rx_fifo(rx_get_byte, rx_store_byte, rx_data_in, rx_reset_fifo, 1);
        end
    end
    i1 = i1 + 1;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

numRecBytes = numBytesFromFifo;
if sum(msgBytes-message) == 0
    disp('Received message correctly');
else
    disp('Received message incorrectly');
end    
native2unicode(msgBytes)



Создайте новую папку и скопируйте соответствующие файлы

Выполните следующие строки кода, чтобы скопировать необходимые файлы примера во временную папку.

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_fifo'];

% Create a temporary folder and copy the MATLAB files.
cd(tempdir);
[~, ~, ~] = rmdir(mlhdlc_temp_dir, 's');
mkdir(mlhdlc_temp_dir);
cd(mlhdlc_temp_dir);

copyfile(fullfile(mlhdlc_demo_dir, 'mlhdlc_fifo_tb.m*'), mlhdlc_temp_dir);
copyfile(fullfile(mlhdlc_demo_dir, 'mlhdlc_rx_fifo.m*'), mlhdlc_temp_dir);
copyfile(fullfile(mlhdlc_demo_dir, 'mlhdlc_tx_fifo.m*'), mlhdlc_temp_dir);

% Additional test files
copyfile(fullfile(mlhdlc_demo_dir, 'mlhdlc_rx_fifo_tb.m*'), mlhdlc_temp_dir);
copyfile(fullfile(mlhdlc_demo_dir, 'mlhdlc_tx_fifo_tb.m*'), mlhdlc_temp_dir);

Моделируйте проект

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

mlhdlc_fifo_tb
Received message correctly

ans =

    'Hello World!'

Создайте новый HDL Coder™ проект

coder -hdlcoder -new mlhdlc_fifo

Затем добавьте файл 'mlhdlc _ fifo.m' к проекту в качестве функции MATLAB и 'mlhdlc _ fifo _ tb.m' в качестве испытательного стенда MATLAB.

Более полное руководство по созданию и заполнению проектов MATLAB HDL Coder см. в разделе «Начало работы с MATLAB в HDL».

Запуск преобразования с фиксированной точкой и генерации HDL-кода

Запустите Workflow Advisor на вкладке Build и щелкните правой нажатие кнопки по шагу 'Генерация Кода' и выберите опцию 'Run to selected task', чтобы запустить все шаги от начала до генерации HDL-кода.

Исследуйте сгенерированный HDL-код, нажав на гиперссылки в Генерацию кода Журнала окне.

Очистка сгенерированных файлов

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

mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos');
mlhdlc_temp_dir = [tempdir 'mlhdlc_fifo'];
clear mex;
cd (mlhdlc_demo_dir);
rmdir(mlhdlc_temp_dir, 's');
Для просмотра документации необходимо авторизоваться на сайте