Debugging is the most time-critical activity of any verification engineer. Finding a bug is very often a combination of having a good hunch, experience, and the quality of testbench code that you need to analyze. Since having a good hunch and experience is something everyone needs to acquire for themselves, I am going to focus on potential code optimizations that help reduce debug time.
Encapsulate your Aspects
As in any other object-oriented language, modeling should be a planned rather than an ad-hoc process. However, as a verification engineer you are heavily reliant on others to help you in the planning process to develop your testbench. As such, you will quite often be forced to do ad-hoc programming to model a new requirement, or rewrite already existing code to meet a slight change in an already existing requirement. The UVM-e guidelines already provide a very solid basis; however even within those guidelines, your scoreboard can be very prone to becoming a dumpster for anything that you have to do on an ad-hoc basis.
You might be fine with just using your scoreboard for modeling all the RTL-to-testbench output checking. However, your testbench might have to handle more complex input-to-output transformations to provide the testbench output. This is where using the scoreboard as a dumpster for anything you can think of is a bad idea, and you should think about using a dedicated reference model to provide a well encapsulated input-to-output transformation or even an input predictor, based on the output you received.
As an e user you are in luck, because it is very easy to perform ad-hoc programming in e and avoid "the dumpster." In a series of steps, I am going to guide you through how to integrate your reference model into your block-level monitor unit.
- Declare your scoreboard
<’
// This is just a place-holder for your scoreboard
unit my_scbd_u like uvm_base_unit {
// Place-holder method for input-to-output transformation
transform_received_to_expected( src_tr: src_prot_tr_s ): target_prot_tr_s is empty;
};
‘>
2. Instantiate your scoreboard in the Block-Level Monitor
<’
unit my_block_monitor_u like uvm_base_unit {
// the scoreboard instance
scbd: my_scbd_u is instance;
};
extend my_scbd_u {
// reference, do not generate
!p_block_mon: my_block_monitor_u;
connect_pointers() is also {
p_block_mon = get_enclosing_unit( my_block_monitor_u );
};
};
‘>
3. Create your reference model aspect feature and instantiate it in the monitor
<’
unit my_model_aspect_a_u like uvm_base_unit {
// reference to your monitor unit
!p_block_mon: my_block_monitor_u;
// All your fields, events, methods etc go in here
// ...
my_transformation_algorithm( src_tr: src_prot_tr_s ): target_prot_tr_s is {
// algorithm that models the transformation from input to output
};
connect_pointers() is also {
p_block_mon = get_enclosing_unit( my_block_monitor_u );
};
// Add a name for your model
short_name(): string is also {
result = ”ASPECT_A”;
};
};
extend my_block_monitor_u {
model_aspect_a: my_model_aspect_a_u is instance;
};
‘>
4. Integrate the first model aspect into the scoreboard
<’
extend my_scbd_u {
// Reference the aspect
!p_model_aspect_a: my_model_aspect_a_u;
// Add the transformation hook
transform_received_to_expected( src_tr: src_prot_tr ): target_prot_tr is {
result = p_model_aspect_a.my_transformation_algorithm( src_tr );
};
connect_pointers() is also {
p_model_aspect_a = p_block_mon.model_aspect_a;
};
};
‘>
5. Adding more aspects to the verification environment.
<’
extend my_scbd_u {
// Reference another aspect
!p_model_aspect_b: my_model_aspect_b_u;
// Add the transformation hook for another model aspect
transform_received_to_expected( src_tr: src_prot_tr ): target_prot_tr isalso {
// This could be an example of a filter that alters or removes transactions
result = p_model_aspect_b.apply_filters( );
};
connect_pointers() is also {
p_model_aspect_b = p_block_mon.model_aspect_b;
};
};
‘>
In this flow, steps 1 through 4 have to be done once, and step 5 is simply just extending your transformation hook method with any additional algorithms you need to add to your scoreboard.
By following these steps as a guideline, you can quickly change reference model aspects to your scoreboard without creating a dumpster and this will help you debug any issues tremendously. Don’t forget to extend the short_name() method in your units for your messaging!
Daniel Bayer