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.

Synchronous input FSM & sensitivity list

Status
Not open for further replies.

Kaskode

Newbie level 4
Joined
May 2, 2017
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
64
Hello all!, I am learning VHDL, sorry if this is too obvious or doesn't make sense at all.

I am trying to implement a FSM whose inputs are only registered synchronously, that is, the output logic process only contains CurrentState in the sensitivity list and it is updated on the rising edge of the clock.

The synthesizer (Quartus II) complains about the inputs not being declared in the sensitivity list, but I want it this way so they are only registered when CurrentState changes.

What am I missing?
 

If signals are updated on the rising edge of a clock, then only clock should be in the sensitivity list, and you should be using this template:

Code:
process(clock)
begin
  if rising_edge(clock) then
    --- synchronous code
  end if;
end process;

It sounds like you dont have a synchronous process at all - why not post the problem code?
 

Thank you very much TrickyDicky!

The code is as follows:
Code:
library ieee;
use ieee.std_logic_1164.all;

entity Test1 is
	port(
		rst, clk, input: in std_logic;
		data: out std_logic
	);
end Test1;

architecture rtl of Test1 is
	type state is (A, B);
	signal stateReg, stateNext: state;
	signal valueA: std_logic;
begin
	process(clk, rst)
	begin
		if rst = '1' then
			stateReg <= A;
		elsif clk'event and clk='1' then
			stateReg <= stateNext;
		end if;
	end process;

	process(stateReg)
	begin
		case stateReg is
			when A =>
				stateNext <= B;
			when others =>
				stateNext <= A;
		end case;
	end process;
	
	process(stateReg)
	begin
	case stateReg is
		when A =>
			valueA <= input;
			data <= '0';
		when others =>
			data <= valueA;
			valueA <= valueA;
		end case;
	end process;
end rtl;

My thought is if stateReg is synch. (because it only updated on rising edge of "clk") and the output process depends only on it, then the output process is also synch. As an example: on the rising edge of the clock stateReg would change to A, as stateReg has changed the process would execute and valueA would register "input" pin.

If I change the sensitivity list of the last process to "clk" and include all the code in the template you mention, I don't see the same behavior, would it be the same?

Thank you!
 

My thought is if stateReg is synch. (because it only updated on rising edge of "clk") and the output process depends only on it, then the output process is also synch. As an example: on the rising edge of the clock stateReg would change to A, as stateReg has changed the process would execute and valueA would register "input" pin.
That's not how VHDL works. The stateReg processes are defined combinational, it's outputs will update instantly on any input change. The synthesis behavior doesn't actually depend on sensitivity lists, the Quartus warning has only the purpose to warn you about possible mismatch between simulation and hardware synthesis.

If you want you registered outputs, you have to put it in a synchronous process triggered by clk edge.
 

Code:
	process(stateReg)
	begin
		case stateReg is
			when A =>
				stateNext <= B;
			when others =>
				stateNext <= A;
		end case;
	end process;

This is just abusing the VHDL others clause in a case statement.

You are using others as the state B. That isn't what others was meant to be used for. Perhaps you should read about how to code a case statement and when others is applicable and why.
 

Abusing or not, it's legal VHDL. IF THEN ELSE would be another way to describe the same logic.

The latch for valueA implemented in the other process bothers me more.
 

Abusing or not, it's legal VHDL. IF THEN ELSE would be another way to describe the same logic.

The latch for valueA implemented in the other process bothers me more.

I just looked at that, now that bothers me too. Why did you have to point it out!?

I actually stopped looking further through the code once I saw the "legal VHDL", where synthesis results don't always match between vendors.
 

Using vhdl 2008 you can have a combinatorial circuit, that transitions through the state machine. You can use the *all* keyword to tell the tools that every signal utilized for a conditional statement (and assignment) is included in the sensitivity list

I recommend you google or duckduckgo or anything but yahoo "mealy & moore vhdl".


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
sync : process
begin
  if rising_edge(clk) then
    state <= nextstate;
  end if;
end process;
 
--
comb : process (all)  -- sensitivity list will now trigger when value A changes
begin
  case (state) is 
     when A => 
...

 

Thank you all very much! I see my view of VHDL is not right...

My intention is to register "input" pin in the rising edge of the clock and at the same time output '0' through "data". In the next rising edge I want to output the value of "input" in the previous cycle and repeat again and again.

I am not sure if the code at the end is correct since StateReg is being updated and read in the rising edge of the clock. Is there a correct approach for that??

Thank you again!

Code:
library ieee;
use ieee.std_logic_1164.all;

entity Test1 is
	port(
		rst, clk, input: in std_logic;
		data: out std_logic
	);
end Test1;

architecture rtl of Test1 is
	type state is (A, B);
	signal stateReg, stateNext: state;
	signal valueA: std_logic;
begin
	process(clk, rst)
	begin
		if rst = '1' then
			stateReg <= A;
		elsif clk'event and clk='1' then
			stateReg <= stateNext;
		end if;
	end process;

	process(stateReg)
	begin
		case stateReg is
			when A =>
				stateNext <= B;
			when others =>
				stateNext <= A;
		end case;
	end process;
	
	process(clk)
	begin
		if clk'event and clk='1' then
				if stateReg = A then
					valueA <= input;
					data <= '0';
				else
					data <= valueA;
				end if;
		end if;
	end process;
end rtl;
 

Hi Kaskode,
Try this
Code:
...
Architecture rtl of test1 is
Begin
[INDENT]process (clk, rst)[/INDENT]
[INDENT]begin[/INDENT]
[INDENT][INDENT]if rst = '1' then
[INDENT]data <= '0';[/INDENT]
Elsif (clk'event and clk = '1') then 
[INDENT]data <= input;[/INDENT]
End if[/INDENT]
End process;
[/INDENT]
End rtl;

Realise that there are no states in your problem. You are only constantly passing "input" through "data" on every event of clock.
"rst" is just there for the essence of reset.
Remember that for FSM, you need conditions to transition from one state to another. You don't have any such condition as I notice.
 
Last edited:

Can't agree. stateReg is continuously toggling between two states, it implements a simple clock frequency divider, in so far the design has states. stateReg however doesn't depend on input signal.
 

Hello,
Thank you for your answers! Akanimo, I think your code doesn't implement what I am trying to achieve.

I have simulated the last code I submitted and it seems to work, my concern is if there is a better way to do this or not. In particular this process:

Code:
	process(clk)
	begin
		if clk'event and clk='1' then
				if stateReg = A then
					valueA <= input;
					data <= '0';
				else
					data <= valueA;
				end if;
		end if;
	end process;

Thank you very much!
 

I did not understand your problem then.
 

...
I have simulated the last code I submitted and it seems to work,...

Your problem is not very clear though especially where you wrote, ‘repeat again and again.’ Did you mean that you want to output successive previous cycle ‘input’s while remaining in state B and not transitioning with clock?

Although I have not simulated your code, as a result of your first and second processes, stateReg toggles from the reset state (A) and the active state (B) as clock events. This would make data to output ‘0’->’input’->’0’->’input’…, and I believe this is your simulation result.

I sense that you desire to remain in the active state (B) after you have reset and clock has evented until you desire to reset again or an indeterminate state is entered.

However, in your last process, valueA acts like a latch and is only updated when you reset. You need to update it with input when in the active state (B) as well.

I have written a code that I believe would solve your problem assuming I now understand your problem. I have not simulated the code though due to my PC having a power pack issue.


Code:
library ieee;
use ieee.std_logic_1164.all;

entity Test1 is
	port(
		rst, clk, input: in std_logic;
		data: out std_logic
	);
end Test1;

architecture rtl of Test1 is
	type state is (A, B);
	signal stateReg, stateNext: state;
	signal valueA: std_logic;
begin
	process(clk, rst)
	begin
		if rst = '1' then
			StateReg <= A;
			stateNext <= B;
		elsif clk’event and clk=’1’ then
			stateReg <= stateNext;
		end if;
	end process;

	process(clk)
	begin
		If clk’event and clk = ’1’ then
			case stateReg is
				when A =>
					valueA <= input;
					data <= ‘0’;
				When B =>
					valueA <= input;
					data <= valueA;
				when others =>
					stateReg <= A;
			end case;
		end if;
	end process;
end rtl;

You could try it.
 

Although I have not simulated your code, as a result of your first and second processes, stateReg toggles from the reset state (A) and the active state (B) as clock events. This would make data to output ‘0’->’input’->’0’->’input’…, and I believe this is your simulation result.

What active state (B)? They don't have a B state defined anywhere, they tell the FSM to go to state B but then don't define a state B as one of the cases, instead they use default... DEFAULT is not a state, but they sure use it as a state (legal VHDL, but abusing the language). This is just plain bad coding style and I would give them 0 marks on any interviews for that FSM design.

Not sure why nobody else has a problem with that.
 

...
This is just plain bad coding style...

The coding style is very poor, I agree with you. Even the stateNext signal was not necessary since the state would always transition from A to B on the next rising edge of clock after it had been reset and there was not to be any state beyond B. I just did not want to touch that.

The entire FSM, as a matter of fact, was not necessary as the design could be implemented with two cascaded single-bit registers with reset connected to the output register.
 

I've seen this in the past. It basically comes down to if you are more annoyed not seeing a default case, or if you are more annoyed not seeing all states listed, or more annoyed seeing an unused default.

From a technical perspective, not having the default is the best choice in this application. However, you'll get points off in any interview as it is a meta-game of guessing what the interviewer knows and wants to see.

(I normally implement this with "toggle <= not toggle;" in a clocked process.)
 

Thank you all for your comments.

As for the case comments, I have tried to simplify the original code as much as I could to highlight my real problem, that meant removing states. I left the default state for the B state as a safe mechamisn, that is, to be sure stateReg doesn't contain anything else but a defined state.

Akanimo, I don't see how my last code can generate a latch for valueA since it is inside a synchronous process, I think it would generate an edge-triggered register. In fact, I think your code may generate one for stateNext in the first process and lacks the next state logic. Besides that I think it is the same as my code.

Thank you all for your time!
 

I've seen this in the past. It basically comes down to if you are more annoyed not seeing a default case, or if you are more annoyed not seeing all states listed, or more annoyed seeing an unused default.

My problem with it isn't that it doesn't simulate or that it is annoying. My problem is the ambiguity in less than ideal conditions like in a facility in Colorado where you can get occasional single event upsets that affect your design.

If your "default" state happens to be the state that corresponds to write_the_flash, then well if the FSM goes into the weeds and the recovery of the FSM results in the FSM going to default....

You can't make a FSM safe if you use default as a state unless that default state is the recovery state then you might be fine. But I would still consider the FSM to be wrong.
 

Are you certain this is accurate for VHDL? From what I've read, using default case and safe fsm are independent concepts. It looks like Xilinx uses FSM_SAFE_STATE which allows you to declare a safe state for the type -- the safe state is not inferred by the default state. For Altera it looks like there is a syn_encoding = safe which infers the safe state based on the reset state. Other forums seem to indicate that this style is equivalent to enumerating all states in the case statement -- specifically if you want a safe state you must use synthesis attributes.

For Verilog2001 you are probably correct as you provide the encoding yourself. I'm not sure if tools ever re-encode the FSM though.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top