dak 0 5 февраля, 2016 Опубликовано 5 февраля, 2016 (изменено) · Жалоба Здравствуйте. Надо преобразовать в целое число std_logic_vector в 64 бита. Стандартными средствами VHDL этого, как я понимаю, сделать нельзя: conv_integer может принимать максимум вектор на 32 бита. Поэтому решил сделать так: phase_acc:process(clk120MHz,arst) begin if arst='1' then int_clock_value <= 0; clock_value_reg <= (others=>'0'); elsif rising_edge(clk120MHz) then clock_value_reg <= clock_value_synch; for inc in 0 to 63 loop int_clock_value <= int_clock_value + conv_integer(conv_std_logic_vector(clock_value_reg(inc),4))*(2**inc); end loop; int_clock_value объявлен как signal integer. До этого блока есть еще пара, которые отвечают за clock_value_synch. При симуляции получаю правилньые значения в clock_value_synch, clock_value_reg, но сумма оказывается равной нулю все время. Подскажите,пожалуйста,в чем ошибка. Изменено 5 февраля, 2016 пользователем dak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
twix 0 6 февраля, 2016 Опубликовано 6 февраля, 2016 · Жалоба У Вас длина вектора в формуле 4 бита всего, вместо 64. А в целом, почему нельзя сделать в два приема. Взять 64 бита как два по 32. И преобразовать в две строки, младшую часть и старшую. А затем сложить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 6 февраля, 2016 Опубликовано 6 февраля, 2016 · Жалоба Здравствуйте. Надо преобразовать в целое число std_logic_vector в 64 бита. Стандартными средствами VHDL этого, как я понимаю, сделать нельзя: conv_integer может принимать максимум вектор на 32 бита. Тип Integer имеет длину 32 бита, поэтому и conv_integer с большей длиной не работает. Если нужно больше 32 бит, используйте signed. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dak 0 6 февраля, 2016 Опубликовано 6 февраля, 2016 (изменено) · Жалоба У Вас длина вектора в формуле 4 бита всего, вместо 64. А в целом, почему нельзя сделать в два приема. Взять 64 бита как два по 32. И преобразовать в две строки, младшую часть и старшую. А затем сложить. Спасибо. Но мои данные - unsigned. То есть, если разбивать (на самом деле,не разбивать - этот вектор в 64 бита я и получил из двух, сначала забыл про 32 бита на integer) на вектора по 32 бита, то мои данные это числа от 0 и гипотетически до 2^32. А максимум можно до 2^31-1. Не катит такой способ. Например: int_clock_value_high <= conv_integer(unsigned(clock_value_high_reg)); А в clock_value_high_reg 10101010101010101010101010101011. И получаем ошибку. Наверно, можно разбдробить на еще более мелкие вектора и для них отдельно вычислять. Но может есть более рациональные пути? UPD: кстати, а разве так вообще делать можно? Разве результат эквивалентен? Как я понимаю,нет. Например: 100011 = 32, но 100=8, 011=5 и не равно 35 Тип Integer имеет длину 32 бита, поэтому и conv_integer с большей длиной не работает. Если нужно больше 32 бит, используйте signed. Спасибо. Боюсь, что я не совсем понимаю,что предлагаете сделать. Изменено 6 февраля, 2016 пользователем dak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 6 февраля, 2016 Опубликовано 6 февраля, 2016 · Жалоба Спасибо. Боюсь, что я не совсем понимаю,что предлагаете сделать. Использовать для вычислений пакеты numeric_std(что лучше) или std_logic_arith, и тип signed(или unsigned) а не пытаться переводить всё в integer. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dak 0 6 февраля, 2016 Опубликовано 6 февраля, 2016 · Жалоба Использовать для вычислений пакеты numeric_std(что лучше) или std_logic_arith, и тип signed(или unsigned) а не пытаться переводить всё в integer. Спасибо. После мытарств с переходом в integer тоже об этом подумал и сейчас переделываю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dak 0 6 февраля, 2016 Опубликовано 6 февраля, 2016 · Жалоба Заработало, но меня смущает количество ресерсов, съедаемых этой штукой (после синтеза). ARCHITECTURE arch OF dynamic_freq_divider IS signal acc: std_logic_vector (38 downto 0); -- аккумулятор фазы signal M : std_logic_vector (63 downto 0); --константа для аккумултора signal clock_value_reg : std_logic_vector (63 downto 0); signal V: std_logic_vector (19 downto 0); BEGIN phase_acc:process(clk120MHz,arst) begin if arst='1' then acc <= (others=>'0'); M <= (others=>'0'); V <= std_logic_vector(to_unsigned(1000000,20)); clock_value_reg <= (others=>'0'); elsif rising_edge(clk120MHz) then clock_value_reg <= clock_value_synch; M <= std_logic_vector(unsigned(clock_value_reg)/unsigned(V)); acc <= std_logic_vector(unsigned(acc) + unsigned(M (38 downto 0))); end if; end process phase_acc; clock_out <= acc(38); END ARCHITECTURE arch; С вероятностью 99,9% можно сделать так,чтобы жрало меньше логики. Какие шаги в первую очередь? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
twix 0 6 февраля, 2016 Опубликовано 6 февраля, 2016 (изменено) · Жалоба Например: 100011 = 32, но 100=8, 011=5 и не равно 35 Интересно эти цифры в какой системе исчисления, потому что у меня в двоичной получается 100011 = 35, 100 = 4, 011=3 Изменено 6 февраля, 2016 пользователем twix Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dak 0 6 февраля, 2016 Опубликовано 6 февраля, 2016 (изменено) · Жалоба Интересно эти цифры в какой системе исчисления, потому что у меня в двоичной получается 100011 = 35, 100 = 4, 011=3 Да,я ошибся. Но все равно 7 не равно 35 :-) Изменено 6 февраля, 2016 пользователем dak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 15 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Заработало, но меня смущает количество ресерсов, съедаемых этой штукой (после синтеза).И неудивительно. M <= std_logic_vector(unsigned(clock_value_reg)/unsigned(V)); Как вы думаете, делитель такой разрядности (64 / 20) сильно большой или не очень? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dak 0 7 февраля, 2016 Опубликовано 7 февраля, 2016 (изменено) · Жалоба И неудивительно. M <= std_logic_vector(unsigned(clock_value_reg)/unsigned(V)); Как вы думаете, делитель такой разрядности (64 / 20) сильно большой или не очень? Очевидно,что не маленький, но разрядности никак не уменьшить. Я имел в виду, может есть более оптимальные варианты по организации деления? Изменено 7 февраля, 2016 пользователем dak Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Очевидно,что не маленький, но разрядности никак не уменьшить. Я имел в виду, может есть более оптимальные варианты по организации деления? деление сдвигом или на степень двойки не подходит? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dak 0 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба деление сдвигом или на степень двойки не подходит? Спасибо. Боюсь, что надо делить именно на 1 000 000. Что касается деления со сдвигом. Это же вроде классичекий метод, еще в школе изучают. Я полагал, что именно так оно в VHDL и устроенно. Возможно, я не правильно Вас понимаю. Не могли бы Вы привести ссылку на какой-нибудь пример, чтобы устранить сомнения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба Боюсь, что надо делить именно на 1 000 000. тогда можно попробовать так Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dak 0 7 февраля, 2016 Опубликовано 7 февраля, 2016 · Жалоба тогда можно попробовать так Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться