Get system time in VCS - verilog

Is there way to get system time in VCS/UVM ? I am looking for something similar to Perl's localtime(time). Is there way to print system time for every uvm_info printed ?

One way is to use $system() to run any system command, including system' date command.
initial
begin
$system("date");
end
From IEEE 1800 LRM:
$system makes a call to the C function system(). The C function
executes the argument passed to it as if the argument was executed
from the terminal. $system can be called as either a task or a
function. When called as a function, it returns the return value of
the call to system() with data type int. If $system is called with no
string argument, the C function system() will be called with the NULL
string.
Also, see here.

Depends on the version of VCS you are using. The latest version should support $system as defined in IEEE Std 1800-2012 § 20.18.1. Assuming you are running in a UNIX based environment you can do:
function string get_localtime();
int fd;
string localtime;
void'($system("data > localtime")); // temp file
fd = $fopen("localtime", "r");
void'($fscanf(fd,"%s",localtime));
$fclose(fd);
void'($system("rm localtime")); // delete file
return localtime;
endfunction
If your version VCS doesn't support $system or if your more conformable with C/C++, then use DPI (see IEEE Std 1800-2012 § 35). Create a function in C and compile it in VCS with your SystemVerilog files. In the SystemVerilog, add the import to allow access to your C function. Assuming your method name is my_localtime and and return time is a string, the import should look like:
import "DPI" function string my_localtime();

In c file wallclock.c :
#include <time.h>
wallclock() {
time_t t;
t = time(NULL);
return (ctime(&t));
//return time(NULL);
}
In SV file :
import "DPI-C" function string wallclock();
module try;
//int unsigned t;
string t;
initial begin
t = wallclock();
$write("time=%0s\n", t);
end
endmodule

Related

How do I generate parameters dependent onf previous parameters in systemverilog

I recently switched from VHDL to SystemVerilog and I am converting some of my codes. I want to generate an array of local parameters based on 3 parameters SZ,L,max.
module test #(
parameter int SZ = 1024,
parameter int L = 35,
parameter int MAX = 4
)()
//...
localparam int n[MAX:0] = ;//...
for(genvar i = 0; i < max; i++) begin: gg
//n[i] and n[i+1] will be used here
//There is a second generate loop here that uses n[i+1] and therefore n[i+1] has to be parameter.
end
I tried using a function to generate localparams but I get an error that element assignment in function is not constant. I never had this issue in VHDL.
The only other option I can think of is to create the params inside the for generate but how would I reference the initial value? Is there any other solution?
The simulator I am using is Verilator but I also want the design to work in Xilinx Vivado.
Edit: I do not want to generate the parameters from an external script because I lose the ability to use Vivado's ability to run multiple synthesis/implementation in the same project with different parameters. That was what I used to do in VHDL.
You can use a function to initialize a parameter, you just have to have the output of the entire array as the result of the function. To do that, you need a typedef
typedef int array_type[MAX:0];
function array_type f();
f[0]=SZ;
for(int i=0;i<MAX;i++)
f[i+1]=f[i]-((2*i)+1)*L)/2;
endfunction
localparam array_type n = f();
I got it working by using packed array of 32-bits. Verilator doesn't support unpacked int with constants. Packed int is also not supported so I had to change the type to pack of 32-bits.
typedef [MAX:0][31:0] array_type;
function array_type f();
f[0]=SZ;
for(int i=0;i<MAX;i++)
f[i+1]=f[i]-((2*i)+1)*L)/2;
endfunction
localparam array_type n = f();

How to vary a struct going through a port in system verilog - generate doesnt work

module testy
#(
parameter W = 10,
parameter C = 2
)
(
aa
);
generate
if (W == 8)
begin:W8
if(C == 1)
begin:W8C1
typedef struct {
logic [8:0] so;
}my_struct;
end
if(C == 2)
begin:W8C2
typedef struct {
logic [10:0] so;
}my_struct;
end
end
endgenerate
input my_struct aa;
endmodule
I get this error:
irun(64): 14.20-p001: (c) Copyright 1995-2015 Cadence Design Systems, Inc.
file: testy.v
input my_struct aa;
|
ncvlog: *E,SVNOTY (testy.v,30|14): Syntactically this identifier appears to begin a datatype but it does not refer to a visible datatype in the current scope.
module worklib.testy:v
errors: 1, warnings: 0
ncvlog: *F,NOTOPL: no top-level unit found, must have recursive instances.
irun: *E,VLGERR: An error occurred during parsing. Review the log file for errors with the code *E and fix those identified problems to proceed. Exiting with code (status 2).
I thought generates were statically determined but I have problems compiling it - since parameters cant be overridden in packages and couldn't think of a way to do this in design which needs to be synthesized and didn't want to add interfaces or classes. Is there a bettwe way to do this. My struct has over 100 entries if I include all the combinations and use only what I want but I thought using generates I could trim it to what I want based on a set of parameters.
Thanks
Your problem is the scope of the typedef is local to the blocks inside your generate statements. If all you need to do is change the size of a data type, you can use a constant function call, with is statically determined. But then you run into another problem with your unpacked struct declaration - it is still local to the module and you will not be able to connect another struct to it with a matching data type. An interface would be a better solution and is synthesizable.
Another possibility is passing down a type parameter.

How to pass string/integer value from js to c++?

I am using Nodejs c++ addon in my nodejs project. JS calls a method defined in c++ with a string as the parameter. I couldn't get the string in c++. Below is my code in c++:
NAN_METHOD(DBNode::Test){
printf("Hello\n");
printf("%s\n", info[0]->ToString());
printf("%d\n", info[1]->ToNumber());
}
Below is my js code:
const test = require('./build/Release/test.node');
test.test('ssss', 99);
Below is the output:
$ node demo.js
Hello
?ڄ?C
-272643000
You can see from the above output that the string and integer values are not correctly printed. Is there anything wrong with my code?
Let start from numbers. ToNumber returns value of type Local<Number>. It differs from regular C-like value what printf can digest.
First of all you need unwrap Local. It is v8 pointer-like utility class.
You can do it with overrided * operator. So *(info[1]->ToNumber()) gives us v8 Number child of Value. But this is not the end of story. Now we can pull good-old int from it (*(info[1]->ToNumber())).Int32Value(). Or you can use the fact Handle ancestors override -> operator too and write like info[1]->ToNumber()->Int32Value().
String case is harder. V8 uses utf8 strings and you can use String::Utf8Value utility class to get buffer of char from it. *(String::Utf8Value(info[0]->ToString()))
Usually you do not need it in v8 addons and I suggest you work with v8 objects(like Local, String, Number, etc) in your native code.
below is the solution :--
NAN_METHOD(updateSignalValue) {
Nan::Utf8String lSignal(info[0]);
int len = lSignal.length();
if (len <= 0) {
return Nan::ThrowTypeError("arg must be a non-empty string");
}
std::cout << "\n hello lSignal value is :"<
Regards, Rakesh Kumar Jha

Tick-including a header file inside package in systemverilog

Hi I've following scenario and it's not working for me.
file: a.svh
a.svh defines some parameters and functions- let's say function xyz(b)
file b.sv
package b;
`include "a.svh"
typedef logic[(xyz(10)-1):0] h;
endpackage
Now the issue is, b.sv can't find xyz function in it's scope, even thought I'm tick-including a.svh in b.sv. Everything works fine if I don't use a package in b.sv file. (comment out package b and endpackage lines).
//package b;
`include "a.svh"
typedef logic[(xyz(10)-1):0] h;
//endpackage
Is it an illigal case in systemverilog?
I recreated your scenario on EDAplayground. I didn't get any errors.
A function is intended to be evaluated during simulation. Some simulators support evaluating function during compile/elaboration, but it doesn't appear to be a requirement.
SystemVerilog also has let, which is more appropriate for for compile time evaluation (it supports simulation time as well). Refer to IEEE Std 1800-2012 § 11.13 Let construct:
let declarations can be used for customization and can replace the text macros in many cases. The let construct is safer because it has a local scope, while the scope of compiler directives is global within the compilation unit. Including let declarations in packages (see Clause 26) is a natural way to implement a well-structured customization for the design code.
a.svh
function int xyz_func(int b);
return b;
endfunction
let xyz_let(b) = b;
design.sv (equivalent to your b.sv, EDAplayground requires design.sv to exist)
package b;
`include "a.svh"
typedef logic[(xyz_func(10)-1):0] hf;
typedef logic[xyz_let(10):1] hl;
endpackage
testbench.sv
module tb;
import b::*;
hf myhf;
hl myhl;
initial begin
myhf = -1;
myhl = -1;
$display("hf:%b left:%0d right:%0d", myhf, $left(myhf), $right(myhf));
$display("hl:%b left:%0d right:%0d", myhl, $left(myhl), $right(myhl));
end
endmodule
Output:
hf:1111111111 left:9 right:0
hl:1111111111 left:10 right:1

Which system call is called for strcpy or strcat C++ functions?

I was wondering if strcpy or strcat like functions causes any system call or they are handled internally by the OS?
No system call is involved. In fact, the source code of most if not all implementations would look like this:
char *
strcpy(char *s1, const char *s2) {
char *s = s1;
while ((*s++ = *s2++) != 0) ;
return (s1);
}
strcat is similar:
char *
strcat(char *s1, const char *s2)
{
strcpy(&s1[strlen(s1)], s2);
return s1;
}
On Linux, those calls are implemented by the standard library (and those are part of the standard C library). See also glibc. System calls are invocations from user code to kernel code for hardware access (e.g. memory allocation); they are accomplished with an interrupt 0x80.
No OS calls are REQUIRED for such simple operations - they can be performed easily in the libraries.
Note that the OS may be entered during such calls, eg. because they generate a page-fault or some other hardware interrupt occurs.

Resources