Использование Array Slices в VHDL - PullRequest
0 голосов
/ 22 мая 2018

Я пытаюсь создать синтезируемый код VHDL, который использует некоторые функции многомерного массива.RTL имеет массив из 64 слов (, называемый big_array_s , 64 x 16 бит ), используемый для хранения некоторых начальных значений LUT.Также в проекте используется массив из 4 слов ( small_array_s , 4 x 16 бит ).Существует требование назначить срез большого массива в маленький массив.Это проиллюстрировано в следующих фрагментах кода:

type small_array is array (0 to 3) of bit_vector(15 downto 0);
type big_array is array (0 to 64) of bit_vector(15 downto 0);

signal small_array_s : small_array;
signal big_array_s : big_array := init_array_func("test.dat");

init_array_func () - это функция VHDL, которая инициализирует big_array_s данными из файла ascii "test.dat".Раздел, в котором я застрял, назначает часть big_array_s для small_array_s.Например, что-то вроде

small_array_s  <= big_array_s(0 to 3);

- это то, чего мне нужно достичь с помощью RTL.Но это прямое назначение невозможно, поскольку LHS и RHS имеют разные типы массивов. У меня вопрос, как мне добиться такого среза массива в VHDL?


Другой метод, который я мог бы использовать, - это объявить тип big_array как массив small_array.Например,

type small_array is array (0 to 3) of bit_vector(15 downto 0);
type big_array is array (0 to 15) of small_array;

signal small_array_s : small_array;
signal big_array_s : big_array;

В этом случае оператор

small_array_s  <= big_array_s(0);

будет работать без сбоев.Но я сомневаюсь, как инициализировать 3D-массив big_array_s с учетом поддержки синтеза.

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

В вашем вопросе нет объявленных многомерных (3D) типов массивов.Ваше второе объявление big_array имеет один индекс.

IEEE Std 1976-2008

5.3.2 Типы массивов
5.3.2.1 Общие

Объект массивахарактеризуется количеством показателей (размерностью массива);тип, положение и диапазон каждого индекса;и тип и возможные ограничения элементов.Порядок индексов значителен.

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

Для первого метода вы можете объявлять подтипы вместо независимых типов.Следствием этого является то, что они одного типа.

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

Создание работающего примера Minimal, Complete and Verifiable будет выглядеть примерно так для вашего первого фрагмента:

entity some_array is
end entity;

architecture fuu of some_array is
    -- type small_array is array (0 to 3) of bit_vector(15 downto 0);
    -- type big_array is array (0 to 64) of bit_vector(15 downto 0);
    type some_array is array (natural range <>) of bit_vector(15 downto 0);
    subtype small_array is some_array(0 to 3);
    subtype big_array is some_array (0 to 64);

    impure function init_array_func (init_file:  in string) return 
             big_array is
        use std.textio.all;
        file big_array_file: text is in init_file;
        variable file_line:         line;
        variable big_array_val:     big_array;
    begin
        for i in big_array'range  loop
            readline (big_array_file, file_line);
            read (file_line, big_array_val(i));
        end loop;
        return big_array_val;
    end function;

    function to_string (inp: bit_vector) return string is
        variable image_str: string (1 to inp'length);
        alias input_str:  bit_vector (1 to inp'length) is inp;
        begin
        for i in input_str'range loop
            image_str(i) := character'VALUE(bit'IMAGE(input_str(i)));
        end loop;
        return image_str;
    end function;

    signal small_array_s : small_array;
    signal big_array_s : big_array := init_array_func("test.dat");

begin
    small_array_s  <= big_array_s(0 to 3);

MONITOR:
    process
    begin
        wait on small_array_s;
        wait for 0 ns; -- not the default value;
        for i in small_array_s'range loop
            report "small_array_s(" & integer'image(i) & ") = " &
                    to_string(small_array_s(i));
        end loop;
    end process;

end architecture;

И это дает:

ghdl -r some_array
some_array.vhdl: 47: 13:@ 0ms: (примечание к отчету): small_array_s (0) = 0000000000000000
some_array.vhdl: 47: 13: @ 0ms: (примечание к отчету): small_array_s (1) = 0000000000000001
some_array.vhdl: 47: 13:@ 0ms: (примечание к отчету): small_array_s (2) = 0000000000000010
some_array.vhdl: 47: 13: @ 0ms: (примечание к отчету): small_array_s (3) = 0000000000000011

Что правильнопоказывает первые четыре значения, инициализированные для сигнализации big_array_s для известного содержимого test.dat.

Функции совместимы с ревизиями стандарта VHDL ранее -2008 и вырезаны, вставлены и отредактированы из другого примераs.

Обратите внимание, что для функции init_array_func требуется файл test.dat, содержащий не менее 65 строк допустимых значений для элемента big_array, и такую ​​функцию можно также обобщить, передав число элементов big_array (length), возвращаязначение произвольного подтипа some_array.

Вы также можете выполнить явное преобразование типов между типами массивов с одинаковыми измерениями (числом индексов) с типами элементов, которые тесно связаны:

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

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

...
- Типы массива - два типа массива тесно связаны тогда и только тогда, когда типы имеют одинаковую размерность и типы элементовтесно связаны

Обратите внимание, что тип элемента, который является типом массива, должен соответствовать тем же требованиям, что и его элемент (подэлемент, здесь бит типа).

Использование исходногообъявления типов без объявлений подтипа, единственным другим изменением будет присвоение:

small_array_s  <= small_array(big_array_s(0 to 3));

Где выражение операнда преобразования типа big_array_s (от 0 до 3) имеет ту же размерность, что и small_array_s, и тип элемента тесно связан(оба bit_vector (15 до 0)).

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

Обратите внимание, что преобразование типов также рассчитывает на семантику присваивания, обеспечивающую соответствиеэлементы для цели назначения и выражения с правой стороны:

14.7.3.4 Обновление сигнала

Чтобы обновить сигнал в течение данного цикла моделирования, процесс ядра сначала определяет движущие и эффективные значения этого сигнала.Затем процесс ядра обновляет переменную, содержащую значение возбуждения, с помощью вновь определенного значения возбуждения.Ядро также обновляет переменную, содержащую текущее значение сигнала, с помощью нового определенного действующего значения, следующим образом:

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

И бит о преобразовании подтипа означает, что диапазоны индекса не должны совпадать, выражениеи цель должна иметь соответствующие элементы.

0 голосов
/ 22 мая 2018

Для нарезки массива вы можете использовать оператор создания, копирующий один бит_вектор (от 15 до 0) за раз.

Что касается трехмерного массива, то у меня плохой опыт синтеза с использованием Xilinx Vivado.Vivado распознает его как трехмерный массив, сообщает, что он не поддерживается, и реализует несколько регистров.

...