Forum Discussion
Altera_Forum
Honored Contributor
19 years agoCyclone II is not working correct???
Hello,
I have written a small process, which should read a dmx-signal (seriell signal with special timings). THe whole thing is working realy good, but sometimes it makes things, which i haven`t programmed. The dmx-reader is a state machine and sometimes, one state changes into another, which i haven`t writen (states which are never assigned occurs or the state change is not correct). This is the source code for the state machine (it runs at 10MHz).process (pwm_clock)
variable divider : integer := 0;
variable state : bit_vector (3 downto 0) :="0000";
variable dmx_data : std_logic_vector (0 to 7) :="00000000";
variable dmx_bit_value : integer := 0;
variable dmx_bit_count : integer := 0;
variable dmx_data_count : integer range 0 to 255 := 0;
variable dmx_data_position : integer range 0 to 511 := 0;
begin
if (rising_edge(pwm_clock)) then
divider := divider +1;
if(divider > 1) then
divider := 0;
-- different states
case state is
-- waiting for startbit
when "0000" =>
case check(dmx_in) is
when '0' =>
dmx_bit_value := dmx_bit_value +1;
when '1'=>
if(dmx_bit_value > 430) then
state := "0001";
elsif(dmx_bit_value > 200) and (dmx_data = "00000000") then
state := "0001";
end if;
dmx_bit_value := 0;
dmx_data_position := 0;
when others => null;
end case;
-- waiting for Mark after Break
when "0001" =>
case check(dmx_in) is
when '1' =>
dmx_data_count := dmx_data_count +1;
when '0' =>
if(dmx_data_count > 38) then
state := "0010";
dmx_data_count := 0;
else
dmx_data_count := 0;
end if;
when others => null;
end case;
-- waiting for Start Byte and startbit
when "0010" =>
case check(dmx_in) is
when '0' =>
dmx_data_count := dmx_data_count +1;
when '1'=>
if(dmx_data_count > 178) then
state := "0011";
dmx_data_count := 0;
else
state := "0000";
dmx_data_count := 0;
end if;
when others => null;
end case;
-- waiting for 2 stopbits
when "0011" =>
case check(dmx_in) is
when '1'=>
dmx_data_count := dmx_data_count +1;
when '0'=>
if(dmx_data_count > 38) then
state := "0100";
dmx_data_count := 0;
else
state := "0000";
dmx_data_count := 0;
end if;
when others =>
state := "0000";
dmx_data_count := 0;
end case;
--receive startbit, after the startbit, you have to wait for 2 clocks, to sync back to the signal
when "0100" =>
dmx_data_count := dmx_data_count +1;
if(dmx_data_count > 17) then
if(dmx_bit_value > 13)then
state := "0101";
else
state:="0000";
end if;
dmx_data_count := 0;
dmx_bit_value := 0;
end if;
case check(dmx_in) is
when '0' =>
dmx_bit_value := dmx_bit_value +1;
when others =>
null;
end case;
-- Wait 2 clock (to avoid the signal flanks)
when "0101" =>
dmx_data_count := dmx_data_count +1;
if(dmx_data_count > 1) then
state :="0110";
dmx_data_count := 0;
dmx_bit_value := 0;
dmx_bit_count :=0;
end if;
-- Receive the data_bytes
when "0110" =>
-- Receive for 19 Clocks and check the signal
case check(dmx_in) is
when '1'=>
dmx_bit_value := dmx_bit_value +1;
when others => null;
end case;
dmx_data_count := dmx_data_count +1;
if(dmx_data_count > 17) then
-- if more then 14 received bits are '1' then the transmitted bit is 1
if(dmx_bit_value > 13) then
dmx_data(7-dmx_bit_count) := '1';
else
dmx_data(7-dmx_bit_count) := '0';
end if;
dmx_data_count := 0;
dmx_bit_count := dmx_bit_count +1;
state :="0111";
end if;
-- wait for 2 Clocks (to avoid the signal flanks)
when "0111" =>
dmx_data_count := dmx_data_count +1;
if(dmx_data_count > 1) then
state :="0110";
dmx_data_count := 0;
dmx_bit_value := 0;
-- check if 8 bits are received
if(dmx_bit_count > 7) then
dmx_bit_count := 0;
dmx_data_count := 0;
state:="1000";
end if;
end if;
-- wait for the 2 Stopbits and check, if the signal is correct, or if it is a new start signal
when "1000" =>
case check(dmx_in) is
when '1' =>
dmx_bit_value := dmx_bit_value +1;
when others => null;
end case;
dmx_data_count := dmx_data_count +1;
if(dmx_data_count > 38) then
if(dmx_bit_value > 30) then
dmx_pwm_integer_value(dmx_data_position) := conv_integer(dmx_data);
--leds <= dmx_data;
dmx_data_position := dmx_data_position +1;
dmx_bit_value := 0;
state :="1001";
else
state :="0000";
end if;
dmx_data_count := 0;
end if;
-- wait for the next startbit
when "1001" =>
if(check(dmx_in) = '0') then
state := "0100";
end if;
when others =>state:="0000";
end case;
end if;
end if;
end process; Examples of wrong state changes: Here the State machine changes from 1001b to 1010b which is not declared (it should change to 0100b. http://ej-lighting.at/stp1.jpg A change from 1001b to 1011b which is never declared!! http://ej-lighting.at/stp2.jpg At the moment I have no Idea what could be wrong in this implementation. Thanks Thomas Brunner11 Replies
- Altera_Forum
Honored Contributor
Without having looked into any details of your design I would ask:
are all inputs to you statemachine syncronized before entering? I.e. they should pass at least one DFF clocked at the same clock as the SM. If not, you may end up having metastable state FF's, which will manifest exactly what you see: Erratic performance now and then. Second point is: Check for warnings in timing analyser.