• FPGA刷题——序列检测


    Verilog快速入门已经全部刷完,详见主页FPGA刷题(1)~(5)

    今天开始干Verilog进阶挑战,序列检测部分有4道题:

     

    目录

     输入序列连续的序列检测

    含有无关项的序列检测

    不重叠序列检测

    输入序列连续的序列检测


     输入序列连续的序列检测

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

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

    序列缓存对比法,则是将八个时刻的数据缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其它元素左移,把最早输入的数据移出。然后将数组和目标序列对比,如果数组和目标序列相等,则说明出现目标序列。

    序列缓存对比法在实现上比较简单,本题采用该方法实现。首先声明一个数组,缓存八个时刻的a输入的数值。移位可以通过位截取操作和位拼接操作实现:a_tem[6:0]表示截取a_tem的低7位,{a_tem[6:0],a}表示把a_tem[6:0]和新输入的数值a拼接,a位于低位。

    1. `timescale 1ns/1ns
    2. module sequence_detect(
    3. input clk,
    4. input rst_n,
    5. input a,
    6. output reg match
    7. );
    8. reg[7:0]a_reg;
    9. always@(posedge clk or negedge rst_n)begin
    10. if(~rst_n)begin
    11. a_reg<=8'd0;
    12. end
    13. else begin
    14. a_reg<={a_reg[6:0],a};
    15. end
    16. end
    17. always@(posedge clk or negedge rst_n)begin
    18. if(a_reg==8'b01110001)begin
    19. match<=1'd1;
    20. end
    21. else begin
    22. match<=1'd0;
    23. end
    24. end
    25. endmodule

    含有无关项的序列检测

    题目要求检测a的序列,a为单bit输入,每个时刻可能具有不同的值,题目要求检测前三位和后三位,不要求检测中间三位,如果把如果把中间的XXX,分别列出:000,001,010,011,100,101,110,111,分别检测,代码过于累赘,考虑分别检测前三位和后三位,分成两个小段的序列检测。当前三位信号和后三位信号同时匹配时,把匹配信号match拉高。

    将九个时刻的数据缓存,作为一个数组,每个时刻的输入位于数组的末尾,数组其它元素左移,把最早输入的数据移出。然后截取数组的前三位和目标序列011对比,截取数组的后三位和目标序列110对比,如果两段数组都和目标序列相等,则说明出现目标序列。

    1. module sequence_detect(
    2. input clk,
    3. input rst_n,
    4. input a,
    5. output match
    6. );
    7. reg [8:0] a_reg;
    8. reg match_1;
    9. reg match_0;
    10. always@(posedge clk or negedge rst_n)begin
    11. if(~rst_n)begin
    12. a_reg<=9'd0;
    13. end
    14. else begin
    15. a_reg<={a_reg[7:0],a};
    16. end
    17. end
    18. always@(posedge clk or negedge rst_n)begin
    19. if(~rst_n)begin
    20. match_1<=1'd0;
    21. end
    22. else if(a_reg[8:6]==3'b011)begin
    23. match_1<=1'd1;
    24. end
    25. else begin
    26. match_1<=1'd0;
    27. end
    28. end
    29. always@(posedge clk or negedge rst_n)begin
    30. if(~rst_n)begin
    31. match_0<=1'd0;
    32. end
    33. else if(a_reg[2:0]==3'b110)begin
    34. match_0<=1'd1;
    35. end
    36. else begin
    37. match_0<=1'd0;
    38. end
    39. end
    40. assign match = (match_1) && (match_0);
    41. endmodule

    不重叠序列检测

     题目要求检测a的序列,a为单bit输入,每个时刻可能具有不同的值, 当连续的六个输入值符合目标序列表示序列匹配,当六个输入值的一个或多个不符合则表示序列不匹配。

    值得注意的是:题目要求以六位数据为一组,不同于常见的序列检测,要求检测重复序列,在画状态转移图时要注意,例如第一位不匹配,不应该返回到初始状态去进行第一位的判断,因为此时的输入是第二位数值,题目要求不对该数值做判断,而需要等到六个时钟周期之后,即第七位数据(第二组数值的第一位)再判断是否匹配目标序列的第一位。

    1. `timescale 1ns/1ns
    2. module sequence_detect(
    3. input clk,
    4. input rst_n,
    5. input data,
    6. output reg match,
    7. output reg not_match
    8. );
    9. parameter ZERO=0, ONE=1, TWO=2, THREE=3, FOUR=4, FIVE=5, SIX=6, FAIL=7;
    10. reg [2:0] state, nstate;
    11. reg [2:0] cnt;
    12. always@(posedge clk or negedge rst_n) begin
    13. if(~rst_n)
    14. cnt <= 0;
    15. else
    16. cnt <= cnt==6? 1: cnt+1;
    17. end
    18. always@(posedge clk or negedge rst_n) begin
    19. if(~rst_n)
    20. state <= ZERO;
    21. else
    22. state <= nstate;
    23. end
    24. always@(*) begin
    25. if(~rst_n)
    26. nstate = ZERO;
    27. else
    28. case(state)
    29. ZERO : nstate = data? FAIL : ONE;
    30. ONE : nstate = data? TWO : FAIL;
    31. TWO : nstate = data? THREE: FAIL;
    32. THREE: nstate = data? FOUR : FAIL;
    33. FOUR : nstate = data? FAIL : FIVE;
    34. FIVE : nstate = data? FAIL : SIX;
    35. SIX : nstate = data? FAIL : ONE;
    36. FAIL : nstate = cnt==6&&data==0? ONE: FAIL;
    37. default: nstate = ZERO;
    38. endcase
    39. end
    40. always@(*) begin
    41. if(~rst_n) begin
    42. match = 0;
    43. not_match = 0;
    44. end
    45. else begin
    46. match = cnt==6&&state==SIX;
    47. not_match = cnt==6&&state==FAIL;
    48. end
    49. end
    50. endmodule

    输入序列连续的序列检测

     

    1. `timescale 1ns/1ns
    2. module sequence_detect(
    3. input clk,
    4. input rst_n,
    5. input data,
    6. input data_valid,
    7. output reg match
    8. );
    9. reg [3:0] pstate,nstate;
    10. parameter idle=4'd0,
    11. s1_d0=4'd1,
    12. s2_d01=4'd2,
    13. s3_d011=4'd3,
    14. s4_d0110=4'd4;
    15. always @(posedge clk or negedge rst_n)
    16. begin
    17. if(!rst_n)
    18. pstate<=idle;
    19. else
    20. pstate<=nstate;
    21. end
    22. always @(pstate or data or data_valid)
    23. begin
    24. case(pstate)
    25. idle:
    26. if(data_valid && !data)
    27. nstate=s1_d0; //第一位匹配
    28. else
    29. nstate=idle;
    30. s1_d0:
    31. if (data_valid)
    32. begin
    33. if (data) nstate = s2_d01; //数据有效且为1,即前两位01匹配,下一状态为s2_d01
    34. else nstate = s1_d0; //数据有效但为0,即只有第一位0匹配,下一状态为s1_d0
    35. end
    36. else nstate = s1_d0; //数据无效,保持在s1_d0
    37. s2_d01:
    38. if (data_valid)
    39. begin
    40. if (data) nstate = s3_d011; //数据有效且为1,即前三位011匹配,下一状态为s3_d011
    41. else nstate = s1_d0; //数据有效但为0,即只有第一位0匹配,下一状态为s1_d0
    42. end
    43. else nstate = s2_d01; //数据无效,保持在s2_d01
    44. s3_d011:
    45. if (data_valid)
    46. begin
    47. if (!data) nstate = s4_d0110; //数据有效且为0,即前四位0110匹配,下一状态为s4_d0110
    48. else nstate = idle; //数据有效但为1,即不匹配,下一状态为idle
    49. end
    50. else nstate = s3_d011; //数据无效,保持在s3_d011
    51. s4_d0110:
    52. if (data_valid)
    53. begin
    54. if (!data) nstate = s1_d0; //数据有效且为0,即匹配目标序列的第一位0,下一状态为s1_d0
    55. else nstate = idle; //数据有效但为1,不匹配目标序列,下一状态为idle
    56. end
    57. else nstate = idle; //数据无效,下一状态为idle
    58. default:
    59. nstate=idle;
    60. endcase
    61. end
    62. always @(pstate or rst_n)
    63. begin
    64. if(!rst_n==1)
    65. match=1'b0;
    66. else if(pstate==s4_d0110) //进入状态s4_d0110表示四位数据都匹配,把匹配指示信号match拉高
    67. match=1'b1;
    68. else
    69. match=1'b0;
    70. end
    71. endmodule

  • 相关阅读:
    SpringBoot SpringBoot 基础篇 2 SpringBoot 基础配置 2.4 配置文件加载优先级
    ES性能优化最佳实践- 检索性能提升30倍!
    Docker consul
    新手小白学JAVA 日期类Date SimpleDateFormat Calendar
    做个小工具按规则筛选当前Object并输出基础信息
    2022年11月高项案例分析答案解析
    自动抓取app数据技术方案总结
    torch.nn中LSTM使用
    运行vite项目报错:await import(‘source-map-support‘).then((r) => r.default.install())
    大数据学习(4)-hive表操作
  • 原文地址:https://blog.csdn.net/weixin_46188211/article/details/125969795