SV dialect interface modports

I want to lower an ESI connection to a SV interface and connect its modports it to an RTL module. The RTL dialect’s ModuleOp only takes Types as ports whereas the SV dialect models interfaces’ modports as instructions… How should I do this? (It doesn’t seem possible currently.) Should I be trying this?

More generally, how should the SV and RTL dialects inter-operate? Should it be RTL → SV only? I had imagined them being supplementary.

(Tagging @mikeurbach since he did the InterfaceOp for the SV dialect.)

I have a proposal for my specific problem: SystemVerilog interfaces are odd cats. They’re instantiated like modules but their modports are used like types in module declarations. So you’ve gotta instantiate both the interface and the modules then pass around the interface’s modports like wires.

As such, I think if we added an InterfaceModportType which pointed to the SV dialects modport that could be used to bridge the gap while also being analogous to SystemVerilog semantics. Demonstrative example:

  sv.interface @handshake_example {
    sv.interface.signal @data : i32
    sv.interface.signal @valid : i1
    sv.interface.signal @ready : i1
    sv.interface.modport @dataflow_in ("input" @data, "input" @valid, "output" @ready)
    sv.interface.modport @dataflow_out ("output" @data, "output" @valid, "input" @ready)
  }

rtl.module @foo(%a: !sv.modport<@handshake_example.dataflow_in>) ...

Tangent: @clattner – Is there a standard MLIR syntax to refer to a symbol inside another symbol’s region?

Does this seem reasonable?

This is how I was imagining it would work. I prototyped a form of this a while back and brought it up on the forums here. Things have changed in the last month and a half, but I still think what you are proposing here is generally how I would approach this.

We talked before about how the RTL dialect should be an open system. It seems like this proposal makes good use of that flexibility. I personally think a mixture of RTL and SV dialects can and should be supported, so that RTL modules can progressively be lowered to SV. Similar things happen in FIRRTL already, where you can have a mix of FIRRTL and SV that ultimately gets emitted to System Verilog.

Sorry Mike! I missed (or more likely forgot) that post. Sounds like we’re on the same page on all counts.

I’ll implement this type in the next few days.

No worries, and sounds good. After the discussion above, I put this on my back burner, but this was always something I wanted to see eventually.

BTW- I never added support for SV interfaces to EmitVerilog, but I can help out with that now that it is needed. It should be straightforward to emit the actual sv.interface ops, but I think it may be a little more involved to handle the new type.

I’ll have to create my own EmitVerilog to handle special ESI constructs and types anyway. Emitting types should be easier there. I’ll be playing around with verilog printers and/or interfaces to learn what works well and what doesn’t. You’re welcome to collaborate when I start that work!

Ah right, I remember now that is where things were heading. I’m happy to collaborate.

I’m now at the point where I need to generate SV and I’m re-thinking the need to create my own Verilog emission. I was initially planning on having the ability to generate SystemVerilog fragments to be `included in existing SV but I no longer think that’s necessary for the prototype to which I’m sprinting.

@mikeurbach – You had said you were willing to add interface emissions to EmitVerilog.cpp. Are you still willing?

I’m currently working on the type support for modports and interface instances which we discussed above. I got sidetracked for a bit so hadn’t started before today.

I’m still willing, and I am just wrapping something up, so the timing is great for me to jump on it. Since we modeled these directly on the System Verilog AST, this should be a straightforward addition to EmitVerilog.

[SV] Types to allow InterfaceOps to play with the RTL dialect by teqdruid · Pull Request #294 · llvm/circt (github.com)

Implementing this may be more complicated than I anticipated: [SV] Types and ops to allow InterfaceOps to be instantiated and passed around by teqdruid · Pull Request #294 · llvm/circt · GitHub

Just FYI I started taking a look at this with circt-translate -emit-verilog. Did you have any plans for that @jdd? I started looking into this in EmitVerilog once, so trying to dust that off.

I am not looking at it but will need it. If you were to do it, I’d appreciate it.

I’m working on a lowering pass from ESI physical to interfaceops and some pipeline stage modules in SV/RTL. Once we have RTL generation in place for interfaceops, ESI should be able to synthesize to RTL! (Then I’ll just have to debug the RTL and write/debug the cosim <–> ESI interface op bridge.)

~John

I took a crack at this in here: SV interface emission in RTL instance ports by mikeurbach · Pull Request #302 · llvm/circt · GitHub.