cvfpu
cvfpu copied to clipboard
FPU Configuration Discussion
FPU Configuration Discussion
There are plenty of configuration options for the FPU, almost all of which currently are passed to the top level module as parameters. This leads to a cumbersome layout and amount of parameters, since there are options for every operation and format (the number of which can be redefined in the package).
This issue aims at finding a satisfactory solution for configuring the design. Initial considerations are:
Everything through parameters (current state)
Currently, (almost) all configuration is done through parameters. The set of available FP and int formats are set up in the package and can then be enabled/disabled via parameters.
Pros
- Full control of design-space without changing RTL for different implementation options (like varying number of pipeline stages, enabling/disabling formats or operations etc.)
- Multiple versions of the FPU within one design / project easily possible - differentiated through parameter list.
Cons
- Many parameters:
- either a bulky array-of-arrays style parametrization (current, module interface independent of number of formats supported)
- or a huge list of options (module interface dependent on the number of formats defined in the pkg)
- Large amount of parameters are unrolled into long and difficult to manage module names in synthesis
- Most of these parameters are not modified anymore after an initial exploration
Everything from the package
Alternatively, all configuration could be done through parameters in the package
Pros
- No parameters cluttering up the modules
Cons
- Each configuration change requires modifying the RTL
- Only one version of the package (= FPU configuration) possible in the design
- Different configurations of FPU are not discernible through module name - alignment issues more easily possible if outdated pre-compiled design and changed RTL (in case of parameter change) are combined
A mix of the two
It might make sense to reduce the number of parameters to just the most frequently modified ones. However identifying these is difficult and cons from both options might need to be dealt with..
What is the "status" of passing in structs as parameters? Does this break outside of Synopsys DC? Otherwise we could just pass everything in as a custom struct… Maybe that's done already anyway?
I think a configuration struct makes the most sense. As far as I know that is being supported in every tool.
I would also go for structs. This seems to work fine with VCS, Verilator, Questa, DC and Vivado so far. Have a look at this for an example
I agree that a struct would be the cleanest way of configuring the FPU, and it was the desired option during the design, too. Having named struct members is definitely the most convenient for changing just part of the config, instead of passing a 2d array as it is now.
However, the issue is that the number and names of these struct members depend on the set of formats defined in the package.
Adding a new format would necessitate redefining the configuration struct type, and subsequently all uses of the configuration, i.e. the entire RTL. Also, I don't think the iterative foreach
-style generation of subunits would work well with a unified struct.
However, it might make sense to define a struct type holding the configuration of everything pertaining to a single format, and then have the parameter be an array of these structs (one for each format).
Ok I see. The array-of-structs sounds like a good idea to try out then...
Yeah let's try that.
In general, if having parameters at the top level is an issue, an additional option could be to provide an alternative version of the top module without any parameters, that internally just binds to the DEFAULT
parameters from the package.
Any change could then be done in the package for those who prefer this flow.
Had a deeper look into this, and given SystemVerilog's (and EDA tools') limitations it's a miracle any slightly more complex structure can be even generated as is currently..
The main limitation of using arrays as parameters is that the dimensions of said arrays have to be explicitly specified as parameters, as well - or be hard-coded in the package which is what we're trying to avoid here. The array size
method is not considered static and synthesis tools don't like unbounded arrays anyways. This means that there is more to keep track of and explicitly supply on the user's end of things.
Also, to ensure generation only covers where HW is actually required and there aren't as many dangling 'inactive' blocks, the parameters will have to more explicitly convey the exact structure of hardware needed - which is a massive pain to work out in SystemVerilog alone, see current heaps of helper functions figuring out how wide something should be etc. Again this puts a greater burden on the user, in essence they have to more or less provide a structural recipe of what exactly they need so that it can be instantiated as such.
So going the 'it has to first get worse to become better' route, I'm gonna try to get most of the 'magic' structural generation out of there to simplify the life of EDA tools (at the cost of the user having to explicitly specify the entire structure of the FPU). In the longer run, as the user will have to supply a complete recipe of the HW structure anyways it seems only reasonable to replace all the 'generation magic' in SystemVerilog with an external script that just bakes in the user's recipe into a flat piece of HDL that only relies on the very basic generate structures, if at all.
Sorry about the necroposting, I was just browsing and saw the "help wanted" tag. :) About the parameters, I think it's good to have all default values be set from the package, but overridable in instantiation (where it makes sense).
Configuration structs can also work if the number of parameters grows too much, but I guess many of the parameters on the "deeper levels" of the design hierarchy are somewhat codependent on parameters set higher up (only certain combinations will work etc.), and as such multiple may be set to one of a few possible values depending on the "master" parameter?
(disclaimer: I have not yet looked properly at the code - just making general assumptions, and as such I might be horribly wrong 🙂)