信号不是激活过程?
Signal is not activating process?
所以我似乎在标志信号被断言方面遇到了问题。所以基本上我在 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 =>...
您的作业边界检查失败,i <= 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。
所以我似乎在标志信号被断言方面遇到了问题。所以基本上我在 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 =>...
您的作业边界检查失败,i <= 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。