列表

详情


VL35. 状态机-非重叠的序列检测

描述

设计一个状态机,用来检测序列 10111,要求:

1、进行非重叠检测   101110111 只会被检测通过一次

2、寄存器输出且同步输出结果

注意rst低电平复位

信号示意图:

波形示意图:


输入描述

输入信号 clk rst data 
类型 wire

输出描述

输出信号  flag
类型  reg

原站题解

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

module sequence_test1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
//*************code***********//

   parameter s0 = 'd0 ;
   parameter s1 = 'd1 ;
   parameter s2 = 'd2 ;
   parameter s3 = 'd3 ;
   parameter s4 = 'd4 ;
   parameter s5 = 'd5 ;
   
    reg [2:0] cs,ns ;
    
    always @ (posedge clk or negedge rst) begin
        if(!rst)
            cs <= s0 ;
        else 
            cs <=  ns ;
    end
    
  always @ (posedge clk or negedge rst) begin
        if(!rst)
            flag <= 1'b0 ;
      else if (ns == s5)
            flag <= 1'b1 ;
      else flag  <= 1'b0 ;        // flag <= ns == s5 ;
  end                          // flag <= (ns == s5) ? 1 : 0 ;
      
    always @ (*) begin
          case (cs)
              s0: if (data) ns = s1 ;
                  else  ns = s0 ;
                  
              s1: if(!data) ns = s2 ;
                  else ns = s1 ;
                  
              s2: if(data) ns = s3 ;
                  else ns = s0 ;
                  
              s3: if(data) ns = s4 ;
                  else ns = s2 ;
                  
              s4: if(data) ns = s5 ;
                  else  ns = s2 ;
                  
              s5: if(data) ns = s1 ;
                  else ns = s0 ;
          endcase
      end
     
/*    reg [2:0] cnt ;  
    reg [4:0] data_tmp ;
 always @ (posedge clk or negedge rst) begin
     if(!rst) begin
         cnt      <= 3'd0 ;
         data_tmp <= 5'b0 ;
         flag     <= 0 ;
      end 
      else begin 
          if(cnt == 4) begin
            cnt      <= 0 ;
            data_tmp <= 0 ;
            if( {data_tmp,data} == 5'b10111 )
                  flag <= 1 ;
            else flag <= 0 ;
          end
          else begin
            cnt        <= cnt +1'b1 ;
            data_tmp   <= { data_tmp[3:0] , data } ;
            flag       <= 0 ;
          end
      end
 end
 */     
      
      
      
      
      
    
//*************code***********//
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

module sequence_test1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
//*************code***********//
parameter a=3'd0,b=3'd1,c=3'd2,d=3'd3,e=3'd4,f=3'd5;
    reg[2:0]state;
    always@(posedge clk or negedge rst)begin
        if(!rst)
            state<=a;
        else begin
            case(state)
                a:state<=(data)?b:a;
                b:state<=(data)?b:c;
                c:state<=(data)?d:a;
                d:state<=(data)?e:a;
                e:state<=(data)?f:a;
                f:state<=(data)?b:a;
                default:state<=a;
            endcase
        end
            
    end
    always@(*)begin
        if(!rst)
            flag<=1'b0;
        else if(state==f)
            flag<=1'b1;
        else
            flag<=1'b0;
    end
   
    

//*************code***********//
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns
 
module sequence_test1(
    input wire clk  ,
    input wire rst  ,
    input wire data ,
    output reg flag
);
//*************code***********//
    parameter S0=0, S1=1, S2=2, S3=3, S4=4, S5=5;
    reg [2:0] state, nstate;
 
    always@(posedge clk or posedge rst) begin
        if(~rst)
            state <= S0;
        else
            state <= nstate;
    end
     
    always@(*) begin
        if(~rst)
            nstate <= S0;
        else
            case(state)
                S0     : nstate <= data? S1: S0;
                S1     : nstate <= data? S0: S2;
                S2     : nstate <= data? S3: S0;
                S3     : nstate <= data? S4: S2;
                S4     : nstate <= data? S5: S2;
                S5     : nstate <= data? S1: S0;
                default: nstate <= S0;
            endcase
    end
     
    always@(*) begin
        if(~rst)
            flag <= 0;
        else
            flag <= state==S5;
    end
//*************code***********//
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

/*设计一个状态机,用来检测序列 10111,要求:
1、进行非重叠检测   即101110111 只会被检测通过一次
2、寄存器输出且同步输出结果*/

//35 状态机-非重叠的序列检测

`timescale 1ns/1ns

module sequence_test1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output reg flag
);
//*************code***********//

	localparam	IDEL  = 3'b000;
	localparam	data1 = 3'b001;
	localparam	data2 = 3'b011;
	localparam	data3 = 3'b010;
	localparam	data4 = 3'b110;
	localparam	data5 = 3'b111;
	
	reg	[2:0] current_state;
	reg	[2:0] next_state;

//LV1:状态转移(同步时序逻辑)
	always@(posedge clk or negedge rst)begin
		if(!rst)
			current_state <= IDEL;
		else
			current_state <= next_state;
	end
//LV2:状态转移条件(组合逻辑)	
	always@(*)begin
		case(current_state)
			IDEL:begin
				if(data == 1'b1)
					next_state <= data1;
				else
					next_state <= IDEL;
			end
			data1:begin
				if(data == 1'b0)
					next_state <= data2;
				else
					next_state <= data1;
			end
			data2:begin
				if(data == 1'b1)
					next_state <= data3;
				else
					next_state <= data2;
			end
			data3:begin
				if(data == 1'b1)
					next_state <= data4;
				else
					next_state <= data3;
			end
			data4:begin
				if(data == 1'b1)
					next_state <= data5;
				else
					next_state <= data4;
			end
			data5:begin
				if(data == 1'b0)
					next_state <= data1;
				else
					next_state <= IDEL;
			end
		endcase
	end
//LV3:状态输出(组合逻辑)
	always@(*)begin
		if(!rst)
			flag <= 1'b0;
		else if(current_state == data5)
			flag <= 1'b1;
		else
			flag <= 1'b0;
	end

//*************code***********//
endmodule

Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06

`timescale 1ns/1ns

module sequence_test1(
	input wire clk  ,
	input wire rst  ,
	input wire data ,
	output flag
);
//*************code***********//

    parameter    IDLE = 3'd0;
    parameter    S0 = 3'd1;
    parameter    S1 = 3'd2;
    parameter    S2 = 3'd3;
    parameter    S3 = 3'd4;
    parameter    S4 = 3'd5;

    reg [2:0] curr_st;
    reg [2:0] next_st;
    
    always@(posedge clk or negedge rst)begin
        if(~rst)
            curr_st <= 3'd0;
        else 
            curr_st <= next_st;
    end
    
    always@(*)begin //10111
        case (curr_st)
            IDLE : next_st = data ? S0 : IDLE; //1
            S0 : next_st = data ? S0 : S1; //10
            S1 : next_st = data ? S2 : IDLE; //01
            S2 : next_st = data ? S3 : S1; //011
            S3 : next_st = data ? S4 : S1; //0111
            S4 : next_st = IDLE; //0111
            default : next_st = IDLE;
        endcase
    end
    
    /*always@(posedge clk or negedge rst)begin
        if(~rst)
            flag <= 1'b0;
        else if(curr_st == S3 && data)
            flag <= 1'b1;
        else
            flag <= 1'b0;
    end*/
    assign flag = (curr_st == S4);
//*************code***********//
endmodule

上一题