【问题标题】:Signal is not activating process?信号不是激活过程?
【发布时间】:2017-02-23 00:44:52
【问题描述】:

所以我似乎在声明标志信号方面遇到了问题。所以基本上我在 2 个 fpga 之间实现 i2c 接口。我的主人将发送超过 50 个字节。在我的从属端,我想将传入的字节存储到一个数组中。因此,我检查何时读取了整个字节并且可用,然后将其放入数组中。现在的问题是,在我填满整个数组后,我想断言一个应该激活进程的信号。我的问题是,当信号被断言并且进程被激活时,我永远卡在空闲循环中,这让我感到困惑,因为我假设当我进入进程并检查标志信号断言条件时它是估计很高。那么问题是我的信号没有激活进程还是我的问题是当我检查标志断言时标志已经回到0? 我附上了一些代码:

  signal i : integer range 0 to 49 := 0;

  type field_array is array(0 to 49) of std_logic_vector(7 downto 0);
begin
process(clk,rst) 
begin

if( rst = '1') then

    i <= 0;

elsif (rising_edge(clk)) then

    if(data_available = '1') then

        array_of_data(i) <= Master_Data;

        i <= i + 1;

    end if;

    if(i = 49) then

        i <= 0; -- reset index back to zero

    end if;

end if;

end process;

flag <= '1' when i = 49 else '0'; 

process(state,flag)
begin

next_state   <= state;

case (state) is 

    when idle =>

        if(flag = '1') then

            next_state <= Send_data;

        end if;

     when Send_data =>...

【问题讨论】:

标签: process signals vhdl fpga timing


【解决方案1】:

您的作业边界检查失败,i &lt;= i+1;。它试图在稍后执行的检查之前对其进行评估 (if i=49...)。

将代码的同步部分更改为:

elsif rising_edge(clk) then
    if data_available = '1' then
        array_of_data(i) <= Master_Data;
        if i = 49 then
            i <= 0;
        else
            i <= i + 1;
        end if;
    end if;
end if;

编辑:

您可以看到标志正在被断言并且状态更改here

进一步编辑:

考虑使您的状态机同步并移除next_state 信号。例如。

type state_t is (idle_s, send_s, others_s);
signal state : state_t := idle_s;
...
process(clk,rst)
begin
    if rst = '1' then
        -- rst
    elsif rising_edge(clk) then
        case (state) is
            when idle_s =>
                if flag = '1' then
                    state <= send_s;
                else
                    state <= idle_s;
                end if;
            when send_s =>
            -- Do stuff
            when others =>
            -- stuff
        end case;
    end if;
end process;

如果您想在状态更改后立即分配输出,则可以使用两进程状态机。其中一个过程(同步)用于控制状态转换,另一个用于控制输出(组合)。您实际上会有另一个类似于第一个的过程:

process(state)
begin
    case state is
        when idle_s =>
            my_output <= '0';
        when send_s =>
            -- Assign output as necessary
            my_output <= '1';
        when others =>
        --assign output
    end case;
end process;

一个例子显示在here

【讨论】:

  • 感谢您的更正。是的,它似乎在模拟上运行良好,但是当我在我的 fpga 上运行它时,它似乎只停留在空闲状态(使用 LED 检查状态)。如果我错了,请纠正我,但是当标志被断言时(0 -> 1),该过程应该激活并且当我检查(标志='1')时,条件应该是正确的吗?
  • 正确。进一步查看后,我可能还会修改您的状态控制器流程;使其同步,并摆脱next_state 信号
  • 当我尝试模拟它时,我在 GHDL 的那条线上得到一个边界检查错误
  • @gsm 道歉。我错了。您的作业会出现边界检查失败。
  • 感谢@gsm 的修改建议和帮助。出于某种原因,当我使用我第一次发布的组合过程时,它现在可以工作了。奇怪的。 Anywho,你提到的同步过程很好用,谢谢,但我一开始没有开始同步的原因是因为在我的发送数据案例中,我计划断言一些输出,我希望它们尽快被断言这种情况会在同一个时钟周期内发生反应,而另一方面,如果我要同步,我相信我要断言的输出会在一个时钟周期后改变。
猜你喜欢
  • 1970-01-01
  • 2017-09-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-30
  • 1970-01-01
  • 2015-01-23
  • 1970-01-01
相关资源
最近更新 更多