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 VLSI 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
