2

我花了很长时间试图弄清楚如何将 Xilinx Spartan 6 FPGA 的内核生成的 Block RAM 连接到双向数据总线。我能找到的所有示例都说仅单独使用输入和输出数据端口,但就我而言,我被迫将其用作双向数据总线。

我正在使用 VHDL。

生成的组件具有以下定义:

COMPONENT ram
    PORT (
       clka  : IN STD_LOGIC;
       wea   : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
       addra : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
       dina  : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
       douta : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
    );
END COMPONENT;

实例化如下:

ram1 : ram
  PORT MAP (
    clka => clk,
    wea => r_w,
    addra => addr,
    dina => din,
    douta => dout
  );

有人可以向我展示一个将连接dina并连接douta到一个inout名为的端口的进程块data吗?

我尝试了以下方法,成功率为 0%:

process(clk)
begin
  if rising_edge(clk) then
    if r_w = "1" then
      -- Write
      din <= data;
      dout <= temp;
    else
      -- Read
      din <= (others => 'Z');
      data <= dout;
    end if;
  end if;
end process;

谢谢您的帮助!

4

2 回答 2

3

首先,重要的是要了解现代 FPGA 内部(例如您正在谈论的 Xilinx Spartan-6),实际上并没有任何真正的双向布线。真正的双向/三态信号只能用于 I/O 引脚。可以模拟内部双向/三态信号,但这通常只用于与传统 HDL 的接口,而不是用于任何新的东西。

现在,无论是否存在真正的三态,为了连接单向dinadouta“双向” data,您需要一些信号来控制内存何时驱动。由于我们已经有了短名称,所以我们将其称为oe“输出启用”。这个信号需要由您的设计以一种有意义的方式控制。

鉴于此,您可以使用以下并发代码(不在进程中)将不同方向的两个单向信号以及输出启用方向选择器转换为逻辑双向数据总线:

dina <= data;
data <= douta when oe = '1' else (others => 'Z');
于 2012-06-14T04:22:17.740 回答
1

在该if r_w = "1"块中,您似乎正在尝试驱动您的dout信号,该信号应由端口驱动douta。这可能解释了一个问题(除非temp都是'Z')。

以下注意事项:我现在没有任何东西可以测试这个,所以这一切都在我的脑海中。让我知道它是否没有帮助!

我不认为同步过程是解决此问题的最佳方法。自从我需要这样做已经有一段时间了,但这就是我认为你需要的。请注意,这不是一个过程,它在架构中是正确的。

din <= data when (r_w = '1') else (others => 'Z');
data <= dout when (r_w = '0') else (others => 'Z');

说明:当信号被多个源驱动(或分配给)时,除了其中一个之外,所有信号都必须是“Z”。第二行设置data为由“Z”驱动——但这实际上“释放了它”(从解析器的角度来看)由端口驱动。

如果你确实需要它是同步的,这应该很容易适应——但请记住,这'0'并不是'1'唯一可能的情况std_logic,所以考虑一个else子句或others一个case块!

于 2012-06-14T04:21:43.780 回答