Этот пример показывает, как сгенерировать 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!'
coder -hdlcoder -new mlhdlc_fifo
Затем, добавьте файл 'mlhdlc_fifo.m' в проект как функция MATLAB и 'mlhdlc_fifo_tb.m' как Испытательный стенд MATLAB.
Можно обратиться к Началу работы с MATLAB к примеру по Рабочему процессу HDL для более полного примера при создании и заполнении проектов HDL Coder MATLAB.
Запустите Советника по вопросам Рабочего процесса от вкладки Build, и щелчок правой кнопкой по 'Генерации кода' продвигаются и выбирают опцию, 'Запущенную к выбранной задаче', чтобы запустить все шаги с начала через генерацию HDL-кода.
Исследуйте сгенерированный HDL-код путем нажатия на гиперссылки в окне Code Generation Log.
Можно запустить следующие команды, чтобы очистить временную папку проекта.
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');