Let me focus on a simplified example.
First consider the sine generator as a simple component with no hierarchy. Conceptually it is as simple as this:
Code: module sinegen(out, freq, ampl, phase, offset);
output electrical out;
input wreal freq, ampl, phase, offset;
analog V(out) <+ ampl*sin(freq*$abstime + phase) + offset;
endmodule
I'm don't really understand why you want to instantiate the filter in the generator, but conceptually here is how you would do it:
Code: module sinegen(out, freq, ampl, phase, offset);
output electrical out;
input wreal freq, ampl, phase, offset;
electrical in;
lpf(.o(out), .i(.in));
analog V(in) <+ ampl*sin(freq*$abstime + phase) + offset;
endmodule
Having said that, this generator has a number of issues. First, it is filled with discontinuities. They should be eliminated with transition functions.
Code: module sinegen(out, freq, ampl, phase, offset);
output electrical out;
input wreal freq, ampl, phase, offset;
parameter tt=1u from [0:inf);
analog V(out) <+ transition(ampl, 0, tt)*sin(transition(freq, 0, tt)*$abstime + transition(phase, 0, tt)) + transition(offset, 0, tt);
endmodule
For efficiency sake you want to make the transition time
tt as long as possible.
Second, when you are generating a high frequency output when there is no corresponding high frequency input, you need to inform the simulator so you don't get aliasing. You do that by adding a bound on the time step.
Code: module sinegen(out, freq, ampl, phase, offset);
output electrical out;
input wreal freq, ampl, phase, offset;
parameter tt=1u from [0:inf);
analog begin
V(out) <+ transition(ampl, 0, tt)*sin(transition(freq, 0, tt)*$abstime + transition(phase, 0, tt)) + transition(offset, 0, tt);
$bound_step(10/freq);
endmodule
I use ten points per period. You probably need at least 4, but realize that the larger you make this number the slower you simulation will be.
Finally, you need to synchronize your kernels, meaning that you need to force the analog simulator to place time points at the events in the digital inputs. Conceptually you can do that with:
Code: module sinegen(out, freq, ampl, phase, offset);
output electrical out;
input wreal freq, ampl, phase, offset;
parameter tt=1u from [0:inf);
analog begin
@(freq or ampl or phase or offset)
;
V(out) <+ transition(ampl, 0, tt)*sin(transition(freq, 0, tt)*$abstime + transition(phase, 0, tt)) + transition(offset, 0, tt);
$bound_step(10/freq);
endmodule
I say conceptually because even though that is legal Verilog-AMS code, Cadence has never supported arbitrary events in the analog block, so it must be rewritten as:
Code: module sinegen(out, freq, ampl, phase, offset);
output electrical out;
input wreal freq, ampl, phase, offset;
parameter tt=1u from [0:inf);
reg break = 0;
always @(freq or ampl or phase or offset) break <= !break;
analog begin
@(posedge break or negedge break)
;
V(out) <+ transition(ampl, 0, tt)*sin(transition(freq, 0, tt)*$abstime + transition(phase, 0, tt)) + transition(offset, 0, tt);
$bound_step(10/freq);
endmodule
I just typed this code in from memory, so it might not work as given. But hopefully you find it useful.