Skip to Content

Offsite blog roll

Posted on  by  from the site Verification Martial Arts
In this blog, I’d like to cover two cool features that are coming up with the DVT Integrated Development Environment (IDE). The 1st one is the possibility to color VMM log occurrences, the 2nd one a possibility to hyperlink these occurrences to the VMM source code. Here is a snapshot showing VMM logs being colored and hyperlinked to source code: Not only providing hyperlinks from VMM log to source code, DVT also provides hyperlinks to VCS compilation/simulation errors and warnings. To enable these features, all you have to do is to define the right parameters in DVT Run Configuration window. For instance, you can specify the compilation/simulation commands and turn VMM log filtering from the corresponding tab.   This is just one among many other VMM features that are available in DVT. For more details see www.dvteclipse.com. ShareThis...
Uncategorized
Posted on  by  from the site Verification Martial Arts
Andrew Piziali, independent consultant Jim Bondi, DMTS, Texas Instruments Functional verification engineers—also known as DV engineers—often think quite highly of themselves. Having mastered both hardware and software design, and each new design from top to bottom with an understanding exceeding all but the architects, we can see why they might end up with an inflated ego. Yet, responsibility for verification of the design is not theirs alone and sometimes not theirs at all! In this next series of blog posts I am going to direct your attention to the role various members of a design team play in the verification process. Each will be co-authored by someone contributing to their design in the role under discussion. It is not uncommon these days for a small design team to lack any dedicated verification engineers.  Hence, the designers become responsible for the functional verification process embedded in, yet operating in parallel to, the design process.  What does that overall process look like?[1] Specification and Modeling Hardware/Software Partitioning Pre-Partitioning Analysis Partitioning Post-Partitioning Analysis and Debug Post-Partitioning Verification Hardware and Software Implementation Implementation Verification Specification and modeling is responsible for exploring nascent design spaces and capturing original intent. The difficult choices of how to partition the design implementation between hardware and software components comes next. Then, analysis of each partitioning choice and debugging these high level models. Our first opportunity for functional verification follows post-partitioning analysis and debug, where abstract algorithm errors are discovered and eliminated. Hardware and software implementation is self explanatory, lastly leading to implementation verification, answering the question “Has the design intent been preserved in the implementation?” This kick-off post in this series addresses the role of the architect in verification. My co-author, Jim Bondi, has been a key architect on numerous design projects at Texas Instruments ranging from embedded military systems to Pentium-class x86 processors to ultra low power DSP platforms for medical applications. The architect, whether a single individual or several, is responsible for specifying a solution to customer product requirements that captures the initial design intent of the solution. The resultant specification is iteratively refined during the first three stages of design. In addition to authoring the original design intent, the second role of the architect in the verification process is preserving that intent and contributing to its precise conveyance throughout the remainder of the design process.[2] This begins during verification planning, where the scope of the verification problem is quantified and its solution specified. Verification planning itself begins with specification analysis, where the features of the design are identified and quantified. The complexity of most designs requires a top down analysis of the specification—first, because of its size (>20 pages) and second, because behavioral requirements must be distilled. This analysis is performed in a series of brainstorming meetings wherein each of the stakeholders of the design contribute: architect, system engineer, verification engineer, software engineer, hardware designer and project manager. A brainstorming session is guided by someone familiar with the planning process. The architect describes each design feature and—through Q&A—its attributes are illuminated. These attributes and their associated values—registers, data paths, control logic, opcodes—are initially recorded in an Ishikawa diagram (also known as a “fish bone diagram”) for organizational purposes and then transferred to a coverage model design table as they are refined. Ultimately, each coverage model is implemented using a high level verification language (HVL), as part of the verification environment, and used to measure verification progress. The seasoned architect knows that, even though modeling is mentioned only in the first design step above, it is most effective not only when started early but also continued iteratively throughout most of the design process. It is quite true that system modeling should be started early—as soon as possible and ideally before any RTL is written—when modeling can have its biggest impact on the design and offer its biggest return on model investment. In this early stage, modeling can best help tune the nascent architecture to the application, with the biggest resultant possible improvements in system performance and power. When used right, models are developed first and then actually drive the development of RTL in later design steps. This is contrary to the all- to-common tendency to jump prematurely to RTL representations of the design, and then perhaps use modeling mostly thereafter in attempts to help check and improve the RTL. Used in this fashion, the ability of modeling to improve the design is limited. More experienced architects have learned that modeling is best applied “up front” because it is here, before the design is cast in RTL, that up to 75% of the overall possible improvements in system performance and power can be realized.  The architect knows that a design process that jumps prematurely to RTL leaves much of this potential performance and power improvement on the table. The seasoned architect also knows that, even though started early, modeling should be continued iteratively throughout most of the remainder of the design process. They know that, in fact, a set of models is needed to best support the design process. The first is typically an untimed functional model that becomes the design’s “golden” reference model, effectively an executable specification. As the design process continues, other models are derived from it, with, for example, timing added to derive performance models and power estimates added to derive power-aware models. In later stages, after modeling has been used “up front” to tune the architecture, optimal RTL can actually be derived from the models. Wherever verification is applied in the design process, whether before or after RTL appears, the models, as a natural form of executable golden reference, can support, or even drive, the verification process. Thus, in design flows that use modeling best, system modeling begins up front and is continued iteratively throughout most of the overall design process. Indeed, the architect plays a crucial role in the overall design process and in the functional verification of the design derived from that process. They are heavily involved in all design phases affecting and involving verification, from authoring the initial design intent to ensuring its preservation throughout the rest of the design process.  The seasoned architect leverages a special set of system models to help perform this crucial role. Despite the verification engineer’s well-deserved reputation as a jack-of-all-trades, they cannot verify the design alone and may not even be represented in a small design team.  The architect is the “intent glue” that holds the design together until it is complete! ——————- [1] ESL Design and Verification, Bailey, Martin and Piziali, Elsevier, 2007 [2] Functional Verification Coverage Measurement and Analysis, Piziali, Springer, 2004 ShareThis...
Modelling
Posted on  by  from the site Verification Martial Arts
Srinivasan Venkataramanan, CVC Pvt. Ltd. Abhishek Muchandikar, CAE, Verification Group, Synopsys Raja Mahadevan, Sr. CAE, Verification Group, Synopsys   It is well understood and accepted fact that Assertions play a critical role in detecting a class of design errors (or bugs) in functional verification. Just like any other verification component in a robust, reusable environment, assertions need to be both controllable and observable from various levels including tests, regressions, command line etc. However an ad-hoc throw of assertions across the design and verification code doesn’t always consider this requirement upfront. Recently standardized SystemVerilog 2009 construct checker..endchecker is definitely a good step towards creating a good encapsulation for these widely spread out assertions. In our recent book on SystemVerilog Assertions (2nd edition of SVA handbook, www.systemverilog.us/sva_info.html ) we cover this construct in depth. We also presented a case study of a Cache controller verification using these new constructs at DVCon 2010 (paper & code available from www.cvcblr.com on request). The role of a methodology goes far beyond the constructs, it does utilize them but provides more controllability and observability for the end user trying to make sense out of all these various features to achieve his/her final goal of getting verification done. In this series of blog entries we try and cover some of the key aspects of such methodology role in adopting ABV (Assertion Based Verification). We welcome reader comments to add more innovative thoughts and ideas to this puzzle. Our goal of this blog series is not to cover all possible aspects of ABV methodology as that would include a wide range of topics, many of them already well covered in VMM book (www.vmm-sv.org); rather in this blog series we look at application aspects of ABV methodology. To start with, let’s partition the role of methodology into two major buckets: observability & controllability. Under observability we will explore the following: · Make assertions observable in native form within the methodology framework · Tie the assertion results to the verification plan via VMM Planner hooks Under controllability we will explore the following: · Control the severity & verbosity of assertions from external world – command line, testcases etc. · Control assertion execution during reset, exceptions, low power etc. Making assertions natively observable in VMM In simulation based verification, observability is primarily enabled by the kind of messages that get emitted during the run. Messaging service plays an important part in a verification environment indicating the progress of the simulation or providing additional information to debug a design malfunction.  To ensure a consistent look and better organization of messages issued by various verification layers be it the transactor, scoreboards, or assertions, use of a standard messaging service is required. VMM provides a time-proven utility vmm_log to enable this key requirement. While the use of vmm_log in a typical VMM environment is well understood and widely deployed, the integration of the same to assertions is not that widely spoken about in the literature. Assertion reporting as such always tends to be a loner in terms of the verification environment messaging family. This is due to the fact that assertion reporting has been handled in ad-hoc manner – many a times unattended (i.e. no action blocks at all), this can lead to simulator specific reports for assertion firings (pass/fail) where as the rest of testbench environment uses a consistent vmm_log style. The drawback of such a use model is twofold: · Absence of a single tightly integrated messaging service across the verification board Assertion failures do not interact with the test bench environment and hence there is absolutely no way to effectively and correctly qualify the simulation. The limitation of such a behavior (in a regression setup), would never qualify the test as a “failures” unless some other post processing is duly placed · Assertion results bear zero control over the verification simulation cycles Quite often it is observed that the tests tend to run the entire simulation cycles even in the presence of assertions failures which maybe uncalled for and may warrant an immediate termination of the simulation. Efficient incorporation of assertions in a verification environment calls for synchronization between assertion results and the verification environment. A common messaging service would be the key to such synchronization. The VMM messaging service “vmm_log” is a fine example of a standard messaging class which is seamlessly integrated into assertion checkers/properties which ensures consistency across the complete verification environment. The user could force the simulation to quit via a `vmm_fatal macro or proceed with the simulation for a particular checker instance failure. The use of vmm_log for assertion error messaging gets recognized by the VMM environment leading to an effective simulation result. Integration of VMM messaging service provides extended flexibility to the user to control the simulation based on the severity of the checker instance. Steps to integrate vmm_log with assertion reporting · Declaration of a new package with a static VMM log object  package vmm_sva; `include "vmm.sv" vmm_log sva_vmm_log = new("SVA_CHECKER",$psprintf("%m")); endpackage : vmm_sva · Inclusion of the package in the assertion file module sva_file(….) import vmm_sva ::*; // AHB master property check property HburstSingleHtransNseq;         @ (posedge HCLK)disable iff (!HRESETn) (         ((SINGLE && HGRANT)         )         |-> ((NSEQ || IDLE))); endproperty HburstSingleHtransNseq_check  : assert property (HburstSingleHtransNseq) else `vmm_fatal (sva_vmm_log, "AMBA Compliance Protocol Rules : ERRMSINGLE: Master has issued a SEQ/BUSY type SINGLE transfer")); endmodule Simulation Result: Bases on the severity of the assertion, you could terminate the simulation and also the testbench environment recognizers this failure and qualifies the simulation as a failure as depicted below *FATAL*[FAILURE] on SVA_CHECKER(vmm_sva) at                  195:     [AMBA Compliance Protocol Rules : ERRMSINGLE]   Master has issued a SEQ/BUSY type SINGLE transfer Simulation *FAILED* on /./ (/./) at                  195: 1 errors, 0 warnings $finish called from file "/tools/eda/snps/vcs-mx/etc/rvm/vmm.sv", line 36499. $finish at simulation time                  195            V C S   S i m u l a t i o n   R e p o r t Users can choose from the variety of vmm_log macros such as `vmm_error, `vmm_warning etc. to suit the relevant message being flagged by that assertion. With this subtle change/enhancement to the SVA action block one can leverage on VMM’s simulation controllability features such as error counting, simulation handling of errors (stop, debug, continue etc.). One can also promote/demote errors to warnings for instance. A final note on the logger instance being shown in this example: while the above shown code works, typical usage would classify the messages originating from different portions of design/verification into individual logger instances. In our next entry in this series, we will address the second aspect of observability – i.e. tie the results to Verification plan, so stay tuned! ShareThis...
Uncategorized
Posted on  by  from the site Verification Martial Arts
A two-part articles by Cisco and Synopsys engineers in IC Design and Verification Journal explains how complex constraints can be better managed to simplify the solving process, yet obtain high-quality results. Part1 deals with solutions spaces and constraint partitions. Part2 introduces the concept of soft constraint in e and default constraints in OpenVera. You can read part1 and part2 here. ShareThis...
Uncategorized
Posted on  by  from the site Verification Martial Arts
Srinivasan Venkataramanan, CVC Pvt. Ltd. Abhishek Muchandikar, Sr RnD Engineer, Verification Group, Synopsys Sadanand Gulwadi, Sr. Staff CAE, Verification Group, Synopsys Inc., Mt. View, CA, USA Assertions for protocol checking has been popular for quite some time now. With several off-the-shelf assertion/monitor IPs available from EDA vendors and providers such as CVC (www.cvcblr.com), end users need not have to spend too much time thinking about what assertions to add in their designs, how to code them etc. All that users would need to do is to create suitable bind files and off they go! While using assertions sounds simple and straightforward, there are scenarios for which users need to watch out. For example, if assertions did fire, then you have likely found a bug. However if assertions remained silent throughout a simulation, then you cannot afford to be too happy, for the assertions may have been “totally vacuous”. This is a term that my ex-colleague and I coined during our work at a large DSP customer here. They were adding assertions and looking for improved productivity early on rather than having to go through detailed assertion coverage metrics, various dump files, and so forth at a later stage While standard garden variety vacuity is quite well understood and explained in our regular SVA trainings (http://www.cvcblr.com/trng_profiles/CVC_LG_SVA_profile.pdf), the concept of “totally vacuous” is a step beyond that. Totally vacuous assertions are those that were *never* successful during the entire simulation run. This can be due to a few reasons: 1. The assertions were never attempted at all (perhaps the CLOCK was undriven, or was part of a gated clock of a low power domain etc.) 2. The antecedent of a property was never satisfied etc. Further, observation of the assertion behaviour stated above might indicate the following potential issues in your design or verification plan: 1. Incorrect clock network connections, clock enables, and so forth. 2. Test-case is weak and does not address a key portion of your design (a coverage hole). For instance, consider the following assertion (taken from our SVA handbook, www.systemverilog.us/sva_info.html) /* Behavior: if the transfer type is BUSY then on the corresponding data transfer , the slave must provide a zero wait state OKAY response (default clock) */ property pResponseToBusyMustBeZeroWaitOKAY (hResp,hReady,hTrans); @(posedge hclk) (((hTrans == BUSY) && (hReady == 1)) |-> ##1 ((hResp == OKAY) && (hReady == 1)) ); endproperty: pResponseToBusyMustBeZeroWaitOKAY Consider the case when the stimulus didn’t drive the hTrans to be BUSY throughout the simulation. This is strange and means that the stimulus is weak. However when (and how) does a user find this out? With the usual wisdom of “No news is GOOD news”, it is very easy to ignore this important coverage hole and move on with other work. However, the customer desired such strange assertion behaviour to be flagged as early as possible – at the end of every simulation run. VCS does have the ability to catch such “totally vacuous” assertions and accordingly reports the following at the end of a simulation run: **** Following assertions did not fire at all during simulation. ***** "/proj/cvc_mips/ahb_mip/master.sva ", 48: a_pResponseToBusyMustBeZeroWaitOKAY: Antecedent was never satisfied "/proj/cvc_mips/ahb_mip/slave.sva ", 32: a_pLowPowerGclk: No attempt started The above output is default in VCS without the need for any additional user-driven options and frees the user from the additional steps of enabling assertion coverage, debug, etc. Assertion coverage and debug are indeed powerful features for analyzing problems, but should be turned on only after ensuring the assertions are not “totally vacuous” – a glaring weakness that requires being flagged early on by default. It is all about productivity at the end of the day – if a tool can help improve productivity it is always welcome So the next time VCS prints such a message, you had better watch out before calling it a day! ShareThis...
Uncategorized
Posted on  by  from the site Verification Martial Arts
  John Aynsley, CTO, Doulos     Analysis ports are another feature from the SystemC TLM-2.0 standard that has been incorporated into VMM 1.2. Analysis ports provide a mechanism for distributing transactions to passive components in a verification environment, such as checkers and scoreboards. Analysis ports and exports are a variant on the TLM ports and exports that I have discussed in previous blog posts. The main difference between analysis ports and regular ports is that a single analysis port can be bound to multiple exports, in which case the same transaction is sent to each and every export or “subscriber” or “observer” connected to the analysis port. The terms subscriber and observer are used interchangeably in the VMM documentation. Let us take a look at an example: class my_tx extends vmm_data;  // User-defined transaction class   … class transactor extends vmm_xactor;    vmm_tlm_analysis_port #(transactor, my_tx) m_ap;   // The analysis port   …    virtual task main;     my_tx tx;     …     m_ap.write(tx);     … The transactor above sends a transaction tx out through an analysis port m_ap. The type of the analysis port is parameterized with the type of the transactor and of the transaction my_tx. The call to write sends the transaction to any object that has registered itself with the analysis port. There could be zero, one, or many such observers registered with the analysis port. To continue the example, let us look at one observer: class observer extends vmm_object;    vmm_tlm_analysis_export #(observer, my_tx) m_export;   function new (string inst, vmm_object parent = null);     …     m_export = new(this, "m_export");     …   function void write(int id, my_tx tx);     … The observer has an instance of an analysis export and must implement the write method that the export will provide to the transactors. Note that the observer extends vmm_object. Since an observer is passive, it need not extend vmm_xactor. The analysis port may be bound to any number of observers in the surrounding environment: class tb_env extends vmm_group;    transactor  m_transactor;   observer    m_observer_1;   another     m_observer_2;   yet_another m_observer_3;   virtual function void build_ph;     m_transactor = new( "m_transactor", this );     m_observer   = new( "m_observer",   this );     …   endfunction   virtual function void connect_ph;       m_transactor.m_ap.tlm_bind( m_observer_1.m_export );     m_transactor.m_ap.tlm_bind( m_observer_2.m_export );     m_transactor.m_ap.tlm_bind( m_observer_3.m_export );     … Note the use of the predefined phase methods from VMM 1.2. Transactors are created during the build phase, and ports are connected during the connect phase. Finally, let us compare analysis ports with VMM callbacks:   m_ap.write(tx); versus   `vmm_callback(callback_facade, write(tx)); The effect is very similar, but there are differences. Unlike VMM callbacks, the name of the method called through an analysis port is fixed at write. A VMM callback method is permitted to modify the transaction object, whereas a transaction sent through an analysis port cannot be modified. When multiple callbacks are registered, the prepend_callback and append_callback methods allow you to determine the order in which the callbacks are made, whereas you have no control over the order in which write is called for multiple observers bound to an analysis port. Because of these differences, only VMM callbacks are appropriate for modifying the behavior of transactors. Analysis ports are only appropriate for sending transactions to passive components that will not attempt to modify the transaction object. On the other hand, that in itself is the feature and strength of analysis ports; they are only for analysis. It can make sense to combine a VMM callback with an analysis port in the same transactor, using the callback to inject an error and the analysis port to send the modified transaction to a scoreboard, for example:   `vmm_callback(callback_facade, inject_error(tx));    m_ap.write(tx); In this situation, the VMM recommendation is to make the analysis call after the callback, as shown here. ShareThis...
Uncategorized
Posted on  by  from the site Verification Martial Arts
Srinivasan Venkataramanan, CVC Pvt. Ltd. Vishal Namshiker, Brocade Communications India Any complex system requires debugging at some point or the other. To ease the debug process, a good, proven coding practice is to add enough messages for the end user to aid in debug. However as systems become mature the messages tend to become too many and quickly users feel a need for controlling the messages. VMM provides a comprehensive log scheme that provides enough flexibility to let users control what-how-and-when to see certain messages (See: http://www.vmmcentral.org/vmartialarts/?p=259). Recently during a brainstorming session we sought for common issues seen by users at Brocade. One of the engineers mentioned that he has abandoned the usage of `vmm_verbose, `vmm_debug macros altogether, when probed why, an interesting problem emerged. As we know the usage of them requires the +vmm_log_default=VERBOSE” flag at run time. However when used this way, there are tons of messages coming from VMM base classes too – as they are under the VERBOSE/DEBUG severity. Sure they are useful to one set of/class of problems, but if the current problem is with user code, user would like to be able to exclude the ones from VMM base classes. An interesting problem of contradictory requirements perhaps? Not really, VMM base class is well architected to handle this situation. In VMM, there are two dimensions to control which messages user would like to see. The verbosity level specifies the minimum severity to display and you’ll see every message with a severity greater to equal to it. The other dimension/classification is based on TYPE. There are several values for the TYPE such as NOTE_TYP, DEBUG_TYP etc. Most relevant here is the INTERNAL_TYP – a special type intended to be used exclusively by VMM base class code. All debug related VMM library messages are classified under INTERNAL_TYP. You can use vmm_log::disable_types() method. A quick example to do this inside the user_env is below:   virtual function void my_env::build();    super.build();    … this.log.disable_types(.typs(vmm_log::INTERNAL_TYP),                                     .name(“/./”),.inst( “/./”) );   endfunction : build This is a typical usage if everyone in the team agrees to such a change. However if a localized change is needed for few runs alone, one can combine the power of VCS’s Aspect Oriented Extensions (AOE) made to SystemVerilog. In this case, user supply a separate file as shown below: ///////////  disable_vmm_msg.sv extends disable_log(vmm_log); after function new(string name = "/./",                    string instance = "/./",                    vmm_log under = null);   this.disable_types(.typs(vmm_log::INTERNAL_TYP)); endfunction:new endextends Add this file to the compile list and voila! BTW, during recent SystemVerilog extensions discussion at DVCon 2010, AOP extensions are being requested by more users to be added to the LRM standard. With its due process, a version of AOP is likely to be added to the LRM in the future (let’s hope in the “near future” J ). ShareThis...
Debug, SV, VMM, vmm_log
Posted on  by  from the site Verification Martial Arts
  Varun S, CAE, Synopsys Iterators are objects that know how to traverse and navigate the implementation of the scoreboard. They provide high level methods for moving through the scoreboard and modifying its content at the location of the iterator. The actual data structure used to implement the data stream scoreboard is entirely private to the implementation of the foundation classes. However, for implementing user-defined functionality, the entire content of the scoreboard should be made available to the user, so that it can be searched and modified. You can do this using iterators without exposing the underlying implementation. Logical streams: Datastream applications involve transmission, multiplexing, prioritization, or transformation of data items. A stream in general is a sequence of data elements. In VMM, a stream is composed of transaction descriptors based on the vmm_data class. A stream of data elements flowing between two transactors through a vmm_channel instance or to the DUT through a physical interface is a structural stream. Through multiplexing, it maybe composed of data elements from different inputs or destined to different outputs. If there is a way to identify the original input a data element came from or the destination a data element is going to, a structural stream can be said to be composed of multiple logical substreams. It is up to you to define the logical streams based on the nature of the application you are trying to verify. For example, if you are verifying a router with 16 input and 16 output ports, all data packet going from 0th input port to 0th output port can be viewed as belonging to the same logical stream giving rise to a total of 256 logical streams. Kinds of iterators: 1. Scoreboard iterators (vmm_sb_ds_iter class) – These move from one logic stream of expected data to another. An instance is created using vmm_sb_ds::new_sb_iter() method. 2. Stream iterators (vmm_sb_ds_stream_iter class) – These move from one data element to another on a single logical data stream. An instance is created using vmm_sb_ds_iter::new_stream_iter() method. —————————————– |  d00 |  d01 |  d02  |          |  d0n |         ^ —————————————–          |                                                               | —————————————–          | |  d10 |  d11 |  d12 |           |  d1n |          | —————————————–          |                                                              |vmm_sb_ds_iter —————————————–          |  |        |          |       |           |        |          | —————————————–          |                                                              | —————————————–          | |  dm0| dm1 | dm2|            | dmn |         v —————————————–    <——————————–> vmm_sb_ds_stream_iter The figure above shows ‘m’ logical streams, each stream consisting of ‘n’ data elements. As previously mentioned, logical streams are user-defined based on the application and within the scoreboard they correspond to data queues into which data elements are stored. Once the queues are populated, if the user wishes to modify a data element or delete a few of them, he can do so by the use of iterators. A set of high level methods have been implemented within the iterator classes, which aid in navigating through the data queued up in the scoreboard and modify it, if necessary. The methods first(), next(), last(), prev(), length() are some of the methods that have been implemented within both the iterator classes. Note : Logical streams only exist if they contain(or have contained in the past) expected data and the iterator will only iterate over logical streams that exist. Sample code:   class my_scoreboard extends vmm_sb_ds;       /* creates a scoreboard iterator that iterates over different streams of data */       vmm_sb_ds_iter iter_over_streams = this.new_sb_iter();        for(iter_over_streams.first(); iter_over_streams.is_ok(); iter_over_streams.next()) begin           /* a stream iterator that scans the data within a stream */           vmm_sb_sb_stream_iter scan_stream = iter_over_streams.new_stream_iter();           if(scan_stream.find(pkt)) begin               repeat(scan_stream.pos()) begin                   scan_stream.prev();                   scan_stream.delete();               end           end       end   endclass The sample code shows a very simple scoreboard. Here, a scoreboard iterator "iter_over_streams" is instantiated and set to iterate over all the streams using the for loop. The method first() sets the scoreboard iterator on the first stream in the scoreboard. The method is_ok() returns TRUE if the iterator is currently positioned on a valid stream, returns FALSE if the iterator has moved beyond the valid streams. The method next() moves the iterator to the next applicable stream. A stream iterator "scan_stream" is then created to iterate over the stream on which "iter_over_streams" is positioned. The find() method used in the if-statement is used to locate the next packet in the stream matching the specified packet "pkt". The repeat loop is used to delete all the packets before the found packet. The method pos() returns the current position of the iterator, prev() moves the iterator to the previous packet and delete() deletes the packet at the position where the iterator is positioned. Hence, you can see that you can easily traverse across the different streams easily to find/alter any specific packets  that you need to. Hope you find this useful and use these iterators to make your verifications tasks simpler. For more information about the complete list of methods, see the VMM Datastream Scoreboard User Guide. ShareThis...
Uncategorized
Posted on  by  from the site Verification Martial Arts
Tri-state busses are typically present in a verification environment when we have multiple drivers driving a bus. One of the drivers drives the bus and the rest of the drivers on the bus present high impedance to the bus. By far and large, it is preferred to have a single interface from the testbench side to deal with the tristate bus. This typically helps avoid bus contention. In some circumstances, this may not be easily possible. Why don’t you just imagine having to elaborate a design, run to a certain point and run a drivers() command? I’m not sure any of us is looking forward to that are we? Especially if we have to do it again and again. If you’re going to do have a tristate bus, one tip would be to add a simple internal signal to the driver that is asserted whenever you’re going to drive a tristate bus. In a dump, that will show up. The only other alternative would be to run a trace drivers command with a debug switch (-debug_all) to find the contention. The simple internal signal will save you a lot of debug time and will get thrown out by synthesis if you mark it with the appropriate pragma’s and do it right…. More later… Stay tuned… ShareThis...
Debug
Posted on  by  from the site Verification Martial Arts
John Aynsley, CTO, Doulos   In the previous post I described TLM ports and exports from VMM 1.2. In this post, we will look at how to handle incoming transactions from multiple sources, that is, multiple producers connected to a single consumer. VMM 1.2 provides two separate mechanisms to handle this situation: peer ids, and shorthand macros. We will explore what these mechanisms have in common, and also the differences between them. We are discussing the following situation, where two separate producer instances send transactions to a single consumer: class producer extends vmm_xactor;     vmm_tlm_b_transport_port #(producer, my_tx) m_port;     …     m_port.b_transport(tx, delay);     … class consumer extends vmm_xactor;     vmm_tlm_b_transport_export #(consumer, my_tx) m_export;     function new (string inst, vmm_object parent = null);         super.new(get_typename(), inst, -1, parent);         m_export = new(this, "m_export", 2); // 3rd argument = max # bindings     endfunction     function void start_of_sim_ph;         vmm_note(log, $psprintf("Number of peers = %d", m_export.get_n_peers()));     endfunction     task b_transport(int id = -1,         my_tx trans, ref int delay);     … class my_env extends vmm_group;     producer m_producer_1;     producer m_producer_2;     consumer m_consumer;     virtual function void connect_ph;         m_producer_1.m_port.tlm_bind( m_consumer.m_export, 0 ); // 2nd argument = id         m_producer_2.m_port.tlm_bind( m_consumer.m_export, 1 );     endfunction     … The first thing to notice is the connect_ph method of the environment, which binds two separate ports to the same export. The tlm_bind method takes a second argument, the peer id, which allows transactions from the two ports to be distinguished. The second thing to notice is that when the export is instantiated, the constructor new takes a third argument that specifies the maximum number of bindings to this export. The default value of 1 would be inadequate in this case, since the export is bound twice. Thirdly, the method get_n_peers called from start_of_sim_ph returns the number of peers, which would be 2 in this case. Finally, the first argument to the b_transport method implemented in the consumer is the peer id passed to the tlm_bind method. The implementation of b_transport can now use the peer id to distinguish between transactions from the two producers. So much for peer ids. Now let us take a look at the alternative, that is, shorthand macros. Instead of binding two ports to a single export, we could have used the shorthand macros to create two separate exports: class consumer extends vmm_xactor;     `vmm_tlm_b_transport_export(_1) // Argument is suffix to name     `vmm_tlm_b_transport_export(_2)     vmm_tlm_b_transport_export_1 #(consumer, my_tx) m_export_1;     vmm_tlm_b_transport_export_2 #(consumer, my_tx) m_export_2;     task b_transport_1(int id = -1,     my_tx trans, ref int delay);     …     task b_transport_2(int id = -1,         my_tx trans, ref int delay);     … The argument passed to the macro is used as the suffix for a new type name and a new method name. Those new types are then used to create two separate exports, and the consumer contains two separate and differently named implementations of the b_transport method, one for each export. It is good practice to use the same suffix when naming the export members themselves (e.g. m_export_1), though this is not strictly necessary. Since peer ids are not being used, the id argument to b_transport will have the value 0 for both methods. As usual, ports are bound to exports in the surrounding environment, but this time using separate exports rather than peer ids: class my_env extends vmm_group;     producer m_producer_1;     producer m_producer_2;     consumer m_consumer;     virtual function void connect_ph;         m_producer_1.m_port.tlm_bind( m_consumer.m_export_1 );         m_producer_2.m_port.tlm_bind( m_consumer.m_export_2 );     endfunction     … In conclusion, we have seen peer ids and shorthand macros used to accomplish the same thing, that is, multiple producers sending transactions to a single consumer. With peer ids we instantiate a single export and provide a single b_transport method, distinguishing between the incoming transactions using the peer id argument. With shorthand macros we instantiate two exports and provide two implementations of b_transport, distinguished by the suffix to their names. ShareThis...
Uncategorized