TestBencher Pro and Reactive Test Bench Help

10.9 Scoreboarding

10.9 Scoreboarding

Previous topic Next topic  

10.9 Scoreboarding

Previous topic Next topic  

Scoreboarding is the process of tracking which transactions have been applied to the model under test (MUT). One way to do scoreboarding is to create a "slave diagram" that you launch near the start of the test bench that reacts to the same read/write protocol as the model under test. This diagram would therefore run in parallel with your MUT and would snoop on the bus to save off all the writes written to the memory to either an array or an associate array. For small address spaces (e.g. 64k or less) an array can be used, but for larger address spaces it is better to use an associative array.

Simple Test Benches

In a simple testbench, you would create the array in the "class library" for the project and have the slave diagram save data to this memory using a sample to capture the address and data values at the appropriate points during the recognition of a write cycle (any diagram in a project can read/write the project level variables).

Complicated Test Benches

In a more complicated system with several memories being tested at once, you would probably want to make a separate project file (*.hpj file) to act as the "golden reference"/"executable specification" ram model. This would create an entire "ram" component that could be instantiated multiple times in an upper level project file.

An Asynchronous Example:

There is an example of this, in the Examples > TestBencher > VHDL > VME directory, where an upper level project, VME.hpj, contains two different types of subcomponents (VME_slave.hpj and VME_master.hpj). To view this example, open up VME.hpj, then drill into the VME_slave.hpj file under the "Project Library" folder. If you look into the Variable List under Component Model for VME_slave, you'll see there's a variable called memory defined here. It's a simple 65k element array of 4 state values. It's written to by the slave's write diagram whenever the write diagram detects a write bus transaction.

The write diagram is the key piece of this example, as it shows one way to create a slave that "recognizes" a write transaction on an asynchronous bus like VME using "sensitive edges". For VME, the address strobe (AS) and the data strobe were made sensitive edges to indicate the diagram should "wait" until these events occur. To make the rising or falling edges of a signal sensitive, double click on the signal name and click the appropriate check box at the bottom of the Signal Properties dialog. Any drawn edges of the sensitive type will then generate an appropriate "wait" statement in the VHDL code at either the relative time or during that relative clock cycle (depending on whether the signal is "unclocked" or "clocked"). Section 2.6 Sensitive Edges - a Blocking Construct covers sensitive edges and has links to other methods for waiting for events in a diagram.

After the address strobe occurs (the wait condition is met), the sample triggered by the address strobe checks the address to verify it's within the range of the SRAM, otherwise the diagram ignores the write cycle (by "restarting" and waiting for another address strobe).

The other important sample is the one triggered when the data strobe falls. This one verifies that it's actually a write cycle (if it's not the diagram is "restarted" and waits for another address strobe).

A Synchronous Example

The PCI example, located in the Examples > TestBencher > VHDL > PCI directory, is very similar to the VME example, except it demonstrates monitoring a synchronous bus rather than an asynchronous one. For fastest simulation, the write diagram in the slave of this example waits for a falling edge on FRAME signal (which indicates a cycle of some sort is beginning), then samples the address on the next clock cycle after the frame to verify we have an address with the address space of the device.

The PCI write example also demonstrates how to capture the data from a "burst write" using a loop. To gain an understanding of how it works, it is best to double click on each marker and also on the samples in the diagram and press the HDL Code button on the Sample Properties dialog. The SampleData sample does the actual capture of the data being written to the bus, and it saves it out to an array of 32 bit words:

@sram.data[CONV_INTEGER(UNSIGNED(DecodeAddress[4:0]))]

Note it's using the DecodeAddress it captured in the DecodeAddress sample to write to the proper location in the array.