Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
120 lines (115 loc) · 10.8 KB
/
Copy pathindex.html
File metadata and controls
120 lines (115 loc) · 10.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>DPI-C and Python</title>
<link rel="stylesheet" href="assets/guide.css">
<script>try{var t=localStorage.getItem('dpic-theme');if(t)document.documentElement.dataset.theme=t}catch(e){}</script>
<script defer src="assets/guide.js"></script>
<style>
.home{max-width:1080px;margin:0 auto;padding:0 16px 120px}
.home .hero{padding:64px 0 24px}
.home h1{max-width:16ch}
.part{display:flex;align-items:baseline;gap:14px;margin:64px 0 18px}
.part h2{margin:0}
.part span{font:500 12.5px var(--font-mono);color:var(--muted)}
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:18px}
.card{display:flex;flex-direction:column;gap:10px;padding:20px 22px;background:var(--surface);border:1px solid var(--line);border-radius:16px;
text-decoration:none;color:var(--ink);box-shadow:var(--shadow);transition:transform .15s,border-color .15s}
.card:hover{transform:translateY(-3px);border-color:var(--acc)}
.card .top{display:flex;justify-content:space-between;align-items:center;margin:0}
.card .num{font:600 40px/1 var(--font-display);font-variation-settings:"SOFT" 100;color:var(--acc)}
.card .pct{font:500 12px var(--font-mono);color:var(--muted)}
.card .pct.done{color:var(--ok)}
.card h3{margin:0;font-size:22px}
.card p{margin:0;font-size:16px;line-height:1.55;color:var(--ink-2)}
.card .bar{height:4px;border-radius:4px;background:var(--surface-2);overflow:hidden;margin-top:auto}
.card .bar b{display:block;height:100%;width:0;background:var(--ok)}
.card.gaps{border-style:dashed}
.card.gaps .num{color:var(--trap)}
.facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px;margin:28px 0 0}
.facts div{background:var(--surface);border:1px solid var(--line);border-radius:12px;padding:12px 16px}
.facts b{display:block;font:600 22px var(--font-display);font-variation-settings:"SOFT" 100;color:var(--acc)}
.facts span{font:500 12.5px var(--font-mono);color:var(--muted)}
.cta{display:flex;flex-wrap:wrap;gap:12px;margin:8px 0 0}
.cta a{font:500 15px var(--font-mono);padding:9px 18px;border-radius:10px;border:1px solid var(--line-2);color:var(--ink);text-decoration:none}
.cta a.go{background:var(--acc);border-color:var(--acc);color:var(--on-acc)}
.cta a:hover{border-color:var(--acc)}
.home h2{margin-top:64px}
.home .part h2{margin:0}
</style>
</head>
<body>
<div class="home">
<main style="max-width:none">
<p class="kicker">python-dpic · tutorial</p>
<h1>DPI-C from scratch, then Python as a golden model</h1>
<p class="deck">An incremental tutorial on the SystemVerilog Direct Programming Interface, measured on Verilator 5.052, ending with Python functions called as bit-exact reference models from a SystemVerilog testbench.</p>
<div class="cta"><a class="go" href="01_first_call/guide.html">Start with step 01 →</a><a href="#start">Run the labs</a><a href="https://github.com/leandrotozzi/python-dpic">Source on GitHub</a></div>
<div class="facts">
<div><b>8</b><span>steps, ≈ 2 h each</span></div>
<div><b>458</b><span>lab checks, all passing</span></div>
<div><b>52</b><span>measured Verilator gaps</span></div>
<div><b>15</b><span>book errata fixed</span></div>
</div>
<h2 id="start">Get started</h2>
<p>Each step is a guide plus a lab. The guide reads in the browser (this site, or <code>tutorial/index.html</code> from a clone, offline). The lab is a folder of small SystemVerilog + C/Python testbenches that Verilator builds and runs; <code>check.py</code> asserts every number the guide quotes.</p>
<div class="tbl"><table>
<tr><th>You need</th><th>For</th><th>Measured with</th></tr>
<tr><td>Verilator 5.x</td><td>every lab (<code>--binary --timing</code>)</td><td>5.052</td></tr>
<tr><td>A C/C++ compiler</td><td>every lab</td><td>Apple clang, macOS x86_64</td></tr>
<tr><td>Python 3 with <code>python3-config</code></td><td><code>check.py</code>; embedding in steps 07–08</td><td>3.14</td></tr>
<tr><td>numpy</td><td>step 08 (FIR golden model)</td><td>2.x</td></tr>
<tr><td>z3</td><td>step 06 (<code>randomize()</code> calls it as an external solver)</td><td></td></tr>
<tr><td>ccache (optional)</td><td>faster rebuilds</td><td></td></tr>
</table></div>
<pre><code class="language-bash">git clone https://github.com/leandrotozzi/python-dpic.git
cd python-dpic/tutorial/01_first_call/lab
python3 check.py <span class="c"># builds every testbench in build/, runs them, asserts the results</span></code></pre>
<p>Every guide has the same layout: text → worked examples → exercises with hidden solutions → self-graded quiz → lab walkthrough → cheat sheet. Try an exercise before opening its solution; the files it refers to are in the step's <code>lab/</code> (<code>lab/ex/</code> for exercises). The index on the left of each guide ticks off sections as you read; the cards below show that progress.</p>
<p>Everything was measured on macOS. Linux runs the same commands; the few macOS-only details are flagged on the <a href="verilator_gaps.html">Verilator gaps</a> page. Commercial simulators (Questa, VCS, Xcelium) follow the same IEEE 1800 Annex H rules; where they differ from Verilator the guides say so.</p>
<div class="part"><h2>Part A · DPI-C</h2><span>Spear & Tumbush ch. 12</span></div>
<div class="cards">
<a class="card" href="01_first_call/guide.html"><div class="top"><span class="num">01</span><span class="pct"></span></div><h3>First call</h3><p>import "DPI-C", pure, renaming, libm, how Verilator compiles and links C, the generated prototype header, extern "C".</p><div class="bar"><b></b></div></a>
<a class="card" href="02_data_types/guide.html"><div class="top"><span class="num">02</span><span class="pct"></span></div><h3>Data types</h3><p>The SV↔C type map, svBitVecVal/svLogicVecVal, wide vectors, directions, 2-state vs 4-state.</p><div class="bar"><b></b></div></a>
<a class="card" href="03_state_and_handles/guide.html"><div class="top"><span class="num">03</span><span class="pct"></span></div><h3>State and handles</h3><p>Static vs per-instance state, chandle, C++ models behind a C ABI, lifetime and leaks, threads.</p><div class="bar"><b></b></div></a>
<a class="card" href="04_arrays_structs_strings/guide.html"><div class="top"><span class="num">04</span><span class="pct"></span></div><h3>Arrays, structs, strings</h3><p>Fixed and open arrays, svOpenArrayHandle, packed arrays, struct layout, string ownership.</p><div class="bar"><b></b></div></a>
<a class="card" href="05_export_and_context/guide.html"><div class="top"><span class="num">05</span><span class="pct"></span></div><h3>Export and context</h3><p>Calling SV from C, context vs pure, scopes, why exported tasks can't wait in Verilator.</p><div class="bar"><b></b></div></a>
<a class="card" href="06_golden_model_c/guide.html"><div class="top"><span class="num">06</span><span class="pct"></span></div><h3>Golden model in C</h3><p>DUT + C reference + scoreboard, random stimulus, mutants, cost per call, stream vs batch.</p><div class="bar"><b></b></div></a>
</div>
<div class="part"><h2>Part B · Python</h2><span>the same SV imports, backed by Python</span></div>
<div class="cards">
<a class="card" href="07_embedding_python/guide.html"><div class="top"><span class="num">07</span><span class="pct"></span></div><h3>Embedding Python</h3><p>The CPython C API from a DPI library: lifecycle, imports, refcounts, errors, the GIL, venvs.</p><div class="bar"><b></b></div></a>
<a class="card" href="08_python_golden_model/guide.html"><div class="top"><span class="num">08</span><span class="pct"></span></div><h3>Python golden model</h3><p>zlib and numpy as reference models, wide ints, batching, measured C vs Python, pysv / PyHDL-IF / cocotb.</p><div class="bar"><b></b></div></a>
<a class="card gaps" href="verilator_gaps.html"><div class="top"><span class="num">!</span><span class="pct"></span></div><h3>What doesn't work in Verilator</h3><p>52 measured gaps in one place, silent wrong results first, each with its workaround and the lab that proves it.</p><div class="bar"><b></b></div></a>
</div>
<p style="margin-top:28px">Steps 06 and 08 share two DUTs: <a href="common/rtl/crc32_stream.sv"><code>crc32_stream.sv</code></a> (CRC-32/IEEE, bit-exact with <code>zlib.crc32</code>) and <a href="common/rtl/fir8.sv"><code>fir8.sv</code></a> (8-tap Q1.15 FIR, round half-up, saturating). Raw measurements behind every guide: <a href="NOTES.md">NOTES.md</a>.</p>
<h2 id="references">References</h2>
<ul>
<li><b>IEEE Std 1800-2023</b>, clause 35 (DPI), Annex H (DPI C layer), Annex I (<code>svdpi.h</code>). The normative source.</li>
<li><b>Spear & Tumbush</b>, <i>SystemVerilog for Verification</i>, 3rd ed., Springer 2012, ch. 12 “Interfacing with C/C++”. Steps 01–06 follow it; its errata are on the <a href="verilator_gaps.html">gaps page</a>.</li>
<li><a href="https://verilator.org/guide/latest/connecting.html">Verilator manual</a>, “Direct Programming Interface (DPI)” and “Connecting to C++”.</li>
<li>Doulos, <a href="https://www.doulos.com/knowhow/systemverilog/systemverilog-tutorials/systemverilog-dpi-tutorial/">SystemVerilog DPI tutorial</a>.</li>
<li>AMD UG900, “Open Arrays in DPI” / “Support for svdpi.h functions” (a clear vendor summary of Annex H/I).</li>
<li>AMIQ, <a href="https://www.consulting.amiq.com/2019/01/30/how-to-call-c-functions-from-systemverilog-using-dpi-c/">How to Call C-functions from SystemVerilog Using DPI-C</a> and <a href="https://www.consulting.amiq.com/?p=5664">How to Connect SystemVerilog with Python</a> (2019).</li>
<li>Python docs, <a href="https://docs.python.org/3/extending/embedding.html">Embedding Python in Another Application</a> and <a href="https://docs.python.org/3/c-api/init_config.html">Python Initialization Configuration</a> (PEP 587 / PEP 741).</li>
<li>M. Ballance, <i>Properly Introducing Python to your UVM Testbench</i>, DVCon US 2026 (PyHDL-IF).</li>
<li>Libraries for later: <a href="https://github.com/Kuree/pysv">pysv</a>, <a href="https://github.com/fvutils/pyhdl-if">PyHDL-IF</a>, <a href="https://www.cocotb.org">cocotb</a>, <a href="https://github.com/pyuvm/pyuvm">pyuvm</a>.</li>
</ul>
</main>
</div>
<script>
document.querySelectorAll('.card').forEach(function (c) {
var href = c.getAttribute('href'), parts = href.split('/'), key = 'dpic-seen:' + (parts.length > 1 ? parts[0] : 'tutorial') + '/' + parts[parts.length - 1];
var seen = {}; try { seen = JSON.parse(localStorage.getItem(key) || '{}') || {}; } catch (e) {}
var total = 0; try { total = +localStorage.getItem(key.replace('dpic-seen:', 'dpic-total:')) || 0; } catch (e) {}
var n = Object.keys(seen).length;
if (!n || !total) return;
var pct = Math.min(100, Math.round(100 * n / total));
c.querySelector('.bar b').style.width = pct + '%';
var p = c.querySelector('.pct'); p.textContent = pct >= 100 ? 'read ✓' : pct + '% read'; if (pct >= 100) p.classList.add('done');
});
</script>
</body>
</html>