I'm trying to think about how to deal with generators whose parameters need to be calculated by a different generator. This is necessary to mix different verilog-generating languages, and also to be able to generate code for VHDL or verilog modules, where the generation depends on the generic parameters of the entity.
Mixed language example
We're using a migen FIFO implementation.
That FIFO is used in a chisel design.
That chisel design is instantiated in a verilog module.
Currently in using fusesoc we can create a generator for the FIFO. It will presumably take parameters of width and depth. We can also create a generator for the chisel design. The problem is that there is no way for the chisel generator to tell the FIFO generator what parameters it should use.
There is a need for generators to be able to both define the generators they depend on and to produce the parameters for those generators.
VHDL example
We have generator that produces wrappers for ASIC memory macros.
We have a VHDL design that instantiates 10 of these memories using different parameters.
How can we determine the parameters that must be passed to the generator? They will be some complex function of the generics of the top-level VHDL entity.
Proposed Solution
Introduce a hiergenerator. This is essentially a generator, with the difference that it can depend on other hiergenerators and can pass them customized parameters. For example in the first example we would have a either a standard generator or a hiergenerator for the migen FIFO, we would use a hiergenerator for the chisel design, and a hiergenerator for the verilog modules at the top of the design.
The top level hiergenerator would analyze the verilog files to determine what parameters were passed to the chisel design. This analysis could be done by adding a dummy placeholder for the chisel design which logs the parameters to a file. The parameters could be found by running the design for a short simulation.
The middle level hiergenerator would generate files from the chisel design, using the parameters passed from the top level hiergenerator.
The migen FIFO could be specified with either a standard generator, or a hiergenerator. The files would be generated from the migen design using the parameters passed from the middle level hiergenerator.
Implementation
The difference between a generator and a hiergenerator is what the executable returns. A hiergenerator returns:
A list of the required files.
A list of the required generators/hiergenerators with their parameters.
(optional) A set of parameters describing itself, to pass to it's parent hiergenerator to implement the chisel diplomacy behavior.
There would be two main kinds of hiergenerators:
Pure generation for things like migen or chisel.
VHDL or verilog hiergenerators where the source code isn't generated but is analyzed to determine the parameters to pass to child hiergenerators. These hiergenerators can explicitly list their file contents or can contain a tree of standard fusesoc cores.
Hiergenerators would list all possible cores, generators, hiergenerators that they might use in their dependency list. However for a given set of parameters they would not necessarily use all these dependencies.
Processing of cores would go as:
detect all cores that might be used by the design by following dependency tree.
Follow the dependency tree, but treat hiergenerators as leaves. Get a list of all the cores and generators that are definitely used, and a list of the hiergenerators.
Run configuration on all the hiergenerators to determine what cores they actually use, and which hiergenerators with which parameters they use.
Repeat the configuration until there are no unconfigured hiergenerators.
Path of Least Resistance
I think the simplest way to support this functionality is, when running generators, to process any generated core files. It would get messy since a hiergenerator would be implemented as a standard generator that called fusesoc again internally :(. There are probably other issues with this I haven't thought of.
I'm going to have go at implementing this outside fusesoc to get a better feel of what works, and then think about whether it makes sense to integrate it into fusesoc or not.
I'm trying to think about how to deal with generators whose parameters need to be calculated by a different generator. This is necessary to mix different verilog-generating languages, and also to be able to generate code for VHDL or verilog modules, where the generation depends on the generic parameters of the entity.
Mixed language example We're using a migen FIFO implementation. That FIFO is used in a chisel design. That chisel design is instantiated in a verilog module.
Currently in using fusesoc we can create a generator for the FIFO. It will presumably take parameters of width and depth. We can also create a generator for the chisel design. The problem is that there is no way for the chisel generator to tell the FIFO generator what parameters it should use.
There is a need for generators to be able to both define the generators they depend on and to produce the parameters for those generators.
VHDL example We have generator that produces wrappers for ASIC memory macros. We have a VHDL design that instantiates 10 of these memories using different parameters.
How can we determine the parameters that must be passed to the generator? They will be some complex function of the generics of the top-level VHDL entity.
Proposed Solution Introduce a hiergenerator. This is essentially a generator, with the difference that it can depend on other hiergenerators and can pass them customized parameters. For example in the first example we would have a either a standard generator or a hiergenerator for the migen FIFO, we would use a hiergenerator for the chisel design, and a hiergenerator for the verilog modules at the top of the design.
The top level hiergenerator would analyze the verilog files to determine what parameters were passed to the chisel design. This analysis could be done by adding a dummy placeholder for the chisel design which logs the parameters to a file. The parameters could be found by running the design for a short simulation.
The middle level hiergenerator would generate files from the chisel design, using the parameters passed from the top level hiergenerator.
The migen FIFO could be specified with either a standard generator, or a hiergenerator. The files would be generated from the migen design using the parameters passed from the middle level hiergenerator.
Implementation The difference between a generator and a hiergenerator is what the executable returns. A hiergenerator returns:
There would be two main kinds of hiergenerators:
Hiergenerators would list all possible cores, generators, hiergenerators that they might use in their dependency list. However for a given set of parameters they would not necessarily use all these dependencies.
Processing of cores would go as:
Path of Least Resistance I think the simplest way to support this functionality is, when running generators, to process any generated core files. It would get messy since a hiergenerator would be implemented as a standard generator that called fusesoc again internally :(. There are probably other issues with this I haven't thought of.