Перейти к содержанию
    

Вопрос по преобразованию типов в VHDL

Здравствуйте. Надо преобразовать в целое число 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, но сумма оказывается равной нулю все время. Подскажите,пожалуйста,в чем ошибка.

Изменено пользователем dak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У Вас длина вектора в формуле 4 бита всего, вместо 64. А в целом, почему нельзя сделать в два приема.

Взять 64 бита как два по 32. И преобразовать в две строки, младшую часть и старшую. А затем сложить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте. Надо преобразовать в целое число std_logic_vector в 64 бита.

 

Стандартными средствами VHDL этого, как я понимаю, сделать нельзя: conv_integer может принимать максимум вектор на 32 бита.

Тип Integer имеет длину 32 бита, поэтому и conv_integer с большей длиной не работает. Если нужно больше 32 бит, используйте signed.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У Вас длина вектора в формуле 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.

Спасибо. Боюсь, что я не совсем понимаю,что предлагаете сделать.

Изменено пользователем dak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо. Боюсь, что я не совсем понимаю,что предлагаете сделать.

Использовать для вычислений пакеты numeric_std(что лучше) или std_logic_arith, и тип signed(или unsigned) а не пытаться переводить всё в integer.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Использовать для вычислений пакеты numeric_std(что лучше) или std_logic_arith, и тип signed(или unsigned) а не пытаться переводить всё в integer.

Спасибо. После мытарств с переходом в integer тоже об этом подумал и сейчас переделываю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Заработало, но меня смущает количество ресерсов, съедаемых этой штукой (после синтеза).

 

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% можно сделать так,чтобы жрало меньше логики. Какие шаги в первую очередь?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Например: 100011 = 32, но 100=8, 011=5 и не равно 35

 

Интересно эти цифры в какой системе исчисления, потому что у меня в двоичной получается

100011 = 35, 100 = 4, 011=3

Изменено пользователем twix

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересно эти цифры в какой системе исчисления, потому что у меня в двоичной получается

100011 = 35, 100 = 4, 011=3

Да,я ошибся.

 

Но все равно 7 не равно 35 :-)

Изменено пользователем dak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Заработало, но меня смущает количество ресерсов, съедаемых этой штукой (после синтеза).
И неудивительно.

M <= std_logic_vector(unsigned(clock_value_reg)/unsigned(V));

Как вы думаете, делитель такой разрядности (64 / 20) сильно большой или не очень?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И неудивительно.

M <= std_logic_vector(unsigned(clock_value_reg)/unsigned(V));

Как вы думаете, делитель такой разрядности (64 / 20) сильно большой или не очень?

Очевидно,что не маленький, но разрядности никак не уменьшить. Я имел в виду, может есть более оптимальные варианты по организации деления?

Изменено пользователем dak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очевидно,что не маленький, но разрядности никак не уменьшить. Я имел в виду, может есть более оптимальные варианты по организации деления?

деление сдвигом или на степень двойки не подходит?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

деление сдвигом или на степень двойки не подходит?

Спасибо.

 

Боюсь, что надо делить именно на 1 000 000.

 

Что касается деления со сдвигом. Это же вроде классичекий метод, еще в школе изучают. Я полагал, что именно так оно в VHDL и устроенно. Возможно, я не правильно Вас понимаю. Не могли бы Вы привести ссылку на какой-нибудь пример, чтобы устранить сомнения?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Боюсь, что надо делить именно на 1 000 000.

тогда можно попробовать так

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...