VAPL Strategy Pattern
VAPL Strategy Pattern
Applicability: This pattern helps implement one of the basic principles of Object
Oriented programming, i.e. Open Close Principle. This principle states classes
should be open for extension but closed for modification. It implies “change”
what the modules do without changing them.
Structure:
Implementation:
The implementation of the Strategy Pattern has 3 basic classes/structures.
If a Client exists then use the Client interfaces or uses the context class.
Example:
1. Policies in OVM/UVM: Each of UVM’s policy classes perform a specific
task for uvm_object-based objects like printing, comparing, recording,
packing, and unpacking. They are implemented separately from
uvm_object so that users can use different ways to print, compare, etc.
without modifying the actual object class being operated on. The user can
simply apply a different printer or compare “policy” to change how an
object is printed or compared.
2. UVM Sequences and tests are a common example of having a base class
with a common interface with subclasses capturing different algorithms.
The context class here would be testbench top from where a test is
selected.
// This library contains the three test cases which are inherited from the
// base. Each subclass here represents a different algorithm/behaviour. From
// the top, any of the test can be invoked/called seamlessly.
// bus_test_base - Takes care of the common set up and configuration
// seq_rand_test - How to use sequence randomization to configure a sequence
// complete_transfer_test - Using sequence object persistence
// rand_transfer_test - Sequences executed in a random order
// All of the example test cases inherit from this base class
//
`uvm_component_utils(bus_test_base)
bus_agent m_agent;
bus_agent_config m_cfg;
endclass: bus_test_base
//
// This test shows how to randomize the memory_trans_seq
// to set it up for a block transfer
//
class seq_rand_test extends bus_test_base;
`uvm_component_utils(seq_rand_test)
//
// This could also be done directly
//
if(!seq.randomize() with {src_addr == 32'h0100_0800;
dst_addr inside {[32'h0101_0000:32'h0103_0000]};
transfer_size == 128;}) begin
`uvm_error("run_phase", "seq randomization failure")
end
seq.start(m_agent.m_sequencer);
phase.drop_objection(this, "Finishing test");
endtask: run_phase
endclass: seq_rand_test
`uvm_component_utils(complete_transfer_test)
endclass: complete_transfer_test
`uvm_component_utils(rand_transfer_test)
endclass: rand_transfer_test
Consequences: The client that finally uses the algorithm using the context
should be aware of all the types of strategies/algorithms that are available.
Related Patterns: