exponenta event banner

Алгоритм секционирования для вычисления квадратного корня беззнакового числа с фиксированной точкой

В этом примере показано, как создать код HDL из MATLAB ® design, реализующего алгоритм биссекции для вычисления квадратного корня числа в виде фиксированной точки.

Та же реализация, первоначально использующая n-множители в коде HDL для оптимизации совместного использования и потоковой передачи слов n, может генерировать код HDL только с 1 множителем, демонстрирующим мощность оптимизации кодера MATLAB ® HDL.

Конструкция алгоритма квадратного корня показывает концепции конвейеризации для достижения быстрой тактовой частоты в результирующей конструкции RTL. Поскольку эта конструкция уже находится в фиксированной точке, выполнение преобразования с фиксированной точкой не требуется.

Проектирование MATLAB

% 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

Создание нового проекта HDL Coder™

coder -hdlcoder -new mlhdlc_sqrt_prj

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

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

Запуск генерации кода HDL

Эта конструкция уже находится в фиксированной точке и подходит для генерации кода HDL. Нежелательно запускать помощник с плавающей и фиксированной точками в этой конструкции.

  1. Запуск помощника по рабочим процессам

  2. В разделе «Определение входных типов» выберите «Сохранить исходные типы» для параметра «Преобразование фиксированных точек».

  3. На вкладке «Optimizations» в поле «RAM Mapping» снимите флажок «MAP persistent variables to RAM». Мы не хотим, чтобы конвейер выводился как ОЗУ.

  4. При необходимости на вкладке «Optimizations» (Оптимизации) выберите «Area Optimizations» (Оптимизации области) и установите «Resource sharing factor» (Коэффициент совместного использования ресурсов) равной длине слова (10 здесь), выберите «Stream Loops» (Циклы) на вкладке «Loop Optimizations» (Оптимизации цикла). Также не забудьте проверить параметр «Распределенная конвейерная обработка» при включении оптимизации.

  5. Щелкните по шагу «Code Generation» и выберите «Run».

Проверьте созданный код HDL, щелкнув гиперссылки в окне Журнал генерации кода.

Анализ результатов синтеза

  1. Если на компьютере установлен ISE, выполните шаг логического синтеза со следующими параметрами по умолчанию.

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

  3. Как правило, синхронизация производительности этой конструкции с использованием инструмента синтеза Xilinx ISE для семейства чипов 'Virtex7', устройство 'xc7v285t', степень скорости -3, чтобы быть около 229MHz, и максимальная комбинаторная задержка пути: 0,406ns.

  4. Оптимизация этой конструкции (потоковая передача по контуру и совместное использование множителя) позволяет сократить использование ресурсов с умеренным компромиссом по времени. Для конкретного размера слова-длины на тестовом стенде вы увидите уменьшение 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');