УДК 004.438 А.Е. ШАТАЛОВ, Н.И. ФОМИН A.E. SHATALOV, N.I. FOMIN ЭМУЛЯЦИЯ РАБОТЫ ЭНЕРГОНЕЗАВИСИМОЙ ПАМЯТИ НА ЯЗЫКЕ VERILOG EMULATION OF NON-VOLATILE MEMORY ON VERILOG В работе описано создание модуля – эмулятора энергонезависимой памяти на языке Verilog. Сохранение и считывание данных осуществляется из файла. В работе дается краткое описание основных операторов, необходимых для работы с файловой системой посредством языка Verilog, дан пример программы и приведена временная диаграмма, поясняющая принцип работы эмулятора. Ключевые слова: Verilog, testbench, эмулятор, энергонезависимая память. The paper describes a module - emulator of non-volatile memory in the language Verilog. Saving and reading data provided from the file. The paper gives a brief description of the operators needed to work with the file system through language Verilog, an example program and a timing chart for explaining the operation of the emulator. Keywords: Verilog, testbench, emulator, non-volatile memory. В современных цифровых устройствах огромное распространение нашло применение энергонезависимой памяти для хранения параметров функционирования прибора. Кроме того, наличие пользовательского интерфейса позволяет пользователю самому устанавливать некоторые параметры. Простейшим примером может являться установка уровня громкости динамиков телевизора. Разработчик, пишущий программное обеспечение для ПЛИС может столкнуться с необходимостью хранения значений некоторых регистров в энергонезависимой памяти. При написании несентезируемых Testbench-модулей для тестирования такого ПО, бывает полезно предварительно создать программный эмулятор микросхемы памяти. Естественно, широкий выбор микросхем памяти подразумевает под собой различные типы интерфейсов, управляющих и считываемых сигналов. Поэтому, в рамках данной статьи будет рассмотрен упрощенный параллельный интерфейс однокристальной микросхемы памяти объемом 8х64 бит. Установка уровней напряжений на выходах, и реакция на входные сигналы происходит мгновенно. Таблица 1 – Описание входов и выходов микросхемы Наименование Тип Разрядность, бит Описание CS Вход 1 Выбор кристалла. RW Вход 1 Переключение режимов чтения/записи. 1 – чтение, 0 – запись. A Вход 6 Адрес. IO Вход/выход 8 Вход/выход. Назначение порта определяется сигналом на входе OE. Данные, записанные в память необходимо сохранять в файл при каждом обращении к микросхеме. Для работы с файловой системой компьютера понадобятся следующие операторы: $fopen, $fscanf, $fdisplay, $fseek, $fclose. Рассмотрим каждый из них подробнее. Работа с файлом начинается с его открытия, установки способа работы с файлом и получения его дескриптора. Все эти функции выполняет оператор $fopen. Синтаксис команды: <file_handler> = $fopen("<file_name>", "<file_mode>"); 1 где: <file_handler> – дескриптор файла, полученный функцией $fopen, <file_name> – путь и имя файла, включая расширение, <file_mode> – режим открытия файла. Подробнее о режиме открытия можно прочитать в стандарте Verilog 2001 (IEEE Std 1364-2001). Функция $fopen должена выполняться перед вызовом любых команд, связанных с файлом. Для чтения данных из файла необходим оператор $fscanf. Синтаксис команды: <ret_val> = $fscanf(<file_handler>, "<string_format>", <reg>); $fscanf возвращает количество прочитанных данных в регистр <ret_val>. При возникновении ошибки функция вернет 0. <file_handler> – дескриптор файла, полученный функцией $fopen. <string_format> – формат, в котором в текстовом виде записаны данные, в данном случае «%h». Для записи данных в файл используется оператор $fdisplay. Запись должна производиться в том же формате, что и чтение, в конце строки добавляется символ переноса каретки. Синтаксис команды: $fdisplay(<file_handler>, "<string_format>", <reg>); В регистре <reg> содержаться данные для записи в файл. Чтение и запись в файл происходит построково. Каждая строка хранит 1 байт данных в текстовом виде в шестнадцатеричной записи и оканчивается двумя непечатными символами (например, «01\r\n»). Чтобы прочитать/переписать байт данных, необходимо установить каретку оператором $fseek. Его синтаксис: < ret_val > = $fseek(<file_handler>, <offset>, 0); Значение <offset> определяет положение каретки относительно начала файла. Т.к. строка состоит из четырех символов, смещение каретки рассчитывается как произведение адреса регистра памяти на 4. Для закрытия файла по его дескриптору используется команда $fclose. Ее синтаксис: $fclose(<file_handler>); В программном коде логично сделать так, чтобы файл закрывался при завершении работы с микросхемой, т.е. по фронту сигнала cs. Конечно, возможны ситуации, когда симуляция остановится раньше, чем будет вызвана команда $fclose, в таком случае файл закроется автоматически. Листинг программы: module Memory #( parameter FILENAME = "src/data.txt" // Имя и путь к файлу ) ( input wire cs, // Сигнал "Выбор кристалла" input wire rw, // Сигнал "Чтение/запись" input wire [5:0] a, // Адресный вход inout reg [7:0] io // Ввод/вывод данных ); integer file_h, ret_val; // Дескриптор, возвращаемое значение 2 // Проверка и подготовка файла данных (опционально) initial Init; // По спаду сигнала cs открыть файл для чтения/записи always @(negedge cs) file_h = $fopen(FILENAME, "r+"); // По фронту сигнала cs закрыть файл always @(posedge cs) $fclose(file_h); // По фронту сигнала rw прочитать регистр always @(posedge rw) begin if (!cs) begin // Переместить каретку в позицию, соответствующую адресу // на входе "а" ret_val = $fseek(file_h, a*4, 0); // Прочитать байт в регистр io ret_val = $fscanf(file_h, "%h", io); end end // По спаду сигнала rw записать регистр в файл always @(negedge rw) begin if (!cs) begin // Переместить каретку в позицию, соответствующую адресу // на входе "а" ret_val = $fseek(file_h, a*4, 0); // Записать значение регистра io в файл $fdisplay(file_h, "%h", io); end end // Сценарий проверки файла данных task Init; // Открыть файл для чтения и записи file_h = $fopen(FILENAME, "r+"); // Если файла не существует if (!file_h) begin //$finish; // Остановить симуляцию FileFilling; // Выполнить сценарий FileFilling end else begin // Если файл существует, необходимо проверить, // что он содержит в себе 64 строки. Для этого необходимо // переместить каретку к строке №64 ret_val = $fseek(file_h, 63*4, 0); // Прочитать строку ret_val = $fscanf(file_h, "%h", io); // Если $fscan вернула ошибку if (&ret_val) begin $fclose(file_h); // Закрыть файл FileFilling; // Выполнить сценарий FileFilling 3 end end $fclose(file_h); endtask // Закрыть файл // Сценарий подготовки файла task FileFilling; integer i; // Счетчик // Открыть файл для перезаписи file_h = $fopen(FILENAME, "w"); // Записать 64 строки формата "00\r\n" for (i = 0; i < 64; i = i + 1) $fdisplay(file_h, "%h", 8'h00); endtask endmodule Симуляция работы эмулятора показана на рисунке 1. Рисунок 1 – Временная диаграмма работы эмулятора СПИСОК ЛИТЕРАТУРЫ 1. Verilog® HDL. Quick Reference Guide by Stuart Sutherland [Электронный ресурс] – Режим доступа: www.sutherland-hdl.com. Дата обращения: 2001 г. 2. IEEE Std 1364-2001. IEEE Standard Verilog® Hardware Description Language. – Введ. 2001-09-28. – The Institute of Electrical and Electronics Engineers, Inc, 2001. – 778 с. Шаталов Андрей Евгеньевич ФГБОУ ВПО «Госуниверситет-УНПК», г. Орел Аспирант кафедры «Приборостроение, метрология и сертификация» Тел. +7 (919) 260-37-40 E-mail: ae.shatalov@gmail.com Фомин Николай Иванович ФГБОУ ВПО «Госуниверситет-УНПК», г. Орел Аспирант кафедры «Электроника, вычислительная техника и информационная безопасность» Тел. +7 (953) 610-63-47 E-mail: evtib_gu_unpk@mail.ru 4