1
0
mirror of https://github.com/myhdl/myhdl.git synced 2025-01-24 21:52:56 +08:00

debugged cosim

This commit is contained in:
jand 2003-04-22 22:49:17 +00:00
parent a37cf288a0
commit 61c5cd2671
4 changed files with 122 additions and 84 deletions

View File

@ -2,17 +2,28 @@
#include <unistd.h> #include <unistd.h>
#include <assert.h> #include <assert.h>
#include "vpi_user.h" #include "vpi_user.h"
#include <string.h>
#define MAXLINE 4096 #define MAXLINE 4096
#define MAXWIDTH 10 #define MAXWIDTH 10
// #define DEBUG 1
/* Sized variables */
#ifndef PLI_TYPES
#define PLI_TYPES
typedef int PLI_INT32; typedef int PLI_INT32;
typedef unsigned int PLI_UINT32;
typedef short PLI_INT16;
typedef unsigned short PLI_UINT16;
typedef char PLI_BYTE8; typedef char PLI_BYTE8;
typedef unsigned char PLI_UBYTE8;
#endif
static int rpipe; static int rpipe;
static int wpipe; static int wpipe;
static vpiHandle from_myhdl_systf_handle = NULL; static vpiHandle from_myhdl_systf_handle = NULL;
static vpiHandle to_myhdl_systf_handle = NULL;
typedef struct to_myhdl_data { typedef struct to_myhdl_data {
vpiHandle systf_handle; vpiHandle systf_handle;
@ -23,7 +34,8 @@ typedef struct to_myhdl_data {
static PLI_INT32 from_myhdl_calltf(PLI_BYTE8 *user_data); static PLI_INT32 from_myhdl_calltf(PLI_BYTE8 *user_data);
static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data); static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data);
static PLI_INT32 to_myhdl_sensitivity_callback(p_cb_data cb_data); static PLI_INT32 to_myhdl_sensitivity_callback(p_cb_data cb_data);
static PLI_INT32 to_myhdl_write_callback(p_cb_data cb_data); static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data);
static PLI_INT32 to_myhdl_delay_callback(p_cb_data cb_data);
static int init_pipes(); static int init_pipes();
@ -35,7 +47,6 @@ static int init_pipes()
static int init_pipes_flag = 0; static int init_pipes_flag = 0;
if (init_pipes_flag) { if (init_pipes_flag) {
vprintf("INFO: pipes already initialized\n");
return(0); return(0);
} }
@ -63,6 +74,7 @@ static PLI_INT32 from_myhdl_calltf(PLI_BYTE8 *user_data)
char buf[MAXLINE]; char buf[MAXLINE];
char s[MAXWIDTH]; char s[MAXWIDTH];
int n; int n;
vpiHandle q;
static int from_myhdl_flag = 0; static int from_myhdl_flag = 0;
@ -92,19 +104,18 @@ static PLI_INT32 from_myhdl_calltf(PLI_BYTE8 *user_data)
write(wpipe, buf, strlen(buf)); write(wpipe, buf, strlen(buf));
if ((n = read(rpipe, buf, MAXLINE)) == 0) { if ((n = read(rpipe, buf, MAXLINE)) == 0) {
vpi_printf("Info: myhdl down\n"); vpi_printf("Info: MyHDL simulator down\n");
vpi_control(vpiFinish, 1); /* abort simulation */ vpi_control(vpiFinish, 1); /* abort simulation */
return(0); return(0);
} }
buf[n] = '\0'; buf[n] = '\0';
return(0); return(0);
} }
static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data) static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data)
{ {
vpiHandle systf_handle, net_iter, net_handle; vpiHandle net_iter, net_handle;
vpiHandle cb_h; vpiHandle cb_h;
char buf[MAXLINE]; char buf[MAXLINE];
char s[MAXWIDTH]; char s[MAXWIDTH];
@ -126,30 +137,15 @@ static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data)
init_pipes(); init_pipes();
vpi_printf("Hello from $to_myhdl %d %d\n", rpipe, wpipe); vpi_printf("Hello from $to_myhdl %d %d\n", rpipe, wpipe);
systf_handle = vpi_handle(vpiSysTfCall, NULL); to_myhdl_systf_handle = vpi_handle(vpiSysTfCall, NULL);
to_myhdl_data = (p_to_myhdl_data)malloc(sizeof(s_to_myhdl_data)); net_iter = vpi_iterate(vpiArgument, to_myhdl_systf_handle);
to_myhdl_data->systf_handle = systf_handle;
to_myhdl_data->sync_flag = 0;
/* setup sensitivity callback */
time_s.type = vpiSuppressTime;
value_s.format = vpiSuppressVal;
cb_data_s.reason = cbValueChange;
cb_data_s.user_data = (PLI_BYTE8 *)to_myhdl_data;
cb_data_s.cb_rtn = to_myhdl_sensitivity_callback;
cb_data_s.time = &time_s;
cb_data_s.value = NULL;
net_iter = vpi_iterate(vpiArgument, systf_handle);
current_time.type = vpiSimTime; current_time.type = vpiSimTime;
vpi_get_time(NULL, &current_time); vpi_get_time(NULL, &current_time);
sprintf(buf, "TO %x%08x ", current_time.high, current_time.low); sprintf(buf, "TO %x%08x ", current_time.high, current_time.low);
while ((net_handle = vpi_scan(net_iter)) != NULL) { while ((net_handle = vpi_scan(net_iter)) != NULL) {
cb_data_s.obj = net_handle;
vpi_register_cb(&cb_data_s);
strcat(buf, vpi_get_str(vpiName, net_handle)); strcat(buf, vpi_get_str(vpiName, net_handle));
strcat(buf, " "); strcat(buf, " ");
sprintf(s, "%d ", vpi_get(vpiSize, net_handle)); sprintf(s, "%d ", vpi_get(vpiSize, net_handle));
@ -158,89 +154,58 @@ static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data)
write(wpipe, buf, strlen(buf)); write(wpipe, buf, strlen(buf));
if ((n = read(rpipe, buf, MAXLINE)) == 0) { if ((n = read(rpipe, buf, MAXLINE)) == 0) {
vpi_printf("Info: myhdl down\n"); vpi_printf("Info: MyHDL simulator down\n");
vpi_control(vpiFinish, 1); /* abort simulation */ vpi_control(vpiFinish, 1); /* abort simulation */
return(0); return(0);
} }
buf[n] = '\0'; buf[n] = '\0';
// register write callback by default at time 0 // // register write callback //
vpi_printf("register cb\n");
to_myhdl_data->sync_flag = 1;
time_s.type = vpiSimTime; time_s.type = vpiSimTime;
time_s.high = 0; time_s.high = 0;
time_s.low = 0; time_s.low = 0;
cb_data_s.reason = cbReadWriteSynch; cb_data_s.reason = cbReadWriteSynch;
cb_data_s.user_data = (PLI_BYTE8 *)to_myhdl_data; cb_data_s.user_data = NULL;
cb_data_s.cb_rtn = to_myhdl_write_callback; cb_data_s.cb_rtn = to_myhdl_readwrite_callback;
cb_data_s.obj = NULL; cb_data_s.obj = NULL;
cb_data_s.time = &time_s; cb_data_s.time = &time_s;
cb_data_s.value = NULL; cb_data_s.value = NULL;
vpi_register_cb(&cb_data_s); vpi_register_cb(&cb_data_s);
return(0); return(0);
} }
static PLI_INT32 to_myhdl_sensitivity_callback(p_cb_data cb_data) static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data)
{
vpiHandle cb_h;
s_cb_data cb_data_s;
s_vpi_time time_s;
p_to_myhdl_data to_myhdl_data;
vpiHandle net_handle;
to_myhdl_data = (p_to_myhdl_data)cb_data->user_data;
vpi_printf("sens triggered\n");
if (!to_myhdl_data->sync_flag) {
vpi_printf("register cb\n");
to_myhdl_data->sync_flag = 1;
time_s.type = vpiSimTime;
time_s.high = 0;
time_s.low = 0;
cb_data_s.reason = cbReadWriteSynch;
cb_data_s.user_data = (PLI_BYTE8 *)to_myhdl_data;
cb_data_s.cb_rtn = to_myhdl_write_callback;
cb_data_s.obj = NULL;
cb_data_s.time = &time_s;
cb_data_s.value = NULL;
vpi_register_cb(&cb_data_s);
}
return(0);
}
static PLI_INT32 to_myhdl_write_callback(p_cb_data cb_data)
{ {
vpiHandle systf_handle; vpiHandle systf_handle;
vpiHandle net_iter, net_handle; vpiHandle net_iter, net_handle;
vpiHandle reg_iter, reg_handle; vpiHandle reg_iter, reg_handle;
p_to_myhdl_data to_myhdl_data;
s_vpi_time current_time; s_vpi_time current_time;
s_vpi_value value_s; s_vpi_value value_s;
s_cb_data cb_data_s;
s_vpi_time time_s;
char buf[MAXLINE]; char buf[MAXLINE];
int n; int n;
char *time_high_string;
char *time_low_string;
PLI_UINT32 time_low;
PLI_UINT32 time_high;
PLI_UINT32 delay;
static int start_flag = 1; static int start_flag = 1;
vpi_printf("write callback\n");
if (start_flag) { if (start_flag) {
start_flag = 0; start_flag = 0;
write(wpipe, "START", 5); write(wpipe, "START", 5);
if ((n = read(rpipe, buf, MAXLINE)) == 0) { if ((n = read(rpipe, buf, MAXLINE)) == 0) {
vpi_printf("Info: myhdl down\n"); vpi_printf("Info: MyHDL simulator down\n");
vpi_control(vpiFinish, 1); /* abort simulation */ vpi_control(vpiFinish, 1); /* abort simulation */
buf[n] = '\0'; buf[n] = '\0';
} }
} }
to_myhdl_data = (p_to_myhdl_data)cb_data->user_data; net_iter = vpi_iterate(vpiArgument, to_myhdl_systf_handle);
vpi_printf("sync flag: %d\n", to_myhdl_data->sync_flag);
to_myhdl_data->sync_flag = 0;
systf_handle = to_myhdl_data->systf_handle;
net_iter = vpi_iterate(vpiArgument, systf_handle);
buf[0] = '\0'; buf[0] = '\0';
current_time.type = vpiSimTime; current_time.type = vpiSimTime;
vpi_get_time(systf_handle, &current_time); vpi_get_time(systf_handle, &current_time);
@ -253,22 +218,86 @@ static PLI_INT32 to_myhdl_write_callback(p_cb_data cb_data)
} }
write(wpipe, buf, strlen(buf)); write(wpipe, buf, strlen(buf));
if ((n = read(rpipe, buf, MAXLINE)) == 0) { if ((n = read(rpipe, buf, MAXLINE)) == 0) {
vpi_printf("Info: myhdl down\n"); vpi_printf("Info: MyHDL simulator down\n");
vpi_control(vpiFinish, 1); /* abort simulation */ vpi_control(vpiFinish, 1); /* abort simulation */
return(0); return(0);
} }
buf[n] = '\0'; buf[n] = '\0';
vpi_printf("C Read %d %s\n", n, buf);
reg_iter = vpi_iterate(vpiArgument, from_myhdl_systf_handle); reg_iter = vpi_iterate(vpiArgument, from_myhdl_systf_handle);
time_high_string = strtok(buf, " ");
time_low_string = strtok(NULL, " ");
time_high = (PLI_UINT32) strtoul(time_high_string, (char **) NULL, 16);
time_low = (PLI_UINT32) strtoul(time_low_string, (char **) NULL, 16);
assert(time_high == current_time.high);
if (time_low != current_time.low) { // schedule cbAfterDelay callback
if (time_low < current_time.low) {
delay = 0xFFFFFFFF - current_time.low + time_low;
} else {
delay = time_low - current_time.low;
}
// register cbAfterDelay callback //
time_s.type = vpiSimTime;
time_s.high = 0;
time_s.low = delay;
cb_data_s.reason = cbAfterDelay;
cb_data_s.user_data = NULL;
cb_data_s.cb_rtn = to_myhdl_delay_callback;
cb_data_s.obj = NULL;
cb_data_s.time = &time_s;
cb_data_s.value = NULL;
vpi_register_cb(&cb_data_s);
// We're done for now
if (reg_iter != NULL) {
vpi_free_object(reg_iter);
}
/* while ((reg_handle = vpi_scan(reg_iter)) != NULL) { */
/* value_s.value.str = strtok(NULL, " "); */
// }
return(0);
}
while ((reg_handle = vpi_scan(reg_iter)) != NULL) { while ((reg_handle = vpi_scan(reg_iter)) != NULL) {
assert(sscanf(buf, "%s", value_s.value.str)); value_s.value.str = strtok(NULL, " ");
vpi_put_value(reg_handle, &value_s, NULL, vpiNoDelay); vpi_put_value(reg_handle, &value_s, NULL, vpiNoDelay);
} }
// register myself again //
time_s.type = vpiSimTime;
time_s.high = 0;
time_s.low = 0;
cb_data_s.reason = cbReadWriteSynch;
cb_data_s.user_data = NULL;
cb_data_s.cb_rtn = to_myhdl_readwrite_callback;
cb_data_s.obj = NULL;
cb_data_s.time = &time_s;
cb_data_s.value = NULL;
vpi_register_cb(&cb_data_s);
return(0); return(0);
} }
static PLI_INT32 to_myhdl_delay_callback(p_cb_data cb_data)
{
s_cb_data cb_data_s;
s_vpi_time time_s;
s_vpi_time current_time;
vpi_get_time(NULL, &current_time);
// register readwrite callback //
time_s.type = vpiSimTime;
time_s.high = 0;
time_s.low = 0;
cb_data_s.reason = cbReadWriteSynch;
cb_data_s.user_data = NULL;
cb_data_s.cb_rtn = to_myhdl_readwrite_callback;
cb_data_s.obj = NULL;
cb_data_s.time = &time_s;
cb_data_s.value = NULL;
vpi_register_cb(&cb_data_s);
return(0);
}
void myhdl_register() void myhdl_register()
{ {

View File

@ -69,7 +69,6 @@ class Cosimulation(object):
if _simulator._cosim: if _simulator._cosim:
raise MultipleCosimError raise MultipleCosimError
_simulator._cosim = 1 _simulator._cosim = 1
print _simulator._cosim
self._rt, self._wt = rt, wt = os.pipe() self._rt, self._wt = rt, wt = os.pipe()
self._rf, self._wf = rf, wf = os.pipe() self._rf, self._wf = rf, wf = os.pipe()
@ -81,9 +80,9 @@ class Cosimulation(object):
self._toSizes = toSizes = [] self._toSizes = toSizes = []
self._toSigs = toSigs = [] self._toSigs = toSigs = []
self._changeFlag = 0 self._hasChange = 0
child_pid = os.fork() child_pid = self._child_pid = os.fork()
if child_pid == 0: if child_pid == 0:
os.close(rt) os.close(rt)
@ -136,6 +135,7 @@ class Cosimulation(object):
break break
else: else:
raise Error, "Unexpected cosim input" raise Error, "Unexpected cosim input"
# os.waitpid(child_pid, 0)
def _get(self): def _get(self):
s = os.read(self._rt, _MAXLINE) s = os.read(self._rt, _MAXLINE)
@ -151,8 +151,8 @@ class Cosimulation(object):
if s.val != next: if s.val != next:
s.next = next s.next = next
def _put(self): def _put(self, time):
t = hex(_simulator._time)[2:] t = hex(time)[2:]
if t[-1] == 'L': if t[-1] == 'L':
t = t[:-1] # strip trailing L t = t[:-1] # strip trailing L
t = (9 - len(t)) * '0' + t # zero-extend to more than 32 bits t = (9 - len(t)) * '0' + t # zero-extend to more than 32 bits
@ -160,14 +160,14 @@ class Cosimulation(object):
for s in self._fromSigs: for s in self._fromSigs:
buf += hex(s)[2:] buf += hex(s)[2:]
buf += " " buf += " "
self._changeFlag = 0 self._hasChange = 0
os.write(self._wf, buf) os.write(self._wf, buf)
def _waiter(self): def _waiter(self):
sigs = tuple(self._fromSigs) sigs = tuple(self._fromSigs)
while 1: while 1:
yield sigs yield sigs
self._changeFlag = 1 self._hasChange = 1
def __del__(self): def __del__(self):
""" Clear flag when this object destroyed - to suite unittest. """ """ Clear flag when this object destroyed - to suite unittest. """

View File

@ -25,6 +25,7 @@ __date__ = "$Date$"
from __future__ import generators from __future__ import generators
import sys import sys
import os
import exceptions import exceptions
from warnings import warn from warnings import warn
@ -128,15 +129,19 @@ class Simulation(object):
if cosim: if cosim:
cosim._get() cosim._get()
cosim._put() if _siglist or cosim._hasChange:
cosim._put(t)
if _siglist: continue continue
elif _siglist:
continue
if t == maxTime: if t == maxTime:
raise StopSimulation, "Simulated for duration %s" % duration raise StopSimulation, "Simulated for duration %s" % duration
if _futureEvents: if _futureEvents:
_futureEvents.sort() _futureEvents.sort()
t = sim._time = _futureEvents[0][0] t = sim._time = _futureEvents[0][0]
if cosim:
cosim._put(t)
while _futureEvents: while _futureEvents:
newt, event = _futureEvents[0] newt, event = _futureEvents[0]
if newt == t: if newt == t:
@ -148,6 +153,10 @@ class Simulation(object):
else: else:
break break
else: else:
if cosim:
os.close(cosim._rt)
os.close(cosim._wf)
os.waitpid(cosim._child_pid, 0)
raise StopSimulation, "No more events" raise StopSimulation, "No more events"
except StopSimulation, e: except StopSimulation, e:

View File

@ -201,7 +201,7 @@ class CosimulationTest(TestCase):
def testFromSignalVals(self): def testFromSignalVals(self):
cosim = Cosimulation(exe + ".cosimFromSignalVals", **allSigs) cosim = Cosimulation(exe + ".cosimFromSignalVals", **allSigs)
os.read(cosim._rt, MAXLINE) os.read(cosim._rt, MAXLINE)
cosim._put() cosim._put(0)
def cosimFromSignalVals(self): def cosimFromSignalVals(self):
wt = int(os.environ['MYHDL_TO_PIPE']) wt = int(os.environ['MYHDL_TO_PIPE'])