1.输入序列连续的序列检测
- 题面
- 思路
对于序列检测题目,常规的解法有两种:状态机法和序列缓存对比法。
状态机法的过程类似于:在初始状态中,先判断第一位是否符合,若符合则进入下一个状态,判断第二位是否符合;若第一位不符合则保持在初始状态,直到第一位匹配。如前两位匹配,则判断第三位是否符合,若第一位匹配,最新输入的数值和目标序列的第二位不匹配,则根据最新一位是否匹配第一位,进入第一位匹配状态或者初始状态。依次类推。
序列缓存对比法,则是将八个时刻的数据缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其它元素左移,把最早输入的数据移出。然后将数组和目标序列对比,如果数组和目标序列相等,则说明出现目标序列。
序列缓存对比法在实现上比较简单。首先声明一个数组,缓存八个时刻的a输入的数值。移位可以通过位截取操作和位拼接操作实现:a_tem[6:0]表示截取a_tem的低7位,{a_tem[6:0],a}表示把a_tem[6:0]和新输入的数值a拼接,a位于低位。
- 代码
verilog
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg [7:0] a_tem;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
match <=1'b0;
end
else if (a_tem == 8'b0111_0001) begin
match <= 1'b1;
end
else begin
match <= 1'b0;
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
a_tem <= 8'b0;
end
else begin
a_tem <= {a_tem[6:0],a};
end
end
endmodule
2.含有无关项的序列检测
- 题面
- 思路
序列缓存对比法,则是将九个时刻的数据缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其它元素左移,把最早输入的数据移出。然后截取数组的前三位和目标序列011对比,截取数组的后三位和目标序列110对比,如果两段数组都和目标序列相等,则说明出现目标序列。
序列缓存对比法在实现上比较简单,本题采用该方法实现。首先声明一个数组,缓存九个时刻的a输入的数值。移位可以通过位截取操作和位拼接操作实现:a_tem[7:0]表示截取a_tem的低7位,{a_tem[7:0],a}表示把a_tem[7:0]和新输入的数值a拼接,a位于低位。
-
代码
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output match
);
reg [8:0] a_tem;
reg match_f;
reg match_b;always @(posedge clk or negedge rst_n) begin if (!rst_n) begin match_f <=1'b0; end else if (a_tem[8:6] == 3'b011) begin match_f <= 1'b1; end else begin match_f <= 1'b0; end end always @(posedge clk or negedge rst_n) begin if (!rst_n) begin match_b <= 1'b0; end else if (a_tem[2:0] == 3'b110) begin match_b <= 1'b1; end else begin match_b <= 1'b0; end end always @(posedge clk or negedge rst_n) begin if (!rst_n) begin a_tem <= 9'b0; end else begin a_tem <= {a_tem[7:0],a}; end end assign match = match_b && match_f;
endmodule
-
解法2
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg [8:0] sequence;always @(posedge clk or negedge rst_n) begin if (~rst_n) begin sequence <= 9'b0; end else begin sequence <= {sequence[7:0],a}; end end always @(posedge clk or negedge rst_n) begin if (~rst_n) begin match <= 0; end else if (sequence[8:6] == 3'b011 && sequence[2:0] == 3'b110) begin match <= 1; end else begin match <= 0; end end
endmodule
-
解法3
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input a,
output reg match
);
reg [8:0] val;always @(posedge clk or negedge rst_n) begin if (!rst_n) begin val <= 9'b0; end else begin val <= {val[7:0],a}; end end always @(posedge clk or negedge rst_n) begin if (!rst_n) begin match <= 1'b0; end else begin casex (val) 9'b011xxx110 : match <= 1'b1; default : match <= 1'b0; endcase end end
endmodule
3. 不重叠序列检测
- 题意
题目描写错误,应该是001110,而题目是011100,差评。 - 思路