so I seem to be having a problem in regards to flag signal getting asserted. So basically I am implementing i2c interface between 2 fpga's. My master will send over 50 bytes. On my slave side I want to store the byte coming in into an array. So I check when ever the whole byte is read and available i put it into an array. Now the problem is that after i fill up the whole array i want to assert a signal that should activate a process. My problem is that when the signal is asserted and the process is activated that that I am stuck in the idle loop forever, which confuses me because I was under the assumption that when i enter the process and check the flag signal assertion condition that it is suppose to be high. So is the problem that my signal is not activating the process or is my problem that the by the time i check the flag assertion conditional that the flag already went back to 0? I have attached some code:
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 =>...
There is a bounds check failure on your assignment, i <= i+1;
. It is trying to evaluate it before the check that is performed later (if i=49...
).
Change the synchronous part of you code to:
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;
EDIT:
You can see that the flag is being asserted and the state changes here.
Further EDIT:
Consider making your state machine synchronous and removing the next_state
signal. eg.
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;
If you want to assign your outputs as soon as your state changes, you can use a two process state machine. One of the processes (synchronous) is used to control state transitions, the other is used to control the output (combinational). You would effectively have another process similar to the first:
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;
An example is shown here.