In the early days of verification, engineers used simple Verilog tasks and functions. But as chip designs became more complex (think of your smartphone's processor with billions of transistors!), we needed a better way to organize our testbench code.
Consider this scenario: You're verifying a memory controller that handles read and write transactions. Each transaction has an address, data, and transaction type. Without classes, you'd have to pass these as separate variables everywhere:
task drive_transaction(
input [31:0] addr,
input [63:0] data,
input [1:0] trans_type,
input [3:0] burst_length,
input lock,
// ... and 10 more signals!
);
// Too many parameters to manage!
endtask
This approach becomes a nightmare when you have 20+ parameters. Classes solve this by bundling related data and operations together in a single, reusable package.