VHDL中std_logic_vector比较及代码转译报错解决咨询
MIG DDR2/3 VHDL代码转译报错解决与std_logic_vector比较方法
问题背景
将实现MIG DDR2/3读写功能的Verilog代码转译为VHDL后,在Vivado中遇到两个报错:
- 语句
wr_last <= app_wdf_wren and (conv_integer(wr_addr_cnt) = WR_LEN-1);中,conv_integer提示无匹配子程序,=运算符提示无合适定义 - 此前直接比较状态信号时也触发
=运算符报错,改用case语句规避后仍存在上述问题
1. 修复当前报错的具体方法
解决conv_integer无匹配子程序问题
conv_integer是VHDL-93的旧函数,仅支持integer、signed、unsigned类型转整数。如果wr_addr_cnt是std_logic_vector类型,直接调用会因为类型不匹配报错,推荐用以下两种方法:
- 方法一(推荐):使用标准库
numeric_std的转换函数
先在代码顶部导入标准库,再把std_logic_vector转成unsigned后转整数:library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; -- 必须导入这个库 -- 修改后的目标语句 wr_last <= app_wdf_wren and (to_integer(unsigned(wr_addr_cnt)) = WR_LEN - 1); - 方法二:兼容旧库
std_logic_arith
如果你的代码依赖旧库ieee.std_logic_arith.all,可以用conv_integer(unsigned(wr_addr_cnt)),但不推荐长期使用,numeric_std是VHDL官方标准库,兼容性更强。
解决=运算符无合适定义问题
这个报错核心是类型不匹配:conv_integer调用失败后,左边的类型和右边的整数WR_LEN-1无法比较。上面的修改已经把wr_addr_cnt转成了整数类型,和WR_LEN-1类型统一后,=运算符就能正常工作。
另外,之前状态信号比较报错的原因也类似:直接用=比较两个std_logic_vector时,必须保证两者位宽完全一致,否则也会触发类型不匹配错误。比如位宽为3的state和位宽为2的next_state直接比较就会报错,需要先调整位宽再比较。
2. 简洁比较std_logic_vector是否完全相同的方法
直接用=运算符即可,但要满足两个前提:
- 代码已经导入
ieee.std_logic_1164.all库(几乎所有VHDL代码都会包含这个库) - 两个
std_logic_vector的位宽完全一致
示例代码
signal a : std_logic_vector(3 downto 0); signal b : std_logic_vector(3 downto 0); signal is_equal : std_logic; -- 赋值语句中比较 is_equal <= '1' when a = b else '0'; -- 条件语句中直接判断 process(a, b) begin if a = b then -- 执行匹配后的逻辑 else -- 执行不匹配的逻辑 end if; end process;
如果两个信号位宽不一致,需要先调整位宽再比较:
signal a : std_logic_vector(3 downto 0); signal b : std_logic_vector(2 downto 0); signal is_equal : std_logic; -- 截断a的最高位,和b的位宽对齐后比较 is_equal <= '1' when a(2 downto 0) = b else '0'; -- 或者给b补高位,和a的位宽对齐后比较 is_equal <= '1' when a = ('0' & b) else '0';
内容的提问来源于stack exchange,提问作者Feng Qinping
相关产品推荐
相关产品推荐

