Saturday, 14 May 2011

VHDL Test Bench Packge: Version 2 Beta Release

 The version 2 VHDL Test Bench Package Beta is now available.

This version of the package introduces very few changes. The main addition to the package is the ability to have an undefined number of parameters for a command. The other addition is the predefined record types for the stimulus access bus. A minor change is the clean up of the package for commented out lines and unused functions. They were removed.

There is one bug fix in this issue. It seems the file_name variable had no return value from the access_inst_sequ procedure.

In order to create an instruction that has an undefined number of parameters, the “args” value, in the define_instruction call, must contain a value larger than six. This will cause the parser to skip the checking for the correct number of parameters for that command.

The reason for introducing the ability to have an undefined number of parameters passed in an instruction is to enable more dynamic commands to be created. For instance, the CPU style commands presented in the code_snips download, have some commands defined as three parameters. Optionally those commands could be created so two or three parameters could be passed. If only two parameters are valid, then the target of the operation must be the second parameter. As another example, an INC command could be created that enables the one to six parameters to be passed and have all of them incremented in value in one line of a stimulus script. I am sure users will find a use for this feature.
There is one caution about commands with an undefined number of parameters. The test bench package parsing was created such that user scripting errors were found ASAP. One of the items tested for is a correct number of parameters being passed for every command. By creating an instruction to have an undefined number of parameters, you are telling the parser to skip testing for the correct number of parameters. It then becomes the responsibility of the creator to deal with user input, or ignore errors like too many parameters passed. The code for this change was done in the check_valid_inst procedure.

The predefined stimulus bus record types are intended to be used on BFMs. They are presented as an example of a flexible, standardized interface method. Not that this interface is a standard in industry, but it could be for you applications. This definition of the stimulus bus interface enables the flexibility of ease of change. Say you adopt these record types and create many BFMs using them. If later you find that there is another signal needed in your system, it can be added easily just by changing the record definitions. As a facility to easily set a stimulus bus into a neutral state, a stm_neut function is also provided. This function returns a value that can be directly assigned to the record type, making interfacing simpler. This also provides an example of record assignment and function overloading.

As an example of the stimulus bus record types a packet generator BFM example is provided with the beta release. This BFM implementation demonstrates the following features:
  • self generating data, incrementing and random
  • data loading from a file and file opening
  • data loading from the stimulus file
  • dynamic file name in stimulus files
  • direct setting of text data from the stimulus file.
  • use of the new stimulus port definition.
NOTE: It is required to download the random package from here http://www.synthworks.com/downloads/ package link in order for the example BFM to compile.

The packet generator itself is a generic data generator example. It could be combined with a signaling BFM to implement an complete interface. This is a way of disconnecting the data generation from the actual interface signaling. A data generator can service many different kinds of signaling interfaces. This concept is restated in the BFMs #1 blog post. The request input to the packet generator would originate from a signaling BFM to get new data. In this case the request is implemented in a stimulus command called REQUEST.

The other interesting item presented in the example, something I have never done before, is the assignment of text from the stimulus file. In the example stimulus_file.stm file, the SET_FN command takes the dynamic string and assigns it to the stm_text type input of the BFM. This feature is handy for setting file names dynamically from the test case. The parsing system ensures that strings are nul terminated. This makes it easy to do assignment in a loop. The text string input on the example packet generator BFM is part of the stimulus system, but I did not see it needed for all cases, so left it out of the record definitions.

The Beta version of the test bench package is available here: tb_2011beta2.zip direct download in .zip form. Once I am confident the package has no obvious errors the OpenCores release will be updated.

Included in this release is an updated test bench package header and body files. Some additions and fixes to the ttb_gen utility. Updated documentation, yet to be fully completed. And an example of the new package features and test bench techniques in the form of a packet generator BFM.

If you are a user of the VHDL Test Bench Package and discover a bug or want an enhancement, now is your opportunity provide input. Feel free to post any responses in the comments section of this post.

If you are already using the VHDL Test Bench Package, you can upgrade to the new release, there should be no changes needed to your bhv file.

Enjoy

Sckoarn

Tuesday, 10 May 2011

VHDL Test Bench Package: Using BFMs #1


Bus Functional Models (BFM's) are the back bone of the VHDL Test Bench system. Using BFM's relieves the scripting system from having to implement detailed signal sequence generation and reaction. Other than your basic READ and WRITE commands, the scripting system should not implement interface signaling. In other words, data path elements outside the DUT should be implemented in a BFM.

For instance, lets say we have a SoC design. It has a processor, a PCIe interface and a high speed optical interface. There is a DDR2 RAM device interface for the processor and temp storage for packet data. This is a very simple design specification and it states we have at least 3 major interfaces to the design. There is no way that the scripting system can act as the DDR2 RAM at the same time as it interacts with the PCIe interface. This is because a script command usually “waits” for signaling to proceed through it's function. i.e. A READ command asserting address, select signals, and waiting for an acknowledge before collecting the read data and terminating the cycle. To solve the problem of concurrency in the scripting system BFM's are used.

A BFM is a functional model of the object of interest. In the case of a DDR2 RAM, the BFM acts and reacts like the real device would. At the same time it should not implement the timing of the RAM interface as those types of models are not BFM's but actual models of the device. Models of devices that include timing can significantly slow your simulations. Avoid using models with timing if possible. BFM's on the other hand may not even model a memory location until it is written to, in other words a sparse memory model. A BFM is purely functional and does not model timing. This is of course unless it is required to model the timing, in which case it becomes a model as apposed to a BFM.

Notice I use the word object when referring to a BFM. A VHDL component can be considered an Object, as it has interface requirements and data access control. In the case of our BFM, it has a specific interface to the DUT and that interface has restrictions on the BFM internal access, i.e through its interface signalling. The test system has a stimulus access port to access various controls and storage, but in a very controlled way. The BFM will have internal signals and variables that are not accessible to the outside itself, they can be considered private to the BFM. Sort of like an object in an OOP language, but not quite.

Creating BFM's is part of the verification effort. If it is well done, the effort can be reused. A well thought out BFM may be reusable in the next project, or for other projects that have similar interfaces. When I create a BFM I look at it as if it was a device. It has an entity and architecture just like any other design object. Besides the obvious DUT interfaces required to exercise the design interface I provide an interface for the test bench. I call it the stimulus access port in the VHDL Test Bench Package documentation, Section 7. Behind the access port is a register set or addressable space. I use the registers (several default ones again and again) to control and configure the BFM.

A refinement I have added to the test bench package is stimulus access port record type definitions. These additions include slave and master versions of the bus definition. The master versions will enable smart objects to use the stimulus bus to control BFMs. Records types for pins enables the pins to be modified and have the over all coding effort, for the change, be reduced. Records for pin types are a very good practice, even in the DUT. The new “standard” record types are part of a new release of the test bench package, (available for Beta testing soon).

To continue on the topic of creating BFM's, if your efforts are part of a large corporation or team, good BFM planning can save a lot of time. If you have many different signalling interfaces and very few data configurations, it may be beneficial to break the BFM's into parts. One part could be the data generation BFM and another part could be the signalling interface BFM. When you create your signalling BFM's you use an interface compatible with the data generation BFM so you can reuse the data generator. So if you had ten different signalling interfaces and only one data type, you saved rewriting or copy/pasting the data generation code nine times over. Not only that but, if your data generation system changes there is only one place to make the change. Modularity is the key word. This kind of structure can save time in the creation of the verification environment as well as in test case writing. Once you have used something, it is easier when you use it again.

When I create a BFM I start by writing a simple specification. Since I use a BFM like a device, accessed through its stimulus port, I create a register map of the control, functionality options and internal memory(s). This enables me to plan out what I will build as well as provides documentation for users. When implementing, you have a specification to code from and this makes the coding easier.
As an example, using my default BMF register set and one memory range:

---
Name              Address     Bit(s) Description
Control Register    0           0    Enable
                                1    Open file trigger, Write a '1'
                                     to this bit to trigger file open
                                     This bit is self clearing.

Configuration       1         3-0    Data coding mode
Register                             0000 Incrementing
                                     0001 Random
                                     0010 Load from file
                                     0011 User Data

Error Register     2                 Read only definition of error indications

Seed Register      3         31-0    Seed value for random number generation

User Data Memory 0x1000 – 0x107F     Bits 7 downto 0 of the data are written
                                       to the addressed location.

The above specification is for the example packet generator BFM provided with the new test bench package version, to be released in the next blog posting.

The stimulus access port provides 32 bit addressing and 32 bit data, which has been enough for everything I have ever implemented. If I have BFM that needs more registers I have all the rest of the 32 bits of addressing to use. The above registers I always put into a BFM because they seem common. As well, it is just a copy/paste away from a working base implementation.

When coding the BFM, I create a test bench for it, using the VHDL test bench package of course. The other thing that one may have to build is a mating BFM for your development. If you are building a SPI Master interface, for instance, you need a slave to react with the master commands, so you might have to build both. This can have the advantage of having to know the interface better and producing both versions of the interface. When the BFM is connected to the DUT for testing, there is a whole test environment to fall back on when there are interface problems.

In the weeks to come, I will post up examples of specific BFM types. The plan is to produce a signaling BFM to partner with the packet generator, a BFM to recover DUT output data, a compare BMF for testing correctness of data and finally a master BFM to demonstrate my vision of the master stimulus bus. The master stimulus bus is new and I will have to do some playing around with it to be able to produce a usage example.  The next post, will be the release of the Beta version of the Test Bench Package.  This includes the BFM and stimulus bus defintion stated above.

Sckoarn