State the Use parameters and parameter definition modules.
Parameters aren't preprocessor definitions and they have scope (for example parameters are associated with specific modules). Parameters are hence more clean, and if you are in the habit of using a lot of defines; consider switching to parameters. As an instance, let's say we have a test (e.g. test12) that needs many parameters to have specific settings. In your code, you might have this sort of stuff:
module testbench_uart1 (....)
parameter BAUDRATE = 9600;
...
if (BAUDRATE > 9600) begin
... E.g. use parameter in your code like you might any general variable
... BAUDRATE is completely local to this module and this instance. You might
... have the same parameters in 3 other UART instances and they'd all be different
... values...
Now, your test12 has all sorts of settings required for it. Let's define a special module known as testparams that specifies all these settings. It would itself be a module instantiated under testbench:
module testparams;
defparam testbench.cpu.uart1.BAUDRATE = 19200;
defparam testbench.cpu.uart2.BAUDRATE = 9600;
defparam testbench.cpu.uart3.BAUDRATE = 9600;
defparam testbench.clockrate CLOCKRATE = 200; // Period in ns.
... etc ...
endmodule
Above module always has same module name though you would have many different filenames; one for each test. So, above would be kept in test12_params.v. Your Makefile includes appropriate params file given desired make target. (BTW: You may run across this sort of approach by ASIC vendors who might have a module containing parameters for a memory model or you might see this used to collect together a large number of system calls which turn off timing or warnings on particular troublesome nets, etc.)