Note that Synopsys' VCS 6.1, NC-Verilog 3.3, and MTI's ModelSim 5.5
offer native support for the IEEE-1364 2001 standard. Verilog-XL does not
support these tasks except through this PLI application.
The Verilog language has a rich set of system functions to write files
($fdisplay, $fwrite, etc.) but only reads files with a single, fixed format
($readmem). In the past if you wanted to read a file that was not in $readmem
format, you would have to learn the Programming Language Interface (PLI)
and the C language, write C code to read the file and pass values into
Verilog, then debug the combined C and Verilog code. In addition, the Verilog
is limited to 32 open files at a time.
However, using the new file I/O system functions you can perform your
file I/O directly from Verilog. You can write Verilog HDL to:
1) In fileio $fopen has read, write, append variants:
file = $fopenr("filename");
file = $fopenw("filename");
file = $fopena("filename");
In V2K, there is a single $fopen for both multi-channel descriptors
(MCD) and file descriptors (FD). Whether an FD or MCD is produced
is indicated by the presence of a mode string added to $fopen in V2K:
file = $fopen("filename", "w");
// FD
file = $fopen("filename");
// MCD
Fileio supports the V2K $fopen format under a package compilation switch
but that then blocks any use of MCDs since it hides the builtin $fopen.
2) Fileio $fclose has read and write variants that return a status:
r = $fcloser(file);
r = $fclosew(file);
In V2K, there is a single $fclose for both MCDs and FDs. It does
not return a status. Errors can be determined by using $ferror.
Fileio supports the V2K $fclose format under a package compilation switch
but that then blocks any use of MCDs since it hides the builtin $fclose.
3) Fileio $getchar is not directly supported in Verilog-2001.
The operation can be done by using $fgetc('h8000_0000) which makes use
of the reserved FD for stdin.
4) Fileio defines $fgets as:
r = $fgets(string, n, file);
V2K does not support a maximum count "n" of characters to read. Input
in V2K always terminates at end of line and then string assignment to the
target is done.
Fileio's $gets is not directly supported in Verilog 2001. The
operation can be done by using:
$fgets(string, 'h8000_0000);
that makes use of the reserved FD for stdin.
5) Fileio $scanf is not directly supported in Verilog 2001. The
operation can be done by using:
$fscanf('h8000_0000, format, args);
which makes use of the reserved FD for stdin.
6) Fileio does not support ? as an alias for X; V2K does.
7) Fileio does not support reading X or Z for %d format specification;
V2K does.
8) Fileio supports %f, but not the synonyms %e and %g. V2K supports
all three. Fileio does not support %f on in $sscanf; V2K supports
all specifiers in $sscanf.
9) Fileio does not support %u, %z, %v, %t, or %m input format specifiers;
V2K supports all of them.
10) Fileio supports special character input handling for \ (i.e. \\,
\oNNN); V2K does not support this (not in LRM).
11) Fileio requires that $fread on a memory use "mem[0]" as the memory
referend. V2K requires "mem" since "mem[0]" will be taken as a register
read.
12) Fileio defines $sprintf and $fprintf which are not defined in V2K.
V2K defines the $swrite family of tasks for string ouput and allows both
MCDs and FDs in the $fwrite, $fdisplay, $fmonitor, and $fstrobe families
of tasks. V2K supports $sformat where the difference in $sformat
and $swrite is in the management of format specification strings.
Fileio requires a single format string in $sprintf, etc; V2K follows the
normal Verilog convention of treating any constant strings as format specifiers
for $swrite. In V2K, all output format specifications are consistent
and produce the same result independent of whether the target is a string,
file, or standard output.
13) Fileio $ferror only returns a status. V2k $ferror takes a
second parameter and stores the error string in that register. Additionally,
V2K $ferror accepts a file descriptor with the value 0 and simple produces
the most recent system error status.
14) Fileio requires an argument to $fflush; V2K permits a parameterless
call and flushes all files (including MCD files) in that case. V2K
$fflush supports either MCDs or FDs.
15) V2K supports $rewind which Fileio does not.
16) Fileio supports $fputc which V2K does not.
17) Fileio supports $feof which V2K does not. Some functions
such as $fgetc return EOF (-1) but this is not the same.
integer file;
file = $fopenr("filename");
file = $fopenw("filename");
file = $fopena("filename");
integer file, r;
r = $fcloser(file);
r = $fclosew(file);
integer file;
reg eof;
eof = $feof(file);
The function $ferror returns the error status of a file. If an error
has occurred while reading from a file, $ferror returns a non-zero value,
else 0. The error value is returned once, then reset to 0.
integer file, char;
char = $fgetc(file);
char = $getc();
integer file;
reg [7:0] char, r;
r = $ungetc(char, file);
Note that since there is no $ungetc for stdin in C, there will not be
one in the file I/O package.
integer stream, r, char;
r = $fputc(stream, char);
integer file, n, r;
reg [n*8-1:0] string;
r = $fgets(string, n, file);
r = $gets(string);
The function $gets is no longer supported by default in fileio v3.4.
If you want to use it, you must compile fileio.c with -DGETS. This is
because some C compilers will give an error message when compiling
fileio.c:
fileio.o: In function `fileio_gets_call`:
fileio.o: the gets function is dangerous and should not be used
integer file, count;
count = $fscanf(file, format, args);
count = $sscanf(string, format, args);
count = $scanf(format, args);
The format can be either a string constant or a reg. It can contain:
Formatting & padding is closer to Verilog than C. For example,
%x of 16'h24 is '0024', not '24', and %0x returns '24', not '0024'.
$fscanf, $sscanf, and $scanf return the number of successful assignments
performed. If you do not want a return value from these routines, compile
fileio.c (and veriuser.c for Cadence users) with -Dscanf_task. VCS users
should switch from fileio.tab to fileio_task.tab
integer file, position;
position = $ftell(file);
`define SEEK_SET 0
`define SEEK_CUR 1
`define SEEK_END 2
integer file, offset, position, r;
r = $fseek(file, 0, `SEEK_SET); /* Beginning */
r = $fseek(file, 0, `SEEK_CUR); /* No effect */
r = $fseek(file, 0, `SEEK_END); /* End of file */
r = $fseek(file, position, `SEEK_SET); /* Previous loc */
integer r, file, start, count;
reg [15:0] mem[0:10], r16;
r = $fread(file, mem[0], start, count);
r = $fread(file, r16);
By default $fread will store data in the first data location through
the final location. For the memory up[10:20], the first location loaded
would be up[10], then up[11]. For down[20:10], the first location would
be down[10], then down[11].
start and count are ignored if $fread storing data in a reg instead
of a memory. No warning is printed if the file contains more data than
will fit in the memory.
start is the word offset from the lowest element in the memory.
For start = 2 and the memory up[10:20], the first data would be loaded
at up[12]. For the memory down[20:10] , the first location loaded would
be down[12], then down[13].
$fread returns the number of elements read from the file, If $fread
terminates early because of an error, it will return the number of elements
successfully read. $feof can be used to determine whether the end-of-file
was reached during $fread.
The data in the file is broken into bytes according to the width
of the memory. An 8-bit wide memory takes one byte per location, while
a 9-bit wide memory takes 2 bytes. Care should be taken when using memories
with widths not evenly divisible by 8 as there may be gaps in the data
in the memory vs. data in the file.
The $fread system task only works with NC-Verilog if you use the
-MEMPACK switch as in:
ncverilog +ncvlogargs+-NOMEMPACK foo.v
integer file, r, a, b;
reg [80*8:1] string;
file = $fopenw("output.log");
r = $sformat(string, "Formatted %d %x", a, b);
r = $sprintf(string, "Formatted %d %x", a, b);
r = $fprintf(file, "Formatted %d %x", a, b);
The supported formats include b, c, d, e, f, g, h, m, o, r, s, and
x. %t for printing formatted time is NOT supported yet.
integer file, r;
file = $fopenw("output.log");
r = $fflush(file);
while (c=fgetc(stream) != EOF) {
<process input>
}
c = $fgetc(file);
while (c !== `EOF)
begin
<process input>
c = $fgetc(file);
end
The maximum number of files (MAX_FILES) is set in the C code to
12. The maximum string size is 1000 characters. There is no known limit
to the number of conversion operators in $fscanf or $sscanf.
This is the pattern file - read_pattern.pat , included in the examples
directory:
// This is a pattern file
// time bin dec hex
10: 001 1 1
20.0: 010 20 020
50.02: 111 5 FFF
62.345: 100 4 DEADBEEF
75.789: XXX 2 ZzZzZzZz
The module read_pattern.v reads the time for the next pattern from
an ASCII file. It then waits until the absolute time specified in the input
file, and reads the new values for the input signals (bin, dec, hex). The
time in the file is a real value and, when used in a delay, is rounded
according to the timescale directive. Thus the time 75.789 is rounded to
75.79 ns.
`timescale 1ns / 10 ps
`define EOF 32'hFFFF_FFFF
`define NULL 0
`define MAX_LINE_LENGTH 1000
module read_pattern;
integer file, c, r;
reg [3:0] bin;
reg [31:0] dec, hex;
real real_time;
reg [8*`MAX_LINE_LENGTH:0] line; /* Line of text read from file */
initial
begin : file_block
$timeformat(-9, 3, "ns", 6);
$display("time bin decimal hex");
file = $fopenr("read_pattern.pat");
if (file == `NULL) // If error opening file
disable file_block; // Just quit
c = $fgetc(file);
while (c != `EOF)
begin
/* Check the first character for comment */
if (c == "/")
r = $fgets(line, `MAX_LINE_LENGTH, file);
else
begin
// Push the character back to the file then read the next time
r = $ungetc(c, file);
r = $fscanf(file," %f:\n", real_time);
// Wait until the absolute time in the file, then read stimulus
if ($realtime > real_time)
$display("Error - absolute time in file is out of order - %t",
real_time);
else
#(real_time - $realtime)
r = $fscanf(file," %b %d %h\n",bin,dec,hex);
end // if c else
c = $fgetc(file);
end // while not EOF
r = $fcloser(file);
end // initial
// Display changes to the signals
always @(bin or dec or hex)
$display("%t %b %d %h", $realtime, bin, dec, hex);
endmodule // read_pattern
The following model, compare.v, reads a file containing both
stimulus and expected results. The input signals are toggled at the
beginning of a clock cycle and the output is compared just before the
end of the cycle.
`define EOF 32'hFFFF_FFFF
`define NULL 0
`define MAX_LINE_LENGTH 1000
module compare;
integer file, r;
reg a, b, expect, clock;
wire out;
reg [`MAX_LINE_LENGTH*8:1];
parameter cycle = 20;
initial
begin : file_block
$display("Time Stim Expect Output");
clock = 0;
file = $fopenr("compare.pat");
if (file == `NULL)
disable file_block;
r = $fgets(line, MAX_LINE_LENGTH, file); // Skip comments
r = $fgets(line, MAX_LINE_LENGTH, file);
while (!$feof(file))
begin
// Wait until rising clock, read stimulus
@(posedge clock)
r = $fscanf(file, " %b %b %b\n", a, b, expect);
// Wait just before the end of cycle to do compare
#(cycle - 1)
$display("%d %b %b %b %b", $stime, a, b, expect, out);
$strobe_compare(expect, out);
end // while not EOF
r = $fcloser(file);
$stop;
end // initial
always #(cycle / 2) clock = !clock; // Clock generator
and #4 (out, a, b); // Circuit under test
endmodule // compare
Sometimes a detailed simulation model for a device is not available, such as a
microprocessor. As a substitute, you can write a bus-functional model which reads
a script of bus transactions and performs these actions. The following, script.v,
reads a file with commands plus data values.
`define EOF 32'hFFFF_FFFF
`define NULL 0
module script;
integer file, r;
reg [80*8:1] command;
reg [31:0] addr, data;
initial
begin : file_block
clock = 0;
file = $fopenr("script.txt");
if (file == `NULL)
disable file_block;
while (!$feof(file))
begin
r = $fscanf(file, " %s %h %h \n", command, addr, data);
case (command)
"read":
$display("READ mem[%h], expect = %h", addr, data);
"write":
$display("WRITE mem[%h] = %h", addr, data);
default:
$display("Unknown command '%0s'", command);
endcase
end // while not EOF
r = $fcloser(file);
end // initial
endmodule // script
read 9 0
write 300a feedface
read 2FF xxxxxxxx
bad
Reading a formatted ASCII file is easy with the system tasks. The following
is an example of reading a binary file into a Verilog memory. $fread can
also read a file one word at a time and copy the word into memory, but
this is about 100 times slower than using $fread to read the entire array
directly.
This is the file load_mem.v
`define EOF 32'HFFFF_FFFF
`define MEM_SIZE 200_000
module load_mem;
integer file, i;
reg [7:0] mem[0:`MEM_SIZE];
reg [80*8:1] file_name;
initial
begin
file_name = "data.bin";
file = $fopenr(file_name);
i = $fread(file, mem[0]);
$display("Loaded %0d entries \n", i);
i = $fcloser(file);
$stop;
end
endmodule // load_mem
Note that VCS 6.1 and later supports the IEEE-1364 2001 standard.
To use the file I/O system functions with VCS, you will need to:
On the DEC/Alpha use:
cc -c fileio.c -I$VCS_HOME/`vcs -platform`/lib -taso -xtaso_short
On Windows, use the Microsoft C++ compiler included with VCS:
cl -c -Zp4 fileio.c
The -Zp4 switch tells the compiler to use longword alignment. Note
that the compiler produces fileio.obj, not fileio.o. In the example below,
if you compile on Windows, change the file extension.
Note that the system variable "include" must contain a reference
to the VCS include files, such as:
c:\vcs422\Windows_NT\lib
% vcs load_mem.v fileio.o -P fileio.tab -R
Chronologic VCS (TM)
Version 5.1 -- Tue Jan 11 09:00:41 2000
Copyright (c) 1991-2000 by Synopsys Inc.
ALL RIGHTS RESERVED
This program is proprietary and confidential information of Synopsys Inc.
and may be used and disclosed only as authorized in a license agreement
controlling such use and disclosure.
Compiling load_mem.v
Top Level Modules:
load_mem
( cd csrc ; make -f Makefile DEFAULT_RUNTIME=TRUE product )
../simv up to date
Chronologic VCS simulator copyright 1991-2000
Contains Synopsys proprietary information.
Compiler version 5.1; Runtime version 5.1; Jan 11 09:00 2000
Loaded 200 entries
$stop at time 0 Scope: load_mem File: load_mem.v Line: 13
cli_0 >
Verilog-XL does not natively support the IEEE-1364 2001 tasks except through
this PLI application.
Note: this information is based on an older version of Verilog-XL.
Send me an update if you have one.
To use the file I/O system functions with Verilog-XL, you will need to:
| |
|
|
Please enter the name of the output script | cr_vlog |
Please choose a target | 1 Stand Alone |
Please choose how to link in PLI application | 4 Static with user PLI application |
What do you want to name the Verilog-XL target? | verilog_fileio |
Do you want to compile for the SimVision environment? | n |
Do you want to include GR_WAVES | n |
Do you want to include the Simulation History Manager | n |
The LAI interface in no longer supported | n |
Do you want to include the LMSI HARDWARE MODELER interface software in this executable? | return |
Do you want to include the Verilog Mixed-Signal interface software in this executable? | return |
Do you want to include the Standard Delay File Annotator in this executable? | return |
The user template file 'veriuser.c' must always be included in the link statement. What is the path name of this file? | ./veriuser.c |
Please list any other user files to be linked with this Verilog-XL ... terminating with a single '.' | ./fileio.c . (period) |
cc -Dverilogxl -o verilog_read $1 $2 -g \
...
fileio.c \
...
VERILOG-XL 2.1.12 Jun 21, 1995 14:55:32
Copyright (c) 2000 Cadence Design Systems, Inc. All Rights Reserved.
.
.
.
<<< Routines for file read linked in >>
Compiling source file "load_mem.v"
Highest level modules:
load_mem
Loaded 200 entries
L13 "load_mem.v": $stop at simulation time 0
Type ? for help
C1>
MTI's ModelSim 5.5 and later offer native support these IEEE-1364 2001
system tasks.
Create fileio.so, the shareable object:
make MTI=1 fileio.soor: gcc -c -g fileio.c -DMTI -I$MTI_PATH/include
ld -G -Bdynamic -o fileio.so fileio.oCompile and run your design with:
rm -rf workYou might have to set the environment variable LD_LIBRARY_PATH to point
vlib work
vlog test1.v # Your Verilog code here
vsim -c test1 -pli fileio.so -do "run -all"
NC-Verilog 3.3 and later offer native support for these IEEE-1364 2001
system tasks.
NC-Verilog does not support the tf_nodeinfo PLI call which is used in
several places by fileio.c. If you want to use these system functions with
NC-Verilog, compile fileio.c with the -DNCVerilog switch. This will disable
the $fread routine, and passing some strings using a register, such as
the format string to $fscanf.
If you have any information on linking with NC-Verilog, please pass
it on to me!
You can use makefile_fileio_ncv to compile and link with NC-Verilog.
I make no promises!
文章评论(0条评论)
登录后参与讨论