static PyObject *get_root_handle(PyObject *self, PyObject *args) { const char *name; gpi_sim_hdl result; PyObject *value; if (!PyArg_ParseTuple(args, "z", &name)) { return NULL; } result = gpi_get_root_handle(name); if (NULL == result) { Py_RETURN_NONE; } value = PyLong_FromVoidPtr(result); return value; }
void embed_sim_init(gpi_sim_info_t *info) { FENTER int i; // Find the simulation root gpi_sim_hdl dut = gpi_get_root_handle(getenv("TOPLEVEL")); if (dut == NULL) { fprintf(stderr, "Unable to find root instance!\n"); gpi_sim_end(); return; } PyObject *cocotb_module, *cocotb_init, *cocotb_args, *cocotb_retval; PyObject *simlog_obj, *simlog_func; PyObject *argv_list, *argc, *arg_dict, *arg_value; cocotb_module = NULL; arg_dict = NULL; //Ensure that the current thread is ready to callthe Python C API PyGILState_STATE gstate = PyGILState_Ensure(); if (get_module_ref(COCOTB_MODULE, &cocotb_module)) goto cleanup; // Create a logger object simlog_obj = PyObject_GetAttrString(cocotb_module, "log"); if (simlog_obj == NULL) { PyErr_Print(); fprintf(stderr, "Failed to to get simlog object\n"); } simlog_func = PyObject_GetAttrString(simlog_obj, "_printRecord"); if (simlog_func == NULL) { PyErr_Print(); fprintf(stderr, "Failed to get the _printRecord method"); goto cleanup; } if (!PyCallable_Check(simlog_func)) { PyErr_Print(); fprintf(stderr, "_printRecord is not callable"); goto cleanup; } set_log_handler(simlog_func); Py_DECREF(simlog_func); simlog_func = PyObject_GetAttrString(simlog_obj, "_willLog"); if (simlog_func == NULL) { PyErr_Print(); fprintf(stderr, "Failed to get the _willLog method"); goto cleanup; } if (!PyCallable_Check(simlog_func)) { PyErr_Print(); fprintf(stderr, "_willLog is not callable"); goto cleanup; } set_log_filter(simlog_func); argv_list = PyList_New(0); for (i = 0; i < info->argc; i++) { arg_value = PyString_FromString(info->argv[i]); PyList_Append(argv_list, arg_value); } arg_dict = PyModule_GetDict(cocotb_module); PyDict_SetItemString(arg_dict, "argv", argv_list); argc = PyInt_FromLong(info->argc); PyDict_SetItemString(arg_dict, "argc", argc); if (!PyCallable_Check(simlog_func)) { PyErr_Print(); fprintf(stderr, "_printRecord is not callable"); goto cleanup; } LOG_INFO("Running on %s version %s", info->product, info->version); LOG_INFO("Python interpreter initialised and cocotb loaded!"); // Now that logging has been set up ok we initialise the testbench if (-1 == PyObject_SetAttrString(cocotb_module, "SIM_NAME", PyString_FromString(info->product))) { PyErr_Print(); fprintf(stderr, "Unable to set SIM_NAME"); goto cleanup; } // Hold onto a reference to our _fail_test function pEventFn = PyObject_GetAttrString(cocotb_module, "_sim_event"); if (!PyCallable_Check(pEventFn)) { PyErr_Print(); fprintf(stderr, "cocotb._sim_event is not callable"); goto cleanup; } Py_INCREF(pEventFn); cocotb_init = PyObject_GetAttrString(cocotb_module, "_initialise_testbench"); // New reference if (cocotb_init == NULL || !PyCallable_Check(cocotb_init)) { if (PyErr_Occurred()) PyErr_Print(); fprintf(stderr, "Cannot find function \"%s\"\n", "_initialise_testbench"); Py_DECREF(cocotb_init); goto cleanup; } cocotb_args = PyTuple_New(1); PyTuple_SetItem(cocotb_args, 0, PyLong_FromLong((long)dut)); // Note: This function “steals” a reference to o. cocotb_retval = PyObject_CallObject(cocotb_init, cocotb_args); if (cocotb_retval != NULL) { LOG_DEBUG("_initialise_testbench successful"); Py_DECREF(cocotb_retval); } else { PyErr_Print(); fprintf(stderr,"Call failed\n"); gpi_sim_end(); goto cleanup; } FEXIT cleanup: if (cocotb_module) { Py_DECREF(cocotb_module); } if (arg_dict) { Py_DECREF(arg_dict); } PyGILState_Release(gstate); }