В этом примере показано, как создать код HDL из MATLAB ® design, реализующего алгоритм биссекции для вычисления квадратного корня числа в виде фиксированной точки.
Та же реализация, первоначально использующая n-множители в коде HDL для оптимизации совместного использования и потоковой передачи слов n, может генерировать код HDL только с 1 множителем, демонстрирующим мощность оптимизации кодера MATLAB ® HDL.
Конструкция алгоритма квадратного корня показывает концепции конвейеризации для достижения быстрой тактовой частоты в результирующей конструкции RTL. Поскольку эта конструкция уже находится в фиксированной точке, выполнение преобразования с фиксированной точкой не требуется.
% Design Sqrt design_name = 'mlhdlc_sqrt'; % Test Bench for Sqrt testbench_name = 'mlhdlc_sqrt_tb';
Рассмотрим конструкцию Sqrt
dbtype(design_name)
1 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2 % MATLAB design: Pipelined Bisection Square root algorithm
3 %
4 % Introduction:
5 %
6 % Implement SQRT by the bisection algorithm in a pipeline, for unsigned fixed
7 % point numbers (also why you don't need to run fixed-point conversion for this design).
8 % The demo illustrates the usage of a pipelined implementation for numerical algorithms.
9 %
10 % Key Design pattern covered in this example:
11 % (1) State of the bisection algorithm is maintained with persistent variables
12 % (2) Stages of the bisection algorithm are implemented in a pipeline
13 % (3) Code is written in a parameterized fashion, i.e. word-length independent, to work for any size fi-type
14 %
15 % Ref. 1. R. W. Hamming, "Numerical Methods for Scientists and Engineers," 2nd, Ed, pp 67-69. ISBN-13: 978-0486652412.
16 % 2. Bisection method, http://en.wikipedia.org/wiki/Bisection_method, (accessed 02/18/13).
17 %
18
19 % Copyright 2013-2015 The MathWorks, Inc.
20
21 %#codegen
22 function [y,z] = mlhdlc_sqrt( x )
23 persistent sqrt_pipe
24 persistent in_pipe
25 if isempty(sqrt_pipe)
26 sqrt_pipe = fi(zeros(1,x.WordLength),numerictype(x));
27 in_pipe = fi(zeros(1,x.WordLength),numerictype(x));
28 end
29
30 % Extract the outputs from pipeline
31 y = sqrt_pipe(x.WordLength);
32 z = in_pipe(x.WordLength);
33
34 % for analysis purposes you can calculate the error between the fixed-point bisection routine and the floating point result.
35 %Q = [double(y).^2, double(z)];
36 %[Q, diff(Q)]
37
38 % work the pipeline
39 for itr = x.WordLength-1:-1:1
40 % move pipeline forward
41 in_pipe(itr+1) = in_pipe(itr);
42 % guess the bits of the square-root solution from MSB to the LSB of word length
43 sqrt_pipe(itr+1) = guess_and_update( sqrt_pipe(itr), in_pipe(itr+1), itr );
44 end
45
46 %% Prime the pipeline
47 % with new input and the guess
48 in_pipe(1) = x;
49 sqrt_pipe(1) = guess_and_update( fi(0,numerictype(x)), x, 1 );
50
51 %% optionally print state of the pipeline
52 %disp('************** State of Pipeline **********************')
53 %double([in_pipe; sqrt_pipe])
54
55 return
56 end
57
58 % Guess the bits of the square-root solution from MSB to the LSB in
59 % a binary search-fashion.
60 function update = guess_and_update( prev_guess, x, stage )
61 % Key step of the bisection algorithm is to set the bits
62 guess = bitset( prev_guess, x.WordLength - stage + 1);
63 % compare if the set bit is a candidate solution to retain or clear it
64 if ( guess*guess <= x )
65 update = guess;
66 else
67 update = prev_guess;
68 end
69 return
70 end
Выполните следующие строки кода, чтобы скопировать необходимые файлы примеров во временную папку.
mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos'); mlhdlc_temp_dir = [tempdir 'mlhdlc_sqrt']; % create a temporary folder and copy the MATLAB files cd(tempdir); [~, ~, ~] = rmdir(mlhdlc_temp_dir, 's'); mkdir(mlhdlc_temp_dir); cd(mlhdlc_temp_dir); % copy files to the temp dir copyfile(fullfile(mlhdlc_demo_dir, [design_name,'.m*']), mlhdlc_temp_dir); copyfile(fullfile(mlhdlc_demo_dir, [testbench_name,'.m*']), mlhdlc_temp_dir);
Всегда рекомендуется моделировать конструкцию с помощью средства тестирования до создания кода, чтобы убедиться в отсутствии ошибок во время выполнения.
mlhdlc_sqrt_tb
Iter = 01| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 02| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 03| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 04| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 05| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 06| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 07| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 08| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 09| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 10| Input = 0.000| Output = 0000000000 (0.00) | actual = 0.000000 | abserror = 0.000000 Iter = 11| Input = 4.625| Output = 0000010000 (2.00) | actual = 2.150581 | abserror = 0.150581 Iter = 12| Input = 12.500| Output = 0000011100 (3.50) | actual = 3.535534 | abserror = 0.035534 Iter = 13| Input = 16.250| Output = 0000100000 (4.00) | actual = 4.031129 | abserror = 0.031129 Iter = 14| Input = 18.125| Output = 0000100010 (4.25) | actual = 4.257347 | abserror = 0.007347 Iter = 15| Input = 20.125| Output = 0000100010 (4.25) | actual = 4.486090 | abserror = 0.236090 Iter = 16| Input = 21.875| Output = 0000100100 (4.50) | actual = 4.677072 | abserror = 0.177072 Iter = 17| Input = 35.625| Output = 0000101110 (5.75) | actual = 5.968668 | abserror = 0.218668 Iter = 18| Input = 50.250| Output = 0000111000 (7.00) | actual = 7.088723 | abserror = 0.088723 Iter = 19| Input = 54.000| Output = 0000111010 (7.25) | actual = 7.348469 | abserror = 0.098469 Iter = 20| Input = 62.125| Output = 0000111110 (7.75) | actual = 7.881941 | abserror = 0.131941 Iter = 21| Input = 70.000| Output = 0001000010 (8.25) | actual = 8.366600 | abserror = 0.116600 Iter = 22| Input = 81.000| Output = 0001001000 (9.00) | actual = 9.000000 | abserror = 0.000000 Iter = 23| Input = 83.875| Output = 0001001000 (9.00) | actual = 9.158330 | abserror = 0.158330 Iter = 24| Input = 83.875| Output = 0001001000 (9.00) | actual = 9.158330 | abserror = 0.158330 Iter = 25| Input = 86.875| Output = 0001001010 (9.25) | actual = 9.320676 | abserror = 0.070676 Iter = 26| Input = 95.125| Output = 0001001110 (9.75) | actual = 9.753205 | abserror = 0.003205 Iter = 27| Input = 97.000| Output = 0001001110 (9.75) | actual = 9.848858 | abserror = 0.098858 Iter = 28| Input = 101.375| Output = 0001010000 (10.00) | actual = 10.068515 | abserror = 0.068515 Iter = 29| Input = 102.375| Output = 0001010000 (10.00) | actual = 10.118053 | abserror = 0.118053 Iter = 30| Input = 104.250| Output = 0001010000 (10.00) | actual = 10.210289 | abserror = 0.210289

coder -hdlcoder -new mlhdlc_sqrt_prj
Затем добавьте файл «mlhdlc _ sqrt.m» в проект в качестве функции MATLAB и «mlhdlc _ sqrt _ tb.m» в качестве тестового стенда MATLAB.
Более подробное руководство по созданию и заполнению проектов кодера MATLAB HDL см. в разделе Начало работы с MATLAB в Workflow-процессе HDL.
Эта конструкция уже находится в фиксированной точке и подходит для генерации кода HDL. Нежелательно запускать помощник с плавающей и фиксированной точками в этой конструкции.
Запуск помощника по рабочим процессам
В разделе «Определение входных типов» выберите «Сохранить исходные типы» для параметра «Преобразование фиксированных точек».
На вкладке «Optimizations» в поле «RAM Mapping» снимите флажок «MAP persistent variables to RAM». Мы не хотим, чтобы конвейер выводился как ОЗУ.
При необходимости на вкладке «Optimizations» (Оптимизации) выберите «Area Optimizations» (Оптимизации области) и установите «Resource sharing factor» (Коэффициент совместного использования ресурсов) равной длине слова (10 здесь), выберите «Stream Loops» (Циклы) на вкладке «Loop Optimizations» (Оптимизации цикла). Также не забудьте проверить параметр «Распределенная конвейерная обработка» при включении оптимизации.
Щелкните по шагу «Code Generation» и выберите «Run».
Проверьте созданный код HDL, щелкнув гиперссылки в окне Журнал генерации кода.
Если на компьютере установлен ISE, выполните шаг логического синтеза со следующими параметрами по умолчанию.
В отчете по синтезу запишите тактовую частоту, сообщенную средством синтеза, без включения опций оптимизации.
Как правило, синхронизация производительности этой конструкции с использованием инструмента синтеза Xilinx ISE для семейства чипов 'Virtex7', устройство 'xc7v285t', степень скорости -3, чтобы быть около 229MHz, и максимальная комбинаторная задержка пути: 0,406ns.
Оптимизация этой конструкции (потоковая передача по контуру и совместное использование множителя) позволяет сократить использование ресурсов с умеренным компромиссом по времени. Для конкретного размера слова-длины на тестовом стенде вы увидите уменьшение n множителей до 1.
Для очистки временной папки проекта можно выполнить следующие команды.
mlhdlc_demo_dir = fullfile(matlabroot, 'toolbox', 'hdlcoder', 'hdlcoderdemos', 'matlabhdlcoderdemos'); mlhdlc_temp_dir = [tempdir 'mlhdlc_sqrt']; clear mex; cd (mlhdlc_demo_dir); rmdir(mlhdlc_temp_dir, 's');