0

I'm trying to understand how to create a C++ testbench to drive stimulus to a DUT in Verilog. Let's say I have a simple scenario:

// Testbench Top.
module tb_top();

import "DPI-C" function void wait_for_input_ready();
initial
    wait_for_input_ready();

import "DPI-C" function void notify_input_ready();
always @(posedge clk or negedge rst)
begin
   // based on some condition here I want to send input-ready notify.
   notify_input_ready();
end

endmodule

And here is my C++ code:

test_case.h

    extern "C" void wait_for_input_ready();
    extern "C" void notify_input_ready();

test_case.cpp

    #include "test_case.h"

    std::conditional_variable cond_var;
    std::mutex input_mutex;
    bool input_ready = false;

    void wait_for_input_ready()
    {
        std::unique_lock<std::mutex> lock(input_mutex);

        while(input_ready != true)
            cond_var.wait(lock, [&]{return input_ready == true;});  // This is where the problem happens.
    }

    void notify_input_ready()
    {
        std::unique_lock<std::mutex> lock(input_mutex);
        is_ready = true;
        cond_var.notify_one(); // Unblock to wait statement.
    }

In this example, the wait statement on the conditional variable blocks forever and does not let the simulator execute any other parts of the Verilog code. So what is the right approach here? Should I create a thread in C++ inside the wait_for_input_ready function and detach it completely?

Greg
  • 18,111
  • 5
  • 46
  • 68
sundar
  • 456
  • 2
  • 7
  • 19

1 Answers1

3

You cannot mix the concepts of SystemVerilog threads with C++ threads. From the DPI point of view, everything is executing in the same thread. If you want the C++ code to appear as if it were a SystemVerilog thread, you need to import your C++ code as a task, and have it call an exported SystemVerilog task.

Several links you may want to read: https://s3.amazonaws.com/verificationacademy-news/DVCon2013/Papers/MGC_DVCon_13_Easy_Steps_Towards_Virtual_Prototyping_Using_the_SystemVerilog_DPI.pdf

https://verificationacademy.com/forums/ovm/how-maintain-database-c-function-if-firmware-hardware-co-simulation-used#reply-37204

dave_59
  • 39,096
  • 3
  • 24
  • 63
  • Thanks for the pointers Dave. I'm trying to create an independent (threaded) c++ testbench that will communicate to a HDL synthesized on an emulator through Scemi APIs (e.g. function based DPI-C). But even before I move to an emulator I want to use my simulator to test the whole thing (by calling my c++ testcase in tb_top) and since DPI-C is supported in all simulators. So my C++ testbench runs a thread which will wait for a input ready notify from the HDL. The notify call from HDL will unblock the waiting C++ thread which will in-turn send the data to the DUT. Or is this even possible ? – sundar Oct 19 '15 at 09:23
  • SCE-MI has a service loop that arbitrates all the threads on the C++ side with the simulation. I thought it was possible to use SCE-MI with a pure software simulation, but I'm not sure. I think you will get much better help contacting your vendor direct as there are not that many people with knowledge in this area. – dave_59 Oct 19 '15 at 15:35