Lack of constructs with a sensitivity list

One of the features that the two classical Hardware Description Languages Verilog and VHDL support are constructs that allow a sensitivity list. For VHDL this is the process:

sensitive_proc: process(clk, rst) is
begin
-- sensitive_proc is now sensitive on clk and rst
end process;

and for verilog this is the always block:

always @(clk, rst) begin
// code in here is now sensitive on clk and rst
end;

In CIRCT no such construct exists (if such a construct exists in a dialect and I just wasn’t able to find it, I’m sorry for not having searched thoroughly). What is the rationale behind not implementing such a feature or is this feature planned but not implemented yet?

There are sv.always, sv.alwayff, sv.always_comb. Are those what you are looking for?

Not quite, I‘m looking for something more abstract, i.e. something that‘s not connected to a particular language?

1 Like

No, we don’t have what you’re looking for. Those are behavioral constructs whereas the other “core” dialects (hw/comb/seq) are intentionally structural.

I see. Are you planning to add a behavioral dialect (or a family of such dialects) at any time in the future?

I don’t think there have been any plans along these lines. So far, we’ve only supported (System) Verilog, and the existing behavioral constructs live in the SV dialect, to directly model SV’s semantics. I am less familiar with VHDL, and I don’t know how well abstracting over both SV and VHDL’s behavioral semantics would go.

The constructs are more or less the same as far as I can see. In Verilog, you would write something along the lines of

always @ (a, b, posedge c, negedge d) begin
  // statements
end

In VHDL, a compact notation which includes statements is not possible, i.e. the same statement as above would be written like this:

process (a, b, c, d) is
begin
    if rising_edge(c) or falling_edge(d) begin
        -- statements
    end if;
end process;

in other words: VHDL is more verbose but the effects during simulation are the same.

A potential behavioral dialect could combine the constructs of both languages like so:

%0 = behav.posedge %c : i1
%1 = behav.negedge %d : i1

behav.process(%a, %b, %0, %1) {
    // Statements
}

I think such a dialect could be particularly interesting as a target for new hardware description languages that allow behavioral modeling of circuits.

I’d have to go read the specs to understand the details, but if it is possible to generalize that could be interesting.

Like the rest of MLIR/LLVM, CIRCT features are generally developed as the need arises. Do you have a use-case in mind for such a behav dialect? Since we only support (System) Verilog emission, I’m not sure what the extra layer of abstraction provides versus using the sv.always family of ops (and seq, for the specific case of sequential registers).

This is why the next-gen HDLs that have been targeting CIRCT have so far used the sv dialect when they need generalized sensitivity lists, or seq when they need registers specifically. That said, if you have a use-case for the behav dialect, and would be willing to help design and implement it, I’m sure the community would be happy to discuss such an addition.

1 Like

I don’t have a specific use-case in mind, it’s more or less an abstract “it would be nice to have something like this for next-gen languages that also allow behavioral modeling”. One thing that I was wondering, however, is why there are abstract options available for structural modeling, but not for behavioral modeling (since theoretically an and operation could just as easy reside in the sv dialect).
As far as I understand, structural modeling is the only way to taget actual hardware (a behavioral model has to be converted to a net list or similar by the means of scheduling, allocation, binding, e.t.c. first). Behavioral modeling on the other hand is generally simpler to write and easier to simulate (please correct me if I’m wrong here).
I hope that I correctly understand the sv dialect as necessary evil since hardware tools generally only accept the languages Verilog, VHDL (and sometimes SystemC). Ideally, it would be great to get an IR that is both supported by common tools and not dependent on a real-world language.

Thinking out loud, one potential use-case does come in mind. If I remember correctly, there was some talk about a potential simulator that targets CIRCT dialects. As it stands now, this simulator has to understand the sv dialect (again, please correct me if I’m wrong) but it would be far simpler if such a simulator only had to cope with core dialects (plus the llhd Dialect and maybe more “exotic” dialects such as the handshake or FSM dialect using a plugin model or similar). A behavioral dialect might just close the gap between high-level languages and a simulator that wants to simulate behavioral models too, without having to deal with Verilog.

I would gladly help design and implement such a dialect, but only when the consensus is that there could actually be some use in the dialect via the scenarios that I have described above.

This is a good question, and one answer might just be nothing has needed it yet. Let me try to expand, and explain the current state.

The hw/comb/seq dialects are trying to take a first-principles look at modeling structure, combinational logic, and sequential logic in an SSA-based compiler. They’re designed to be easy to analyze and transform (for example all the transforms in CombFolds.cpp).

On the other hand, the SV dialect is designed to model (System) Verilog language constructs more or less 1:1. As you surmise, this is a necessary evil, because the tools consume (System) Verilog, not CIRCT’s IRs (yet). It’s not really good for analysis and transformation, its sole purpose (so far) is to help give some structure the (System) Verilog emitter can use to guide the emission.

The hw/comb/seq dialects exist because they support the modeling, analysis, and transformation the community needed. The behavioral stuff just hasn’t been as much of a concern yet. It has only come up in the context of needing to be emitted with the right format, so it has remained a thing in the SV dialect. As soon as there is a need for a more rich behavioral analysis/transformation framework (e.g. for a simulator), it could make sense. We just haven’t had such a need yet.

1 Like

Thanks a lot for that elaborate explanation, that clears up a lot for me!
I will fiddle around with some concepts and potentially update this thread when something emerges