如何在保持向后兼容聚合的同时扩展记录类型?

How to extend a record type while remaining backwards compatible with an aggregate?

我们的许多模块使用一组配置描述符记录来配置 Configurable 组件。数组类型、记录类型和可配置组件在全局包中声明,每个人都使用。

type config_descriptor_type is record
    config0 : integer;
    config1 : boolean;
end record;

type config_type is array(natural range <>) of config_descriptor_type;

component Configurable is
    generic (
        g_CONFIG : config_type
    );
end component;

每个使用此 Configurable 的模块都有一个包含该模块配置信息的包(所有现有的此类配置必须保持不变)。

constant c_config : config_type(0 to 3) := (
    (1, true),
    (2, false),
    (8, false),
    (4, true)
);

这个每个模块常量被传递给 Configurable 实例(实例化也必须保持不变)。

config_inst : Configurable
    generic map (
        g_CONFIG => c_config
    );

我正在向 Configurable 添加一些功能,这些功能需要 config_descriptor_type 记录中的附加字段。

type new_config_descriptor_type is record
    config0 : integer;
    config1 : boolean;
    config2 : integer; -- this field was added
end record;

我可以自由地对全局可配置包和实体以及使用新功能的任何新模块进行任何我喜欢的更改,但我不应该触及任何使用可配置的现有模块。如果由旧模块实例化,新字段应获得一些默认值。

有没有什么方法可以添加这样的字段而不必修改所有使用可配置项的现有模块?

类型不能包含仅来自对象(信号、变量、常量)的默认值。并且在为对象赋值时(如常量的初始值),所有字段都需要定义。

有一个解决方法,但需要一次性更改所有先前定义的常量的代码,不需要再次更改。如果您定义了一个基本的“init”函数,其中所有参数都有一个默认值,那么如果您向基本类型添加更多项目,那么现有代码将始终 return 一个分配了所有字段的合法对象。

type config_descriptor_type is record
    config0 : integer;
    config1 : boolean;
    config2 : integer;
end record;

type config_type is array(natural range <>) of config_descriptor_type;

function init_config_descriptor_type( config0 : integer := 0;
                                      config1 : boolean := true;
                                      config2 : integer := 0     ) return config_descriptor_type is
  variable r : config_descriptor_type;
begin
  r.config0 := config0;
  r.config1 := config1;
  r.config2 := config2;
  return r;
end function;


-- Now you can create configs from the function. Config2 will be default value (0)
constant c_config : config_type(0 to 3) := (
    init_config_descriptor_type(1, true),
    init_config_descriptor_type(2, false),
    init_config_descriptor_type(8, false),
    init_config_descriptor_type(4, true)
);