2013-09-22 2 views
0

VHDL, используя функции для генерации Заявления оVHDL, используя функции для генерации отчетности

У меня есть компонент, который должен быть инстанцированным около 8000 раз, я использовал для генерировать заявление с помощью некоторых постоянных значений для уменьшения количество кода, но мне пришлось объявить функцию для параметризации соединений компонентов.

Моя функция выглядит следующим образом:

function dim1_calc (
     cmp_index : integer; 
     prt_index : integer 
    ) return integer is 
     variable updw : integer := 0; 
     variable shft_v : integer := 0; 
     variable result : integer := 0; 
    begin 

     if (cmp_index < max_up) then 
     updw := 1; 
     else 
     updw := 2; 
     end if; 

     case prt_index is 
     when 1 => 
      shft_v := cnst_rom(updw)(1) + (i-1); 
     when 2 => 
      shft_v := cnst_rom(updw)(2) + (i); 
      -- 
      -- 
      -- 
     when 32 => 
      shft_v := cnst_rom(updw)(32) + (i); 
     when others => 
      shft_v := 0; 
     end case; 

     if (updw = 1) then 
     if (shft_v = min_up & ((prt_index mod 2) = 0)) then 
      result <= max_up; 
     elsif (shft_v = max_up & ((prt_index mod 2) = 1)) then 
      result <= min_up; 
     elsif (shft_v < max_up) then 
      result <= shft_v; 
     else 
      result <= shft_v - max_up; 
     end if; 
     else 
     --something like first condition statements... 
     -- 
     -- 
     end if; 


     return result; 

    end function; 

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

--these type definitions are in my package 
     type  nx_bits_at is array (natural range <>) of std_logic_vector (bits-1 downto 0); 
     type  mxn_bits_at is array (natural range <>) of nx_bits_at; 
    -- 
    -- 
    -- 
     component pn_cmpn is 
     port(
      clk  : in std_logic; 
      bn_to_pn : in nx_bits_at(1 to row_wght); 
      pn_to_bn : out nx_bits_at(1 to row_wght) 
     ); 
     end component; 
     -- 
     -- 
     -- 
     signal v2c : mxn_bits_at(1 to bn_num)(1 to col_wght); 
     signal c2v : mxn_bits_at(1 to pn_num)(1 to row_wght); 
     -- 
     -- 
     -- 
     gen_pn : for i in (1 to pn_num) generate 

     ins_pn : pn_cmpn port map (
     clk   => clk, 
     bn_to_pn(1) => b2p (dim1_calc(i, 1)) (dim2_calc(i, 1)), 
     bn_to_pn(2) => b2p (dim1_calc(i, 2)) (dim2_calc(i, 2)), 
     . 
     . 
     . 
     bn_to_pn(32) => b2p (dim1_calc(i, 32)) (dim2_calc(i, 32)), 
     pn_to_bn  => p2b (i) 
     ); 

     end generate; 

Я знаю, что использование слишком много последовательных заявлений вместе вообще не подходит, и я избегаю их как можно больше, но в этом случае я предположил, что эта функция не будет синтезироваться в какое-то реальное оборудование, а синтезатор просто вычисляет выходное значение и помещает его в соответствующие экземпляры что compone нт. Я прав? или этот способ кодирования приводит к дополнительным аппаратным средствам по сравнению с всего 8000 экземпляров.

PS1: Первоначально я использовал «0 ...» для определения диапазонов второго и третьего измерений моих массивов, но из-за путаницы, которые были сделаны в функции вычисления размера, основанной на параметре оператора for-generate, я заменил их с «1 до ...». Это нормально! стиль кодирования или я должен избегать этого?

PS2: Есть ли способ, что отображение портов часть в коде выше сочетает в чем-то вроде этого: (я знаю, что это сильно неправильно, это просто уточнение того, что я хочу)

 gen_pn : for i in (1 to pn_num) generate 

     ins_pn : pn_cmpn port map (
     clk   => clk, 

     gen_bn_to_pn : for j in (1 to 32) generate 
      bn_to_pn(j) => b2p (dim1_calc(i, j)) (dim2_calc(i, j)), 
     end generate; 

     pn_to_bn  => p2b (i) 
     ); 

     end generate; 

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

ins_test : test_comp port map (
     clk   => clk, 
     test_port(1) => test_sig(2) 
     test_port(2) => test_sig(3) 
     test_port(3) => test_sig(4) 
     ); 

есть ли способ, что я могу использовать для генерации здесь? что-то вроде:

ins_test : test_comp port map (
     clk   => clk, 
     gen_pn : for i in (1 to 3) generate 
      test_port(i) => test_sig(i+1) 
     end generate; 
     ); 

PS3: Можно ли вызвать функцию внутри другой функции в VHDL?

ответ

2

Функции могут использоваться таким образом. Если у вас возникнут проблемы, я уверен, что они будут рассматривать детали в средствах дизайна или дизайна, а не в базовом подходе.

Одна из потенциальных проблем заключается в том, что функция относится к некоторым внешним «вещам», таким как max_up, i, cnst_rom, чьи объявления не являются частью функции или параметров для нее. Это делает его «нечистой функцией», которая, поскольку она относится к внешнему состоянию или даже модифицирует его, имеет ограничения на его вызов (поскольку внешнее состояние может измениться, результаты могут зависеть от порядка оценки и т. Д.).

Если вы можете сделать это чистым, сделайте это. У меня такое чувство, что max_up, cnst_rom являются константами: если они не используются в другом месте, объявите их локальными для функции. И i, вероятно, должен быть параметром.

Если это невозможно, сделайте константы внешних деклараций и, предпочтительно, оберните их и функцию вместе в пакете.

Это просто генерирует нужные значения в небольшой, понятной, поддерживаемой форме, а не в бесконечном объеме аппаратного обеспечения.Я использовал сложное гнездо функций, выполняющих арифметику с плавающей запятой, а затем уменьшающе ограниченное числовое округление и целочисленное округление для инициализации таблицы поиска, так что в принципе подход работает.

Потенциал ловушкой:

Некоторые дизайнерские инструменты имеют проблемы с совершенно действительным VHDL, если его использование немного неортодоксальные. Synplicity не может синтезировать некоторые формы функции (которые производят аппаратное обеспечение), хотя не имеет проблем с эквивалентной процедурой, возвращающей результат через параметр OUT !. XST значительно лучше.

XST синтаксический анализ таблицы поиска init имеет абсурдное замедление, квадратное число вызовов функций. Но только если вы используете старый парсер VHDL (по умолчанию для Spartan-3). Spartan-6 использует новый синтаксический анализатор и отлично работает (под вторым, а не через полчаса!), Как и у Modelsim и Isim. (не пробовал Synplicity в этом проекте)

Некоторые инструменты предназначены для неортодоксальных вещей в картах портов: вы можете избежать вызовов функций там; или вам может понадобиться обходные ошибки инструмента, инициализируя константы вызовами и используя эти константы в картах портов.

И ваши дополнительные вопросы:

PS1) Правильный стиль кодирования для диапазона массива является ... все, что делает ваше намерение ясно. Если вы обнаружите, что мысленно компенсируете 1, и получаете путаницу или даже делаете ошибки, STOP! и улучшить дизайн.

Некоторые хорошие стили индексации массива:

type colour is (red, green, blue); 
subtype brightness is natural range 0 to 255; 

hue : array (colour) of brightness; 
gamma : array (brightness) of brightness; 
-- here 0 is a legitimate value 
channel : array (1 to 99) of frequency; 

PS2) Я думаю, что вы спрашиваете, если вы можете гнездятся генерировать отчеты. Да.

Информация может быть неудобной и сложной, но да.

PS3) Да, конечно! Вы можете даже объявлять функции локальными для других; исключая возможность их случайного вызова где-то, они не имеют никакого смысла. Они (нечистые функции) могут получить доступ к области выполнения внешней функции (или процесса), упрощая списки параметров.

+0

Спасибо за ваш ответ. Ваше чувство о max_up, cnst_rom и i было правильным, и я сделаю свою функцию чистой. Мой синтезатор - XST, а моя FPGA - virtex-5, так что тогда это будет хорошо. О стилях индексирования массива: Спасибо, это было облегчением :) И да, я спрашивал о вложенных операциях сгенерированных. Но это особый случай, и, видимо, я не объяснил это хорошо. Я добавил еще один пример для разъяснения. –

0
Q1 - in this case I assumed that this function won't synthesize into some ... 

Это зависит от того, какой синтезатор вы используете. См. this соответствующие вопросы и комментарии ниже.


Q2 - PS1: Initially I used "0 to..." for defining ranges of the ... 

Конечно, это нормально. И, пожалуйста, позвольте нам опубликовать здесь предложение о стиле кодирования. (от this book)
При определении спецификации параметра цикла используйте определение типа (или подтипа) или используйте предопределенные атрибуты объекта (например, PredefinedObject'range, PredefinedObject'length - 1 downto 0). Избегайте использования дискретного диапазона (например, от 1 до 4).
Это правило делает код более многоразовым и гибким для обслуживания.


Q3 - PS2: Is there a way that port mapping part in above code combines into ... 

Я думаю, именно поэтому вы задали 4-й вопрос. Так что обратитесь к следующему ответу :).


Q4 - Is it possible to call a function inside another function in VHDL? 

Хотя я не могу найти официальную ссылку на это, ответ да.

PS: Правила кодирования определяются инструментами синтезатора. Поэтому лучший способ найти ответ - попробовать самому.

+0

Спасибо за ваш ответ и ссылки, конечно. Мой синтезатор XST, к счастью, проблем не будет. Я не знал, что мои последние два вопроса были связаны! поэтому, пожалуйста, дайте мне знать, как я могу использовать функции для своей цели. И о вашем PS: я буду помнить об этом и делать это чаще. –

Смежные вопросы