我从Micronova(http://micro-nova.com/mercury)购买了一块Spartan 3A开发板,我遇到了一些与SRAM连接的问题。
该板有30个GPIO引脚,与赛普拉斯SRAM共用,两个引脚可在它们之间切换。
很明显,将两个VHDL模块(一个用于控制SRAM,另一个用于驱动GPIO)连接到同一个引脚会导致合成时出现“多个驱动程序错误”。
因此,为了解决这个问题,我创建了第三个模块作为中间控制器,将两个模块与另一个变量连接起来,以选择一个操作。
这适用于输出,但是当涉及读取输入时,我总是得到1,与实际值无关。
我不知道哪个引脚会被用作输入而哪些引脚用于输出,因为我想要一个独立的模块,我可以用于其他项目。
这是我到目前为止所得到的:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity DMA2 is
Port (
IOphys : inout STD_LOGIC_VECTOR (29 downto 0);
IOin1 : out STD_LOGIC_VECTOR (29 downto 0);
IOin2 : out STD_LOGIC_VECTOR (29 downto 0);
IOout1 : in STD_LOGIC_VECTOR (29 downto 0);
IOout2 : in STD_LOGIC_VECTOR (29 downto 0);
SwitchEn2 : in STD_LOGIC
);
end DMA2;
architecture Behavioral of DMA2 is
begin
IOin2 <= IOphys;
IOin1 <= IOphys;
IOphys <= IOout2 when SwitchEn2 = '1' else IOout1;
end Behavioral;
IOphys是电路板上的物理引脚,SwitchEn2用于选择驱动模块,其他是模块的输入和输出。
答案 0 :(得分:0)
您为应该输入的引脚分配了什么值?
如果在该引脚应该是输入的情况下为IOout1和IOout2信号分配'Z',则可能能够推断出正确的操作,但我建议您实际实例化三态I / O引脚。除了多路复用输出状态外,还应该在两个模块之间复用输出使能,然后输入代码才能正常工作。
因此每个模块都会生成输出信号和一组输出使能。这些信号被多路复用并连接到一组物理引脚,输出使得能够确定哪些引脚是输入,哪些是输出。这样,FPGA中的所有内容都是二进制逻辑,您不依赖于合成器来推断三态总线。
答案 1 :(得分:0)
您似乎没有推动您的输出。作为首发,如何定义像这样的三态驱动程序
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tristate is
port (
signal data_in : out std_logic;
signal data_out : in std_logic;
signal data_tristate : inout std_logic;
signal tristate_select : in std_logic
);
architecture rtl of tristate is
begin
data_in <= data_tristate;
data_tristate <= 'z' when tristate_select = '1' else data_out;
end architecture;
然后在其使用之间进行选择
entity arbitrate_bus
port(
-- the pins
IOphys : inout STD_LOGIC_VECTOR (29 downto 0);
IOin1 : out STD_LOGIC_VECTOR (29 downto 0);
IOout1 : in STD_LOGIC_VECTOR (29 downto 0);
IO_direction1 : in STD_LOGIC_VECTOR (29 downto 0);
IOin2 : out STD_LOGIC_VECTOR (29 downto 0);
IOout2 : in STD_LOGIC_VECTOR (29 downto 0);
IO_direction2 : in STD_LOGIC_VECTOR (29 downto 0);
SwitchEn2 : in STD_LOGIC
);
architecture like_this of arbitrate_bus is
signal input : STD_LOGIC_VECTOR (29 downto 0);
signal output_selected : STD_LOGIC_VECTOR (29 downto 0);
signal direction_selected : STD_LOGIC_VECTOR (29 downto 0);
begin
output_selected <= IOout1 when SwitchEn2 = '0' else IOout2;
direction_selected <= IO_direction1 when SwitchEn2 = '0' else IO_direction2;
g_ts: for g in output_selected'range generate
begin
u_ts: entity tristate
port map(
data_in => input(g),
data_out => output_selected(g),
data_tristate => IOphys(g),
tristate_select => direction_selected(g)
);
end generate;
IOin1 <= input;
IOin2 <= input;
end architecture;