Jump to content
    

Krys

Свой
  • Posts

    2,052
  • Joined

  • Last visited

Posts posted by Krys


  1. https://inf.news/en/economy/7b07c778506a36eeb6bf1b5381f930b3.html

    Quote

    The Procise tool developed by Fudan Microelectronics is the first ultra-large-scale full-process EDA design tool in the domestic FPGA field. It has a friendly interface, powerful and simple to use. It can provide full-process automatic design services for ultra-large-scale FPGAs and integrates a large number of IP Resources to help customers quickly realize application development.

     

    • Like 1
  2. On 10/8/2022 at 4:12 AM, Alex77 said:

    я не знаю можно ли накатывать 2 апдейт без 1-го.

    Я проверил, можно. Только что закончил скачивание и установку. Сначала поставил полный пакет из закромов, 2022.1, а затем на него сразу аптейт 2022.1.2.

  3. Здравствуйте. Запускаю установщик 2022.1 из закромов, пишет сразу ошибку There is no valid Xilinx installation that this Update can be applied to. Подскажите пожалуйста, ЧЯДНТ? Надо установить какую-то предыдущую версию? Как точно узнать, какие промежуточные нужно поставить, чтобы эта поставилась? Ведь даже это весит немало (около 70 гигов).

  4. 1 hour ago, _4afc_ said:

    Написать свою функцию, спрятав в неё то что некрасиво.

    Тут тоже внутренний перфекционист негодует )))

    Вопрос мой скорее можно ли штатным образом так сделать

  5. 8 minutes ago, stealthisname said:
    с = 3*real(c)+1i*imag(c);

    ну так тоже не очень красиво (чисто из перфекционизма). Всё равно вытаскивается мнимая часть, которая здесь не участвует в вычислениях. Мне бы как-то получить доступ только к вещественной части числа на запись. Вот в этом вопрос.

  6. On 9/8/2022 at 12:33 AM, stealthisname said:

    конкретно для перехода из полярных координат к комплексному числу

    Спасибо за подсказку, действительно, элементарно, формула Эйлера, что ж я раньше об этом сам не догадался ))

    Однако в моём вопросе меня интересовал общий случай, любые функции и переменные. Не знаете решение?

    И также есть у меня вопрос: можно ли получить доступ к отдельным квадратурам комплексного числа? Вот типа допустим есть у меня

    c = x + 1i*y

    Я бы хотел записать примерно такое:

    c.Re = с.Re*3

    Т.е. выполнить некоторые преобразования только с одной квадратурой. Сейчас я знаю лишь способ сначала разложить на отдельные вещественные числа квадратур, выполнить преобразование с одной квадратурой, затем собрать обратно в комплексное число:

    x = real(c);
    y = imag(c);
    x = x*3;
    c = complex(x, y);

    Но чисто из перфекционизма мне так делать не нравится. Хочется как-то напрямую получить доступ к квадратуре.

  7. 1 hour ago, Krys said:

    Разобрался!

    На основе вашей подсказки доработал свою функцию (изменения под комментариями со словами aspect ratio):

    Spoiler
    %% function to generate x and y arrays for plot function to plot lines with
    %%  arrows (vectors)
    % INPUTS:
    %   X, Y - vectors of x and y as it could be plotted by plot function
    %       (without arrows, as is)
    % OUTPUTS:
    %   xVec, yVec - arrays (vectors) with x and y coodinates for plot function
    %       to plot lines with arrows
    %   xVecM, yVecM - matrix of vectors, each column contains one line with
    %       arrow (one vector). It can be useful to plot each vector separately
    %       in different plot function in a loop
    %   xArrow, yArrow - arrays (vectors) with x and y coordinates for plot
    %       function to plot only arrows (can be useful to plot arrows with
    %       anoter plot function call with different color, for example)
    %   aspRat - aspect ratio (X:Y)
    
    function [xVec, yVec, xVecM, yVecM, xArrow, yArrow, aspRat] = pvec(X, Y)
    
    arLenFac = 0.05;  % factor of lenght of arrow relative to vector length
    arAngDeg = 20;    % angle of arrow relative to vector line in degree
    arAng = deg2rad(arAngDeg);
    vecSize = 6; % number of points to plot one vector
    nPoints = length(X);
    vecM = zeros(vecSize, nPoints-1);
    arrowM = vecM;
    
    % changing to equal aspect ratio
    [xMin, xMax] = bounds(X);
    [yMin, yMax] = bounds(Y);
    aspRat = (xMax - xMin) / (yMax - yMin);
    X = X / aspRat;
    
    % conversion inputs into complex numbers and then finding length and angle
    inCompl = complex(X, Y);
    inDif = diff(inCompl);
    angVec = angle(inDif);
    lenVec = abs(inDif);
    
    % arrow up and down parts angles
    upArAng = angVec + arAng;
    dnArAng = angVec - arAng;
    
    arLen = lenVec * arLenFac; % arrow length
    
    % up and down arrow parts Cartesian coordinates from origin, that means
    %   coordinates diff
    [upArDifX, upArDifY] = pol2cart(upArAng, arLen);
    [dnArDifX, dnArDifY] = pol2cart(dnArAng, arLen);
    upArDifCompl = complex(upArDifX, upArDifY);
    dnArDifCompl = complex(dnArDifX, dnArDifY);
    
    
    % full coordinates of up and down parts of arrow from the end of vector line
    upArCompl = inCompl(2 : end) - upArDifCompl;
    dnArCompl = inCompl(2 : end) - dnArDifCompl;
    
    % filling the points for plot function to draw full vector with arrow (can
    %   be used to plot vectors one-by-one)
    vecM(1, :) = inCompl(1 : end - 1);
    vecM(2, :) = inCompl(2 : end);
    vecM(3, :) = upArCompl;
    vecM(4, :) = NaN;
    vecM(5, :) = dnArCompl;
    vecM(6, :) = inCompl(2 : end);
    
    % returning to original aspect ratio
    vecM = complex(real(vecM) * aspRat, imag(vecM));
    
    % only arrows preparation
    arrowM(1, :) = NaN;
    arrowM(2 : end, :) = vecM(2 : end, :);
    
    % reshaping 2-dim matrix into 1-dim to plot
    vec = reshape(vecM, [], 1);
    arrows = reshape (arrowM, [], 1);
    
    % final separation for x and y part for output variables
    xVecM = real(vecM);
    yVecM = imag(vecM);
    
    xVec = real(vec);
    yVec = imag(vec);
    
    xArrow = real(arrows);
    yArrow = imag(arrows);
    
    end

     

    И вызывающий её код теперь выглядит вот так:

    Spoiler
    [~, ~, ~, ~, xArrow, yArrow, aspRat] = pvec(coe, res);
    figure; hold on;
    daspect([aspRat 1 1]);
    plot(coe, res);
    plot(xArrow, yArrow);
    dx = diff(coe);
    dy = diff(res);
    str = num2str((1 : length(coe)-1).');
    text(coe(1:end-1), res(1:end-1), str);
    hold off;

     

    Теперь выглядит неплохо:

    Spoiler

    Screenshot_5.png.b6f92ddf284b1867e5d83aeec8180b3f.png

    Так что в принципе вопрос можно считать решённым.

  8. 2 hours ago, stealthisname said:
    Spoiler

    image.thumb.png.9288a4bf9ed8b08383f3fcdc634a9580.png

     

    Вот-вот, именно это у меня и получалось )))

     

    2 hours ago, stealthisname said:

    идём другим путём

    Спасибо за подсказку! Попробую разобраться )

    Я так понимаю, вы в матлабе далеко не новичок. Не загляните в тему? https://electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=168358

    9 minutes ago, Krys said:

    Попробую разобраться )

    Разобрался! Очень просто оказывается. Как здорово, что вам приходят в голову такие вещи, со стороны кажется: ну почему я сам не догадался ))

    2 hours ago, stealthisname said:

    пробуем работу Вашей функции pvec

    Я так понимаю, можно и с помощью quiver такой же финт провернуть?

  9. Здравствуйте. Есть у меня желание чисто ради перфекционизма кода в матлабе подставить сразу несколько выходных переменных одной функции в несколько входных переменных другой функции? Гулил, нашёл похожую проблему, но решения не увидел:

    https://uk.mathworks.com/matlabcentral/answers/180164-use-a-function-that-returns-multiple-values-as-input-argument-to-another-function

    Своими словами:

    Есть встроенная функция

    [x,y] = pol2cart(theta,rho)

    Я хотел бы из x и y сделать комплексное число такой подстановкой:

    С = complex(pol2cart(theta,rho))

    Но при такой записи передаётся только вещественная часть, мнимая по нулям.
    Пока реализовал через промежуточные переменные, но это костыли:

    [x,y] = pol2cart(theta,rho)
    
    С = complex(x,y)

    Может есть всё же способ сделать красиво, в одну строчку, без промежуточных переменных?

  10.  

    On 9/2/2022 at 12:55 AM, Самурай said:

    Вот как тут.

    Спасибо. Хотел напрямую слямзить этот код. Но он бажный. В некоторых направлениях стрелки рисует нормально, в некоторых коряво. В результате свой написал (см.ниже).

     

     

    On 9/4/2022 at 2:03 PM, stealthisname said:
    quiver

    Огромное спасибо за подсказку. Да, я смотрел эту функцию, но не так понял. Посчитал, что 3й и 4й аргументы это модуль и угол вектора. Испугался полярных координат, что типа некогда искать функции по пересчёту.
    В результате по примеру по ссылке из второго сообщения сделал свою функцию:

    Spoiler
    %% function to generate x and y arrays for plot function to plot lines with
    %%  arrows (vectors)
    % INPUTS:
    %   X, Y - vectors of x and y as it could be plotted by plot function
    %       (without arrows, as is)
    % OUTPUTS:
    %   xVec, yVec - arrays (vectors) with x and y coodinates for plot function
    %       to plot lines with arrows
    %   xVecM, yVecM - matrix of vectors, each column contains one line with
    %       arrow (one vector). It can be useful to plot each vector separately
    %       in different plot function in a loop
    %   xArrow, yArrow - arrays (vectors) with x and y coordinates for plot
    %       function to plot only arrows (can be useful to plot arrows with
    %       anoter plot function call with different color, for example)
    
    function [xVec, yVec, xVecM, yVecM, xArrow, yArrow] = pvec(X, Y)
    
    arLenFac = 0.05;  % factor of lenght of arrow relative to vector length
    arAngDeg = 20;    % angle of arrow relative to vector line in degree
    arAng = deg2rad(arAngDeg);
    vecSize = 6; % number of points to plot one vector
    nPoints = length(X);
    vecM = zeros(vecSize, nPoints-1);
    arrowM = vecM;
    
    % conversion inputs into complex numbers and then finding length and angle
    inCompl = complex(X, Y);
    inDif = diff(inCompl);
    angVec = angle(inDif);
    lenVec = abs(inDif);
    
    % arrow up and down parts angles
    upArAng = angVec + arAng;
    dnArAng = angVec - arAng;
    
    arLen = lenVec * arLenFac; % arrow length
    
    % up and down arrow parts Cartesian coordinates from origin, that means
    %   coordinates diff
    [upArDifX, upArDifY] = pol2cart(upArAng, arLen);
    [dnArDifX, dnArDifY] = pol2cart(dnArAng, arLen);
    upArDifCompl = complex(upArDifX, upArDifY);
    dnArDifCompl = complex(dnArDifX, dnArDifY);
    
    
    % full coordinates of up and down parts of arrow from the end of vector line
    upArCompl = inCompl(2 : end) - upArDifCompl;
    dnArCompl = inCompl(2 : end) - dnArDifCompl;
    
    % filling the points for plot function to draw full vector with arrow (can
    %   be used to plot vectors one-by-one)
    vecM(1, :) = inCompl(1 : end - 1);
    vecM(2, :) = inCompl(2 : end);
    vecM(3, :) = upArCompl;
    vecM(4, :) = NaN;
    vecM(5, :) = dnArCompl;
    vecM(6, :) = inCompl(2 : end);
    
    % only arrows preparation
    arrowM(1, :) = NaN;
    arrowM(2 : end, :) = vecM(2 : end, :);
    
    % reshaping 2-dim matrix into 1-dim to plot
    vec = reshape(vecM, [], 1);
    arrows = reshape (arrowM, [], 1);
    
    % final separation for x and y part for output variables
    xVecM = real(vecM);
    yVecM = imag(vecM);
    
    xVec = real(vec);
    yVec = imag(vec);
    
    xArrow = real(arrows);
    yArrow = imag(arrows);
    
    end

     

    И потом увидел ваше сообщение. Да, quiver в принципе повторяет то, что я сделал, только куда проще.

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

     

  11. Здравствуйте. Вопрос такой. Вот есть у меня вектор значений X и вектор значений Y какого-то процесса, который последовательно передвигается от одной точки к другой. Если я напишу plot(X, Y), то мне нарисует изломанную кривую из прямых линий, соединяющих мои точки в X и Y. Вроде мне так и надо. Но мне бы ещё к этому в конце каждой линии, соединяющей мои точки в X и Y, пририсовать хвостик у стрелочки. А желательно ещё и номерок подписать, какая это по счёту стрелочка. Чтобы я понимал, в какой очерёдности и в каком направлении движется процесс.

    Я попробовал annotation. И всё бы хорошо, но там точные координаты не задать, там либо в пикселях, либо в см и т.п., короче привязано к самому окошку графика. А мне бы в единицах измерения моего процесса.

    feather, quiver смотрел - вроде не то.

  12. 2 часа назад, Krys сказал:

    Я попробовал тупо скопировать файл проекта *.qsf, дам видно, что только seed отличается. Развёл этим файлом проекта - никуда не делись слаки.

    Дополнение: DSE оставляет  для каждой exploration point отдельную папку. Там есть запакованный архив проекта, а есть незапакованный проект. Я попробовал распаковать и скомпилить из архива. И попробовал незапакованный скомпилить. Проблема со слаками остаётся.

    Да, ещё есть кнопка Write to project на вкладке Results. По её нажатию я ожидал, что требуемые настройки запишутся в мой проект основной, откуда я из квартуса через меню Tools и вызвал DSE. Но я не увидел, чтобы что-то поменялось при нажатии этой кнопки. Как будто кнопка не действует.

  13. 23.04.2011 в 17:31, Kuzmi4 сказал:

    Потому как, с того что можно руками задать в DSE - это только seed для фита :crying: всё остальное получается как бы скрыто.

    Подниму бородатую тему. Полез в сабж решать проблему со слаками. Да, в сабже она решилась. Но как я могу перетащить в свой основной проект (для разводки чисто в квартусе, без использования каждый раз сабжа) те настройки, что были сделаны для exploration point с лучшим результатом? Я попробовал тупо скопировать файл проекта *.qsf, дам видно, что только seed отличается. Развёл этим файлом проекта - никуда не делись слаки. Значит данная exploration point имеет и другие настройки, кроме seed, которые отличаются от моего основного проекта, но где их выколупать - я не знаю.

    Также есть жалоба на кривоватость работы...

    Скрытый текст

     

    Рассчитал, что один процесс памяти сжирает 7ГБ (всего 32), сделал настройку, чтобы использовать одновременно 4 процесса на 4 процессорных ядра, по одному ядру на процесс. Однако по факту запустилось 5 процессов, в результате памяти не хватило )))

    Screenshot_1.thumb.png.9c3ff264db372ba5971f48fbfa780307.png

    Screenshot_2.thumb.png.0e9d115c75a98305c90a79fcec6571b1.png

    Ну и всё это дело в конце не могло само остановиться, только принудительное убийство всех процессов помогло.

     

  14. 24.05.2022 в 21:55, new123 сказал:

    от себя еще добавлю, что на Verilog я делал, нормально назначало.

    Переделал всё на верилог. Умножение сделал через генерацию LPM_MULT в визарде. Прописал latency большую в надежде, что упихает в регистры внутри DSP-блока. Нифига. Сделал снаружи на рассыпухе.

    Сейчас умножение напишу прямо на верилоге, может поможет.

     

    Дополнение: но при этом слаков больше нет. Значит переделывать не буду, так и оставлю, не стоит оно идеализации.

  15. 1 час назад, blackfin сказал:

    Была похожая тема:

    Огромное спасибо, действительно, проблема один в один, сейчас буду читать, что там вышло в итоге. Понравились высказывания, ржал ))

    Цитата

    Оказалось  что корка LPM_MULT   в Qu это не корка а так  - чистый  надувательство

    Цитата

    а я то наивный, Xilinx разбалованный, думал что там уже если не нетлист то хотя-бы жестко на примитивах собрано)

    Цитата

    лепит умножитель на чистой комбинаторике из DSP, а сзади цепляет к нему регистры (и даже пытается оптимизировать их в shift-ram, ха-ха-ха)

    Цитата

    Ну думаю - может подкину ему еще  1-2 дополнительных pipeline и все будет ок.

    Выше - это один в один мои мысли. Думаю чо мозг напрягать, подкину регистров, 5 на входе, 5 на выходе, "пусть долгоносик подавится" ))))

    И вообще, продвинутые спецы умеют под альтеру в виваде сразу разводить:

    Цитата

    Ну и Quartus я уже давно заменил на Vivado и, как видно, не зря..

    Ржал до слёз:

    Цитата

    Ведь не факт что похожее только с mult случается.  Например похожая по непонятности  ситуация  с  атрибутом синтеза maxfan.  На который как я вижу Qu кладет свой maxfuck.

    Цитата

    дало  увеличение времени сборки  на 40 мин и толику временных ошибок типа "поиздеваться над разработчиком", в цепях регистр - адрес памяти  ошибка тайминга  ~0.05 ns. :ireful2:

     

  16. 12 часов назад, Krys сказал:

    Я тут подумал... Не может ли виной быть, что задействована межкаскажная шина?

    И всё же меня смущает, зачем задействована межкаскадная шина. Вот она на resource property editor (есть и в первом посте, но ниже более подробно):

    Скрытый текст

    Screenshot_10.thumb.png.5dc47ce4d6e87910fa2b5d4e98c68354.pngScreenshot_11.png.d55d2c243f354aa7f2cd206d7820d04e.png

    В первом посте есть картинка из Technology map viewer, привожу её ещё раз, чтобы туда не прокручивать:

    Скрытый текст

    Screenshot_7.png.4f9a59c4e5461ccff7e4bbeb289c7b12.png

    И на этой картинке видно, что операнды 25 и 16 бит, а результат 22 бита (лишние биты не используются, отрезаны). Для таких разрядностей всё должно влезать в один DSP-блок, без каскадирования. И главное на этой же картинке не показано наличие этой межкаскадной шины. И я даже не понимаю, где и как глянуть, куда всё же она потом идёт с выхода DSP-блока.

  17. 12 часов назад, new123 сказал:

    На работе ваша ссылка открыталсь (до этого смотрел из дома, а на работе хитрый прокси есть для обхода). Я посмотрел оглавление документа и понял, что это всё про синплифай синопсис. Или для квартус прайм тоже годится?

    Скрытый текст

    Screenshot_9.thumb.png.8b62e668c3658dcc12f517baca9122c8.png

     

    7 часов назад, new123 сказал:

    Вы только имейте ввиду, что dsp расположены же в определенных местах, это надо цепи туда довести, потом от туда забрать. Это хорошо, если чип пустой и можно пихать логику куда хочешь, а если подзабит, то можно и по времянке не пролезть

    У меня с чего всё началось: после компиляции прошивки моего чудо-девайса вылезли слаки. Я начал разбираться, понял, что регистр, который подразумевался внутри DSP-блока, был размещён снаружи по непонятной мне причине. Вот это и есть причина слака. Вот если регистр всё же заставить упихаться, тогда и посмотрим, "в определённых местах" или не в определённых местах. А пока до этого ещё не дошли, это так сказать величина второго порядка малости )

  18. 37 минут назад, new123 сказал:

    у вас мануал от Quartus II, но насколько помню под пятерку можно уже и Prime, если вдруг вы его поставили, то по мануалу там чуть другой параметр.

    Да, Прайм, спасибо за уточнение и помощь с параметром! Я думал всё одинаково с квартусом 2, это от недостатка опыта.

    37 минут назад, new123 сказал:

    Если сайт не открывается

    И ведь точно, не открылось, написало про  санкции, спасибо, что предусмотрительно скинули скрины!

    Меня смущает вот это:

    Screenshot_20220524-223247_Opera.thumb.jpg.4f7ed437c1e67ee074e7ec6cb50a29ff.jpg

    Т.е. применяется к цепям, но не к регистрам. А мне то надо заставить регистр упихаться в DSP блок.

    Я тут подумал... Не может ли виной быть, что задействована межкаскажная шина? Хотя по идее должно и с ней регистр ставить

  19. Здравствуйте. С Альтерой у меня опыта нет, поэтому вопрос возможно простой. Плисина Ария 5. Не получается синтезатору запихать выходной регистр внутрь DSP-блока.

    Вот так это описано:

    	process(clk)
    	begin
    		if rising_edge(clk) then
    			dta_c3_re_r <= coef3_reg_re_pp * deg2_mult_r_reg_pp;
    		end if;
    	end process;

    Предполагается, что регистр dta_c3_re_r будет внутри DSP-блока. Но он снаружи. Я даже атрибут нашёл вот тут и приделал его к описанию регистра:

        signal dta_c3_re_r : signed(2*wide_data_g-pre_dsp_cut_c+16 downto 0) := (others => '0');
        attribute multstyle : string;
        attribute multstyle of dta_c3_re_r : signal is "dsp";

    Но это не помогает.

    Выглядит это вот так на technology map:

    Скрытый текст

    Screenshot_7.png.4f9a59c4e5461ccff7e4bbeb289c7b12.png

    И вот так на resource property editor:

    Скрытый текст

    Screenshot_8.thumb.png.25bf5e3ae64e4f7bf0853d02da376551.png

     

  20. 1 минуту назад, Maverick_ сказал:

    спасибо

    Ну что вы, не за что, я отсюда столько опыта за всё своё время регистрации здесь вывез, что грузовика не хватит, так что надо по-маленьку возвращать долги ))

  21. спасибо за ссылку! Там правда симулинк, не голый матлаб, мож кто в симулинке не работает по каким-то причинам... А так - да, получается куда быстрее. Но в целом один раз это пройти, будет некий шаблон, который можно будет очень быстро корректировать под любую следующую косимуляцию. Долгая писанина - это с начала, шаблон создать. Да и вообще путь пройти, как это должно правильно быть написано. А последующие разы - по накатанной.

  22. Выложу здесь инструкцию по косимуляции в матлабе (оно же может называться Matlab Cosimulation, Matlab Link for Modelsim). Это когда из матлаба запускается HDL код в симуляторе, входные и выходные данные передаются напрямую между симулятором и матлабом без использования промежуточных текстовых файлов (как это обычно было принято). Инструкция скорее для себя, чтобы не забыть. И может ещё кому-то полезно будет, чтобы с нуля не ходить по граблям.

    Косимуляция бывает как минимум двух видов:

    1. Когда все тестовые воздействия генерятся в тестбенче симулятора, потом вход и выход симулятора передаются в малтаб, где подаются на матлаб-функцию модели HDL-кода для сравнения. В результате выдаётся вердикт: совпало или не совпало в симуляторе и в матлабе.
    2. Когда пользователь в матлабе генерит тестовые воздействия, они передаются в симулятор, а результаты с выхода HDL-кода принимаются обратно в матлаб для анализа.


    Для моих работ мне больше подошёл последний вариант, поскольку при отладке DSP генерация сложного сигнала в матлабе проще, чем в симуляторе. Как и анализ результатов работы HDL-кода в матлабе проще, поскольку можно нанести несколько графиков на один рисунок, построить преобразование Фурье или другие функции. К тому же, как потом выяснилось, при таком способе возможно задавать не только воздействия на входные порты, но и переопределять любые внутренние сигналы (как делается drive в тестбенче). А также можно вычитывать в матлаб любые внутренние сигналы для анализа и отладки.

    Для косимуляции требуется определённая версия матлаба и симулятора. Для Matlab R2021b требуется Modelsim SE 2020.4. Однако в такой версии моделсима у меня почему-то не получилось, и я перешёл на QuestaSim 2021.1, в такой связке у меня работает нормально. Правда выдаёт warning, что несовместимые версии, но его можно отключить, просто подправив код выдачи ворнинга, номер строки указывается в самом ворнинге.

    Вообще за пример была взята эта страница:
    https://www.mathworks.com/help/hdlverifier/ug/verify-viterbi-decoder-using-matlab-system-object-and-hdl-simulator.html
    Там справа сверху есть команда для запуска примера в матлабе:
    openExample('hdlverifier/VerifyViterbiDecoderUsingSystemObjectAndHDLSimulatorExample')
    Можно открыть, поизучать, попробовать запустить. Нужно будет установить правильный тип симулятора, там сверху константы задаются. Также возможно потребуется увеличить таймаут на запуск симулятора, т.к. со штатным таймаутом почему-то не вышло.

    Краткое пояснение основных шагов, необходимых для создания косимуляции:

    1. В коде матлаб вставляем примерно такую конструкцию (исправляем её под себя):

    hDec = hdlcosim('InputSignals', {'/viterbi_block/In1','/viterbi_block/In2','/viterbi_block/Traceback_out1'}, ...
                    'OutputSignals', {'/viterbi_block/Out1', '/viterbi_block/Delay5_out1'}, ...
                    'OutputSigned', false, ...
                    'OutputFractionLengths', 0, ...                   
                    'TCLPostSimulationCommand', 'echo "done";', ...
                    'PreRunTime', {10,'ns'}, ...
                    'Connection', {'Shared'}, ...
                    'SampleTime', {10,'ns'});


    Пока эта команда просто создаёт объект с параметрами. Здесь задаём входые и выходные сигналы. При том, как было сказано выше, можно задавать не только воздействия на входные порты, но и переопределять любые внутренние сигналы (как делается drive в тестбенче). А также можно вычитывать в матлаб любые внутренние сигналы для анализа и отладки.
    Также нужно обратить внимание на PreRunTime и SampleTime и правильно задать их значения:
    PreRunTime - это время предварительного выполнения симуляции для установления всех переходных процессов, требуемых перед основной симуляцией. Например это может быть длительность сигнала сброса или задержка появления сигнала на выходе (связана с Latency вашего HDL кода). Более подробно про предварительное выполнение будет понятно ниже.
    SampleTime - это периодичность выборок данных (обмена данными) между матлабом и симулятором. Наиболее вероятно это будет совпадать с периодом вашей тактовой частоты clk, ведь данные у вас будут меняться каждый клок. Если у вас несколько кратных частот, то видимо придётся взять самую высокую и на ней обмениваться с матлабом. Если несколько частот некратных, то наверное данная косимуляция вообще не подойдёт, т.к. выборки будет в непредсказуемые моменты времени. Хотя... можно и сам клок ещё вытаскивать в матлаб на утроенной или упятерённой частоте, а потом определять в нём интервал неизменного состояния, для которого фиксировать данные. Короче уже извраты пошли.
    Ну и может кому-то будет интересно поправить TCLPostSimulationCommand, это строка с TCL-скриптом, который будет выполнен по окончании симуляции.
    Параметр Connection задаёт способ соединения с симулятором: есть через разделяемую память, а есть через сокет TCP/IP. Сами матлабохелпописатели продвигают вариант через сокет, типа крутой и многофункциональный. Но я решил оставить через память как простой, без единой настройки.

    2. Далее вставляем примерно такую конструкцию (и тоже правим под себя):

    hDec.TCLPreSimulationCommand = ...
        'force /viterbi_block/clk_enable 1 0; force /viterbi_block/clk 0 0 ns, 1 5 ns -repeat 10 ns; force /viterbi_block/reset 1 0 ns, 0 8 ns; ';

    Здесь описывается обычный TCL скрипт, который, вобщем-то, и будет являться нашим тестбенчем, т.е. он сработает в момент начала симуляции. Как мы видим тут переопределяется поведение клока и сброса. Тут наверное всё понятно, как исправить под себя.

    3. Далее вставляем такую конструкцию (в вышеупомянутом примере это довольно запутано, но вместо кучи вложенных функций и переменных можно написать всё самому плоским текстом при желании):

    vsim('tclstart',viterbi_cosimulation_tclcmds('vsimmatlabsysobj'));

    где второй аргумент - это функция (её имя можно исправить на подходящее по смыслу под ваш проект), которую пользователь сам должен под себя написать примерно так:

    function tclCmds = viterbi_cosimulation_tclcmds(loadCmd)
    srcDir   = './viterbi_hdlsrc';
    % VHDL source files
    srcFiles = {...
        'viterbi_block_pkg.vhd',... '
        'ACS0.vhd'};
    compile_cmds = strcat({'vcom  "'}, {srcDir}, '/', srcFiles,'"');
    tclCmds = [{'vlib work'}, ...
               compile_cmds, ...
               [loadCmd '  viterbi_block -voptargs=+acc=lprn'], ...
               'do wave.do', ...
               'puts "Ready for cosimulation ..."'];


    Тут командой vsim() вызывается симулятор, в котором должен выполниться стартовый tcl-скрипт. Но это не тот стартовый скрипт, что упоминался выше. Выше там именно типа тестбенч, выполняемый во время самой симуляции, в самом её начале. А тут предполагается, что стартовый скрипт - это просто компиляция исходников. Т.е. tclCmds - это просто строка, в которую записаны обычные команды скрипта TCL, которые бы вы сами написали, чтобы скомпилировать ваши исходники.
    Может кому-то будет полезна ещё информация, как сделать самому тестбенч. У кого опыта выше крыши - тот может сам всё написать как ему надо. Но если опыта недостаточно, можно подсмотреть, как тестбенч делает Vivado, ведь в вивадо есть встроенный инструмент для запуска симуляции в моделсиме.

    Скрытый текст

    Для начала нужно скомпилировать библиотеки через меню Tools - Compile Simulation Libraries. Сверху выбираем Simulator моделсим или квесту, чуть ниже семейство ПЛИС, под которые мы хотим библиотеки. Можно выбрать все возможные, но бывает нет времени ждать компиляцию всех, тогда можно выбрать только какое-то конкретное семейство. Чуть ниже выбираем путь, куда будут помещены скомпилированные библиотеки: Compiled library location. Внимание! Нужно сразу хорошо подумать и выбрать правильное расположение папки, т.к. потом будут сложности при её переносе, поскольку абсолютные пути будут прописаны в файл modelsim.ini, помещаемый в эту же папку, а этот файл будет при вызове симуляции подменять собой стандартный файл modelsim.ini. После компиляции библиотек мы заходим в меню Flow - Simulation Settings. Выбираем Target simulator как моделсим или квесту (в соответствии с тем, что у нас установлено), а чуть ниже задаём путь Compiled library location, это как раз сюда нужно прописать ту папку, куда у нас были ранее скомпилированы библиотеки. Далее нужно вызывать команду меню Flow - Run Simulation - Run Behavioral Simulation. После этого будут подготовлены все необходимые скрипты для компиляции и симуляции и будет запущена симуляция. После этого переходим в папку, где расположен ваш вивадовский проект, а далее в подпапку <название вашего вивадовского проекта>.sim\sim_1\behav\ . В этой папке можно подсмореть, как делается тестбенч, какими командами что запускается, и сделать по образу и подобию под себя.


    Нужно обратить внимание в куске кода выше на строку

    do wave.do


    Её не было в вышеупомянутом примере, её приписал я сам для своих нужд. А нужды такие, чтобы мочь отлаживать что-то по осциллограммам в самом симуляторе, как мы это обычно делаем, если пользуемся только самим симулятором, без матлаба. Можно этот файл пока оставить пустым, если вам не нужны осциллограммы. А потом в него можно будет что-то дописать. Допустим мы выполнили косимуляцию, у нас плохой результат, нам надо подебажить внутренности по осциллограммам в симуляторе. Окно симулятора мы не закрываем по окончании косимуляции. Переходим в симулятор и мышкой или ещё как вытаскиваем нужные нам сигналы на окно waveform. Затем это окно с сигналами сохраняем в файл в wave.do просто командой сохранить. И вот тогда указанная выше строчка do wave.do при каждой косимуляции будет открывать нам окно с нужными нам сигналами и на них будут осциллограммы.

    Также обращу внимание на запись

    -voptargs=+acc=lprn

    Её тоже не было в вышеупомянутом примере, её я дописал для своих нужд. Эта запись позволила получить видимость всех сигналов, чтобы их можно было подключить в косимуляции. Для вышеупомянутого примера это не требуется, но когда будете писать на его основе свою косимуляцию, то может так получиться, что в результате оптимизации не видно тех сигналов, с которыми требуется связаться из матлаба. Понятно, что это отключение оптимизации приведёт к тормозам, и нужно быть аккуратным с этим.
    Подсказку по такой записи нашёл здесь:
    https://stackoverflow.com/questions/24179095/modelsim-optimization-issue

    Цитата

    "While optimization is not necessary for class based debugging, you might want to use
    vsim -voptargs=+acc=lprn to enable visibility into your design for RTL debugging."

    Ну и кроме того, во время выполнения команды vsim на данном шаге происходит подключение между матлабом и симулятором. По команде vsim выполняется не просто целиком скрипт, указанный в аргументе tclCmds, а генерируется более расширенный скрипт compile_and_launch.tcl (его можно будет увидеть в вашей рабочей папке, где выполняется симулятор), в который tclCmds входит как конечная часть. А вот начальная часть, как раз, описывает подключение между матлабом и симулятором. И выглядит это примерно следующим образом:

    proc vsimmatlabsysobj {args} {
      lappend sllibarg -foreign \{matlabsysobjserver \{D:/Program Files/MATLAB/R2021b/toolbox/edalink/extensions/modelsim/windows64/liblfmhdls_gcc450vc12.dll\}
      if {[catch {lsearch -exact $args -socket} idx]==0  && $idx >= 0} {
        set socket [lindex $args [expr {$idx + 1}]]
        set args [lreplace $args $idx [expr {$idx + 1}]]
        append socketarg " \; -socket " "$socket"
        lappend sllibarg $socketarg
      }
      set runmode "GUI"
      if { $runmode == "Batch" || $runmode == "Batch with Xterm"} {
        lappend sllibarg " \; -batch"
      }
      lappend sllibarg \}
      set args [linsert $args 0 vsim]
      lappend args [join $sllibarg]
      uplevel 1 [join $args]
    }


    Заметьте: ключевое слово vsimmatlabsysobj уже фигурировало выше, и можно проследить взаимосвязь этих кусков кода.

    4. Далее в код нужно добавить такие строчки:

    Timeout=90;
    processid = pingHdlSim(Timeout);
    % Check if HDL simulator is ready for Cosimulation.
    assert(ischar(processid),['Timeout: HDL simulator took more than ', num2str(Timeout),' seconds to setup,please increase the timeout in ''pingHdlSim''']);
    disp('...Simulator is ready for cosimulation.');


    Эта секция приостанавливает на этом месте дальнейшее выполнение скрипта, пока симулятор не отработает предыдущее. Чтобы выполнение матлаба и симулятора было синхронизировано на нужных стадиях. Таймаут задаёт время ожидания ответа. Можно отрегулировать. Изначально в вышеупомянутом примере было 30с, но на моём компе не хватало, я увеличил.

    5. Ну и самый главный пункт - основная симуляция. Описывается примерно такой строчкой:

    [receivedBits, ttt]    = step(hDec,input1, input2, input3);

    Т.е. указываем входные и выходные переменные. При том, как было сказано выше, возможно задавать не только воздействия на входные порты, но и переопределять любые внутренние сигналы (как делается drive в тестбенче). А также можно вычитывать в матлаб любые внутренние сигналы для анализа и отладки. Эти сигналы должны быть определены согласно п.1. Входные переменные могут быть скалярами или векторами одинаковой размерности. Каждый следующий элемент вектора подставляется в симулятор на каждом следующем периоде времени, указанном в параметре SampleTime в п.1. Метод step можно вызывать не обязательно однократно, а сколько угодно раз (в цикле например, как в вышеупомянутом примере), пока не закончатся входные данные.
    Вместо

    step(hDec,input1, input2, input3);


    можно вызывать

    hDec(input1, input2, input3);

    Вот тут этому объяснение:
    https://www.mathworks.com/help/matlab/ref/step.html

    Цитата

    "Starting in R2016b, instead of using the step method to perform the operation defined by the System object, you can call the object with arguments, as if it were a function. For example, y = step(obj,x) and y = obj(x) perform equivalent operations."


    6. По окончании симуляции нужно дать следующую команду:

    clear hDec;


    Это удалит объект, связанный с симулятором, и разблокирует симулятор для возможности управления им мышкой пользователем (до этого момента симулятор остаётся заблокирован, и ничего с ним сделать пользователю нельзя). После разблокировки пользователь может подебажить в симуляторе обычным образом, по вэйвформам, которые были добавлены командой do wave.do в п.3.
    Если на вэйвформах не хватает каких-то сигналов, то мышкой или ещё как вытаскиваем нужные нам сигналы на окно waveform. Затем это окно с сигналами сохраняем в файл в wave.do просто командой сохранить. Затем косимуляцию нужно перезапустить с начала, т.е. с п.1.

    На этом всё.

    Приведу дополнительные ссылки почитать для общей информации, может, будет полезно:
    https://www.mathworks.com/help/releases/R2021b/hdlverifier/ref/matlabcp.html
    https://www.mathworks.com/help/releases/R2021b/hdlverifier/ug/verify-raised-cosine-filter-design-using-matlab.html
    https://www.mathworks.com/help/releases/R2021b/hdlverifier/ug/import-hdl-code-for-matlab-function.html#btx017h-19
    https://www.mathworks.com/help/hdlverifier/ref/hdldaemon.html
    https://www.mathworks.com/help/hdlverifier/ug/verify-hdl-model-with-matlab-testbench.html
    https://www.mathworks.com/help/hdlverifier/ug/startup-for-hdl-cosimulation.html?s_tid=srchtitle_startup-for-hdl-cosimulation_1
    https://docs.exponenta.ru/hdlverifier/ug/startup-for-hdl-cosimulation.html#bt9u4xl-3
    https://docs.exponenta.ru/hdlverifier/ug/verify-hdl-model-with-matlab-testbench.html#bt9obpv-71
    https://www.mathworks.com/help/hdlverifier/ref/vsim.html
    https://www.embedders.org/content/sovmestnoe-modelirovanie-proektov-v-modelsim-qusestasim-i-simulink
    https://exponenta.ru/hdl-verifier
    https://www.mathworks.com/help/hdlverifier/ug/getting-started-with-matlab-based-systemverilog-dpi-component-generation.html
    https://www.mathworks.com/help/releases/R2021b/hdlverifier/gs/supported-eda-tools.html
    https://www.mathworks.com/help/hdlverifier/ug/verify-hdl-model-with-simulink-test-bench.html
    https://www.edaboard.com/threads/matlab-and-modelsim-cosimulation.229534/
    https://people.ece.cornell.edu/land/courses/eceprojectsland/STUDENTPROJ/2009to2010/mal283/Simulink_ModelSim_Tutorial.pdf

  23. 10 часов назад, AnatolySh сказал:

    Вот этот файл cmul14x16.vhd обязательно было в vhdl выводить?

    вы думаете это я? Да у меня самого от вхдл глаз дёргается. В настройках проекта при генерации указан целевой язык верилог. И знаете как это понимает вивада? Что нужно обёртку на верилоге сделать. А все внутренности можно продолжать делать на её любимом вхдле.

    Хуже того, я сталкивался с тем, что во встроенном симуляторе ISE ISim если сгенерить корку под верилог, то не так симулится или вообще подвисает (уже не помню), а вот если под вхдл сгенерить - то симулится норм.

  24. 02.05.2022 в 12:25, AnatolySh сказал:

    Вы можете минимизировать Ваш проект настолько, чтобы Ваш путь можно было бы повторить,

    я минимизировал проект, чтобы можно было повторить )) glbl можно было выкинуть, можно было не выкидывать, на повторение это не влияло, т.е. формально я ТЗ не нарушил )

    Я сейчас glbl закоментарил, т.е. его нет получается. А ошибка так и вываливается. Так что думаю если вы закоментарите у себя, то ничего не изменится, просто вам будет спокойнее, что ничего лишнего в проекте нет.

×
×
  • Create New...