They have 2 different paradigms - icarus verilog lets you write your testbenches in non-synthesizable verilog (which lets you use wait/delay statements), while verilator converts your verilog into a C++ class, which you instantiate and then testbench in C++ or Python ( timing is usually controlled with a small
tick
function that ticks the clock, advances time, and saves waveforms)