# How can Qsys component configuration be accessed in software?

I'm designing a Qsys component which I want to be user-configurable. It has config parameters which are defined in the TCL file. For example, for a GPIO bank component I would write:

add_parameter GPIO_OUTPUTS_COUNT POSITIVE 8 "Number of GPIO pins"
set_parameter_property GPIO_OUTPUTS_COUNT DEFAULT_VALUE 8
set_parameter_property GPIO_OUTPUTS_COUNT ALLOWED_RANGES 1:32
set_parameter_property GPIO_OUTPUTS_COUNT HDL_PARAMETER true


The value of this parameter can be accesses in HDL code easily:

module gpio
(
...
);

parameter GPIO_OUTPUTS_COUNT; // gets the value assigned by user


Now, I would also like to have this value in my driver's C code, e.g. to check for errors where the user is trying to access non-existing pins:

int gpio_write(pin, level) {
if(pin >= GPIO_OUTPUTS_COUNT) return -1; // No such pin

...

return 0; // Success
}


How can I get GPIO_OUTPUTS_COUNT name defined in my C code?

Several ways spring to mind:

A/ The way I have done this in the past is to add the parameters to the registers.

A (professional) peripheral has:

• An ID register
• A version register

• Parameter register.

If required you can easily pack four 8-bit parameters in a 32-bit register:

case (read_adrs)
4'h0 : rdata <= control_register;
4'h4 : rdata <= 32'h4F495047; // "GPIO" in little endian
4'h8 : rdata <= {VERSION_MINOR,VERSION_MAJOR};
4'hC : rdata <= GPIO_OUTPUTS_COUNT;
...


The CPU can then read the width. The disadvantage is that with a define you can have all compile-time optimizations which are now not possible.

B/ As an alternative to put all that type of parameters in one include file. Then you could make a sed script which converts the Verilog 'include file' format to C include file format and include that. The syntax is close enough to make that very simple.

C/ Add a define to both make files. But I find that error prone.

• I thought about exposing all HDL settings in the address space, but like you mention, this excludes any chance of setting-specific compiler optimization. – Dmitry Grigoryev Jun 16 '19 at 14:19

Adding the following contraption to the TCL file worked:

set_module_property VALIDATION_CALLBACK validate
proc validate {} {
set GPIO_OUTPUTS_COUNT [ get_parameter_value GPIO_OUTPUTS_COUNT ]
set_module_assignment embeddedsw.CMacro.OUTPUTS_COUNT "\$GPIO_OUTPUTS_COUNT"
}


Assuming the component instance is called gpio_0, the following line will be added to system.h upon generation:

#define GPIO_0_OUTPUTS_COUNT 8 // Value selected by the user in Qsys