解法一:最容易想到的状态机
- `timescale 1ns/1ns
- module sequence_detect(
- input clk,
- input rst_n,
- input a,
- output reg match
- );
- parameter IDLE = 3'd0;
- parameter s0 = 3'd1;
- parameter s1 = 3'd2;
- parameter s2 = 3'd3;
- parameter s3 = 3'd4;
- parameter s4 = 3'd5;
- parameter s5 = 3'd6;
- parameter s6 = 3'd7;
-
- reg [2:0] state,next_state;
- reg flag;
- always@(*)begin
- if(!rst_n)begin
- state <= IDLE;
- next_state <= IDLE;
- end
- else begin
- case(state)
- IDLE:begin
- if(a==0)
- next_state <= s0;
- else
- next_state <= IDLE;
- end
- s0: begin
- if(a==1)
- next_state <= s1;
- else
- next_state <= s0;
- end
- s1: begin
- if(a==1)
- next_state <= s2;
- else
- next_state <= s0;
- end
- s2: begin
- if(a==1)
- next_state <= s3;
- else
- next_state <= s0;
- end
- s3: begin
- if(a==0)
- next_state <= s4;
- else
- next_state <= IDLE;
- end
- s4: begin
- if(a==0)
- next_state <= s5;
- else
- next_state <= s1;
- end
- s5: begin
- if(a==0)
- next_state <= s6;
- else
- next_state <= s1;
- end
- s6: begin
- if(a==1)
- next_state <= s1;
- else
- next_state <= s0;
- end
- default : next_state <= IDLE;
- endcase
- end
- end
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)
- state <= IDLE;
- else
- state <= next_state;
- end
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)
- flag <= 1'b0;
- else if(state==s6 && a)
- flag <= 1'b1;
- else
- flag <= 0;
- end
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)
- match <= 1'b0;
- else
- match <= flag;
- end
- endmodule
解法二:同样状态机,三目运算符写法 match <= state==EIGHT;也是三目运算符写法
- `timescale 1ns/1ns
- module sequence_detect(
- input clk,
- input rst_n,
- input a,
- output reg match
- );
- parameter ZERO=0,ONE=1,TWO=2,THREE=3,FOUR=4,FIVE=5,SIX=6,SEVEN=7,EIGHT=8;
- reg [3:0] state,nstate;
- always@(posedge clk or negedge rst_n)begin
- if(~rst_n)
- state <= ZERO;
- else
- state <= nstate;
- end
- always@(*)begin
- case(state)
- ZERO :nstate = a? ZERO : ONE;
- ONE :nstate = a? TWO : ONE;
- TWO :nstate = a? THREE: ONE;
- THREE :nstate = a? FOUR : ONE;
- FOUR :nstate = a? ZERO : FIVE;
- FIVE :nstate = a? TWO : SIX;
- SIX :nstate = a? TWO : SEVEN;
- SEVEN :nstate = a? EIGHT : ONE;
- EIGHT :nstate = a? THREE : ONE;
- default: nstate = ZERO;
- endcase
- end
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)
- match <= 0;
- else
- match <= state==EIGHT;
- end
- endmodule
解法三:使用位拼接运算
- `timescale 1ns/1ns
- module sequence_detect(
- input clk,
- input rst_n,
- input a,
- output reg match
- );
- reg [7:0] a_r;
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- a_r <= 1'b0;
- end
- else begin
- a_r <= {a_r[6:0],a};
- end
- end
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- match <= 1'b0;
- end
- else begin
- match <= a_r==8'b01110001;
- end
- end
- endmodule
解法四:解法三的简化
- `timescale 1ns/1ns
- module sequence_detect(
- input clk,
- input rst_n,
- input a,
- output reg match
- );
- reg [7:0] a_reg;
- always@(posedge clk or negedge rst_n)begin
- if(!rst_n)begin
- a_reg <= 8'd0;
- match <= 1'b0;
- end
- else begin
- a_reg <= {a_reg[6:0],a};
- if(a_reg == 8'b0111_0001)
- match <= 1'b1;
- else
- match <= 1'b0;
- end
- end
- endmodule