Implementation of finite state machine under Vivado


Finite state machines are used when processing relatively complex logic. Different states are set, jump to the corresponding state according to the trigger conditions, and then perform corresponding processing in different states. Finite state machines mainly use always statements and case statements.


Implementation of 1011 state machine

The article Design a state machine for identifying the binary sequence "1011" under Quartus II software is a state machine designed in the Quartus II software to identify the binary sequence "1011". Here, the example is implemented in Vivado. .
The design source code is as follows.

module timing(
    input  clk, 
    input  rst, 
    input  en,
    input  in, 
    output reg out
);

parameter ST0 = 0;
parameter ST1 = 1;
parameter ST2 = 2;
parameter ST3 = 3;
parameter ST4 = 4;

reg [2:0] state;
reg [2:0] next_state;

initial
begin
    next_state = ST0;
end

always @ (in or en or state)
begin
  case (state)
    ST0:
    begin 
		if(en == 1 && in == 1) 
			next_state = ST1;
		else 
			next_state = ST0;
	end
    ST1:
    begin 
		if(en == 1 && in == 0) 
		    next_state = ST2; 
		else if(en == 1 && in == 1) 
		    next_state = ST1;
		else 
		    next_state = ST0;
		end
    ST2:
    begin 
		if(en == 1 && in == 1) 
		    next_state = ST3; 
		else 
		    next_state = ST0;
		end
    ST3:
    begin 
		if(en == 1 && in == 1)
		    next_state = ST4;           
		else if(en == 1 && in == 0) 
		    next_state = ST2;
		else 
		    next_state = ST0;
		end
	//ST4:
	   //next_state = ST0;
   endcase 
end

always @ (posedge clk or negedge rst)
begin
  if(!rst)
    state <= ST0;
  else
    state <= next_state;
end

always @ (state or posedge clk) 
begin
  if(state == ST4)
    begin
        state = ST1;
        out = 1;
    end
  else 
     out = 0;
end

endmodule

The simulation test source code is as follows.

module sim_timing();
reg clk;
reg rst;
reg en;
reg in;
wire out;

initial
begin
    en = 0;
    clk = 0;
    rst = 1;
    #50 
    en = 1;
    #400
    rst = 0;
    #50
    rst = 1;
end

initial
begin
    in = 0;
    forever
    begin
    #20
    in = {
    
    $random}%2;
    end 
end

always #10 clk = ~clk;

timing uut_timing(
    .clk(clk),
    .rst(rst),
    .en(en),
    .in(in),
    .out(out)
);
endmodule

The simulation output results are shown in the figure below.
Insert image description here
As can be seen from the above figure, every time a "1011" sequence is input, the output out is set to 1, and is cleared after one clock cycle. The output result is consistent with expectations.


Shift operation in four states

The following figure shows four states. The initial state is Idle. In this state, it is judged whether the shift start signal shift_start is high. If it is high, it enters the Start state. In the Start state, it delays for several cycles and enters the Run state. Then perform shift processing. If the shift stop signal shift_stop is valid, enter the Stop state, clear the value in the memory and then return to the Idle state.
Insert image description here
The output of Mealy finite state machine is not only related to the current state, but also related to the input signal.
The design source code of Mealy finite state machine is as follows.

module timing(
    input  clk, 
    input  rst, 
    input  in,
    input  shift_start, 
    input  shift_stop, 
    output reg[7:0] out
);

parameter Idle = 0;
parameter Start = 1;
parameter Run = 2;
parameter Stop = 3;

reg [1:0] state;
reg [3:0] count;

always @ (posedge clk or negedge rst)
begin
  if(!rst)
    begin
        state <= Idle;
        count <= 0;
        out <= 0;
    end
  else
  case(state)
    Idle:
        begin
            if(shift_start)
                state <= Start;
        end
    Start:
        begin
            if(count == 4'd10)
            begin
                count <= 0;
                state <= Run;
            end 
            else
                count <= count + 1'b1;   
        end
     Run:
        begin
            if(shift_stop)
                state <= Stop;
            else
                out <= {
    
    out[6:0],in};
        end
     Stop:
        begin
            out <= 0;
            state <= Idle;
        end
     default : state <= Idle;
     endcase 
end
endmodule

The output of Moore finite state machine is only related to the current state and has nothing to do with the input signal. The input signal only affects the change of state and does not affect the output. For example, the counting signal and output signal in this example.
The design source code of Moore finite state machine is as follows.

module timing(
    input  clk, 
    input  rst, 
    input  in,
    input  shift_start, 
    input  shift_stop, 
    output reg[7:0] out
);

parameter Idle = 0;
parameter Start = 1;
parameter Run = 2;
parameter Stop = 3;

reg [1:0] cur_state;
reg [1:0] next_state;
reg [3:0] count;

always @ (posedge clk or negedge rst)
begin
  if(!rst)
      cur_state <= Idle;
  else
      cur_state <= next_state;
end

always@(*)
begin
  case(cur_state)
    Idle:
        begin
            if(shift_start)
                next_state <= Start;
            else
                next_state <= Idle;
        end
    Start:
        begin
            if(count == 4'd10)
                next_state <= Run;
            else
                next_state <= Start;
        end
     Run:
        begin
            if(shift_stop)
                next_state <= Stop;
            else
                next_state <= Run;
        end
     Stop:
        next_state <= Idle;
     default : next_state <= Idle;
     endcase 
end

always@(posedge clk or negedge rst)
begin
    if(!rst)
        count <= 0;
    else if (cur_state == Start)
        count <= count + 1'b1;
    else
        count <= 0;
end

always@(posedge clk or negedge rst)
begin
    if(!rst)
        out <= 0;
    else if (cur_state == Run)
        out <= {
    
    out[6:0],in};
    else
        out <= 0;
end

endmodule

Two ways of writing are used in the above two programs. The first Mealy state machine adopts a one-paragraph writing method. Only one always statement is used in the code, and all state transfers, judgment state transfer conditions, and data output are All in one always statement. The disadvantage of this writing method is that if there are too many states, the entire program will become lengthy. The second is the Moore state machine, which adopts a three-stage writing method. An always statement is used for state transfer, an always statement is used to determine the state transfer condition, and an always statement is also used for data output. The code written in this way is more intuitive. It is clear, and it will not appear cumbersome when there are many states.
The simulation test code for both is the same, as shown below.

module sim_timing();
reg  clk;
reg  rst; 
reg  in;
reg  shift_start; 
reg  shift_stop; 
wire [7:0] out;

initial
begin
    clk = 0;
    rst = 0;
    in = 0;
    #100 
    rst = 1;
    forever
    begin
        #({
    
    $random}%100)
        in = ~in;
    end
end

initial
begin
    shift_start = 0;
    shift_stop = 0;
    #200
    shift_start = 1;
    #500
    shift_start = 0;
    shift_stop = 1;
    #50
    shift_stop = 0;
    shift_start = 1;
end

always #10 clk = ~clk;

timing uut_timing(
    .clk(clk),
    .rst(rst),
    .in(in),
    .shift_start(shift_start),
    .shift_stop(shift_stop),
    .out(out)
);
endmodule

The simulation output results are shown in the figure below.
Insert image description here
As can be seen from the above figure, in the Start state, after counting to 10, it jumps to the Run state and starts the shifting operation. The above picture is the overall simulation process. The shift operation cannot be seen clearly, so the output out is displayed in binary. The enlarged picture is as follows. You can see that when shift_start is valid, the left shift operation is performed correctly.
Insert image description here


The above is all the content of finite state machine implementation under Vivado!
Reference:
ZYNQ Development Platform FPGA Tutorial AX7020

Guess you like

Origin blog.csdn.net/weixin_42570192/article/details/130938824