... and here's one if you prefer string input for the pwl (e.g., pwl="0.0, 0.0, 0.5, 1.1, 1.0, -1.1,..."). It does use the non-standard string .len() operator from System-Verilog, and so may not be suitable for your application.
Code:module strpwl(p, n);
electrical p, n;
inout p, n;
parameter string pwl = "";
parameter dcval = 0.0;
analog function real scanval;
input s;
inout pos;
string s;
integer pos;
integer ipos;
string valstr;
begin
ipos = pos;
while(pos < s.len() && s.substr(pos, pos) != ",")
pos = pos+1;
valstr = s.substr(ipos, pos-1);
if(1 == $sscanf(valstr, "%g", scanval))
pos = pos+1;
else
pos = -1; // Error indicator
end
endfunction
integer pos = 0;
real tnext, vnext;
real tprev = 0.0;
real vprev = dcval;
real slope;
integer err;
analog initial begin : blk
real retVal;
tprev = 0.0;
vprev = dcval;
tnext = scanval(pwl, pos);
vnext = scanval(pwl, pos);
if (tnext-tprev != 0.0)
slope = (vnext - vprev)/(tnext - tprev);
$strobe(tnext, vnext);
end
analog begin
@(timer(tnext)) begin
tprev = tnext;
vprev = vnext;
tnext = scanval(pwl, pos);
vnext = scanval(pwl, pos);
if(pos > 0)
begin
if(tnext - tprev <= 0) begin
err = 1;
$debug("Non monotonic time sequence.");
$finish;
end
if(!err)
slope = (vnext - vprev)/(tnext - tprev);
end
end
if(!err)
V(p, n) <+ vprev + slope*($abstime - tprev);
end
endmodule