verilog语言分别设计一、二、三段式状态机

状态机

Mealy状态机:输出不但取决于状态还取决于输入。

Moore状态机:输出只取决于当前状态

设计题目:将下列状态图分别用一段式、二段式、三段式状态机实现

如下图用verilog实现

verilog语言分别设计一、二、三段式状态机_第1张图片

1、一段状态机

一个模块既包含状态转移,又包含组合逻辑输入/输出。

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date: 2018/12/05 21:04:31
// Design Name: 
// Module Name: test
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module test(
clk,rst_n, z_o,a_i,current_state
    );
//数据声明部分
 input clk,rst_n;
 input a_i;
 output reg  z_o; 
 output current_state;
 //参数声明
 parameter S0=  3'd0;
 parameter S1 = 3'd1;
 parameter S2 = 3'd2;
 parameter S3 = 3'd3;
 parameter S4 = 3'd4;
 parameter S5 = 3'd5;
 //内部信号声明
 reg[2:0] current_state;
 //状态跳转逻辑程序设计
 always @(posedge clk or negedge rst_n)
 begin
   if(!rst_n) begin
         z_o<= 0;
         current_state <= S0;
   end
   else   begin
         case(current_state) 
          S0: begin
             if(a_i) begin
                  current_state <= S1;
             end
             else begin
                 current_state <= S0;
             end
             z_o<=0;
          end
          S1: begin
             if(a_i) begin
                  current_state <= S1;
             end
             else begin
                 current_state <= S2;
             end
             z_o<=0;
          end
          S2: begin
                     if(a_i) begin
                          current_state <= S1;
                     end
                     else begin
                         current_state <= S3;
                     end
                     z_o<=0;
            end
            S3: begin
                  if(a_i) begin
                      current_state <= S4;
                  end
                  else begin
                      current_state <= S0;
                  end
                      z_o<=0;
             end
             S4: begin
                   if(a_i) begin
                       current_state <= S1;
                   end
                   else begin
                       current_state <= S5;
                   end
                       z_o<=0;
              end
            S5: begin
                      if(a_i) begin
                          current_state <= S1;
                      end
                      else begin
                          current_state <= S3;
                      end
                          z_o<=1;
                 end
         endcase
      end
  end

endmodule

2、两段式状态机

一个always语句实现时序逻辑,一个always语句实现组合逻辑。提高了代码的可读性和可维护性,它需要定义一个两个状态---现态和次态。通过现态和次态的转换来实现逻辑。

module test(
clk,rst_n, z_o,a_i,current_state
    );
//数据声明部分
 input clk,rst_n;
 input a_i;
 output reg  z_o; 
 output current_state;
 //参数声明
 parameter S0=  3'd0;
 parameter S1 = 3'd1;
 parameter S2 = 3'd2;
 parameter S3 = 3'd3;
 parameter S4 = 3'd4;
 parameter S5 = 3'd5;
 //内部信号声明
 reg[2:0] current_state;
 reg[2:0] next_state;
 //状态跳转逻辑程序设计
  always @(posedge clk or negedge rst_n)
  begin
    if(!rst_n) begin
        current_state<= S0;
    end
    else 
        current_state<= next_state;
  end
 //状态输出逻辑设计
 always @(current_state)
 begin
       case(current_state) 
          S0: begin
             if(a_i) begin
                   next_state <= S1;
             end
             else begin
                  next_state <= S0;
             end
             z_o<=0;
          end
          S1: begin
             if(a_i) begin
                   next_state <= S1;
             end
             else begin
                 next_state <= S2;
             end
             z_o<=0;
          end
          S2: begin
                     if(a_i) begin
                           next_state <= S1;
                     end
                     else begin
                          next_state <= S3;
                     end
                     z_o<=0;
            end
            S3: begin
                  if(a_i) begin
                       next_state<= S4;
                  end
                  else begin
                       next_state<= S0;
                  end
                      z_o<=0;
             end
             S4: begin
                   if(a_i) begin
                        next_state <= S1;
                   end
                   else begin
                        next_state <= S5;
                   end
                       z_o<=0;
              end
            S5: begin
                      if(a_i) begin
                           next_state<= S1;
                      end
                      else begin
                           next_state<= S3;
                      end
                          z_o<=1;
                 end
         endcase
  end

endmodule

3、三段式状态机程

在FPGA逻辑设计中,如果状态机比较大,需要的状态转移、信号等的处理比较复杂,建议使用三段式状态机来完成设计。

优点:

(1)将组合逻辑和时序逻辑分开,利于综合器分析优化和程序维护;

(2)更符合设计的思维习惯;

(3)代码少,比一段式状态机更简洁。

module finite_fsm(
z_o,
clk,
Rst_n,
a_i
);
//输出端口
output z_o;

//输入端口
input clk;
input Rst_n;
input a_i;

//输出端口类型声明
reg z_o;

//参数声明
parameter S0=  3'd0;
parameter S1 = 3'd1;
parameter S2 = 3'd2;
parameter S3 = 3'd3;
parameter S4 = 3'd4;
parameter S5 = 3'd5;

//内部信号声明
reg[2:0] current_state;
reg[2:0] next_state;

//状态寄存器
always @ (posedge clk or negedge Rst_n) begin
    if(!Rst_n)
            current_state <= S0;
    else
        current_state <= next_state;//控制次态

//次态的组合逻辑
always @ (a_i or current_state) begin
    case(current_state)
        S0:begin
                  if(a_i) next_state = S1;
                   else   next_state =  S0;
              end
        S1:  begin
                    if(a_i) next_state = S1;
                    else    next_state = S2;
             end
        S2:  begin
                    if(a_i) next_state = S1;
                    else    next_state = S3;
             end
		  S3:  begin
                    if(a_i) next_state = S4;
                    else    next_state = S0;
			    end
		  S4:  begin
                    if(a_i) next_state = S1;
                    else    next_state =S5;
             end
		  S5:  begin
                    if(a_i) next_state = S1;
                    else    next_state = S3;
             end
        default : next_state = 3'bxx;
   endcase
end
//输出逻辑
always @ (*) beign
    case(current_state)
        S0:    z_o = 1'b0;
        S1:    z_o = 1'b0;
		S2:    z_o = 1'b0;
	    S3:    z_o = 1'b0;
		S4:    z_o = 1'b0;
	    S5:    z_o = 1'b1;
        default:  z_0 = 1'b0;
    endcase
end
endmodule

你可能感兴趣的:(Verilog)