A few named constructs in SystemVerilog, including lets and sequences, allow untyped formal arguments. Another example, from 25.3.3, is that module ports can be declared as generic interface references. This was originally intended for “generic bundles” of signals, but, because functions and types (and even always blocks) can also be wrapped up in an interface and passed around, I was wondering if this capability could be exploited to achieve generic programming with SystemVerilog. Here’s an example showing that it might be possible.

/* ------------------------------------------------- Given an interface that defines types "T_in" and "T_out" and a function "f" from one to the other, define a function "lookup" with the same signature as "f", but implemented as a lookup table. ------------------------------------------------- */modulelut_template(interfaceifc);typedefifc.T_in T_in;typedefifc.T_out T_out;localparamN = $bits(T_in); T_out A[2**N];for(genvarI = 0; I < 2**N; I++)begin:GENassignA[I] = ifc.f(T_in'(I[0+:N]));endtypedef logic[N-1:0] T_index;function automaticT_out lookup(T_in in);returnA[T_index'(in)];endfunctionendmodule:lut_templatemoduletest#(parameterN = 3)(output logic[2*N-1:0] out); example#(3) ex1(); lut_template lut1(ex1);always_combout = lut1.lookup('{5,7}); /* == 35 */initial begin#1 $display(out);end endmodule:testinterfaceexample#(parameterN = 1);typedef struct{logic[N-1:0] x, y;} T_in;typedef logic[2*N-1:0] T_out;function automaticT_out f(inputT_in in);return(in.x * in.y);endfunction endinterface:example

Advertisements