不枉初心,砥砺前行

皮皮祥的博客

欢迎留言,评论

导航

Verilog实现序列产生器(状态转移形,移位形,计数形)

Verilog实现序列产生器是Verilog基础学习甚至求职面试时的一个常见问题,它用到计数器、状态机、移位寄存器等一系列知识。因此有必要进行学习与仿真:

一、思路

    状态转移形(利用状态机转移,逐个输出序列值);
    移位寄存器形(输入整个序列,在时钟驱动下不断按顺序循环输出序列中的某一位,从而实现序列的循环输出);
    计数形(计数与组合逻辑相结合,通过卡诺图化简得到计数值与输出的关系);

仿真:简单起见,假定实现1011序列

二、状态转移形式

采用思路一,设计状态机,实现几个状态循环转移的过程,每一个状态输出对应序列值,实现序列输出;

状态设置:

设置为四个状态,s0=2'b0、s1=2'b1、s2=2'b10、s3=2'b11(常见编码方式有二进制编码、格雷码、独热码,此处选为二进制码)

状态机设置:

三段式描述方式(时序逻辑描述状态转移、组合逻辑描述状态转移条件、时序逻辑描述输出)

Verilog代码如下:

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer: guoliang CLL
  5. //
  6. // Create Date: 2020/02/21 00:20:42
  7. // Design Name:
  8. // Module Name: seq_gen_fsm
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module seq_gen_fsm(
  22. input clk,
  23. input rst_n,
  24. output reg seq
  25. );
  26. // state declaration
  27. parameter s0 = 2'b0,s1 = 2'b1,s2 = 2'b10,s3 = 2'b11;
  28. reg [1:0]c_state,n_state;
  29. // 状态转移
  30. always@(posedge clk or negedge rst_n)
  31. begin
  32. if(!rst_n)
  33. begin
  34. c_state <= s0;
  35. end
  36. else
  37. begin
  38. c_state <= n_state;
  39. end
  40. end
  41. // 状态转移条件
  42. always@(c_state or rst_n)
  43. begin
  44. if(!rst_n)
  45. begin
  46. n_state = s0;
  47. end
  48. else
  49. begin
  50. case(c_state)
  51. s0:n_state = s1;
  52. s1:n_state = s2;
  53. s2:n_state = s3;
  54. s3:n_state = s0;
  55. default:n_state = s0;
  56. endcase
  57. end
  58. end
  59. // 输出
  60. always@(posedge clk or negedge rst_n)
  61. begin
  62. if(!rst_n)
  63. begin
  64. seq <= 1'b0;
  65. end
  66. else
  67. begin
  68. case(n_state)
  69. s0:seq <= 1'b1;
  70. s1:seq <= 1'b0;
  71. s2:seq <= 1'b1;
  72. s3:seq <= 1'b1;
  73. default:seq <= 1'b0;
  74. endcase
  75. end
  76. end
  77. endmodule

测试代码如下:

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. // Create Date: 2020/02/21 00:35:17
  6. // Design Name:
  7. // Module Name: seq_gen_tsb
  8. // Project Name:
  9. // Target Devices:
  10. // Tool Versions:
  11. // Description:
  12. // Dependencies:
  13. // Revision:
  14. // Revision 0.01 - File Created
  15. // Additional Comments:
  16. module seq_gen_tsb(
  17. );
  18. // port
  19. reg clk;
  20. reg rst_n;
  21. wire seq;
  22. // clk
  23. initial
  24. begin
  25. clk = 1'b1;
  26. forever #10 clk = ~clk;
  27. end
  28. initial
  29. begin
  30. rst_n = 1'b1;
  31. #20 rst_n = 1'b0;
  32. #50 rst_n = 1'b1;
  33. end
  34. // instantation
  35. seq_gen_fsm inst(
  36. .clk(clk),
  37. .rst_n(rst_n),
  38. .seq(seq)
  39. );
  40. endmodule

输出波形如下:

RTL电路如下:

三、循环移位形式:

利用循环移位寄存器,每个时钟移位一次,也可以很简单的实现序列产生

实现代码如下:

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2020/02/21 00:58:25
  7. // Design Name:
  8. // Module Name: seq_gen_shift
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module seq_gen_shift(
  22. input clk,
  23. input rst_n,
  24. output seq
  25. );
  26. // sequence declaration
  27. reg [3:0]SEQ = 4'b1011;
  28. //
  29. always@(posedge clk or negedge rst_n)
  30. begin
  31. if(!rst_n)
  32. SEQ <= 4'b1011;
  33. else
  34. SEQ <= {SEQ[2:0],SEQ[3]};
  35. end
  36. assign seq = SEQ[3];
  37. endmodule

测试文件不变

输出如下:

RTL电路如下:

四、计数器译码形式

设计4值的循环计数器,在此基础上对计数进行译码(可以case选择,也可以与或非描述),不同计数值时输出不同序列值,即可实现序列产生;

实现代码如下:

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2020/02/21 01:19:15
  7. // Design Name:
  8. // Module Name: seq_gen_count
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module seq_gen_count(
  22. input clk,
  23. input rst_n,
  24. output seq
  25. );
  26. reg [1:0]count;
  27. always@(posedge clk or negedge rst_n)
  28. begin
  29. if(!rst_n)
  30. count <= 2'b0;
  31. else if(count == 2'b11)
  32. count <= 2'b0;
  33. else
  34. count <= count+2'b1;
  35. end
  36. // out
  37. assign seq = (count[1]&count[0]) | (!count[1]&!count[0]) | (count[1]&!count[0]);
  38. endmodule

测试代码不变

输出如下:

RTL电路如下:

五、参考文献:

有重叠与无重叠序列之序列检测与序列产生

序列信号产生器的verilog HDL 设计

posted on 2023-02-03 15:11  皮皮祥  阅读(304)  评论(0编辑  收藏  举报