0
点赞
收藏
分享

微信扫一扫

verilog序列检测器_11010110

莞尔小迷糊 2022-04-19 阅读 119
windows

功能说明:

•捕捉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值保持不变 

 

 

举报

相关推荐

0 条评论