Add support for one argumenr $urandom_range()

This commit is contained in:
Cary R 2014-06-14 14:16:26 -07:00
parent f7752caaac
commit 0961eae27e
1 changed files with 21 additions and 19 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000-2013 Stephen Williams (steve@icarus.com)
* Copyright (c) 2000-2014 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
@ -539,7 +539,7 @@ static PLI_INT32 sys_random_calltf(PLI_BYTE8 *name)
return 0;
}
/* From System Verilog 3.1a. */
/* From SystemVerilog. */
static PLI_INT32 sys_urandom_range_compiletf(PLI_BYTE8 *name)
{
vpiHandle callh = vpi_handle(vpiSysTfCall, 0);
@ -548,20 +548,17 @@ static PLI_INT32 sys_urandom_range_compiletf(PLI_BYTE8 *name)
/* Check that there are arguments. */
if (argv == 0) {
vpi_printf("ERROR: %s requires two arguments.\n", name);
vpi_printf("ERROR: %s requires one or two arguments.\n", name);
vpi_control(vpiFinish, 1);
return 0;
}
/* Check that there are at least two arguments. */
/* Check that there is at least one argument. */
arg = vpi_scan(argv); /* This should never be zero. */
assert(arg);
arg = vpi_scan(argv);
if (arg == 0) {
vpi_printf("ERROR: %s requires two arguments.\n", name);
vpi_control(vpiFinish, 1);
return 0;
}
/* Is this a single argument function call? */
if (arg == 0) return 0;
/* These functions takes at most two argument. */
arg = vpi_scan(argv);
@ -575,7 +572,7 @@ static PLI_INT32 sys_urandom_range_compiletf(PLI_BYTE8 *name)
return 0;
}
/* From System Verilog 3.1a. */
/* From SystemVerilog. */
static unsigned long urandom(long *seed, unsigned long max, unsigned long min)
{
static long i_seed = 0;
@ -590,7 +587,7 @@ static unsigned long urandom(long *seed, unsigned long max, unsigned long min)
return result;
}
/* From System Verilog 3.1a. */
/* From SystemVerilog. */
static PLI_INT32 sys_urandom_calltf(PLI_BYTE8 *name)
{
vpiHandle callh, argv, seed = 0;
@ -626,12 +623,12 @@ static PLI_INT32 sys_urandom_calltf(PLI_BYTE8 *name)
return 0;
}
/* From System Verilog 3.1a. */
/* From SystemVerilog. */
static PLI_INT32 sys_urandom_range_calltf(PLI_BYTE8 *name)
{
vpiHandle callh, argv, maxval, minval;
s_vpi_value val;
unsigned long i_maxval, i_minval, tmp;
unsigned long i_maxval, i_minval;
/* Get the argument handles and convert them. */
callh = vpi_handle(vpiSysTfCall, 0);
@ -643,12 +640,18 @@ static PLI_INT32 sys_urandom_range_calltf(PLI_BYTE8 *name)
vpi_get_value(maxval, &val);
i_maxval = val.value.integer;
vpi_get_value(minval, &val);
i_minval = val.value.integer;
/* Is this a two or one argument function call? */
if (minval) {
vpi_get_value(minval, &val);
i_minval = val.value.integer;
vpi_free_object(argv);
} else {
i_minval = 0;
}
/* Swap the two arguments if they are out of order. */
if (i_minval > i_maxval) {
tmp = i_minval;
unsigned long tmp = i_minval;
i_minval = i_maxval;
i_maxval = tmp;
}
@ -656,7 +659,6 @@ static PLI_INT32 sys_urandom_range_calltf(PLI_BYTE8 *name)
/* Calculate and return the result. */
val.value.integer = urandom(0, i_maxval, i_minval);
vpi_put_value(callh, &val, 0, vpiNoDelay);
vpi_free_object(argv);
return 0;
}
@ -907,7 +909,7 @@ void sys_random_register()
tf_data.user_data = "$random";
vpi_register_systf(&tf_data);
/* From System Verilog 3.1a. */
/* From SystemVerilog. */
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$urandom";
@ -917,7 +919,7 @@ void sys_random_register()
tf_data.user_data = "$urandom";
vpi_register_systf(&tf_data);
/* From System Verilog 3.1a. */
/* From SystemVerilog. */
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$urandom_range";