interface Interface(i); input i; logic v; logic o; task tick; $display("I i = %b, v = %b, o = %b", i, v, o); endtask initial $display("Hello I'm Interface!"); modport ModportA( input .i(i ^ 1'b1), output v ); modport ModportB( input .i(i), output .v(o) ); endinterface module ModuleA(i); parameter flip = 0; Interface i; assign i.v = i.i ^ 1'(flip); task tick; $display("A i.v = %b", i.v); endtask initial $display("Hello I'm ModuleA %0d!", flip); endmodule module ModuleASet(is); parameter flip2 = 0; parameter flip1 = 0; parameter flip0 = 0; Interface is [2:0]; assign is[2].v = is[2].i ^ 1'(flip2); assign is[1].v = is[1].i ^ 1'(flip1); assign is[0].v = is[0].i ^ 1'(flip0); task tick; $display("AS i.v = %b", is[2].v); $display("AS i.v = %b", is[1].v); $display("AS i.v = %b", is[0].v); endtask initial begin $display("Hello I'm ModuleASet %0d %0d %0d!", flip2, flip1, flip0); end endmodule module ModuleCSet(is); parameter flip2 = 0; parameter flip1 = 0; parameter flip0 = 0; Interface.ModportB is [2:0]; assign is[2].v = is[2].i ^ 1'(flip2); assign is[1].v = is[1].i ^ 1'(flip1); assign is[0].v = is[0].i ^ 1'(flip0); task tick; $display("CS i.v = %b", is[2].v); $display("CS i.v = %b", is[1].v); $display("CS i.v = %b", is[0].v); endtask initial begin $display("Hello I'm ModuleCSet %0d %0d %0d!", flip2, flip1, flip0); end endmodule module ModuleB(is); parameter WIDTH = 1; Interface is [WIDTH-1:0]; logic [WIDTH-1:0] i_concat; logic [WIDTH-1:0] v_concat; for (genvar i = WIDTH - 1; i >= 0; i = i - 1) begin assign i_concat[i] = is[i].i; assign v_concat[i] = is[i].v; end task tick; $display("B i_concat = %b, v_concat = %b", i_concat, v_concat); bn.tick; endtask initial $display("Hello I'm ModuleB %0d!", WIDTH); ModuleBNested #(WIDTH) bn(is); endmodule module ModuleBNested(is); parameter WIDTH = 1; Interface is [WIDTH-1:0]; logic [WIDTH-1:0] i_concat; logic [WIDTH-1:0] v_concat; for (genvar i = WIDTH - 1; i >= 0; i = i - 1) begin assign i_concat[i] = is[i].i; assign v_concat[i] = is[i].v; end task tick; $display("BN i_concat = %b, v_concat = %b", i_concat, v_concat); endtask endmodule module top; logic inp; Interface intfX[2:0](inp); ModuleA #(0) xa2(intfX[2]); ModuleA #(1) xa1(intfX[1]); ModuleA #(1) xa0(intfX[0]); ModuleB #(3) xb20(intfX[2:0]); ModuleB #(2) xb21(intfX[2:1]); ModuleB #(1) xb22(intfX[2:2]); ModuleB #(1) xb11(intfX[1:1]); ModuleB #(1) xb00(intfX[0:0]); ModuleB #(3) xbf(intfX); ModuleASet #(1, 1, 0) xs(intfX[2:0].ModportB); Interface intfY[2:0](inp); ModuleA #(0) ya2(intfY[2].ModportA); ModuleA #(1) ya1(intfY[1].ModportA); ModuleA #(1) ya0(intfY[0].ModportA); ModuleB #(3) yb20(intfY[2:0].ModportA); ModuleB #(2) yb21(intfY[2:1].ModportA); ModuleB #(1) yb22(intfY[2:2].ModportA); ModuleB #(1) yb11(intfY[1:1].ModportA); ModuleB #(1) yb00(intfY[0:0].ModportA); ModuleB #(3) ybf(intfY.ModportA); ModuleCSet #(0, 0, 1) ys(intfY[2:0]); initial begin inp = 0; tick; inp = 1; tick; inp = 0; tick; inp = 1; tick; end task tick; #1; intfX[2].tick; intfX[1].tick; intfX[0].tick; xa2.tick; xa1.tick; xa0.tick; xb20.tick; xb21.tick; xb22.tick; xb11.tick; xb00.tick; xbf.tick; xs.tick; intfY[2].tick; intfY[1].tick; intfY[0].tick; ya2.tick; ya1.tick; ya0.tick; yb20.tick; yb21.tick; yb22.tick; yb11.tick; yb00.tick; ybf.tick; ys.tick; endtask endmodule