В этом примере показано, как сгенерировать 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 Coder см. в разделе «Начало работы с MATLAB в 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');