olofk / fusesoc

Package manager and build abstraction tool for FPGA/ASIC development
BSD 2-Clause "Simplified" License
1.21k stars 246 forks source link

Dealing with Generators that depend on Generators #248

Closed benreynwar closed 5 years ago

benreynwar commented 5 years ago

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.

benreynwar commented 5 years ago

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.

benreynwar commented 5 years ago

Replaced by issue #251.