diff --git a/vpi/sys_display.c b/vpi/sys_display.c index ad36a1fbd..98446b8a1 100644 --- a/vpi/sys_display.c +++ b/vpi/sys_display.c @@ -65,6 +65,23 @@ static PLI_INT32 my_mcd_printf(PLI_UINT32 mcd, const char *fmt, ...) return r; } +static void my_mcd_rawwrite(PLI_UINT32 mcd, const char*buf, size_t count) +{ + if (IS_MCD(mcd)) { + vpip_mcd_rawwrite(mcd, buf, count); + } else { + FILE*fp = vpi_get_file(mcd); + if (fp) { + while (count > 0) { + size_t rc = fwrite(buf, 1, count, fp); + if (rc <= 0) break; + count -= rc; + buf += rc; + } + } + } +} + struct timeformat_info_s timeformat_info = { 0, 0, 0, 20 }; struct strobe_cb_info { @@ -1198,7 +1215,7 @@ static PLI_INT32 sys_display_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) vpiHandle callh, argv, scope; struct strobe_cb_info info; char* result; - unsigned int size, location=0; + unsigned int size; PLI_UINT32 fd_mcd; callh = vpi_handle(vpiSysTfCall, 0); @@ -1247,17 +1264,9 @@ static PLI_INT32 sys_display_calltf(ICARUS_VPI_CONST PLI_BYTE8 *name) /* Because %u and %z may put embedded NULL characters into the * returned string strlen() may not match the real size! */ result = get_display(&size, &info); - while (location < size) { - if (result[location] == '\0') { - my_mcd_printf(fd_mcd, "%c", '\0'); - location += 1; - } else { - my_mcd_printf(fd_mcd, "%s", &result[location]); - location += strlen(&result[location]); - } - } + my_mcd_rawwrite(fd_mcd, result, size); if ((strncmp(name,"$display",8) == 0) || - (strncmp(name,"$fdisplay",9) == 0)) my_mcd_printf(fd_mcd, "\n"); + (strncmp(name,"$fdisplay",9) == 0)) my_mcd_rawwrite(fd_mcd, "\n", 1); free(info.filename); free(info.items); @@ -1282,20 +1291,12 @@ static PLI_INT32 strobe_cb(p_cb_data cb) if ((! IS_MCD(info->fd_mcd) && vpi_get_file(info->fd_mcd) != NULL) || ( IS_MCD(info->fd_mcd) && my_mcd_printf(info->fd_mcd, "") != EOF)) { char* result; - unsigned int size, location=0; + unsigned int size; /* Because %u and %z may put embedded NULL characters into the * returned string strlen() may not match the real size! */ result = get_display(&size, info); - while (location < size) { - if (result[location] == '\0') { - my_mcd_printf(info->fd_mcd, "%c", '\0'); - location += 1; - } else { - my_mcd_printf(info->fd_mcd, "%s", &result[location]); - location += strlen(&result[location]); - } - } - my_mcd_printf(info->fd_mcd, "\n"); + my_mcd_rawwrite(info->fd_mcd, result, size); + my_mcd_rawwrite(info->fd_mcd, "\n", 1); free(result); } @@ -1397,23 +1398,15 @@ static int monitor_enabled = 1; static PLI_INT32 monitor_cb_2(p_cb_data cb) { char* result; - unsigned int size, location=0; + unsigned int size; (void)cb; /* Parameter is not used. */ /* Because %u and %z may put embedded NULL characters into the * returned string strlen() may not match the real size! */ result = get_display(&size, &monitor_info); - while (location < size) { - if (result[location] == '\0') { - my_mcd_printf(monitor_info.fd_mcd, "%c", '\0'); - location += 1; - } else { - my_mcd_printf(monitor_info.fd_mcd, "%s", &result[location]); - location += strlen(&result[location]); - } - } - my_mcd_printf(monitor_info.fd_mcd, "\n"); + my_mcd_rawwrite(monitor_info.fd_mcd, result, size); + my_mcd_rawwrite(monitor_info.fd_mcd, "\n", 1); monitor_scheduled = 0; free(result); return 0; diff --git a/vpi_user.h b/vpi_user.h index 52f9a5f78..8fb8b12d8 100644 --- a/vpi_user.h +++ b/vpi_user.h @@ -632,6 +632,10 @@ extern void vpip_set_return_value(int value); extern s_vpi_vecval vpip_calc_clog2(vpiHandle arg); extern void vpip_make_systf_system_defined(vpiHandle ref); + /* Perform fwrite to mcd files. This is used to write raw data, + which may include nulls. */ +extern void vpip_mcd_rawwrite(PLI_UINT32 mcd, const char*buf, size_t count); + /* Return driver information for a net bit. The information is returned in the 'counts' array as follows: counts[0] - number of drivers driving '0' onto the net diff --git a/vvp/vpi_mcd.cc b/vvp/vpi_mcd.cc index 7a092c3c7..b64e5ce35 100644 --- a/vvp/vpi_mcd.cc +++ b/vvp/vpi_mcd.cc @@ -230,6 +230,24 @@ extern "C" PLI_INT32 vpi_mcd_printf(PLI_UINT32 mcd, const char *fmt, ...) return r; } +extern "C" void vpip_mcd_rawwrite(PLI_UINT32 mcd, const char*buf, size_t cnt) +{ + if (!IS_MCD(mcd)) return; + + for(int idx = 0; idx < 31; idx += 1) { + if (((mcd>>idx) & 1) == 0) + continue; + + if (mcd_table[idx].fp == 0) + continue; + + fwrite(buf, 1, cnt, mcd_table[idx].fp); + if (idx == 0 && logfile) + fwrite(buf, 1, cnt, mcd_table[idx].fp); + + } +} + extern "C" PLI_INT32 vpi_mcd_flush(PLI_UINT32 mcd) { int rc = 0; diff --git a/vvp/vvp.def b/vvp/vvp.def index 20434df84..c49f79400 100644 --- a/vvp/vvp.def +++ b/vvp/vvp.def @@ -41,4 +41,5 @@ vpip_calc_clog2 vpip_count_drivers vpip_format_strength vpip_make_systf_system_defined +vpip_mcd_rawwrite vpip_set_return_value