ArtyA7开发板SPI Master的inout端口如何接多个IO及Vivado约束失效问题
问题根因
- 你当前的约束对同一个顶层端口(
spi_clk、spi[0]、spi[1])重复分配了不同的物理引脚,Vivado处理约束时,对同一对象的同一属性赋值,后写的约束会直接覆盖之前的约束,所以只有最后一组生效,这是工具的正常逻辑,不是开发流程的bug。 - FPGA的每个顶层端口固定对应唯一的IOB(输入输出块)硬件资源,不可能把一个内部端口同时映射到两个物理引脚,这是硬件结构决定的,和端口是不是inout类型无关。
正确实现方案
根据你的实际需求二选一即可:
方案1:多从机共享SPI总线(常规用法)
标准SPI多从机架构下,spi_clk、MOSI(你这里的spi[0])、MISO(你这里的spi[1])是全局共享总线,所有从机并联挂在这三个信号上,每个从机单独分配一个CS片选信号即可,不需要给时钟和数据线分配多个引脚:
你只需要保留一组时钟和数据线的约束,给每个spi_cs[x]单独分配不同引脚即可,示例约束如下:
set_property -dict {PACKAGE_PIN L16 IOSTANDARD LVCMOS33} [get_ports spi_clk] set_property -dict {PACKAGE_PIN K17 IOSTANDARD LVCMOS33} [get_ports {spi[0]}] set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports {spi[1]}] # 片选信号逐个分配不同引脚 set_property -dict {PACKAGE_PIN L13 IOSTANDARD LVCMOS33} [get_ports {spi_cs[0]}] set_property -dict {PACKAGE_PIN G13 IOSTANDARD LVCMOS33} [get_ports {spi_cs[1]}] # 新增从机只需要加spi_cs[x]的约束即可
逻辑侧只要在通信时拉低对应从机的CS片选,其他从机的MISO会自动进入高阻态,不会干扰总线。
方案2:多组独立SPI接口
如果你需要多个完全独立的SPI控制器,各自对接不同的从机,不共享总线,那你需要修改顶层端口定义,把时钟、数据线也扩展为数组:
比如定义为spi_clk[1:0]、spi_mosi[1:0]、spi_miso[1:0]、spi_cs[1:0],再给每个通道的信号分别绑定不同引脚,就不会出现约束覆盖的问题:
# SPI通道0约束 set_property -dict {PACKAGE_PIN L16 IOSTANDARD LVCMOS33} [get_ports {spi_clk[0]}] set_property -dict {PACKAGE_PIN K17 IOSTANDARD LVCMOS33} [get_ports {spi_mosi[0]}] set_property -dict {PACKAGE_PIN K18 IOSTANDARD LVCMOS33} [get_ports {spi_miso[0]}] set_property -dict {PACKAGE_PIN L13 IOSTANDARD LVCMOS33} [get_ports {spi_cs[0]}] # SPI通道1约束 set_property -dict {PACKAGE_PIN D12 IOSTANDARD LVCMOS33} [get_ports {spi_clk[1]}] set_property -dict {PACKAGE_PIN B11 IOSTANDARD LVCMOS33} [get_ports {spi_mosi[1]}] set_property -dict {PACKAGE_PIN A11 IOSTANDARD LVCMOS33} [get_ports {spi_miso[1]}] set_property -dict {PACKAGE_PIN G13 IOSTANDARD LVCMOS33} [get_ports {spi_cs[1]}]
其他注意事项
- 引脚名大小写尽量和官方手册保持一致,比如你原来写的
k17应为大写K17,避免工具识别异常。 - inout类型的SPI数据线需要在逻辑侧做好三态控制,避免总线冲突。
内容的提问来源于stack exchange,提问作者molvm
相关产品推荐
相关产品推荐

