mirror of
https://github.com/myhdl/myhdl.git
synced 2025-01-24 21:52:56 +08:00
added
This commit is contained in:
parent
cbdec54ba5
commit
1bdfe5ab97
205
myhdl/simrunc.c
Normal file
205
myhdl/simrunc.c
Normal file
@ -0,0 +1,205 @@
|
||||
#include "Python.h"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
static PyObject *_simulator;
|
||||
static PyObject *_siglist;
|
||||
static PyObject *_futureEvents;
|
||||
static PyObject *_WaiterList;
|
||||
static PyObject *_Waiter;
|
||||
static PyObject *Signal;
|
||||
static PyObject *delay;
|
||||
static PyObject *StopSimulation;
|
||||
static PyObject *SuspendSimulation;
|
||||
|
||||
|
||||
PyObject *
|
||||
run(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||
{
|
||||
|
||||
PyObject *sim;
|
||||
long int duration = 0;
|
||||
int quiet = 0;
|
||||
static char *argnames[] = {"sim", "duration", "quiet", NULL};
|
||||
|
||||
PyObject *waiters, *waiter, *clauses, *clone, *clause, *type, *newtO, *event;
|
||||
long long int maxTime = -1;
|
||||
long long int t = 0;
|
||||
long long int ct = 0;
|
||||
long long int newt = 0;
|
||||
int nr;
|
||||
int len, i, j;
|
||||
PyObject *tO, *extl, *s, *hr, *hgl, *nt, *c, *wl, *ev, *ctO, *r;
|
||||
|
||||
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|li", argnames,
|
||||
&sim, &duration, &quiet)) {
|
||||
return NULL;
|
||||
}
|
||||
waiters = PyObject_GetAttrString(sim, "_waiters");
|
||||
tO = PyObject_GetAttrString(_simulator, "_time");
|
||||
t = PyLong_AsLongLong(tO);
|
||||
Py_DECREF(tO);
|
||||
|
||||
|
||||
for (;;) {
|
||||
|
||||
|
||||
len = PyList_Size(_siglist);
|
||||
for (i = 0; i < len; i++) {
|
||||
s = PyList_GetItem(_siglist, i);
|
||||
extl = PyObject_CallMethod(s, "_update", NULL);
|
||||
for (j = 0; j < PyList_Size(extl); j++) {
|
||||
PyList_Append(waiters, PyList_GetItem(extl, j));
|
||||
}
|
||||
Py_DECREF(extl);
|
||||
}
|
||||
PySequence_DelSlice(_siglist, 0, len);
|
||||
|
||||
while (PyList_Size(waiters) > 0) {
|
||||
waiter = PyList_GetItem(waiters, 0);
|
||||
Py_INCREF(waiter);
|
||||
PySequence_DelItem(waiters, 0);
|
||||
hr = PyObject_GetAttrString(waiter, "hasRun");
|
||||
if (PyObject_IsTrue(hr)) {
|
||||
Py_DECREF(waiter);
|
||||
Py_DECREF(hr);
|
||||
continue;
|
||||
}
|
||||
Py_DECREF(hr);
|
||||
hgl = PyObject_CallMethod(waiter, "hasGreenLight", NULL);
|
||||
if (!PyObject_IsTrue(hgl)) {
|
||||
Py_DECREF(waiter);
|
||||
Py_DECREF(hgl);
|
||||
continue;
|
||||
}
|
||||
Py_DECREF(hgl);
|
||||
nt = PyObject_CallMethod(waiter, "next", NULL);
|
||||
if (nt == NULL) {
|
||||
if (PyErr_ExceptionMatches(PyExc_StopIteration)) {
|
||||
c = PyObject_GetAttrString(waiter, "caller");
|
||||
if (c != Py_None) {
|
||||
PyList_Append(waiters, c);
|
||||
}
|
||||
Py_DECREF(waiter);
|
||||
Py_DECREF(c);
|
||||
continue;
|
||||
} else {
|
||||
goto exception;
|
||||
}
|
||||
}
|
||||
clauses = PyTuple_GetItem(nt, 0);
|
||||
clone = PyTuple_GetItem(nt, 1);
|
||||
nr = PyTuple_Size(clauses);
|
||||
for (i = 0; i < nr; i++) {
|
||||
clause = PySequence_GetItem(clauses, i);
|
||||
type = PyObject_Type(clause);
|
||||
if (type == _WaiterList) {
|
||||
PyList_Append(clause, clone);
|
||||
} else if (PyObject_IsInstance(clause, Signal)) {
|
||||
wl = PyObject_GetAttrString(clause, "_eventWaiters");
|
||||
PyList_Append(wl, clone);
|
||||
Py_DECREF(wl);
|
||||
} else if (type == delay) {
|
||||
ctO = PyObject_GetAttrString(clause, "_time");
|
||||
ct = PyLong_AsLongLong(ctO);
|
||||
Py_DECREF(ctO);
|
||||
ev = PyTuple_New(2);
|
||||
newtO = PyLong_FromLongLong(t + ct);
|
||||
PyTuple_SetItem(ev, 0, newtO);
|
||||
PyTuple_SetItem(ev, 1, clone);
|
||||
PyList_Append(_futureEvents, ev);
|
||||
Py_DECREF(ev);
|
||||
} else {
|
||||
assert(0);
|
||||
}
|
||||
Py_DECREF(clause);
|
||||
}
|
||||
Py_DECREF(nt);
|
||||
}
|
||||
|
||||
|
||||
if (PyList_Size(_siglist) > 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (PyList_Size(_futureEvents) > 0) {
|
||||
PyObject_CallMethod(_futureEvents, "sort", NULL);
|
||||
newtO = PyTuple_GetItem(PyList_GetItem(_futureEvents, 0), 0);
|
||||
PyObject_SetAttrString(_simulator, "_time", newtO);
|
||||
t = PyLong_AsLongLong(newtO);
|
||||
while (PyList_Size(_futureEvents) > 0) {
|
||||
ev = PyList_GetItem(_futureEvents, 0);
|
||||
newtO = PyTuple_GetItem(ev, 0);
|
||||
newt = PyLong_AsLongLong(newtO);
|
||||
event = PyTuple_GetItem(ev, 1);
|
||||
if (newt == t) {
|
||||
if (PyObject_Type(event) == _Waiter) {
|
||||
PyList_Append(waiters, event);
|
||||
} else {
|
||||
extl = PyObject_CallMethod(event, "apply", NULL);
|
||||
for (j = 0; j < PyList_Size(extl); j++) {
|
||||
PyList_Append(waiters, PyList_GetItem(extl, j));
|
||||
}
|
||||
Py_DECREF(extl);
|
||||
}
|
||||
PySequence_DelItem(_futureEvents, 0);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
PyErr_SetString(StopSimulation, "No more events");
|
||||
printf("No more events\n");
|
||||
goto exception;
|
||||
}
|
||||
}
|
||||
|
||||
assert(0); /* should not get here */
|
||||
|
||||
exception:
|
||||
if (PyErr_ExceptionMatches(StopSimulation)) {
|
||||
printf("Stop simulation reached \n");
|
||||
PyErr_Clear();
|
||||
r = PyObject_CallMethod(sim, "_finalize", NULL);
|
||||
Py_DECREF(r);
|
||||
return PyInt_FromLong(0);
|
||||
}
|
||||
return Py_BuildValue("");
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef simruncmethods[] = {
|
||||
{"run", (PyCFunction)run, METH_VARARGS | METH_KEYWORDS},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
void initsimrunc(void) {
|
||||
PyObject *SignalModule;
|
||||
PyObject *delayModule;
|
||||
PyObject *_WaiterModule;
|
||||
PyObject *utilModule;
|
||||
|
||||
Py_InitModule("simrunc", simruncmethods);
|
||||
|
||||
_simulator = PyImport_ImportModule("_simulator");
|
||||
_siglist = PyObject_GetAttrString(_simulator, "_siglist");
|
||||
_futureEvents = PyObject_GetAttrString(_simulator, "_futureEvents");
|
||||
SignalModule = PyImport_ImportModule("Signal");
|
||||
Signal = PyObject_GetAttrString(SignalModule, "Signal");
|
||||
_WaiterList = PyObject_GetAttrString(SignalModule, "_WaiterList");
|
||||
delayModule = PyImport_ImportModule("delay");
|
||||
delay = PyObject_GetAttrString(delayModule, "delay");
|
||||
_WaiterModule = PyImport_ImportModule("_Waiter");
|
||||
_Waiter = PyObject_GetAttrString(_WaiterModule, "_Waiter");
|
||||
utilModule = PyImport_ImportModule("util");
|
||||
StopSimulation = PyObject_GetAttrString(utilModule, "StopSimulation");
|
||||
SuspendSimulation = PyObject_GetAttrString(utilModule, "SuspendSimulation");
|
||||
|
||||
Py_DECREF(SignalModule);
|
||||
Py_DECREF(delayModule);
|
||||
Py_DECREF(_WaiterModule);
|
||||
Py_DECREF(utilModule);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user