Dominando la E/S de Archivos en Verilog: Abrir, Leer, Escribir y Cerrar
Verilog proporciona tareas y funciones de sistema que permiten abrir archivos, escribir valores en ellos, leer valores desde archivos y cargarlos en variables, y cerrar archivos.
Apertura y cierre de archivos
module tb;
// Variable para almacenar el manejador de archivo
integer fd;
initial begin
// Abre un nuevo archivo llamado "my_file.txt"
// con permisos de escritura, y almacena el puntero
// del manejador en la variable "fd"
fd = $fopen("my_file.txt", "w");
// Cierra el manejador de archivo apuntado por "fd"
$fclose(fd);
end
endmodule
Modos de apertura de archivos
| Argumento | Descripción |
|---|---|
| "r" o "rb" | Abrir para lectura |
| "w" o "wb" | Crear un nuevo archivo para escritura. Si el archivo existe, se trunca a longitud cero y se sobrescribe |
| "a" o "ab" | Si el archivo existe, agregar (abrir para escritura al final), sino crear uno nuevo |
| "r+", "r+b" o "rb+" | Abrir para lectura y escritura |
| "w+", "w+b" o "wb+" | Truncar o crear para actualización |
| "a+", "a+b", o "ab+" | Agregar, o crear nuevo archivo para actualización al final |
Cómo escribir en archivos
| Función | Descripción |
|---|---|
| $fdisplay | Similar a $display, pero escribe en archivo |
| $fwrite | Similar a $write, pero escribe en archivo |
| $fstrobe | Similar a $strobe, pero escribe en archivo |
| $fmonitor | Similar a $monitor, pero escribe en archivo |
Cada una de las funciones anteriores imprime valores en radix decimal por defecto. También tienen tres versiones adicionales para imprimir en binario, octal y hexadecimal.
| Función | Descripción |
|---|---|
| $fdisplay() | Imprime en decimal por defecto |
| $fdisplayb() | Imprime en binario |
| $fdisplayo() | Imprime en octal |
| $fdisplayh() | Imprime en hexadecimal |
module tb;
integer fd;
integer i;
reg [7:0] my_var;
initial begin
// Crear un nuevo archivo
fd = $fopen("my_file.txt", "w");
my_var = 0;
$fdisplay(fd, "Valor mostrado con $fdisplay");
#10 my_var = 8'h1A;
$fdisplay(fd, my_var); // Muestra en decimal
$fdisplayb(fd, my_var); // Muestra en binario
$fdisplayo(fd, my_var); // Muestra en octal
$fdisplayh(fd, my_var); // Muestra en hex
// $fwrite no imprime el carácter de nueva línea '\n'
// automáticamente al final de cada línea; así que todos
// los valores impresos abajo aparecerán en la misma línea
$fdisplay(fd, "Valor mostrado con $fwrite");
#10 my_var = 8'h2B;
$fwrite(fd, my_var);
$fwriteb(fd, my_var);
$fwriteo(fd, my_var);
$fwriteh(fd, my_var);
// Saltar a nueva línea con '\n', e imprimir con strobe
// que toma el valor final de la variable después de
// asignaciones no bloqueantes
$fdisplay(fd, " Valor mostrado con $fstrobe");
#10 my_var <= 8'h3C;
$fstrobe(fd, my_var);
$fstrobeb(fd, my_var);
$fstrobeo(fd, my_var);
$fstrobeh(fd, my_var);
#10 $fdisplay(fd, "Valor mostrado con $fmonitor");
$fmonitor(fd, my_var);
for(i = 0; i < 5; i= i+1) begin
#5 my_var <= i;
end
#10 $fclose(fd);
end
endmodule
Registro de simulación
Valor mostrado con $fdisplay 26 00011010 032 1a Valor mostrado con $fwrite 43001010110532b Valor mostrado con $fstrobe 60 00111100 074 3c Valor mostrado con $fmonitor 60 0 1 2 3 4
Cómo leer archivos
Lectura de una línea
La función de sistema $fgets lee caracteres desde el archivo especificado por fd hacia la variable str hasta que str se llena, o se lee y transfiere un carácter de nueva línea a str, o se encuentra una condición de EOF.
Si ocurre un error durante la lectura, devuelve código cero; de lo contrario, devuelve el número de caracteres leídos.
Detección de EOF
La función de sistema $feof devuelve un valor no cero cuando se encuentra EOF, y cero en caso contrario, para un descriptor de archivo dado como argumento.
module tb;
reg[8*45:1] str;
integer fd;
initial begin
fd = $fopen("my_file.txt", "r");
// Seguir leyendo líneas hasta encontrar EOF
while (! $feof(fd)) begin
// Obtener la línea actual en la variable 'str'
$fgets(str, fd);
// Mostrar el contenido de la variable
$display("%0s", str);
end
$fclose(fd);
end
endmodule
Múltiples argumentos en fdisplay
Cuando se dan múltiples variables a $fdisplay, simplemente imprime todas las variables en el orden dado, una tras otra, sin espacio.
module tb;
reg [3:0] a, b, c, d;
reg [8*30:0] str;
integer fd;
initial begin
a = 4'ha;
b = 4'hb;
c = 4'hc;
d = 4'hd;
fd = $fopen("my_file.txt", "w");
$fdisplay(fd, a, b, c, d);
$fclose(fd);
end
endmodule
Registro de simulación
10111213
Formateo de datos en una cadena
El primer argumento en la función de sistema $sformat es el nombre de la variable donde se coloca el resultado. El segundo argumento es el format_string que indica cómo deben formatearse los argumentos siguientes en una cadena.
module tb;
reg [8*19:0] str;
reg [3:0] a, b;
initial begin
a = 4'hA;
b = 4'hB;
// Formatear 'a' y 'b' en una cadena según
// el formato, y almacenar en la variable 'str'
$sformat(str, "a=%0d b=0x%0h", a, b);
$display("%0s", str);
end
endmodule
Registro de simulación
xcelium> run a=10 b=0xb xmsim: *W,RNQUIE: La simulación ha finalizado.
Verilog
- Dominar Verilog: Tutorial completo para diseño de circuitos digitales
- Dominar la concatenación en Verilog: Guía práctica
- Comprender las asignaciones en Verilog: tipos, sintaxis y mejores prácticas
- Bloqueante vs. No bloqueante en Verilog: Diferencias clave explicadas
- Dominar las funciones en Verilog para diseño RTL eficiente
- Comprender las Tasks en Verilog: Funciones vs Tasks, sintaxis y uso
- Generador de reloj en Verilog: Guía de diseño e implementación
- Dominar las funciones matemáticas en Verilog para diseño de hardware eficiente
- Dominar $timeformat en Verilog: Control de precisión y visualización
- Comprender e imprimir timescales de Verilog en cualquier alcance
- Guía para Principiantes de Verilog: Ejemplo Hola Mundo