blob: 461e40de2a7e7383e6df37cba150774bf4211394 [file] [log] [blame]
#include <stdlib.h> /* ANSI C standard library */
#include <stdio.h> /* ANSI C standard input/output library */
#include <time.h>
#include <stdarg.h> /* ANSI C standard arguments library */
#include "vpi_user.h" /* IEEE 1364 PLI VPI routine library */
#define CMD_RTC_INIT 0
#define CMD_RTC_NEXT_SECOND 1
#define CMD_RTC_NEXT_DATE 2
/* prototypes of PLI application routine names */
PLI_INT32 PLIbook_RtcSizetf(PLI_BYTE8 *user_data);
PLI_INT32 PLIbook_RtcCalltf(PLI_BYTE8 *user_data);
PLI_INT32 PLIbook_RtcCompiletf(PLI_BYTE8 *user_data);
PLI_INT32 PLIbook_RtcStartOfSim(s_cb_data *callback_data);
/* tm structure */
/* struct tm {
int tm_sec; // seconds, range 0 to 59
int tm_min; // minutes, range 0 to 59
int tm_hour; // hours, range 0 to 23
int tm_mday; // day of the month, range 1 to 31
int tm_mon; // month, range 0 to 11
int tm_year; // The number of years since 1900
int tm_wday; // day of the week, range 0 to 6
int tm_yday; // day in the year, range 0 to 365
int tm_isdst; // daylight saving time
}; */
struct tm tm = {0};
/*******************************************
* Sizetf application
* *****************************************/
PLI_INT32 PLIbook_RtcSizetf(PLI_BYTE8 *user_data)
{
return(32); /* $rtc returns 32-bit values */
}
/*********************************************
* compiletf application to verify valid systf args.
* *************************************************/
PLI_INT32 PLIbook_RtcCompiletf(PLI_BYTE8 *user_data)
{
s_vpi_value value_s;
vpiHandle systf_handle, arg_itr, arg_handle;
PLI_INT32 tfarg_type;
PLI_INT32 cmd;
int err_flag = 0;
do { /* group all tests, so can break out of group on error */
systf_handle = vpi_handle(vpiSysTfCall, NULL);
arg_itr = vpi_iterate(vpiArgument, systf_handle);
if (arg_itr == NULL) {
vpi_printf("ERROR: $c_rtc requires 7 arguments; has none\n");
err_flag = 1;
break;
}
arg_handle = vpi_scan(arg_itr);
tfarg_type = vpi_get(vpiType, arg_handle);
if ( (tfarg_type != vpiReg) &&
(tfarg_type != vpiIntegerVar) &&
(tfarg_type != vpiConstant) ) {
vpi_printf("ERROR: $c_rtc arg1 must be number, variable or net\n");
err_flag = 1;
break;
}
value_s.format = vpiIntVal;
vpi_get_value(arg_handle, &value_s);
cmd = value_s.value.integer;
// RTC Init has 7 Parameter
if(cmd == CMD_RTC_INIT) {
arg_handle = vpi_scan(arg_itr);
tfarg_type = vpi_get(vpiType, arg_handle);
if ( (tfarg_type != vpiReg) &&
(tfarg_type != vpiIntegerVar) &&
(tfarg_type != vpiConstant) ) {
vpi_printf("ERROR: $c_rtc arg2 must be number, variable or net\n");
err_flag = 1;
break;
}
arg_handle = vpi_scan(arg_itr);
tfarg_type = vpi_get(vpiType, arg_handle);
if ( (tfarg_type != vpiReg) &&
(tfarg_type != vpiIntegerVar) &&
(tfarg_type != vpiConstant) ) {
vpi_printf("ERROR: $c_rtc arg3 must be number, variable or net\n");
err_flag = 1;
break;
}
arg_handle = vpi_scan(arg_itr);
tfarg_type = vpi_get(vpiType, arg_handle);
if ( (tfarg_type != vpiReg) &&
(tfarg_type != vpiIntegerVar) &&
(tfarg_type != vpiConstant) ) {
vpi_printf("ERROR: $c_rtc arg4 must be number, variable or net\n");
err_flag = 1;
break;
}
arg_handle = vpi_scan(arg_itr);
tfarg_type = vpi_get(vpiType, arg_handle);
if ( (tfarg_type != vpiReg) &&
(tfarg_type != vpiIntegerVar) &&
(tfarg_type != vpiConstant) ) {
vpi_printf("ERROR: $c_rtc arg5 must be number, variable or net\n");
err_flag = 1;
break;
}
arg_handle = vpi_scan(arg_itr);
tfarg_type = vpi_get(vpiType, arg_handle);
if ( (tfarg_type != vpiReg) &&
(tfarg_type != vpiIntegerVar) &&
(tfarg_type != vpiConstant) ) {
vpi_printf("ERROR: $c_rtc arg6 must be number, variable or net\n");
err_flag = 1;
break;
}
arg_handle = vpi_scan(arg_itr);
tfarg_type = vpi_get(vpiType, arg_handle);
if ( (tfarg_type != vpiReg) &&
(tfarg_type != vpiIntegerVar) &&
(tfarg_type != vpiConstant) ) {
vpi_printf("ERROR: $c_rtc arg7 must be number, variable or net\n");
err_flag = 1;
break;
}
arg_handle = vpi_scan(arg_itr);
if (arg_handle != NULL) {
vpi_printf("ERROR: $c_rtc requires 7 arguments; has too many\n");
vpi_free_object(arg_itr);
err_flag = 1;
break;
}
} else { // CMD_RTC_NEXT_SECOND & CMD_RTC_NEXT_DATE has only 1 arguments
arg_handle = vpi_scan(arg_itr);
if (arg_handle != NULL) {
vpi_printf("ERROR: $c_rtc requires 1 arguments; has too many\n");
vpi_free_object(arg_itr);
err_flag = 1;
break;
}
}
} while (0 == 1); /* end of test group; only executed once */
if (err_flag) {
vpi_control(vpiFinish, 1); /* abort simulation */
}
return(0);
}
/******************************************************************
* calltf to calculate floating point addr
* ******************************************************************/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
PLI_INT32 PLIbook_RtcCalltf(PLI_BYTE8 *user_data)
{
s_vpi_value value_s;
vpiHandle systf_handle, arg_itr, arg_handle;
PLI_INT32 cmd,year, month, date, hour,minute,second;
float result;
systf_handle = vpi_handle(vpiSysTfCall, NULL);
arg_itr = vpi_iterate(vpiArgument, systf_handle);
if (arg_itr == NULL) {
vpi_printf("ERROR: $c_rtc failed to obtain systf arg handles\n");
return(0);
}
/* read cmd from systf arg 1 (compiletf has already verified) */
arg_handle = vpi_scan(arg_itr);
value_s.format = vpiIntVal;
vpi_get_value(arg_handle, &value_s);
cmd = value_s.value.integer;
if(cmd == CMD_RTC_INIT) {
/* read input1 from systf arg 6 (compiletf has already verified) */
arg_handle = vpi_scan(arg_itr);
vpi_get_value(arg_handle, &value_s);
year = value_s.value.integer;
/* read input2 from systf arg 6 (compiletf has already verified) */
arg_handle = vpi_scan(arg_itr);
vpi_get_value(arg_handle, &value_s);
month = value_s.value.integer;
/* read input2 from systf arg 6 (compiletf has already verified) */
arg_handle = vpi_scan(arg_itr);
vpi_get_value(arg_handle, &value_s);
date = value_s.value.integer;
/* read input3 from systf arg 6 (compiletf has already verified) */
arg_handle = vpi_scan(arg_itr);
vpi_get_value(arg_handle, &value_s);
hour = value_s.value.integer;
/* read input4 from systf arg 6 (compiletf has already verified) */
arg_handle = vpi_scan(arg_itr);
vpi_get_value(arg_handle, &value_s);
minute = value_s.value.integer;
/* read input5 from systf arg 6 (compiletf has already verified) */
arg_handle = vpi_scan(arg_itr);
vpi_get_value(arg_handle, &value_s);
second = value_s.value.integer;
// initialize the Structure
tm.tm_year = year-1900;
tm.tm_mon = month-1; /* C Month start from 0 to 11 and RTL 1 to 12 */
tm.tm_mday = date;
tm.tm_hour = hour;
tm.tm_min = minute;
tm.tm_sec = second;
}
// vpi_printf("c_func: year: %d; month: %d; day: %d;hour: %d; minute: %d; second: %d;week day: %d; year day: %d\n",
// tm.tm_year + 1900, tm.tm_mon, tm.tm_mday,
// tm.tm_hour, tm.tm_min, tm.tm_sec,
// tm.tm_wday, tm.tm_yday);
if(cmd == CMD_RTC_NEXT_SECOND)
tm.tm_sec = tm.tm_sec + 1;
else if(cmd == CMD_RTC_NEXT_DATE)
tm.tm_mday = tm.tm_mday + 1;
mktime(&tm);
//vpi_printf("c_func: year: %d; month: %d; day: %d;hour: %d; minute: %d; second: %d;week day: %d; year day: %d\n",
// tm.tm_year + 1900, tm.tm_mon, tm.tm_mday,
// tm.tm_hour, tm.tm_min, tm.tm_sec,
// tm.tm_wday, tm.tm_yday);
char str[80];
if(cmd == CMD_RTC_NEXT_SECOND)
sprintf(str,"%02d%02d%02d%02d",tm.tm_mday,tm.tm_hour,tm.tm_min,tm.tm_sec);
else if(cmd == CMD_RTC_NEXT_DATE)
sprintf(str,"%04d%02d%02d",tm.tm_year+1900,tm.tm_mon+1,tm.tm_mday);
vpi_printf("c_func: year: %d; month: %d; day: %d;hour: %d; minute: %d; second: %d;week day: %d; year day: %d\n",
tm.tm_year + 1900, tm.tm_mon+1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec,
tm.tm_wday, tm.tm_yday);
///* write result to simulation as return value $fpu_add */
int c = (int)strtol(str, NULL, 16);
value_s.value.integer = (PLI_INT32)c;
vpi_put_value(systf_handle, &value_s, NULL, vpiNoDelay);
return(0);
}
/**
* Start-of-simulation application
****/
PLI_INT32 PLIbook_RtcStartOfSim(s_cb_data *callback_data)
{
vpi_printf("\n$c_rtc PLI application is being used.\n\n");
return(0);
}
/**********************************************************
$fpu_add Registration Data
(add this function name to the vlog_startup_routines array)
***********************************************************/
void PLIbook_fpu_add_register()
{
s_vpi_systf_data tf_data;
s_cb_data cb_data_s;
vpiHandle callback_handle;
tf_data.type = vpiSysFunc;
tf_data.sysfunctype = vpiSysFuncSized;
tf_data.tfname = "$c_rtc";
tf_data.calltf = PLIbook_RtcCalltf;
tf_data.compiletf = PLIbook_RtcCompiletf;
tf_data.sizetf = PLIbook_RtcSizetf;
tf_data.user_data = NULL;
vpi_register_systf(&tf_data);
cb_data_s.reason = cbStartOfSimulation;
cb_data_s.cb_rtn = PLIbook_RtcStartOfSim;
cb_data_s.obj = NULL;
cb_data_s.time = NULL;
cb_data_s.value = NULL;
cb_data_s.user_data = NULL;
callback_handle = vpi_register_cb(&cb_data_s);
vpi_free_object(callback_handle); /* don’t need callback handle */
}
void (*vlog_startup_routines[])() = {
PLIbook_fpu_add_register,
0
};