题解 | #输入序列连续的序列检测#
不重叠序列检测
http://www.nowcoder.com/practice/9f91a38c74164f8dbdc5f953edcc49cc
不考虑最基础的状态机
提供两种方法,第二种方法资源使用最小。第一种方法是使用counter+RAM,第二种数选器+reg;手头上只有Vivado,简单看了一下资源使用情况
counter+RAM
不用移位寄存器,直接用RAM,资源一样,移位寄存器功耗太大
`timescale 1ns/1ns module sequence_detect( input clk, input rst_n, input data, output reg match, output reg not_match ); reg [2:0] cnt; reg [5:0] ram; always@(posedge clk or negedge rst_n)begin if(! rst_n) cnt <= 3'd0; else if(cnt == 3'd5) cnt <= 3'd0; else cnt <= cnt + 3'd1; end always@(posedge clk or negedge rst_n)begin if(! rst_n) ram <= 6'd0; else case(cnt) 3'd0:ram <= {ram[5:1],data}; 3'd1:ram <= {ram[5:2],data,ram[0]}; 3'd2:ram <= {ram[5:3],data,ram[1:0]}; 3'd3:ram <= {ram[5:4],data,ram[2:0]}; 3'd4:ram <= {ram[5],data,ram[3:0]}; 3'd5:ram <= {data,ram[4:0]}; endcase end always@(posedge clk or negedge rst_n) begin if(! rst_n) match <= 1'd0; else if((ram == 6'b001110 )&&(cnt == 3'd5)) match <= 1'd1; else match <= 1'd0; end always@(posedge clk or negedge rst_n) begin if(! rst_n) not_match <= 1'd0; else if((ram != 6'b001110)&&(cnt == 3'd5)) not_match <= 1'd1; else not_match <= 1'd0; end endmodule
数选器+reg
这种方法就很简单,使用数选器选择出来对应的位,再做同或与最后做与运算,资源用的也很少。
`timescale 1ns/1ns module sequence_detect( input clk, input rst_n, input data, output reg match, output reg not_match ); reg [2:0] cnt; reg cmp; reg detect_cmp; parameter detect = 6'b011100; always@(posedge clk or negedge rst_n)begin if(! rst_n) cnt <= 3'd0; else if(cnt == 3'd5) cnt <= 3'd0; else cnt <= cnt + 3'd1; end always@(*)begin case(cnt) 3'd0: cmp = 1'd0; 3'd1: cmp = 1'd1; 3'd2: cmp = 1'd1; 3'd3: cmp = 1'd1; 3'd4: cmp = 1'd0; 3'd5: cmp = 1'd0; default: cmp = 1'd0; endcase end always@(posedge clk or negedge rst_n) begin if(! rst_n) detect_cmp <= 1'd1; else if(cnt == 3'd5) detect_cmp <= 1'd1; else detect_cmp <= detect_cmp && (~( cmp^ data)); end always@(posedge clk or negedge rst_n) begin if(! rst_n) match <= 1'd0; else if((detect_cmp )&&(cnt == 3'd5)) match <= 1'd1; else match <= 1'd0; end always@(posedge clk or negedge rst_n) begin if(! rst_n) not_match <= 1'd0; else if((!detect_cmp)&&(cnt == 3'd5)) not_match <= 1'd1; else not_match <= 1'd0; end endmodule