mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
debugged cosim
This commit is contained in:
parent
a37cf288a0
commit
61c5cd2671
@ -2,17 +2,28 @@
|
||||
#include <unistd.h>
|
||||
#include <assert.h>
|
||||
#include "vpi_user.h"
|
||||
#include <string.h>
|
||||
|
||||
#define MAXLINE 4096
|
||||
#define MAXWIDTH 10
|
||||
// #define DEBUG 1
|
||||
|
||||
typedef int PLI_INT32;
|
||||
typedef char PLI_BYTE8;
|
||||
/* Sized variables */
|
||||
#ifndef PLI_TYPES
|
||||
#define PLI_TYPES
|
||||
typedef int PLI_INT32;
|
||||
typedef unsigned int PLI_UINT32;
|
||||
typedef short PLI_INT16;
|
||||
typedef unsigned short PLI_UINT16;
|
||||
typedef char PLI_BYTE8;
|
||||
typedef unsigned char PLI_UBYTE8;
|
||||
#endif
|
||||
|
||||
static int rpipe;
|
||||
static int wpipe;
|
||||
|
||||
static vpiHandle from_myhdl_systf_handle = NULL;
|
||||
static vpiHandle to_myhdl_systf_handle = NULL;
|
||||
|
||||
typedef struct to_myhdl_data {
|
||||
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 to_myhdl_calltf(PLI_BYTE8 *user_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();
|
||||
|
||||
@ -35,7 +47,6 @@ static int init_pipes()
|
||||
static int init_pipes_flag = 0;
|
||||
|
||||
if (init_pipes_flag) {
|
||||
vprintf("INFO: pipes already initialized\n");
|
||||
return(0);
|
||||
}
|
||||
|
||||
@ -63,6 +74,7 @@ static PLI_INT32 from_myhdl_calltf(PLI_BYTE8 *user_data)
|
||||
char buf[MAXLINE];
|
||||
char s[MAXWIDTH];
|
||||
int n;
|
||||
vpiHandle q;
|
||||
|
||||
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));
|
||||
|
||||
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 */
|
||||
return(0);
|
||||
}
|
||||
buf[n] = '\0';
|
||||
|
||||
return(0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
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;
|
||||
char buf[MAXLINE];
|
||||
char s[MAXWIDTH];
|
||||
@ -126,30 +137,15 @@ static PLI_INT32 to_myhdl_calltf(PLI_BYTE8 *user_data)
|
||||
init_pipes();
|
||||
|
||||
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));
|
||||
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);
|
||||
net_iter = vpi_iterate(vpiArgument, to_myhdl_systf_handle);
|
||||
|
||||
current_time.type = vpiSimTime;
|
||||
vpi_get_time(NULL, ¤t_time);
|
||||
sprintf(buf, "TO %x%08x ", current_time.high, current_time.low);
|
||||
|
||||
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, " ");
|
||||
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));
|
||||
|
||||
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 */
|
||||
return(0);
|
||||
}
|
||||
buf[n] = '\0';
|
||||
|
||||
// register write callback by default at time 0 //
|
||||
vpi_printf("register cb\n");
|
||||
to_myhdl_data->sync_flag = 1;
|
||||
// register write callback //
|
||||
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.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);
|
||||
|
||||
}
|
||||
|
||||
|
||||
static PLI_INT32 to_myhdl_sensitivity_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)
|
||||
static PLI_INT32 to_myhdl_readwrite_callback(p_cb_data cb_data)
|
||||
{
|
||||
vpiHandle systf_handle;
|
||||
vpiHandle net_iter, net_handle;
|
||||
vpiHandle reg_iter, reg_handle;
|
||||
p_to_myhdl_data to_myhdl_data;
|
||||
s_vpi_time current_time;
|
||||
s_vpi_value value_s;
|
||||
s_cb_data cb_data_s;
|
||||
s_vpi_time time_s;
|
||||
char buf[MAXLINE];
|
||||
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;
|
||||
|
||||
vpi_printf("write callback\n");
|
||||
|
||||
if (start_flag) {
|
||||
start_flag = 0;
|
||||
write(wpipe, "START", 5);
|
||||
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 */
|
||||
buf[n] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
to_myhdl_data = (p_to_myhdl_data)cb_data->user_data;
|
||||
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);
|
||||
net_iter = vpi_iterate(vpiArgument, to_myhdl_systf_handle);
|
||||
buf[0] = '\0';
|
||||
current_time.type = vpiSimTime;
|
||||
vpi_get_time(systf_handle, ¤t_time);
|
||||
@ -253,22 +218,86 @@ static PLI_INT32 to_myhdl_write_callback(p_cb_data cb_data)
|
||||
}
|
||||
write(wpipe, buf, strlen(buf));
|
||||
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 */
|
||||
return(0);
|
||||
}
|
||||
buf[n] = '\0';
|
||||
vpi_printf("C Read %d %s\n", n, buf);
|
||||
|
||||
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) {
|
||||
assert(sscanf(buf, "%s", value_s.value.str));
|
||||
value_s.value.str = strtok(NULL, " ");
|
||||
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);
|
||||
}
|
||||
|
||||
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, ¤t_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()
|
||||
{
|
||||
|
@ -69,7 +69,6 @@ class Cosimulation(object):
|
||||
if _simulator._cosim:
|
||||
raise MultipleCosimError
|
||||
_simulator._cosim = 1
|
||||
print _simulator._cosim
|
||||
|
||||
self._rt, self._wt = rt, wt = os.pipe()
|
||||
self._rf, self._wf = rf, wf = os.pipe()
|
||||
@ -81,9 +80,9 @@ class Cosimulation(object):
|
||||
self._toSizes = toSizes = []
|
||||
self._toSigs = toSigs = []
|
||||
|
||||
self._changeFlag = 0
|
||||
self._hasChange = 0
|
||||
|
||||
child_pid = os.fork()
|
||||
child_pid = self._child_pid = os.fork()
|
||||
|
||||
if child_pid == 0:
|
||||
os.close(rt)
|
||||
@ -136,6 +135,7 @@ class Cosimulation(object):
|
||||
break
|
||||
else:
|
||||
raise Error, "Unexpected cosim input"
|
||||
# os.waitpid(child_pid, 0)
|
||||
|
||||
def _get(self):
|
||||
s = os.read(self._rt, _MAXLINE)
|
||||
@ -151,8 +151,8 @@ class Cosimulation(object):
|
||||
if s.val != next:
|
||||
s.next = next
|
||||
|
||||
def _put(self):
|
||||
t = hex(_simulator._time)[2:]
|
||||
def _put(self, time):
|
||||
t = hex(time)[2:]
|
||||
if t[-1] == 'L':
|
||||
t = t[:-1] # strip trailing L
|
||||
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:
|
||||
buf += hex(s)[2:]
|
||||
buf += " "
|
||||
self._changeFlag = 0
|
||||
self._hasChange = 0
|
||||
os.write(self._wf, buf)
|
||||
|
||||
def _waiter(self):
|
||||
sigs = tuple(self._fromSigs)
|
||||
while 1:
|
||||
yield sigs
|
||||
self._changeFlag = 1
|
||||
self._hasChange = 1
|
||||
|
||||
def __del__(self):
|
||||
""" Clear flag when this object destroyed - to suite unittest. """
|
||||
|
@ -25,6 +25,7 @@ __date__ = "$Date$"
|
||||
|
||||
from __future__ import generators
|
||||
import sys
|
||||
import os
|
||||
import exceptions
|
||||
from warnings import warn
|
||||
|
||||
@ -128,15 +129,19 @@ class Simulation(object):
|
||||
|
||||
if cosim:
|
||||
cosim._get()
|
||||
cosim._put()
|
||||
|
||||
if _siglist: continue
|
||||
if _siglist or cosim._hasChange:
|
||||
cosim._put(t)
|
||||
continue
|
||||
elif _siglist:
|
||||
continue
|
||||
if t == maxTime:
|
||||
raise StopSimulation, "Simulated for duration %s" % duration
|
||||
|
||||
if _futureEvents:
|
||||
_futureEvents.sort()
|
||||
t = sim._time = _futureEvents[0][0]
|
||||
if cosim:
|
||||
cosim._put(t)
|
||||
while _futureEvents:
|
||||
newt, event = _futureEvents[0]
|
||||
if newt == t:
|
||||
@ -148,6 +153,10 @@ class Simulation(object):
|
||||
else:
|
||||
break
|
||||
else:
|
||||
if cosim:
|
||||
os.close(cosim._rt)
|
||||
os.close(cosim._wf)
|
||||
os.waitpid(cosim._child_pid, 0)
|
||||
raise StopSimulation, "No more events"
|
||||
|
||||
except StopSimulation, e:
|
||||
|
@ -201,7 +201,7 @@ class CosimulationTest(TestCase):
|
||||
def testFromSignalVals(self):
|
||||
cosim = Cosimulation(exe + ".cosimFromSignalVals", **allSigs)
|
||||
os.read(cosim._rt, MAXLINE)
|
||||
cosim._put()
|
||||
cosim._put(0)
|
||||
|
||||
def cosimFromSignalVals(self):
|
||||
wt = int(os.environ['MYHDL_TO_PIPE'])
|
||||
|
Loading…
x
Reference in New Issue
Block a user