Doing UNIX stuffs in Verilog
Swapnajit Mittra
It all started when somebody (with little imagination, probably one of Brian
Kernighan or Dennis Ritchie) wanted to execute a shell command from a C program.
For example, if you want to list the contents of the current directory from
your C program, it takes more than just the basic knowledge of C libraries.
But, within a shell, all you need to do is just "ls -l". So why bother writing
pages of code, if somehow you can invoke an "ls -l" and pass it to the shell
!
So, the C system call system() was born and was placed in
stdlib.h. If you call system("ls -l") from your C program,
it will list the directory structure for you.
When Verilog was created and, later standardized, somehow this important
utility was ignored. As a result, standard Verilog does not have a way to
interact with the shell.
Both Verilog-XL and VCS provides a non-stadard system task
$system()which does an equivalent job. You can invoke $system("ls
-l") from your Verilog program to list the contents of the current
directory.
Now, each command executed in a shell returns an exit status to the shell.
Analyzing the exit status is important for analyzing and debugging
the command (imagine the shell command to be a perl program or binary executable,
rather than just "ls -l"). Since $system() is a system task and,
not a system function, there is no way that a Verilog program can get that
information.
This is where the following system call $my_system() can be useful.
It reads in a shell command in form of a string, execute it and then return
the exit status as an integer (32bit).
For sake of brevity, only the calltf function is shown here.
Note, even though the function reads the input argument, executes it and
then return the exit status, it does all these using just one line of code.