llvm / circt

Circuit IR Compilers and Tools
https://circt.org
Other
1.62k stars 281 forks source link

Pre-RFC: language-agnostic module parameterization system #3018

Open teqdruid opened 2 years ago

teqdruid commented 2 years ago

I am facing a problem which is much larger than I anticipated it being: module parameterization or -- more generally -- configuration of the subsystems we produce. The SystemVerilog we have is intended to be as re-usable as possible, which is accomplished via SystemVerilog module parameterization. This scheme works fine if one sticks to the SystemVerilog world, but once we leave that world (and enter any other world, not just CIRCT) an alternative must be used, and it is often very ad-hoc. Integrating into existing code is often difficult since the existing SystemVerilog code's parameters must be matched with the generators' configuration(s).

To elaborate, I have three separable problems I'd like to solve. We could come up with ad-hoc methods for each one separately, but I suspect there's merit to coming up with a solution to all 3 as I see them as related. In ascending order of pain:

  1. Since we (at Microsoft) deal with instance placements, we need to output instance paths identifying where in the instance hierarchy CIRCT modules get instantiated. We have a robust way to generate said instance paths within the CIRCT world, but all bets are off at the boundaries between hand-written RTL and CIRCT. We currently require users to specify by hand where the CIRCT modules are located in the existing instance hierarchy, which is brittle.

  2. At some point in the not-too-distant future (read: the next month or so), CIRCT will output scheduled RTL from a higher-level model. Since the interfaces to these modules won’t always have latency-insensitive ports, SystemVerilog may need to know the IO schedule (since it needs to know when data is valid). One can think of this as configuring the hand-written SystemVerilog. A variant of this problem is fairly common: users want to verify that their code generation is producing what they requested (and possibly adapting to what was produced). IP-XACT is the only example I can think of as an attempt to standardize a solution.

  3. Users want to instantiate parameterized modules from SystemVerilog and while CIRCT has the capability to output parameterized SystemVerilog modules, PyCDE doesn't use them. We prefer to use Python constructs to parameterize the design, and hand-off Python-parameterized modules to CIRCT. So configuring the generated modules has be done outside of the instantiation site, which is acceptable for coarse-grained IP blocks but not so much for many smaller ones. This one in particular seems to be a very common problem: every code generator ever has a custom specification.

Before I continue, does there exist some solution that solves one or more (ideally all) of these problems? Ideally, users would be able to parameterize modules in a language agnostic way inline with the SystemVerilog instantiation, then have available somewhere later in the compile output metadata from the codegen tool. Is there some system which SiFive uses? The hw.generator.schema is a pretty basic example of part of what I need.

If not, does it make sense to have a dialect to support this goal? Could have multiple inputs (e.g. json, restricted mini-language embedded in SV), multiple outputs (e.g. SV packages, IPXACT), would mutable (so generators could add metadata), and be easy to interface with from CIRCT code. If so, I'll put together a rough RFC for said system.

mikeurbach commented 2 years ago

I think this is an interesting topic, and certainly worthy of a discussion and broader RFC. I am less sure about the existing options solutions around this, but I will think on it.