Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] Tracking states of FSM (finite state machine) in Modelsim

Status
Not open for further replies.

mjuneja

Advanced Member level 4
Joined
Aug 28, 2016
Messages
105
Helped
12
Reputation
24
Reaction score
10
Trophy points
18
Location
Bangalore, India
Activity points
674
Hello

My design (coded in VHDL for Virtex 5 FPGA using ISE) worked fine during behavioral simulation.
However when I was trying to run "Post place and route simulation" in Modelsim for the same design, I faced certain issues.

In order to debug the issue, I want to track the state register of FSM written, in the wave window. But I cannot see that state register in object window of Modelsim.

My query is can we somehow add state register in the wave window of Modelsim ?
 

It is bit tricky to do something like that in VHDL.

For such purposes fixed encoding for the states can be used.

-- subtype state_type is std_logic_vector(4 downto 0);
-- constant RESET : state_type := "00000";
-- constant WAIT4_FIFO_RDY : state_type := "00001";
.
.
.
-- signal state : state_type;

Then you can view the "state" in Modelsim.
 

In order to debug the issue, I want to track the state register of FSM written, in the wave window. But I cannot see that state register in object window of Modelsim.

Is your state machine a variable? If that is the case then you can track processes and locals windows etc, you just need to add the window and then add the variable from the correct process in question to the wave window.

What #2 was referring to was something that is possible to test in hardware, by monitoring outputs that represent your state. However in a wave window you'd be present with values like 00001, which might be meaningless to you. There are means of enumeration.
 

I think the problem here might be that signals/variables are getting optimized away. There are ways to preserve these signals, but there is the possible cost of (major) timing impact.
 

The synthesis report also shows the fsm encoding. There is also a synthesis attribute to specify an encoding. The state might have a weird name though, especially if global optimization or retiming was used.
 

The synthesis report also shows the fsm encoding. There is also a synthesis attribute to specify an encoding. The state might have a weird name though, especially if global optimization or retiming was used.

Even if I specify encoding attribute in the synthesis process like one-hot or sequential, how would I relate the encoded bits to the enumeration I have declared in the source code.

@dpaul
It is bit tricky to do something like that in VHDL.

For such purposes fixed encoding for the states can be used.

-- subtype state_type is std_logic_vector(4 downto 0);
-- constant RESET : state_type := "00000";
-- constant WAIT4_FIFO_RDY : state_type := "00001";
.
.
.
-- signal state : state_type;
Then you can view the "state" in Modelsim.

If I will use these constants in coding my FSM next state and output logic , will I be able to see the same code (assigned in declaration) for signal state in the post layout simulation.

And how to track internal signals of the design(uut) in modelsim as the object window only shows the input and outputs of uut and internal signals of test bench.
 

If I will use these constants in coding my FSM next state and output logic , will I be able to see the same code (assigned in declaration) for signal state in the post layout simulation.

Yes.
I didn't mention it first so as to keep the answer simple, I actually do as mentioned in #5. I first take a look into the synth report and then assign the states accordingly, so that I am in sync with the synthesis engine state encoding. I do this for post synth or h/w debug.

In your HDL code, remember the replace the state names such as RESET, WAIT4_FIFO_RDY, etc. with the encoding used (change them again back to human readable names when your bug is fixed and the design is also functioning in real h/w).
When you sim it, then when you see the value "00001", then you know that your state machine is in the WAIT4_FIFO_RDY state.
 

Actually in the synthesis report I didn't find any fsm encoding, instead I got following info.

INFO:Xst:2117 - HDL ADVISOR - Mux Selector <state_now> of Case statement line 362 was re-encoded using one-hot encoding. The case statement will be optimized (default statement optimization), but this optimization may lead to design initialization problems. To ensure the design works safely, you can:
- add an 'INIT' attribute on signal <state_now> (optimization is then done without any risk)
- use the attribute 'signal_encoding user' to avoid onehot optimization
- use the attribute 'safe_implementation yes' to force XST to perform a safe (but less efficient) optimization

while synthesizing in XST.
 

Actually in the synthesis report I didn't find any fsm encoding, instead I got following info.



while synthesizing in XST.

Finally I got the fsm encoding done.

Actually in my case statement I had put a case of "when others =>", that's why it was not realizing that part of code as FSM.
 

Finally I got the fsm encoding done.

Actually in my case statement I had put a case of "when others =>", that's why it was not realizing that part of code as FSM.

That should not affect the implementation of an FSM.

I'm not sure about XST, but in Synplify you have to enable "preserve and decode unreachable states" (i.e., WHEN OTHERS) for it to synthesize the WHEN OTHERS clause.
 

That should not affect the implementation of an FSM.

I'm not sure about XST, but in Synplify you have to enable "preserve and decode unreachable states" (i.e., WHEN OTHERS) for it to synthesize the WHEN OTHERS clause.

I totally agree having a when others clause should not affect the FSM functionality (unless there is a synthesis tool bug).

When I first saw their comment about it working after removing the when others => my first thought was they must have coded their FSM in some weird fashion, which the FSM compiler in XST couldn't figure out that an FSM was being implemented when the others clause was added.

But as they posted none of their FSM code I just ignored their thread.
 

I suspect the encoding in the first attempt was just someplace else in the report. The warning mentions that is is encoded as one-hot. The warning is about the lack of an initial state. In that case, it isn't clear what to do -- go to the first state in the enum? go to the state that appears to be the reset state? go to the state in an others case? The tools will choose something, but an initial state that is explicit removes any doubt.
 

Here is the code of FSM.
Code:
--state_reg------------------------------------------------------------comm
process(clk,rst_n,state_next)  
begin																																																																																																																																																	
	if(rst_n = '0') then
		state_now <= INIT;
	elsif(rising_edge(clk)) then 
		state_now <= state_next;
	end if;
end process;

--FSM------------------------------------------------------------------comm
process(state_now,addr,Data_valid,Data,addr,fram_add_c,fram_siz_1,cntr_px)
begin
	case state_now is
	
		when INIT =>
			NWEi <= '1';
			
			NOEi <= '1';
			addr_en <= "01";
			addr_up <= '0';
			addr_rst <= "10";  
			dir <= '0';        
			DR <= "11";
			mem_act <= '0';
			
			if(Data_valid = '1') then 
				state_next <= WRIT1;
			else
				state_next <= INIT;
			end if;	
			
		when WRIT1 =>       
		        NWEi <= '1';
			
			NOEi <= '1';
			addr_en <= "01";
			addr_up <= '1';
			addr_rst <= "11";
			dir <= '1';
			DR <= "11";
			mem_act <= '1';
			
		   state_next <= WRIT2;

		when WRIT2 =>         
		        NWEi <= '1';
			
			NOEi <= '1';
			addr_en <= "01";
			addr_up <= '0';
			addr_rst <= "11";
			dir <= '1';
			DR <= "11";
			mem_act <= '1';
			
		   state_next <= WRIT7;

		when WRIT7 =>         
		        NWEi <= '1';
			
			NOEi <= '1';
			addr_en <= "01";
			addr_up <= '0';
			addr_rst <= "11";
			dir <= '1';
			DR <= "11";
			mem_act <= '1';
			
		   state_next <= WRIT8;				
			
		when WRIT8 => 
		        NWEi <= '0';
			
			NOEi <= '1';
			addr_en <= "01";
			addr_up <= '0';			
			dir <= '1';
			DR <= "11";	
			mem_act <= '1';
			
			if(cntr_px = 2*fram_siz_1) then  
				state_next <= ADD_RST;
				addr_rst <= "00";
			else
				state_next <= WRIT1;
				addr_rst <= "11";
			end if;
			
              when ADD_RST =>
		        NWEi <= '1';
			
			NOEi <= '1';
			addr_en <= "01";
			addr_up <= '1';			
			addr_rst <= "11";
			dir <= '1';
			DR <= "11";
			mem_act <= '1';
			
			state_next <= RD2;
	
		when RD2   =>
		
		        NWEi <= '1';
			
			NOEi <= '0';
			addr_en <= "01";
			addr_up <= '0';
			addr_rst <= "11";
                        dir <= '0';
			DR <= "00";
			mem_act <= '1';
			
			state_next <= RD4;  

                 when RD4   => 
		
		        NWEi <= '1';
			
			NOEi <= '0';
			addr_en <= "10";
			addr_up <= '0';
			addr_rst <= "11";
                        dir <= '0';
			DR <= "01";
			mem_act <= '1';
			
			state_next <= RD6;  
		
               when RD6   => 
		
		        NWEi <= '1';
			
			NOEi <= '0';
			addr_en <= "11";
			addr_rst <= "11";
                        dir <= '0';
			DR <= "10";
			mem_act <= '1';
			
			if(unsigned(addr) = fram_add_c) then     
				state_next <= INIT;
				addr_up <= '0';
			else
				state_next <= RD2;
			        addr_up <= '1';
			end if;	
			
--		when others =>

	end case;
end process;

when I comment the "when others => " it infers it as FSM otherwise message in post #8 comes.
 
Last edited:

when I comment the "when others => " it infers it as FSM otherwise message in post #8 comes.
Yes, your RTL should include the "when others".
The purpose of using it is to recover the FSM, take it to A KNOWN STATE FROM WHICH LEGAL TRANSITIONS ARE POSSIBLE, in the case the FSM goes to to any unknown state.

Going back to #8
Actually in the synthesis report I didn't find any fsm encoding, instead I got following info.
There can be 2 reasons. Either you couldn't find it in the synth report else your FSM was not extracted properly by the synth tool.
If you use use Vivado, the look into the file \<project_name>.runs\synth_1\runme.log

Following is an excerpt from my current synth log file showing the encoded states.
Code:
---------------------------------------------------------------------------------------------------
                   State |                     New Encoding |                Previous Encoding 
---------------------------------------------------------------------------------------------------
               addr_wait |                              000 |                              000
              read_state |                              001 |                              001
         read_resp_state |                              010 |                              011
             write_state |                              011 |                              010
        write_resp_state |                              100 |                              100
---------------------------------------------------------------------------------------------------
 
Last edited:

Was the "others" case always empty?
I wonder if the synth tool assumed that others covered the impossible states that dont exist in simulation (as you must have covered all states otherwise you'd have a compile error)? It does say he case statement will be optimized (default statement optimization),

Are all of your signals synchronised properly into the clk domain? Have you got all your timing specified? did timing analysis find any problems?

- - - Updated - - -

Yes, your RTL should include the "when others".

When others => is only required when you dont explicitly cover all of your enumerated states in all of the other states. Its perfectly legal to leave it out when this is the case.
If you are hoping that when others covers illegal states, I would never put any faith in that as it is impossible to test at an RTL level. If you need a safe state machine, you should probably be encoding the state variable yourself, or have a separate test explicitly for the netlist to cover it.

Personally, If I know I have covered all states, then all I will put into a "when others" is an assertion telling the user they forgot to include a state in their case statement.
 
When others => is only required when you dont explicitly cover all of your enumerated states in all of the other states.
Correct. I did not give a proper explanation.
I have now logged in to modify my comment, and see that you have already pointed it out! :)
 

I suspect the "when others" is not relevant.

The warning indicates that an FSM was found. Maybe one version of XST had a bug where the FSM states were not listed in the report in this case?

The warning itself is about the tools not knowing what the initial state is. From a tool-writer perspective, it is probably the state that a sole reset input leads to, or the first state in the enum type, or the only state transition from "others", or ideally the declared initial state.
 

Finally I got the answer to this question.

So I found that there can be 2 scenarios while defining FSM:-

1. If the total no. of states (except others) is 2, 4 , 8 , 16 or any 2^n ; then whether I write "when others =>" or not it doesn't make difference.

FSM will be inferred by XST.

2. If the total no. of states( except others) is some other number; then

(a) if when others => is used and left empty as shown in my code then FSM is not inferred and I get the message in post #8.

(b) if when others => is used and next state signal is defined under this, then FSM is inferred.

(c) if when others => is not used, then also FSM is inferred.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top