Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expanded interface instance #230

Open
michael-lehn opened this issue Feb 25, 2023 · 3 comments
Open

expanded interface instance #230

michael-lehn opened this issue Feb 25, 2023 · 3 comments

Comments

@michael-lehn
Copy link

michael-lehn commented Feb 25, 2023

I am using netlistsvg to visualize my SystemVerilog design after translating it to Verilog with sv2v. This works nice. However, when the design uses interfaces I have to use some workaround in order to hide details of modules in my visualization. I have added some toy example to describe what I am doing. What I would like to discuss is whether there is a better way to do it ...

Toy example without interface instance

Details of module foo should be hidden in the overall visualization:

module foo(
    input logic a,
    input logic b,
    output logic out0,
    output logic out1
);

    always_comb begin
        out0 = a & b;
        out1 = a | b;
    end

endmodule

In the top level module it will be used as some black box:

module test (
    input BTN1,
    input BTN2,
    output logic LED1,
    output logic LED2
);

    logic a, b, out0, out1;
    assign {a, b} = {BTN1, BTN2};
    assign {LED1, LED2} = {out0, out1};


    foo foo0(
        .a(a),
        .b(b),
        .out0(out0),
        .out1(out1)
    );

endmodule

And this is exactly what is shown here:

test1

Toy example with interface instance

In general modules will have lots of pins. For convenience I would like to use interfaces. So here I would define the interface as follows:

interface if_foo;
    logic a;
    logic b;
    logic out0;
    logic out1;

    modport mp(
        input a,
        input b,
        output out0,
        output out1
    );

endinterface

Here the adapted module foo

module foo(
    if_foo.mp mp
);

    always_comb begin
        mp.out0 = mp.a & mp.b;
        mp.out1 = mp.a | mp.b;
    end

endmodule

Here the adapted top module

module test (
    input BTN1,
    input BTN2,
    output logic LED1,
    output logic LED2
);

    if_foo foo();

    assign {foo.a, foo.b} = {BTN1, BTN2};
    assign {LED1, LED2} = {foo.out0, foo.out1};

    foo foo0(
        .mp(foo.mp)
    );

endmodule

Because sv2v expands the interface instance the details of foo show up:

test2

My workaround

In oder to use interfaces in my code but at the same time hide details in the visualization I write two versions for modules that use interfaces. In this case a "low level (ll)" module foo_ll:

module foo_ll(
    input logic mp_a,
    input logic mp_b,
    output logic mp_out0,
    output logic mp_out1
);

    always_comb begin
        mp_out0 = mp_a & mp_b;
        mp_out1 = mp_a | mp_b;
    end

endmodule

And a high level module foo which just connects the pins:

module foo(
    if_foo.mp mp
);

    foo_ll foo_ll0(
        .mp_a(mp.a),
        .mp_b(mp.b),
        .mp_out0(mp.out0),
        .mp_out1(mp.out1)
    );

endmodule

With that details are still hidden in the visualization behind the low level module:

test

So this actually works for me but I wonder if something like this could be directly supported by sv2v.

@michael-lehn
Copy link
Author

Would you like to comment?

@zachjs
Copy link
Owner

zachjs commented Apr 13, 2023

Thank you for taking the time to explain your use case!

The interface conversion wasn't designed with this usage in mind. Some interfaces can only be correctly converted via inlining, so I decided to inline always rather than maintaining two interface conversion strategies. I can imagine having it conditionally elaborate modports a series of ports instead (i.e. preserve the module hierarchy), but adding this alongside the existing implementation would be a significant undertaking. sv2v used to work this way in v0.0.5 and prior. You may want to give that a try in the mean time, though a lot has changed (and improved!) in the three years since.

It may also be possible to handle this transformation within netlistsvg itself. Naively, this might entail some form of graph contraction: take all vertices foo.bar.* and contract them into a bar module with the necessary ports.

@ThanasisVlioras
Copy link

This is something that I also want to see work without any workarounds. Great explanation of the problem michael!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants