画状态转移图
有限状态机三段式
`timescale 1ns / 1ps
module top(
input clk,
input rst_n,
input a,
output reg match
);
reg [3:0]state,next_state;
parameter IDLE=4'd0;
parameter S1=4'd1;
parameter S2=4'd2;
parameter S3=4'd3;
parameter S4=4'd4;
parameter S5=4'd5;
parameter S6=4'd6;
parameter S7=4'd7;
parameter S8=4'd8;
//第一段同步时序逻辑描述状态转移(固定写法)
always@(posedge clk or negedge rst_n)begin
if(!rst_n)
state<=IDLE;
else
state<=next_state;
end
//第二段组合逻辑描述状态转移条件
always@(*)begin
case(state)
IDLE:next_state=a?IDLE:S1;
S1: next_state=a?S2:S1;
S2: next_state=a?S3:S1;
S3: next_state=a?S4:S1;
S4: next_state=a?IDLE:S5;
S5: next_state=a?S2:S6;
S6: next_state=a?S2:S7;
S7: next_state=a?S8:S1;
S8: next_state=a?IDLE:S1;
endcase
end
//第三段时序逻辑描述输出,摩尔型输出只与当前状态有关,米利型输出与当前状态和输入有关
always@(posedge clk or posedge rst_n)begin
if(!rst_n)
match<=1'd0;
else if(state==S8)
match<=1'd1;
else
match<=1'd0;
end
endmodule
tb
`timescale 1ns / 1ps
`define CLK_PERIOD 20
module top_test();
reg clk,rst_n;
reg a;
wire match;
//时钟
initial clk=0;
always#(`CLK_PERIOD/2) clk=~clk;
//输入和复位信号赋初值
initial begin
rst_n = 1;
a = 1;
#(`CLK_PERIOD) rst_n = 0;
#(`CLK_PERIOD) rst_n = 1;
#1;
#(`CLK_PERIOD) a=0;
#(`CLK_PERIOD) a=1;
#(`CLK_PERIOD) a=1;
#(`CLK_PERIOD) a=1;
#(`CLK_PERIOD) a=0;
#(`CLK_PERIOD) a=0;
#(`CLK_PERIOD) a=0;
#(`CLK_PERIOD) a=1;
end
top top_int(
.clk(clk),
.rst_n(rst_n),
.a(a),
.match(match)
);
endmodule
行为级仿真
注意:
1.待检测第一位状态为IDLE
2.后面每一位不向后转移可能回到非IDLE状态,从序列开头开始检测。
序列缓存对比法,则是将八个时刻的数据缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其它元素左移,把最早输入的数据移出。然后将数组和目标序列对比,如果数组和目标序列相等,则说明出现目标序列。
序列缓存对比法在实现上比较简单,本题采用该方法实现。首先声明一个数组,缓存八个时刻的a输入的数值。移位可以通过位截取操作和位拼接操作实现:a_tem[6:0]表示截取a_tem的低7位,{a_tem[6:0],a}表示把a_tem[6:0]和新输入的数值a拼接,a位于低位。
(待补充)