inout参数是如何实现的?

how does inout parameters be implemented?

我知道 inout 参数是什么以及如何使用它们。假设我们有一个inout参数io,想创建一个双向静态RAM比如下面的代码:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

ENTITY sram IS
    port(
        clk  : IN    std_logic;
        wr   : IN    std_logic;
        io   : INOUT std_logic;
        addr : IN    INTEGER RANGE 0 TO 7
    );
END sram;

ARCHITECTURE behavioral OF sram IS
    TYPE matrix IS ARRAY (0 TO 7) OF std_logic;
    SIGNAL mem : matrix;
BEGIN
    PROCESS(clk)
    BEGIN
        IF rising_edge(clk) THEN
            IF wr = '1' THEN
                mem(addr) <= io;
            END IF;
        END IF;
    END PROCESS;
    io <= mem(addr) WHEN wr = '0' ELSE 'Z';
END behavioral;

我们可以创建一个sram的实例,然后在上面写入如下代码:

io <= '1' WHEN wr = '1' ELSE 'Z';

问:综合工具如何控制多个驱动之间的多重赋值判断?实施什么硬件来做到这一点?


感谢评论和回答...

对于典型的 FPGA 和 ASIC 设备,三态功能的实现仅在 IO 上可用,例如在 Altera Arria 10 FPGA 中:

因此对于此类设备,内部 RAM 始终使用专用输入和输出端口实现,因此不使用任何内部三态功能。

即使 RAM 连接到支持三态的外部 IOs,内部 RAM 块通常仍使用专用输入和输出端口创建,因此连接到设备上支持三态的引脚是通过具有输出使能和三态能力的 in-out 缓冲器处理。

如果内部设计在设备不支持时尝试使用三态功能或多个驱动程序,则综合工具将生成错误,通常表示同一网络不支持多个驱动程序。

在 Xilinx 设备上,原理图相似。

这是原始 IOBUF 的图像:

绿色部分为三态控制输出驱动;蓝色部分是输入驱动器。完整的 IOB(Input/Output 块)由几个原语组成:

  • IOB 寄存器(输入、输出、三态控制)
  • 延迟链
  • 将两个 IOB 组合成差分 IOB (**BUFDS) 的连线
  • 驱动时钟网络的能力(CC-IOB - 支持时钟的 IOB)
  • 上拉,下拉,...
  • 驱动程序(IOBUF)
  • pin/ball(IPAD、OPAD、IOPAD)- 这包括 ESD 保护

合成是如何工作的?

  • Xilinx 综合工具 (XST / Synth) 为 top-level 组件端口描述中的每条线添加 IPAD 或 OPAD 原语。 pad只是FPGA封装下表示物理pin或ball的原语。
  • 如果启用自动添加 I/O 缓冲区,该工具将在每个 PAD 和 top-level 端口之间添加 IBUF、OBUF、IOBUF、IBUFDS 等原语。它使用端口方向(in、out、inout)来推断正确的缓冲区类型。如果禁用此选项(默认 = 打开),您必须为每个 I/O 引脚手动添加缓冲区。在某些情况下,XST 被冒犯了:我手动添加了一些具有三态控制的 IOBUF,因此 XST 拒绝推断丢失的缓冲区。所以我不得不手动添加 all 缓冲区 ...

在使用 Xilinx XST 时,可以在 top-level 下使用三态总线(端口方向 = inout)。 XST 将报告它添加了(虚拟)三态缓冲区。如果总线的每一位的方向有明显的方向并且没有多驱动程序问题,这些缓冲区将被修剪。

这在 iSim 中不起作用。