2015-12-27 3 views
2

фона:Как увеличить std_logic_vector в массиве с использованием индекса? VHDL

У меня есть тип массив из четырех 4-битный STD_LOGIC_VECTOR'S:

type my_arr_type is array (0 to 3) of std_logic_vector (3 downto 0); 

и соответствующий сигнал:

signal my_signal : my_arr_type; 

У меня также есть 2-битный вектор а для использования в качестве индекса массива:

signal index : std_logic_vector (1 downto 0) := "00"; 

Это позволяет мне получить доступ к каждому 4-битный вектор динамически так:

my_signal(to_integer(unsigned(index))) <= "0001"; 

В этом случае индексируется 4-битный вектор получит значение б «0001».

Проблема:

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

Я думал, что я мог бы это с чем-то вроде:

process(clk) 
begin 
    if(rising_edge(clk)) then 
     if switch = '1' then --switch flicked (increment) 
      my_signal(to_integer(unsigned(index))) 
      <= std_logic_vector(unsigned(my_signal(to_integer(unsigned(index)))) + 1); 
     else --remain the same 
      my_signal(to_integer(unsigned(index))) 
      <= my_signal(to_integer(unsigned(index))); 
     end if; 
    end if; 
end process; 

Однако, я должен делать что-то неправильно, так как проходя результирующий сигнал на выходе выдает сообщение об ошибке - вдоль линий:

Signal X is connected to multiple drivers. ERROR:HDLCompiler:1401 

Вопрос:

Что я делаю неправильно в вышеуказанной попытке? Что было бы правильным решением?

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

(Проектирование для синтеза в Digilent NEXYS 3 в ISE Рго Nav)

(редактировать) Longer фрагмент кода для большей scrunity:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity ui_top is 
Port ( clk   : in std_logic; 
      buttons  : in std_logic_vector (4 downto 0); -- centre, left, up, right, down 
      switches : in std_logic_vector (7 downto 0); 
      leds   : out std_logic_vector (7 downto 0); 
      digit   : out std_logic_vector (3 downto 0) := "1110"; 
      segments : out std_logic_vector (7 downto 0) := (others => '0'); 
      uart_tx  : out std_logic); 
end ui_top; 

architecture Behavioral of ui_top is 

    type my_arr_type is array (0 to 3) of std_logic_vector(3 downto 0); 

    signal my_signal : my_arr_type; 
    signal index : std_logic_vector (1 downto 0) := "00"; 


begin 

    -- send indexed signal to leds 
    leds(3 downto 0) <= my_signal(to_integer(unsigned(index))); 

    -- set other outputs arbitrarily 
    leds(7 downto 4) <= (others => '1'); 
    uart_tx <= '1'; 
    digit <= "1110"; 
    segments <= (others => '0'); 

    -- set index 
    index <= "00"; 

    process(clk) 
    begin 
     if (rising_edge(clk)) then 
      if switches(1) = '1' then -- up 
       my_signal(to_integer(unsigned(index))) 
       <= std_logic_vector(unsigned(my_signal(to_integer(unsigned(index)))) + 1); 
      end if; 
     end if; -- rising clock edge 
    end process; 

    -- set non indexed values arbitrarily 
    my_signal(1) <= "0000"; 
    my_signal(2) <= "0000"; 
    my_signal(3) <= "0000"; 

end Behavioral; 

редактировать: Все ответы и комментарии имеют были полезны. Спасибо!

+0

Ваш инструмент синтеза не распознает, что 'index' является постоянным значением. Таким образом, он вычисляет несколько драйверов по имени каждого сигнала, а не по имени индекса. Пожалуйста, измените свой индекс 'index' на константу, и он должен ее распознать (это просто для тестирования). – Paebbels

+0

@Paebbels Хорошо. В этом есть смысл. И вы правы - изменение «индекса» до постоянного значения делает синтез кода возможным. Любые советы о том, как преодолеть эту проблему, когда индекс не является константой? –

+0

Даже с постоянным индексом мой инструмент останавливается во время «Место и маршрут». –

ответ

0

Причина (вероятно) заключается в том, что существует другой процесс или параллельное назначение, которое управляет (назначает) my_signal, поэтому просмотрите весь свой код или отправьте его здесь для дальнейшего изучения.

Обратите внимание, что водитель (назначить) может быть другим индексом; взгляните на this answer.

КПП. Вы можете удалить

else --remain the same 
    my_signal(to_integer(unsigned(index))) 
    <= my_signal(to_integer(unsigned(index))); 

поскольку my_signal сохранит текущее значение до тех пор, пока данный новый.

+0

Это мое понимание ошибки, но я не вижу ничего другого, который присваивает my_signal (по крайней мере, не 4-битный вектор, проиндексированный, я предполагаю, что некоторая заблуждение в этой сложности - моя проблема). Я добавил весь свой код для вас, чтобы проверить, если хотите. Между тем, я прочитаю ваш другой ответ. –

2

Это связано с длинным статическим префиксом, это не просто проблема синтеза, но также отражается и на моделировании.

Драйверы для my_signal в процессе определяются самым длинным статическим префиксом my_signal.

Используя нестатические значения для индекса в массиве, вы создали драйверы для my_signal (0), my_signal (1), my_signal (2) и my_signal (3) в вашем немеченом процессе.

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

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

См. IEEE Std 1076-2008 8. Имена, 8.1 Общие положения (длинный статический префикс, параграф 8), 14.7 Исполнение модели, 14.7.2 Драйверы 1, 14.7.3 Распространение значений сигналов, 14.7.3.1 Общие положения , para 5.

Если вы использовали неразрешенный тип элемента (BIT, BIT_VECTOR), вы получали сообщения об одной или нескольких ошибках при разработке нескольких драйверов в сетке сигналов. Это эквивалентно тому, что сообщает ваш инструмент синтеза.

1

Ваша проблема - проблема с несколькими дисками. This post and its answer может помочь понять это. Когда вы используете разрешенные типы (std_logic), вы не будете получать ошибки или предупреждения при компиляции или имитации. Инструмент, который вы используете (ISE), является логическим синтезатором. Он пытается сопоставить описанное вами поведение с существующими аппаратными ресурсами. Поскольку ваша аппаратная цель не поддерживает несколько дисков, вы получаете ошибки. Мои советы:

  • не использовать разрешенные типы, когда они не нужны,
  • использовать соответствующие типы (как это мудро, предложенные Brian Drummond).

Что-то вроде следующего кода должно быть лучше. Адаптируйте его к вашим конкретным потребностям. Обратите внимание, что тип unsignedieee.numeric_std, к сожалению, является разрешенным типом. Поэтому используйте его внимательно и избегайте ситуаций с несколькими дисками. Или, еще лучше, если ваши инструменты поддерживают его, используйте unresolved_unsigned неразрешенную версию unsigned.

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.numeric_std.all; 

entity ui_top is 
    Port(clk   : in std_ulogic; 
     buttons  : in std_ulogic_vector (4 downto 0); -- centre, left, up, right, down 
     switches : in std_ulogic_vector (7 downto 0); 
     leds  : out std_ulogic_vector (7 downto 0); 
     digit  : out std_ulogic_vector (3 downto 0); 
     segments : out std_ulogic_vector (7 downto 0); 
     uart_tx  : out std_ulogic); 
end ui_top; 

architecture Behavioral of ui_top is 

    constant n: positive := 4; 
    type my_arr_type is array (0 to 3) of unsigned(n-1 downto 0); 
    -- type my_arr_type is array (0 to 3) of unresolved_unsigned(n-1 downto 0); 

    signal my_signal : my_arr_type; 
    signal index : natural range 0 to n-1; 

begin 

    -- send indexed signal to leds 
    leds(n-1 downto 0) <= std_ulogic_vector(my_signal(index)); 

    -- set other outputs arbitrarily 
    leds(7 downto n) <= (others => '1'); 
    uart_tx <= '1'; 
    digit <= "1110"; 
    segments <= (others => '0'); 
    -- set index 
    index <= 0; 

    process(clk) 
    begin 
    if (rising_edge(clk)) then 
     -- set non indexed values arbitrarily 
     for i in 0 to n-1 loop 
     if i = index then 
      if switches(1) = '1' then -- up 
      my_signal(i) <= my_signal(i) + 1; 
      end if; 
     else 
      my_signal(i) <= (others => '0'); 
     end if; 
     end loop; 
    end if; -- rising clock edge 
    end process; 

end Behavioral; 
+0

Использование неразрешенных типов обычно является хорошим советом, но здесь это не помогает. Синтезатор ISE 14.7 жалуется на ту же ошибку: используется ли 'std_logic_vector' или' std_ulogic_vector' для элементов 'my_signal'. Несколько драйверов перечислены, но, к сожалению, не очевидно, откуда они взялись. –

+0

@MartinZabel Использование нерешенных типов не мешает вам писать фиктивный код. Это просто помогает избежать многих ситуаций с несколькими дисками: ваш инструмент моделирования будет вызывать ошибки и сообщать вам, что не так. В любом случае, отладка кода VHDL с помощью синтезатора - плохая идея. –

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