без использования переменных:
sum <= in_a + in_b;
process (clock)
begin
if rising_edge(clock) then
data_out <= in_c - ('0' & sum(7 downto 1));
end if;
end process;
Все декларации, за исключением часов являются unsigned(7 downto 0);
почему делают его более сложным, чем это?
Оригинальный, конвейерный до 3 тактов, вероятно, будет работать при более высоких тактовых частотах.
EDIT следующий комментарий:
Я хотел показать, что VHDL на самом деле не должны быть что многословным.
Однако, похоже, что многие люди «учат» VHDL, которые сосредоточены на элементарных элементах и полностью теряют общую картину, поэтому я скажу немного об этом.
VHDL - это строго типизированный язык, чтобы избежать ошибок, возникающих при ошибках типов друг для друга и (например,) вы добавляете два больших числа и получаете отрицательный результат.
Это НЕ следует из того, что вам нужно преобразовать тип по всему месту. Действительно, если вам нужно много преобразований типов, это признак того, что ваш дизайн, вероятно, неправильный, и пришло время переосмыслить это, вместо того, чтобы пахать вперед по неправильному пути.
Код - на ЛЮБОЙ языке - должен быть максимально чистым и простым.
В противном случае это трудно прочитать, и в нем, вероятно, есть ошибки.
Большая разница между C-подобным языком и VHDL это:
В C, используя правильные типы данных, которые вы можете написать sum = in_a + in_b;
и он будет работать. Используя неправильные типы данных, вы также можете написать sum = in_a + in_b;
, и он будет компилироваться просто отлично; то, что он на самом деле делает, это другое дело! Ошибки скрыты: вам решать определить правильные типы, и если вы ошибаетесь, вы можете сделать это очень мало, кроме как продолжать тестирование.
в VHDL, используя правильные типы вы можете написать sum <= in_a + in_b;
и используя неправильные типы, компилятор заставляет вас писать что-то вроде sum <= std_logic_vector(unsigned(in_a) + unsigned(in_b));
, который чертовски некрасиво, но (возможно: см примечание 1) по-прежнему работать правильно.
Чтобы ответить на вопрос: как я могу использовать unsigned
или std_logic_vector
?
Я вижу, что мне нужны три входа и выход. I мог просто сделать их std_logic_vector
, но я останавливаюсь и спрашиваю: что они представляют?
Номера.
Могут ли они быть отрицательными? Не согласно моему чтению спецификации (ваш вопрос).
Таким образом, без знака ... (Примечание 1)
мне нужно, не арифметические операции над ними делать? Да, есть сдвиг. (Примечание 2)
Итак, numeric_std.unsigned
, что связано с std_logic_vector
вместо natural
, которое является целым числом.
Теперь вы не можете избежать преобразования типов вообще. Стандарты кодирования могут налагать такие ограничения, как «все порты верхнего уровня должны быть std_logic_vector
», и вы должны реализовать спецификацию внешнего объекта, к которой вы просили; промежуточные сигналы для преобразования типов иногда более чистые, чем альтернативы, например. in_a <= unsigned(data_in_a);
Или, если вы получаете инструкции, символы и цифры выше из той же памяти, например, вы можете решить, что содержимое памяти должно быть std_logic_vector
, потому что оно не просто содержит номера. Но выберите подходящее место для преобразования типа, и вы обнаружите, что 90% типов конверсий исчезают. Возьмите это как руководство по проектированию.
(Примечание 1: а что произойдет, если C < (A + B)/2 Если data_out подписываются Даже думать вдоль этих линий всплыл вероятную ошибку, STD_LOGIC_VECTOR оставил скрытые ...
право? ответ зависит от неизвестных, включая цель data_out: если он действительно должен быть неподписанным, напримерадрес памяти, вы можете пометить ошибку вместо того, чтобы он подписал)
(Примечание 2: не существует инструмент синтеза, который остался в живых не будет переводить signal a : natural; ... x <= a/2
в сдвиг вправо, так natural
бы также работа, если не было других причин выбора неподписанных. Многим кажется, что их все еще учат, что целые числа не являются синтезируемыми, и это всего лишь неправильный.)
Спасибо, Дэвид. Код, который вы предоставили, также достиг цели синхронизации с правильным результатом. Означает ли это, что присвоение сигналов вне блока процесса происходит последовательным образом? (Sum_out оценивается до shift_out. Затем происходит процесс.)? – ElectroJunkie
shift_out не должен был находиться в списке чувствительности процесса, я удалил его (многозадачность, ошибка автопилота). Причина, по которой он работает как цепочка, состоит в том, что оператор одновременного назначения сигналов чувствителен к сигналам с правой стороны. В модели с нулевым временем процесс будет ожидать часы, а shift_out уже будет готов. Назначения sum_out, shift_out и data_out являются последовательными, но не последовательными, упорядоченными по событиям. Синтез описания проекта будет зависеть от задержек задержек, добавляемых до менее чем одного периода тактового сигнала. – user1155120
Мне приходилось много раз читать, чтобы понять это, но я думаю, что у меня есть это сейчас. Shift_out будет ожидать вычисления sum_out, потому что у присваивания shift_out есть sum_out с правой стороны. Это гарантирует, что sum_out и shift_out будут работать последовательно. Это была большая помощь. Большое спасибо, Дэвид! – ElectroJunkie