VHDL不同大小2D数组赋值Vivado报Synth 8-2234错误解决方案问询
问题原因分析
- 第一是索引越界:你定义的
rx_ram属于ram_1300_block类型,合法索引范围是0 ~ 1300,但赋值语句里你取了rx_ram(1341 downto 42),1341已经超出了最大合法索引,这是首要错误。如果是需要取rx_ram全部1300个元素,正确的切片范围应该是rx_ram(1300 downto 0),和Q1_ram(1300 downto 1)的长度(1300个元素)刚好匹配。 - 第二是类型不兼容:VHDL是强类型语言,
ram_1300_block和ram_2700_block是两个完全独立的自定义类型,哪怕存储单元结构完全一致,老版本Vivado(尤其是2015.x系列)在推断RAM的场景下,会直接拒绝跨类型的切片赋值,抛出Synth 8-2234错误。
可行解决方法(均不需要调整数组容量)
方法1:逐元素循环赋值
兼容性最好,不需要修改任何类型定义,综合后资源占用和直接切片赋值完全一致。示例代码:
process(clk) begin if rising_edge(clk) then -- 遍历1300个元素逐位赋值 for i in 0 to 1299 loop Q1_ram(i + 1) <= rx_ram(i); end loop; end if; end process;
如果是组合逻辑赋值,去掉时钟边沿判断、把对应信号放到process敏感列表里即可,不过RAM赋值推荐按时序逻辑写,避免综合出非预期的锁存器。
方法2:显式类型转换
如果不想写循环,可以用显式类型转换把rx_ram的切片转成和Q1_ram兼容的类型,示例代码:
-- 先修正rx_ram的切片范围,再显式转换为ram_2700_block类型 Q1_ram(1300 downto 1) <= ram_2700_block(rx_ram(1300 downto 0));
注意转换前后的切片长度必须严格相等,否则会报编译错误。
方法3:调整类型定义为同源子类型
如果可以修改数组类型的定义规则,可以把两个数组类型改为同一个无约束数组的子类型,后续就可以直接做切片赋值,不需要额外转换。修改后的类型定义示例:
-- 先定义无约束的通用RAM类型 type ram_block is array (natural range <>) of std_logic_vector(7 downto 0); -- 再基于通用类型定义不同长度的子类型,容量和原来完全一致 subtype ram_1300_block is ram_block(1300 downto 0); subtype ram_2700_block is ram_block(2700 downto 0); -- 数组声明和原来完全一致 rx_ram : ram_1300_block; Q1_ram : ram_2700_block;
修改完成后直接写Q1_ram(1300 downto 1) <= rx_ram(1300 downto 0);就可以正常编译综合。
内容的提问来源于stack exchange,提问作者Sre M
相关产品推荐
相关产品推荐

