Ответ 1
Один идет вверх, один идет вниз:
-- gives 0, 1, 2, 3:
for i in 0 to 3 loop
-- gives 3, 2, 1, 0:
for i in 3 downto 0 loop
Я не уверен, что понимаю разницу между "downto" и "to" в vhdl.
Я видел некоторые онлайн-объяснения, но я все еще не думаю, что понимаю. Может ли кто-нибудь изложить это для меня?
Один идет вверх, один идет вниз:
-- gives 0, 1, 2, 3:
for i in 0 to 3 loop
-- gives 3, 2, 1, 0:
for i in 3 downto 0 loop
Если вы берете процессор, для Little endian систем мы можем использовать "downto", а для бигдианских систем мы используем "to".
Например,
signal t1 : std_logic_vector(7 downto 0); --7th bit is MSB and 0th bit is LSB here.
и
signal t2 : std_logic_vector(0 to 7); --0th bit is MSB and 7th bit is LSB here.
Вы можете использовать оба типа представлений, просто убедитесь, что другие части дизайна написаны соответствующим образом.
Этот post говорит что-то другое:
"Термин big endian (или little endian) обозначает порядок байтов в байтовых ориентированных процессорах и не подходит для битовых векторов VHDL. Техническим термином является диапазон возрастания и убывания массива. Предопределенные числовые типы, такие как signed и unsigned, ограничены к нисходящим диапазонам по соглашению."
Итак, этот ответ может ввести в заблуждение...
Интересная онлайн-ссылка, которую я нашел, здесь, где, среди прочего, в разделе "Array Assignments" вы можете прочитать:
Два объекта массива могут быть назначены друг другу, если они одного типа и одного размера. Важно отметить, что назначение выполняется по положению, а не по номеру индекса. В языке нет понятия значимого бита. Это толко интерпретируется пользователем, который использует массив. Ниже приведены примеры присвоений массивов:
со следующим объявлением:
....
SIGNAL z_bus: BIT_VECTOR (3 DOWNTO 0);
SIGNAL a_bus: BIT_VECTOR (1 TO 4);
....
z_bus <= a_bus;
совпадает с:
z_bus(3) <= a_bus(1);
z_bus(2) <= a_bus(2);
z_bus(1) <= a_bus(3);
z_bus(0) <= a_bus(4);
замечания:
1) Любая разница "downto" и "to" появляется, когда мы хотим использовать битовый вектор не только для представления массива бит, где каждый бит имеет независимое поведение, но и представляет целое число. Затем существует разница в значении бита, поскольку номера обрабатываются такими схемами, как сумматоры, множители и т.д.
В этом, возможно, частном случае, предполагая, что 0 < x < y, это обычное соглашение, что при использовании x to y
x является самым значимым битом (MSB) и y наименее значимым битом (LSB). И наоборот, при использовании y downto x
y является MSB и x LSB. Вы можете сказать, что разница для битовых векторов, представляющих целые числа, исходит из того, что индекс MSB приходит первым, независимо от того, используете ли вы "to" или "downto" (хотя первый индекс меньше второго при использовании "to" , и больше при использовании "downto" ).
2) Вы должны заметить, что y downto x
означает, что y является MSB и, наоборот, x to y
означает, что x является MSB, являются известными соглашениями, обычно используемыми в ядрах интеллектуальной собственности (IP), которые вы можете найти, и даже бесплатно, Это также соглашение, используемое библиотеками IEEE VHDL, я думаю, при преобразовании между битовыми векторами и целыми числами. Но нет ничего сложного в структурном моделировании, например, 32-разрядного сумматора, который использует входные битовые векторы формы y downto x
и использует y в качестве LSB или использует входные битовые векторы формы x to y
где x используется как LSB...
Тем не менее, разумно использовать обозначение x downto 0
для неотрицательного целого числа, поскольку позиции бит соответствуют мощности 2, умноженной на цифру, чтобы добавить к номеру значение. Это, по-видимому, было расширено и в большинстве других практик, включающих целые числа.
3) Бит-порядок имеет ничего, чтобы сделать с контентом. Endianness относится к порядку байтов (ну, порядок байтов - это форма битового упорядочения...). Endianness - проблема, возникающая на уровне архитектуры набора инструкций (ISA), то есть она видна программисту, который может обращаться к одному и тому же адресу памяти с различными размерами операндов (например, слово, байт, двойное слово и т.д.). Бит-упорядочение в реализации (как в вопросе) никогда не отображается на уровне ISA. Только семантика относительных позиций битов видна программисту (например, сдвиг влево логический может быть фактически реализован путем смещения права на регистр, значение бита которого изменяется в реализации).
(Удивительно, сколько ответов, которые упоминают об этом, были проголосованы!)
В типах векторов самый старший бит является самым значительным. Следовательно, для диапазона 0 to n
бит 0
- это msb, а бит n downto 0
n
- это msb.
Это пригодится, когда вы комбинируете IP-адрес, который использует как порядковые номера биллиантовых, так и мало-конечных бит, чтобы держать голову прямо!
Например, Microblaze является big-endian и использует 0
в качестве своего msb. Я подключил его к внешнему устройству, которое было малоподобным, поэтому я использовал 15 downto 0
на внешних контактах и перенаправил их на 16 to 31
на конец микрообъектива в моем ядре интерфейса.
VHDL заставляет вас говорить об этом явно, поэтому вы не можете напрямую делать le_vec <= be_vec;
.
В основном это просто мешает вам смешивать порядок бит, когда вы создаете компоненты. Вы не захотите хранить LSB в X(0)
и передать это компоненту, который ожидает, что X(0)
будет содержать MSB.
Практически говоря, я предпочитаю использовать DOWNTO
для векторов бит (STD_LOGIC_VECTOR(7 DOWNTO 0)
или UNSIGNED(31 DOWNTO 0)
) и TO
для ОЗУ (TYPE data_ram IS ARRAY(RANGE NATURAL<>) OF UNSIGNED(15 DOWNTO 0); SIGNAL r : data_ram(0 TO 1023);
) и интегральных счетчиков (SIGNAL counter : NATURAL RANGE 0 TO max_delay;
).
Чтобы развернуть @KerrekSB ответ, рассмотрите приоритетный кодер:
ENTITY prio
PORT (
a : IN STD_LOGIC_VECTOR(7 DOWNTO 1);
y : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
);
END ENTITY;
ARCHITECTURE seq OF prio IS
BEGIN
PROCESS (a)
BEGIN
y <= "000";
FOR i IN a'LOW TO a'HIGH LOOP
IF a(i) = '1' THEN
y <= STD_LOGIC_VECTOR(TO_UNSIGNED(i, y'LENGTH));
END IF;
END LOOP;
END PROCESS;
END ENTITY;
Направление цикла (TO
или DOWNTO
) определяет, что происходит, когда утверждается несколько входов (пример: a := "0010100"
). При TO
выигрыш наивысшего номера (y <= "100"
). При DOWNTO
наименьший пронумерованный вход выигрывает (y <= "010"
). Это связано с тем, что последнее назначение в процессе имеет приоритет. Но вы также можете использовать EXIT FOR
для определения приоритета.
Мне учили, что хорошим правилом является использование "downto" для вопросов, где важно поддерживать двоичный порядок (например, 8-битный сигнал с символом) и "to" используется, когда сигнал не обязательно связан между собой, например если каждый бит в сигнале представляет собой светодиод, который вы включаете и выключаете.
подключение 4-битного "вниз" и 4-битного "к" выглядит примерно как
sig1 (3 до 0) <= sig2 (от 0 до 3)
------- 3 -------------------- 0
------- 2 -------------------- 1
------- 1 -------------------- 2
------- 0 -------------------- 3
принимает часть сигнала вместо sig1 (2 до 1) <= sig2 (от 0 до 1)
------- 2 -------------------- 0
------- 1 -------------------- 1