8.7. Introduction to Encapsulation
Encapsulation is the mechanism of bundling data and methods within a single unit (class), restricting direct access to components. It's the most fundamental OOP principle for building maintainable, secure verification environments.
Why Encapsulation Matters in VLSI
-
Protects sensitive verification data from unintended modifications
-
Enables validation of all data before use
-
Allows changing implementations without affecting testbenches
-
Creates clear interfaces between verification components
-
Improves code reusability and maintainability
Encapsulation: Data Hiding and Protection

8.7.1. Access Specifiers
Access specifiers control the visibility of class members. SystemVerilog supports three access specifiers:


8.7.1.1. Local (Private)
Local members are accessible only within the class where they are declared. They are NOT accessible in derived
classes or from outside the class.
Verilog
8.7.1.2. Protected
Protected members are accessible within the class and in all derived classes, but NOT from outside the class hierarchy.
Verilog
8.7.1.3. Public (Default)
Public members (default when no specifier is mentioned) are accessible from anywhere - within the class, in derived classes, and from outside the class.
Verilog
8.7.1.4. Access Specifier Comparison Table

8.7.2. Data Hiding with Getters and Setters
The getter/setter pattern is fundamental to encapsulation. Make data private and provide controlled access.

Basic Pattern
Verilog
8.7.2.1. Benefits of Getters/Setters
-
Validation: Check data before setting
-
Debugging: Add logging/monitoring
-
Flexibility: Change internal representation
-
Security: Control who can read/write
-
Constraints: Enforce business rules
8.7.2.2. Real VLSI Example
Verilog
8.7.3. Information Hiding
Data Hiding vs Information Hiding

Data Hiding: Protecting the data itself (making it private)
Information Hiding: Hiding how something is implemented
Verilog
8.7.4. Encapsulation Layers

Use multiple layers of protection:
-
Core Layer (local): Most sensitive data
-
Protected Layer: Shared with derived classes
-
Public Layer: External interface

8.7.5. Package-Based Encapsulation
Hiding Package Internals
Verilog
Benefits
-
Users only see what they need
-
Can refactor internal helpers without breaking user code
-
Cleaner namespace
-
Better organization
8.7.6. Real-World Encapsulation Examples

8.7.6.1. Encapsulated Bus Driver
Verilog
Benefits: Clean interface, hidden complexity, extensible protocols.
8.7.6.2 Encapsulated Scoreboard
Verilog
8.7.7. Advanced Encapsulation Techniques
8.7.7.1 Read-Only Properties
Provide getter but no setter for read-only data:
Verilog
8.7.7.2 Lazy Initialization
Verilog
8.7.7.3 Computed Properties
Verilog
8.7.7.4 Copy Protection
Verilog
8.7.8. Common Pitfalls and Solutions
8.7.8.1 Pitfall: Making Everything Public
Problem: New users often make all members public.
Verilog
Solution: Start with local, make public only what's needed.
Verilog
8.7.8.2 Pitfall: Not Using Getters/Setters
Problem: Cannot add validation later.
// BAD - no validation possible
obj.balance = -100; // Whoops!
Solution: Use setters from the start.
8.3 Pitfall: Returning References to Private Data
Problem: Breaks encapsulation.
// BAD
function ref Queue get_queue();
return internal_queue; // Users can modify!
endfunction
Solution: Return copy or provide controlled access.
// GOOD
function Queue get_queue_copy();
return internal_queue; // Returns copy
endfunction
8.4 Pitfall: Over-encapsulation
Problem: Too many layers makes code complex.
Solution: Balance - protect what matters, keep interface simple.
8.7.9. Coding Guidelines and Best Practices
8.7.9.1 General Guidelines
-
Default to local (private) for data members
-
Use protected for data shared with derived classes
-
Make only interface methods public
-
Always validate in setters
-
Provide getters only when needed
-
Keep public interface minimal and stable
8.7.9.2 Naming Conventions
-
Prefix private members with underscore: _internal_data
-
Use get_/set_ prefix for accessors: get_value(), set_value()
-
Use verb names for methods: calculate(), validate()
8.7.9.3 Documentation
-
Document public interface thoroughly
-
Explain validation rules in setter comments
-
Note which methods are virtual/overridable
8.7.9.4 Testing
-
Test all validation in setters
-
Test boundary conditions
-
Verify encapsulation - try to access private from outside