ase(curr_state)
IDLE :next_state = seq_in?S1:IDLE;
S1 :next_state = seq_in?S1:S2;
S2 :next_state = seq_in?S1:S3;
S3 :next_state = seq_in?S4:IDLE;
S4 :next_state = seq_in?S1:S2;
default:next_state = IDLE; //养成良好代码风格,不能遗漏,防生成latch,也可以通过赋初值避免
endcase
end
end
//第三段描述状态输出(可以使用组合逻辑,也可以用时序逻辑)
//此处采用组合逻辑,同时也提供时序逻辑代码示例
assign mismatch = (curr_state ==S4) ? 1'b0 : 1'b1; //组合逻辑描述输出
/*
//时序逻辑描述输出
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
mismatch <= 1'b1;
end
else if(next_state == S4) begin
mismatch <= 1'b0;
end
else begin
mismatch <= 1'b1;
end
end
*/
endmodule
2.13 testbench
`timescale 1ns/1ps //仿真时间单位1ns 仿真时间精度1ps
module sequence_detect01_tb();
//信号申明
reg clk;
reg rst_n;
reg seq_in;
wire mismatch;
//生成复位信号
//为时钟信号和复位信号赋初值
initial begin
clk = 0;
rst_n = 1;
seq_in = 1;
#5 rst_n = 0;
#10 rst_n = 1;
end
always #6 seq_in = $random; //生成随机数作为信号输入
always #5 clk = ~clk; //生成时钟信号
//模块实例化(将申明的信号连接起来即可)
sequence_detect01 u_sequence_detect01
(.clk (clk),
.rst_n (rst_n),
.seq_in (seq_in),
.mismatch (mismatch)
);
endmodule
2.14仿真结果
)
Testbench中采用随机数来验证序列检测器的准确性,当时间来到705ns,随机数连续输出1001,mismatch在接收四位数字进行信号翻转。
2.2移位寄存器法
2.21 使用移位寄存器法检测1001
题目:设计一个序列检测器,用来检测序列 1001,用_移位寄存器_完成电路设计。
移位寄存器方法比较简单。设置一个和序列等长的寄存器,在数据输入后将输入移入寄存器的最低位,并判断寄存器中的值是否与序列相同。因为移位寄存器的工作原理,设计出来的序列检测器可以重叠检测序列。
2.22 verilog代码
//使用移位寄存器设计检测“1001”的序列检测器
//可重叠检测序列“1001”
module sequence_detect02(
input clk,
input rst_n,
input seq_in,
output reg mismatch //时序逻辑中需要定义为reg型
);
reg [3:0] seq_in_r; //定义一个寄存器缓存数据
//使用时序逻辑完成复位和移位寄存器移位过程
always@(posedge clk or negedge rst_n) begin
if (!rst_n) begin
seq_in_r <= 4'b0; //中间寄存器复位
end
else begin
seq_in_r <= {seq_in_r[2:0],seq_in}; //输入数据置于数组右端,移位寄存器左移位
end
end
//使用时序逻辑完成复位与输出
always@(posedge clk or negedge rst_n) begin
if (!rst_n) begin
mismatch <= 1'b1;
end
else if (seq_in_r == 4'b1001) begin //若检测到1001则将mismatch置1,表明检测到序列1001
mismatch <= 1'b0;
end
else begin
mismatch <= 1'b1; //养成良好代码风格,不能遗漏,防生成latch,可通过赋初值避免
end
end
endmodule
2.23 testbench
`timescale 1ns/1ps //仿真时间单位1ns 仿真时间精度1ps
module sequence_detect02_tb;
//信号申明
reg clk;
reg rst_n;
reg seq_in;
wire mismatch;
//复位信号生成
//时钟信号与复位信号赋初值
initial begin
clk = 0;
rst_n = 1;
seq_in = 1;
#5 rst_n = 0;
#10 rst_n = 1;
end
always #6 seq_in = $random; //生成随机数作为信号输入
always #5 clk = ~clk; //生成时钟信号
//模块实例化(将申明的信号连接起来即可)
sequence_detect01 u_sequence_detect01
(.clk (clk),
.rst_n (rst_n),
.seq_in (seq_in),
.mismatch (mismatch)
);
endmodule
2.24仿真结果
Testbench中采用随机数来验证序列检测器的准确性,当时间来到705ns,随机数连续输出1001,mismatch在接收四位数字且在时钟上升沿进行信号翻转。
三、重叠检测与非重叠检测(检测序列1001)
数字IC序列检测中的重叠检测和非重叠检测是两种不同的检测方式。
重叠检测是指在一个序列中,子序列之间会有部分重叠的情况,而重叠区域也需要进行检测,并被判定为单独的子序列。
非重叠检测则是指在一个序列中,每个子序列之间没有重叠部分,因此只需要检测每个子序列本身是否满足特定的条件即可。
3.1重叠检测
3.11 重叠检测方法
题目:设计一个序列检测器,用来检测序列 1001,用_状态机完成电路,可重复检测_序列1001
第一步,分析状态机状态转移,分析如下:
IDLE: 初始状态,代表目前没有接收到满足要求的数据。
seq_in = 1时,等于1001中的第一个数,进入S1状态;
seq_in = 0时,保持状态。
S1:代表目前已经有了1个匹配的数据。
seq_in = 0时,当前序列为10,等于1001中的前两个数,进入S2状态;
seq_in = 1时,当前序列为11,不是1001的前两个数,但1是1001的第一个数,所以保持S1状态。
S2:代表目前已经有了2个匹配的数据。
seq_in = 0时,当前序列为100,等于1001中的前三个数,进入S3状态;
seq_in = 1时,当前序列为101,不是1001的前三个数