如何在VHDL端口声明时约束记录类型的数组成员长度?
实现实体端口直接指定floating_point的mantissa长度(Vivado 2013.4)
要在Vivado 2013.4里实现你想要的效果,得先解决核心问题:你当前定义的floating_point类型没有参数化能力,没法直接在端口声明时指定mantissa的长度。下面给你两种可行方案,按兼容性优先级排列:
方案一:兼容VHDL-93的子类型定义(无需开启VHDL-2008)
这种方式最稳妥,适合老版本工具。思路是先定义一个基础的floating_point类型(其中mantissa是非限定数组),然后针对不同的mantissa长度定义专属子类型:
第一步:修改包定义
package my_package is -- 补全你原来的natural_sub子类型定义(可根据实际需求调整范围) subtype natural_sub is natural; type natural_array is array (NATURAL RANGE <>) of natural_sub; -- 定义基础的浮点类型,mantissa为非限定数组 type floating_point_base is record sign : integer range -1 to 1; mantissa : natural_array; exponent : integer range -50 to 50; end record; -- 为不同mantissa长度定义子类型 subtype floating_point_4 is floating_point_base(mantissa(3 downto 0)); subtype floating_point_8 is floating_point_base(mantissa(7 downto 0)); end my_package;
第二步:在实体中使用子类型
use work.my_package.all; entity arithematic_unit is Port ( a_in: in floating_point_4; -- 对应mantissa长度4 b_in : in floating_point_4; op: in natural range 1 to 7; c_out : out floating_point_8 -- 对应mantissa长度8 ); end arithematic_unit;
这种写法在VHDL-93标准下完全合法,Vivado 2013.4无需额外设置就能编译通过。
方案二:使用VHDL-2008参数化记录类型(更灵活)
如果你想保留你最初期望的floating_point(3 downto 0)这种写法,需要用到VHDL-2008的参数化记录类型特性。Vivado 2013.4已经支持该特性,但需要手动开启VHDL-2008语言标准:
第一步:开启Vivado的VHDL-2008支持
- 打开你的Vivado项目,右键点击项目名称 → Project Settings
- 在左侧导航栏选择IP → Synthesis,将VHDL Language Standard设置为VHDL 2008
- 同样在Implementation选项卡中,把语言标准也改成VHDL 2008,确保全流程支持
第二步:修改包定义为参数化类型
package my_package is subtype natural_sub is natural; -- 补全natural_sub定义 type natural_array is array (NATURAL RANGE <>) of natural_sub; -- 定义带参数的浮点类型,参数为mantissa的范围 type floating_point(MANTISSA_RANGE : natural range <>) is record sign : integer range -1 to 1; mantissa : natural_array(MANTISSA_RANGE); -- 用传入的范围约束mantissa exponent : integer range -50 to 50; end record; end my_package;
第三步:在实体中直接指定长度
现在你就能按照最初的想法写端口声明了:
use work.my_package.all; entity arithematic_unit is Port ( a_in: in floating_point(3 downto 0); -- 直接指定mantissa的范围 b_in : in floating_point(3 downto 0); op: in natural range 1 to 7; c_out : out floating_point(7 downto 0) ); end arithematic_unit;
注意事项
- 如果你原来的
natural_sub是有具体范围的子类型(比如natural range 0 to 255),一定要在包中补全定义,否则编译器会报错 - 若使用参数化类型时遇到编译错误,先检查VHDL-2008是否已正确开启,以及类型参数的语法是否正确
内容的提问来源于stack exchange,提问作者Veena
相关产品推荐
相关产品推荐

