Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Industrial programming >> VHDL

Файл стимула читается в тестовом стенде с помощью TEXTIO

Чтение значений сигнала из файла — это альтернативный способ создания стимулов для тестируемого устройства (DUT). Последовательность тестового стенда и синхронизация жестко запрограммированы в файле стимула, который считывается тестовым стендом VHDL построчно. Это позволяет вам легко изменить шаблон сигнала, который вы хотите подать на тестовый объект.

Иногда у вас есть очень специфический тестовый шаблон или последовательность событий, через которые вы хотите провести тестируемое устройство. Этого можно добиться, указав в файле ASCII значения сигналов, которые должен иметь каждый сигнал, а также относительное время моделирования, в которое они должны изменяться. Роль испытательного стенда VHDL в такой стратегии заключается в считывании данных из файла стимулов и применении значений на входах тестируемого устройства в нужное время.

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

Этот пост в блоге является частью серии статей об использовании библиотеки TEXTIO в VHDL. Прочтите другие статьи здесь:

Как инициализировать ОЗУ из файла с помощью TEXTIO

Растровое изображение файла BMP, прочитанное с помощью TEXTIO

Тестовый пример

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

Объект MUX показан ниже.

entity mux_4 is
  port(
    -- Data in
    din_0 : in unsigned(7 downto 0);
    din_1 : in unsigned(7 downto 0);
    din_2 : in unsigned(7 downto 0);
    din_3 : in unsigned(7 downto 0);

    -- Selector
    sel  : in unsigned(1 downto 0);

    -- Data out
    dout : out unsigned(7 downto 0));
end entity;

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

signal din_0 : unsigned(7 downto 0);
signal din_1 : unsigned(7 downto 0);
signal din_2 : unsigned(7 downto 0);
signal din_3 : unsigned(7 downto 0);
signal sel  : unsigned(1 downto 0);
signal dout : unsigned(7 downto 0);

Мы используем метод создания объекта для создания экземпляра MUX с меткой «DUT» в верхней части области архитектуры нашего тестового стенда. Сигналы объектов подключаются к сигналам локального тестового стенда с теми же именами, как показано в коде ниже.

DUT: entity work.mux_4(rtl)
port map (
    din_0 => din_0,
    din_1 => din_1,
    din_2 => din_2,
    din_3 => din_3,
    sel  => sel,
    dout => dout
);

Файл стимула

Файл стимула может иметь множество различных форматов, представленный здесь — это всего лишь пример, который я придумал во время написания этой статьи. Тем не менее, когда вы поймете, как я его создал, вы сможете изменить его в соответствии со своими потребностями.

В приведенном ниже листинге показан полный файл стимула, использованный в этом примере.

# Column description:
# wait_time | sel | din_0 | din_1 | din_2 | din3 # Optional console printout

0 ns 0 AA BB CC DD # Setting initial values
10 ns 1 AA BB CC DD # Testing by changing the selector signal
10 ns 2 AA BB CC DD
10 ns 3 AA BB CC DD
10 ns 3 A1 B1 C1 D1 # Testing by changing all data inputs
10 ns 3 A2 B2 C2 D2
10 ns 3 A3 B3 C3 D3
10 ns 3 00 00 00 D2 # Changing all unselected inputs
10 ns 3 01 02 03 D2
10 ns 3 11 22 33 D2
1 ns 0 CC DD EE FF # Changing all inputs fast
1 ns 1 DD EE FF CC
1 ns 2 EE FF CC DD
1 ns 3 FF CC DD EE
10 ns 0 00 00 00 00 # Simulation stop

Давайте пока проигнорируем комментарии, они отмечены зеленым цветом и всегда начинаются с символа «#». Каждая строка представляет один временной шаг в моделировании. В каждой строке есть шесть столбцов команд, на самом деле семь столбцов текста, но первые два столбца относятся к одному и тому же элементу данных.

Текстовые столбцы один и два описывают значение времени, на которое симулятор должен приостановиться в этой строке перед применением значений, перечисленных в других столбцах. Таким образом, абсолютное время симуляции при выполнении команды относится к событию, описанному в предыдущей строке. Мы используем только 0, 1 или 10 наносекунд, но это может быть что угодно, 1000 наносекунд или 1000 часов (1000 hr ) в этом отношении.

Остальные пять текстовых столбцов описывают значения сигналов, которые должны подаваться на входы ИУ. Они задаются в виде шестнадцатеричных литералов, а порядок сигналов — sel. , din_0 , din_1 , din_2 и, наконец, din_3 .

Теперь к комментариям. Есть два типа комментариев; однострочные комментарии и конечные комментарии. Наш испытательный стенд должен относиться к ним по-разному. Однострочные комментарии, например, в начале файла, будут игнорироваться. С другой стороны, завершающие комментарии должны выводиться на консоль симулятора. Мы можем использовать их, чтобы получить подсказки о том, что происходит во время моделирования.

Чтение файла стимула в VHDL

VHDL — не самый лучший язык для обработки текста, но он справляется со своей задачей. Поддержка динамических строк ограничена, и в ней отсутствуют удобные процедуры, например, для удаления или пропуска пробелов. Чтобы облегчить себе задачу, предположим, что файл со стимулами хорошо написан. Давайте позаботимся о том, чтобы всегда был один пробел между текстовыми элементами и один пробел между символом «#» и текстом комментария. Кроме того, в файле стимула нет лишних начальных или конечных пробелов.

PROC_SEQUENCER : process
  file text_file : text open read_mode is "stimulus.txt";
  variable text_line : line;
  variable ok : boolean;
  variable char : character;
  variable wait_time : time;
  variable selector : sel'subtype;
  variable data : dout'subtype;
begin

Декларативная область PROC_SEQUENCER процедура показана выше. Во-первых, мы объявляем специальный file объект, тип обработчика файла VHDL. Затем мы объявляем переменную типа line . Это просто тип доступа к строке, указатель на динамически выделяемый строковый объект. ok переменная логического типа предназначена для проверки успешности операций чтения. Наконец, мы объявляем четыре переменные char , wait_time , selector и data . Эти переменные предназначены для извлечения данных из каждого столбца из каждой строки текста.

  while not endfile(text_file) loop

    readline(text_file, text_line);

    -- Skip empty lines and single-line comments
    if text_line.all'length = 0 or text_line.all(1) = '#' then
      next;
    end if;

В теле процесса мы переходим прямо в цикл while, который будет перебирать каждую строку текста в файле стимула. readline процедура присваивает новую строку текста text_line переменная на каждой итерации этого цикла. После прочтения строки мы проверяем, пуста ли строка и является ли первый символ «#», и в этом случае мы сразу же переходим к следующей строке, используя next ключевое слово, чтобы пропустить итерацию цикла. Обратите внимание, что мы используем text_line.all. чтобы получить доступ к строке внутри line объект.

    read(text_line, wait_time, ok);
    assert ok
      report "Read 'wait_time' failed for line: " & text_line.all
      severity failure;

    hread(text_line, selector, ok);
    assert ok
      report "Read 'sel' failed for line: " & text_line.all
      severity failure;
    sel <= selector;

    hread(text_line, data, ok);
    assert ok
      report "Read 'din_0' failed for line: " & text_line.all
      severity failure;
    din_0 <= data;

    hread(text_line, data, ok);
    assert ok
      report "Read 'din_1' failed for line: " & text_line.all
      severity failure;
    din_1 <= data;

    hread(text_line, data, ok);
    assert ok
      report "Read 'din_2' failed for line: " & text_line.all
      severity failure;
    din_2 <= data;

    hread(text_line, data, ok);
    assert ok
      report "Read 'din_3' failed for line: " & text_line.all
      severity failure;
    din_3 <= data;

Далее следует ряд чтений из text_line объект. read и hread вызовы процедур пропускают начальные пробелы, поэтому нам не нужно выполнять фиктивные чтения для перемещения внутренней начальной позиции чтения внутри text_line объект. Мы могли бы опустить операторы assert, но я хочу, чтобы симуляция останавливалась в случае сбоя чтения. По крайней мере, в ModelSim симуляция не останавливается автоматически, когда это происходит. Мы назначаем каждую успешно прочитанную переменную соответствующему сигналу тестируемого устройства, за исключением wait_time переменная, которая не имеет соответствующего входа DUT.

    wait for wait_time;

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

    -- Print trailing comment to console, if any
    read(text_line, char, ok); -- Skip expected newline
    read(text_line, char, ok);
    if char = '#' then
      read(text_line, char, ok); -- Skip expected newline
      report text_line.all;
    end if;

  end loop;

  finish;

end process;

Наконец, когда программа выходит из состояния ожидания, мы ищем дополнительный комментарий в конце text_line. объект. Любой комментарий выводится на консоль с помощью оператора report после того, как мы удалили символ «#» и следующий за ним пробел с помощью фиктивного чтения.

После обработки последней строки текста из файла стимула цикл while завершается. Есть VHDL-2008 finish ключевое слово в конце процесса, отвечающее за остановку тестового стенда.

Вывод

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


# ** Note: Setting initial values
#    Time: 0 ns  Iteration: 1  Instance: /file_stim_tb
# ** Note: Testing by changing the selector signal
#    Time: 10 ns  Iteration: 0  Instance: /file_stim_tb
# ** Note: Testing by changing all data inputs
#    Time: 40 ns  Iteration: 0  Instance: /file_stim_tb
# ** Note: Changing all unselected inputs
#    Time: 70 ns  Iteration: 0  Instance: /file_stim_tb
# ** Note: Changing all inputs fast
#    Time: 91 ns  Iteration: 0  Instance: /file_stim_tbf
# ** Note: Simulation stop
#    Time: 104 ns  Iteration: 0  Instance: /file_stim_tb
# Break in Process PROC_SEQUENCER at file_stim_tb.vhd line 98

Форма сигнала для моделирования показана ниже. Он показывает визуальное представление того, как значения из нашего файла стимулов применяются к сигналам в указанные моменты времени моделирования.

Заключительные мысли

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

Однако одна вещь, которую мы не обсудили, — это проверка выходов тестируемого устройства. Наш пример тестового стенда вообще не проверяет выходные данные. Вы можете проверить поведение тестируемого устройства точно так же, как и в полном испытательном стенде VHDL, например, используя поведенческую модель для сравнения. Или вы можете изменить код и файл стимула, включив в него ожидаемые выходные значения. Какую бы стратегию вы ни выбрали, убедитесь, что вы создали испытательный стенд с самопроверкой и не полагаетесь на ручную проверку формы сигнала.


VHDL

  1. С# с использованием
  2. C Обработка файлов
  3. Класс файла Java
  4. Как инициализировать RAM из файла с помощью TEXTIO
  5. Как создать самопроверяющийся тестовый стенд
  6. Java BufferedReader:как читать файл в Java с примером
  7. Python JSON:кодировать (дампы), декодировать (загружать) и читать файл JSON
  8. Операции ввода-вывода файлов Verilog
  9. C — заголовочные файлы
  10. Что такое треугольный файл?