<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>xcelium on
A Scripter's Notes</title><link>https://scripter.co/tags/xcelium/</link><description>Recent content in xcelium
on A Scripter's Notes</description><language>en-us</language><managingEditor>kaushal.modi@gmail.com (Kaushal Modi)</managingEditor><webMaster>kaushal.modi@gmail.com (Kaushal Modi)</webMaster><lastBuildDate>Wed, 22 Apr 2026 08:24:58 -0400</lastBuildDate><generator>Hugo -- gohugo.io</generator><docs>https://validator.w3.org/feed/docs/rss2.html</docs><atom:link href="https://scripter.co/tags/xcelium/index.xml" rel="self" type="application/rss+xml"/><item><title> "Hello World" for SV/C++ DPI-C integration</title><link>https://scripter.co/hello-world-for-sv-cpp-dpi-c-integration/</link><description>&lt;blockquote>A little example demonstrating calling a C++ written function in
SystemVerilog.&lt;/blockquote>&lt;div class="ox-hugo-toc toc">
&lt;div class="heading">Table of Contents&lt;/div>
&lt;ul>
&lt;li>&lt;a href="#c-plus-plus-header">C++ Header&lt;/a>&lt;/li>
&lt;li>&lt;a href="#c-plus-plus-source-code">C++ Source Code&lt;/a>&lt;/li>
&lt;li>&lt;a href="#creating-shared-object--dot-so">Creating shared object (&lt;code>.so&lt;/code>)&lt;/a>
&lt;ul>
&lt;li>&lt;a href="#verifying-that-the-dot-so-actually-contains-that-exported-function">Verifying that the &lt;code>.so&lt;/code> actually contains that exported function&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>&lt;a href="#systemverilog-test-bench">SystemVerilog test bench&lt;/a>&lt;/li>
&lt;li>&lt;a href="#result">Result&lt;/a>&lt;/li>
&lt;/ul>
&lt;/div>
&lt;!--endtoc-->
&lt;p>Let&amp;rsquo;s say we want to call a C++ function named &lt;code>hello_from_cpp&lt;/code> in
SystemVerilog, and for simplicity, let&amp;rsquo;s say that this is a &lt;em>void&lt;/em>
returning function and takes no arguments.&lt;/p>
&lt;h2 id="c-plus-plus-header">C++ Header&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#c-plus-plus-header">#&lt;/a>&lt;/h2>
&lt;p>So that function signature would look like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span> &lt;span class="nf">hello_from_cpp&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>We need to &lt;strong>export&lt;/strong> that function from the C++ compiled library. So we
need to prefix that signature with the &lt;code>extern&lt;/code> keyword and wrap it
with &lt;code>extern &amp;quot;C&amp;quot;&lt;/code> as shown below, in &lt;code>libdpi.h&lt;/code>:&lt;/p>
&lt;p>&lt;a id="code-snippet--libdpi-h">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// libdpi.h
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="cp">#ifdef __cplusplus
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>&lt;span class="k">extern&lt;/span> &lt;span class="s">&amp;#34;C&amp;#34;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#endif
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">extern&lt;/span> &lt;span class="kt">void&lt;/span> &lt;span class="nf">hello_from_cpp&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#ifdef __cplusplus
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#endif
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="src-block-caption">
&lt;span class="src-block-number">&lt;a href="#code-snippet--libdpi-h">Code Snippet 1&lt;/a>:&lt;/span>
C++ Header file marking the &lt;code>hello_from_cpp&lt;/code> function as &lt;b>exportable&lt;/b>
&lt;/div>
&lt;h2 id="c-plus-plus-source-code">C++ Source Code&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#c-plus-plus-source-code">#&lt;/a>&lt;/h2>
&lt;p>And here&amp;rsquo;s the implementation of that &lt;code>hello_from_cpp&lt;/code> function in
C++:&lt;/p>
&lt;p>&lt;a id="code-snippet--libdpi-cpp">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-cpp" data-lang="cpp">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">// libdpi.cpp
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;lt;iostream&amp;gt;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>&lt;span class="k">using&lt;/span> &lt;span class="k">namespace&lt;/span> &lt;span class="n">std&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">#include&lt;/span> &lt;span class="cpf">&amp;#34;libdpi.h&amp;#34;&lt;/span>&lt;span class="cp">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="cp">&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kt">void&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nf">hello_from_cpp&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">cout&lt;/span> &lt;span class="o">&amp;lt;&amp;lt;&lt;/span> &lt;span class="s">&amp;#34;Hello from C++!&lt;/span>&lt;span class="se">\n&lt;/span>&lt;span class="s">&amp;#34;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="src-block-caption">
&lt;span class="src-block-number">&lt;a href="#code-snippet--libdpi-cpp">Code Snippet 2&lt;/a>:&lt;/span>
Implementation of the &lt;code>hello_from_cpp&lt;/code> function in C++
&lt;/div>
&lt;h2 id="creating-shared-object--dot-so">Creating shared object (&lt;code>.so&lt;/code>)&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#creating-shared-object--dot-so">#&lt;/a>&lt;/h2>
&lt;p>Cadence Xcelium uses a &lt;code>libdpi.so&lt;/code> by default as an &amp;ldquo;SV/DPI Lib&amp;rdquo;
(&lt;code>-sv_lib&lt;/code> switch) if it is present in the compilation directory. So
we will simply compile the above to a &lt;code>libdpi.so&lt;/code>.&lt;/p>
&lt;p>&lt;a id="code-snippet--libdpi-cpp-build-steps">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">g++ -c -fPIC libdpi.cpp -o libdpi.o
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">g++ -shared -Wl,-soname,libdpi.so -o libdpi.so libdpi.o
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="src-block-caption">
&lt;span class="src-block-number">&lt;a href="#code-snippet--libdpi-cpp-build-steps">Code Snippet 3&lt;/a>:&lt;/span>
&lt;code>g++&lt;/code> commands to compile &lt;code>libdpi.cpp&lt;/code> into the shared object &lt;code>libdpi.so&lt;/code>
&lt;/div>
&lt;h3 id="verifying-that-the-dot-so-actually-contains-that-exported-function">Verifying that the &lt;code>.so&lt;/code> actually contains that exported function&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#verifying-that-the-dot-so-actually-contains-that-exported-function">#&lt;/a>&lt;/h3>
&lt;p>This is a &lt;a href="https://stackoverflow.com/a/67985/1219634">wonderful SO answer&lt;/a> that taught me the existence of a CLI
GNU development tool called &lt;code>nm&lt;/code>. From its &lt;em>man&lt;/em> page, this utility nm
list symbols from object files.&lt;/p>
&lt;p>Here, I need to know which symbols from the text/code section got
exported to the &lt;code>libdpi.so&lt;/code>. When I did &lt;code>nm libdpi.so&lt;/code>, it listed
about two dozen symbols, most of which were gibberish to me. But the
symbol that I cared about: &lt;code>hello_from_cpp&lt;/code> has a &lt;strong>T&lt;/strong> before it.&lt;/p>
&lt;p>&lt;a href="http://man7.org/linux/man-pages/man1/nm.1.html">&lt;code>man nm&lt;/code>&lt;/a> says this about that &lt;strong>T&lt;/strong>:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">&amp;#34;T&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;t&amp;#34; The symbol is in the text (code) section.
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>So after kind of understanding that, I do:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-shell" data-lang="shell">&lt;span class="line">&lt;span class="cl">nm libdpi.so &lt;span class="p">|&lt;/span> rg &lt;span class="s1">&amp;#39;\bT\b&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>and I get:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">0000000000000888 T _fini
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">0000000000000698 T _init
&lt;/span>&lt;/span>&lt;span class="line hl">&lt;span class="cl">00000000000007cc T hello_from_cpp
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>
&lt;h2 id="systemverilog-test-bench">SystemVerilog test bench&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#systemverilog-test-bench">#&lt;/a>&lt;/h2>
&lt;p>With the &lt;code>libdpi.so&lt;/code> object containing the exported &lt;code>hello_from_cpp&lt;/code>
ready, we just need to &lt;em>DPI-C import&lt;/em> it into the SystemVerilog test
bench.&lt;/p>
&lt;p>&lt;a id="code-snippet--libdpi-cpp-sv-tn">&lt;/a>&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-systemverilog" data-lang="systemverilog">&lt;span class="line">&lt;span class="cl">&lt;span class="k">program&lt;/span> &lt;span class="n">top&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kn">import&lt;/span> &lt;span class="s">&amp;#34;DPI-C&amp;#34;&lt;/span> &lt;span class="k">function&lt;/span> &lt;span class="k">void&lt;/span> &lt;span class="n">hello_from_cpp&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">initial&lt;/span> &lt;span class="k">begin&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">hello_from_cpp&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">$finish&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">end&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">endprogram&lt;/span> &lt;span class="o">:&lt;/span> &lt;span class="n">top&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="src-block-caption">
&lt;span class="src-block-number">&lt;a href="#code-snippet--libdpi-cpp-sv-tn">Code Snippet 4&lt;/a>:&lt;/span>
SystemVerilog test bench importing function from C++
&lt;/div>
&lt;h2 id="result">Result&amp;nbsp;&lt;a class="headline-hash no-text-decoration" href="#result">#&lt;/a>&lt;/h2>
&lt;p>And running:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">xrun -64bit tb.sv
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>gives:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">xcelium&amp;gt; run
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Hello from C++!
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description><author>Kaushal.Modi@fakeEmailToMakeValidatorHappy.com (Kaushal Modi)</author><category domain="https://scripter.co/categories/systemverilog">systemverilog</category><category domain="https://scripter.co/tags/dpi-c">dpi-c</category><category domain="https://scripter.co/tags/cpp">cpp</category><category domain="https://scripter.co/tags/cadence">cadence</category><category domain="https://scripter.co/tags/xcelium">xcelium</category><guid>https://scripter.co/hello-world-for-sv-cpp-dpi-c-integration/</guid><pubDate>Fri, 26 Apr 2019 16:16:00 -0400</pubDate></item></channel></rss>