ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【FPGA学习笔记】VL28 输入序列不连续的序列检测

2022-07-03 20:04:27  阅读:209  来源: 互联网

标签:nstate 匹配 FPGA else valid VL28 序列 data match


题目描述:

请编写一个序列检测模块,输入信号端口为data,表示数据有效的指示信号端口为data_valid。当data_valid信号为高时,表示此刻的输入信号data有效,参与序列检测;当data_valid为低时,data无效,抛弃该时刻的输入。当输入序列的有效信号满足0110时,拉高序列匹配信号match。

模块的接口信号图如下:

 

 

 

 

 

 

clk:系统时钟信号 rst_n:异步复位信号,低电平有效 data:单比特信号,待检测的数据 data_valid:输入信号有效标志,当该信号为1时,表示输入信号有效  

输出描述:

match:当输入信号data满足目标序列,该信号为1,其余时刻该信号为0。    

  对于序列检测题目,常规的解法有两种:状态机法和序列缓存对比法。

状态机法的过程类似于题意理解中提到的过程:在初始状态中,在data_valid有效时逐一判断当前时刻的数值。先判断第一位是否符合,若符合则进入下一个状态,判断第二位是否符合;若第一位不符合则保持在初始状态,直到第一位匹配。如前两位匹配,则判断第三位是否符合,若第一位匹配,最新输入的数值和目标序列的第二位不匹配,则根据最新一位是否匹配第一位,进入第一位匹配状态或者初始状态。依次类推。

序列缓存对比法,则是将四个data_valid有效的数据data缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其它元素左移,把最早输入的数据移出。如果数组和目标序列相等,则说明出现目标序列。拉高match信号。

状态机: 首先画出状态转移图。

 

 

 

 s1_d0表示第一位0匹配,s2_d01表示前两位01匹配,s3_d011表示前三位011匹配,s4_d0110表示四位数值0110全部匹配。X表示不论data的值为0或1,都完成该状态跳变。依据状态转移图编写verilog代码:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 `timescale 1ns/1ns module sequence_detect(     input clk,     input rst_n,     input data,     input data_valid,     output reg match     );     reg [3:0] pstate,nstate;   parameter idle=4'd0,           s1_d0=4'd1,           s2_d01=4'd2,           s3_d011=4'd3,           s4_d0110=4'd4;   always @(posedge clk or negedge rst_n) begin     if(!rst_n)         pstate<=idle;     else         pstate<=nstate; end   always @(pstate or data or data_valid) begin     case(pstate)         idle:             if(data_valid && !data)                 nstate=s1_d0;           //第一位匹配             else                 nstate=idle;         s1_d0:             if (data_valid)                 begin                       if (data) nstate = s2_d01;      //数据有效且为1,即前两位01匹配,下一状态为s2_d01                     else nstate = s1_d0;         //数据有效但为0,即只有第一位0匹配,下一状态为s1_d0                 end             else nstate = s1_d0;                 //数据无效,保持在s1_d0         s2_d01:             if (data_valid)                 begin                       if (data) nstate = s3_d011;     //数据有效且为1,即前三位011匹配,下一状态为s3_d011                     else nstate = s1_d0;         //数据有效但为0,即只有第一位0匹配,下一状态为s1_d0                 end             else nstate = s2_d01;                    //数据无效,保持在s2_d01         s3_d011:             if (data_valid)                 begin                       if (!data) nstate = s4_d0110;       //数据有效且为0,即前四位0110匹配,下一状态为s4_d0110                     else nstate = idle;                  //数据有效但为1,即不匹配,下一状态为idle                 end             else nstate = s3_d011;                   //数据无效,保持在s3_d011         s4_d0110:             if (data_valid)                 begin                       if (!data) nstate = s1_d0;      //数据有效且为0,即匹配目标序列的第一位0,下一状态为s1_d0                     else nstate = idle;          //数据有效但为1,不匹配目标序列,下一状态为idle                 end             else nstate = idle;                  //数据无效,下一状态为idle         default:             nstate=idle;         endcase end   always @(pstate or rst_n) begin     if(!rst_n==1)         match=1'b0;     else if(pstate==s4_d0110)                      //进入状态s4_d0110表示四位数据都匹配,把匹配指示信号match拉高             match=1'b1;          else             match=1'b0; end   endmodule
          使用移位寄存器: 此题可以使用移位寄存器,但是需要注意时钟在最后一拍(也就是输入的第四个数)输出就跳变了,不存在延时一拍,因此输出时序部分的判断条件需要注意。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 `timescale 1ns/1ns module sequence_detect(     input clk,     input rst_n,     input data,     input data_valid,     output reg match     );     reg [3:0] data_r;           always@(posedge clk or negedge rst_n) begin         if(~rst_n)             data_r <= 4'b0;         else             data_r <= data_valid? {data_r[2:0], data}: data_r;     end           always@(posedge clk or negedge rst_n) begin         if(~rst_n)             match <= 0;         else             match <= data_r[2:0]==3'b011 && data==0// && ~match;     end //注释为延迟一拍的结果 //  always@(posedge clk or negedge rst_n) begin //     if(~rst_n) //         match <= 0; //     else //         match <= data_r==4'b0110; //  end       endmodule

标签:nstate,匹配,FPGA,else,valid,VL28,序列,data,match
来源: https://www.cnblogs.com/mahaidong/p/16440661.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有