-
Notifications
You must be signed in to change notification settings - Fork 239
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
Add Configurable Generators #251
Comments
Hi @benreynwar I had totally missed this one. Just writing to know that I've seen it now. Unfortunately I have only taken the time for a quick look and not yet had time to think properly about your suggestions |
@olofk This is two years old so I don't really remember what I was thinking. It all looks a bit complicated looking at it now, but perhaps there are some useful ideas in there :). |
Haha. Before seeing your latest comment, I just started reading through it thinking it all looked very complicated and that it would need to take time to wrap my head around it :) As you say, it might be too complicated, I'm not sure at this point. One point that directly stood out is how we can intertwine verilog/vhdl parameters/generics with generator parameterization (is that a word?). I think that this could be reasonably solved with variable substitution in the core files which is on the roadmap. The big thing I think we haven't solved is the diplomacy aspect of passing configuration upstream. That's one tricky bit and I honestly hope we can get around it in other ways instead |
Yep. I agree that generics to generator parameterization would be really useful and that the upstream configuration is more trouble than it's worth. I mainly need generics to generator parameterization for configuring compiled memories. Currently I do this creating a stub vhdl file for my memories that just logs the depth and width of the memory to stdout. I call fusesoc to generate all my files, then use ghdl to run a 0 clock cycle simulation which causes all the widths and depths of my memories to get logged to stdout. I have a little script that then collects these widths and depths and writes them to a file. I then call fusesoc again and this time the memory generator uses that file to generate all the appropriate memories. It works, but it's a bit ugly. I'm unsure what the best way to integrate this kind of functionality into fusesoc is, or how generally useful it would be. On a slightly higher level, we have all these cool hdl generators like migen and chisel, but it's not clear how a chisel design would instantiate a migen design, if the parameters for the migen design are some function of the parameters for the chisel design. Fusesoc feels like a good place to create conventions for how to pass elaboration parameters through a hierarchy of generators. Realistically I don't think this is actually a real problem yet :). Hopefully in the future we'll have lots of open-source designs that depend on each other and we'll have to start worrying about it! Feel free to close this issue, since I don't think there is any direction action that needs to be taken for it. |
I've run into this with my
|
Configurable Generators
At the moment all the parameters for a 'generator' must be fully
specified in the core file with the corresponding 'generate' (ttctg).
It would be useful to have a 'generate' that doesn't specify the
parameters of the generator. We'll call generators that don't require
the 'generate' to specify the parameters as 'Configurable Generators',
as opposed to the current 'Nonconfigurable Generators'.
Configurable Generators can be configured in four ways;
While making this change it also makes sense to add the ability for
cores to pass parameters to their parent generators (see issue #250)
Both configurable and unconfigurable generators would receive these
parameters.
The motivation for these changes are described in issue #248 which I'm
replacing with this issue.
Configuration Implementation
Each core contains filesets and generates(ttctg). These
filesets/generates within each core can be arranged into a dependency
order. Each fileset or generate can have dependencies on other cores.
Build a dependency tree of filesets/generates. A dependency on a
core, is changed to a dependency on the fileset/generate at the
top of that cores dependency order.
Generators are divided into configurable and nonconfigurable
generators. We classify filesets and configurable generators as
nonconfigurable components. Configurable generators are
configurable components.
We now have a dependency tree containing configurable and
nonconfigurable components. Nonconfigurable components that are
directly connected in the dependency tree are grouped into
neighbourhoods. We now have a dependency tree of configurable
generators and neighbourhoods.
Each configurable generator and neighbourhood has a 'configure'
method. A configure method receives a set of configuration
parameters from it's parent. During execution a configure method
calls the configure methods of the children. These configure calls
return parameters. It saves it's state, and returns parameters to
it's parent. How this is done is different for a configurable
generator vs a neighbourhood. For a configurable generator the
'configure' method just calls the 'configure_command' specified
in it's core file.
Fileset neighbourhoods receive parameters either from the command
line (if they are at the top-level) or from a parent generator. If
a fileset neighbourhood has no child generators, then all the
configure method does is directly return any 'back_parameters'
defined in the top core. If a fileset neighbourhood has any child
generators that need to receive parameters then a simulation of the
neighbourhood is run using 'target=configure'. The child generators
must have the 'configurable_from_fileset' property. This means that
when 'target=configure' they generate a stub file that logs the
generics/parameters with which they were instantiated to stdout.
The generics/parameters are extracted from stdout and are then
passed to the appropriate generator configure calls as parameters.
If the fileset neighbourhood contains nonconfigurable generators
then these must be run before the simulation is run.
Because generators can save state on a call to configure a second
call to configure can produce different parameters. Using this it
is possible to support the chisel diplomacy protocol. The
convention is that if the top-level generator returns a parmeter of
'run_config_again'=True then configure should be run again.
Generation
Once configuration is complete generation is run. Any unconfigurable
generators that haven't been run yet are run. The generate methods
on the configurable generators are called.
Changes Required for CAPI2 core definition
Although this involves a bunch of changes to fusesoc itself it
has a pretty minimal effect on the core definitions.
fileset
generator
generate
The text was updated successfully, but these errors were encountered: