VHDL Место и анализ пути маршрута

моя проблема в том, что когда я реализую свой проект с помощью Xilinx ISE 14.7 + XPS, я часто получаю очень разное количество проанализированных путей при статическом анализе времени, а также очень мало различий в файлах .vhd. В частности, единственный файл, который я меняю (или который я думаю изменить...), выглядит примерно так:

entity my_entity is(
    ...
    data_in : in std_logic_vector(N*B-1 downto 0);
    ...
);
end entity my_entity;

architecture bhv of my_entity is
    signal data : std_logic_vector(B-1 downto 0);
    signal idx_vect : std_logic_vector(log2(N)-1 downto 0);
    signal idx : integer range 0 to N-1;
    ...
begin
    process(clk)
    begin
        if(rising_edge(clk))then
            idx_vect <= idx_vect + 1;
        end if;
    end process;

    idx <= to_integer(unsigned(idx_vect));

    data <= data_in((idx+1)*B-1 downto idx*B);

end architecture bhv;

Я не уверен, что проблема исходит отсюда, но я не нахожу другой возможной причины пятикратного уменьшения количества проанализированных путей. Есть ли какой-то синтаксис, которого следует избегать, чтобы получить правильную реализацию? Возможно ли, что индексация массива с использованием целого числа (как в примере кодека) каким-то образом разбивает пути, делая их не анализируемыми?

Изменение кода выглядит примерно так:

process(shift_reg, data_in)
    for i in range 0 to N-1 loop
        if(shift_reg(i) = '1')then
            data <= data_in((i+1)*B-1 downto i*B);
        end if;
    end loop;
end process;

в котором вместо инкремента idx_vect у меня есть циклический однократный регистр сдвига из N бит. Заранее спасибо.


person arandomuser    schedule 30.11.2015    source источник
comment
Что вы на самом деле изменили в этом коде? Анализатор времени сообщает номер проанализированного пути для каждого временного ограничения. Какой из них вы имеете в виду здесь? Код синтезируется, как и ожидалось, пока XST не выдает (вредных) предупреждений.   -  person Martin Zabel    schedule 01.12.2015
comment
Изменения касаются того, как я индексирую массив, кажется, что когда я не использую целое число (но, например, цикл for для проверки условия, поэтому прямой индексации нет), количество анализируемых путей увеличивается. Никаких предупреждений XST не выдает. Вероятно, проблема где-то в другом, но я просто хочу иметь подтверждение того, что синтаксис правильный и что известных проблем нет...   -  person arandomuser    schedule 01.12.2015
comment
Пожалуйста, отредактируйте свой вопрос и добавьте for loop. Синтаксис правильный, если он принимается XST без ошибок. Семантика верна, если симуляция показывает желаемый результат, а XST не выдает предупреждений. Вы не ответили на мой второй вопрос. Ответ важен для меня, чтобы, вероятно, решить ваш вопрос.   -  person Martin Zabel    schedule 01.12.2015
comment
Спасибо @MartinZabel. Ограничение является производным ограничением, созданным XPS. Мое ограничение периода относится к P-стороне дифференциальных часов, привязанных к определенному контакту и входящих в генератор тактовых импульсов, который распространяется на некоторые новые производные ограничения (которые выглядят правильно для меня, за исключением сильно изменчивого количества анализируемых путей одного из них). , тот, который я использую почти во всех своих проектах).   -  person arandomuser    schedule 01.12.2015
comment
Если (из-за ошибки кодирования, такой как пропуск соединения результата с выходами) большую часть вашего оборудования можно оптимизировать, анализировать будет нечего. Стоит проверить сводный отчет на наличие более урезанных логических отчетов, чем раньше, или подозрительного сокращения использования LUT/FF.   -  person user_1818839    schedule 01.12.2015
comment
@BrianDrummond Я подозреваю что-то подобное, но мое оборудование работает какое-то время, а затем выдает случайную ошибку в случайное время ... если некоторые выходы не подключены, я полагаю, что все не будет работать вообще.   -  person arandomuser    schedule 01.12.2015


Ответы (1)


Стиль кодирования мультиплексора на этой линии

data <= data_in((idx+1)*B-1 downto idx*B);

может сильно повлиять на логический синтез. Это приводит к очень различному количеству путей для анализа времени.

Оригинальный мультиплексор.

Сначала я проверил синтез приведенной выше строки на этом небольшом примере:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity mux1 is
    generic (
        B : positive := 32;
        M : positive := 7); -- M := ceil(log_2 N)
    port (
        d : in  STD_LOGIC_VECTOR ((2**M)*B-1 downto 0); -- input data
        s : in  STD_LOGIC_VECTOR (M-1 downto 0);        -- selector
        y : out  STD_LOGIC_VECTOR(B-1 downto 0));       -- result
end mux1;

architecture Behavioral of mux1 is
    constant N : positive := 2**M;
    signal idx : integer range 0 to N-1;
begin
    idx <= to_integer(unsigned(s));
    y <= d((idx+1)*B-1 downto idx*B);
end Behavioral;

Если кто-то синтезирует это для Spartan-6, XST сообщает об этом (отрывок):

Macro Statistics
# Adders/Subtractors                                   : 2
 13-bit subtractor                                     : 1
 8-bit adder                                           : 1
...
 Number of Slice LUTs:                 1516  out of   5720    26%  
...
Timing constraint: Default path analysis
  Total number of paths / destination ports: 139264 / 32

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

Оптимизированная реализация

Такого же мультиплексирования можно добиться с помощью: (EDIT: исправление ошибки и упрощение)

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity mux2 is
    generic (
        B : positive := 32;
        M : positive := 7); -- M := ceil(log_2 N)
    port (
        d : in  STD_LOGIC_VECTOR ((2**M)*B-1 downto 0);
        s : in  STD_LOGIC_VECTOR (M-1 downto 0);
        y : out  STD_LOGIC_VECTOR(B-1 downto 0));
end mux2;

-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-- !! The entire architecture has been FIXED and simplified. !!
-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
architecture Behavioral of mux2 is
    constant N : positive := 2**M;
    type matrix is array (N-1 downto 0) of std_logic_vector(B-1 downto 0);
    signal dd : matrix;
begin
    -- reinterpret 1D vector 'd' as 2D matrix, i.e.
    -- row 0 holds d(B-1 downto 0) which is selected in case s = 0
    row_loop: for row in 0 to N-1 generate
        dd(row) <= d((row+1)*B-1 downto row*B);
    end generate;

    -- select the requested row
    y <= dd(to_integer(unsigned(s)));
end Behavioral;

Теперь отчет XST выглядит намного лучше:

Macro Statistics
# Multiplexers                                         : 1
 32-bit 128-to-1 multiplexer                           : 1
...
 Number of Slice LUTs:                 1344  out of   5720    23%  
...
Timing constraint: Default path analysis
  Total number of paths / destination ports: 6816 / 32

Он обнаруживает, что для каждого выходного бита требуется мультиплексор 128-к-1. Оптимизированный синтез такого широкого мультиплексора встроен в инструмент синтеза. Количество LUT уменьшилось лишь незначительно. Но количество путей, которые должны быть обработаны временным анализатором, резко сокращается в 20 раз!

Реализация с использованием одного горячего селектора

В приведенных выше примерах используется селекторный сигнал с двоичным кодированием. Я проверил также вариант с одним горячим кодированием:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity mux3 is
    generic (
        B : positive := 32;
        N : positive := 128);
    port ( d : in  STD_LOGIC_VECTOR (N*B-1 downto 0);
           s : in  STD_LOGIC_VECTOR (N-1 downto 0);
           y : out  STD_LOGIC_VECTOR(B-1 downto 0));
end mux3;

architecture Behavioral of mux3 is

begin
    process(d, s)
    begin
        y <= (others => '0'); -- avoid latch!
        for i in 0 to N-1 loop
            if s(i) = '1' then
                y <= d((i+1)*B-1 downto i*B);
            end if;
        end loop;
    end process;

end Behavioral;

Теперь отчет XST снова отличается:

Macro Statistics
# Multiplexers                                         : 128
 32-bit 2-to-1 multiplexer                             : 128
...
Number of Slice LUTs:                 2070  out of   5720    36%  
...
Timing constraint: Default path analysis
  Total number of paths / destination ports: 13376 / 32

Обнаружен мультиплексор 2-к-1, т.к. описан приоритетный мультиплексор, аналог этой схемы:

if s(127) = '1' then
  y <= d(128*B-1 downto 127*B);
else
  if s(126) = '1' then
    y <= d(127*B-1 downto 126*B);
  else
    ...
                             if s(0) = '1' then
                               y <= d(B-1 downto 0);
                             else
                               y <= (others => '0');
                             end if;
  end if; -- s(126)
end if; -- s(127)

Я не использовал здесь elsif по дидактическим причинам. Каждая ступень if-else представляет собой 32-битный мультиплексор 2-к-1. Проблема здесь в том, что синтез не знает, что s является сигналом, закодированным в горячем виде. Таким образом, требуется немного больше логики, как в моей оптимизированной реализации.

Количество путей для анализа времени снова существенно меняется. Цифра в 10 раз ниже, чем в исходной реализации, но в 2 раза выше, чем в моей оптимизированной.

person Martin Zabel    schedule 01.12.2015
comment
Невероятный! Большое спасибо за объяснение! - person arandomuser; 02.12.2015
comment
@Alessandro Если вы планируете использовать мою оптимизированную реализацию, взгляните на мою исправленную ошибку mux2. Теперь это еще проще. Извини. - person Martin Zabel; 02.12.2015