Esempio n. 1
0
static PyObject *stop_simulator(PyObject *self, PyObject *args)
{
    gpi_sim_end();
    return Py_BuildValue("s", "OK!");
}
Esempio n. 2
0
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);
}
Esempio n. 3
0
/**
 * @name    Callback Handling
 * @brief   Handle a callback coming from GPI
 * @ingroup python_c_api
 *
 * GILState before calling: Unknown
 *
 * GILState after calling: Unknown
 *
 * Makes one call to TAKE_GIL and one call to DROP_GIL
 *
 * Returns 0 on success or 1 on a failure.
 *
 * Handles a callback from the simulator, all of which call this function.
 *
 * We extract the associated context and find the Python function (usually
 * cocotb.scheduler.react) calling it with a reference to the trigger that
 * fired. The scheduler can then call next() on all the coroutines that
 * are waiting on that particular trigger.
 *
 * TODO:
 *  - Tidy up return values
 *  - Ensure cleanup correctly in exception cases
 *
 */
int handle_gpi_callback(void *user_data)
{
    int ret = 0;
    to_python();
    p_callback_data callback_data_p = (p_callback_data)user_data;

    if (callback_data_p->id_value != COCOTB_ACTIVE_ID) {
        fprintf(stderr, "Userdata corrupted!\n");
        ret = 1;
        goto err;
    }
    callback_data_p->id_value = COCOTB_INACTIVE_ID;

    /* Cache the sim time */
    gpi_get_sim_time(&cache_time.high, &cache_time.low);

    PyGILState_STATE gstate;
    gstate = TAKE_GIL();

    // Python allowed

    if (!PyCallable_Check(callback_data_p->function)) {
        fprintf(stderr, "Callback fired but function isn't callable?!\n");
        ret = 1;
        goto out;
    }

    // Call the callback
    PyObject *pValue = PyObject_Call(callback_data_p->function, callback_data_p->args, callback_data_p->kwargs);

    // If the return value is NULL a Python exception has occurred
    // The best thing to do here is shutdown as any subsequent
    // calls will go back to python which is now in an unknown state
    if (pValue == NULL)
    {
        fprintf(stderr, "ERROR: called callback function returned NULL\n");
        if (PyErr_Occurred()) {
            fprintf(stderr, "Failed to execute callback due to python exception\n");
            PyErr_Print();
        } else {
            fprintf(stderr, "Failed to execute callback\n");
        }

        gpi_sim_end();
        ret = 0;
        goto out;
    }

    // Free up our mess
    Py_DECREF(pValue);

    // Callbacks may have been re-enabled
    if (callback_data_p->id_value == COCOTB_INACTIVE_ID) {
        Py_DECREF(callback_data_p->function);
        Py_DECREF(callback_data_p->args);

        // Free the callback data
        free(callback_data_p);
    }

out:
    DROP_GIL(gstate);

err:
    to_simulator();
    return ret;
}