VHDL логический вектор для назначения записи - PullRequest
0 голосов
/ 27 января 2019

Предположим, я определил запись с полями std_ulogic_vector для представления большего std_ulogic_vector.Преобразовать эту запись в большой вектор просто, используя конкатенацию (без знания размера для каждого поля).

Как мне сделать обратное, например, преобразовать большое std_ulogic_vector обратно в запись?

Пример:

architecture RTL of record_conversion is
  type data_t is record
    top    : std_ulogic_vector(4 downto 0);
    bottom : std_ulogic_vector(2 downto 0);
  end record data_t;

  signal record_s : data_t;
  signal vector_s : std_ulogic_vector(7 downto 0);
begin

  -- vector to record works
  --vector_s <= record_s.top & record_s.bottom;

  -- record to vector does not work
  (record_s.top, record_s.bottom) <= vector_s;

  -- tedious solution with knowledge of the field size
  record_s.top    <= vector_s(7 downto 3);
  record_s.bottom <= vector_s(2 downto 0);

end architecture;

Ответы [ 2 ]

0 голосов
/ 28 января 2019

Существует несколько других методов, кроме использования вызовов подпрограмм для присвоения элементов одного типа элементам другого типа.

Вы можете использовать квалифицированное выражение:

  record_s <= data_t'(vector_s(7 downto 3), vector_s (2 downto 0));

Гдеагрегат состоит из двух частей vector_s с явным типом, соответствующим записи.См. IEEE Std 1076-2008 9.3.6 Квалифицированные выражения.

Во время моделирования подтверждаются новые значения для сигналов.См. 14.7.3.4 Обновление сигнала:

b) Если S является составным сигналом (включая фрагмент массива), эффективное значение S неявно преобразуется в подтип S. Преобразование подтипапроверяет, что для каждого элемента S есть соответствующий элемент в эффективном значении, и наоборот.Произошла ошибка, если эта проверка не удалась.Результат этого преобразования подтипа затем присваивается переменной, представляющей текущее значение S.

Помимо наличия соответствующего преобразования подтипа элемента (подэлемента, ...) изменяет диапазоны индекса, чтобы соответствовать цели.

Вы можете указать диапазоны индексов слайсов с диапазонами индексов подтипов:

library ieee;
use ieee.std_logic_1164.all;

entity record_conversion is
end entity;

architecture subtypes of record_conversion is
  type data_t is record
    top    : std_ulogic_vector(4 downto 0);
    bottom : std_ulogic_vector(2 downto 0);
  end record data_t;

  signal record_s : data_t;
  signal vector_s : std_ulogic_vector(7 downto 0);
  subtype t is std_logic_vector (
        vector_s'LEFT downto vector_s'LEFT - record_s.top'length + 1
  );
  subtype b is std_logic_vector (
        vector_s'LEFT - record_s.top'length downto 0
  );
begin

  record_s <= data_t'(vector_s(t'range), vector_s(b'range));

end architecture;

Здесь срезы диапазонов индексов подтипов правых элементов выражения.

Вы можетеопишите срезы с псевдонимами:

architecture aliases of record_conversion is
    type data_t is record
        top:     std_ulogic_vector(4 downto 0);
        bottom:  std_ulogic_vector(2 downto 0);
    end record data_t;

    signal record_s:  data_t;
    signal vector_s:  std_ulogic_vector(7 downto 0);
    alias vector_s_top: std_ulogic_vector(record_s.top'range) is
        vector_s(7 downto 3);
    alias vector_s_bottom: std_ulogic_vector(record_s.bottom'range) is
        vector_s (2 downto 0);

begin
    record_s <= data_t'(vector_s_top, vector_s_bottom);
end architecture;

Здесь два псевдонима описывают поля vector_s.Если вы гарантированно всегда назначаете составной объект записи, вы можете фактически отказаться от записей и просто использовать псевдонимы.Наиболее близкий VHDL приходит к объединениям.

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

Квалифицированные выражения, объявления подтипов и псевдонимы не требуют дополнительных затрат на моделированиев то время как вызовы подпрограммы делают.

0 голосов
/ 27 января 2019

Обычно хорошей идеей является оборачивать такое преобразование в функции и с subtype для результирующего вектора, например:

...
  constant LEN : integer := 8;  -- Number of bits in data_t

  type data_t is record
    top    : std_ulogic_vector(4 downto 0);
    bottom : std_ulogic_vector(2 downto 0);
  end record data_t;

  subtype vector_t is std_ulogic_vector(LEN - 1 downto 0);

  function data_to_vector(data : data_t) return std_ulogic_vector is
    variable res_v : vector_t;
  begin
    res_v := data.top & data.bottom;
    return res_v;
  end function;

  function vector_to_data(vector : vector_t) return data_t is
    variable res_v : data_t;
  begin
    res_v.top    := vector(LEN - 1 downto LEN - res_v.top'length);
    res_v.bottom := vector(res_v.bottom'length - 1 downto 0);
    return res_v;
  end function;

  signal record_s : data_t;
  signal vector_s : vector_t;

begin

  record_s <= vector_to_data(vector_s);
  vector_s <= data_to_vector(record_s);
...

Возможно, следует добавить еще одну константу для определения разделения между top и bottom.

...