Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
VHDL代码在合成后表现异常(I2C)_Vhdl_I2c - Fatal编程技术网

VHDL代码在合成后表现异常(I2C)

VHDL代码在合成后表现异常(I2C),vhdl,i2c,Vhdl,I2c,首先,由于公司披露协议,我不允许发布我的代码,因此我将描述这种行为的症状,希望这样就足够了 我使用的是由提供的I2C主机IP,我使用的方式与页面上提供的示例相同。区别在于我有几个示例中描述的过程 WHEN get_data => --state for conducting this transaction busy_prev <= i2c_busy; --capture the

首先,由于公司披露协议,我不允许发布我的代码,因此我将描述这种行为的症状,希望这样就足够了

我使用的是由提供的I2C主机IP,我使用的方式与页面上提供的示例相同。区别在于我有几个示例中描述的过程

WHEN get_data =>                               --state for conducting this transaction
busy_prev <= i2c_busy;                       --capture the value of the previous i2c busy signal
IF(busy_prev = '0' AND i2c_busy = '1') THEN  --i2c busy just went high
    busy_cnt := busy_cnt + 1;                  --counts the times busy has gone from low to high during transaction
END IF;

CASE busy_cnt IS                             --busy_cnt keeps track of which command we are on
    WHEN 0 =>                                  --no command latched in yet
        i2c_ena <= '1';                            --initiate the transaction
        i2c_addr <= slave_addr;                    --set the address of the slave
        i2c_rw <= '0';                             --command 1 is a write
        i2c_data_wr <= data_to_write;              --data to be written

    WHEN 1 =>                                  --1st busy high: command 1 latched, okay to issue command 2
        i2c_rw <= '1';                             --command 2 is a read (addr stays the same)

    WHEN 2 =>                                  --2nd busy high: command 2 latched, okay to issue command 3
        i2c_rw <= '0';                             --command 3 is a write
        i2c_data_wr <= new_data_to_write;          --data to be written
        IF(i2c_busy = '0') THEN                    --indicates data read in command 2 is ready
            data(15 DOWNTO 8) <= i2c_data_rd;       --retrieve data from command 2
        END IF;

    WHEN 3 =>                                  --3rd busy high: command 3 latched, okay to issue command 4
        i2c_rw <= '1';                             --command 4 is read (addr stays the same)

    WHEN 4 =>                                  --4th busy high: command 4 latched, ready to stop
        i2c_ena <= '0';                            --deassert enable to stop transaction after command 4
        IF(i2c_busy = '0') THEN                    --indicates data read in command 4 is ready
            data(7 DOWNTO 0) <= i2c_data_rd;         --retrieve data from command 4
            busy_cnt := 0;                           --reset busy_cnt for next transaction
            state <= home;                           --transaction complete, go to next state in design
        END IF;

    WHEN OTHERS => NULL;

END CASE;
WHEN get_data=>--执行此事务的状态
busy_prev--尚未锁定任何命令

i2c_ena根据评论,如果发布的代码片段不再是计时过程的一部分,那么它会出现严重问题:


Me:发布的代码仍然是计时过程的一部分吗


mmahdich:@Martin在我的代码中不是这样的,如果您将原来的单进程SM转换为更复杂的2进程SM,那么时钟进程只会更新当前状态,从而提供几种引入失败的方法。仔细检查已注册但不再注册的敏感度列表和输出。“时钟信号路由[奇怪]”警告可能是这种情况的症状-您可以确定其原因。我强烈推荐单进程形式:是什么驱使您重写为2进程?根据警告“时钟信号是使用通用路由资源路由的,可能会出现过度延迟和/或扭曲”,这意味着您生成了一些本地时钟,这些时钟不是有意的,就是您必须通过时钟缓冲区对其进行缓冲。但是,在发布的代码中,这似乎不是一个问题。再次阅读代码后,
busy\u cnt
看起来可疑,但需要更多的上下文。@Brian除了习惯和清晰之外,没有特别的理由在两个过程中编写它。我会尝试你的解决方案并回复@Martin我并不是有意生成这些内容的,我怀疑这与这个片段无关。
busy\u cnt
仅仅是示例中设计师提供的相同设计(假设他最了解)。发布的代码仍然是计时过程的一部分吗?我明白了,谢谢Martin这实际上是一个很好的解释。我将尝试尽快将解决方案作为一个计时过程来实施。不幸的是,这将需要一段时间,因为我休假到明年。感谢您抽出时间回答。这是一种新的生活方式!我检查了一下,问题似乎是我把过程分成了两部分。当我回到单进程方法时,甚至警告也消失了。非常感谢你的帮助,非常感谢。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity i2c_test is
  port (
    clk               : in  std_logic;
    i2c_busy          : in  std_logic;
    slave_addr        : in  std_logic;
    data_to_write     : in  std_logic_vector(7 downto 0);
    new_data_to_write : in  std_logic_vector(7 downto 0);
    i2c_data_rd       : in  std_logic_vector(7 downto 0);
    i2c_ena           : out std_logic;
    i2c_addr          : out std_logic;
    i2c_rw            : out std_logic;
    i2c_data_wr       : out std_logic_vector(7 downto 0);
    data              : out std_logic_vector(15 downto 0));
end i2c_test;

architecture rtl of i2c_test is
  type   state_t is (get_data, home);
  signal curr_state : state_t := home;
  signal state      : state_t;          -- next state is named "state" in OP code
  signal busy_prev  : std_logic;
begin  -- rtl
  process (clk)
  begin  -- process
    if rising_edge(clk) then
      curr_state <= state;
    end if;
  end process;

  process(curr_state, busy_prev, i2c_busy, slave_addr, data_to_write, new_data_to_write, i2c_data_rd)
    variable busy_cnt : integer range 0 to 4 := 0;
  begin
    state <= curr_state;              -- next state is named "state" in OP code
    i2c_ena <= '0';
    i2c_addr <= '-';
    i2c_rw  <= '-';
    i2c_data_wr <= (others => '-');
    -- no default assignments for busy_prev and data here, because the usage
    -- below indicates that a register was intended

    case curr_state is
      when home => state <= get_data;

    ---------------------------------------------------------------
    -- Add code from question here
    ---------------------------------------------------------------

    
    end case;
  end process;
end rtl;
busy_prev <= i2c_busy;              --capture the value of the previous i2c busy signal
data(15 DOWNTO 8) <= i2c_data_rd;   --retrieve data from command 2
data(7 DOWNTO 0) <= i2c_data_rd;    --retrieve data from command 4
WHEN get_data =>                               --state for conducting this transaction
  IF(busy_prev = '0' AND i2c_busy = '1') THEN  --i2c busy just went high
    busy_cnt := busy_cnt + 1;                  --counts the times busy has gone from low to high during transaction
  END IF;