代码之家  ›  专栏  ›  技术社区  ›  nichollsg

使用泛型选择包/记录

  •  2
  • nichollsg  · 技术社区  · 6 年前

    我正在尝试更改基于泛型的端口记录,但不知道如何进行此操作。如果可能的话,我试图避免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和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 回复  |  直到 6 年前
        1
  •  1
  •   Renaud Pacalet    6 年前

    如果您不能使用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