<?xml version="1.0" encoding="ISO-8859-1"?>
<feed version="0.3" xmlns="http://purl.org/atom/ns#" xml:lang="en-US">
	<title>Tips for HVL and HDL users with special emphasis on Specman-e, SystemVerilog and Questa</title>
	<link rel="alternate" type="text/html" href="http://www.specman-verification.com/index.php" />
	<modified>2010-03-10T06:10:10Z</modified>
	<author>
		<name>Avidan Efody</name>
		<email>avidan_e@yahoo.com</email>
	</author>
	<copyright>Copyright 2010, Avidan Efody</copyright>
	<generator url="http://www.sourceforge.net/projects/sphpblog" version="0.4.6.1">SPHPBLOG</generator>
	<entry>
		<title>Specman profiler for beginners</title>
		<link rel="alternate" type="text/html" href="http://www.specman-verification.com/index.php?entry=entry091112-093154" />
		<content type="text/html" mode="escaped"><![CDATA[We had a small discussion: Pini, my great office-mate claimed that his way of writing e code was more efficient then mine, I had a feeling mine was as good as his, but wouldn&#039;t have been ready to place a bet for anything worth more then 5$ to back this up. We had an hour or two on our hands, and we thought that instead of fighting, we could settle our differences in a civilized manner by way an experiment which would also help us freshen up our knowledge on running Specman profiler.<br /><br />To make our experiment reliable we carried it out with both simulator and Specman in batch mode. The time consumed by GUI related activities such as refreshing screen images simply adds noise to the profiler results, which are not the easiest thing to figure out anyway. In our case, we had a super-simple code that did not include any printouts to the screen or to files, but if you&#039;re running the profiler with a normal testbench, you might want to disable as much of these as you can. If you&#039;ve done things the eRM way, and have used only message/messagef and no out/outf/print, this should be a peace of cake, at least on the testbench side.<br /><br />The following <a href="http://www.specman-verification.com/user_files/profiler.zip" target="_blank" >zip file</a> holds mine and Pini&#039;s code (every_clock.e, every_10_clocks.e correspondingly), a small DUT, and the simple magic commands required to compile everything and run the profiler in a Cadence IES environment. It also holds another piece of code (optimized.e) and its corresponding profiler report, which, as you can easily tell from its name, is the optimized version that I created based on the profiler reports for the other two versions.  For those of you who detest zip, the competing code snippets and the optimized one can also be found below, and the profiler reports can be viewed <a href="http://www.specman-verification.com/tutorial/every_10_clocks.html" target="_blank" >here(Pini)</a>, <a href="http://www.specman-verification.com/tutorial/every_clock.html" target="_blank" >here(Avidan)</a> and <a href="http://www.specman-verification.com/tutorial/optimized.html" target="_blank" >here(optimized)</a>, but try not to look at the optimized version until you&#039;ve reached the end...<br /><br />A quick look at the results for my and Pini&#039;s code, will give you the impression that our contest ended up more or less in a tie - the difference in the percentage of time consumed by Specman between the two version is only 1.3%, 84.8% in my version compared to 86.1% in Pini&#039;s. However, the quick look is misleading in this case, and these 2% are more significant then they would seem. To understand why, think about a case where version A consumes 99% of simulation time, and version B 98%. Assuming the simulator code used with both A and B is identical, the 1% with A reflects the same CPU usage as the 2% with B, which actually means that version B&#039;s e code is using 50% less CPU then version A&#039;s e code. Since your e code in this case is taking the vast majority of simulation time, it means that B will run almost twice as fast as A! Therefore, if you have two results you want to compare, you might want to use the following formula to calculate the actual performance improvement (this is in fact a very close approximation of the real difference, but we&#039;re not doing our A level in Mathematics here):<br /><br />&quot;Version B will take ((version A&#039;s simulator time)/(version B&#039;s simulator time))*100 of the time version A takes&quot;.<br /> <br />and in our case:<br /><br />Avidan&#039;s version will take 13.86/15.18*100=91% of the time Pini&#039;s Version takes.<br /><br />And this looks already more significant...<br /><br />I must admit that I&#039;m not an expert figuring out what goes on in the profiler report: Basically, I work my way through it fairly stupidly, looking for the most wasteful parts of my code and trying to recode them, but not always knowing to pinpoint the exact problem, if my recoding will improve it or make it worse, or if there was a problem at all to begin with, or what I see is just a normal behavior. Looking at the reports for my and Pini&#039;s code, I could see that his &quot;temporals&quot; section, takes almost as much time as my own &quot;temporals&quot; and &quot;user methods&quot; sections put together. This makes sense because what Pini chose to implement in a temporal expression (i.e. wait till the cnt signal is 10), I have implemented inside the TCM. Basically, our argument was over the question if it is better to make the TCM or the event more complex, and the results seem to indicate that both options are very much equivalent. However, in Pini&#039;s report there&#039;s an anigmatic item called &quot;scheduling&quot; that takes more then in my report, and probably makes the difference...What can it point to?<br /><br />I gave this question some thought and the best guess I could come up with was that the difference is probably due to the fact that Pini&#039;s code has two parallel processes (the temporal expression and the TCM), while my code has only one (the TCM). I assumed that &quot;scheduling&quot; probably referred to switching between the threads, and since Pini has 2, while I have only 1, his scheduling expenses are higher. To confirm this hypothesis, I replaced the TCM in Pini&#039;s code with an &quot;on&quot; construct, thereby removing one of the threads, which resulted in a version that did much better then both mine and Pini&#039;s. This was a bit too good, because I was expecting the new version to be more or less equivalent to mine, but I already told you I&#039;m not the biggest profiler expert, right?! If someone can explain the results better, please write me, and I&#039;ll put your explanation here, along with the appropriate credit.<br /><br />BTW, from the pure e perspective, this entry doesn&#039;t result in any clear coding guidelines. While &quot;on&quot; seems to be the winner, it has several annoying characteristics that brought it to the verge of extinction in modern day e. To name just two: it can&#039;t consume any time, and it can&#039;t trigger on an event defined elsewhere. Also, if my assumption is correct and the differences between the versions are just related to the number of threads used in each, then in any reasonable size testbench where you have 10 threads or more, these coding styles should be equivalent.<br /><br />Thanks to the people who helped me with this entry or corrected mistakes:<br /><a href="http://www.linkedin.com/profile?viewProfile=&amp;key=8281213&amp;authToken=K46g&amp;authType=NAME_SEARCH&amp;locale=en_US&amp;srchindex=1&amp;pvs=ps&amp;goback=%2Efps_Daniel+P%C3%B6rsch_*1_*1_*1_*1_*1_*1_*1_Y_*1_*1_*1_false_1_R_true_CC%2CN%2CI%2CG%2CPC%2CED%2CFG%2CL_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2" target="_blank" >Daniel Pörsch</a><br /><a href="http://www.linkedin.com/profile?viewProfile=&amp;key=42848712&amp;authToken=PbdF&amp;authType=NAME_SEARCH&amp;locale=en_US&amp;srchindex=1&amp;pvs=ps&amp;goback=%2Efps_ronen+ben+zino_*1_*1_*1_*1_*1_*1_*1_Y_*1_*1_*1_false_1_R_true_CC%2CN%2CG%2CI%2CPC%2CED%2CFG%2CL_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2_*2" target="_blank" >Ronen Ben-Zino</a><br /><br /><br />----- Avidan&#039;s version - TCM that runs every clock -----<br /><br />	    <pre>

<span class="comment"><&#039;</span>
<span class="keyword">unit</span> env_u <span class="specman-punctuation">{</span>
    <span class="variable-name">clk</span> <span class="specman-punctuation">:</span> <span class="keyword">in</span> event_port <span class="keyword">is instance</span><span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> <span class="function-name">bind</span><span class="specman-punctuation">(</span>clk<span class="specman-punctuation">,</span> <span class="keyword">external</span><span class="specman-punctuation">);</span>
    
    <span class="variable-name">cnt</span> <span class="specman-punctuation">:</span> <span class="keyword">in</span> simple_port <span class="keyword">of</span> <span class="type">uint</span> <span class="specman-punctuation">(</span><span class="variable-name"><span class="type">bits</span></span><span class="specman-punctuation">:</span><span class="constant">16</span><span class="specman-punctuation">)</span> <span class="keyword">is instance</span><span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> <span class="function-name">bind</span><span class="specman-punctuation">(</span>cnt<span class="specman-punctuation">,</span> <span class="keyword">external</span><span class="specman-punctuation">);</span>
        
    <span class="specman-punctuation">!</span><span class="variable-name">cnt_10s</span> <span class="specman-punctuation">:</span> <span class="type">uint</span><span class="specman-punctuation">;</span>


    <span class="function-name">every_clk_tcm</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">@</span> clk<span class="specman-punctuation">$</span> <span class="keyword">is</span> <span class="specman-punctuation">{</span>
        <span class="keyword">while</span><span class="specman-punctuation">(</span><span class="constant">TRUE</span><span class="specman-punctuation">)</span> <span class="specman-punctuation">{</span>

            <span class="keyword">if</span><span class="specman-punctuation">(</span>cnt<span class="specman-punctuation">$</span> <span class="specman-punctuation">==</span> <span class="constant">10</span><span class="specman-punctuation">)</span> <span class="keyword">then</span> <span class="specman-punctuation">{</span>
                cnt_10s<span class="specman-punctuation">+=</span><span class="constant">1</span><span class="specman-punctuation">;</span>

            <span class="specman-punctuation">};</span>
            <span class="keyword">wait</span> <span class="keyword">cycle</span><span class="specman-punctuation">;</span>
        <span class="specman-punctuation">};</span>
    <span class="specman-punctuation">};</span>
    
    <span class="function-name">run</span><span class="specman-punctuation">()</span> <span class="keyword">is also</span> <span class="specman-punctuation">{</span>

        <span class="keyword">start</span> every_clk_tcm<span class="specman-punctuation">();</span>
    <span class="specman-punctuation">};</span>
<span class="specman-punctuation">};</span>

<span class="keyword">extend</span> sys <span class="specman-punctuation">{</span>

    <span class="variable-name">env</span> <span class="specman-punctuation">:</span> env_u <span class="keyword">is instance</span><span class="specman-punctuation">;</span>
    <span class="keyword">keep</span> env<span class="specman-punctuation">.</span><span class="function-name">hdl_path</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">==</span> "<span class="string">~/top</span>"<span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> env<span class="specman-punctuation">.</span>clk<span class="specman-punctuation">.</span><span class="function-name">hdl_path</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">==</span> "<span class="string">clk</span>"<span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> env<span class="specman-punctuation">.</span>cnt<span class="specman-punctuation">.</span><span class="function-name">hdl_path</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">==</span> "<span class="string">cnt</span>"<span class="specman-punctuation">;</span>

    
    <span class="function-name">setup</span><span class="specman-punctuation">()</span> <span class="keyword">is also</span> <span class="specman-punctuation">{</span> 
        <span class="function-name">set_config</span><span class="specman-punctuation">(</span>run<span class="specman-punctuation">,</span> tick_max<span class="specman-punctuation">,</span> <span class="constant">MAX_INT</span><span class="specman-punctuation">,</span> exit_on<span class="specman-punctuation">,</span> error<span class="specman-punctuation">);</span> 
    <span class="specman-punctuation">};</span> 

<span class="specman-punctuation">};</span>
    
<span class="comment">&#039;>
</span></pre><br /><br /><br />----- Pini&#039;s version - TCM that runs every 10th clock -----<br /><br />    <pre>

<span class="comment"><&#039;</span>
<span class="keyword">unit</span> env_u <span class="specman-punctuation">{</span>    
    <span class="variable-name">clk</span> <span class="specman-punctuation">:</span> <span class="keyword">in</span> event_port <span class="keyword">is instance</span><span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> <span class="function-name">bind</span><span class="specman-punctuation">(</span>clk<span class="specman-punctuation">,</span> <span class="keyword">external</span><span class="specman-punctuation">);</span>
    
    <span class="variable-name">cnt</span> <span class="specman-punctuation">:</span> <span class="keyword">in</span> simple_port <span class="keyword">of</span> <span class="type">uint</span> <span class="specman-punctuation">(</span><span class="variable-name"><span class="type">bits</span></span><span class="specman-punctuation">:</span><span class="constant">16</span><span class="specman-punctuation">)</span> <span class="keyword">is instance</span><span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> <span class="function-name">bind</span><span class="specman-punctuation">(</span>cnt<span class="specman-punctuation">,</span> <span class="keyword">external</span><span class="specman-punctuation">);</span>
        
    <span class="specman-punctuation">!</span><span class="variable-name">cnt_10s</span> <span class="specman-punctuation">:</span> <span class="type">uint</span><span class="specman-punctuation">;</span>

    
    <span class="keyword">event</span> <span class="variable-name">every_10_clks_e</span> <span class="keyword">is</span> <span class="function-name">true</span><span class="specman-punctuation">(</span>cnt<span class="specman-punctuation">$</span> <span class="specman-punctuation">==</span> <span class="constant">10</span><span class="specman-punctuation">)</span> <span class="specman-punctuation">@</span> clk<span class="specman-punctuation">$;</span>

    <span class="function-name">every_10_clks_tcm</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">@</span> every_10_clks_e <span class="keyword">is</span> <span class="specman-punctuation">{</span>
        <span class="keyword">while</span><span class="specman-punctuation">(</span><span class="constant">TRUE</span><span class="specman-punctuation">)</span> <span class="specman-punctuation">{</span>

            cnt_10s<span class="specman-punctuation">+=</span><span class="constant">1</span><span class="specman-punctuation">;</span>
            <span class="keyword">wait</span> <span class="keyword">cycle</span><span class="specman-punctuation">;</span>
        <span class="specman-punctuation">};</span>
    <span class="specman-punctuation">};</span>

        
    <span class="function-name">run</span><span class="specman-punctuation">()</span> <span class="keyword">is also</span> <span class="specman-punctuation">{</span>
        <span class="keyword">start</span> every_10_clks_tcm<span class="specman-punctuation">();</span>
    <span class="specman-punctuation">};</span>

<span class="specman-punctuation">};</span>

<span class="keyword">extend</span> sys <span class="specman-punctuation">{</span>
    <span class="variable-name">env</span> <span class="specman-punctuation">:</span> env_u <span class="keyword">is instance</span><span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> env<span class="specman-punctuation">.</span><span class="function-name">hdl_path</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">==</span> "<span class="string">~/top</span>"<span class="specman-punctuation">;</span>
    <span class="keyword">keep</span> env<span class="specman-punctuation">.</span>clk<span class="specman-punctuation">.</span><span class="function-name">hdl_path</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">==</span> "<span class="string">clk</span>"<span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> env<span class="specman-punctuation">.</span>cnt<span class="specman-punctuation">.</span><span class="function-name">hdl_path</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">==</span> "<span class="string">cnt</span>"<span class="specman-punctuation">;</span>

    
    <span class="function-name">setup</span><span class="specman-punctuation">()</span> <span class="keyword">is also</span> <span class="specman-punctuation">{</span> 
        <span class="function-name">set_config</span><span class="specman-punctuation">(</span>run<span class="specman-punctuation">,</span> tick_max<span class="specman-punctuation">,</span> <span class="constant">MAX_INT</span><span class="specman-punctuation">,</span> exit_on<span class="specman-punctuation">,</span> error<span class="specman-punctuation">);</span> 
    <span class="specman-punctuation">};</span> 

<span class="specman-punctuation">};</span>
    
<span class="comment">&#039;>


</span></pre><br /><br />----- Optimized version - using &quot;on&quot; -----<br />
    <pre>

<span class="comment"><&#039;</span>
<span class="keyword">unit</span> env_u <span class="specman-punctuation">{</span>    
    <span class="variable-name">clk</span> <span class="specman-punctuation">:</span> <span class="keyword">in</span> event_port <span class="keyword">is instance</span><span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> <span class="function-name">bind</span><span class="specman-punctuation">(</span>clk<span class="specman-punctuation">,</span> <span class="keyword">external</span><span class="specman-punctuation">);</span>
    
    <span class="variable-name">cnt</span> <span class="specman-punctuation">:</span> <span class="keyword">in</span> simple_port <span class="keyword">of</span> <span class="type">uint</span> <span class="specman-punctuation">(</span><span class="variable-name"><span class="type">bits</span></span><span class="specman-punctuation">:</span><span class="constant">16</span><span class="specman-punctuation">)</span> <span class="keyword">is instance</span><span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> <span class="function-name">bind</span><span class="specman-punctuation">(</span>cnt<span class="specman-punctuation">,</span> <span class="keyword">external</span><span class="specman-punctuation">);</span>
        
    <span class="specman-punctuation">!</span><span class="variable-name">cnt_10s</span> <span class="specman-punctuation">:</span> <span class="type">uint</span><span class="specman-punctuation">;</span>

    
    <span class="keyword">event</span> <span class="variable-name">every_10_clks_e</span> <span class="keyword">is</span> <span class="function-name">true</span><span class="specman-punctuation">(</span>cnt<span class="specman-punctuation">$</span> <span class="specman-punctuation">==</span> <span class="constant">10</span><span class="specman-punctuation">)</span> <span class="specman-punctuation">@</span> clk<span class="specman-punctuation">$;</span>

    
    <span class="function-name"><span class="keyword">on</span></span><span class="function-name"> every_10_clks_e</span> <span class="specman-punctuation">{</span>
        cnt_10s<span class="specman-punctuation">+=</span><span class="constant">1</span><span class="specman-punctuation">;</span>
    <span class="specman-punctuation">};</span>
<span class="specman-punctuation">};</span>

<span class="keyword">extend</span> sys <span class="specman-punctuation">{</span>
    <span class="variable-name">env</span> <span class="specman-punctuation">:</span> env_u <span class="keyword">is instance</span><span class="specman-punctuation">;</span>
    <span class="keyword">keep</span> env<span class="specman-punctuation">.</span><span class="function-name">hdl_path</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">==</span> "<span class="string">~/top</span>"<span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> env<span class="specman-punctuation">.</span>clk<span class="specman-punctuation">.</span><span class="function-name">hdl_path</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">==</span> "<span class="string">clk</span>"<span class="specman-punctuation">;</span>

    <span class="keyword">keep</span> env<span class="specman-punctuation">.</span>cnt<span class="specman-punctuation">.</span><span class="function-name">hdl_path</span><span class="specman-punctuation">()</span> <span class="specman-punctuation">==</span> "<span class="string">cnt</span>"<span class="specman-punctuation">;</span>

    
    <span class="function-name">setup</span><span class="specman-punctuation">()</span> <span class="keyword">is also</span> <span class="specman-punctuation">{</span> 
        <span class="function-name">set_config</span><span class="specman-punctuation">(</span>run<span class="specman-punctuation">,</span> tick_max<span class="specman-punctuation">,</span> <span class="constant">MAX_INT</span><span class="specman-punctuation">,</span> exit_on<span class="specman-punctuation">,</span> error<span class="specman-punctuation">);</span> 
    <span class="specman-punctuation">};</span> 

<span class="specman-punctuation">};</span>
    
<span class="comment">&#039;>


</span></pre><br />]]></content>
		<id>http://www.specman-verification.com/index.php?entry=entry091112-093154</id>
		<issued>2009-11-12T00:00:00Z</issued>
		<modified>2009-11-12T00:00:00Z</modified>
	</entry>
	<entry>
		<title>Greping all loaded e files for a regex</title>
		<link rel="alternate" type="text/html" href="http://www.specman-verification.com/index.php?entry=entry091002-101327" />
		<content type="text/html" mode="escaped"><![CDATA[Warning: This entry was extensively modified since it was first published about two weeks ago. Many good people, more than I thought were reading this blog, have pointed out mistakes, inaccuracies, and outright lies in the ~20 lines I wrote. After I got one or two lawsuit threats I finally decided to rewrite it ;-)<br /> <br />When originally posted, this entry started with the sentence &quot;For some reason that escapes me, Specman&#039;s &#039;search&#039; command will only look for a regular string in the e files in your testbench, but not for a regular expression&quot;. While this sentence is true (i.e. when you type &quot;search&quot; at Specman&#039;s command line you can only give a string as a parameter), it is absolutely not true that you can&#039;t do a regex search from within Specman itself: Pushing Specman&#039;s GUI search button will take you to a search screen where you can look for regular expressions or for regular strings inside type definitions, constraints and what not. The search is preformed, needless to say, in all the currently loaded e modules.<br /> <br />If, like me, you&#039;re working for a company that doesn&#039;t have an all-you-can-eat deal with Cadence, then probably you don&#039;t want to take a license every time you want to search your e files. To search the e modules in your testbench for regular expressions and strings offline, you can use the perl script below to extract a list of e files from your specman.elog file, then use this file list with grep. This will require you to run Specman only once, so that you have a specman.elog file where all the files in your testbench are imported: the stubs creation stage will do for this purpose. Once the file list is created,  here are some useful greps you can use it with:<br /> <br />grep &quot;field_name.*\:&quot; `cat modules.txt` #will take you to the field definition (and maybe to one or two other garbage places)<br />grep &quot;\:.*field_type&quot; `cat modules.txt` #will take you to all the places where a field of a certain type is defined<br />grep &quot;port_name.*hdl_path&quot; `cat modules.txt` #will take you to the place where a port is tied to its hdl path.<br />grep &quot;struct[ ]+[a-zA-Z0-9_]+&quot; `cat modules.txt` #will look for all struct definitions<br /><br />But why write your greps alone if you can get David Robinson to borrow you his? Verilab&#039;s great <a href="http://www.verilab.com/resources/e-toolkit/" target="_blank" >e toolkit</a>, written by David, will look for just about anything you might want in the list of files you feed it with, and print the results nicely formatted to your screen. This will save you the headache of coming up with the correct regular expression for whatever you&#039;re looking for. The toolkit will also do some wonderfully useful things such as collecting all the class or enum extensions from your files, or printing the &quot;like&quot; inheritance hierarchy. In short, it will do everything you can do from Specman and more.<br /><br />Many thanks to Corey Goss from Cadence for his feedback, David Robinson from Verilab for pointing me to the toolkit, <a href="http://bknpk.no-ip.biz/" target="_blank" >Pini Krengel</a> who provided the original version of the script below and <a href="http://www.verifigen.com" target="_blank" >Ran Karen</a> who knows everything about Specman, for their help with this post. God, I hope I made everyone happy and won&#039;t have to rewrite it again...<br /> <br />
    <pre>
<span class="comment">#!/usr/bin/perl
</span>
<span class="type">open</span>(MODULE_LIST, "<span class="string">>modules.txt</span>") &#124;&#124; <span class="keyword">die</span> $!;

{
  <span class="keyword">local</span> $/=<span class="cperl-nonoverridable">undef</span>;
  <span class="type">open</span> LOG, "<span class="string">specman1.elog</span>" <span class="type">or</span> <span class="keyword">die</span> "<span class="string">Couldn&#039;t open file: $!</span>";
  <span class="type">binmode</span> LOG;
  $log = <LOG>;

  <span class="comment"># turn cyclic imports into normal import form
</span>  $log =~ <span class="cperl-nonoverridable">s</span><span class="constant">/</span><span class="string">\n</span><span class="constant">/</span> <span class="constant">/</span><span class="cperl-nonoverridable">g</span>;
  $log =~ <span class="cperl-nonoverridable">s</span><span class="constant">/</span><span class="string">Loading \(([^\)]*)\)</span><span class="constant">/</span>L<span class="string">oading $1</span><span class="constant">/</span><span class="cperl-nonoverridable">g</span>;
  $log =~ <span class="cperl-nonoverridable">s</span><span class="constant">/</span><span class="string"> \+ ([^ ]*)</span><span class="constant">/</span>L<span class="string">oading $1</span><span class="constant">/</span><span class="cperl-nonoverridable">g</span>;
  $log =~ <span class="cperl-nonoverridable">s</span><span class="constant">/</span><span class="string">Loading</span><span class="constant">/</span>\<span class="string">nLoading</span><span class="constant">/</span><span class="cperl-nonoverridable">g</span>;

  <span class="comment"># match normal imports
</span>  <span class="keyword">my</span> <span class="variable-name">$normal_import_match_string</span> = &#039;<span class="string">^Loading[ &#124;\n]([^ ]+\\.e)</span>&#039;;
  <span class="keyword">my</span> <span class="cperl-array">@evc_files</span>;
  <span class="keyword">if</span>(<span class="cperl-array">@evc_files</span> = $log =~ <span class="constant">/</span><span class="string">$normal_import_match_string</span><span class="constant">/</span><span class="cperl-nonoverridable">smg</span>) {
    <span class="keyword">foreach</span> <span class="variable-name">$evc_file</span> (<span class="cperl-array">@evc_files</span>) {
      <span class="cperl-nonoverridable">print</span> MODULE_LIST "<span class="string">$evc_file</span>" . "<span class="string">\n</span>";
    }
  }
}

<span class="type">close</span>(LOG);
<span class="type">close</span>(MODULE_LIST);</pre> <br /><br />]]></content>
		<id>http://www.specman-verification.com/index.php?entry=entry091002-101327</id>
		<issued>2009-10-02T00:00:00Z</issued>
		<modified>2009-10-02T00:00:00Z</modified>
	</entry>
	<entry>
		<title>Parsing Verilog using Perl (out of boredom)</title>
		<link rel="alternate" type="text/html" href="http://www.specman-verification.com/index.php?entry=entry090926-113114" />
		<content type="text/html" mode="escaped"><![CDATA[I&#039;ve always suspected that boredom, not money, power, sex or anything else, is what makes the world go around and after 3 weeks of unemployment, now finally behind me, I am at last able to confirm this suspicion. In search of something meaningful to do with my time between the beach, the Israeli version of Survivor, and some occasional meetings with potential employers, I decided to pursue an idea I had some time ago, and try to implement it myself. This took me into an unexpected direction of trying to figure out what&#039;s the best way of parsing Verilog files. It is hard to say at this stage where my idea will end up, but as a by-product I got some short useful insights and some <a href="http://www.specman-verification.com/user_files/verilog_grammer_for_perl_recdescent.zip" target="_blank" >real code</a> for anyone who intends to use Perl to look into the entrails of a Verilog file...<br /> <br />Starting with google, a simple search of &quot;perl verilog parser&quot; will immediately take you to a package called <a href="http://kobesearch.cpan.org/htdocs/Verilog-Perl/Verilog/Parser.html" target="_blank" >Verilog::Parser</a>, and another package called <a href="http://www.burbleland.com/v2html/v2html.html" target="_blank" >v2html</a>. Using these ready-made packages is an easy way to go, but you have to be aware that both of them will hide out a lot of information that you might want to have. Verilog::Parser, for example, breaks a Verilog file into atoms such as keywords, tokens, and numbers and gives you a callback for each. However, if you want to look for something bigger, say, a complete &quot;always&quot; block, you will find yourself re-parsing these atoms into blocks, which is not an easy task. Since my idea required a more high-level point of view, I decided to look for something else.<br /> <br />The next step, therefore, was to dump Verilog::Parser and v2html, and just look at parsing files with Perl. I was assuming that Perl has something generic to offer here, since almost every second programmer, uses Perl exactly for this kind of task. And in fact, Perl does have a very cool and well documented package called <a href="http://search.cpan.org/dist/Parse-RecDescent/lib/Parse/RecDescent.pm" target="_blank" >Parse::RecDescent</a>, which will parse any file according to any BNF grammar you provide, and enable you to preform custom things for any production it sees on its way. Verilog&#039;s BNF can be found <a href="http://www.verilog.com/VerilogBNF.html" target="_blank" >here</a>, and in a version that can be easily converted into what Perl&#039;s RecDescent would eat, right <a href="http://www.antlr.org/grammar/1227766760039/Verilog3.g" target="_blank" >here</a>. This last link leads to a page under <a href="http://www.antlr.org" target="_blank" >ANTLR&#039;s website</a>, and I&#039;ll go back to talk about ANTLR in a second.<br /> <br />After adapting the grammar to Perl and installing RecDescent, I was ready to go, and although I still have some difficulties implementing my idea, they&#039;re much smaller compared to the ones I had to deal with before...If you think this might be useful for you as well, you can download my Verilog grammer for Perl&#039;s RecDescent, and a small example, <a href="http://www.specman-verification.com/user_files/verilog_grammer_for_perl_recdescent.zip" target="_blank" >right here</a>.<br /> <br />As mentioned above I adapted the Perl RecDescent Verilog grammer from a grammer I found on ANTLR&#039;s site. This, of course, made me curious about what ANTLR was, and I soon found out it was a very cool free IDE for debugging grammar&#039;s and building compilers. For example, it can give you a graphical representation of any grammer you load into it, which can be very helpful when you&#039;re trying to figure out how a rule is broken down into individual productions all the way to the individual identifiers. It also has an active user community which had helped me patiently with some stupid questions I had. It is worth trying out...<br />]]></content>
		<id>http://www.specman-verification.com/index.php?entry=entry090926-113114</id>
		<issued>2009-09-26T00:00:00Z</issued>
		<modified>2009-09-26T00:00:00Z</modified>
	</entry>
	<entry>
		<title>No comments!</title>
		<link rel="alternate" type="text/html" href="http://www.specman-verification.com/index.php?entry=entry090817-160459" />
		<content type="text/html" mode="escaped"><![CDATA[Due to an annoying spam comments attack I&#039;ve decided to disable comments for a while. Please feel free to contact me directly with anything you would like to say at avidan_e at yahoo dot com.]]></content>
		<id>http://www.specman-verification.com/index.php?entry=entry090817-160459</id>
		<issued>2009-08-17T00:00:00Z</issued>
		<modified>2009-08-17T00:00:00Z</modified>
	</entry>
	<entry>
		<title>Do you believe in life after „when“ inheritance?</title>
		<link rel="alternate" type="text/html" href="http://www.specman-verification.com/index.php?entry=entry090801-151343" />
		<content type="text/html" mode="escaped"><![CDATA[e „when“ inheritance has something in common with the internet, the cell-phone, the TV, the reality show and all of these other great inventions: Everybody that was born into the world after they were invented has a very hard time imagining life without it. This disbelief persists even in the face of overwhelming proofs that life can and do exist without these inventions, such as the shocking personal testimonies of people who used to have books in their living room instead of a HD flat screen. Going back to the verification world, people who have used “when” are often convinced that it is impossible to really verify a DUT without this feature, no matter how many one spin tape-outs to the contrary you present them with.<br /><br />As one of the few people who have gone back in time from a world with “when” to a world without it, I think I have quite a comprehensive view with regards to the needs and requirements that “when” inheritance fulfils, the alternatives to “when” inheritance that SV/OVM has to offer, and the shortcomings of these alternatives. For the sake of my impatient readers, I’ll start with the bottom line: working with a language that doesn’t support “when”, will make your code uglier, and your debugging harder. However, it is definitely not the end of the world.<br /><br />“when” inheritance is very strong where transactions of different types take place on a single channel completely at random. This somewhat lame description can be resumed in one word: packets. Packet traffic is often made of several types of packets that can appear on a single channel completely at random. When you’re dealing with this kind of traffic, using “when” inheritance will make your code cleaner and easier to debug.<br /><br />In order to understand why, let us have a look at the two common solutions to generating such packet traffic in SV/OVM. In the first solution, often referred to as “the factory” solution, you would have a different class for each packet type. To generate the packet traffic, you have to go in two stages: First you randomly select the type of the packet you would like to generate next, then you generate an instance of the corresponding class. The code at the end of this entry (which can be used by OVM newbies also as a complete sequence example) demonstrates this solution.<br /><br />At the height of the e-SV wars, some years ago, this solution was strongly promoted as a “when” replacement. Personally, I don’t like it at all, mainly because of (A) the two step randomization proecess, which limits the use of bidirectional constraints and (B) the fact that the type of the packet, which in my eyes is a property of the packet, is actually moved out of the packet to the factory that generates it (in the case of my example, the factory is located in the sequence). If you would like to constrain all packets to be of a certain type, you have to add a constraint to the factory, not to the packet as you would do in the case of “when”. This means that some of the packet properties are constrained through the packet object itself, while others are constrained through the factory. Ugly. It was also said at the time that this solution might lead to a “class explosion” if you have more then one “when” determinant. From my experience, this doesn’t happen too often in real life projects, so this objection belongs more in the theoretical realm.<br /><br />If you would like to keep all the packet properties in one single packet class, like me, and still be able to generate different kinds of packets, at a distribution that can be easily constrained from the test by the user, the easiest solution is simply to have a packet class which is the aggregation of all the subtypes. This means that the packet class has all the fields of all the subtypes, but for a specific subtype, only some of these fields are actually valid/used. Obviously, the downside of this approach is that you have many garbage fields in your class, and this might make debugging more complex. When you open your packet in a watch window, you will have to search a bit for the fields that are actually relevant for you. However, this pain can be somewhat reduced by providing type-specific print functions. <br /><br />So, as said above, verification without “when” is possible, at the price of some ugliness of code, or some extra effort in debugging and if this takes several thousand dollars off your license fees, it is worth considering. What prevents many e people from seeing this simple truth is, I believe the fact that “when” inheritance is very often used at places where it is not really required. Take for example the vr_ad register package: is it really required to define each register as a “when” subtype, or could they also be defined as normal derived classes of a register base class? In my opinion, “when” has little added value here. It is very rare that you just choose to read or write a random register, and if you know which register you’re reading or writing upfront, why don’t you just instantiate the register class you want? In this case, instantiating a specific class and randomizing it means almost no additional pain. Where the type and the transaction are completely random, “when” is a big help. Where the type is not random, and the transaction is, you can do just as well with normal OO.  <br /><br />You can read some more on &quot;when&quot; inheritance in SV <a href="http://www.coolverification.com/2007/02/systemverilog_v.html" target="_blank" >here</a> <br /><br />Factory example:<br />
    <pre>
<span class="keyword">package</span> packet_pkg;

<span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
<span class="function-name">`include</span> "<span class="string">ovm_macros.svh</span>"

<span class="type">typedef</span> <span class="verilog-font-lock-p1800">enum</span> {A, B} packet_type_t;

<span class="verilog-font-lock-p1800">class</span> packet_base <span class="verilog-font-lock-p1800">extends</span> ovm_sequence_item;
   <span class="function-name">`ovm_object_utils</span>(packet_base);

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name = "");     
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name);     
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="verilog-font-lock-p1800">class</span> packet_A <span class="verilog-font-lock-p1800">extends</span> packet_base;
   
   <span class="verilog-font-lock-p1800">rand</span> <span class="verilog-font-lock-p1800">int</span> a;

   <span class="function-name">`ovm_object_utils_begin</span>(packet_A);
   <span class="function-name">`ovm_field_int</span>(a, OVM_ALL_ON)
   <span class="function-name">`ovm_object_utils_end</span>
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name = "");     
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name);     
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="verilog-font-lock-p1800">class</span> packet_B <span class="verilog-font-lock-p1800">extends</span> packet_base;

   <span class="verilog-font-lock-p1800">rand</span> <span class="verilog-font-lock-p1800">int</span> b;

   <span class="function-name">`ovm_object_utils_begin</span>(packet_B);
   <span class="function-name">`ovm_field_int</span>(b, OVM_ALL_ON)
   <span class="function-name">`ovm_object_utils_end</span>
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name = "");     
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name);     
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="verilog-font-lock-p1800">class</span> packet_sequencer <span class="verilog-font-lock-p1800">extends</span> ovm_sequencer<span class="type">#(packet_base, packet_base)</span>;
   <span class="function-name">`ovm_sequencer_utils</span>(packet_sequencer);
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);   
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name, parent);
      <span class="function-name">`ovm_update_sequence_lib</span>
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="verilog-font-lock-p1800">class</span> packet_driver <span class="verilog-font-lock-p1800">extends</span> ovm_driver<span class="type">#(packet_base, packet_base)</span>;
  <span class="function-name">`ovm_component_utils</span>(packet_driver)

  <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);     
    <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
  <span class="keyword">endfunction</span>

  <span class="keyword">task</span> <span class="function-name">run</span>();
     packet_base next_packet;

     <span class="comment">// This driver does nothing except for printing
</span>     <span class="keyword">forever</span> <span class="keyword">begin</span>
        seq_item_port.<span class="function-name">get_next_item</span>(next_packet);
        <span class="function-name">ovm_report_info</span>("<span class="string">NEXT_PACKET</span>",{"<span class="string">The next packet is:\n</span>", next_packet.<span class="function-name">sprint</span>()});
        seq_item_port.<span class="function-name">item_done</span>(next_packet);
     <span class="keyword">end</span>                
  <span class="keyword">endtask</span> 
<span class="verilog-font-lock-p1800">endclass</span>

<span class="verilog-font-lock-p1800">class</span> packet_env <span class="verilog-font-lock-p1800">extends</span> ovm_env;
   <span class="function-name">`ovm_component_utils</span>(packet_env);

   packet_sequencer sequencer;
   packet_driver driver;
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);   
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name, parent);
   <span class="keyword">endfunction</span> <span class="comment">// new
</span>
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">build</span>();
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">build</span>();
      sequencer = packet_sequencer::type_id::<span class="function-name">create</span>("<span class="string">packet_sequencer</span>", <span class="verilog-font-lock-p1800">this</span>);
      driver = packet_driver::type_id::<span class="function-name">create</span>("<span class="string">packet_driver</span>", <span class="verilog-font-lock-p1800">this</span>);
   <span class="keyword">endfunction</span>
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">connect</span>();
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">connect</span>();
      driver.seq_item_port.<span class="function-name">connect</span>(sequencer.seq_item_export);
      driver.rsp_port.<span class="function-name">connect</span>(sequencer.rsp_export);
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="verilog-font-lock-p1800">class</span> packet_seq_base <span class="verilog-font-lock-p1800">extends</span> ovm_sequence<span class="type">#(packet_base)</span>;

  <span class="function-name">`ovm_sequence_utils</span>(packet_seq_base, packet_sequencer)

   <span class="comment">// constrain this field to control packet_type
</span>   <span class="verilog-font-lock-p1800">rand</span> packet_type_t packet_type;
   
   packet_A p_A;
   packet_B p_B;
   
  <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name = "<span class="string">packet_seq_base</span>");
    <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name);
  <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>
<span class="keyword">endpackage</span>

<span class="keyword">package</span> test_pkg;
<span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
<span class="verilog-font-lock-p1800">import</span> packet_pkg::*;
<span class="function-name">`include</span> "<span class="string">ovm_macros.svh</span>"

<span class="verilog-font-lock-p1800">class</span> specific_seq <span class="verilog-font-lock-p1800">extends</span> packet_seq_base;
   <span class="function-name">`ovm_sequence_utils</span>(specific_seq, packet_sequencer)

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name = "<span class="string">specific_seq</span>");
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name);
   <span class="keyword">endfunction</span> <span class="comment">// new
</span>
   <span class="comment">// in a specific sequence:
</span>   <span class="comment">// 1. randomize to choose the next packet
</span>   <span class="comment">// 2. use the sequencer built-in factory
</span>   <span class="comment">// to create the item, randomize and send it
</span>   
   <span class="keyword">task</span> <span class="function-name">body</span>();  
     <span class="keyword">forever</span> <span class="keyword">begin</span>

        <span class="function-name">randomize</span>();
        
        <span class="keyword">case</span>(packet_type)
          A : <span class="function-name">`ovm_do_with</span>(p_A, {p_A.a == 5;}) 
          B : <span class="function-name">`ovm_do_with</span>(p_B, {p_B.b == 6;}) 
        <span class="keyword">endcase</span>

        <span class="type">#1</span>;
     <span class="keyword">end</span>
  <span class="keyword">endtask</span>
<span class="verilog-font-lock-p1800">endclass</span>  

<span class="verilog-font-lock-p1800">class</span> test <span class="verilog-font-lock-p1800">extends</span> ovm_test;
   <span class="function-name">`ovm_component_utils</span>(test);

   packet_env env;
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name = "<span class="string">test</span>", ovm_component parent=<span class="verilog-font-lock-p1800">null</span>);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
   <span class="keyword">endfunction</span>
   
  <span class="verilog-font-lock-p1800">virtual</span> <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">build</span>();
     <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">build</span>();

     env = packet_env::type_id::<span class="function-name">create</span>("<span class="string">env</span>", <span class="verilog-font-lock-p1800">this</span>);
     <span class="function-name">set_config_string</span>("<span class="string">env.sequencer</span>","<span class="string">default_sequence</span>", "<span class="string">specific_seq</span>");
  <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>                                 
<span class="keyword">endpackage</span>

<span class="keyword">module</span> top;
   <span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
   <span class="verilog-font-lock-p1800">import</span> packet_pkg::*;
   <span class="verilog-font-lock-p1800">import</span> test_pkg::*;

   <span class="keyword">initial</span> <span class="keyword">begin</span>      
      <span class="function-name">run_test</span>();
   <span class="keyword">end</span>
<span class="keyword">endmodule</span></pre>
]]></content>
		<id>http://www.specman-verification.com/index.php?entry=entry090801-151343</id>
		<issued>2009-08-01T00:00:00Z</issued>
		<modified>2009-08-01T00:00:00Z</modified>
	</entry>
	<entry>
		<title>OVM FIFO should be the last choice</title>
		<link rel="alternate" type="text/html" href="http://www.specman-verification.com/index.php?entry=entry090718-162417" />
		<content type="text/html" mode="escaped"><![CDATA[OVM users tend to use FIFOs just about everywhere. This is largely due to two reasons: (A) using a FIFO sometime simplifies the OVM code that is required to create the actual connection and (B) This solution is frequently promoted in the OVM reference material. FIFOs, however, come with a significant price, which is often forgotten during coding, but then fires back painfully during debugging: they break the data flow. When you insert a FIFO between two elements you are actually creating, without even noticing it, two independent processes – one which does the put(), and another which does the get(). This means, for example, that if during debugging you want to follow your transaction across a FIFO, then you have to place one breakpoint on the put(), then, when execution stops, go to the other end of the FIFO, and place another breakpoint after the get().  Or it means that you won’t be able to use the function call stack window, to trace back the origins of a specific transaction. To see this live, just run the following example, and follow the instructions in the comments. <br /><br />
    <pre>
<span class="keyword">package</span> vip_pkg;

<span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
<span class="function-name">`include</span> "<span class="string">ovm_macros.svh</span>"

<span class="verilog-font-lock-p1800">class</span> tr <span class="verilog-font-lock-p1800">extends</span> ovm_object;
   <span class="verilog-font-lock-p1800">int</span> serial_num;
   
   <span class="function-name">`ovm_object_utils_begin</span>(tr)
   <span class="function-name">`ovm_field_int</span>(serial_num, OVM_ALL_ON);
   <span class="function-name">`ovm_object_utils_end</span>

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name ="");
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name);
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="comment">// a : put side of the fifo
// b : get side of the fifo
// env : instantiates the fifo and connects
// it between a and b
</span>
<span class="comment">// The port at the beginning
</span><span class="verilog-font-lock-p1800">class</span> a <span class="verilog-font-lock-p1800">extends</span> ovm_component;
   <span class="function-name">`ovm_component_utils</span>(a)

   ovm_blocking_put_port<span class="type">#(tr)</span> put_port;

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
      put_port = <span class="verilog-font-lock-p1800">new</span>("<span class="string">put_port</span>", <span class="verilog-font-lock-p1800">this</span>);
   <span class="keyword">endfunction</span>

   <span class="keyword">task</span> <span class="function-name">run</span>();
      <span class="verilog-font-lock-p1800">int</span> serial_num;
      <span class="keyword">forever</span> <span class="keyword">begin</span>
         tr tr_i;
         
         <span class="keyword">$cast</span>(tr_i, <span class="function-name">create_object</span>("<span class="string">tr</span>", "<span class="string">tr_i</span>"));
         tr_i.serial_num = serial_num++; 
         <span class="comment">// To follow a transaction place a breakpoint
</span>         <span class="comment">// on the line below.
</span>         <span class="comment">// When it breaks, go to "b" and place a
</span>         <span class="comment">// breakpoint at the designated point.
</span>         <span class="comment">// This is the only way you can follow a
</span>         <span class="comment">// transaction across a FIFO.
</span>         put_port.<span class="function-name">put</span>(tr_i);
         <span class="type">#1</span>;
      <span class="keyword">end</span>
   <span class="keyword">endtask</span>
<span class="verilog-font-lock-p1800">endclass</span> 

<span class="comment">// The implementation at the end
</span><span class="verilog-font-lock-p1800">class</span> b <span class="verilog-font-lock-p1800">extends</span> ovm_component;
   <span class="function-name">`ovm_component_utils</span>(b)
   
   ovm_blocking_get_port<span class="type">#(tr)</span> get_port; 

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
      get_port = <span class="verilog-font-lock-p1800">new</span>("<span class="string">get_port</span>",<span class="verilog-font-lock-p1800">this</span>);
   <span class="keyword">endfunction</span>

   <span class="keyword">task</span> <span class="function-name">run</span>();
      tr tr_i;
      <span class="keyword">forever</span>
        <span class="keyword">begin</span>
           get_port.<span class="function-name">get</span>(tr_i);
           <span class="comment">// Place a breakpoint on the line below
</span>           <span class="comment">// to see the transaction come out of
</span>           <span class="comment">// the fifo.
</span>           <span class="comment">// Once it breaks, open the stack window.
</span>           <span class="comment">// You&#039;ll see that a is not anywhere there,
</span>           <span class="comment">// although that would be the most helpful
</span>           <span class="comment">// hint.
</span>           tr_i.<span class="function-name">print</span>();
        <span class="keyword">end</span>
   <span class="keyword">endtask</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="comment">// The env connects the port to the export
</span><span class="verilog-font-lock-p1800">class</span> env <span class="verilog-font-lock-p1800">extends</span> ovm_env;
   <span class="function-name">`ovm_component_utils</span>(env)

   a a_i;
   b b_i;
   tlm_fifo<span class="type">#(tr)</span> tlm_fifo_i;

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
   <span class="keyword">endfunction</span>

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">build</span>();
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">build</span>();
      <span class="keyword">$cast</span>(a_i, <span class="function-name">create_component</span>("<span class="string">a</span>", "<span class="string">a_i</span>"));
      <span class="keyword">$cast</span>(b_i, <span class="function-name">create_component</span>("<span class="string">b</span>", "<span class="string">b_i</span>"));
      tlm_fifo_i = <span class="verilog-font-lock-p1800">new</span>("<span class="string">tlm_fifo_i</span>",<span class="verilog-font-lock-p1800">this</span>);
   <span class="keyword">endfunction</span> <span class="comment">// void
</span>
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">connect</span>();
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">connect</span>();
      a_i.put_port.<span class="function-name">connect</span>(tlm_fifo_i.blocking_put_export);
      b_i.get_port.<span class="function-name">connect</span>(tlm_fifo_i.blocking_get_export);
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span> <span class="comment">// env
</span>
<span class="keyword">endpackage</span> <span class="comment">// vip
</span>
<span class="keyword">package</span> tests;

<span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
<span class="verilog-font-lock-p1800">import</span> vip_pkg::*;
<span class="function-name">`include</span> "<span class="string">ovm_macros.svh</span>"

<span class="verilog-font-lock-p1800">class</span> test <span class="verilog-font-lock-p1800">extends</span> ovm_test;
   <span class="function-name">`ovm_component_utils</span>(test);

   env env_i;
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name = "<span class="string">test</span>", ovm_component parent=<span class="verilog-font-lock-p1800">null</span>);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
   <span class="keyword">endfunction</span> <span class="comment">// new
</span>
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">build</span>();      
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">build</span>();
      <span class="keyword">$cast</span>(env_i, <span class="function-name">create_component</span>("<span class="string">env</span>", "<span class="string">env_i</span>"));
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>
<span class="keyword">endpackage</span> <span class="comment">// z
</span>
<span class="keyword">module</span> <span class="function-name">top</span>();
   <span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
   <span class="verilog-font-lock-p1800">import</span> vip_pkg::*;
   <span class="verilog-font-lock-p1800">import</span> tests::*;
   

   <span class="keyword">initial</span>
     <span class="function-name">run_test</span>();
<span class="keyword">endmodule</span></pre>
<br /><br />Note how much effort you need in order to trace a single transaction across one FIFO. If you have several instances of “a” and “b” this will become even worse. Also note, that between the break at the “put()” and the break at the “get()” you’ll have at least 1 delta delay difference. Much better to avoid such garbage delays…Where you really need a FIFO, this pain can’t be avoided. However, in the majority of cases you can simply use a normal port to imp connection as shown below:<br /><br />
    <pre>
<span class="keyword">package</span> vip_pkg;

<span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
<span class="function-name">`include</span> "<span class="string">ovm_macros.svh</span>"

<span class="verilog-font-lock-p1800">class</span> tr <span class="verilog-font-lock-p1800">extends</span> ovm_object;
   <span class="verilog-font-lock-p1800">int</span> serial_num;
   
   <span class="function-name">`ovm_object_utils_begin</span>(tr)
   <span class="function-name">`ovm_field_int</span>(serial_num, OVM_ALL_ON);
   <span class="function-name">`ovm_object_utils_end</span>

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name ="");
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name);
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span> <span class="comment">// tr
</span>
<span class="comment">// a : the port at the beginning
// b : the implementation at the end
</span>
<span class="comment">// The port at the beginning
</span><span class="verilog-font-lock-p1800">class</span> a <span class="verilog-font-lock-p1800">extends</span> ovm_component;
   <span class="function-name">`ovm_component_utils</span>(a)

   ovm_blocking_put_port<span class="type">#(tr)</span> put_port;

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
      put_port = <span class="verilog-font-lock-p1800">new</span>("<span class="string">put_port</span>", <span class="verilog-font-lock-p1800">this</span>);
   <span class="keyword">endfunction</span>

   <span class="keyword">task</span> <span class="function-name">run</span>();
      <span class="verilog-font-lock-p1800">int</span> serial_num;
      <span class="keyword">forever</span> <span class="keyword">begin</span>
         tr tr_i;
         
         <span class="keyword">$cast</span>(tr_i, <span class="function-name">create_object</span>("<span class="string">tr</span>", "<span class="string">tr_i</span>"));
         tr_i.serial_num = serial_num++;      
         put_port.<span class="function-name">put</span>(tr_i);
         <span class="type">#1</span>;
      <span class="keyword">end</span>
   <span class="keyword">endtask</span>
<span class="verilog-font-lock-p1800">endclass</span> 

<span class="comment">// The implementation at the end
</span><span class="verilog-font-lock-p1800">class</span> b <span class="verilog-font-lock-p1800">extends</span> ovm_component;
   <span class="function-name">`ovm_component_utils</span>(b)
   
   ovm_blocking_put_imp<span class="type">#(tr,b)</span> put_imp;

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
      put_imp = <span class="verilog-font-lock-p1800">new</span>("<span class="string">put_imp</span>",<span class="verilog-font-lock-p1800">this</span>);
   <span class="keyword">endfunction</span>

   <span class="keyword">task</span> <span class="function-name">put</span>(tr tr_i);
      tr_i.<span class="function-name">print</span>();    
   <span class="keyword">endtask</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="comment">// The env connects the port to the export
</span><span class="verilog-font-lock-p1800">class</span> env <span class="verilog-font-lock-p1800">extends</span> ovm_env;
   <span class="function-name">`ovm_component_utils</span>(env)

   a a_i;
   b b_i;

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
   <span class="keyword">endfunction</span>

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">build</span>();
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">build</span>();
      <span class="keyword">$cast</span>(a_i, <span class="function-name">create_component</span>("<span class="string">a</span>", "<span class="string">a_i</span>"));
      <span class="keyword">$cast</span>(b_i, <span class="function-name">create_component</span>("<span class="string">b</span>", "<span class="string">b_i</span>"));      
   <span class="keyword">endfunction</span> <span class="comment">// void
</span>
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">connect</span>();
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">connect</span>();
      a_i.put_port.<span class="function-name">connect</span>(b_i.put_imp);
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span> <span class="comment">// env
</span>
<span class="keyword">endpackage</span> <span class="comment">// vip
</span>
<span class="keyword">package</span> tests;

<span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
<span class="verilog-font-lock-p1800">import</span> vip_pkg::*;
<span class="function-name">`include</span> "<span class="string">ovm_macros.svh</span>"

<span class="verilog-font-lock-p1800">class</span> test <span class="verilog-font-lock-p1800">extends</span> ovm_test;
   <span class="function-name">`ovm_component_utils</span>(test);

   env env_i;
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name = "<span class="string">test</span>", ovm_component parent=<span class="verilog-font-lock-p1800">null</span>);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
   <span class="keyword">endfunction</span> <span class="comment">// new
</span>
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">build</span>();      
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">build</span>();
      <span class="keyword">$cast</span>(env_i, <span class="function-name">create_component</span>("<span class="string">env</span>", "<span class="string">env_i</span>"));
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>
<span class="keyword">endpackage</span> <span class="comment">// z
</span>
<span class="keyword">module</span> <span class="function-name">top</span>();
   <span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
   <span class="verilog-font-lock-p1800">import</span> vip_pkg::*;
   <span class="verilog-font-lock-p1800">import</span> tests::*;
   

   <span class="keyword">initial</span>
     <span class="function-name">run_test</span>();
<span class="keyword">endmodule</span></pre>
<br /><br />If you place a breakpoint on the print() at “b” now, and open the stack window, you’ll see “a”, which is probably what you want.<br /><br />The port to imp connection, however, can become complicated to use if “b” has to connect to two different data sources. This is common in scoreboards that have to look at DUT input data and DUT output data. The solution is simply to tweak the OVM imp class a little bit so that it sends its own name, along with the transaction, thereby enabling its parent component to know where the transaction came from. For example, if a scoreboard has “dut_input” and “dut_output” ports, then the transactions coming from the “dut_input” port will come along with a string whose value is, surprisingly, “dut_input”. Here are the tweaked versions of the two most popular imps, namely, blocking_put_imp and analysis_imp. You can easily rewrite in the same way any other OVM imp when required.<br /><br />
    <pre>
<span class="keyword">package</span> multiple_port_imps_pkg;
<span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
<span class="function-name">`include</span> "<span class="string">ovm_macros.svh</span>"

<span class="function-name">`define</span> <span class="function-name">TLM_BLOCKING_PUT_MASK</span> (1<<0)
<span class="function-name">`define</span> <span class="function-name">TLM_ANALYSIS_MASK</span> (1<<8)

<span class="verilog-font-lock-p1800">class</span> ovm_blocking_multiple_put_imp <span class="type">#(</span><span class="type"><span class="verilog-font-lock-p1800">type</span></span><span class="type"> T=</span><span class="type"><span class="verilog-font-lock-p1800">int</span></span><span class="type">, </span><span class="type"><span class="verilog-font-lock-p1800">type</span></span><span class="type"> IMP=</span><span class="type"><span class="verilog-font-lock-p1800">int</span></span><span class="type">)</span>
  <span class="verilog-font-lock-p1800">extends</span> ovm_port_base #(tlm_if_base <span class="type">#(T,T)</span>);
   <span class="verilog-font-lock-p1800">local</span> IMP m_imp; 
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span> (<span class="verilog-font-lock-p1800">string</span> name, IMP imp); 
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span> (name, imp, OVM_IMPLEMENTATION, 1, 1); 
      m_imp = imp; 
      m_if_mask = <span class="function-name">`TLM_BLOCKING_PUT_MASK</span>;
   <span class="keyword">endfunction</span> <span class="comment">// new
</span>   
   <span class="verilog-font-lock-p1800">virtual</span> <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">string</span></span> <span class="function-name">get_type_name</span>();
      <span class="keyword">return</span> "<span class="string">ovm_blocking_multiple_put_imp</span>";
   <span class="keyword">endfunction</span> <span class="comment">// string
</span>
   <span class="keyword">task</span> <span class="function-name">put</span> (T t);
      m_imp.<span class="function-name">put</span>(<span class="function-name">get_name</span>(),t);
   <span class="keyword">endtask</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="verilog-font-lock-p1800">class</span> ovm_multiple_analysis_imp <span class="type">#(</span><span class="type"><span class="verilog-font-lock-p1800">type</span></span><span class="type"> T=</span><span class="type"><span class="verilog-font-lock-p1800">int</span></span><span class="type">, </span><span class="type"><span class="verilog-font-lock-p1800">type</span></span><span class="type"> IMP=</span><span class="type"><span class="verilog-font-lock-p1800">int</span></span><span class="type">)</span>
  <span class="verilog-font-lock-p1800">extends</span> ovm_port_base #(tlm_if_base <span class="type">#(T,T)</span>);
   <span class="verilog-font-lock-p1800">local</span> IMP m_imp; 
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span> (<span class="verilog-font-lock-p1800">string</span> name, IMP imp); 
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span> (name, imp, OVM_IMPLEMENTATION, 1, 1); 
      m_imp = imp; 
      m_if_mask = <span class="function-name">`TLM_ANALYSIS_MASK</span>;
   <span class="keyword">endfunction</span> <span class="comment">// new
</span>   
   <span class="verilog-font-lock-p1800">virtual</span> <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">string</span></span> <span class="function-name">get_type_name</span>();
      <span class="keyword">return</span> "<span class="string">ovm_multiple_analysis_imp</span>";
   <span class="keyword">endfunction</span> <span class="comment">// string
</span>
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">write</span> (<span class="type">input</span> T t);
      m_imp.<span class="function-name">write</span>(<span class="function-name">get_name</span>(),t);
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="keyword">endpackage</span></pre>
<br /><br />And now you can use these imps to connect “a1” and “a2” to “b”, without any FIFOs.<br /><br />
<pre>
<span class="keyword">package</span> vip_pkg;

<span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
<span class="verilog-font-lock-p1800">import</span> multiple_port_imps_pkg::*;
<span class="function-name">`include</span> "<span class="string">ovm_macros.svh</span>"

<span class="verilog-font-lock-p1800">class</span> tr <span class="verilog-font-lock-p1800">extends</span> ovm_object;
   <span class="verilog-font-lock-p1800">int</span> serial_num;
   
   <span class="function-name">`ovm_object_utils_begin</span>(tr)
   <span class="function-name">`ovm_field_int</span>(serial_num, OVM_ALL_ON);
   <span class="function-name">`ovm_object_utils_end</span>

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name ="");
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name);
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span> <span class="comment">// tr
</span>
<span class="comment">// a1,a2 : the two ports at the beginning
// b : the implementation at the end
</span>
<span class="comment">// The port at the beginning (both are identical)
</span><span class="verilog-font-lock-p1800">class</span> a <span class="verilog-font-lock-p1800">extends</span> ovm_component;
   <span class="function-name">`ovm_component_utils</span>(a)

   ovm_blocking_put_port<span class="type">#(tr)</span> put_port;

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
      put_port = <span class="verilog-font-lock-p1800">new</span>("<span class="string">put_port</span>", <span class="verilog-font-lock-p1800">this</span>);
   <span class="keyword">endfunction</span>

   <span class="keyword">task</span> <span class="function-name">run</span>();
      <span class="verilog-font-lock-p1800">int</span> serial_num;
      <span class="keyword">forever</span> <span class="keyword">begin</span>
         tr tr_i;
         
         <span class="keyword">$cast</span>(tr_i, <span class="function-name">create_object</span>("<span class="string">tr</span>", "<span class="string">tr_i</span>"));
         tr_i.serial_num = serial_num++;      
         put_port.<span class="function-name">put</span>(tr_i);
         <span class="type">#1</span>;
      <span class="keyword">end</span>
   <span class="keyword">endtask</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="comment">// The implementation at the end
</span><span class="verilog-font-lock-p1800">class</span> b <span class="verilog-font-lock-p1800">extends</span> ovm_component;
   <span class="function-name">`ovm_component_utils</span>(b)
   
   ovm_blocking_multiple_put_imp<span class="type">#(tr,b)</span> put_imp_source1;
   ovm_blocking_multiple_put_imp<span class="type">#(tr,b)</span> put_imp_source2;

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
      put_imp_source1 = <span class="verilog-font-lock-p1800">new</span>("<span class="string">put_imp_source1</span>",<span class="verilog-font-lock-p1800">this</span>);
      put_imp_source2 = <span class="verilog-font-lock-p1800">new</span>("<span class="string">put_imp_source2</span>",<span class="verilog-font-lock-p1800">this</span>);
   <span class="keyword">endfunction</span>
   
   <span class="keyword">task</span> <span class="function-name">put</span>(<span class="verilog-font-lock-p1800">string</span> port_name, tr tr_i);
      <span class="keyword">case</span>(port_name)
        "<span class="string">put_imp_source1</span>" : <span class="function-name">put_source1</span>(tr_i);
        "<span class="string">put_imp_source2</span>" : <span class="function-name">put_source2</span>(tr_i);
      <span class="keyword">endcase</span>
   <span class="keyword">endtask</span> <span class="comment">// put
</span>
   <span class="keyword">task</span> <span class="function-name">put_source1</span>(tr tr_i);
      tr_i.<span class="function-name">print</span>();
   <span class="keyword">endtask</span> <span class="comment">// put_source1
</span>
   <span class="keyword">task</span> <span class="function-name">put_source2</span>(tr tr_i);
      tr_i.<span class="function-name">print</span>();
   <span class="keyword">endtask</span>
<span class="verilog-font-lock-p1800">endclass</span>

<span class="comment">// The env connects the port to the export
</span><span class="verilog-font-lock-p1800">class</span> env <span class="verilog-font-lock-p1800">extends</span> ovm_env;
   <span class="function-name">`ovm_component_utils</span>(env)

   a a1_i;
   a a2_i;
   b b_i;

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name, ovm_component parent);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
   <span class="keyword">endfunction</span>

   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">build</span>();
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">build</span>();
      <span class="keyword">$cast</span>(a1_i, <span class="function-name">create_component</span>("<span class="string">a</span>", "<span class="string">a1_i</span>"));
      <span class="keyword">$cast</span>(a2_i, <span class="function-name">create_component</span>("<span class="string">a</span>", "<span class="string">a2_i</span>"));
      <span class="keyword">$cast</span>(b_i, <span class="function-name">create_component</span>("<span class="string">b</span>", "<span class="string">b_i</span>"));      
   <span class="keyword">endfunction</span> <span class="comment">// void
</span>
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">connect</span>();
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">connect</span>();
      a1_i.put_port.<span class="function-name">connect</span>(b_i.put_imp_source1);
      a2_i.put_port.<span class="function-name">connect</span>(b_i.put_imp_source2);
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span> <span class="comment">// env
</span>
<span class="keyword">endpackage</span> <span class="comment">// vip
</span>
<span class="keyword">package</span> tests;

<span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
<span class="verilog-font-lock-p1800">import</span> vip_pkg::*;
<span class="function-name">`include</span> "<span class="string">ovm_macros.svh</span>"

<span class="verilog-font-lock-p1800">class</span> test <span class="verilog-font-lock-p1800">extends</span> ovm_test;
   <span class="function-name">`ovm_component_utils</span>(test);

   env env_i;
   
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">new</span></span>(<span class="verilog-font-lock-p1800">string</span> name = "<span class="string">test</span>", ovm_component parent=<span class="verilog-font-lock-p1800">null</span>);
      <span class="verilog-font-lock-p1800">super</span>.<span class="verilog-font-lock-p1800">new</span>(name,parent);
   <span class="keyword">endfunction</span> <span class="comment">// new
</span>
   <span class="keyword">function</span> <span class="reference"><span class="verilog-font-lock-p1800">void</span></span> <span class="function-name">build</span>();      
      <span class="verilog-font-lock-p1800">super</span>.<span class="function-name">build</span>();
      <span class="keyword">$cast</span>(env_i, <span class="function-name">create_component</span>("<span class="string">env</span>", "<span class="string">env_i</span>"));
   <span class="keyword">endfunction</span>
<span class="verilog-font-lock-p1800">endclass</span>
<span class="keyword">endpackage</span> <span class="comment">// z
</span>
<span class="keyword">module</span> <span class="function-name">top</span>();
   <span class="verilog-font-lock-p1800">import</span> ovm_pkg::*;
   <span class="verilog-font-lock-p1800">import</span> vip_pkg::*;
   <span class="verilog-font-lock-p1800">import</span> tests::*;
   

   <span class="keyword">initial</span>
     <span class="function-name">run_test</span>();
<span class="keyword">endmodule</span></pre>
<br /><br /> <br />]]></content>
		<id>http://www.specman-verification.com/index.php?entry=entry090718-162417</id>
		<issued>2009-07-18T00:00:00Z</issued>
		<modified>2009-07-18T00:00:00Z</modified>
	</entry>
</feed>

