<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>VUnit on Elaborated Designs</title>
    <link>https://elaborateddesigns.com/tags/vunit/</link>
    <description>Recent content in VUnit on Elaborated Designs</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <lastBuildDate>Thu, 13 Mar 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://elaborateddesigns.com/tags/vunit/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Using Queues in VHDL with VUnit</title>
      <link>https://elaborateddesigns.com/posts/007_using_queues_in_vhdl_with_vunit/</link>
      <pubDate>Thu, 13 Mar 2025 00:00:00 +0000</pubDate>
      
      <guid>https://elaborateddesigns.com/posts/007_using_queues_in_vhdl_with_vunit/</guid>
      <description>In this post we will discuss what queues are and how we can use them in VHDL with the VUnit verification framework.</description>
      <content:encoded><![CDATA[
    <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/OgWrzgIF0Mo?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<br>
<h2 id="learning-outcome">Learning Outcome</h2>
<p>By the end of this post we’ll understand how to use queues to store and share data across processes in our test testbenches, and we’ll have several examples of working code to help us get started in our next project.</p>
<h2 id="what-is-a-queue">What is a Queue?</h2>
<p>A queue is a data structure into which data are written on one side (push) and read on the other side (pop). Queues operate on a first-in first-out basis, and like a hardware FIFO, we usually cannot access the elements inside the queue.</p>
<p>At a minimum, a queue must support pushing data to it and popping data from it. In a ‘push’ operation the data is added to the back of the queue. Any existing elements inside the queue are shifted to make room for the new data.</p>
<p>A ‘pop’ operation works in the opposite direction: data is removed from the from the front of the queue. Any remaining elements stay in their position as the queue shrinks, until eventually it is empty again.</p>
<p>Queues are very useful for storing and sharing data between processes in a test bench. A typical use case is to save the inputs to a design under test (DUT) in an input queue and the outputs of the DUT in an output queue. The test bench can then run a reference model that reads the data from the input queue, calculates a set of expected outputs, and compares them with the actual output values stored in the output queue.</p>
<h2 id="using-queues-in-vunit">Using Queues in VUnit</h2>
<p>Unlike SystemVerilog, VHDL does not support queues natively. Luckily, the VUnit verification framework includes a queue data type and API to interact with it, so we don’t have to implement our own.</p>
<p>The function calls that we’ll use most frequently when working with queues in VUnit are: <strong>new</strong>, <strong>push</strong>, <strong>pop</strong>, <strong>is_empty</strong>, <strong>length</strong>, and <strong>flush</strong>. Let’s discuss each one with a code example.</p>
<p>We start by setting up a minimal VUnit testbench.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">library</span> <span class="nn">vunit_lib</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">context</span> <span class="n">vunit_lib</span><span class="p">.</span><span class="n">vunit_context</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">entity</span> <span class="nc">tb_example</span> <span class="k">is</span>
</span></span><span class="line"><span class="cl">  <span class="k">generic</span> <span class="p">(</span><span class="n">runner_cfg</span> <span class="o">:</span> <span class="kt">string</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">entity</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">architecture</span> <span class="nc">tb</span> <span class="k">of</span> <span class="nc">tb_example</span> <span class="k">is</span>
</span></span><span class="line"><span class="cl"><span class="k">begin</span>
</span></span><span class="line"><span class="cl">  <span class="n">main</span> <span class="o">:</span> <span class="k">process</span>
</span></span><span class="line"><span class="cl">  <span class="k">begin</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_runner_setup</span><span class="p">(</span><span class="n">runner</span><span class="p">,</span> <span class="n">runner_cfg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_runner_cleanup</span><span class="p">(</span><span class="n">runner</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span> <span class="k">process</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">architecture</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Then we can add our &rsquo;test_queue&rsquo; signal, of type &lsquo;queue_t&rsquo;.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">architecture</span> <span class="nc">tb</span> <span class="k">of</span> <span class="nc">tb_example</span> <span class="k">is</span>
</span></span><span class="line"><span class="cl">  <span class="k">signal</span> <span class="n">test_queue</span> <span class="o">:</span> <span class="n">queue_t</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">begin</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>We&rsquo;ll also declare several variables in our &lsquo;main&rsquo; process to exchange data with the queue API.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">main</span> <span class="o">:</span> <span class="k">process</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">bit_push_v</span>       <span class="o">:</span> <span class="kt">std_logic</span> <span class="o">:=</span> <span class="sc">&#39;1&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">vector_16_push_v</span> <span class="o">:</span> <span class="kt">std_logic_vector</span><span class="p">(</span><span class="mi">15</span> <span class="k">downto</span> <span class="mi">0</span><span class="p">)</span> <span class="o">:=</span> <span class="mh">x&#34;0123&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">vector_32_push_v</span> <span class="o">:</span> <span class="kt">std_logic_vector</span><span class="p">(</span><span class="mi">31</span> <span class="k">downto</span> <span class="mi">0</span><span class="p">)</span> <span class="o">:=</span> <span class="mh">x&#34;456789AB&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">integer_push_v</span>   <span class="o">:</span> <span class="kt">integer</span> <span class="o">:=</span> <span class="mi">2147483647</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">bit_pop_v</span>        <span class="o">:</span> <span class="kt">std_logic</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">vector_16_pop_v</span>  <span class="o">:</span> <span class="kt">std_logic_vector</span><span class="p">(</span><span class="mi">15</span> <span class="k">downto</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">vector_32_pop_v</span>  <span class="o">:</span> <span class="kt">std_logic_vector</span><span class="p">(</span><span class="mi">31</span> <span class="k">downto</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">integer_pop_v</span>    <span class="o">:</span> <span class="kt">integer</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">begin</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Now we are ready to describe the logic in our &lsquo;main&rsquo; process.</p>
<h3 id="new">New</h3>
<p>The <strong>&rsquo;new&rsquo;</strong> function creates the underlying queue object that we will use. It must be called before performing any other operations on the queue.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;***** Creating the queue *****&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">test_queue</span> <span class="o">&lt;=</span> <span class="n">new_queue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">wait</span> <span class="k">for</span> <span class="mi">0</span> <span class="n">ns</span><span class="p">;</span>  <span class="c1">-- Removing this will cause an error</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>One important thing to note is that the queue operations do not consume any simulation time, so in some cases we’ll need to add a delay to make sure that a function call is executed. In this example, if we remove the ‘wait for 0 ns’ statement, the next operation (push) would produce an error, because we’d be trying to manipulate a null queue.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="err">#</span> <span class="n">Surrounding</span> <span class="n">code</span> <span class="n">from</span> <span class="na">&#39;see</span><span class="p">&#39;</span> <span class="n">command</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span>   <span class="mi">86</span> <span class="o">:</span>     <span class="n">value</span> <span class="o">:</span> <span class="kt">character</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span>   <span class="mi">87</span> <span class="o">:</span>   <span class="p">)</span> <span class="k">is</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span>   <span class="mi">88</span> <span class="o">:</span>     <span class="k">variable</span> <span class="n">tail</span> <span class="o">:</span> <span class="kt">integer</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span>   <span class="mi">89</span> <span class="o">:</span>     <span class="k">variable</span> <span class="n">head</span> <span class="o">:</span> <span class="kt">integer</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span>   <span class="mi">90</span> <span class="o">:</span>   <span class="k">begin</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="o">-&gt;</span><span class="mi">91</span> <span class="o">:</span>     <span class="k">assert</span> <span class="n">queue</span> <span class="o">/=</span> <span class="n">null_queue</span> <span class="n">report</span> <span class="s">&#34;Push to null queue&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span>   <span class="mi">92</span> <span class="o">:</span>     <span class="n">tail</span> <span class="o">:=</span> <span class="n">get</span><span class="p">(</span><span class="n">queue</span><span class="p">.</span><span class="n">p_meta</span><span class="p">,</span> <span class="n">tail_idx</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span>   <span class="mi">93</span> <span class="o">:</span>     <span class="n">head</span> <span class="o">:=</span> <span class="n">get</span><span class="p">(</span><span class="n">queue</span><span class="p">.</span><span class="n">p_meta</span><span class="p">,</span> <span class="n">head_idx</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span>   <span class="mi">94</span> <span class="o">:</span>     <span class="k">if</span> <span class="n">length</span><span class="p">(</span><span class="n">queue</span><span class="p">.</span><span class="n">data</span><span class="p">)</span> <span class="o">&lt;</span> <span class="n">tail</span> <span class="o">+</span> <span class="mi">1</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span>   <span class="mi">95</span> <span class="o">:</span>       <span class="c1">-- Allocate more new data, double data to avoid</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> 
</span></span><span class="line"><span class="cl"><span class="n">fail</span> <span class="p">(</span><span class="n">P</span><span class="o">=</span><span class="mi">0</span> <span class="n">S</span><span class="o">=</span><span class="mi">0</span> <span class="n">F</span><span class="o">=</span><span class="mi">1</span> <span class="n">T</span><span class="o">=</span><span class="mi">1</span><span class="p">)</span> <span class="n">lib</span><span class="p">.</span><span class="n">vubit_queue_tb</span><span class="p">.</span><span class="k">all</span> <span class="p">(</span><span class="mi">1</span><span class="p">.</span><span class="mi">6</span> <span class="n">seconds</span><span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="push">Push</h3>
<p>The <strong>&lsquo;push&rsquo;</strong> function stores a new element into the queue. Unlike SystemVerilog queues, a single VUnit queue can hold elements of different data types at the same time.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Pushing elements of different types to the queue&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">bit_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">vector_16_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">vector_32_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">integer_v</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="pop">Pop</h3>
<p>The <strong>&lsquo;pop&rsquo;</strong> function removes the oldest element in the queue and returns it so that we can use or store it.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;***** Popping elements of different types from the queue *****&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">bit_pop_v</span> <span class="o">:=</span> <span class="n">pop</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">vector_16_pop_v</span> <span class="o">:=</span> <span class="n">pop</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">vector_32_pop_v</span> <span class="o">:=</span> <span class="n">pop</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">integer_pop_v</span> <span class="o">:=</span> <span class="n">pop</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Popped a 16-bit vector: &#34;</span> <span class="o">&amp;</span> <span class="n">to_hstring</span><span class="p">(</span><span class="n">vector_16_pop_v</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Popped a 32-bit vector: &#34;</span> <span class="o">&amp;</span> <span class="n">to_hstring</span><span class="p">(</span><span class="n">vector_32_pop_v</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Popped an integer: &#34;</span> <span class="o">&amp;</span> <span class="kt">integer</span><span class="na">&#39;image</span><span class="p">(</span><span class="n">integer_pop_v</span><span class="p">));</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- Simulation output</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="o">*****</span> <span class="n">Popping</span> <span class="n">elements</span> <span class="k">of</span> <span class="n">different</span> <span class="n">types</span> <span class="n">from</span> <span class="n">the</span> <span class="n">queue</span> <span class="o">*****</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Popped</span> <span class="n">a</span> <span class="mi">16</span><span class="o">-</span><span class="kt">bit</span> <span class="n">vector</span><span class="o">:</span> <span class="mi">0123</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Popped</span> <span class="n">a</span> <span class="mi">32</span><span class="o">-</span><span class="kt">bit</span> <span class="n">vector</span><span class="o">:</span> <span class="mi">456789</span><span class="n">AB</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Popped</span> <span class="n">an</span> <span class="kt">integer</span><span class="o">:</span> <span class="mi">2147483647</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>The VUnit API also includes verbose versions of the <strong>&lsquo;push&rsquo;</strong> and <strong>&lsquo;pop&rsquo;</strong> functions, which we can use to make the type of the argument or return type explicit.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;***** Using verbose funtion calls to resolve data types *****&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">vector_32_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Popping a logic vector: &#34;</span> <span class="o">&amp;</span> <span class="n">to_string</span><span class="p">(</span><span class="n">pop_std_ulogic_vector</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">vector_32_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="c1">-- info(&#34;Popping a logic vector: &#34; &amp; to_string(pop(test_queue)));    -- Error!</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Uncommenting the last line of the code section above produces an error.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- Simulation output</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="o">*****</span> <span class="n">Using</span> <span class="n">verbose</span> <span class="n">funtion</span> <span class="n">calls</span> <span class="k">to</span> <span class="n">resolve</span> <span class="n">data</span> <span class="n">types</span> <span class="o">*****</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Popping</span> <span class="n">a</span> <span class="n">logic</span> <span class="n">vector</span><span class="o">:</span> <span class="mi">01000101011001111000100110101011</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="o">**</span> <span class="n">Error</span><span class="o">:</span> <span class="n">Got</span> <span class="n">queue</span> <span class="n">element</span> <span class="k">of</span> <span class="k">type</span> <span class="kt">std_ulogic_vector</span><span class="p">,</span> <span class="n">expected</span> <span class="n">string_ptr_t</span><span class="p">.</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>We can comment the last line again to get the testbench running. This also leaves the second 32-bit vector still in the queue.</p>
<h3 id="is-empty">Is Empty</h3>
<p>The <strong>&lsquo;is_empty&rsquo;</strong> function returns ‘true’ if the queue is empty, and ‘false’ if it has at least one element.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Checking if the queue is empty&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="n">is_empty</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="n">info</span><span class="p">(</span><span class="s">&#34;The queue is empty&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="n">info</span><span class="p">(</span><span class="s">&#34;The queue is not empty&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">if</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">bit_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="n">is_empty</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)</span> <span class="k">then</span>
</span></span><span class="line"><span class="cl">  <span class="n">info</span><span class="p">(</span><span class="s">&#34;The queue is empty&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">else</span>
</span></span><span class="line"><span class="cl">  <span class="n">info</span><span class="p">(</span><span class="s">&#34;The queue is not empty&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">if</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- Simulation output</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="o">*****</span> <span class="n">Checking</span> <span class="k">if</span> <span class="n">the</span> <span class="n">queue</span> <span class="k">is</span> <span class="n">empty</span> <span class="o">*****</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">The</span> <span class="n">queue</span> <span class="k">is</span> <span class="k">not</span> <span class="n">empty</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">The</span> <span class="n">queue</span> <span class="k">is</span> <span class="n">empty</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="flush">Flush</h3>
<p>The <strong>&lsquo;flush&rsquo;</strong> function removes all elements from the queue, leaving it empty.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;***** Flushing the queue *****&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">bit_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">vector_16_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">vector_32_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">integer_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Queue length before flushing:&#34;</span> <span class="o">&amp;</span> <span class="kt">natural</span><span class="na">&#39;image</span><span class="p">(</span><span class="n">length</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl"><span class="n">flush</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Queue length after flushing:&#34;</span> <span class="o">&amp;</span> <span class="kt">natural</span><span class="na">&#39;image</span><span class="p">(</span><span class="n">length</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)));</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- Simulation output</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="o">*****</span> <span class="n">Flushing</span> <span class="n">the</span> <span class="n">queue</span> <span class="o">*****</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Queue</span> <span class="n">length</span> <span class="n">before</span> <span class="n">flushing</span><span class="o">:</span> <span class="mi">59</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Queue</span> <span class="n">length</span> <span class="k">after</span> <span class="n">flushing</span><span class="o">:</span> <span class="mi">0</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="length">Length</h3>
<p>The <strong>&rsquo;length&rsquo;</strong> function returns the length of the queue, in bytes. It’s important to note that this length refers to the space that the simulator allocates to each element in the queue, and not the size of the element that we use in our test bench. For example, calling the ‘length’ function on a queue with one integer returns 5 bytes, not the 4 bytes that we might expect given that an integer in VHDL is by default 32-bits wide. The same applies to logic vectors: the length of a 1-bit vector is 2 bytes, the length of a 32-bit vector is 30 bytes.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- File: vunit_queues.vhd</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;***** Getting the queue&#39;s length *****&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">bit_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Queue length after pushing a single bit: &#34;</span> <span class="o">&amp;</span> <span class="kt">natural</span><span class="na">&#39;image</span><span class="p">(</span><span class="n">length</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl"><span class="n">flush</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">vector_8_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Queue length after pushing a 8-bit vector: &#34;</span> <span class="o">&amp;</span> <span class="kt">natural</span><span class="na">&#39;image</span><span class="p">(</span><span class="n">length</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl"><span class="n">flush</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">vector_16_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Queue length after pushing a 16-bit vector: &#34;</span> <span class="o">&amp;</span> <span class="kt">natural</span><span class="na">&#39;image</span><span class="p">(</span><span class="n">length</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl"><span class="n">flush</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">vector_32_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Queue length after pushing a 32-bit vector: &#34;</span> <span class="o">&amp;</span> <span class="kt">natural</span><span class="na">&#39;image</span><span class="p">(</span><span class="n">length</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl"><span class="n">flush</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">push</span><span class="p">(</span><span class="n">test_queue</span><span class="p">,</span> <span class="n">integer_push_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">info</span><span class="p">(</span><span class="s">&#34;Queue length after pushing an integer: &#34;</span> <span class="o">&amp;</span> <span class="kt">natural</span><span class="na">&#39;image</span><span class="p">(</span><span class="n">length</span><span class="p">(</span><span class="n">test_queue</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl"><span class="n">flush</span><span class="p">(</span><span class="n">test_queue</span><span class="p">);</span>
</span></span></code></pre></td></tr></table>
</div>
</div><div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="c1">-- Simulation output</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="o">*****</span> <span class="n">Getting</span> <span class="n">the</span> <span class="n">queue</span><span class="na">&#39;s</span> <span class="n">length</span> <span class="o">*****</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Queue</span> <span class="n">length</span> <span class="k">after</span> <span class="n">pushing</span> <span class="n">a</span> <span class="n">single</span> <span class="kt">bit</span><span class="o">:</span><span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Queue</span> <span class="n">length</span> <span class="k">after</span> <span class="n">pushing</span> <span class="n">a</span> <span class="mi">8</span><span class="o">-</span><span class="kt">bit</span> <span class="n">vector</span><span class="o">:</span><span class="mi">18</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Queue</span> <span class="n">length</span> <span class="k">after</span> <span class="n">pushing</span> <span class="n">a</span> <span class="mi">16</span><span class="o">-</span><span class="kt">bit</span> <span class="n">vector</span><span class="o">:</span><span class="mi">22</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Queue</span> <span class="n">length</span> <span class="k">after</span> <span class="n">pushing</span> <span class="n">a</span> <span class="mi">32</span><span class="o">-</span><span class="kt">bit</span> <span class="n">vector</span><span class="o">:</span><span class="mi">30</span>
</span></span><span class="line"><span class="cl"><span class="err">#</span> <span class="mi">0</span> <span class="n">ps</span> <span class="o">-</span> <span class="n">default</span> <span class="o">-</span> <span class="n">INFO</span> <span class="o">-</span> <span class="n">Queue</span> <span class="n">length</span> <span class="k">after</span> <span class="n">pushing</span> <span class="n">an</span> <span class="kt">integer</span><span class="o">:</span><span class="mi">5</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="summary">Summary</h2>
<p>In this post we discussed queues, a FIFO-like data structure that we can use to transfer data between processes in a testbench. Because of VHDL&rsquo;s lack of native support for queues, we looked into the VUnit&rsquo;s queue library, and ran code examples for the most common operations in the VUnit queue API: new, push, pop, is_empty, length, and flush.</p>
<p>Cheers,</p>
<p>Isaac</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Setting up a VHDL Verification Environment with VUnit</title>
      <link>https://elaborateddesigns.com/posts/005_setting_up_a_vhdl_verification_environment_with_vunit/</link>
      <pubDate>Fri, 24 Jan 2025 00:00:00 +0000</pubDate>
      
      <guid>https://elaborateddesigns.com/posts/005_setting_up_a_vhdl_verification_environment_with_vunit/</guid>
      <description>In this post we will set up a minimal verification environment with VUnit. Our testbench will include verification components for driving an monitoring an AXI-Stream bus.</description>
      <content:encoded><![CDATA[
    <div style="position: relative; padding-bottom: 56.25%; height: 0; overflow: hidden;">
      <iframe allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen="allowfullscreen" loading="eager" referrerpolicy="strict-origin-when-cross-origin" src="https://www.youtube-nocookie.com/embed/_i8MCmtIPmg?autoplay=0&amp;controls=1&amp;end=0&amp;loop=0&amp;mute=0&amp;start=0" style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; border:0;" title="YouTube video"></iframe>
    </div>

<br>
<p>Using a verification framework can dramatically improve the quality of our designs. However, setting up a verification framework from scratch can be quite daunting. Luckily, there are open-source libraries that handle most of the infrastructure required for creating, running and managing our tests, so that we can focus on the parts of our testbench that are unique to our design and add value to our development process.</p>
<p>In this post we will set up a minimal verification environment with VUnit. Our testbench will include verification components for driving an monitoring an AXI-Stream bus.</p>
<h2 id="what-is-vunit">What is VUnit?</h2>
<p>VUnit is a open-source unit-testing framework for digital systems design with VHDL and SystemVerilog. It provides the infrastructure for creating and managing verification environments so we can focus on writing meaningful tests. At its core, VUnit provides a Python-based test runner that manages our test cases, handles compilation dependencies, and produces structured test reports.</p>
<p>In addition to automating the simulation runs and test management, VUnit also provides several libraries to help write our testcases. These libraries include verification components, logging mechanisms, check procedures, and randomization. By leveraging these pre-built components we can make the testcase-creation process more efficient, less error-prone, and more enjoyable.</p>
<h2 id="prerequisites-for-setting-up-a-verification-environment-with-vunit">Prerequisites for Setting up a Verification Environment with VUnit</h2>
<p>There are two prerequisites for using VUnit: we must have a supported VHDL simulator and we must have a Python installation, including a package manager and a tool for creating virtual environments.</p>
<p>VUnit supports several simulators, a comprehensive list can be found in the project&rsquo;s <a href="https://vunit.github.io/cli.html#simulator-selection">documentation</a>. For this example we will use GHDL. In Ubuntu 24.04.1 LTS we can install GHDL using the Snap packet manager.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo snap install ghdl
</span></span></code></pre></td></tr></table>
</div>
</div><p>Once we have our simulator, we can install the VUnit Python module. The recommended way to do this is within a Python virtual environment. If we&rsquo;re using <code>venv</code> we can do this from the terminal by moving into the folder where we&rsquo;ll run our simulations and using the commands shown below.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 -m venv venv
</span></span><span class="line"><span class="cl"><span class="nb">source</span> venv/bin/activate
</span></span><span class="line"><span class="cl">pip install vunit_hdl
</span></span></code></pre></td></tr></table>
</div>
</div><p>We are now ready to create our verification environemnt.</p>
<h2 id="setting-up-a-minimal-verification-environment-with-vunit">Setting up a minimal Verification Environment with VUnit</h2>
<p>A VUnit verification environment includes at least two files: a testbench and a simulation script.</p>
<p>This is what a VUnit testbench in its simplest form looks like, as described in the <a href="https://vunit.github.io/user_guide.html">VUnit User Guide</a>.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="k">library</span> <span class="nn">vunit_lib</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">context</span> <span class="n">vunit_lib</span><span class="p">.</span><span class="n">vunit_context</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">entity</span> <span class="nc">tb_example</span> <span class="k">is</span>
</span></span><span class="line"><span class="cl">  <span class="k">generic</span> <span class="p">(</span><span class="n">runner_cfg</span> <span class="o">:</span> <span class="kt">string</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">entity</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">architecture</span> <span class="nc">tb</span> <span class="k">of</span> <span class="nc">tb_example</span> <span class="k">is</span>
</span></span><span class="line"><span class="cl"><span class="k">begin</span>
</span></span><span class="line"><span class="cl">  <span class="n">main</span> <span class="o">:</span> <span class="k">process</span>
</span></span><span class="line"><span class="cl">  <span class="k">begin</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_runner_setup</span><span class="p">(</span><span class="n">runner</span><span class="p">,</span> <span class="n">runner_cfg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">report</span> <span class="s">&#34;Hello world!&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_runner_cleanup</span><span class="p">(</span><span class="n">runner</span><span class="p">);</span> <span class="c1">-- Simulation ends here</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span> <span class="k">process</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">architecture</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>We must pair our testbench with a simulation script, which in its minimal form looks like this:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">vunit</span> <span class="kn">import</span> <span class="n">VUnit</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Create VUnit instance by parsing command line arguments</span>
</span></span><span class="line"><span class="cl"><span class="n">vu</span> <span class="o">=</span> <span class="n">VUnit</span><span class="o">.</span><span class="n">from_argv</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Add VUnit&#39;s builtin HDL utilities</span>
</span></span><span class="line"><span class="cl"><span class="n">vu</span><span class="o">.</span><span class="n">add_vhdl_builtins</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Create library &#39;lib&#39;</span>
</span></span><span class="line"><span class="cl"><span class="n">lib</span> <span class="o">=</span> <span class="n">vu</span><span class="o">.</span><span class="n">add_library</span><span class="p">(</span><span class="s2">&#34;lib&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Add all files ending in .vhd in current working directory to library</span>
</span></span><span class="line"><span class="cl"><span class="n">lib</span><span class="o">.</span><span class="n">add_source_files</span><span class="p">(</span><span class="s2">&#34;*.vhd&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Run vunit function</span>
</span></span><span class="line"><span class="cl"><span class="n">vu</span><span class="o">.</span><span class="n">main</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>We can then run the simulation script from the command line.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 run.py
</span></span></code></pre></td></tr></table>
</div>
</div><p>The terminal output confirms that the test was run succesfully. Line 4 shows the location of the file where all the messages in our testbench are logged.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">Compile passed
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Starting lib.tb_example.all
</span></span><span class="line"><span class="cl">Output file: /home/isaac/Projects/blog/004_vunit_verification_environment/vunit_out/test_output/lib.tb_example.all_7b5933c73ddb812488c059080644e9fd58c418d9/output.txt
</span></span><span class="line"><span class="cl">pass <span class="o">(</span><span class="nv">P</span><span class="o">=</span><span class="m">1</span> <span class="nv">S</span><span class="o">=</span><span class="m">0</span> <span class="nv">F</span><span class="o">=</span><span class="m">0</span> <span class="nv">T</span><span class="o">=</span>1<span class="o">)</span> lib.tb_example.all <span class="o">(</span>0.3 seconds<span class="o">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">====</span> <span class="nv">Summary</span> <span class="o">==============================</span>
</span></span><span class="line"><span class="cl">pass lib.tb_example.all <span class="o">(</span>0.3 seconds<span class="o">)</span>
</span></span><span class="line"><span class="cl"><span class="o">===========================================</span>
</span></span><span class="line"><span class="cl">pass <span class="m">1</span> of <span class="nv">1</span>
</span></span><span class="line"><span class="cl"><span class="o">===========================================</span>
</span></span><span class="line"><span class="cl">Total <span class="nb">time</span> was 0.3 seconds
</span></span><span class="line"><span class="cl">Elapsed <span class="nb">time</span> was 0.3 <span class="nv">seconds</span>
</span></span><span class="line"><span class="cl"><span class="o">===========================================</span>
</span></span><span class="line"><span class="cl">All passed!
</span></span></code></pre></td></tr></table>
</div>
</div><p>Our testcase executed a single statement - printing &ldquo;Hello World!&rdquo; to the output file.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">/home/isaac/Projects/blog/004_vunit_verification_environment/vunit_tb.vhd:13:5:@0ms:<span class="o">(</span>report note<span class="o">)</span>: Hello world!
</span></span><span class="line"><span class="cl">simulation stopped @0ms with status <span class="m">0</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="using-axi-stream-verification-components">Using AXI-Stream Verification Components</h2>
<p>VUnit includes Verification Components with support for several standard interfaces, including AXI-Stream.</p>
<p>To get started, we include the <code>vu.add_verification_components()</code> statement in our simulation script to add support for the Verification Components.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">vunit</span> <span class="kn">import</span> <span class="n">VUnit</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Create VUnit instance by parsing command line arguments</span>
</span></span><span class="line"><span class="cl"><span class="n">vu</span> <span class="o">=</span> <span class="n">VUnit</span><span class="o">.</span><span class="n">from_argv</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Add VUnit&#39;s builtin HDL utilities</span>
</span></span><span class="line"><span class="cl"><span class="n">vu</span><span class="o">.</span><span class="n">add_vhdl_builtins</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Add VUnit Verification Components</span>
</span></span><span class="line"><span class="cl"><span class="n">vu</span><span class="o">.</span><span class="n">add_verification_components</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Create library &#39;lib&#39;</span>
</span></span><span class="line"><span class="cl"><span class="n">lib</span> <span class="o">=</span> <span class="n">vu</span><span class="o">.</span><span class="n">add_library</span><span class="p">(</span><span class="s2">&#34;lib&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Add all files ending in .vhd in current working directory to library</span>
</span></span><span class="line"><span class="cl"><span class="n">lib</span><span class="o">.</span><span class="n">add_source_files</span><span class="p">(</span><span class="s2">&#34;*.vhd&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Run vunit function</span>
</span></span><span class="line"><span class="cl"><span class="n">vu</span><span class="o">.</span><span class="n">main</span><span class="p">()</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>We can now expand our existing testbench by adding one AXI-Stream Master and one AXI-Stream Slave Verification Component. First we add all the signals and constants that we&rsquo;ll use to configure and connect the verification components.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="k">architecture</span> <span class="nc">tb</span> <span class="k">of</span> <span class="nc">tb_example</span> <span class="k">is</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">signal</span>    <span class="n">clk</span>             <span class="o">:</span> <span class="kt">std_logic</span> <span class="o">:=</span> <span class="sc">&#39;0&#39;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">constant</span>  <span class="n">CLK_PERIOD</span>      <span class="o">:</span> <span class="kt">time</span>      <span class="o">:=</span> <span class="mi">10</span> <span class="n">ns</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">constant</span>  <span class="n">AXIS_DATA_WIDTH</span> <span class="o">:</span> <span class="kt">integer</span>   <span class="o">:=</span> <span class="mi">24</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">-- AXI-Stream Master Interface Deifnition and Configuration</span>
</span></span><span class="line"><span class="cl">  <span class="k">constant</span> <span class="n">m_axis</span> <span class="o">:</span> <span class="n">axi_stream_master_t</span> <span class="o">:=</span> <span class="n">new_axi_stream_master</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">data_length</span> <span class="o">=&gt;</span> <span class="n">AXIS_DATA_WIDTH</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">stall_config</span> <span class="o">=&gt;</span> <span class="n">new_stall_config</span><span class="p">(</span><span class="mi">0</span><span class="p">.</span><span class="mi">05</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">-- AXI-Stream Slave Interface Deifnition and Configuration</span>
</span></span><span class="line"><span class="cl">  <span class="k">constant</span> <span class="n">s_axis</span>  <span class="o">:</span> <span class="n">axi_stream_slave_t</span>  <span class="o">:=</span> <span class="n">new_axi_stream_slave</span><span class="p">(</span>
</span></span><span class="line"><span class="cl">    <span class="n">data_length</span> <span class="o">=&gt;</span> <span class="n">AXIS_DATA_WIDTH</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">stall_config</span> <span class="o">=&gt;</span> <span class="n">new_stall_config</span><span class="p">(</span><span class="mi">0</span><span class="p">.</span><span class="mi">05</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">-- AXI-Stream Signals</span>
</span></span><span class="line"><span class="cl">  <span class="k">signal</span> <span class="n">axis_valid</span>  <span class="o">:</span> <span class="kt">std_logic</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">signal</span> <span class="n">axis_ready</span>  <span class="o">:</span> <span class="kt">std_logic</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">signal</span> <span class="n">axis_last</span>   <span class="o">:</span> <span class="kt">std_logic</span><span class="p">;</span> 
</span></span><span class="line"><span class="cl">  <span class="k">signal</span> <span class="n">axis_data</span>   <span class="o">:</span> <span class="kt">std_logic_vector</span><span class="p">(</span><span class="n">AXIS_DATA_WIDTH</span><span class="o">-</span><span class="mi">1</span> <span class="k">downto</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">begin</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Then we can add the Verification Components themselves.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="k">begin</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">vunit_axism</span> <span class="o">:</span> <span class="k">entity</span> <span class="nc">vunit_lib</span><span class="p">.</span><span class="n">axi_stream_master</span>
</span></span><span class="line"><span class="cl">    <span class="k">generic</span> <span class="k">map</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="n">master</span> <span class="o">=&gt;</span> <span class="n">m_axis</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">port</span> <span class="k">map</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="n">aclk</span>   <span class="o">=&gt;</span> <span class="n">clk</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="n">tvalid</span> <span class="o">=&gt;</span> <span class="n">axis_valid</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="n">tready</span> <span class="o">=&gt;</span> <span class="n">axis_ready</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="n">tdata</span>  <span class="o">=&gt;</span> <span class="n">axis_data</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="n">tlast</span>  <span class="o">=&gt;</span> <span class="n">axis_last</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">vunit_axiss</span> <span class="o">:</span> <span class="k">entity</span> <span class="nc">vunit_lib</span><span class="p">.</span><span class="n">axi_stream_slave</span>
</span></span><span class="line"><span class="cl">    <span class="k">generic</span> <span class="k">map</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="n">slave</span> <span class="o">=&gt;</span> <span class="n">s_axis</span>
</span></span><span class="line"><span class="cl">    <span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="k">port</span> <span class="k">map</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl">      <span class="n">aclk</span>   <span class="o">=&gt;</span> <span class="n">clk</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="n">tvalid</span> <span class="o">=&gt;</span> <span class="n">axis_valid</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="n">tready</span> <span class="o">=&gt;</span> <span class="n">axis_ready</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="n">tdata</span>  <span class="o">=&gt;</span> <span class="n">axis_data</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="n">tlast</span>  <span class="o">=&gt;</span> <span class="n">axis_last</span>
</span></span><span class="line"><span class="cl">    <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="n">main</span> <span class="o">:</span> <span class="k">process</span>
</span></span><span class="line"><span class="cl">  <span class="k">begin</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_runner_setup</span><span class="p">(</span><span class="n">runner</span><span class="p">,</span> <span class="n">runner_cfg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">report</span> <span class="s">&#34;Hello world!&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_runner_cleanup</span><span class="p">(</span><span class="n">runner</span><span class="p">);</span> <span class="c1">-- Simulation ends here</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span> <span class="k">process</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">architecture</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>We are now ready to generate - and capture - data over the AXI-Stream bus. To do this we must expand our &lsquo;main&rsquo; process to start the data transmission and reception in the AXI-Stream Verification Components.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-vhdl" data-lang="vhdl"><span class="line"><span class="cl"><span class="n">main</span> <span class="o">:</span> <span class="k">process</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">axis_tdata_v</span> <span class="o">:</span> <span class="kt">std_logic_vector</span><span class="p">(</span><span class="n">AXIS_DATA_WIDTH</span><span class="o">-</span><span class="mi">1</span> <span class="k">downto</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">variable</span> <span class="n">axis_tlast_v</span> <span class="o">:</span> <span class="kt">std_logic</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">begin</span>
</span></span><span class="line"><span class="cl">  <span class="n">test_runner_setup</span><span class="p">(</span><span class="n">runner</span><span class="p">,</span> <span class="n">runner_cfg</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="n">report</span> <span class="s">&#34;Hello world!&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">for</span> <span class="n">i</span> <span class="k">in</span> <span class="mi">0</span> <span class="k">to</span> <span class="mi">99</span> <span class="k">loop</span>
</span></span><span class="line"><span class="cl">    <span class="n">push_axi_stream</span><span class="p">(</span><span class="n">net</span><span class="p">,</span> <span class="n">m_axis</span><span class="p">,</span> <span class="kt">std_logic_vector</span><span class="p">(</span><span class="n">to_unsigned</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">AXIS_DATA_WIDTH</span><span class="p">))</span> <span class="p">,</span> <span class="n">tlast</span> <span class="o">=&gt;</span> <span class="n">axis_tlast</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">pop_axi_stream</span><span class="p">(</span><span class="n">net</span><span class="p">,</span> <span class="n">s_axis</span><span class="p">,</span> <span class="n">tdata</span> <span class="o">=&gt;</span> <span class="n">axis_tdata_v</span><span class="p">,</span> <span class="n">tlast</span> <span class="o">=&gt;</span> <span class="n">axis_tlast_v</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">  <span class="k">end</span> <span class="k">loop</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="k">wait</span> <span class="k">for</span> <span class="mi">1</span> <span class="n">us</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="n">test_runner_cleanup</span><span class="p">(</span><span class="n">runner</span><span class="p">);</span> <span class="c1">-- Simulation ends here</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span> <span class="k">process</span> <span class="nc">main</span><span class="p">;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>At this point we can simulate our expanded testbench. Because I&rsquo;m using GHDL as my simulator, I&rsquo;ll include an argument that creates a VCD waveform in the simulation script.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">python3 run.py --gtkwave-fmt vcd
</span></span></code></pre></td></tr></table>
</div>
</div><p>Finally, we can see the results of our simulation. For this example I&rsquo;m using Surfer as a waveform viewer. Surfer is a VSCode extension, which allows us to visualize our waveforms without leaving the code editor.</p>
<p><img loading="lazy" src="/posts/005_setting_up_a_vhdl_verification_environment_with_vunit/images/simulation_with_vunit_axi_stream_components.png" type="" alt="Simulation with VUnit AXI-Stream Components"  /></p>
<p>Zooming in at the start of the simulation, we can see that the <code>tvalid</code> and <code>tready</code> signals of the AXI-Stream bus are toggled by the Verification Components. For this they use the parameters we set when we declared the <code>m_axis</code> and <code>s_axis</code> constants for the AXI-Stream Master and Slave interfaces, respectively.</p>
<p><img loading="lazy" src="/posts/005_setting_up_a_vhdl_verification_environment_with_vunit/images/start_of_simulation_with_vunit_axi_stream_components.png" type="" alt="Start of Simulation with VUnit AXI-Stream Components"  /></p>
<h2 id="summary">Summary</h2>
<p>In this post we created a minimal simulation environment with VUnit that included driving a monitoring AXI-Stream interfaces.</p>
<p>We started with a minimal VHDL testbench and a Python simulation script, which we used to create a bare-bones &lsquo;Hello World!&rsquo; simulation. We then expanded the simulation script to include the VUnit verification components in our environment and added the logic required for instantiating, connecting, and using the Verification Components in our testbench. Finally, we ran our simulation and confirmed that our verification environment worked by inspecting the generated waveform.</p>
<p>Cheers,</p>
<p>Isaac</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
