Forum Discussion
Altera_Forum
Honored Contributor
18 years agoHello Frank,
thanks for your interesting observation. I continued the investigation and try to summarize my results. I think the state machine viewer has a bug and the compiler inserts redundant logic in special cases: I used the code which I posted on January 11th, 2008 05:03 PM. I have 4 different versions:architecture performancetest of performancetest_1_fsm2conditions_2 is
type STATES is (init, green, yellow, red);
signal state : STATES;
signal reset_timer : std_logic;
signal timer_max : std_logic;
component timer
port(
clk : in std_logic;
reset : in std_logic;
reset_timer : in std_logic;
timer_max : out std_logic
);
end component;
begin
timer1:timer
port map (
clk => clk,
reset => reset,
reset_timer => reset_timer,
timer_max => timer_max
);
process(clk,reset)
variable reset_timer_var : std_logic;
begin
if reset = '1' then
output <= "00";
reset_timer_var := '0';
state <= init;
elsif clk'event and clk = '1' then
reset_timer_var := '0';
if trafficLight_ena = '0' then
reset_timer_var := '1';
state <= init;
else
case state is
when init =>
if trafficLight_ena = '1' then -- removed at version 3 & 4
output <= "00";
reset_timer_var := '1';
state <= red;
else -- removed at version 1 & 3 & 4
state <= init; -- removed at version 1 & 3 & 4
end if;
when green =>
output <= "01";
if timer_max = '1' and input = '0' then
state <= yellow;
else -- removed at version 1 & 3
state <= green; -- removed at version 1 & 3
end if;
when yellow =>
output <= "10";
reset_timer_var := '1';
state <= red;
when red =>
output <= "11";
if timer_max = '1' and input = '1' then
reset_timer_var := '1';
state <= green;
else -- removed at version 1 & 3
state <= red; -- removed at version 1 & 3
end if;
end case;
end if;
reset_timer <= reset_timer_var;
end if;
end process;
end performancetest; 1.: "without else" with redundant if statement -> removed redundant else statements "state <= actual state"; 2.: "with else" with redundant if statement = the posted version 3.: "without else" without redundant if statement -> removed redundant condition "if trafficLight_ena = '1' then" inside state init (= dead code because there is a "global" if statement outside the case) -> removed redundant else statements "state <= actual state"; 4.: "with else" without redundant if statement: -> removed redundant condition "if trafficLight_ena = '1' then" inside state init (= dead code because there is a "global" if statement outside the case) If I use sequential state machine encoding all 4 versions are identical (technology map viewer post fit) and the state machine viewer displays the expected transitions. 12 LEs; 9 Reg; 494,56 MHz
init 0 0
green 0 1
yellow 1 0
red 1 1
init init (!trafficLight_ena)
init red (trafficLight_ena)
green init (!trafficLight_ena)
green green (!timer:timer1).(trafficLight_ena) + (timer:timer1).(input).(trafficLight_ena)
green yellow (timer:timer1).(!input).(trafficLight_ena)
yellow init (!trafficLight_ena)
yellow red (trafficLight_ena)
red init (!trafficLight_ena)
red green (timer:timer1).(input).(trafficLight_ena)
red red (!timer:timer1).(trafficLight_ena) + (timer:timer1).(!input).(trafficLight_ena)
If I use one hot state machine encoding I get completely different results and I'm quite sure now that something is wrong! state machine encoding is equal for all versions: init 0 0 0 0 green 0 0 1 1 yellow 0 1 0 1 red 1 0 0 1 without else = without redundant default state assignment 1.: "without else" with redundant if statement ============================= 15 LEs; 11 Reg; 380,37 Mhz - normal state transitions are displayed inside state machine viewer - at first glance redundant conditions for state transitions -> state.red <= state.red*tmp + !tmp*trafficLight_en*!(timer_max*(input*state.red) + !input*state.green)) tmp = (trafficLight_en*(!timer_max + !state.green*!input + !state.red*input)*state.init*!state.yellow) -> tmp comprises all states! so I'm not sure If the compiler generates redundant logic, but tmp is also used for state transition to state.green - if I use optimization option speed I get the identical result as in version 2 2.: "with else" with redundant if statement = the posted version ========================================= 13 LEs; 10 Reg; 551,27 Mhz - normal state transitions are displayed inside state machine viewer - state.init register optimized away - optimization area, balanced and speed are identical 3.: "without else" without redundant if statement =============================== 14 LEs; 11 Reg; 459,77 Mhz - normal state transitions are displayed inside state machine viewer - the transition (the data input for register) for state.red "is as coded" - optimization area, balanced and speed are identical 4.: "with else" without redundant if statement ============================= 14 LEs; 11 Reg; 459,77 Mhz - BUG in state machine viewer: all transitions to state.init are missing in the table and in the chart - but result is identical to version 3 If I compare the gate level logic for setting state.red register version 1 state.red <= state.red*tmp + !tmp*trafficLight_en*!(timer_max*(input*state.red) + !input*state.green)) tmp = (trafficLight_en*(!timer_max + !state.green*!input + !state.red*input)*state.init*!state.yellow) with version 2: state.red <= trafficLight_ena*!state.green*!(state.red*timer_max*input) or version 3 / 4: state.red <= traffic_ena*((state.red*!(timermax*input)) + !(!state.yellow*state.init)) I'm confused about the results, because I coded and intended the same hardware. In fact version 1 and 2 have identical RTL Viewer and State machine viewer output. But the results are different. I tested the impact of the missing default state assignments at another bigger component and the effect was the same. I would be happy if someone can verify the State Machine Viewer Bug and halp to investigate the impact of (redundant/non redundant) if conditions outside the case statement in correlation with redundant default state assignments. TIA, Axel