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

"Late generators" to generate toplevel #250

Open
imphil opened this issue Mar 15, 2019 · 5 comments
Open

"Late generators" to generate toplevel #250

imphil opened this issue Mar 15, 2019 · 5 comments
Labels
type:feature new functionality

Comments

@imphil
Copy link
Collaborator

imphil commented Mar 15, 2019

I'd like to use a generator to build our toplevel file. We have the following setup:

  • Each register-mapped IP core comes with a small config file describing its register map.
  • I have a "toplevel template", which is processed by the generator to produce SystemVerilog output.
  • The "toplevel template" includes code like "include vendor:ip:uart"
  • Now the generator script needs to
    1. Find the IP core matching "vendor:ip:uart"
    2. Get the config file for this core

Step (ii), getting the config file for a core is easy: just add the config file as type=data source file to the *.core file.

Step (i) is the tricky one. Ideally, I'd get a list of resolved dependencies from fusesoc, look up the "vendor:ip:uart" name there, and go from there. AFAIK, that's currently not possible: generators run and create a *.core file and other generated source code files before the dependency tree is resolved.

So what I'm looking for is a generator that (a) generates its core file during the dependency tree building, and (b) again after the dependency tree is resolved to generate the SystemVerilog toplevel file.

Is there another (easier?) way of doing that? Otherwise I think this feature might be easy to add: just call the generator script twice with a parameter in which phase it is called.

@olofk @benreynwar any thoughts or ideas?

@benreynwar
Copy link
Contributor

Even if you resolved the dependencies first, it's not clear how fusesoc would know to pass the required information to the generator.

I think the simplest solution would be to just use the fusesoc package inside the generator to parse the core file and find the config file. Recursive fusesoc all the way down!

More generally this is the issue that the chisel people were trying to solve with Diplomacy. It would be good for fusesoc to have a compatible mechanism for cores to pass parameters to parent generators.

@benreynwar
Copy link
Contributor

How about if a core had a 'back_parameters' property? If a generator has a dependency on a core with a 'back_parameters' property then those parameters are passed to the generate executable.

@olofk
Copy link
Owner

olofk commented Mar 17, 2019

The dependency list is actually resolved by the time the generators are executed. There's also a new (since 1.9.1) parameter called position to add some control over generator ordering. By setting position : last it should execute after all other cores have been exported (Note: this isn't actually the case right now, but it's fixable. I'll leave the longer explanation for now). What I believe is the only thing missing is to pass the list of dependencies (and probably where their files were exported) to the generators. This is something I have considered adding before, I believe it was for pretty much the same use case you have, e.g. something that needs to pick up pieces of config (like a device tree generator) from all cores. I think this should just be a matter of identifying which extra info is needed, add it to the GAPI and bump the GAPI verison

@imphil
Copy link
Collaborator Author

imphil commented Dec 17, 2020

An implementation we use in OpenTitan is at lowRISC@d97a348. Needs to be prepared for a PR once all dependencies are in.

@imphil imphil added the type:feature new functionality label Dec 18, 2020
@olofk
Copy link
Owner

olofk commented Feb 25, 2021

Looking at it today I see several potential ways to fix this, but it depends a bit on what information we have and need.

If this would operate with the EDAM file as both input and output, it would actually be better suited to be implemented as a node in the next-gen Edalize https://github.com/olofk/edalize/wiki/Edalize-(Slight-return) At the same time, this is a bit further ahead in the future.

So what could we do in the context of FuseSoC instead? We need to hook in at the point where the EDAM is completely created and we know all cores, right? This is normally after the top-level core has been analyzed But not always, since we can have genetarors with pos : last. So with that in mind, I wonder if we instead need another mechanism that doesn't create new cores but allows modifications on the edam file. I don't know, more like a filter or something like that

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

No branches or pull requests

3 participants