我试图基于通用名称更改端口记录,但不知道执行此操作的好方法。我想尽可能避免使用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;
最后,我无法在实体端口映射中声明记录信号并无法通过泛型更改宽度,因为这会破坏成千上万的旧版源代码文件。
答案 0 :(得分:1)
如果您不能使用VHDL2008(已经10年了,并且仍未被某些EDA供应商完全支持...),我只会看到两个选择:
仅使用一种记录类型,其中每个字段都有其最大宽度,但仅使用通用定义的这些位宽度的一部分。合成器应自动丢弃无用的部分。示例:
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);
...
使用多个源文件来定义同一程序包的变体,并选择要在编译或合成时使用的变体。正确使用脚本和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