Во-первых, удалите нестандартные библиотеки.
use IEEE.std_logic_signed.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.ALL;
оставив только std_logic_1164
и numeric_std
.
Другие представляют собой совокупность перекрывающихся деклараций, из-за чего трудно определить, что происходит - и если имеется несколько объявлений для одного и того же оператора с теми же аргументами и типами результатов, компилятор делает их невидимыми, а не собирает произвольный.
Затем решите, что вы пытаетесь сделать. В настоящее время это неоднозначно и противоречиво.
(1) У вас есть декларативный generic (width : integer :=32);
и порт
random_num : out std_logic_vector (width-1 downto 0)
, которые предполагают, что вы имеете дело с 32-битными словами.
(2) У вас есть колебались целое число: Signal random_num_i: INTEGER RANGE 0 to 31;
, который (а) должен быть дальняя NATURAL
, чтобы сделать его еще более ясным, что отрицательные значения ошибки, и (б) предполагает, что вы имеете дело с 5-битовых слов.
Что это? Что именно ты пытаешься сделать?
А тут, по-видимому, пытаясь соединить их вместе в карте порта ...
C1: random Port map (
clk => clock_i,
--random_num <=to_integer(to_signed(random_num_i))
random_num =>random_num_i
);
random_num <=to_integer(to_signed(random_num_i)); -- error
Есть ряд вещей, которые здесь не так.
1) Для простого сопоставления портов, такого как random_num =>random_num_i
, требуется, чтобы обе стороны имели один и тот же тип. Это будет работать, если обе стороны были на самом деле тот же тип: например, если вы добавили объявление сигнала
random_num_slv : std_logic_vector (width-1 downto 0);
то отображение портов random_num =>random_num_slv
будет работать. Теперь вы можете преобразовать в нужный тип random_num_i
в назначении сигнала.
random_num_i <= to_integer (unsigned(random_num_slv));
Есть еще проблемы с этим: 32-разрядный выход, вероятно, переполнит 5-разрядное целое число.
При добавлении промежуточного сигнала random_num_slv
может выглядеть неэффективным и избыточным, он сохраняет дизайн в чистоте и простоте, что имеет значение при работе с инструментами, которые не понимают преобразования типов в портах.
Убедитесь, что вы знаете, как использовать промежуточные сигналы, даже если есть более чистый подход. Это может спасти вас, когда все остальное не удастся.
(2) Закомментированного картирование порта
random_num <=to_integer(to_signed(random_num_i))
бы способ сделать это, за три вещи, за исключением ... (а) <=
является назначение сигнала, необходимо =>
оператор объединения (b) вы преобразовываете целое число в целое число и управляете std_logic_vector с ним. Это действительно не сработает ... (c) порт компонента - OUTPUT, поэтому вы не должны водить его в первую очередь.
То, что вы, вероятно, имел в виду
to_integer(unsigned(random_num)) => random_num_i
, и это будет самым чистым способом сделать это, если ваши преобразования инструментов поддержки в порту карты правильно. Примечания:
- снова имеет проблему переполнения, 32-разрядный вектор не будет соответствовать 5-битовому целому числу.
- Вы можете конвертировать из std_logic_vector в подписанный или неподписанный путем литья
unsigned
, а не для функции преобразования to_signed
, поскольку они являются близкими типами. Целые числа не являются «тесно связанными» с ними, поэтому нужна функция преобразования to_integer
.
- В качестве отрицательных чисел не допускаются декларация
random_num_i
, используйте unsigned
, а не signed
.
(3) Существующий назначение сигнала
random_num <=to_integer(to_signed(random_num_i)); -- error
снова содержит несколько ошибок. Самым большим является то, что нет порта random_num
, видимого вне декларации компонента. Просто удалите эту строку, вам нужно использовать одно из сопоставлений портов.
Дальнейшие соображения:
(1) Некоторые преобразования типов неизбежны. Но если вы делаете слишком много, это, как правило, указывает на ошибку дизайна, например, на использование std_logic_vector
везде, даже для thengs, таких как адреса, которые неизбежно целые без знака, поэтому unsigned
или natural
- лучший выбор. Держите дизайн максимально простым и понятным. Я думаю, что ваше использование integer
здесь, как правило, хорошо, но natural
бы лучше
(2) Если вы хотите добавить гибкость родового как width
, использовать его правильно и последовательно (если вы не нужны отрицательные адреса!) - ИЛИ - проверьте, что это действительно.
Здесь, как описано выше, ваш дизайн ТОЛЬКО работает правильно без сюрпризов, ЕСЛИ этот объект создается с помощью width => 5
.
Итак, проверьте это значение и прервите, если это условие не выполнено.
assert Width = 5 report "Width of " & natural'image(width) & " not supported!"
severity FAILURE;
ИЛИ сделать проектные работы для всех разумных значений родового, например, делая другие величины зависят от него в действительных отношениях.Например:
constant DEPTH : natural := 2**WIDTH - 1;
signal random_num_i : natural range 0 to DEPTH;
и так далее ...
Спасибо, ребята, за помощь, @ user1155120. Моя цель - создать верхний уровень для двух сущностей random и single_clock_ram. Таким образом, я пытаюсь подключить вывод случайного к блоку ram. Основываясь на ваших комментариях, я изменил свой код, но у меня все еще такая же ошибка. – Kooss
Еще один вопрос, как сделать std_vector и integer с равной длиной? – Kooss