功能说明:
•捕捉11010110序列
•在捕捉到每个序列后产生一个1时钟周期的标记信号
•对捕捉到序列个数进行计数并输出
•计数上限为16,计数满后值保持不变,产生计数慢的溢出信号
•允许序列的嵌套
设计思路:
采用mealy型有限状态机
状态图如下所示

在状态转换图中,状态与状态之间的跳变的判定条件实现了序列的嵌套,具体如图上所示。
代码实现
设计模块
`timescale 1 ps/ 1 ps //产生flag信号时需要用到
module detect_11010110(clk,rst_,din,counter,overflow,flag );
//输入——din串行输入检测信号,clk时钟信号,rst_复位信号
//输出——counter计数信号,overflow计数溢出信号,flag标记信号
input din,clk,rst_;
output counter,overflow,flag;
//检测到的序列的数目
reg [4:0] counter;
//数目大于16,溢出,捕捉到序列后产生一个1时钟周期的标记信号
reg overflow,flag;
reg [3:0] state,next_state;
parameter
s0=4'b0000,s1=4'b0001,s2=4'b0010,s3=4'b0011,s4=4'b0100,s5=4'b0101,s6=4'b0110,s7=4'b0111,s8=4'b1000;//参数分别对应初状态和状态一至八
//敏感信号:clk上升沿,rst_下降沿,state,next_state,din
always @(posedge clk or negedge rst_)
   begin
    if (!rst_)
       state=s0;//复位信号,低电平有效,状态恢复至s0
    else
            state<=next_state;
       end
always @(state or din or rst_)//状态转换代码实现
begin
  if (!rst_)
           next_state=s0;
  else
        case(state)
              s0:begin
                   if (din==1) next_state=s1;
                       else next_state = s0;
                     end
              s1:begin
                   if (din==1) next_state=s2;
                       else next_state=s0;
                     end
              s2:begin
                    if (din==0) next_state=s3;
                            else next_state=s2;
                     end
              s3:begin
                   if (din==1) next_state=s4;
                       else next_state=s0;
                     end
          s4:begin
                   if (din==0) next_state=s5;
                       else next_state=s2;
                     end
              s5:begin
                   if (din==1) next_state=s6;
                       else next_state=s0;
                 end
              s6:begin
                   if (din==1) next_state=s7;
                       else next_state=s0;
                 end
              s7:begin
                   if (din==0) next_state=s8;
                       else next_state=s2;
                 end
              s8:begin
                   if (din==1) next_state=s1;
                       else next_state=s4;
                 end
              default: next_state = s0;
       endcase
end
always @(posedge clk or negedge rst_)
    if(!rst_)
           flag<=1'b0;
        else if(state == s8)
           begin
            #10 flag<=1'b1;
               #10 flag<=1'b0;//检测到序列11010110后输出一个flag信号,长度为一个时钟周期
               end
        else;
always @(posedge clk)//实现序列检测的计数
   begin
     if(!rst_)//复位信号有效,计数输出信号和溢出信号清0
            begin
                   counter<=0;
                      overflow<=0;
               end
         else if(state == s8)
               counter<=counter+5'b00001;
                       begin
                          if (counter>=5'b10000)
                                           begin
                                                 overflow<=1;
                                                 counter<=510000;
                                           end
                              else overflow<=0;
                       end
       end
      
endmodule测试模块
`timescale 1 ps/ 1 ps
module detect_11010110_vlg_tst();
reg clk;
reg din;
reg rst_;
// wires                                              
wire [4:0]  counter;
wire flag;
wire overflow;
                        
detect_11010110 i1 (  
       .clk(clk),
       .counter(counter),
       .din(din),
       .flag(flag),
       .overflow(overflow),
       .rst_(rst_)
);
initial //时钟信号,时钟周期为10                                              
begin                                                 
// code that executes only once                        
// insert code here --> begin                         
#0 clk=0;
forever #5 clk=~clk;
end
initial//复位信号
begin                                                      
// --> end
#0 rst_=1;
#20 rst_=0;
#20 rst_=1;                                            
$display("Running testbench");
end
initial
     $monitor($time,,"counter=%d overflow=%b",counter,overflow);
//调用monitor函数,监控和输出参数counter和overflow的值                                                                          
initial                                                                
begin                                                 
//产生随机的串行输入检测信号din                         
din=0;//起始为0
repeat(5000)//重复5000次,每隔10ps输入一个
    begin
     # 10 din={$random} % 2;
        end
$stop;//调用stop函数                                              
end                                                   
endmodule仿真结果
Monitor函数输出结果

检测到第一个11010110信号,输出一个一时钟周期宽度的flag信号
 
计数计到16,产生overflow溢出信号,counter值保持不变











