使用通用选择包/记录

时间:2018-08-18 00:33:03

标签: vhdl xilinx vivado

我试图基于通用名称更改端口记录,但不知道执行此操作的好方法。我想尽可能避免使用VHDL2008构造,因为我想避免与旧版代码向后兼容。无论如何,这就是我想要做的:

--libs for pack256
package pack256 is
    type myDataT is record
        valid : std_logic;
        data  : std_logic_vector(255 downto 0);
    end record;
end package;

-- libs for pack128
package pack128 is
    type myDataT is record
        valid : std_logic;
        data  : std_logic_vector(127 downto 0);
    end record;
end package;

现在,我希望能够选择在我的实体中使用的软件包,因为此记录位于端口映射中。有什么我可以使用VHDL配置或某些方法来确定从顶层获取组件/记录/类型的软件包的创意方法吗?不幸的是,我们有很多代码在看下面的代码,并且需要能够控制使用哪个包,因为某些顶层对myDataT记录使用了不同的数据宽度。如果没有VHDL 2008或创建两个单独的实体就无法解决此问题,那么Vivado AND Altera / Quartus是否支持包泛型/无限制记录?

-- top level declaration stuff
library dataPack;
use dataPack.(pack128 or pack256).all; -- how to choose different package from top level?

entity myEntity is
    generic(
        -- generics);
    port(
        reset : in std_logic;
        clk   : in std_logic;

        ctrl : myDataT;
        -- other port stuff);
end myEntity;

最后,我无法在实体端口映射中声明记录信号并无法通过泛型更改宽度,因为这会破坏成千上万的旧版源代码文件。

1 个答案:

答案 0 :(得分:1)

如果您不能使用VHDL2008(已经10年了,并且仍未被某些EDA供应商完全支持...),我只会看到两个选择:

  1. 仅使用一种记录类型,其中每个字段都有其最大宽度,但仅使用通用定义的这些位宽度的一部分。合成器应自动丢弃无用的部分。示例:

    package pack is
        type myDataT is record
            valid : std_logic;
            data  : std_logic_vector(255 downto 0);
        end record;
    end package;
    ...
    library dataPack;
    use dataPack.pack.all;
    
    entity myEntity is
        generic(
            usefullWidth: natural := 128
        ):
        port(
            reset : in std_logic;
            clk   : in std_logic;
            ctrl  : in myDataT;
            -- other port stuff
        );
    end myEntity;
    ...
    architecture arc of myEntity is
        ...
    begin
        ...
        foobar <= ctrl.data(usefullWidth - 1 downto 0);
        ...
    
  2. 使用多个源文件来定义同一程序包的变体,并选择要在编译或合成时使用的变体。正确使用脚本和GNU make可以轻松地基于一个变量定义执行此操作。示例(更改此键变量的值时,请不要忘记使用make clean):

    $ cat pack256.vhd
    package pack is
        type myDataT is record
            valid : std_logic;
            data  : std_logic_vector(255 downto 0);
        end record;
    end package;
    
    $ cat pack128.vhd
    package pack is
        type myDataT is record
            valid : std_logic;
            data  : std_logic_vector(127 downto 0);
        end record;
    end package;
    
    $ cat Makefile
    .NOTPARALLEL:
    
    INIFILE      := modelsim.ini
    VLIB         := vlib
    VMAP         := vmap
    VCOM         := vcom
    VCOMFLAGS    :=
    
    USEFULLWIDTH := 128
    PACK         := pack$(USEFULLWIDTH)
    
    VHDS         := $(wildcard *.vhd)
    TAGS         := $(patsubst %.vhd,.%.tag,$(VHDS))
    LIBS         := myLib dataPack
    LIBDIRS      := $(patsubst %,.%.lib,$(LIBS))
    
    all: .myEntity.tag
    
    $(TAGS): .%.tag: %.vhd | $(INIFILE)
        $(VCOM) $(VCOMFLAGS) -work $(LIB) $<
        touch $@
    
    .myEntity.tag: .$(PACK).tag
    .myEntity.tag: LIB = myLib
    .$(PACK).tag:  LIB = dataPack
    
    $(INIFILE): | $(LIBDIRS)
        for l in $(LIBS); do \
            $(VMAP) $$l .$$l.lib; |
        done
    
    $(LIBDIRS):
        $(VLIB) $@
    
    clean:
        rm -rf $(TAGS)
    
    ultraclean: clean
        rm -rf $(LIBDIRS) $(INIFILE)
    
    $ make
    vlib .myLib.lib
    vlib .dataPack.lib
    vmap myLib .myLib.lib
    vmap dataPack .dataPack.lib
    vcom  -work dataPack pack128.vhd
    touch .pack128.tag
    vcom  -work myLib myEntity.vhd
    touch .myEntity.tag
    
    $ make clean
    rm -rf .pack256.tag .myEntity.tag .pack128.tag
    
    $ make USEFULLWIDTH=256
    vcom  -work dataPack pack256.vhd
    touch .pack256.tag
    vcom  -work myLib myEntity.vhd
    touch .myEntity.tag