Jump to content
    

Преобразования типов в VHDL

Заранее извиняюсь если подобная тема была, я честно искал)

 

Итак, есть два типа данных которые я часто использую - BIT_VECTOR и integer. Ну и вроде как в любом нормально устройстве иногда нужно работать с числом как с числом, а иногда как с битовым вектором.

Значит, следуя интуитивной логике, преобразования туда и обратно должны проходить относительно легко. Но вот когда я начал делать - не тут то было. В муках я сначала породил вот эти 2 функции.

 

  
  function to_uint(bits: BIT_VECTOR) return integer is
  begin
    return conv_integer(unsigned(To_StdUlogicVector(bits)));
  end to_uint;
  
  function To_BitVector32(number : integer) return BIT_VECTOR is
  begin
    return To_BitVector(STD_LOGIC_VECTOR(IEEE.numeric_std.To_Unsigned(number,32)));
  end To_BitVector32;

 

Исходя из моего программистского опыта, складывается такое ощущение, что тут что-то не так.

Как-то громоздко выглядит. Как правило, хороший код так не выглядит.

 

А потом в книжке "The VHDL CookBook" я еще увидел вот такие примеры:

function bits_to_int (bits : in bit_vector) return integer is
  variable temp : bit_vector(bits'range);
  variable result : integer := 0;
begin
  if bits(bits'left) = '1' then -- negative number
    temp := not bits;
  else
    temp := bits;
  end if;
  for index in bits'range loop -- sign bit of temp = '0'
    result := result * 2 + bit'pos(temp(index));
  end loop;

  if bits(bits'left) = '1' then
    result := (-result) - 1;
  end if;

  return result;
end bits_to_int;

procedure int_to_bits (int : in integer; bits : out bit_vector) is
  variable temp : integer;
  variable result : bit_vector(bits'range);
begin
  if int < 0 then
    temp := -(int+1);
  else
    temp := int;
  end if;

  for index in bits'reverse_range loop
    result(index) := bit'val(temp rem 2);
    temp := temp / 2;
  end loop;

  if int < 0 then
    result := not result;
    result(bits'left) := '1';
  end if; 
  bits := result;
end int_to_bits;

 

И я крепко задумался, что что-то окончательно тут не так. Второй вариант я не пробовал - сразу скажу (хотя можно попробовать конечно и посмотреть на отчет), но ощущение такое, что его схемная реализация при синтезе может быть неэффективной. Вобщем, у меня несколько вопросов.

 

1) Как наиболее правильно с точки зрения языка и схемной реализации приводить преобразования BIT_VECTOR <=> integer ?

2) Для чего нужны типы STD_LOGIC_VECTOR и unsigned. Что касается unsigned мне совсем непонятно - ведь есть же integer range 0 to 'что-то там большое'. Зачем еще один тип? На счет STD_LOGIC_VECTOR я понимаю что там больше значений и может оно где-то полезно, но непонятно почему оно стоит в цепочки преобразований между integer и bit_vector.

3) Почему в некоторых случаях нельзя просто преобразовать как в обычном языке программирования - unsigned(number). Вместо этого приходится использовать спец. функцию IEEE.numeric_std.To_Unsigned(number,32).

4) И почему наконец нельзя напрямую преобразовать BIT_VECTOR в integer - это же такая простая и интуитивно понятная операция. - нет, сначало в STD_LOGIC_VECTOR, потом в unsigned и уж потом только в integer. Может я не нашел просто стандартной функции? Хотя бы как to_int(vec) и to_uint(vec).

 

Заранее спасибо. В VHDL я новичёк, больно не бейте)

Edited by FROL_256

Share this post


Link to post
Share on other sites

Итак, есть два типа данных которые я часто использую - BIT_VECTOR и integer.
Можете почитать главу про пакет NUMERIC_STD в книге "VHDL. Эффективное использование при проектировании цифровых систем". Там написано для чего нужен этот пакет и какие функции в нем описаны. Книгу можно взять в библиотеке gеn.lib.rus.еc.

 

Share this post


Link to post
Share on other sites

1...4

1. не использовать бит вектор и integer

2. для описания логики, integer range и unsigned/signed в VHDL не эквивалентны друг другу.

3. из-за особенностей стандарта языка VHDL

4. потому что такая функция не определена в стандарте и стандартных либах.

 

Теперь о сути, читайте стандарт на VHDL, там всего 200 страниц (в отличие от SV на ~2000 страниц). VHDL это базовый движок, в котором определены минимальные типы/функции. Всё остальное на него навернуто через либы (та же std_logic_1364) в которых всё сделано через эти минимальные функции движка. Именно по этому и нужны все эти шпили-вили с типами %)

 

ЗЫ. ИМХО стремление к языку Paranoid погубит VHDL, курите лучше SV. (это не повод для холивара) %)

Share this post


Link to post
Share on other sites

Исходя из моего программистского опыта, складывается такое ощущение, что тут что-то не так.
Угу, тут 'не так' VHDL. Пока не поздно переходите на Verilog (SystemVerilog)

 

Share this post


Link to post
Share on other sites

Исходя из моего программистского опыта, складывается такое ощущение, что тут что-то не так.
Если ваш программистский опыт испорчен языком Си, то в языке со строгой типизацией вам будет... некомфортно, что ли.

Share this post


Link to post
Share on other sites

та же std_logic_1364

 

Это что за зверь? :laughing:

Это были советы вериложника по использованию VHDL? ;)

Share this post


Link to post
Share on other sites

Всем спасибо большое за ответы. Буду читать и смотреть.

 

Если ваш программистский опыт испорчен языком Си, то в языке со строгой типизацией вам будет... некомфортно, что ли.

Нет, я как раз приверженец строгой типизации и мой любимый язык это Ада. Поэтому я выбрал именно VHDL.

Но я уже понял, что система типов Ады это цветочки по сравнению с системой типов VHDL)

Share this post


Link to post
Share on other sites

Для библиотеки numeric_std есть очень хороший график как преобразовать одни типы данных в другие.

Возможно вы его уже видели http://www.doulos.com/knowhow/vhdl_designe...de/numeric_std/ (вторая картинка)

 

Да, хорошие картинки. Но в данном случае важнее эквивалентный по функциональности numeric_bit.

 

Резюмируя.

Первый очевидный совет топикстартеру - используя bit_vector использовать библиотеку numeric_bit, а не numeric_std.

Второй совет - при конвертации целых в битовые вектора, очевидно, необходимо указывать ширину желаемого битового вектора. В программируемой логике, в отличие от процессоров, битовые вектора могут быть произвольной ширины, с точностью до бита.

Третий совет - заметить, что есть подтипы signed и unsigned типа bit_vector. И что это именно подтипы типа bit_vector, при использовании библиотеки numeric_bit, разумеется, при использовании библиотеки numeric_std они будут определены как подтипы типа std_logic_vector. Подтипы - это термин, отсутствующий в С, но он важен в VHDL. Туда подтипы пришли из прототипа синтаксиса языка VHDL - языка Ада. Разница между signed и unsigned критична при конвертации в целые, так как синтезатор должен знать, расширять знаковый бит, или нет.

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

И последнее. Не забывать, что большинство учебников по кодированию на VHDL, видимо, были тоже написаны вериложниками. Нужно самому читать стандарты, чтобы понять устройство языка.

Share this post


Link to post
Share on other sites

На счет STD_LOGIC_VECTOR

Этот тип отражает реальное поведение электрических схем. Например, с его помощью можно описывать выходы с тремя состояниями, с открытым коллектором (стоком) и прочее. Но здесь уже надо изучать не программирование, а схемотехнику (совсем немного, хватит школьных знаний физики).

Share this post


Link to post
Share on other sites

Резюмируя...

Спасибо, практически исчерпывающий ответ.

 

Этот тип отражает реальное поведение электрических схем. Например, с его помощью можно описывать выходы с тремя состояниями, с открытым коллектором (стоком) и прочее. Но здесь уже надо изучать не программирование, а схемотехнику (совсем немного, хватит школьных знаний физики).

Ну это я понял, да, непонятно что STD_LOGIC_VECTOR забыл в цепочки конвертаций между integer и bit_vector. Ну я еще читаю пока что)

Share this post


Link to post
Share on other sites

Это что за зверь? :laughing:

Это были советы вериложника по использованию VHDL? ;)

ну опечатался в одной цифре, все таки 4 года к VHDL не подходил

Share this post


Link to post
Share on other sites

Этот тип отражает реальное поведение электрических схем. Например, с его помощью можно описывать выходы с тремя состояниями, с открытым коллектором (стоком) и прочее. Но здесь уже надо изучать не программирование, а схемотехнику (совсем немного, хватит школьных знаний физики).

 

Вот-вот, именно электрических схем. При проектировании функциональных блоков внутри FPGA он бывает полезен исключительно из-за нерадивости проектантов тулзов, которые, во-первых, все интерфейсы генерируемых блоков поддержали исключительно через него, и во-вторых, потому что не реализовали автоматическую генерацию переходников для тестов от исходных типизированных интерфейсов компонентов к выраженным через std_logic синтезированным результатам.

Share this post


Link to post
Share on other sites

Ну это я понял, да, непонятно что STD_LOGIC_VECTOR забыл в цепочки конвертаций между integer и bit_vector. Ну я еще читаю пока что)

Как грится, НЕНУЖЕН он там. :)

 

Есть в пакете IEEE.numeric_bit функции

  --============================================================================
  -- Conversion Functions
  --============================================================================

  -- Id: D.1
  function TO_INTEGER (ARG: UNSIGNED) return NATURAL;
    attribute builtin_subprogram of
        TO_INTEGER[UNSIGNED return NATURAL]: function is "numstd_conv_integer_un";.
  -- Result subtype: NATURAL. Value cannot be negative since parameter is an
  --         UNSIGNED vector.
  -- Result: Converts the UNSIGNED vector to an INTEGER.

  -- Id: D.2
  function TO_INTEGER (ARG: SIGNED) return INTEGER;
    attribute builtin_subprogram of
        TO_INTEGER[SIGNED return INTEGER]: function is "numstd_conv_integer_si";.
  -- Result subtype: INTEGER
  -- Result: Converts a SIGNED vector to an INTEGER.

  -- Id: D.3
  function TO_UNSIGNED (ARG, SIZE: NATURAL) return UNSIGNED;
    attribute builtin_subprogram of
        TO_UNSIGNED [NATURAL, NATURAL return UNSIGNED]: function is "numbit_conv_unsigned_nu";
  -- Result subtype: UNSIGNED(SIZE-1 downto 0)
  -- Result: Converts a non-negative INTEGER to an UNSIGNED vector with
  --         the specified size.

  -- Id: D.4
  function TO_SIGNED (ARG: INTEGER; SIZE: NATURAL) return SIGNED;
    attribute builtin_subprogram of
        TO_SIGNED [INTEGER, NATURAL return UNSIGNED]: function is "numbit_conv_signed_is";
  -- Result subtype: SIGNED(SIZE-1 downto 0)
  -- Result: Converts an INTEGER to a SIGNED vector of the specified size.

 

Если вам надо целый сконвертировать в bit_vector, то делаете в зависимости от знаковости целого

bit_vector (to_signed (value, width))

или

bit_vector (to_unsigned (value, width)).

 

Соответственно, наоборот:

to_integer (signed (value))

или

to_integer (unsigned (value)).

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...