在VHDL中驱动与SRAM共享的GPIO引脚

时间:2013-09-01 15:11:37

标签: vhdl bus spartan

我从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用于选择驱动模块,其他是模块的输入和输出。

2 个答案:

答案 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;