Home

Part II: An Open-Source Environment with C++

image

Contents

1. 5 The primary reason for this is because verification component repre sents a pattern while test_component is an example of this pattern The test_component has specific implementations of four of the verification component methods Also test_component intro duces some of these same methods as nonvirtual Finally the seguencing of the methods is different from the test and testbench the two top level components that are verification components These differences are critical for the integrity of the class Test Component and Irritator Classes of the verification component methods into finer detail as one would expect of a lower level object Below is the interface for the test component base class namespace truss class test component protected virtual verification component protected thread public test component const std string amp n virtual void time zero setup 0 virtual void out of reset reset 0 virtual void randomize 0 virtual void write to hardware 0 void start void stop void wait for completion void report const std string amp prefix protected virtual void start virtual void run component traffic virtual void start components 0 virtual void generate 0 virtual void wait for completion 0 bool completed The methods time zero setup out _ of reset and write to hardware are provided to allow the test component to intera
2. In this handbook we use the checker to throttle the system because we want to keep a certain amount of data in flight and the checker is the only agent that knows what has been generated and what has been received The chip can handle an unlimited number of back to back transactions That s all there is to building an irritator Note that you will probably start with a test component and then evolve it into an irritator It will probably be many weeks into your project before the first irritator is built but for coverage and finding congestion bugs irritators are a good choice In fact your first test will probably be even more rudimentary This first test is the focus of the next section Compiling and Running Tests 122 The sections above described the main building blocks of Truss The following chapters as well as later examples will show how these still somewhat abstract concepts get implemented for real projects However before we start looking at more concrete examples there is one more problem to consider that of compiling and running a verification envi ronment All verification environments need some type of run script to compile and build both the RTL and verification code In a large project this is not a simple task because one must track a lot of code as well as many tools and options A goal for Truss is to provide a production grade run script and makefiles as open source components At the moment a
3. to lt lt stop error max lt lt endm The example above works for all integral built in types Accessing Memory For most verification projects it is important to be able to access memory Sometimes you want to do this in zero simulation time Allowing back door accesses of memory improves simulation performance allows the monitoring of memory for automatic checking and makes it possible to insert errors into memory for test purposes Teal provides such a back door mechanism butalso of course supports front door access which can map some memory address ranges to a transactor based model Teal defines each accessible memory transactor model or memory array asamemory bank object A memory bank object can be accessed directly through member functions called to memory and from memory but each memory can also be associated with an address range through A Practitioner s Handbook 81 Chapter 5 Teal Basics the add map function In this way memory can be accessed through addressing by means of read and write functions Working with address ranges has many advantages because it creates code that is easier to understand and is closer to production software The read and write functions can even be redefined in production software to become simple integer pointers as is often appropriate When writing a memory transactor you must define your own memory bank object but when working with
4. take these data members and make the appropriate calls to the generators in the testbench An AHB example 108 An example might make the roles a little clearer Remember that there are several fully implemented examples in Part IV Suppose you are creating a test component to test an AHB arbiter The test component acts as a master generating read and write requests to a number of slaves The generator in the testbench can generate a burst of reads or writes to a given slave using a specific burst length Assume that the generator has a channel interface that can take in an AHB transaction object The randomize function of your ahb_ test component might look like this void ahb test component randomize burst length generate burst length min max is read generate type min type max type slave generate slave min slave max slave The corresponding generate might look like this void ahm test component generate addresses are picked by the generator generator gt gueue burst new AHB transaction burst length is read 6 AMBA Advanced Microcontroller Bus Architecture high performance bus Test Component and Irritator Classes slave_ done signal Signals that test component is done Notice that by nature these calls are executed in a one shot manner That is together they perform a single transaction This is useful to allow an irritator to in
5. bfm gt write_to hardware protected virtual void generate generator gt generator virtual void wait for completion checker gt wait for completion i virtual void start components bfm gt start checker gt start private generator generator bfm bfm_ checker checker_ Although your actual test component will be a bit different from the code above the general form will probably be the same A Practitioner s Handbook 133 Chapter 7 Truss Flow Adjusting the second test s parameters 134 As soon as you introduce randomization into a test you ll probably want some knobs to control the randomization Sweeping most parameters through an entire integer range would chew up a whole lot of simulation time Besides it s probably either 1 not interesting or 2 unacceptable to the register associated with the integer A knob is a technique that uses other variables to control the range of a random variable either directly or indirectly In this example we ll concentrate on controlling the random variables directly The examples in the handbook use the Teal dictionary feature to pass parameters from a number of sources to the method that will use the knob variables For example consider a test for a CPU Assume that a cpu generator class has a send one operation method that is called by a test_component to tell the cpu generator to create one random oper
6. ation The generator is guided by dictionary variables It is best to put the variables to randomize in a separate function at the top of the source file because the seeding depends on line number That way the seguence of values selected does not change if the code below is reorganized Of course new random values chosen will be different for each master seed Here is an example function for generating the operand a variable of a CPU operation namespace uint32 get_operand a uint32 min_v uint32 max_v uint32 returned RAND RANGE returned min v max_v return returned 7 In the cpu generator the following lines could be used Il static uint32 min operand a dictionary find name_ _min operand a 0 static uint32 max operand a dictionary find name_ max operand a 0 operand a get operand a min operand a max operand a This same style is used for the other operand and the operator variables The Second Test Adding Channels and Random Parameters So who sets the knobs There are four ways 1 use the default specified in the dictionary find call as the second parameter 2 put the knob value on the command line 3 use a knob configuration file or 4 finally write code to use the dictionary put call which is the mechanism used in our example Note that because the Teal dictionary is used both the command line and the knob file can be added later without the need to modify any of t
7. below The Irritator Dance Detailed Flow from your_test start test_component start v test_component start_ Start your generator your start_components_ BFM and checker irritator run_component_traffic_ until irritator stop_generation y Caled by test test component run_component traffic _ yoursrandomize yoursgenerate_ gt mam at manod your inter_generate_gap_ gt Pause the generate loop Legend you must implement PROJECT_HOME verification test_components your_irritator cpp you may implement TRUSS_HOME inc test_component h and irritator h The irritator overrides the run component traffic method from the test component base and calls the base class run component traffic method in a loop This is the nature of an irritator it just keeps on going until told to stop The method that stops the loop is stop generation which is usually called by your A Practitioner s Handbook 121 Chapter 7 Truss Flow test once the main feature or interface has finished being tested This will be shown in detail in the Part IV of this handbook One method you will have to implement is inter generate gap_ This method may be empty for a couple of reasons a Your channel has a limited depth and this limit is used to apply back pressure to your system n Your generator has a built in delay of some form
8. result to int return true continue loop The alu_test_component Other than the reset logic and the watchdog timer the monitor and driver are the only code to interact with the chip wires Next we ll look at how we come up with the operations to be sent to the driver The alu_test_component We now run a random seguence of operations through the ALU testing the basic operations with random operands The test component start components method is used to run this exercise The code is shown below void alu test component start components_ driver gt start checker gt start Like most test components this one just starts the lower level compo nents Checking the Chip Because we do verification for a living the automated checking of the chip s results is important In our case we have a legacy c model of the ALU and will use it to check that the answer is what we expected The checker waits for the monitor agent to deliver a completed operation Then it uses the inputs sent by the generator to have the c model come up with the expected result A Practitioner s Handbook 147 Chapter 8 Truss Example The c model prototype is shown below fif defined _ cplusplus extern C endif unsigned int alu model unsigned int a unsigned int b unsigned char op if defined _ cplusplus endif Note that the ifdefs allow the code to be compiled by both C and C code This
9. 143 Chapter 8 Truss Example Running the Simple ALU Example You might want to see the log messages on the screen so let s talk about how to run the example In the examples alu_ tutorial bin direc tory there is a setup script If you look at the setup file it sets up a few environment variables that are needed by the run and make tools First source the setup file then execute the following STRUSS HOME bin truss test tutorial test The truss command has many more options type truss help for a synopsis You should see the C source files being compiled and then the test should run When the test runs a series of printouts will announce the flow through the test Remember that by default Teal prints the file and line number of the message Points of Interest 144 The next few sections address specific places in the code These sections follow the general way you go about hooking up a chip to a Truss based verification system For example the first thing to be concerned with is bringing the chip out of reset After that you ll probably want to pick an interface and write the driver and monitor classes Then you decide upon some specific operations you want to perform and write the test component to exercise the interface or feature In general the test builds the test components and ends when the last operation completes that is when the test component s wait for completion returns Power on
10. Ford Bun a verification system is a daunting task but build we must That is why we use the technigue of layering to break the problem down By starting with the lowest layer that is the one that directly drives and senses the wires we can start to get some real work done Still because C is not what most hardware engineers use for their HDL we ll need an interface layer to connect the HDL with C Teal is just such an interface Teal tries to be as unobtrusive as possible using terms borrowed from the HDL domain such as posedge and reg This chapter introduces Teal and shows how to use it We ll talk a bit about the main parts of Teal for example how you can fairly seam lessly get and set values in the HDL and how you can pause execution until HDL signals change Hardware Verification with C A Practitioner s Handbook 67 Chapter 5 Teal Basics Overview Teal is a C class library for functional verification Teal is tiny consisting of only a handful of source files yet it provides the necessary minimum features for verification A version of Tealis on the companion CD Teal like Vera SystemVerilog and e provides the illusion that the verification system is in control of the chip In Teal you write a verification top function and create tests generators checkers drivers and monitors Each of these objects can appear to be running independently of the chip with each in its own thread of execut
11. IV allows a test component to be reused for other chips that have only a subset of the original chip s functionality Test components are critical to the adaptability of a verification system In general the test components themselves do not know whether they are running in parallel with other test components or are part of a series Thus the most adaptable components are these test components as will be discussed further in the following sections As an implementation trick verification top builds a test by using a define called TEST This trickery set up by the makefile allows the Detailed Responsibilities of the Major Components truss run script to compile in a different test while leaving the rest of the build image the same for all tests This allows each test to be its own class inherited from test_base This cleverness helps one avoid a bad experience in the future Assume that your team had written on the order of 50 tests and then a new test was created that reguired a new subphase to be added to the dance Although the other tests did not need this new method you cannot add the default method This is because all the tests are implemented as a test class There is only one header test h and 50 different test cpp files By defining a base class and then having the actual test be an inherited class with a different header file one can add methods to the base without affecting the existing tests There is one more
12. Note that we do scope the code in an ALU namespace In the testbench C class we have all the components of the ALU interface layer There is a wire layer driver and monitor with their accompanying agents There is a generator and a checker The checker Theory of Operation is interesting because we have a legacy c model of the chip which will be used by the checker There is also a test_component class which runs a random number of operations through the chip And of course there is a alu_test class which builds a test_ component giving it the generator checker and driver from the testbench The following illustrates the wires used by the verification system ALU Example Wires and Objects alu testbench A x a o a WL ms U o Q faal n L alu driver Ww HDL testbench op_code 2 operand_b 3 alu monitor op_result 3 alu A operand_a 32 op_valid 1 op_done The driver and the monitor take care of the protocol into and out of the chip The testbench takes care of bringing the chip out of reset The remaining sections highlight some specific points of interest in the code The code itself being the first example is not that big If you want to follow the code through its execution start with the Truss verification top cpp then move on to testbench cpp and test cpp A Practitioner s Handbook
13. Truss an open source application framework We revisited the benefits of an OOP language such as C but stressed the need to keep things simple despite the power of this language to avoid writing code that is unnecessarily complicated We talked about the key algorithm of verification which the authors called the dance We showed how the dance is used by the verification top program torun a test We discussed the roles and responsibilities of the test testbench and watchdog timer the main parts of the top level dance We discussed the verification component abstract base class which provides pure virtual methods for the dance We then discussed the test_component and irritator classes includ ing their responsibilities and interfaces A Practitioner s Handbook 113 114 o o o o o Hardware Verification with C Truss F low Expensive solutions to all kinds of problems are often signs of mediocrity Ingvar Kamprad founder of IKEA H you ever bought and assembled a piece of furniture from IKEA In the store most of their furniture looks very simple but when you get it home and try to assemble it you realize that it s built from several smaller and often confusing pieces Even with IKEA s famous assembly instructions showing the intent for each piece graphically assembly can still be confusing Imagine how hard it would be withoutinstructions The authors have had to learn many verification enviro
14. Verification Framework 98 Then after the global logging objects have been created verification top allocates the top level objects The test is given a pointer to the testbench so that it can interact with the testbench It is also given a pointer to the watchdog timer in case a part of the test wants to force a shutdown or override the verification top default time outs The watchdog is given a pointer to an object so that it can call the final report method with a watchdog timeout string prefix At this point all the top level objects are constructed As part of their construction they are expected to have established default constraints Then verification top reads the dictionary file if it exists This is to allow the test constraints file to override any default settings put there during the construction of the test the testbench and their subor dinate components After initializing the random number generator verification top calls test gt randomize Once the test is randomized then testbench gt randomize is called At this point it is expected that the test and testbench have built their respective subcomponents and are ready to run the test The first step is the time zero setup method which is used to force wires and initialize interfaces prior to bringing the chip out of reset As expected the next step is out_of reset which is used to bring the chip out of its reset state and set i
15. continue until all generated data have been checked The Truss utility class error_threshold can be used to terminate the simulation in the case of excessive errors The Truss verification top does this Whew We made it through the first example Time for a coffee break and some foosball A Practitioner s Handbook 151 152 e o o o o o o Hardware Verification with C
16. customizable logging mech anism called vout which mimics C s standard streaming mechanism Teal uses a two level logging scheme as shown in the following figure In any code that needs to print information a vout object is created As many vout objects as needed can be created which is good because each vout object can have a relevant instance name Each vout object under the covers calls a global service vlog object This is done so that there is a single point of control where reordering demotion changing or deletion of parts of any message can be done di Although describing this capability completely is beyond the scope of this handbook subsequent chapters show several examples Logging Output Vout and Vlog Objects in Teal verification_top vlog Because vout is modeled after the standard C library stream std cout object vout directly supports the output of the standard types However by following a few simple guidelines you can print complex objects as conveniently as the standard types To end a message just call the Teal endm function To describe a multiline message just use endl like cout where needed and use a final endm at the end When you create a vout you give it a string that represents the functional area it is in You can then build any number of message statements For example note the following finclude teal h using namespace teal void ve
17. for other tests By creating irritators you can use the functionality of other tests as background activities In this way the chip is stressed more and more faults are found prior to production A Practitioner s Handbook 137 138 e o o o o o Hardware Verification with C Truss Example CHAPTER 8 I know that you believe you understand what you think I said but I m not sure you realize that what you heard is not what I meant Robert McCloskey Ci is tricky because we take the great ideas techniques and trade offs and actually make decisions We put fingers to the keyboard and decisions are made and trade offs are fixed in code Furthermore learning a new technique only makes the coding task more difficult An example or several examples can help put the technique into perspective This chapter is the first example of how to use Teal and Truss in a verification system It s useful to build and run some example code when learning something new So install the code on the CD and noodle around with it a bit You can add printf s and change the code a bit If you want use this chapter as a guide to some of the more interesting parts This chapter is not guite a map to the homes of the movie stars Instead it is more like a mariner s map It helps you to navigate in tricky waters Hardware Verification with C A Practitioner s Handbook 139 Chapter 8 Truss Example Overview This chapter provides a fir
18. generators and configuration objects to guide the randomization Initially you will probably have no constraints The test s constructor will create all the test components and irritators that it needs In the testbench randomize method randomize your local vari ables and then call randomize on lower level components as appro priate Your testbench may have configuration objects for each interface or feature that is used to configure the chip The test randomize method is similar in that the test randomizes each test_component it owns In addition the test may select some subset of all the components and irritators it owns Thetestbench time_ zero setup method is where you drive wires prior to letting the chip out of reset You may need to wait for the PLL to lock or set up sensor pins on the chip in this method The test time zero setup usually just calls all the active test component s time zero setup Thisisto allow test components that have a plug in behavior such as USB and PCI Express to perform their initial training To use this method is a judgment call as you may want to bring up an interface later in the simulation The testbench out of reset will bring the chip to a stable state that can accept register access If the team so decides you could use test out of reset to reset the chip The write_to hardware methods in both the test and the testbench are where you perform regi
19. important capability of a verification system Teal s vout class and the global service class vlog provide a uniform yet very flexible logging capability Almost all tests need to have control parameters set by code or files Teal s dictionary provides a global service for managing parameters The memory namespace of Teal can be used for both register access and internal chip memory accesses If reads and writes are extracted from the actual underlying mechanism different transactors can be used Random numbers are essential in verification systems Teal provides a stable independent random number generator We ended the chapter with a look atconcurrency and Teal s at function We looked at the semaphore class and the mutex class for coordinating different threads For Further Reading 88 n The Teal User s Manual available at www trusster com describes Teal in far more depth than this chapter does n For connecting the C code to the chip a great handbook is Principles of Verilog PLI by Swapnajit Mitra n A standard reference manual on PLI VPI is The Verilog PLI Handbook A Tutorial and Reference Manual on the Verilog Programming Language Interface by Stuart Sutherland For Further Reading m The pthreads package officially IEEE POSIX 1003 1c 1995 describes most of the capabilities that a multithreaded system needs A Practitioner s Handbook 89 900 0 0 0 e 0 Hardware Verification with C Truss
20. system The authors have found that sepa rating the test scenarios into test components has maximized the adapt ability of the system By using test components and irritators test writers have been able to minimize their assumptions and distractions and con centrate on exercising the chip Furthermore other test writers can adapt what was done in other functional areas and inherit irritators if they are not already present for use as background traffic This section describes the responsibilities and interfaces of the test_component and irritator abstract base classes The test component abstract base class 106 The test_component is an abstract base class whose role is to exercise some interface of the chip As discussed above this functionality has traditionally been included in the test The test_component describes the interface that all concrete implementations must follow In fact you may have several types of test component for a single interface for example a register read write one a basic data path one and an error case one The fact that these different exercises implement the same interface simplifies reasoning about them In practice most test components use a generator and a wire level object Sometimes they may also be given a checker depending on the designer s intent The test componentclassisnotdirectlyaverification component but it has all the same phases gt The test_component breaks down some
21. the checker that actually decides when the test is done This makes sense because the checker is the best able to judge what the chip did and when all the inputs have been checked But how does the checker know There are many possible ways but in this example the checker assumes that when the generated data channel runs dry the test is over This is a valid assumption as long as you make sure that the generator can always be one step ahead of the checker If your chip has any latency this is not a hard assumption to sustain The checker code is shown below void tutorial checker wait for completion completed flag wait note that the checking thread completed normally completed true and at the bottom of the main check loop 1 Note that an intergenerate delay should not affect when the expected data are sent to the checker The point is that even when delays are inserted this model should be valid A Practitioner s Handbook 149 Chapter 8 Truss Example Summary 150 if generated gt size completed flag signal return Remember that after the wait_for completion returns the top calls the report method in the test The test calls the test_component s report method which in turn calls the checker s report method The report method prints the state of the completed_ boolean In this way when you have multiple test components and the watchdog tim
22. the test just called the same named methods on the test component That s because verification has a fractal structure with repeated patterns The top level dance is repeated with a few changes in the test This time instead of verification top calling the steps the test does The test_ component also plays a role subdividing the start method into several lower level methods as shown in the following figure The run component traffic method has a standard implementa tion which calls randomize and then generate_ The random ize method has the same purpose it had for the top level components to randomize your random variables The next method called A Practitioner s Handbook 119 Chapter 7 Truss Flow 120 Test Component Dance Detailed Flow your new generator bfm checker The cc i your test componen N E time_zero _setup N E Performs the same your out_of_reset function as the top level components your write_to _hardware J LS m test_component start 4 test_component start_ Your I n yy Start your generator test your start_components_ BFM and checker test_component run_component traffic _ your randomize your generate_ test_component wait_for_completion A comp fa _completion J your_test_component wait_for_completion_ Vi test_component final_report
23. thread function can be made more object oriented but the base mechanism is a c function This allows you to decide how object oriented you want your threads It is possible that you may have several verification top types of functions and want to use that style for starting threads To wait for a thread to finish the thread join function is used How does Teal know which function to wait on The run_thread function returns a thread id which is passed to the thread join function Once you have started a thread you ll probably set some wires in the chip and then wait for some response To wait for a wire change use the at function which is intended to model the sensitivity list statement in Verilog This function operates on a sensitivity list of vreg signals and the signals are matched on the posedge negedge or any change Working with Simulation Events and Concurrency Take for example a statement such as the following at posedge clk change reset_n This statement would pause the current thread until either the clk signal changed to a one or any change occurred inthe reset_n signal Execution would then continue As you build layers above this low level wire layer the threads them selves need to communicate Teal s uses its signal and wait class sema phore to accomplish this As with threads the reason Teal provides these capabilities is to prevent a core dump in the simulator T
24. timer Each component has a specific role These components and their roles have been architected to allow a large amount of flexibility with a relatively simple interface These top level components and those the next level down are shown below Verification Component Hierachy verification top test gt watchdog timer test ee irritator component testbench 4 C HDL chip The top most C component is the verification top function whose role is to create and sequence the other components through a standard test algorithm The algorithm is explained in detail in the next section In addition verification top initializes all global ser vices such as logging randomization and the dictionary A Practitioner s Handbook 95 Chapter 6 Truss A Standard Verification Framework The watchdog timer is a component created by verification top This component s role is to shut down a simulation after a certain amount of time has elapsed to make sure the simulation does not run forever The testbench top level component is the bridge between the C veri fication world and the HDL chip world As such the testbench s role is to isolate the tests and test writers from having to know how C transactors traffic generators monitors and so on interact with the chip Whether a bus functional model BFM writes to registers or forces wi
25. where verification is different from software which generally does use destructors as part of the system design A Practitioner s Handbook 99 Chapter 6 Truss A Standard Verification Framework nameandalogger Theinterfaceforverification componentisshown below namespace truss class verification component public verification component const std string amp n virtual verification component virtual void randomize 0 virtual void time zero setup 0 typedef enum cold warm reset virtual void out of reset reset 0 virtual void write to hardware 0 virtual void start 0 virtual void stop 0 virtual void wait for completion 0 virtual void report const std string prefix 0 const std string amp name protected mutable teal vout log i Although verification_component is a base for the test and the test bench it is also useful as a base for other objects Detailed Responsibilities of the Major Components 100 The previous sections discussed the roles of the major components and how they were sequenced to run a test scenario This section dives down a level discussing in more detail the specifications of the major compo nents Because verification top was discussed in detail in the previous section it is not discussed further here Detailed Responsibilities of the Major Components The testbench class The testbench class has two main responsibilit
26. 0A the actual memory is accessed at 0x0A This is because of the add map that we performed This allows the rest of the verification system to read and write memory as specified in the chip s memory map Teal takes care of finding the correct memory bank to access and then removing the mapping offset Random Numbers It is important to have a stable repeatable seeded random number generator Teal s vrandom class provides independent streams of random numbers that can be initialized from a string or file There are also convenient macros for the most common random calls such as getting a random integer value or getting a value from within a range The rest of this section describes the reguired initialization of therandom generator and some simple examples Reguired initialization Before using any random numbers you must initialize the random number generator This is done by calling the init with seed function and passing it a 64 bit seed value It is recommended that higher level code keep track of this seed value and pass it to the random number generator To initialize the random seed generator you would call the following uint64 master seed master seed gets initilized by higher layer vrandom init with seed master seed After the random number generator is initialized it is ready to be used The examples in this handbook use the dictionary to get the master seed Using random numbers 84 Because integers ar
27. A Standard Verification Framework CHAPTER 6 Truss and verify Anon H you ever watched a building being constructed Early in the project when the frame of the building is just a skeleton it s not clear what the finished building will look like However as construction continues from the windows down to the cubicles that are our workplaces the intent of the framework becomes clear In fact a large part of the building s presence depends on the fundamental structure This same basic process occurs when we build a verification system Early in the project the application framework is built The result of years of best practices from both the verification and software fields Truss is an application framework for verification It is an implementa tion and therefore makes some decisions about how things should be structured With verification as with construction the framework sets the tone for the system Hardware Verification with C A Practitioner s Handbook 91 Chapter 6 Truss A Standard Verification Framework Overview 92 Truss is a layered architecture so you can choose how to implement the layers Although it makes very minimal assumptions Truss does provide some base classes and conventions as a guide This chapter presents three main topics n The roles and responsibilities of the various major Truss components n How these components work together n How you adapt this framework for your verificat
28. Final Report VW Legend you must implement PROJECT_HOME Vverification test_components your_test_component cpp base implementation provided TRUSS_HOMETinc truss_test_component h gt called from the same named method in test Set up and run your main traffic method Wait for your checker to complete S generate_ picks up the results of the randomization and interacts with the generator to exercise a feature or an interface of the chip Now it may seem strange that these methods are implemented like this However the idea is to separate the various concerns of the test compo nent starting randomization and generation This as will be discussed in Part III of the book creates more adaptable and less brittle code The organization also sets up the irritator making the transition from a fixed test to an irritator relatively painless The Irritator Dance The Irritator Dance The irritator is an inherited class of test_ component Its purpose is to generate background noise while the test concentrates on some specific area of the chip In some sense using irritators isa way to emulate the real world where many of a chip s features and interfaces are used simultaneously So what does an irritator add to or change from the test component Only one method is changed and two methods are added All these changes involve the new run traffic method shown in the figure
29. HDL memories put a teal memory note in the HDL Teal uses this call to make a memory_bank object for you The following example shows how HDL memory arrays can be associated with an address range and accessed An example of how to write memory transactors is in the UART example chapter A memory note example The following diagram shows a small part of a larger testbench structure This environment verifies a graphics chip that saves graphical texture information in its memory cache In order to speed up simulation back door loading of the texture into the chips memory is used Memory Bank Objects ci hdl GPU i map read write memory_cache memory_bank memory_1 Memory bank lookup memory_bank memory_2 memory_bank memory_3 To support direct memory access you need three things First you need the Teal PLI function teal memory note which is called for each 82 Accessing Memory memory register array to be accessed This registers the array with Teal and creates a memory object for that memory Then you need to deffine an address range for each memory instance to be used allowing Teal to translate from an address to a specific memory Finally once the address range is established you access that memory through read and write functions To do this in the environment pictured above an initi
30. Part ll An Open Source Environment with C Tie previous part of the handbook was a high level look at C and how to architect a verification system by using layers Now we focus on a specific implementation of such a system This part of the handbook introduces two open source libraries called Teal and Truss that together implement a verification environment that uses C The authors and others have used these libraries at several companies to verify real projects The libraries are free and open source because the authors feel strongly that this is the only way to unite and move the industry forward Locking up people s infrastructure is not the way to encourage innovation and standardization both of which are needed if the verification industry is to improve Consequently you ll find no simulator company bias in these libraries These libraries work on all major simulators In this part we discuss the following m Teal a C to HDL interface that enables C for verification n Truss a layered verification framework that defines roles and responsibilities Hardware Verification with C A Practitioner s Handbook 65 Part Il An Open Source Environment with C m How to use Teal and Truss to build a verification system a A first example showing how all the parts we talk about fit together 66 Teal Basics Coming together is a beginning Keeping together is progress Working together is success Henry
31. Reset Power on Reset Most chips have a power on reset seguence This seguence can be basic or rather complicated In this example we address a basic seguence The chip has a resef line which is pulled low to initiate a reset After the line is asserted the chip performs its reset seguence This chip only needs a fixed duration pulse The testbench class is responsible for bringing the chip out of reset The testbench methods time zero setup and out of reset are called by the top program to bring the chip on line In our ALU example we ll use a reference clock to count a number of cycles to keep the reset_n low Below are the snippets of code that perform the chip reset The methods are located in testbench cpp Note that the verification top provided a path to the top of the testbench the path is stored in the variable top_ This method is called first by verification top void testbench time zero setup teal vreg reset top_ reset reset 0 Then this method is called const teal unit32 reset count 10 void testbench out of reset reset r teal vreg reset top_ reset teal vreg clock top_ clock reset 1 for int 1 0 i lt reset count i teal at teal posedge clock reset 0 That s all there is to it Now the chip is ready for operation A Practitioner s Handbook 145 Chapter 8 Truss Example Driver and Monitor Protocol 146 Now that the chi
32. TL include directories This is so that the RTL files can be rooted in a place different from the verification directory The results directory is where you run the tests from It also can be wherever you want The authors generally put this directory in somenon backed up networked storage area that is independent of the source code control system In the handbook example the results directory is placed in examples alu at the same level as the verification directory The verification directory contains all the source code for the verification system The bin directory is there for the project s local scripts The authors usually put a setup script there and alias setup to it The other four subdirectories tests testbench vip and test_components are where the actual source files are The tests directory is where your test_name cpp and test_name h exist These files are used when you give the test lt test_name gt option to the truss script Use the config option to the truss script to select a directory The testbench top directory contains the C and HDL sources for the top level testbench If you have more than one chip in your simulation it may be useful to have testbench lt chip name gt directories The vip directory is where chip interface classes go There should be a subdirectory for each interface and major feature you need to test The idea is that the code in these directories is fairly port
33. This allows the test to report which checkers have completed and which have not helping to provide a clue as to why the simulation ran too long The test class is responsible for selecting configuring and running all the appropriate generators BFMs monitors and checkers It is also responsible for selecting the configuration of the chip to be used While you could directly implement the above responsibilities in the test class Truss encourages another style In Truss the test is intended to consist of a number of independent smaller components called test components These components are the ones that actually do the work the test s role is to create constrain configure and seguence the com 3 The watchdog timer is simple in theory but often hard to execute correctly To be sure it must have a clock and a countdown time but even this basic level can be problematic Should you use wall clock time simulation time or both Should the HDL timer be internal or external What resolution should it have Should the test be able to extend or communicate the expected time of the run The authors worked on a project where the final report code read the status reg isters to make sure that functional area of the chip did not have any errors However when we added a power down test irritator the read hung the sys tem It took us a while to find the offending code Detailed Responsibilities of the Major Components ponents as approp
34. a register whether the contents are individual bits or strings of bits Teal provides the capability to access both as the following example shows uint32 x RAND32 x Assign a random value to x reg a_reg x 32 reg a field a reg 32 25 bit 32 25 to a field cout lt lt a field A Practitioner s Handbook 75 Chapter 5 Teal Basics Registers have a number of logical and mathematical functions as well These functions help define the correct four state behavior for operations and make the registers similar to C s built in types The following is an example of some of the supported register operations vreg addr path address addr 2 addr addr gt gt 2 addr addr lt lt 4 if addr gt 0x64 if addr 0x1 Teal does something a little differently when comparing two registers Because reg is a four state variable Teal implements the operator as the Verilog triple equal in HDLs That is Teal looks at both the 0 1 value and the X Z value when comparing two registers Logging Output 76 Because a lot of debugging is done by reading simulation log files in order to see a progression it is important to organize simulations well In other words to enable postprocessing error counting messages and possibly filtering it is important to have a consistent message format Fortunately the logging facility in the Teal classes encourages such uniformity Teal comes with a standardized
35. able and may contain purchased VIP as well as project and company created VIP In our example there is only the alu directory The test components directory contains the scenarios that you want to run For this example we ll only run one scenario called test component A Practitioner s Handbook 141 Chapter 8 Truss Example Theory of Operation 142 We ll be testing a really basic ALU chip It takes in two 32 bit operands and performs a simple logic or arithmetic function We ll use a legacy c model for comparison with what the chip produces The output consists of a result and an operation complete status interrupt The test bench v will instantiate this ALU module and provide system clocks for the chip and verification system The main objects are shown below ALU Example Objects and Connections testbench v alu driver gt alu alu monitor y wire alu driver_agent v alu monitor_agent alu generator_agent 9 a 9 agent w alu generator alu checker C model L transaction alu test_component alu_test Because there is only one interface in the chip we ll just refer to the components by their functionality In other words we ll say driver although in a chip with many drivers we would need to say which interface we are talking about
36. age on the market has the OOP capabilities of C For example when a language that does not support operator overloading is used the generic operator or copy constructor cannot be used To provide this basic reguired functionality a common generic base must then be used Unfortunately this warps the framework and produces a fragile architecture mostly because of the unsafe type casting As another example with a language that has a A Practitioner s Handbook 93 Chapter 6 Truss A Standard Verification Framework compilation library such as current HDLs there is usually a failure to make a distinction between interface and implementation This leads to amore complicated framework as test writers must separate the interface from the implementation manually and repeatedly C avoids these problems Keeping it simple 94 A stated goal with both Teal and Truss is to avoid unnecessarily compli cated code C has many powerful features but many times they are not appropriate It is easy to get distracted with C techniques and forget that the real goal is keeping the whole team productive For example implementing a generic interface for a verification com ponent such as a transactor as a template can be tricky Sometimes using the template can be more complicated than simply replicating code Sometimes only a convention should be used An example of this is the generator concept One could define an abstract base clas
37. al line block is added to the memory model that is the model is instantiated as memory1 memory2 and memory3 above So part of the memory model looks like this reg 31 0 memory bank 1 1024 0 Actual memory array to register memory bank _1 with Teal initial teal memory note memory bank 1 reg 31 0 memory bank 2 1024 0 initial teal memory note memory bank 2 reg 31 0 memory bank 3 1024 0 initial teal memory note memory bank 3 As can be seen in the illustration the memory model gets instantiated three times as memory1 memory2 and memory3 In the verification top function the three memories get address ranges declared like this memory add map testbench dut memory unit memory 1 0x100 0x200 The following assums the subpath memory 2 is unique memory add map memory 2 0x201 0x400 memory add map memory 3 0x401 0x600 Now any test can access these memory spaces through simple read and write function calls Furthermore neither reading nor writing memory consumes any simulation time A simple memory access would look like this memory write 0x10a 22 i e Oxa in memory 1 22 if memory read 0x10a 22 vlog memory example 1 lt lt teal error lt lt At memory_1 0xa got lt lt memory read 0x10a lt lt expected 22 A Practitioner s Handbook 83 Chapter 5 Teal Basics Constrained Note that while the memory is written and read at 0x1
38. and the HDL signal and also figures out the correct bit length for the C class Working with a Using Teal When you create a reg object you don t supply a Verilog path as there is no connection to an HDL There are several ways to create a reg The default is just like in Verilog a one bit variable You can also give the reg an initial value in which case the register is 64 bits wide If you need a specific bit width you can specify that after the initial value Here is an example of how you would construct a vreg and a reg vreg chip register testbench chip data reg cpp_register OX7FFFFFFFFFFF 47 The first line connects the variable chip register to the HDL signal located inside the chip instance of the testbench The second line creates a 47 bit register array and assigns it an initial value reg or vreg Teal registers are written to act like built in types as much as possible This makes working with them easy and they support assignment to and from most other built in types for example assigning the value of an int to a vreg and vice versa would look like this int drive value 0x52571 vreg v_signal testbench chip signal Assign a value to HDL signal v_signal drive value AO Sample an HDL signal assign it to a sampled value int a_sampled value v_signal to_int The assignment above would work for reg s as well In functional verification it is common to access individual fields in
39. annels here because that s how we wanted to implement the agent layer This could have easily been a more generic producer consumer model or an event driven method but imple ment what feels correct for you All the examples in this handbook use channels Here are the classes for the driver and checker and the inherited classes for their agents namespace my interface class driver public void send data const my data amp typedef channel get lt my data gt input class driver agent public driver public truss thread public driver agent input drain drain drain must have a start to drain the channel void start for send data drain gt get private input drain class checker public check data const my data amp const results amp typedef channel get lt results gt checker in class checker agent public checker public truss thread public checker agent generated channel generated checker in actual generated_ generated actual actual A Practitioner s Handbook 131 Chapter 7 Truss Flow void start_ Check the data for check data generated gt get checker_in gt get private generated channel generated checker in checker in The authors realize that there is a lot of code to look at but just skim it over to get the general idea The general technique is to inherit a class add a channe
40. art ethernet data l start ethernet data 2 start pci express l start A Practitioner s Handbook 103 Chapter 6 Truss A Standard Verification Framework 104 void wait for completion ethernet data l wait for completion ethernet data 2 wait for completion pci express l wait for completion void report const std string amp prefix ethernet _data_1 report prefix ethernet _data_2 report prefix pci express 1 report prefix private ethernet _ test component ethernet data 1 ethernet _test component ethernet data 2 pci irritator pci express 1 In the above example the ethernet basic packet test uses three test components two of which are identical It connects up the appropriate testbench objects and forwards to every test component the following test calls time zero setup out of reset start wait for completion and report So why do testing in this more complicated manner In addition to the previously mentioned idea of simulating close to real world conditions an important reason is to maximize the adaptability of the test compo nents In the example above we used the same test component for both Ethernet ports Also when the test components take in only the parts of the testbench that they need they 1 make explicit what they are using and 2 minimize the assumptions on the rest of the chip This as will be highlighted in the single UART example in Part
41. ase could use the default parameter file and override the force parity error setting like this A Practitioner s Handbook 79 Chapter 5 Teal Basics 80 in parity error test parameters txt stop error probability range 32 81962 75 330 include default test parameters txt force parity error 1 The include default _ test parameters txt line above tells the dictionary to open the default test parameters txt file The force parity error 1 repeats the force parity error parameter and overrides the default value It is not always appropriate to use files to pass parameters Using files can be good if you need to have many different test parameters and a few basic tests However it can be clumsy to make sure the files stay with the respective test code Therefore the examples later in this handbook use the code mechanism Nevertheless including such files or even passing parameters on the command line can be done after most of the test is written without having to modify the test itself So how do we pick up the parameters The following is a complete basic example of how these parameters could be retrieved include teal h using namspace teal void verification top reads file shown above dictionary read default parameters txt vout log first parameter example log lt lt teal info lt lt force parity error is lt lt dictionary find force parity error lt lt endm Because most parameter
42. ct with a BFM or driver Note that a different but equally valid architecture would keep the wire layer components private in the test bench and sequence them by means of the top level dance This assumes that the testbench knows what subset of the BFMs drivers and monitors to start up The start method is used to start the test_ component s generator BFM and so on This method is implemented by a Truss utility class called thread A thread class runs another virtual method start in a separate thread or execution This allows a test class to do the obvious thing and just call start on all the test components the test uses A Practitioner s Handbook 107 Chapter 6 Truss A Standard Verification Framework Let s look at the start_ method as it is the main starting point for an interface of the chip The start_ method runs two methods a start components pure virtual method and a virtual run component traffic with a default implementation The idea behind the start components_ method is that you call start on your generators BFMs and so on as appropriate The examples part of this handbook contains examples of test_component The default run component traffic method calls randomize to randomize the test component and its components and then calls generate Inyourrandomize method randomize the data members that will be used by generate to cause some traffic to be generated In your generate
43. e bin subdirectories of each example on the CD has default values for the TEAL HOME TRUSS_ HOME and PROJECT HOME environment variables You ll need to set SIM and SIMULATOR_ HOME as appropriate for your environment A Practitioner s Handbook 123 Chapter 7 Truss Flow 124 Switches The Truss run script has a number of switches to control its execution Below is a table that expands on descriptions of the most important switches Switch help Function Prints longer help message test lt test name gt Runs the PROJECT HOME testcases lt test name gt test clean options Cleans appropriate selection of the system Default selection is USER The following options are available LOGS Deletes simulation log files CPP Deletes user compiled C code HDL Deletes user compiled HDL code USER Deletes all user generated code LOGS CPP HDL TRUSS Deletes compiled Truss files TEAL Deletes compiled Teal files ALL Deletes all of the above This switch can be repeated clean CPP clean HDL simulator lt SIM gt seed lt seed value gt Selects appropriate simulator from supported list If switch is not used then run script reads SIM If neither SIM or simulator is used script will fail Sets random seed to integer lt seed value gt run lt number gt Runs the selected test a number of times sim lt sim gt Builds and runs using lt sim gt as th
44. e simulator For a full description of all switches from a command line run the following STRUSS HOME bin truss help The First Test A Directed Test The Truss makefile As is customary in the coding world a makefile is used to build the objects and archives The Truss makefile may be a good starting point for your makefiles Almost all of the directories in the examples include a standard makefile located in the inc Makefile subdirectory of Truss As with the truss script this makefile is both too simple and too complex The makefile for three sources is shown below STATIC LIB LIB directory name SIM a INC I a referenced directory SRCS S SRC file one cpp SRC file two cpp SRC file three cpp include TRUSS HOME inc Makefile The first line identifies the output static library name The next three lines identify the source files The last line includes the standard makefile Most makefiles follow this form The Truss makefile has all the compiler switches to build the sources for a variety of simulators The First Test A Directed Test Because starting something new is not always easy this section helps make the process easier by addressing how a first test can be written in Truss This section concentrates on the steps you need to do and how a test can be built up from scratch The next chapter shows a complete first example and focuses more on the flow Your first test
45. e so commonly used here Teal provides a couple of macros to deal with integers After you have initialized the random Constrained Random Numbers number generator you can call these macros directly The most often used macros are RAND_32 and RANDOM RANGE which generate a 32 bit random value and a 32 bit value within a range respectively Here are some examples finclude teal h using namespace teal void verification top uint32 a_rand32 RAND 32 a rand32 uint32 a_random range RAND RANGE a_ random range 0 0x030837 vout log random number test log lt lt a rand32 is lt lt a rand32 lt lt endm log lt lt a random range is lt lt a random range lt lt endm When you want to create more elaborate random numbers you need to work with the vrandom class directly The vrandom class is a simple class that you can draw numbers from after it is created This gives you more direct control over the generation of random numbers The base vrandom class provides a uniform distribution but you can create your own classes to have segmented logarithmic or other distributions You would create an object for your inherited class and draw a number like this vrandom a_random some string some integer uint32 a random value a_random draw The macros use the ANSI standard FILE and LINE forthestring and the integer These parameters are hashed with the master seed and are used to initial
46. er seed Of course the numbers all have their own seed as well n The dictionary namespace This namespace is a global service that abstracts how to set parameters in your test It provides functionality to get and retrieve parameters from code the command line or external scenario files n The run thread function This function forks off a thread You ll use this whenever you have a function such as a generator or monitor that needs to operate independently of the test This function provides a base capability for building transactors drivers checkers and so on n The at function This function allows a thread to pause until any of the HDL signals has changed You provide a sensitivity list of vreg objects with modifiers such as posedge negedge or change Used with the run thread function it allows several independent tasks to run simultaneously All of these classes are described in the following sections along with the small requirements that Teal puts on the HDL testbench Teal needs to be initialized from the HDL testbench and a discussion of how to create the user code entry point function called verification top Using Teal Using Teal It s time to dive into some details regarding how Teal can be used for functional verification This walk through of Teal makes it easier to understand the real world examples presented in subseguent chapters while illustrating how Teal can be used in y
47. er shuts the simulation down you can tell which checkers have not completed This chapter is a tutorial on the Truss framework We exercised a simple ALU but implemented all the parts of a Truss based verification system The main objects and their connections were shown The directory structure was introduced so we can find our way around the code Then the chip and the HDL connections were shown After laying out the verification system and showing how to run the example we looked at how the chip was to be brought out of reset We did a guick side tour to talk about how to run the example Running the example produces many log messages but this is probably a good thing when one is learning We showed how to bring the chip out of reset and how the driver and monitor interfaced with the chip One point to note is that while this interface consisted of only a few wires many interfaces in real protocols are this small Of course your code will be more detailed We looked at an important part of the verification system the checker In this example the checker used a c model to check that the chip was working correctly The last thing we looked at was how the test stopped We looked at the normal path ignoring the watchdog timer We showed how the checker was in charge pausing the end of the test until all the generated data had Summary been checked The interesting point to note is that the checker may have had errors but it will
48. es mechanisms to connect wires and registers in the HDL simulation so they can be used in C code as though they are built in C variables The vreg class is inherited from the reg class m The vout class This Teal class is used for logging to help trace what happens during a simulation Modeled after the standard C cout object the vout class provides the ability to report for example debug error and other informative messages in a consistent format that is coordinated with HDL outputs n The vlog class This class is a global resource that coordinates all the logging from your C code It receives all vout messages l This is not a complete reference manual but rather an overview of the capa bilities of Teal A Practitioner s Handbook 71 Chapter 5 Teal Basics 72 from the simulation and implements a filter chain so you can add useful features such as replicating output to a file and removing messages or parts of messages m The memory namespace This namespace provides an abstract interface for reading and writing memory Internally a group of memory banks are used to handle memory read and write requests providing great flexibility a The vrandom class Because using random numbers for test values is a staple of modern verification this class is Teal s stable random number generator Though small it provides thread aware independent streams of stable random numbers that can be guided by a single mast
49. hannel get This class adds the storage for the actual data as well as The Second Test Adding Channels and Random Parameters the signaling and mutual exclusion mechanisms In addition channel also supports a depth concept for designs that want to implement back pressure in that way The interface for a channel class as well as the base classes are in truss inc truss_channel h on the CD The channel class also provides for other channel put objects to be attached to a channel This allows the data of one put to be replicated across many channels The common use for this is when a generator creates a data item and both the checker and BFM should get the data It is also useful if there are multiple listeners to a channel such as in an Ethernet broadcast or multiple monitors for a data interface Building the second test Now that we have channels let s use them for the agents This section is a bit high level because every situation is different We ll give general direction but after you read this chapter take a look at the next chapter for a first complete example Let s say that you are working on a chip interface called my interface You might have a generator that looks like this namespace my interface class my data class generator public void generate make one virtual void post generate const my data amp 0 We are concerned with the post generate method This is a pure virtual method
50. he main reason for the test has been achieved For example you can have the main goal be a test component perhaps one that generates a fixed but randomized number of packets through a particular chip interface The global goal in this case would be for the test component to achieve completion Here is how the test code might look void noisy packet test wait for completion assume the data members include base packet exerciser the test component of interest and some std container class with a list of irritators basic packet exerciser gt wait for completion std for each irritators begin irritators_ end stop generation std for each irritators begin irritators end wait for competion Ignoring the nontrivial constraining selecting and creating of the test component and irritators what is accomplished in a few lines of code is a shutdown sequence that is powerful while being a fairly simple idiom Note that a verification team could decide to use only irritators in their implementation In that way when to stop the test can then be determined by looking either at a checker or possibly at elapsed simulation time Summary The complex part of the test would then become the randomization and selection of irritators The authors have worked on a variant of this methodology and the resulting verified chip was a first silicon success Summary This chapter introduced
51. he example code The test constrains the test component with respect to the number of times the generator is called Of course this specifies the number of operations sent to the arithmetic logic unit ALU The code is shown below teal dictionary put test component gt name _min operations 4 teal dictionary default only teal dictionary put test component gt name _max operations 10 teal dictionary default only Note that the name of the test_ component is used This allows the test to pick any name for the test_ component and still have the code work However be careful with the spelling of the knob variables They must be spelled the same in both the find and the put routines in order to make a connection Now that the randomization and knobs are connected we have completed writing the second test In some ways this test is rather sophisticated It uses the Truss framework and adds agents by using channels to connect the wire layer classes to the transaction layer classes The testbench created and wired up the generator driver monitor and checker The testbench can bring the chip out of reset and start the monitor The test itself is rather reasonable It creates and connects the test component to the generator driver and checker in the testbench A Practitioner s Handbook 135 Chapter 7 Truss Flow The Remaining Tests Mix and Match Test Components 136 So now what do y
52. herit from this test component later to sequence this pattern any number of times and possibly change the randomization constraints as well So why have two separate methods By separating the randomization from the generation phases one can inherit different classes that either 1 have different randomization characteristics for example logarithmic distributions of the burst length or a pattern or 2 send the data through a filter first then to the generator So now that the transaction has been generated what should the wait for completion method do Because the generation is occur ring in another thread there should be a condition variable to commu nicate when it is done So the code might look like this void AHB test component wait for completion done _ wait Test component housekeeping functionality The test component class also provides a basic housekeeping boolean that tracks when youreturnfromthewait_ for completion method This allows the report method to determine whether you have con sidered the work of the component to have been completed or not This can be very useful in a timeout situation to see which components have not completed What you decide to do in the wait_for completion depends on how you view your test component One view is that it is a traffic generator only which can complete when the generation of traffic has been gueued It is then up to the testbench or test to deter
53. ic responsibilities for control and functionality test or testbench are of course up to the verification team As an implementation detail Truss provides only a testbench base class What verification top builds however is a testbench object You must provide a testbench h which declares a testbench class You will probably also have a testbench cpp which is inherited from truss testbench base A Practitioner s Handbook 101 Chapter 6 Truss A Standard Verification Framework Watchdog timer Test class 102 The watchdog timer component is responsible for providing an impo lite shutdown if the test has executed for too long The timer has two timeout mechanisms one triggers when the watchdog HDL timer trig gers and the other triggers after the first trigger has occurred The watchdog timer uses the dictionary to get its timeout values which are sent to the HDL on time zero setup The start method starts the timers The HDL watchdog uses an internal timer If it were to use a passed in clock that clock may inadvertently be shut off Once either timer triggers the watchdog HDL timer is notified and a second timer is started If this timer expires finish is called This might happen for example if there is some code in the report that is still reading registers but the chip is unable to respond After the watchdog is notified of an HDL timeout the report method in verification top is called
54. ies One is to isolate the test writers from the actual wire interfaces The other is to provide one stop shopping for all the generators checkers monitors configuration objects and BFMs drivers in the system The reason to put all of your components into a single object is to facilitate the adaptation of compo nents into multiple tests In this way a test writer can see all of the possible building blocks that are available The testbench class can be a passive collection point for all these components or it can play an active role in bringing the chip out of reset generating traffic and knowing when the test is done In theory only the global functionality should be handled by the testbench For example the testbench probably should bring the entire chip out of reset while the test can bring separate functionality out of reset In practice the test and the testbench share the work In general it is better to let the test or test components control the simulation This is because a test or test component can then be adapted for several different types of tests A more active testbench may as a counterpoint simplify a large number of tests in a way that a test base class cannot because the testbench has direct access to all the chip s wires Understand that the more test knowledge a testbench has the more all tests must act the same or have control over that testbench s functions This can be good or bad The specif
55. ing the first test we ve counted one Now we will count two The next section will cover the many In this the second test we ll get more sophisticated We ll add the agent layers and also add the generator and checker These are the steps you need in order to create more advanced randomized tests You will probably create several directed tests before you need these additional features but because this is a book we need to keep moving along Remember that the generator and monitor generally have pure virtual methods to communicate the results of their work We ll add our agents to these methods There will be an agent for the generator the driver BFM the monitor and the checker Why all this complexity Because there are many interconnection technigues each one involving some A Practitioner s Handbook 127 Chapter 7 Truss Flow architectural trade offs These trade offs are talked about at length in the OOP Connections chapter in Part III of this handbook To make the connection between the agents we ll use a Truss channel So let s digress a bit and look at a channel The channel classes 128 Verification systems have a lot of producer consumer relationships For example a generator can be considered a producer and a BFM considered a consumer However it is a good idea to minimize the knowledge and assumptions of the interface between these two loosely cooperating objects One way to decrease the c
56. ion Of course in reality these threads only execute in response to a chip wire or register change However by driving wires and registers the threads do in some sense control the chip Teal is unobtrusive it does not get in the way of your C or C structure You don t put Teal calls everywhere you want to sample or drive a signal so Teal is also unobtrusive in the HDL code The authors realize that many companies have developed their own version of an HDL to C C interconnect We encourage those compa nies to contact us and share their experiences so Teal can be made better This is one of the reasons why Teal is open source What Teal provides 68 Teal enables functional verification by providing connections to HDL signals and allowing actions based on changes in the HDL simulation It encourages the development of independent generators checkers drivers and monitors by providing management for user created threads that execute concurrently with the HDL simulation Teal provides repeat ability and constrained random number generation as well as a simple interface to pass in runtime arguments either through the code or com mand line or through scenario text files Teal also provides flexible message printing This functionality provides the basis for functional verification but it serves as only a small part of a verification project You must still write code that stimulates the design checks the output and cont
57. ion system This chapter builds on the two previous chapters of the handbook It implements an open source verification infrastructure based on the dis cussion in the Layered Approach chapter It also uses the Teal library described in the last chapter as a connection between C and the simulation Teal provides the fundamental elements of a verification system and supports a wide array of methodologies Truss on the other hand pro vides the infrastructure layers above Teal adding a set of classes tem plates idioms and conventions to facilitate the construction of an adaptable verification system One of the tricks in building a reasonable system is to find the Key algorithm The rest of the algorithms can usually fit around that key algorithm For example in a video editing program the key algorithm is all about getting the pace of the edits right When you watch a movie that happy sad or scared feeling you get comes from how well timed and precise the changes in scene are The authors having developed software for video editing systems know that in this domain the key algorithm is implemented by adjusting the edit points of a few seconds of video while the video is constantly looping around those edits This is not a trivial thing to do because multiple streams of video and audio k Okay emotions also come from the music but everything works together General Considerations possibly with software algorithms to impleme
58. ize this particular random number generator You may want to pass in your own values For more details see the reference manual available on the CD A Practitioner s Handbook 85 Chapter 5 Teal Basics Working with Simulation Events and Concurrency 86 Chips are massively parallel which means they have many interfaces working at once So when we test them we need parallelism in testing as well Teal provides the ability to start a thread and if you want wait for it to complete Why does Teal provide this capability when there are already several packages both operating system specific and in public domain Most of the current simulators will core dump if any thread runs after control returns to the HDL simulator Teal s threads ensure that this does not happen It is this capability that provides the illusion that the C C code is in control of the simulation However having many threads of execution is no good if we cannot pause for some change in an HDL signal or to wait for another verification thread Fortunately Teal provides this capability As soon as you have threads you ll need a mechanism for exchanging events between threads Teal calls this mechanism a semaphore Let s back up a bit and talk about running a thread The Teal function run thread allows you to call a c function in a new thread of execu tion This is exactly how Teal starts your verification top function The next chapter shows how the run
59. key algorithm is in checker cpp and is shown below void alu checker start_ for operation gen generated gt get teal uint32 actual actual gt get if alu model gen operand a gen operand b gen op code actual log_ lt lt teal info lt lt EXPECTED sent lt lt gen lt lt lt lt actual lt lt endm else log_ lt lt teal error lt lt sent lt lt gen lt lt l lt lt actual lt lt endm if generated gt size completed flag signal return The checker works fine as long as the operation done is in synch with the result However the checker can be wrong if the monitor misses a result or somehow inserts an extra one We could have registered the chip inputs at the same time as we got the results However by doing this we 148 Completing the Test make the assumption that there are no gueuing or pipe stagesin the ALU This assumption works fine for our example but it is probably not valid for most ALUs Completing the Test When does the test stop When verification top calls the test s wait for completion which in turn calls the test component s wait for completion In turn the test component s wait for completion calls the checker s wait for completion The authors agree that this sounds silly but in the later examples we actually do a bit more than just forward the call In the end of the forwarding chain it s
60. l and append agent to the name After the agents have been built they should be added to the testbench The testbench holds the generators drivers monitors and so on The test on the other hand holds the test components Building the second test s test_component 132 The test_ component is relatively straightforward A test_ component constructor takes in the parts of the testbench you need Remember the entire testbench is not taken as a parameter because then we would have to make assumptions about the name of the parts we needed Also by taking in only the parts we need several of our test components can be used in the same chip The most likely candidates for the constructor s parameters are the generator the driver and the checker The rest of the test component usually just forwards its calls to the appropriate objects An example test component is shown below namespace an interface typedef class bfm typedef class generator typedef class checker include truss h The Second Test Adding Channels and Random Parameters namespace an interface class a test component public truss test component public a_test component const std string n generator g bfm b checker c virtual void time zero setup bfm gt time zero setup virtual void out of reset reset r bfm gt out of reset r virtual void randomize next section virtual void write_to hardware
61. ll a user defined function called verification top The verification top could be as simple as the following finclude teal h void verification top teal vout log first code log_ lt lt Hello Verification World lt lt teal endm The verification top must be defined by the user or Teal won t link It normally instantiates other classes and calls their methods Sub seguent chapters will show example of this Teal s reg class implements a four state logic as well as all commonly supported HDL operations while making sure that X s and Z s propagate correctly The class supports addition subtraction shifting boolean operations and comparisons As in any HDL bit fields or subranges are supported and they can be on either side of the egual sign This will be described in more detail in the next section The vreg class builds on the reg class and adds the connection to an HDL simulation All events that happen to a wire reg in either the C or HDL simulation get reflected on both sides The vreg is one of the most used classes in Teal as it serves as the connection point between HDL and C Creating registers Creating either a reg or vreg is easy However here is one of few places where the two classes differ When you create a vreg you supply the string HDL path to the corresponding HDL register port or wire you want the variable to reflect Teal then automatically links together the C variable
62. m flooding the chip There are many ways to get this delay For example in one solution the generator and attached BFM driver could execute the generate request as soon as it is called and thus take simulation time In another solution the way to get a delay would be to have a fixed depth generator and BFM driver channel This would put back pressure on this generate loop In still another solution the generator could have a delay in clock cycles before returning Any of the above solutions is acceptable but there is yet another choice That option is to have the irritator itself provide the delay mechanism 7 This method is supported in Truss s channel class A Practitioner s Handbook 111 Chapter 6 Truss A Standard Verification Framework 112 The intergenerate gap is a virtual method allowing you to imple ment an irritator based delay This allows the irritator to decide on the throttle mechanism Different subclasses could implement different pol icies For example an irritator could wait for a variable number of clock cycles Another example would be to measure some parameter on the checker such as packets in flight As always the team must decide what is appropriate Using the irritator The irritator continues this generate wait loop until a stop generation is called But how do you decide when to stop the irritator The answer of course is When the test reaches its goal One goal could be that t
63. mine when the chip has processed all the data This will most likely involve a checker or monitor A Practitioner s Handbook 109 Chapter 6 Truss A Standard Verification Framework Another view is that your test component represents a generate and check path through the chip In this case the completion of test_component signifies the completion of the entire exercise The examples in this handbook use this view As always the team must decide which view is better for their project The irritator abstract base class As discussed above the test_ component is set up as a one shot traffic generator This works for tests that are directed and for tests where the completion event is predetermined that is tests that Know before the start call what the end conditions are However sometimes it is not good design to have the test_ component determine when completion is achieved This is the case when for example you want to achieve a certain metric and the measurement is not appropriate information for the test_ component For example you may want to send 100 bursts of some AHB traffic While this could be included in the ahb_test component you might not want to measure completion by 100 bursts all the time Instead you might want to write a test that looks at the number of hits each slave device gets and stop the test when all slave devices have been targeted As another alternative you might want a test to run until some c
64. ndomize anything yet Doing the checking can be tricky so let s worry about that last We ll probably be looking at waveforms for the first few days anyway Now build a test that has your test_component as a data member Initially have the test call the same named methods on your test compo nent Note that the wait for completion method probably just returns if you implemented the start method However if you used the generate_ method of the standard test_component you ll want to trigger a condition variable at the end of your generate Then the wait for completion would just wait for the signal to be triggered as shown below class your test component your other code here private teal condition done The Second Test Adding Channels and Random Parameters Then in the last line of the your test component generate method do this void your test component generate your directed exercise code here done _ signal Then your wait for completion would look like this void your test component wait for completion done _ wait That s it You have created your first Truss based test The Second Test Adding Channels and Random Parameters 66 Software engineers count one two and then many This is because only the first three times they use a technigue are significant After that everything looks like many By writ
65. nments through the years and this has often been a very confusing experience What seems like a great concept with a well defined structure at a high level of abstraction is often obscured by troublesome details when you first try to implement it Many times the confusion is increased because of a lack of description regarding how the high level ideas are actually imple mented To help reduce the confusion around Truss this chapter describes the dance in more detail Hardware Verification with C A Practitioner s Handbook 115 Chapter 7 Truss Flow Overview This chapter looks at how the dance described in the preceding chapter is actually implemented It shows the order in which each method is called and describes the files to find the method or its base The chapter then looks at the structure for the major components of Truss First to be described is verification top the first function called in Truss and the base of the dance Following this is a description of the methods and their class through which files are called for each step Then the test component is described This component follows a dance similartothatofverification top but fora different set of classes and files The irritator class is described next While similar to a test_component irritators have some unigue method calls worth point ing out The last part of the chapter talks about steps that need to be taken to build a new Tru
66. not need to use the global filtering mechanisms of vlog Instead you can turn off the display of parts of a message directly at the vout instance This is described in the Teal reference manual available on the accompanying CD Most verification systems have several levels or types of messages Teal being no exception uses the following general categories n teal info Used for standard messages m teal debug lt level gt Used when a test wants to display a little more diagnostic information This is a level sensitive output the vout class has level setting methods and accepts a level for debug messages The message is displayed only if the level of the message is less than or egual to the level that is set n teal error The error type is used when the chip s expected behavior is different from the expected a teal fatal This more severe error type ends the simulation after displaying the message Examples of the above are provided in later examples Using Test Parameters Using Test Parameters It is often important in functional verification to provide test parameters These are freguently used among other things as constraints for random tests For example a single test case may have several different sets of constraints each of which covers a selected range of parameters or directs the test into interesting corner cases Because such parameters are commonly used Teal provides a standard flexible way
67. nse lt lt endl stimulus sent pop front It should be noted that the above example puts all code in the verification top function However this is not recommended for 70 Teal s Main Components real projects where a lot more structure is needed as will be shown throughout this handbook The point here is that if you use Teal you won t end up with code that is hard to understand Teal is straightforward In this example we randomized a stimulus input and applied it to the chip then just printed the response In a more realistic test you would have a model of the chip and compare the results to that model Teal s Main Components Itis important to decide on a common currency when designing a class library The rest of this chapter describes the common currency of the Teal system that is the fundamental building blocks of Teal based verification The following is a summary of themostimportant classes andnamespaces of Teal more detail is given in the following sections n The reg class This is one of the most basic classes in Teal Its main purpose is to provide arbitrary length four state 1 0 X Z registers with corresponding operations The reg class is useful for performing algorithms in the precision of the hardware It also provides register slicing operations n The vreg class This is probably the most commonly used class in Teal as it connects C code to the HDL The vreg class provid
68. nt effects are changing as the user is adjusting the edit points In the verification domain the key algorithm is the seguencing of the various components of the system The authors refer to this as the dance as there are usually a few interacting components involved As we talked about in the Layered Approach chapter the top level dance takes place between the test the testbench and the watchdog timer Truss implements this dance inthe verification top function but Truss does not stop there The authors believe that this dance is the key algorithm in several layers of the system so we created a verification component abstract base class Also we created test_component and irritator base classes to be the top at the interface and feature layers of the system Recognizing and reusing the dance is a significant part of Truss This chapter explains the major components of Truss providing code examples where appropriate Subseguent chapters provide more detailed examples General Considerations The authors have worked on several different implementations of veri fication systems before Truss was available While at a high level veri fication systems can be described uniformly the language used to build them has a lot to do with how a specific framework is constructed Using a language other than C Itis possible to build an OOP based verification framework in languages other than C but no other verification langu
69. o communicate among threads two threads need to share a semaphore instance Then one thread or any number of threads pauses by means of a semaphore wait call Another thread eventually gets some data or reaches some condition and issues a semaphore signal That call unblocks the waiting thread Because you cannot know the order of the thread s execution a wait may occur after the signal has occurred The decision regarding whether a thread should honor this previous signal is up to you If you want to wait for signals that occur only at the current simulation time or later use the wait_now method There is one last point to make about threads Sometimes you want to make sure that only one thread is using a piece of code at a time This is common in a BFM that is accessed directly as opposed to when a queueing mechanism is used In this case the BFMs send read or write methods must use a mutex class A mutex is a mechanism that ensures only one thread uses some shared resource at a time as will be described in the OOP part of this handbook A Practitioner s Handbook 87 Chapter 5 Teal Basics Summary This chapter introduced an open source C to HDL interface called Teal We talked a bit about how Teal starts up and is connected to your testbench Teal s register class was covered along with its inherited class vreg These two common currency classes are the backbone of the interface to the HDL Logging is a very
70. of working with them Test parameters can be defined by means of text files code or command line entries Teal handles simple integer and string parameters as well as complex parameters The functionality of Teal s parameters is defined in the dictionary namespace Teal maintains a list of parameter names and values so that a test for example can guery the dictionary and recover the value When you call the dictionary read std string function Teal reads a text file takes the first word on each line as the parameter name and saves therest of the line as data for that parameter A special keyword ffinclude is used to open other files from within files If a parameter is repeated the last definition is saved In addition to using files you can also use code to add parameters When you do this you have the option of replacing an entry or not Parameters can also be entered on the command line In this case they override any parameter set by a file or the code In this way a parameter can have a default value but still be overridden by a script As an example let s suppose we are testing a UART interface We have a default parameter file that sets up default constraints and then each specific test overrides a few values as well as defines its own parameters The default parameter file could look like this in default parameters txt force parity error 0 dma enable 1 baud rate 115200 921600 A specific parity error test c
71. ou do after creating this second more sophisticated test You do what we verification engineers always do create more tests As these tests are being written new test components will also be created some of which could be used in several tests Deciding which test components to adapt to different tests is the major activity besides writing more tests after you have written the first two tests This is the many count that we talked about earlier Of course you ll be doing other test related activities such as adding randomness to the existing tests and looking over your verification test plan to make sure you know when you re done And how do you go about adapting a test component from one test into another You could just put the new test component in the test and wait until both of them are completed However as explained in the Truss Basics chapter there is another way use the Truss concept of irritators and warm over or recrystallize the existing test component to an irritator Converting the test components to irritators usually justinvolves deriving the existing test component with the truss irritator component Then the appropriate methods will be overridden and the only method you have to writeis inter_generate_gap_ There are many ways to implement a gap from the simplest pausing a number of clock cycles to the more complex using back pressure and bursty traffic If the checker were inherited from Tru
72. oupling between these components is to use an intermediary object An intermediary object would allow the two communicating objects to be anonymous or separated in time The concept behind this object is called a pipe mailbox or channel Truss uses the term channel Truss separates the roles of producer and consumer by having two abstract base classes channel get and channel put This clarifies the roles of the two communicating objects For example the constructor of a gen erator would take in a channel put class because it puts data into a channel A monitor s constructor would also take in a channel put class A BFM or checker s constructor on the other hand would take in a channel get class In Truss the channel get and channel put classes are templated This is one of the very few places where Truss uses templating Don t worry if you don t understand all the details of the code in a first read through these templates are not hard to use as will be shown in the chapter discussing a single UART example The reason we use a template is to encourage a strongly typed channel Another reason is to allow you to have the choice of using pointers or actual objects and data in the channel In general the authors use pointers to objects only when virtual methods are needed Otherwise we put the objects themselves in the channel This simplifies any memory manage ment issues The channel class joins the two concepts channel put and c
73. our environment Initialization Let s start at the beginning For Teal to be used it must be initialized from the HDL This is done through an HDL function call that launches Teal When Teal starts up it initializes itself then calls a user provided function called verification top Verilog is the HDL of choice in this handbook Because Teal was devel oped to work with Verilog many of Teal s syntax and naming conventions mimic those of Verilog Teal uses the Programming Language Interface PLI 1 0 or 2 0 to connect C code to HDL simulators To this end you must put a PLI call somewhere in the HDL code to start Teal This call is normally put in an initial block at the top level testbench but it can be put anywhere and called at any simulation time The call is called Steal_top and other than a call for back door memory access it s the only required HDL call for Teal Your Verilog testbench should include the following module testbench initial Steal top endmodule That s all there is to it Teal will now start and run your test 2 Unfortunately while a Teal for VHDL is in the works it wasn t finished in time for publication Contact the authors at www trusster com if you are inter ested A Practitioner s Handbook 73 Chapter 5 Teal Basics Your C test Registers 74 When the simulation begins the call to teal_top causes Teal to start the threading system and thereafter ca
74. overage occurs which could be any of the previous scenarios or could involve some internal state in the arbiter The irritator inherited from test component is used for situations such as these The interface is shown below namespace truss class irritator public virtual test component public irritator const std string amp n virtual irritator void stop generation generate false protected virtual void start virtual void run traffic 110 Test Component and Irritator Classes virtual bool continue generation virtual void inter generate gap 0 bool generate he The irritator overrides the run traffic method of the test component base class It sets up a loop calling the one shot randomization and generation in the test component s run traffic methods The implementation is shown below virtual void truss irritator run traffic while continue generation test _component run component traffic intergenerate gap The method continue generation just looks at a boolean which is toggled to false by a call to the stop generation method This allows an external class to stop the continual loop of randomization and generation Note that there is a new virtual method in the irritator class called intergenerate gap Because the irritator is continually generating traffic you might need a delay mechanism to prevent the generator fro
75. p is out of reset we can start to drive it This chip has a simple protocol for sending operations to perform Assuming op_ done is asserted the driver puts op code operand a and operand b on the wire Then it asserts do_op and waits for op done to be asserted The code to do this is in alu driver cpp and is shown below void alu driver send operation const operation amp op op code_ op code operand a_ op operand a operand b_ op operand b op valid 1 at posedge op done wait until accepted op_valid 0 at negedge op done 5 The variables above with the trailing are data members and are Teal vreg objects that are connected to the chip The monitor code is fairly simple as well The monitor uses a Truss utility thread class called run loop It consists of two methods loop condition and loop body which are run in a separate thread The idea is that a large number of monitors are infinite loops of wait for trigger and then gather data This class represents that concept The loop condition method of the monitor waits for op done to go high The loop body method then copies the result into a local vari able It then calls the pure virtual method operation completed to connect to the monitor agent Here is the code in cpu monitor cpp void alu monitor loop condition at posedge operation done _ bool alu monitor loop body receive completed
76. part to a test that needs to be discussed Often a test is made better by the addition of random background traffic This traffic be it register reads and writes memory accesses or just the use of other interfaces can uncover corner cases such as bus contention that would not be found otherwise These background traffic test components are called irritators and inherit from the test_component class They differ from the standard test component in that they continue their traffic generation until told to stop by the test Test components by contrast decide themselves when they are done as determined by specified metrics such as a stop time or the number of packets to send Irritators will be describe in more detail later in this chapter With background traffic irritators the testis written essentially as before The exception is that the wait_for completion of the test calls the primary test components wait for completion When the primary componentreturns thetestcalls stop generation onalltheirritators and waits for them by means of their wait for completion Then the test returns control to user main This is explained further in subseguent sections and in the examples in the chapters that follow A Practitioner s Handbook 105 Chapter 6 Truss A Standard Verification Framework Test Component and Irritator Classes As discussed in the previous section test component based design is central to a Truss based test
77. positive edge of the clock and generates a response on the negative edge To make things interesting let s assume there is a three clock latency from the stimulus to the response A Practitioner s Handbook 69 Chapter 5 Teal Basics Here s how Teal might be used to drive the stimulus and get the response include teal h using namespace teal include lt degue gt void verification top const int latency 3 const int number of iterations 10 teal vreg system clock testbench reference clock std degue lt integer gt stimulus sent vreg stimulus testbench stimulus vreg response testbench response for int i 1 i lt number of iterations i drive the stimulus to the chip and remember it at posedge system clock nteger stimulus int RAND UINT32 stimulus int timulus stimulus int drive value to the chip i s save value sent s timulus sent push back stimulus int Read from HDL register response and print result at negedge system clock if i gt latency Note response in line below reads from HDL cout lt lt For stimulus lt lt stimulus sent front lt lt the chip produced lt lt response lt lt endl stimulus_sent pop front need to collect last responses for int i 0 i lt latency i cout lt lt For stimulus lt lt stimulus sent front lt lt the chip produced lt lt respo
78. r there is no other choice At the top level one must trust that the lower level objects do their jobs Note that this usually means that in flight data must be weeded out as the checker proceeds Now if the watchdog timer triggers a different path is taken The watch dog immediately calls the report method on verification top Note that the watchdog itself uses an HDL based timeout so that if the report method hangs the simulation still ends The verification_component Abstract Base Class While the test and the testbench are completely different classes as far as their roles and responsibilities are concerned their interface to verification top is the same For this reason a common class was created This common class used as a base for both the test and testbench is called the verification component The verification component is an abstract base class As such it provides pure virtual methods for the dance described in the previous section In addition verification component provides a constant 2 The authors have tried using the destructor as the final report mechanism In practice however this becomes a difficult part of the design This is because some destructors try to access deallocated memory or other objects that have already been destroyed It then becomes tricky to shut down the simulation in the correct order so as not to cause a crash or hang and still get errors print ed out This is one area
79. reasonable run script and Compiling and Running Tests rudimentary makefiles are provided They are a good starting point for a run script and provide enough functionality to handle the examples in this handbook It is the authors hope that through community effort these scripts can be fleshed out into something better Truss run script The Truss run script controls which files are compiled and run It is written in Perl and has a number of switches that controls its actions The script will first compile all the C files then compile all the HDL files then link all files into a single executable and finally launch the simulation After the simulation finishes it checks the status of the test run This scriptis used to build and run all the examples on thecompanion CD The script is written in Perl and can be located at TRUSS_HOME bin truss Truss uses some environment variables to understand its environment By using environment variables instead of tool_ rc files for example the system s assumptions are both obvious and flexible Truss uses only a small number of environment variables as listed below Variable Function SIM Simulator name such as ncsim mti aldec or vcs SIMULATOR HOME Path to the simulator install area TEAL HOME Path to Teal s source files TRUSS HOME Path to Truss install area PROJECT HOME Path to top of the current verification project The file named setup in each of th
80. res should not be of concern to the test writer In addition the testbench holds the configuration objects of the chip This is needed by the BFMs transactors and similar agents to be able to configure the chip correctly There is probably a configuration object for each interface of the chip For chips that contain internal functions such as dynamic memory allocation DMA there may be a configuration object for each function The last but certainly not the least top level component is the test itself whose role is to execute a specific functionality of the chip It does this by using the testbench created BFMs monitors and generators The test is responsible for choosing among the testbench s many configurations and capabilities and exercising some subset of the chip s functionality In general the test contains very little code This is because any code it contains may need to be used in other tests as well To support code that is more adaptable a test normally consists of several test components as will be discussed later The exception is for directed tests in which case registers may be overwritten specific traffic patters sent or specific corner cases exercised directly in the test component Key test algorithm The dance 96 The top level components of the previous section have a complex yet necessary set of interactions This ensures the maximum flexibility for a test while providing a known set of interaction
81. riate for the test at hand The reasoning behind having multiple independent components is that this is close to the real operation of the chip where each feature is expected to operate simultaneously In reality the chip has common resources that must seguence or arbitrate the use of features It is in these common resources where the more tricky bugs lurk Using this method the test s direct responsibility is to map the features of the chip as presented by the testbench s data members to a set of classes inherited from the test_component base class The test would then add constraints to adapt the test component to the test at hand as in the following example class ethernet basic packet public test base public ethernet basic packet testbench tb watchdog wd ethernet data 1l tb gt e generator 1 tb gt e bfm 1 tb gt e checker 1 ethernet data 2 tb gt e generator 2 tb gt e bfm 2 tb gt e_checker 2 pci express 1 tb gt pci generator 1 tb gt pci bfm 1 tb gt pci checker 1 void time zero setup ethernet data l time zero setup ethernet data 2 time zero setup pci express l time zero setup void out of reset reset r ethernet data l out of reset r ethernet data 2 out of reset r pci express l out of reset r void write to hardware ethernet data l write to hardware ethernet data _2 write to hardware pci express l write to hardware void st
82. rification top vout log a test log lt lt teal info lt lt val lt lt hex lt lt 207218 lt lt endm This example prints the following assuming a thread of tx a file of uart cpp a line number of 313 and a simulation time of 77 ns 77 ns tx a test uart cpp 313 val 64 h32972 Teal displays the file and line number in the source code that originated the message This is useful when the same message comes from several different places in the code Of course this information can be sup pressed A Practitioner s Handbook 77 Chapter 5 Teal Basics 78 Note that when you finish a message statement by using endm the vout instance adds the simulation time the current thread name and the functional area to the message then sends the message to the vlog global service It does not send the message as a text string which would not allow the efficient modification of the message rather it sends the message as a set of pairs of IDs and strings This allows you to instruct the vlog instance to modify messages with respect to their components for example to demote errors to a warning or stop all output from a file or a functional area The vout class also supports decimal hexadecimal and binary output You select the type of output by placing either a hex or dec or bin in the message statement The reg class also looks at the setting when the reg is converted to a string However you often do
83. rols the Overview randomness That is the real work of a verification project The next chapter talks about an open source verification environment Teal s similarity to HDLs Although Teal does make use of classes and inheritance in C your algorithms for driving and sensing the wires can look close to what a hardware engineer is used to As an example suppose you had a signal located at top chip address in your simulation and you wanted to get the value of it at the positive edge of a clock The Teal code would look this teal vreg clock top clock teal vreg address top chip address teal vout log logger id at posedge clock log lt lt The current address is lt lt address lt lt endm Don t worry if this example is not clear We ll walk through each of these Teal classes later The point is that the at posedge clock should be recognizable to Verilog coders In addition the address variable can be used as a regular C integral variable A tiny but complete example This chapter delves into the details about all of Teal s classes but let s look at a basic example of what a complete C example using Teal looks like It should not be hard to understand the code presented here assuming the reader has some familiarity with C or C and a general knowledge of Verilog or VHDL In this example our chip implements a black box function Given a reference clock it samples a stimulus on the
84. s This is one of the tricky parts of a verification system This section discusses this standard algorithm which we call the dance In general the top level components are created randomized and then started Then verification top waits for the test and testbench to be completed This is called the polite path If the watchdog timer Major Classes and Their Roles decides that a timeout has occurred the impolite path is taken and the simulation ends The order of these calls can be better visualized on an event diagram as shown below The four columns show the main components Execution starts at the top left line and the arrows represent function calls to the other components The Dance verification_top Test Watchdog Testbench Create new top x gt objects gt Build and Tandomize configure gt time_zero_setup out_of_reset Main gt test N run write_to_hardware start wait_for_completion Test report final results y E report timeout Timeout 4 path Thefirstthingthatverification top doesisbuildthegloballogging objects These provide logging to a file and shut down the simulation after a threshold number of errors have been logged See truss vout h A Practitioner s Handbook 97 Chapter 6 Truss A Standard
85. s yet the common methods come down to just start stop report and a few others It turns out that this concept of start stop and so on is common to a large set of verification tasks and is represented in Truss as the abstract base class verification component However the concrete subclasses are inherited from verification component only if they use the bulk of the methods Any smaller subset uses the same named methods as a convention instead In this way the framework is not warped to fit a generic class Even more important your design is not warped to fit the generic class Truss implements a specific methodology for functional verification As in any endeavor to generalize the terrain is fraught with peril Never theless as writing code entails making judgments about what is the right decision Truss attempts to generalize a style of verification Deciding on the right balance between generic and specific is a judgment call for the team The idea behind Truss is to foster a a small usable and adaptable methodology for beginners through experts As such Truss Major Classes and Their Roles provides an example of the techniques presented in Part III of this handbook Major Classes and Their Roles Truss is an implementation of the layers talked about in the Layered Approach chapter Conseguently there are only a few top level compo nents the verification top the testbench the test and the watchdog
86. s are not strings Teal provides a templated function find to convert parameters to the correct variable format The find function always returns a string either an empty string if the parameter is not found or the actual string associated with the parameters This function relies on the operator gt gt to be defined for the variable class used The operator gt gt is defined for all built in types such as int char long double and so on For your classes you can define your own operator gt gt and then use Teal s find If defining an operator gt gt is not appropriate for your class or if you don t have a class but instead have a collection of built in types you can usestd istringstream This allows the code to create a stream from Accessing Memory a string from which you can then extract the chars ints doubles and so on as needed For example to read the stop error probability range from the example above you would use the following include teal h using namespace teal void verification top dictionary open parity error test parameters txt reads 32 81962 75 330 from stop error parameter into ss std istringstream ss dictionary find stop error double stop error min 0 double stop error max 0 SS gt gt stop error min gt gt stop error max vout log showing double double reads log lt lt Stop error range is lt lt stop error min lt lt
87. so we must implement it in our inherited class Let s assume we want to add a channel interface like so include generator h namespace my interface typedef channel put lt my data gt generated channel class generator agent public generator public generator agent generated channel out out out A Practitioner s Handbook 129 Chapter 7 Truss Flow virtual void post generate const my data amp d out_ gt put d private generated channel out_ By building a generator agent we have abstracted how the generator gets the created data to the driver BFM A similar situation exists in the monitor namespace my interface class results class monitor public truss thread public void start the connection method virtual void data received const results amp 0 And likewise for an agent for the monitor finclude monitor h namespace my interface typedef channel put lt results gt generated channel class monitor agent public monitor public monitor agent out channel out out out virtual data received const results amp out_ gt put r private out_channel out_ But what about the other side of the channels These objects are the driver agent and checker agent respectively Their job is to take the data out of a channel and act on the data 130 The Second Test Adding Channels and Random Parameters Remember we are discussing ch
88. ss project by taking the more abstract description of classes and applying them to the first few tests in a new project About verification_top cpp 116 When the simulator executes the teal_top call in the HDL control is passed to the verification top function in verification top cpp under the fruss directory In this handbook we refer to this function as the dance or top function It is this function that interacts with your top level components the test the testbench and the watchdog timer Let s look at the dance with respect to the methods you have to write This is illustrated in the figure on the following page A sguare box indicates that the method has a default implementation and a rounded box indicates it needs to be defined for your project About verification_top cpp The Dance Detailed Flow verification_top C testbench new std string watchdog new std string S your_test new testbench watchdog std string C your_test randomize testbench randomize testbench time_zero_setup watchdog time_zero_setup gt C your_test time_zero_setup testbench out_of reset watchdog out_of_reset your_test out_of reset C testbench write_to_hardware 23 watchdog write_to_hardware ea ci your_test write_to_hardware testbench star
89. ss s checker you can also just wait for generated data to be checked This process of writing a new test continues for all the rest of the features and interfaces of the chip Remember the more irritators a test has the more likely it is to model what actually happens when the chip design is realized in silicon Summary Summary This chapter tried to clear the fog of how to go about using Truss We started with a review of the top level dance and then showed that the dance also existed in other layers of the system We looked at the tools provided by Truss which are the truss execution script and a standard makefile We covered writing the first test concluding that it will probably be a directed test Then we took the test up a notch adding connection agents to the generator driver monitor and checker We introduced the Truss channel as the interconnect technique but noted that there are many other technigues We looked a bit at control knobs a technigue for passing parameters to constrain randomization There are many technigues for constraining random variable generation This chapter showed how to harness Teal s dictionary to hook up bounds for randomization We finally discussed what to do after the second test The idea is to write more tests for that interface or feature and also test the rest of the chip The key part of writing more tests is to Keep an eye out for what you can steal rather adapt
90. st complete example of using Truss where you can actually compile and run the code The code is not as complex as what you would encounter in a fully featured chip However all the main parts are here to consider The source files may seem silly or overly complex for the chip we are trying to test but we are trying to demonstrate how to structure a verification system for a real project Your chips will have plenty of complexity to manage This chapter does not walk through every code file We are all capable of reading code What it does instead is look at some of the more important aspects of the verification system Directory Structure In order to help you navigate the source files it s good to show the main directories that comprise a Truss based system shown below We ve also included only the main files we will be working with Directory Structure rtl results verification alu_top v rT TIL l I bin test_components testbench J L tests J vip N truss h truss_verification_top setup test_component cpp h alu_test cpp h cpp h Pdl x top j alu testbench v cpp h hdl_paths h alu_driver cpp h alu_monitor cpp h alu_generator cpp h alu_checker cpp h 140 Directory Structure The source code for the chip is in the rt1 directory How does the truss run script know this The file verification testbench top hdl paths vc is used to specify the paths to the RTL and the R
91. ster writes to move your selected configura tions to the chip The tests write to hardware method usually just calls the same named method on all its test components This is because the actual register writes will occur in the BFM or driver One exception The Test Component Dance is when you are writing a direct test and it s easier just to write the registers at the test level The testbench start method if it Knows which interfaces and features are in use starts up all the BFMs monitors and drivers Depend ing on your architecture it may also start the generators and checkers The test start method usually just calls the start method on all its owned test components The wait for completion methods in the test and testbench are used to pause the verification system until the test is finished Although there are many ways to do this the examples in this handbook just allow the checkers to say when the test is completed The report method in both top level objects reports their status For the testbench it is usually appropriate to report the configurations selected For the test it usually just calls the test components That s it This may seem like a lot of methods to write but you probably do not need to perform tasks in all the methods Later in this chapter we will talk about the order in which you might want to implement these methods The Test Component Dance Did you notice that most of the time
92. t watchdog start your_test start testbench wait_for_completion D your_test wait_for_completion g testbench report Final Report p your_test report Final Report J Legend Build objects apply constraints Perform top level andomization for example chose interfaces or features to be tested Pull wires registers up or down before releasing the reset line Hold the reset line for the minimal amount then release it Return when registers can be accessed Push the configurations down to the hardware Exercise the chip Pause until the checkers are finished Print which components have completed PROJECT_HOME verification testbench top testbench cpp PROJECT_HOME verification tests your_test cpp watchdog TRUSS_HOME src watchdog cpp A Practitioner s Handbook 117 Chapter 7 Truss Flow 118 The watchdog class is already written and should be sufficient for most purposes We will not discuss the watchdog timer s methods because they are relatively straightforward You ll have to write the test and testbench classes In the testbench constructor instantiate your generators checkers BFMs and so on This assumes that your team has decided to put these interface objects in the testbench rather than in the test components Then add your constraints by using the dictionary These constraints will be picked up by your
93. t for initialization through the back door or register writes The next step write to hardware is where the BFMs are called to initialize the chip This can be done by either the test the testbench or a combination of the two What is appropriate depends on your situation as discussed in subseguent sections At this point the system is ready for traffic flow The start method directs the testbench and test to start running The testbench is started first to allow monitors and BFMs to start followed by the watchdog timer Finally the test is told to start which generates the actual traffic Next verification top callswait for completion onthe test bench If your design makes the testbench aware of what checkers are in use this call waits for the testbench checkers to complete If not this method simply returns The verification_component Abstract Base Class Then verification top calls the test s wait_for completion If your design makes the test aware of what checkers are in use this call waits for them to complete This is the style used in the examples At this point the test is almost finished The testbench and test are called to report their final status Then verification top checks to see if any errors were reported If none were reported the test is considered to have passed It may seem weak to accept that the absence of errors is sufficient to consider a test passing In practice howeve
94. will probably be a simple directed test with a test component that does not have a generator and possibly not even a checker It will probably interact directly with the BFM or driver 1 The final shared object is built by the truss script A Practitioner s Handbook 125 Chapter 7 Truss Flow 126 Focus your initial efforts on the driver and BFM Write a first cut at the driver class making it have the methods that seem right to you You may or may not need a monitor depending on the protocol or feature to be tested Next create a testbench that includes that driver BFM and think about how to get clocks to the chip and get it out of reset Now make a test class and get the whole thing compiling Before moving on to connecting the test to the driver with a test component make sure the chip is cleanly out of reset as this can be done by the testbench s out of reset method The next step is to make a simple test_component This component will probably just be a directed exercise with perhaps a few reads and writes or just a few calls to the driver Note that you may use the test_component pre implemented methods if you are comfortable with them but for a first test it might be better just to override the start method directly This is because that s easier than remembering where to put your randomization and traffic generation code If there is any configuration use the chip s default configuration Don t try to ra

Download Pdf Manuals

image

Related Search

Related Contents

MANUAL DE EMPLEO  Westinghouse One-Light Post-Top Outdoor Lantern 6486600 Instruction Manual  Ultra Chef® Brochure  取扱説明書  w260 NA QSG (EFSP) 229-095003  mPulseTM Series  DDX9902S DDX9702S  

Copyright © All rights reserved.
Failed to retrieve file