<?= code ?>
<?
    func bitSum(ports) {
       bitSum := 0;
       for (i:=0; i<sizeOf(ports); i++)
         bitSum = bitSum + ports[i].bits;

       return bitSum;
    }

    func rangeDecl(bits) {
        if (bits > 1)
            return  "[" + (bits - 1) + ":0] ";
        else
            return "";
    }

    func getBitIndex(pos, bits) {
       if (bits = 1)
         return pos;
       else
         return (pos+bits-1) + ":" + pos;
    }

    func getSliceExpr(signal, pos, bits) {
        if (bits = 1)
            return signal + "[" + pos + "]";
        else {
            result := "{";
            for (i := (pos+bits-1); i >= pos; i=i-1) {
                result = result + signal + "[" + i + "]";
                if (i > pos)
                    result = result + ", ";
            }
            result = result + "}";

            return result;
        }
    }

    inBits := bitSum(inputs);
    outBits := bitSum(outputs);

    if (inBits > 1)
        export inRange := "[0:" + (inBits - 1) + "] ";
    else
        export inRange := "";

    if (outBits > 1)
        export outRange := "[0:" + (outBits - 1) + "] ";
    else
        export outRange := "";
?>
module stdIOInterface;
    reg <?= inRange ?>mainIn;
    wire <?= outRange ?>mainOut;
<?

    pos := 0;
    if (inBits > 1) {
        for (i:=0; i<sizeOf(inputs); i++) {
            print("    wire ", rangeDecl(inputs[i].bits), "in_", inputs[i].name, " = ", getSliceExpr("mainIn", pos, inputs[i].bits), ";\n");
            pos = pos + inputs[i].bits;
        }
    }

    pos = 0;
    if (outBits > 1) {
        for (i:=0; i<sizeOf(outputs); i++) {
            print("    wire ", rangeDecl(outputs[i].bits), "out_", outputs[i].name, ";\n");
        }

        for (i:=0; i<sizeOf(outputs); i++) {
            print("    assign ", getSliceExpr("mainOut", pos, outputs[i].bits), " = out_", outputs[i].name, ";\n");
            pos = pos + outputs[i].bits;
        }
    }
?>
    integer res, exit;

    <?= moduleName ?> <?= moduleName + "_inst" ?> (
<?
    if (inBits > 1) {
        for (i:=0; i<sizeOf(inputs); i++) {
            print("        .", inputs[i].name, "(in_", inputs[i].name,"),\n");
        }
    } else {
        print("        .",inputs[0].name,"(mainIn),\n");
    }

    if (outBits > 1) {
        outCount := sizeOf(outputs);
        for (i:=0; i<outCount; i++) {
            print("        .", outputs[i].name, "(out_", outputs[i].name, ")");

            if (i < outCount-1)
                print(",\n");
        }
    } else {
        print("        .", outputs[0].name, "(mainOut)");
    }
?>
    );

    initial begin
        exit = 0;
        while (exit == 0)
        begin
            res = $fscanf('h8000_0000, "%b", mainIn);
            #1;

            if (res == 1) begin
                $display("Digital:%b", mainOut);
                $fflush('h8000_0001);
            end
            else
                exit = 1;
        end
    end
endmodule