题解 | #输入序列连续的序列检测#
不重叠序列检测
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
查看19道真题和解析

