首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >双向数据总线设计

双向数据总线设计
EN

Stack Overflow用户
提问于 2012-08-15 21:06:10
回答 2查看 16.3K关注 0票数 6

我需要通过双向数据总线(ULPI)与芯片通信。

据我所知,数据在ULPI总线上的上升时钟沿移出,并在下降时钟沿读取。我的问题是,在读取寄存器时,我首先需要对上升沿敏感(将命令写入数据总线上的芯片),然后在从芯片将寄存器输出读取到总线上时对下降沿敏感。

我不清楚如何设计出最好的方式。

我尝试了一个有case语句的进程,但为了让它起作用,我的进程需要对上升沿和下降沿都敏感,我认为这并不好。或者这真的没问题吗?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-08-16 00:06:54

双向总线通常通过使用三态缓冲器来实现。当三态缓冲器输出为"Z“时,您可以从inout端口读取,当缓冲器驱动线路时,它充当输出。在VHDL语言中,这可以通过直接实例化一个原语(例如Xilinx设备的IOBUF )来实现,或者让你的综合工具通过如上所述的描述逻辑来推断三态缓冲区。

这里您要处理的信号有3个:

  • T,这是您的三态控件。在了解ULPI协议的情况下,此信号将从同步逻辑中派生。也就是说,由于总线是共享的,因此必须以某种方式知道何时应该接收数据而不是发送data.
  • I这是您希望通过总线发送的输入数据,在被相应的clock.
  • O注册之后这是您在任何registering/synchronization.

之前通过总线接收的输出数据

键:三态缓冲区是不同步的。它是你在三态缓冲区之前/之后所做的事情,它将正确地同步你的信号。在这种情况下,必须在时钟上升沿将输入同步到三态缓冲器(待发送),并在时钟下降沿同步从三态缓冲器/IOBUF接收的寄存器数据。

示例设计.

代码语言:javascript
复制
library ieee;
use ieee.std_logic_1164.all; 

library unisim; -- for xilinx IOBUF
use unisim.vcomponents.all;

entity iobuffer_example is
   port (
      I_CLK                : in    std_logic;  -- synchronized with bidir bus
      IO_DATA              : inout std_logic;  -- data to/from external pin on bidir bus
      I_DIR_CTRL           : in    std_logic;  -- from other VHDL logic, controlling bidir bus direction
      O_DATA_FROM_EXTERNAL : out   std_logic;  -- data received over bidir bus
      I_DATA_TO_EXTERNAL   : in    std_logic);  -- data to send over bidir bus

end entity iobuffer_example;

architecture io_buffer_arch of iobuffer_example is
   signal data_in : std_logic;
   signal data_out : std_logic;
begin

   IOBUF_Inst : IOBUF
      port map (
         O     => data_in,              -- data from bidir bus
         IO    => IO_DATA,              -- data on bidir bus
         I     => data_out,             -- data to bidir bus
         T     => I_DIR_CTRL); -- 3-state enable input, high=input, low=output

   Register_Input : process (I_CLK) is
   begin
      if (falling_edge(I_CLK)) then
         O_DATA_FROM_EXTERNAL <= data_in;
      end if;
   end process Register_Input;

   Register_Output : process (I_CLK) is
   begin
      if (rising_edge(I_CLK)) then
         data_out <= I_DATA_TO_EXTERNAL;
      end if;
   end process Register_Output;

end architecture io_buffer_arch;

备注

要注意跨时钟域的交叉。对于从总线传出的数据,这里有许多可能的交叉点,特别是当您的内部逻辑在不同于总线时钟的时钟上驱动时。没有更多的细节,我不能提出建议。

如果您希望合成工具推断出三态缓冲区的行为表示,可以这样做,而不是使用unisim库和IOBUF吗?

代码语言:javascript
复制
PROCESS (I_DIR_CTRL, IO_DATA)
   BEGIN 
      IF( I_DIR_CTRL = '1') THEN 
         IO_DATA <= 'Z'; 
      ELSE 
         IO_DATA <= data_out; 
      END IF; 
      data_in <= IO_DATA;
END PROCESS;
票数 6
EN

Stack Overflow用户

发布于 2019-04-27 15:28:32

我知道这是一篇非常老的文章,但我的评论是为那些想要连接/实现ULPI的人准备的。在ULPI中,没有三态数据缓冲区。如果你想知道在ULPI中的传输/传输必须如何实现,请阅读"ULPI接口规范“中的2.3.1章总线所有权。

如果你在被接受的答案中写vhdl,你的代码不会一直工作。你必须注意的一些事情是:

  • turn turn cycle
  • aborting data
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11969826

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档