Not to long ago, I wrote a post about what a state machine is. That post covered the state machine as a concept and way to organize your thoughts. Well, if you are looking to use state machines in FPGA design, the idea isn’t much help without knowing how to code it.
As you know from the last post, a state machine is made up of three components. The next state logic, state register and output logic.
The first component I’ll go through is the next state logic. This is coded directly from the state diagram.
I’m going to put the state diagram here for reference.
entity state_machine is
Port (
CLK : in STD_LOGIC;
RST : in STD_LOGIC;
dir : in STD_LOGIC;
en : in STD_LOGIC;
sigout : out STD_LOGIC_VECTOR(3 downto 0)
);
end state_machine;
architecture Behavioral of state_machine is
–define a new type to hold state values
type state_type is (STATE_0, STATE_1, STATE_2, STATE_3, STATE_4);
–present state will turn into the state register
–present state is driven by next state at the clock edge
signal present_state, next_state : state_type;
begin
–controls transitions to next state
state_register_logic:
process(CLK, RST) begin
if (RST = ‘1’) then –reset logic
present_state <= STATE_0;
elsif (CLK'event and CLK = '1') then –if rising edge of clock
present_state
if (dir = ‘0’ and en = ‘1’) then
next_state <= STATE_3;
elsif (dir = '1' and en = '1') then
next_state <= STATE_1;
else
next_state
if (dir = ‘0’ and en = ‘1’) then
next_state <= STATE_2;
elsif (dir = '1' and en = '1') then
next_state <= STATE_4;
else
next_state
if (dir = ‘0’ and en = ‘1’) then
next_state <= STATE_1;
elsif (dir = '1' and en = '1') then
next_state <= STATE_3;
else
next_state
if (dir = ‘0’ and en = ‘1’) then
next_state <= STATE_4;
elsif (dir = '1' and en = '1') then
next_state <= STATE_2;
else
next_state
if ( en = ‘1’) then
next_state <= STATE_1;
else
next_state
sigout
sigout
sigout
sigout
sigout <= "0000";
end case;
end process;
I was wondering if you can provide a blog post about designing a simple digital phase modulator, I’m interested in building my own Software Defined Radio, applying my FPGA knowledge in designing most of the digital components of the radio would be amazing.
If you get stuck at any point in writing your state machine please feel free to post on forum.blog.digilentinc.com. There’s a whole community of people like me willing to help you out!
Hi Abdullah,
I haven’t done any Digital Phase Modulation myself but it looks like from my brief internet search that it’s similar to PWM. If this is the case I’m working on a instructable and blog post on using servos with FPGA which uses PWM. That should be posted relatively soon.
If not, and in the mean time I would post on forum.blog.digilentinc.com. One of the members of the Digilent Forum may have already done this and likely would be better help than me.
I explain how the state machine works and introduce it originally in this post. It explains how state machines work and gives a little more detail about stepper motors.
Hi Kaitlyn,
I am in process of learning Verilog and SysVerilog these days, and i used your blog as a test by just referencing the state diagram. Please checkout my code, i am currently in process of writing a test bench for it as well.
//Sequential logic for storing current state
always @ (posedge i_clk or negedge i_rst_n) begin
if (~i_rst_n)
curr_state <= Sig0;
else
curr_state <= next_state;
end
//Combintational logic for next state logic
always @ (curr_state, i_enable, i_dir) begin // Input and Current State for Mealy Machine
case(curr_state)
Sig0: begin
if (i_enable)
next_state <= Sig1;
else
next_state <= Sig0 // Default
end
Sig1: begin
if (i_enable && i_dir)
next_state <= Sig2;
else if (i_enable && !i_dir)
next_state <= Sig4;
else if (!i_enable)
next_state <= Sig0;
end
Sig2: begin
if (i_enable && i_dir)
next_state <= Sig3;
else if (i_enable && !i_dir)
next_state <= Sig1;
else if (!i_enable)
next_state <= Sig0;
end
Sig3: begin
if (i_enable && i_dir)
next_state <= Sig4;
else if (i_enable && !i_dir)
next_state <= Sig2;
else if (!i_enable)
next_state <= Sig0;
end
Sig4: begin
if (i_enable && i_dir)
next_state <= Sig1;
else if (i_enable && !i_dir)
next_state <= Sig3;
else if (!enable)
next_sate <= Sig0;
end
endcase // curr_state
end
always @ (i_clk) begin
if (~i_rst_n)
o_output <= {4{1'b0}};
else begin
case(curr_state)
Sig0: o_output <= {4{1'b0}};
Sig1: o_output <= 4'b1000;
Sig2: o_output <= 4'b0100;
Sig3: o_output <= 4'b0010;
Sig4: o_output <= 4'b0001;
default: o_output <= 4'b1000;
endcase // curr_state
end
end
Hey Yasir,
I’d recommend posting on Forum.blog.digilentinc.com. There is a whole community of excited FPGA enthusiasts that could help you out with your code.
Nice code!
Is there a VHDL version too?
Fred
I’ve translated Kaitlyn’s example into VHDL:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity state_machine is
Port (
CLK : in STD_LOGIC;
RST : in STD_LOGIC;
dir : in STD_LOGIC;
en : in STD_LOGIC;
sigout : out STD_LOGIC_VECTOR(3 downto 0)
);
end state_machine;
architecture Behavioral of state_machine is
–define a new type to hold state values
type state_type is (STATE_0, STATE_1, STATE_2, STATE_3, STATE_4);
–present state will turn into the state register
–present state is driven by next state at the clock edge
signal present_state, next_state : state_type;
begin
–controls transitions to next state
state_register_logic:
process(CLK, RST) begin
if (RST = ‘1’) then –reset logic
present_state <= STATE_0;
elsif (CLK'event and CLK = '1') then –if rising edge of clock
present_state
if (dir = ‘0’ and en = ‘1’) then
next_state <= STATE_3;
elsif (dir = '1' and en = '1') then
next_state <= STATE_1;
else
next_state
if (dir = ‘0’ and en = ‘1’) then
next_state <= STATE_2;
elsif (dir = '1' and en = '1') then
next_state <= STATE_4;
else
next_state
if (dir = ‘0’ and en = ‘1’) then
next_state <= STATE_1;
elsif (dir = '1' and en = '1') then
next_state <= STATE_3;
else
next_state
if (dir = ‘0’ and en = ‘1’) then
next_state <= STATE_4;
elsif (dir = '1' and en = '1') then
next_state <= STATE_2;
else
next_state
if ( en = ‘1’) then
next_state <= STATE_1;
else
next_state
sigout
sigout
sigout
sigout
sigout <= "0000";
end case;
end process;
end Behavioral;
Hey,
Great article, thanks.
I was wondering if you can provide a blog post about designing a simple digital phase modulator, I’m interested in building my own Software Defined Radio, applying my FPGA knowledge in designing most of the digital components of the radio would be amazing.
Much Regards
Abdullah
Hi Fredrik,
Unfortunately I don’t know VHDL well enough to confidently write up a similar post, I’m in the process of learning. However, I found this blog post that has a VHDL example.
http://vhdlguru.blogspot.com/2010/04/how-to-implement-state-machines-in-vhdl.html
If you get stuck at any point in writing your state machine please feel free to post on forum.blog.digilentinc.com. There’s a whole community of people like me willing to help you out!
Kaitlyn
Hi Abdullah,
I haven’t done any Digital Phase Modulation myself but it looks like from my brief internet search that it’s similar to PWM. If this is the case I’m working on a instructable and blog post on using servos with FPGA which uses PWM. That should be posted relatively soon.
If not, and in the mean time I would post on forum.blog.digilentinc.com. One of the members of the Digilent Forum may have already done this and likely would be better help than me.
Kaitlyn
Just for reference: this state machine is for driving a stepper motor, as explained here: https://blog.digilentinc.com/index.php/controlling-a-stepper-motor-with-an-fpga/
Hi Hendrik,
You are indeed correct!
I explain how the state machine works and introduce it originally in this post. It explains how state machines work and gives a little more detail about stepper motors.
https://blog.digilentinc.com/index.php/what-is-a-state-machine/
Kaitlyn
Hi Kaitlyn,
I am in process of learning Verilog and SysVerilog these days, and i used your blog as a test by just referencing the state diagram. Please checkout my code, i am currently in process of writing a test bench for it as well.
//***************************************************************************************
module FSM(input i_enable, input i_dir, input i_clk, input i_rst_n, output reg [`WIDTH-1:0] o_output);
//***************************************************************************************
parameter Sig0 = 3’b000;
parameter Sig1 = 3’b001;
parameter Sig2 = 3’b010;
parameter Sig3 = 3’b011;
parameter Sig4 = 3’b100;
parameter Sig5 = 3’b101; // NOTUSED
parameter Sig6 = 3’b110; // NOTUSED
parameter Sig7 = 3’b111; // NOTUSED
reg [`WIDTH-2:0] curr_state;
reg [`WIDTH-2:0] next_state;
//Sequential logic for storing current state
always @ (posedge i_clk or negedge i_rst_n) begin
if (~i_rst_n)
curr_state <= Sig0;
else
curr_state <= next_state;
end
//Combintational logic for next state logic
always @ (curr_state, i_enable, i_dir) begin // Input and Current State for Mealy Machine
case(curr_state)
Sig0: begin
if (i_enable)
next_state <= Sig1;
else
next_state <= Sig0 // Default
end
Sig1: begin
if (i_enable && i_dir)
next_state <= Sig2;
else if (i_enable && !i_dir)
next_state <= Sig4;
else if (!i_enable)
next_state <= Sig0;
end
Sig2: begin
if (i_enable && i_dir)
next_state <= Sig3;
else if (i_enable && !i_dir)
next_state <= Sig1;
else if (!i_enable)
next_state <= Sig0;
end
Sig3: begin
if (i_enable && i_dir)
next_state <= Sig4;
else if (i_enable && !i_dir)
next_state <= Sig2;
else if (!i_enable)
next_state <= Sig0;
end
Sig4: begin
if (i_enable && i_dir)
next_state <= Sig1;
else if (i_enable && !i_dir)
next_state <= Sig3;
else if (!enable)
next_sate <= Sig0;
end
endcase // curr_state
end
always @ (i_clk) begin
if (~i_rst_n)
o_output <= {4{1'b0}};
else begin
case(curr_state)
Sig0: o_output <= {4{1'b0}};
Sig1: o_output <= 4'b1000;
Sig2: o_output <= 4'b0100;
Sig3: o_output <= 4'b0010;
Sig4: o_output <= 4'b0001;
default: o_output <= 4'b1000;
endcase // curr_state
end
end
endmodule //FSM
Hey Yasir,
I’d recommend posting on Forum.blog.digilentinc.com. There is a whole community of excited FPGA enthusiasts that could help you out with your code.
You can also refer to the video by Mr P R ShivaKumar which gives a simple and easy explanation of State Machines.
https://www.youtube.com/watch?v=9XIzMLwaTl8