1 1 1 1 1 1 1 1 1 1 Рейтинг 0.00 (0 Голоса(ов)

Вывод отладочной информации в консоль и в файл в Verilog

Очень часто возникает необходимость вывести во время симуляции Verilog-овского файла отладочную информацию на консоль, либо в файл.

Для этого служат системные функции $display, $write, $strobe, $monitor, а также их аналоги для записи в файл.

$display выводит на экран указанную строку, после чего добавляет перевод строки. $write делает то же самое, но без добавления перевода строки. $monitor осуществляет вывод в консоль при изменении значения любой из указанных в выводе переменных. $strobe выводит значение в конце временного интервала.

При написании используется C-подобный синтаксис, с модификаторами формата выводимого значения: 

Код Verilog:
$display("display a:%h b:%h @ %0t", a, b, $time);
 %d  Десятичное значение
 %b  Двоичное значение
 %h  Шестнадцатиричное значение
 %o  Восьмиричное значение
 %c  Символ
%f  Число с плавающей запятой
 %v  Тип цепи

supply

7

Su

strong

6

St

pull

5

Pu

large

4

La

weak

3

We

medium

2

Me

small

1

Sm

highz

0

HiZ

 %m  Имя в иерархии
 %s  Строка
%t  Время

Сразу оговорюсь: данные функции являются несинтезируемыми, поэтому возможность их использования в синтезируемом файле определяется средой, в которой Вы работаете (например Xilinx ISE "переваривает" их, а вот Altera Quartus - нет). Другая ситуация с файловыми аналогами этих функций. При их применении в ситезируемом модуле среда будет ругаться (еще на уровне открытия файла.

Запись в файл

Для открытия файла служит функции $fopen (имя файла), для закрытия - $fclose (имя файла) .

При открытии файла можно использовать знакомые программистам на C конструкции, указывающие права при открытии: "w" - на запись, "r" - на чтение, "r+" - на чтение и запись, "a" - на дополнение. К каждому из модификаторов можно добавить "b", например "wb", указав, что файл является бинарным (хотя в случае с Верилогом в этом нет особого смысла). Впрочем, существуют варианты функции, явно указываюшие на права открытия, например $fopenr - открыть на чтение.

Запись в файл осуществляется функциями $fdisplay, $fwrite, $fstrobe, $fmonitor, которые работают аналогично их "консольным" аналогам.

Для чтения памяти существуют функции $readmemb ("файл", идентификатор памяти [,стартовый адрес[,конечный адрес]])  и $readmemh ("файл", идентификатор памяти [,стартовый адрес[,конечный адрес]]) .

Примеры использования этих функций:

Код Verilog:
integer file ; reg a, b, c; initial begin file = $fopen("data.dat","wb"); a = b & c ; $fdisplay(file, "Выходные данные: %b", a) ; $fclose(file) ; end

 

Код Verilog:
reg [3:0] memory [15:0] ; initial begin $readmemb("data.bin", memory) ; end

Сразу хочу оговориться: в Verilog не предусмотрена запись бинарного файла (хотя чтение есть). Некоторые предлагают использовать модификатор типа данных %u.  Этот метод работает, но:

  1. Не во всех средах, например Xilinx ISim этот тип не понимает
  2. Запись происходит в 32-битном формате, что неудобно для записи 16-битных и 8-битных данных.

Лично я для себя использую такой "лайфхак": я пишу символ с кодом байта который хочу записать:

Код Verilog:
$fwrite(foutb,"%c",data[15:8]); $fwrite(foutb,"%c",data[7:0]);

Чтение из файла

С чтением из файла все не так просто... Вроде и функций достаточно, но вот работают они... Например, fread у меня отказался работать как в Altera Quartus II, так и в Xilinx ISE. Говорил про неверный дескриптор файла при попытке чтения (в Xilinx ISE). Пришлось использовать fgetc.

Чтение форматированного текста (sscanf парсит строку, а не читает файл): 

Код Verilog:
integer file, count; count = $fscanf(file, format, args); count = $sscanf(string, format, args);

Поиск конца файла:

Код Verilog:
integer file; reg eof; eof = $feof(file);

Чтение одиночного символа:

Код Verilog:
integer file, char; char = $fgetc(file);

Вернуть символ в файловый буфер (при следуещем чтении символ будет прочитан повторно, возвращает символ в случае успеха, и EOF в случае ошибки): 

Код Verilog:
integer file; reg [7:0] char, r; r = $ungetc(char, file);

Прочитать строку: 

Код Verilog:
integer file, r; reg [n*8-1:0] string; r = $fgets(string, file);

Узнать позицию в файле:

Код Verilog:
integer file, position; position = $ftell(file);

Установить позицию в файле:

Код Verilog:
`define SEEK_SET 0 `define SEEK_CUR 1 `define SEEK_END 2 integer file, offset, position, r; r = $fseek(file, 0, `SEEK_SET); /* Начало*/ r = $fseek(file, 0, `SEEK_CUR); /* Нет эффекта */ r = $fseek(file, 0, `SEEK_END); /* Конец файла */ r = $fseek(file, position, `SEEK_SET); /* Предыдущее значение */

Чтение бинарных данных:

Код Verilog:
integer r, file, start, count; reg [15:0] mem[0:10], r16; r = $fread(file, mem[0], start, count); r = $fread(file, r16);

Оставьте свой комментарий

Оставить комментарий как гость

0
  • Комментариев нет
Dx WW