Friday 3 October 2014

VHDL Testbench Package: Register Work Bench

This post is to introduce the Register Workbench. It is intended for those design and verification engineers involved in FPGA/ASIC designs that contain registers and memory. For those readers that are tcl/tk users, it may be noted that the Register Workbench is a tcl/tk application and it is distributed in source form. The package can be downloaded from here: Register Workbench VHDL 0.1

The register set and memory map of a design can be very tedious to produce and maintain. This includes definition, documentation, RTL and verification. It has been seen that some bigger design teams break the task “of registers” down into specific tasks for different people. This introduces delays and inconsistencies for the dissemination of needed information. The documentation gets behind, the RTL gets ahead, and verification does not really know what is correct. I posted test bench package variables and described a centralized table definition. This solves some of the problem but not all of it. The solution is a way to gather, store and generate code and documentation, from a register and memory map definition.

I have crated a tool that enables the definition of memory maps and registers. It is called the Register Workbench. This tck/tk application enables the user to input and modify the definition. The storage format is open and documented in the package with the tool. The storage format is also used internally by the tool, as the file is simply read in and held internally as a list. This is the initial public release of the Register Workbench (RWb). It includes generation geared towards the VHDL Test Bench Package. This includes “defines” for registers names and addresses for inclusion in a stimulus file, generation of VHDL BFM shell containing the defined register block and memory, generation of the VHDL RTL of the register block and some basic HTML documentation generation. It is planed to upgrade and extend the Register Workbench for some time.

What will you gain from using the RWb?

First off, you gain by centralizing the information related to your designs register and memory. This includes document related description text. This means that when changes are made, the change propagates down the design chain almost instantly.

Secondly, you gain stability. Once the generation system is in place, the consistency of the output is guaranteed.

You gain options. The open source, tool code, and storage format enables the you to modify and add to the functionality or definitions.

You gain insight. If you have never used a tool like this on a design that contains registers and memory, you will gain the insight into the benefits.

You gain by being efficient. You will save time by using the tool to assist in your register definition and maintenance. Even if you have to write your own generation code, you will gain. This is the main purpose of the RWb, to save time.

Being the sole coder on this project has opened my eyes to how difficult it is to produce a quality tool. One that will be easy to use and give good information to the user. Most of all how difficult it is to cover all possible operations that a user may take. If you use the RWb and find problems, have comments or suggestions, or would like to contribute, my contact information is included in the documentation. I hope, by using the RWb, that you save time and improve the quality of your efforts ...

Sckoarn

October 10, 2014
Update tool to include "C" #defines header file generation.

Nov. 7, 2014
Update/Upgrade HTML output to include browser and Document Outputs.
This is a big upgrade to the generated HTML output.

Tuesday 19 August 2014

VHDL Test Bench Package: License Change & Update


This is a simple notice of changes to the licensing of the VHDL Test Bench Package.  Also a notice that the official release site of the test bench package, Opencores, has been updated.

I recently received an email asking about the licensing of the VHDL Test Bench Package. It is nice to hear from users of the test bench package and readers of this Blog. They decided to not use the test bench package because of the licensing.

The test bench package was under the GNU General Public License, as published by the Free Software Foundation. I will not go over the details, as it is easy to obtain and can be read. The license covered the four files, ttb_gen_gui (and others), template_tb_bhv.vhd, tb_pkg_head.vhd and tb_pkg_body.vhd. The output from ttb_gen, or the use of the template could imply a derived work. This would cause the test bench you created to have to be punished / delivered with the same license as the package. This can cause problems for some businesses.

The license for the VHDL Test Bench Package has been changed to the BSD-2 clause license. This change is reflected on the Opencores site at: Test Bench Package.   If you are using previous versions of the test bench package for business purposes, you should update to the latest version.   The license change ensures that the package conveys my intent, freedom of use.

Just before the license update to he test bench package, I copied all content from my privet site to Opencores.  This includes the example and code snips that were available there.   I now believe that the Opencores site is the most current offering of the test bench package.  I will eventually remove the links, to offerings of the older test bench package, from this blog.

All the Best,
Sckoarn

Saturday 3 August 2013

VHDL Test Bench: VHLD assert Statements

This blog post will be about the use of the VHDL assert statement. The use of the assert statement is demonstrated throughout the VHDL Test Bench Package. Also, in the default instructions, several assert statements are used to terminate the simulation when there is an error of some sort. Please refer to the tb_pkg_body.vhd and template_tb_bhv.vhd files of the VHDL Test Bench Package. You do not have to generate a test bench to see the usage of the assert statements.

In the case of the VHDL Test Bench Package, the assert statement is used to check that the script, the user is feeding into the simulation, has the correct syntax. As the script is parsed and put into the linked list of commands, the existence of the command and the number of variables passed are checked. After the script is populated into the linked list, the variables are tested for existence as well. These checks are done before the simulation starts. The assert statement facilitates ending the simulation through the “failure” severity level. These assert statements are found in the tb_pkg_body.vhd file. The other level of checking that uses asserts is found in the <tb_name>_tb_bhv.vhd file. These asserts are checking the results of a command, or are in place to check the structure of a command like IF . The user should create asserts where needed in commands. These will have to be customization of the ones you find in the tb_bhv.vhd file and code snips (Code snips are now part of the Opencores distribution).

An assert is a VHDL language construct that if the statement that is passed evaluates to false, the body of the statement will execute. There is lots of information on the web about the VHDL assert construct. The body of the assert may contain a “report” field. This text field enables the code to print out a message to the simulation log. The other field is the “severity” field. It enables the command to exist in one of four levels, note, warning, error or failure. The levels enable the simulator to be configured to limit which levels will be reported and which will be ignored. The assert instruction looks like this:

assert (<statement evaluating to true or false>)
   report ”Some Quoted text string including escape characters”
severity <level>;

When I code asserts I try to keep the <statement evaluating to true or false> as simple as possible. Usually “something = something else” is all that is needed.

The assert statement is usually a sequential statement. So most of the time it will be enclosed in a process, procedure or function. The placement of the assert statement in the code will determine when the assert will evaluate. So if the assert is in a clocked process, the assert will evaluate every clock edge the process and logic is sensitive to.

The assert is the “self checking” element provided by the VHDL language. I failed to present this in the “What is Self Checking” post.  When you add asserts to your code, whether it be RTL or test bench code, you are implementing self checking. Implementing asserts in your RTL and test bench is highly recommended. Nothing like having a bunch of silent checkers watching your design or function and when there is a problem, you are able to inform the user of the problem.

In a design effort, which includes design and verification, the use of asserts is recommended in the following areas:

  1. RTL: In the design, there should be asserts coded in the RTL for generic settings and limits, register contents outside legal bounds and any place the designer wants to ensure correctness. The RTL designer should strive to ensure users of their code get notification if something is wrong.
  2. Test Environment: In the test environment the use of the assert statement should be used to check user input and provide meaningful debug information.
    - Asserts should be in any command where checking results in a testcase could result in failure
    - Asserts should be used in BFM's where the address space has limits. (assess range checking)
    - Asserts can be used to output messages as to when a requirement has been seen to have been proven. Very good for DO-254 efforts.
    - Asserts can be used in Monitor BFM's to generate statistics or error/warning/failure messages.


I have rarely used the assert with severity note. This is really of little use except for development debug. Even then I would use the test bench print() command instead. As I have stated in the Messages post, I believe messages should be minimized.

When using an assert statement to prove a complicated function, I create processes that emulate the function and produce an expected output. I then use an assert and check that the emulated value equals the real value. So, I reduce the evaluation statement to “emulate = real”. Though you can implement very complicated statements as the condition to the assert, why do that when you can implement in a process?

If you are not already using the VHDL assert construct, I hope this encourages you to get started. The assert is a very powerful and often under used language construct. For RTL it is an excellent way to make your RTL semi-self checking. For VHDL Test Bench package it is the best way to provide self checking of the stimulus file being read.

Assert!!

Sckoarn

Wednesday 10 July 2013

VHDL Test Bench: Simulation Log File Messages

This blog post will be about the VHDL Test Bench and messaging. This refers to the messages that are output to the simulation log file. For modern verification methods, messaging is an important feature and there is a messaging control structure for controlling what messages will be output. Messaging control is usually termed “Verbosity” and can have many levels of control. The current implementation of the VHDL Test Bench provides two levels of verbosity, always on and debug messages.

When it comes to messages provided by an environment, I see two distinct levels of messaging. One level is the simulation log messages that need to be generated to determine what test ran and if it passed or failed. The other level of messaging is debug. The debug messages are used to help debug the test case during test bench development and RTL bug tracing.

The pass / fail message in a log file is required. I have yet to see a regression that does not need to scan log files to find out which tests passed and which failed. Of course the log file scanning is done by an external script after all the simulations have been run.  The pass/fail message is an "always on" message.

Debug messaging can take several forms. One form of debug messaging is generated by the stimulus file commands. For instance a READ command could report the address read and the value returned during the read operation. Or a VERIFY command could report success (note) as well as failure (failure). For the above two examples every time a READ or VERIFY command is encountered in a stimulus file, messages will be output with details of the operation. Another form of debug messaging are those generated by BFMs or models. These kinds of messages are not directly controllable from stimulus file commands unless a specific implementation is done in the BFM. As an example, if a RAM is generated to be 29x32, (29 locations X 32 bits wide) it may also contain assertions that check that the address applied to the RAM is not greater than 29. This makes sense because the address bus will be capable of addressing 32 locations. Though your RTL will most likely not address the full range, it is likely that your BIST tester will. This has the potential to generate a HUGE amount of messages to the log file during BIST testing. In this case a way of disabling the checking in the RAM model should be provided / implemented.

So, what is all this talk about? Why is there a concern over messages? They go to the log file and are there if we need to look at them, right? My main beef with messages is that, while a message is being output, your simulation is not progressing. To me it is an efficiency issue. I would rather be simulating than be told that some value was read from some address, and never look have at it. I have worked with an environment that generated 2-3 G byte log files. This is ok if you like to spend several minutes waiting for your editor to load the file. (I'm not a VI guy) But this becomes a real problem when your 2000 tests cases cause your disk to become full. Bottom line is that messages waste time and use space. Messaging should be optimized to enable messages that are appropriate for the development phase they are running in.

The VHDL Test Bench provides the two levels of messaging as stated at the beginning.

Those messages that are required to be output, “always on”, can use the '” <text>' facility of the test bench package. This is the “Dynamic Text Strings” as detailed in the VHDL Test Bench users guide. This text string will be output when ever the command line is executed. I would personally use this for statements that a requirement is being tested. They should not be used in loops as this will cause many messages to be output, which may not have any real value. Also, failure messages should also be output with no means to turn them off. I am referring to an assert statement with a failure severity. The VERIFY commands I create use “severity failure” to terminate the test case and output a clear message that the test case failed. (When, Where, Why, What) The FINISH command is the default “passing test” termination command, but if you look closely it also uses an assert with severity failure.

For those messages that are considered debug messages, there should be a mechanism to turn them off. Once the test cases are finished, and you are regressing, debug messages should not be using up simulation time because the test cases should be working by then. The VHDL Test Bench package commands, MESSAGE_ON and MESSAGE_OFF, are in place to enable the control of debug messages generated from the stimulus file. In the bhv file, there is a boolean variable “messages” defined. The MESSAGE_ON & _OFF commands set this variable to false and true respectively. To use this, simply put the “message” variable in an assert statement that you want to control the output of. As an example look at the default “LOOP” command. The message variable is used to control messaging for each loop iteration. By default, the messages are turned off. In the end the test case should have no message control commands. When the test case is finished there should be no debugging needed so the commands to turn on and off messages can be removed. Also, the message commands can be used anywhere in the test case. This enables control over any section of the test case that is being debugged to generate messages by turning messaging on and off where needed.

If the VHDL Test Bench Package provided debug on/off verbosity level is not enough for your needs, the implementation of messages can be augmented. A verbosity variable can be added, and assigned a verbosity level based on an integer. This can then be used in the assert statement along with the messages variable to control different levels of messages. All modern verification methodologies, currently used today, have many levels of verbosity provided in their messaging system implementation.

As mentioned above, BFMs can be a source of messages. As a practice it is good to have a BFM able to generate messages. These can be in any form needed for debug or required messages. As an example of a required BFM message output, consider a protocol monitoring BFM. Some new feature has been added to the protocol and you want to make the BFM output a message stating when the new feature has been seen. This may be done this way because it would be more difficult to determine this from the stimulus file. The same BFM can output debug messages stating when packets are transferred across the interface it is monitoring. These debug type messages should have the ability to be turned off. This can simply be implemented in a register bit of the BFMs register set, as described in BFMs #1 Posting .

I have always found the messaging facilities of the VHDL Test Bench Package to meet my needs. I have also seen how other users use messages not knowing the full effect. One test case I got from a co-worker took 30 minutes to run, and looking at the output, there was a message for every DUT access. The message stated the address and data that was being written or read. There were about 10,000 accesses DUT register and RAM test, hence 20,000+ lines in the log file of messages. I do not like waiting for simulations, so I disabled the messages and the simulation run in under ten minutes. It was then that I realized the effect of messages on the simulation. Though I had always been one to minimize messages, I did not know they could have such a drastic effect on simulation time.

I hope this posting about messages, helps users create effective VHDL Test Bench environments.

Sckoarn


Saturday 18 May 2013

VHDL Test Bench: DO-254 FPGA Verification

The VHDL Test bench is well suited for DO-254 FPGA/ASIC verification efforts. For those that do not know, DO-254 is a certification that electronics have to pass to be put on an air plane. The simplicity and straight forwardness of the test bench implementation is exactly what the certification authorities like to see. The test bench is really a very small part of the over all certification effort. Usually the simulation effort is more to prove the design in another way besides physical demonstration. On one side, simulation verification alone is not enough to get DO-254 certification. On the other side, simulation enables much more exposure to design details than demonstration.

The scripting system, that the VHDL Test bench implements, enables scripting commands that are simple to read and understand for those not involved in details. This can make test cases easier to review. Test cases can be made to generate messages, in log files, when requirements are being tested. It is important to provide traceability. The message output facility of the test bench enables the ability to provide verbose log file output. The VHDL test bench can help simplify the review of the simulation effort. This can save time and instill confidence in the over all quality of the verification.

As usually the simulation effort is not the sole output used for certification, simulation tools are waived from having to be themselves certified. If this is the case, then the code that runs on the simulation platform and facilities it provides, are not reviewed. (simulation tools) This includes the VHDL Test Bench Package. Of course all the details will be stated in your PHAC (Plan for Hardware Aspects of Certification) document.

In the DO-245 project I was involved in, the certification was based mostly on the demonstration of a test plan on the target hardware. There was two separate test plans and requirements were traced in both hardware and simulation test plans. There were some requirements that were not verifiable in each of the test platforms. The simulation effort, though uncovering bugs along the development path, provided the code coverage that enabled dead code to be identified. This is probably the single most important output from the simulation effort, dead code identification. Since most FPGA/ASIC designs are initially a program, the identification and removal of dead code is seen as a major step to increasing reliability and hence safety.

Requirements traceability is another major part of the DO-254 verification effort. The VHDL test bench scripts can have comments added to state the requirements they cover. The test cases can be made to generate messages that state when requirements are being tested. As well as the results of the testing. There are several tools available that will enable the tracing of requirements to be automated. These tools search documents (test cases, log files, design & requirement specs) and provide a matrix that enables the tracing of a requirement through those documents. This also enables holes to be identified quickly. How requirements are traced is detailed in your HPAC. Try to define and use an automated process for requirements tracing. This will greatly reduce the effort of tracing for verification and reviews.

If your design is in VHDL, then the VHDL Test Bench is a perfect fit. The whole effort can be handled by any standard VHDL simulator. This also enables design and verification to share a test environment and reduce the over all effort expended on creating simulation verification environments. A single language and simple test environment enables the team to focus on the design.

The process around a DO-254 development effort, is significant. This process is in place to ensure all efforts are made to ensure safety. Anything that can make the process go smoother, is something that should be considered. I think that, with the right planning, the VHDL Test bench can make a positive contribution to that goal.

Sckoarn

Tuesday 30 April 2013

VHDL Testbench : Call for stories

Hello everyone.

I have been busy with work and life over the past two years. This makes it difficult to find the time or the will to publish new articles. After a full day of coding and verification, I just do not have the drive to write and code in my spare time.


I am currently working with a consulting group called XtremeEDA. We are specialists in the field of verification and design of integrated circuits. Clients of XtremeEDA are those companies that produce silicon designs of all sizes and applications. Some of the clients of XtremeEDA are the biggest players in the semi-conductor industry. This includes EDA vendors.


The contracts I have worked on, this past couple of years, have been a VHDL DO-254 project and some smaller projects proving IP for large SOC designs. I plan to post more information about how the VHDL Testbench can be used for DO-254 verification efforts.


This post is mainly a call for readers to post up some information about how they used the VHDL Testbench for their verification efforts. With the number of pages having been read, above 10,000 there has to be a few that actually used the VHDL Testbench package for something. For those that did use the VHDL Testbench, I like to hear how it was used, problems encountered, solutions to the problems and any general description of usage. I am sure that future readers will find the stories interesting and possibly useful. Hearing from users may also inspire me to write more about VHDL Testbench usage.


NOTE: If you do post something, please do not post proprietary information. If you work for a company then you most likely know what this means. For those that do not, please do not post details about your “design” if you do not own it. For test bench users, you can describe everything except details about code produced in BFMs and instructions, unless you are the owner.

To post something, simplely add a comment to this post.  Once I reveiw it, as long as it is realated to this blog, it will be published.

Sckoarn

Monday 1 August 2011

VHDL Testing: VHDL 2008 FIFO of type ....

This post is about how VHDL 2008 can be used to implement a FIFO or list of items of any type by implementing a “protected type”.
Many applications store or delay data transfers as part of the implementation. For instance, packet switching, video processing and Digital Signal Processing all usually have some delay element during the processing of the information. A packet switch may store hundreds of packets in order to meet traffic constraints. A video processing unit may store several frames of video data as it processes the video data stream. A DSP application may have delays as it processed blocks of data.

What ever the case is, you have supplied stimulus to the DUT and there is a delay before you get results out. Where do you store the input or the expected results? Wouldn't it be nice to include a time stamp in your input data so you could determine the time it took to process the data?

This can all be realized using VHDL 2008 protected types. A protected type can be used as a shared variable as well, so, knowing how to do this can save time and make life easier.

First step is to decide what kind of record to define that will be the FIFO or list item. This can include anything that you can define in a VHDL record type. For the example, the arr128x8 type will be associated with a FIFO type of fifo_data_type. The type that is going to be the FIFO or list item must include a pointer to the type. In the case of this example the FIFO item type is called fifo_item, defined as a record. The pointer is fifo_item_ptr is a type of pointer to a fifo_item type. The pointer to fifo_item type enables a linked list of fifo_items to be traversed. This implementation is called a single linked list. In order to implement a double link list, a prev_rec definition could be added to the fifo_item definition. The fifo_item type must be defined in a separate package. The pgen package used in the example packet generation BFM example, has been extended and put in a separate file. Included below:

------------------------------------------------------------------------------
-- First we start of with the definition of the packet array type
-- and the pack_out record for pins on the entity and comp.
-- The size of the whole system can be changed by changing the
-- array and record types.
library IEEE;
use IEEE.STD_LOGIC_1164.all;

package pgen is
type arr128x8 is array(0 to 127) of std_logic_vector(7 downto 0);
type fifo_data_array is array(0 to 127) of std_logic_vector(7 downto 0);
-- define the fifo_item type and access pointer
type fifo_item; -- the item
type fifo_item_ptr is access fifo_item; -- pointer to item
type fifo_item is record -- full definition of item
   data : fifo_data_array;
   next_rec : fifo_item_ptr;
end record;
type pack_out is record
   dout : arr128x8;
   drdy : std_logic;
   end record;
end package pgen;
Once the type has been defined in a package the protected type is defined in another package. For this example the package is simply called fifo_pkg. The example is presented as a pure implementation of a protected type in the fifo_pkg, but of course you could have many other items defined, including other protected types.

The first thing to define is the header portion of the package. It include the definition of the protected type and its impure functions and procedures.

use std.textio.all ;
library ieee ;
use ieee.std_logic_1164.all ;
use ieee.numeric_std.all ;
use ieee.math_real.all ;
use work.pgen.all; -- include the types, as needed by shared variables
package fifo_pkg is

   type tb_fifo is protected
     procedure push(data : fifo_data_array);
     impure function push(data : fifo_data_array) return integer;
     impure function pop return fifo_data_array;
     impure function fifo_depth return integer;
   end protected tb_fifo;
end fifo_pkg;

Some simple utilities are defined, push in both a procedure and function form, a pop function and a fifo_depth function. Basic FIFO functions. Note the “is protected”, “end protected” and “impure function” syntax.

The body section is there the implementation of the procedures and impure functions are done. The example code for the body is presented below:

package body fifo_pkg is
type tb_fifo is protected body
   variable fifo_ptr : fifo_item_ptr := null;
   variable fifo_cnt : integer := 0;

   -- push function
   impure function push(data : fifo_data_array) return integer is
     variable new_pkt : fifo_item_ptr;
     variable tmp_ptr : fifo_item_ptr;
   begin
     if(fifo_cnt = 0) then
       new_pkt := new fifo_item;
       fifo_ptr := new_pkt;
       -- copy the packet to the new space
       new_pkt.data := data;
       new_pkt.next_rec := null;
       fifo_cnt := 1;
     else
       new_pkt := new fifo_item;
       tmp_ptr := fifo_ptr;
       -- get to the end of the fifo
       while(tmp_ptr.next_rec /= null) loop
         tmp_ptr := tmp_ptr.next_rec;
       end loop;
       -- copy the packet to the new space
       new_pkt.data := data;
       new_pkt.next_rec := null;
       tmp_ptr.next_rec := new_pkt;
       fifo_cnt := fifo_cnt + 1;
     end if;
     return 1;
   end function push;
   -- push procedure
   procedure push(data : fifo_data_array) is
     variable new_pkt : fifo_item_ptr;
     variable tmp_ptr : fifo_item_ptr;
   begin
     if(fifo_cnt = 0) then
       new_pkt := new fifo_item;
       fifo_ptr := new_pkt;
       -- copy the packet to the new space
       new_pkt.data := data;
       new_pkt.next_rec := null;
       fifo_cnt := 1;
     else
       new_pkt := new fifo_item;
       tmp_ptr := fifo_ptr;
       -- get to the end of the fifo
       while(tmp_ptr.next_rec /= null) loop
         tmp_ptr := tmp_ptr.next_rec;
       end loop;
       -- copy the packet to the new space
       new_pkt.data := data;
       new_pkt.next_rec := null;
       tmp_ptr.next_rec := new_pkt;
       fifo_cnt := fifo_cnt + 1;
     end if;
   end procedure push;
   -- pop function
   impure function pop return fifo_data_array is
     variable data : fifo_data_array := (others => (others => 'U'));
     variable tmp_ptr : fifo_item_ptr;
     variable prev_ptr : fifo_item_ptr;
   begin
       case fifo_cnt is
         when 0 =>
           return data;
         when 1 =>
           fifo_cnt := 0;
           data := fifo_ptr.data;
           fifo_ptr := null;
           return data;
         when others =>
           tmp_ptr := fifo_ptr;
           fifo_ptr := tmp_ptr.next_rec;
           tmp_ptr.next_rec := null;
           fifo_cnt := fifo_cnt - 1;
           return tmp_ptr.data;
       end case;
   end function pop;
   -- fifo_depth function
   impure function fifo_depth return integer is
   begin
     return fifo_cnt;
   end function fifo_depth;

 end protected body tb_fifo;

end fifo_pkg;


At the top of the package is the definition of fifo_ptr and fifo_cnt. The fifo_ptr item is the pointer to the top of the linked list of items. The fifo_cnt integer is a count of how many items there are on the fifo.

The package is very simple and does not have many of the nice things like overloaded write and print functions, searching, indexing, deleting and replacing that could be implemented.


Of course to test this the VHDL Test Bench was used and the following stimulus commands were created.

Define just after the architecture statement  shared variable test_fifo : tb_fifo;
or it can be defined as a regular variable as part of the read_file process
-------------------------------------------------------------------------------------------
   elsif (instruction(1 to len) = "PUSH") then
     for i in 0 to test_data'high loop
       --v_dat_array(i) := std_logic_vector(conv_unsigned(v_randv.RandInt(0, 255),8));
       --test_data(i) := std_logic_vector(conv_unsigned(v_randv.RandInt(0, 255),8));
       test_data(i) := std_logic_vector(conv_unsigned(i, 8));
     end loop;
   test_fifo.push(test_data);
   print("fifo depth is: " & integer'image(test_fifo.fifo_depth));
   temp_int := test_fifo.push(test_data);
   print("fifo depth is: " & integer'image(test_fifo.fifo_depth));

------------------------------------------------------------------------------------------
   elsif (instruction(1 to len) = "POP") then
     test_data := (others => (others => 'X'));
     print("POPing fifo depth is: " & integer'image(test_fifo.fifo_depth));
     test_data := test_fifo.pop;


As well the packages have to be included in the tb_ent file. If randomization is used to generate the data, the synthworks Random package must be included.

And the stimulus file used to test the example FIFO implementation:

PUSH
PUSH

POP
POP
POP
POP
POP

PUSH
PUSH

POP
POP
POP
POP
POP

FINISH
The operation was observed by setting break points in the code and looking at the content and status as the simulation progressed.

The example is simple, and could easily be adapted to implement list functions and others. The actual “item” in the FIFO can be changed to include such things as message strings, time stamps, and any other VHDL type. The only draw back is that a FIFO of an unknown type can not be created. If the FIFO item definition is expected to change, some planning should go into the definition so that compatibility can be maintained in the future.

I have used linked lists in the past for storing packet data, but it was not easy. The VHDL Test Bench Package uses linked list techniques extensively. So the only new part to this presentation is the protected types and how you can associate functions and procedures to them. Makes the code that uses protected types more readable I think. As well, access the shared variables of protected types is controlled. I plan to use this FIFO in a checker BFM and in the model of the DUT in the expanded example currently being worked on. (slowly)

The FIFO example could be converted to a list implementation with some additions. For each instance of the example tb_fifo there will be an instance of fifo_cnt. For a list, an index may be needed so that a particular item can be found quickly or ordering can be achieved. Several other functions or procedures will be need to be added to search, re-order and manipulate the list of items. An index field would be added to the record, as it is record specific. Where as a FIFO ID string would be added in the protected body section of the protected type definition, one ID string per fifo. A function or procedure will have to be created that enables the ID string to be set. This is like the fifo_cnt field in the above example code.

Hope that helps some get more acquainted with VHDL 2008 and how it can help your verification efforts.


Sckoarn