• Xilinx FPGA:vivado用串口控制数码管


    一、项目要求

          要求输入从千位到个位数字给4位数码管,要求分别输入的数字都能显示

    二、关键信号流向

    三、程序设计

    顶层:

    1. `timescale 1ns / 1ps
    2. module TOP(
    3. input sys_clk ,
    4. input rst_n ,
    5. input rx_data ,
    6. output wire[3:0] DIG ,
    7. output wire[7:0] SEG
    8. );
    9. /接收端模块例化
    10. wire [7:0] uart_data ;
    11. wire rx_done ;
    12. uart_rx uart_rx_u1(
    13. . sys_clk (sys_clk ) ,
    14. . rst_n (rst_n ) ,
    15. . rx_data (rx_data ) ,
    16. . uart_data (uart_data) ,
    17. . rx_done (rx_done )
    18. );
    19. //translate模块例化
    20. wire[7:0] trans_data ;
    21. translate translate_u1(
    22. . sys_clk (sys_clk ) ,
    23. . rst_n (rst_n ) ,
    24. . uart_data (uart_data ) ,
    25. . rx_done (rx_done ) ,
    26. . trans_data (trans_data)
    27. );
    28. //conversion模块例化
    29. wire[15:0] number ;
    30. conversion conversion_u1(
    31. . sys_clk ( sys_clk ) ,
    32. . rst_n ( rst_n ) ,
    33. . rx_done ( rx_done ) ,
    34. . trans_data (trans_data) , 0 1 2 3 4
    35. . number ( number )
    36. );
    37. //解码器模块例化
    38. wire [3:0] num ;
    39. wire [7:0] seg ;
    40. decoder decoder_u1(
    41. . num (num) ,
    42. . seg (seg)
    43. );
    44. //数码管模块例化
    45. SEG_state SEG_state_u1(
    46. . sys_clk ( sys_clk) ,
    47. . rst_n ( rst_n ) ,
    48. . number (number ) ,//0~9999
    49. . seg (seg ) ,
    50. . DIG (DIG ) ,
    51. . SEG (SEG ) ,
    52. . num (num )
    53. );
    54. endmodule

    接收端模块:

    1. `timescale 1ns / 1ps
    2. module uart_rx(
    3. input sys_clk ,
    4. input rst_n ,
    5. input rx_data ,
    6. output reg[7:0] uart_data,
    7. output reg rx_done
    8. );
    9. parameter SYSCLK = 50_000_000 ;
    10. parameter Baud = 115200 ;
    11. parameter COUNT = SYSCLK/Baud ;//434 传输1比特所需要的时钟周期
    12. parameter MID = COUNT/2 ;
    13. reg rx_reg1 ;
    14. reg rx_reg2 ;
    15. wire start_flag ;
    16. reg rx_flag ;
    17. reg [3:0] cnt_bit ;//0-9
    18. reg [9:0] cnt ;//0-434
    19. reg [7:0] data_reg ;
    20. always@(posedge sys_clk)
    21. if(!rst_n)begin
    22. rx_reg1 <= 1 ;
    23. rx_reg2 <= 2 ;
    24. end
    25. else
    26. begin
    27. rx_reg1 <= rx_data ;
    28. rx_reg2 <= rx_reg1 ;
    29. end
    30. assign start_flag = ~rx_reg1 & rx_reg2 ;
    31. rx_flag
    32. always@(posedge sys_clk)
    33. if(!rst_n)
    34. rx_flag <= 0 ;
    35. else if (start_flag)
    36. rx_flag <= 1 ;
    37. else if ( cnt_bit == 9 && cnt == MID -1)
    38. rx_flag <= 0 ;
    39. else
    40. rx_flag <= rx_flag ;
    41. /cnt 434
    42. always@(posedge sys_clk)
    43. if(!rst_n)
    44. cnt <= 0 ;
    45. else if ( rx_flag == 1)begin
    46. if ( cnt == COUNT -1 )
    47. cnt <= 0 ;
    48. else
    49. cnt <= cnt +1 ;
    50. end
    51. else
    52. cnt <= 0 ;
    53. 计数器
    54. always@(posedge sys_clk)
    55. if(!rst_n)
    56. cnt_bit <= 0 ;
    57. else if ( rx_flag)begin
    58. if ( cnt == COUNT -1 )begin
    59. if( cnt_bit == 9 )
    60. cnt_bit <= 0 ;
    61. else
    62. cnt_bit <= cnt_bit +1;
    63. end
    64. else
    65. cnt_bit <= cnt_bit ;
    66. end
    67. else
    68. cnt_bit <= 0 ;
    69. /中间寄存器的赋值
    70. always@(posedge sys_clk)
    71. if(!rst_n)
    72. data_reg <= 0 ;
    73. else if ( rx_flag )begin
    74. if ( cnt == MID -1 && cnt_bit>0 && cnt_bit <9 )
    75. data_reg[cnt_bit -1] <= rx_data ;
    76. else
    77. data_reg <= data_reg ;
    78. end
    79. else
    80. data_reg <= 0 ;
    81. 给uart_data赋值
    82. always@(posedge sys_clk )
    83. if(!rst_n)
    84. uart_data <= 0 ;
    85. else if ( rx_flag )begin
    86. if ( cnt_bit == 9 && cnt == MID/4 -1)
    87. uart_data <= data_reg ;
    88. else
    89. uart_data <= uart_data ;
    90. end
    91. else
    92. uart_data <= uart_data ;
    93. rx_done
    94. always@(posedge sys_clk )
    95. if(!rst_n)
    96. rx_done <= 0 ;
    97. else if (rx_flag)begin
    98. if (cnt_bit == 9 && cnt == MID/2 -1)
    99. rx_done <= 1;
    100. else
    101. rx_done <= 0 ;
    102. end
    103. else
    104. rx_done <= 0 ;
    105. endmodule

    翻译模块:

    这里注释掉了组合逻辑的写法,因为根据仿真,组合逻辑引发了时序问题

    1. `timescale 1ns / 1ps
    2. module translate(
    3. input sys_clk ,
    4. input rst_n ,
    5. input [7:0] uart_data ,
    6. input rx_done ,
    7. output reg[7:0] trans_data
    8. );
    9. // always@(*)
    10. // if(!rst_n)
    11. // trans_data <= 0 ;
    12. // else if (rx_done)
    13. // case(uart_data)
    14. // 8'h30 : trans_data <= 8'd0 ;
    15. // 8'h31 : trans_data <= 8'd1 ;
    16. // 8'h32 : trans_data <= 8'd2 ;
    17. // 8'h33 : trans_data <= 8'd3 ;
    18. // 8'h34 : trans_data <= 8'd4 ;
    19. // default:;
    20. // endcase
    21. // else
    22. // trans_data <= trans_data ;
    23. always@(posedge sys_clk)
    24. if(!rst_n)
    25. trans_data <= 0 ;
    26. else if (rx_done)
    27. case(uart_data)
    28. 8'h30 : trans_data <= 8'd0 ;
    29. 8'h31 : trans_data <= 8'd1 ;
    30. 8'h32 : trans_data <= 8'd2 ;
    31. 8'h33 : trans_data <= 8'd3 ;
    32. 8'h34 : trans_data <= 8'd4 ;
    33. default:;
    34. endcase
    35. else
    36. trans_data <= trans_data ;
    37. endmodule

    转换模块:

    1. `timescale 1ns / 1ps
    2. /*
    3. 发送40111 显示4
    4. 发送31011 显示3
    5. 发送21101 显示2
    6. 发送11110 显示1
    7. 发送00000 显示0
    8. */
    9. module conversion(
    10. input sys_clk ,
    11. input rst_n ,
    12. input rx_done ,
    13. input wire[7:0] trans_data , 0 1 2 3 4
    14. output wire[15:0] number
    15. );
    16. /数据处理
    17. reg[14:0] trans_qian ; // 1000-9999
    18. reg[10:0] trans_bai ; //100-999
    19. reg[7:0] trans_shi ; // 10-99
    20. reg[4:0] trans_ge ; //0-9
    21. ///状态机///
    22. localparam IDLE = 4'b0000 ;
    23. localparam GE = 4'b0001 ;
    24. localparam SHI = 4'b0010 ;
    25. localparam BAI = 4'b0100 ;
    26. localparam QIAN = 4'b1000 ;
    27. reg[4:0] cur_state ;
    28. reg[4:0] next_state ;
    29. //state1
    30. always@(posedge sys_clk)
    31. if(!rst_n)
    32. cur_state <= IDLE ;
    33. else
    34. cur_state <= next_state ;
    35. //state2
    36. always@(*)
    37. case(cur_state)
    38. // IDLE : next_state = QIAN ;
    39. IDLE :
    40. begin
    41. if (rx_done)
    42. next_state = QIAN ;
    43. else
    44. next_state = cur_state ;
    45. end
    46. QIAN :
    47. begin
    48. if(rx_done)
    49. next_state = BAI ;
    50. else
    51. next_state = cur_state ;
    52. end
    53. BAI :
    54. begin
    55. if(rx_done)
    56. next_state = SHI ;
    57. else
    58. next_state = cur_state ;
    59. end
    60. SHI :
    61. begin
    62. if(rx_done)
    63. next_state = GE ;
    64. else
    65. next_state = cur_state ;
    66. end
    67. GE :
    68. begin
    69. if(rx_done)
    70. next_state = IDLE ;
    71. else
    72. next_state = cur_state ;
    73. end
    74. default:;
    75. endcase
    76. state3
    77. always@(posedge sys_clk)
    78. if(!rst_n)
    79. begin
    80. trans_qian <= 0 ;
    81. trans_bai <= 0 ;
    82. trans_shi <= 0 ;
    83. trans_ge <= 0 ;
    84. end
    85. else
    86. case(cur_state)
    87. IDLE :
    88. begin
    89. trans_qian <= 0 ;
    90. trans_bai <= 0 ;
    91. trans_shi <= 0 ;
    92. trans_ge <= 0 ;
    93. end
    94. QIAN : trans_qian <= trans_data * 1000 ;
    95. BAI : trans_bai <= trans_data * 100 ;
    96. SHI : trans_shi <= trans_data * 10 ;
    97. GE : trans_ge <= trans_data * 1 ;
    98. default:;
    99. endcase
    100. assign number = trans_qian + trans_bai + trans_shi + trans_ge ;
    101. endmodule

    译码模块:

    1. `timescale 1ns / 1ps
    2. module decoder(
    3. input [3:0] num ,
    4. output reg[7:0] seg
    5. );
    6. always@(*)
    7. case(num)
    8. 4'd0: seg = 8'h3f;
    9. 4'd1: seg = 8'h06;
    10. 4'd2: seg = 8'h5b;
    11. 4'd3: seg = 8'h4f;
    12. 4'd4: seg = 8'h66;
    13. 4'd5: seg = 8'h6d;
    14. 4'd6: seg = 8'h7d;
    15. 4'd7: seg = 8'h07;
    16. 4'd8: seg = 8'h7f;
    17. 4'd9: seg = 8'h6f;
    18. default:;
    19. endcase
    20. endmodule

    数码管模块: 

    1. `timescale 1ns / 1ps
    2. module SEG_state(
    3. input sys_clk ,
    4. input rst_n ,
    5. input wire[15:0] number ,//0~9999
    6. input wire[7:0] seg ,
    7. output wire[3:0] DIG ,
    8. output wire[7:0] SEG ,
    9. output reg[3:0] num
    10. );
    11. parameter MODE = 0 ; ///共阴极
    12. ///数据处理
    13. // reg[3:0] num ;
    14. // reg[7:0] seg ;
    15. reg[3:0] dig ;
    16. wire[3:0] num_ge ;
    17. wire[3:0] num_shi ;
    18. wire[3:0] num_bai ;
    19. wire[3:0] num_qian ;
    20. assign num_ge = number%10 ;
    21. assign num_shi = number/10%10 ;
    22. assign num_bai = number/100%10 ;
    23. assign num_qian = number/1000%10 ;
    24. 状态机
    25. // parameter TIME_1ms = 16'd50_000 ;
    26. parameter TIME_1ms = 16'd5 ; //测试用
    27. reg[3:0] cur_state ;
    28. reg[3:0] next_state ;
    29. reg[20:0] cnt_1ms ;
    30. localparam IDLE = 4'b0000 ;
    31. localparam GE = 4'b0001 ;
    32. localparam SHI = 4'b0010 ;
    33. localparam BAI = 4'b0100 ;
    34. localparam QIAN = 4'b1000 ;
    35. always@(posedge sys_clk)
    36. if(!rst_n)
    37. cur_state <= IDLE ;
    38. else
    39. cur_state <= next_state ;
    40. always@(*)
    41. case(cur_state)
    42. IDLE :next_state = GE ;
    43. GE :
    44. begin
    45. if( cnt_1ms == TIME_1ms -1 )
    46. next_state = SHI ;
    47. else
    48. next_state = cur_state ;
    49. end
    50. SHI :
    51. begin
    52. if( cnt_1ms == TIME_1ms -1 )
    53. next_state = BAI ;
    54. else
    55. next_state = cur_state ;
    56. end
    57. BAI :
    58. begin
    59. if( cnt_1ms == TIME_1ms -1 )
    60. next_state = QIAN ;
    61. else
    62. next_state = cur_state ;
    63. end
    64. QIAN :
    65. begin
    66. if( cnt_1ms == TIME_1ms -1 )
    67. next_state = GE ;
    68. else
    69. next_state = cur_state ;
    70. end
    71. default:;
    72. endcase
    73. always@(posedge sys_clk )
    74. if(!rst_n)begin
    75. dig <= 0 ;
    76. cnt_1ms <= 0 ;
    77. num <= 0 ;
    78. end
    79. else
    80. case(cur_state)
    81. IDLE :
    82. begin
    83. dig <= 0 ;
    84. cnt_1ms <= 0 ;
    85. num <= 0;
    86. end
    87. GE :
    88. begin
    89. dig <= 4'b1110 ;
    90. num <= num_ge ;
    91. if( cnt_1ms == TIME_1ms -1 )
    92. cnt_1ms <= 0 ;
    93. else
    94. cnt_1ms <= cnt_1ms +1 ;
    95. end
    96. SHI :
    97. begin
    98. dig <= 4'b1101 ;
    99. num <= num_shi ;
    100. if( cnt_1ms == TIME_1ms -1 )
    101. cnt_1ms <= 0 ;
    102. else
    103. cnt_1ms <= cnt_1ms +1 ;
    104. end
    105. BAI :
    106. begin
    107. dig <= 4'b1011 ;
    108. num <= num_bai ;
    109. if( cnt_1ms == TIME_1ms -1 )
    110. cnt_1ms <= 0 ;
    111. else
    112. cnt_1ms <= cnt_1ms +1 ;
    113. end
    114. QIAN :
    115. begin
    116. dig <= 4'b0111 ;
    117. num <= num_qian ;
    118. if( cnt_1ms == TIME_1ms -1 )
    119. cnt_1ms <= 0 ;
    120. else
    121. cnt_1ms <= cnt_1ms +1 ;
    122. end
    123. default:;
    124. endcase
    125. assign DIG = (MODE == 0 ) ? dig : ~dig ;
    126. assign SEG = (MODE == 0 ) ? seg : ~seg ;
    127. endmodule

    四、仿真文件

    1. `timescale 1ns / 1ps
    2. module test_bench( );
    3. reg sys_clk ;
    4. reg rst_n ;
    5. reg rx_data ;
    6. wire[3:0] DIG ;
    7. wire[7:0] SEG ;
    8. parameter SYSCLK = 50_000_000 ;
    9. parameter Baud = 115200 ;
    10. parameter COUNT = SYSCLK/Baud ;
    11. parameter MID = COUNT/2 ;
    12. initial
    13. begin
    14. sys_clk = 0 ;
    15. rst_n = 0 ;
    16. #10
    17. rst_n = 1 ;
    18. end
    19. always #1 sys_clk = ~sys_clk ;
    20. initial
    21. begin
    22. uart_out (8'h31) ;
    23. uart_out (8'h32) ;
    24. uart_out (8'h33) ;
    25. uart_out (8'h34) ;
    26. end
    27. 任务函数
    28. task uart_out ;
    29. input [7:0] DATA ;
    30. begin
    31. rx_data = 1 ;空闲位初始
    32. #20
    33. rx_data = 0 ;起始位
    34. #(COUNT*2) rx_data = DATA[0] ;///数据位第一位
    35. #(COUNT*2) rx_data = DATA[1] ;///数据位第二位
    36. #(COUNT*2) rx_data = DATA[2] ;
    37. #(COUNT*2) rx_data = DATA[3] ;
    38. #(COUNT*2) rx_data = DATA[4] ;
    39. #(COUNT*2) rx_data = DATA[5] ;
    40. #(COUNT*2) rx_data = DATA[6] ;
    41. #(COUNT*2) rx_data = DATA[7] ;
    42. #(COUNT*2) rx_data = 1 ;
    43. #(COUNT*2) ;//停止位也需要时间
    44. #200;//0_000 ;
    45. end //2ms数据发送的时间至少要大于点阵屏切换数据的时间(1ms)
    46. endtask
    47. TOP TOP_u1(
    48. . sys_clk (sys_clk) ,
    49. . rst_n (rst_n ) ,
    50. . rx_data (rx_data) ,
    51. . DIG (DIG ) ,
    52. . SEG (SEG )
    53. );
    54. endmodule

    仿真结果:

    五、绑定管脚

    1. set_property PACKAGE_PIN P20 [get_ports {DIG[0]}]
    2. set_property PACKAGE_PIN N18 [get_ports {DIG[1]}]
    3. set_property PACKAGE_PIN P18 [get_ports {DIG[2]}]
    4. set_property PACKAGE_PIN W16 [get_ports {DIG[3]}]
    5. set_property IOSTANDARD LVCMOS33 [get_ports {DIG[3]}]
    6. set_property IOSTANDARD LVCMOS33 [get_ports {DIG[2]}]
    7. set_property IOSTANDARD LVCMOS33 [get_ports {DIG[1]}]
    8. set_property IOSTANDARD LVCMOS33 [get_ports {DIG[0]}]
    9. set_property PACKAGE_PIN R18 [get_ports {SEG[0]}]
    10. set_property PACKAGE_PIN N20 [get_ports {SEG[1]}]
    11. set_property PACKAGE_PIN U20 [get_ports {SEG[2]}]
    12. set_property PACKAGE_PIN W20 [get_ports {SEG[3]}]
    13. set_property PACKAGE_PIN R17 [get_ports {SEG[4]}]
    14. set_property PACKAGE_PIN P19 [get_ports {SEG[5]}]
    15. set_property PACKAGE_PIN T20 [get_ports {SEG[6]}]
    16. set_property PACKAGE_PIN V20 [get_ports {SEG[7]}]
    17. set_property IOSTANDARD LVCMOS33 [get_ports {SEG[7]}]
    18. set_property IOSTANDARD LVCMOS33 [get_ports {SEG[6]}]
    19. set_property IOSTANDARD LVCMOS33 [get_ports {SEG[5]}]
    20. set_property IOSTANDARD LVCMOS33 [get_ports {SEG[4]}]
    21. set_property IOSTANDARD LVCMOS33 [get_ports {SEG[3]}]
    22. set_property IOSTANDARD LVCMOS33 [get_ports {SEG[2]}]
    23. set_property IOSTANDARD LVCMOS33 [get_ports {SEG[1]}]
    24. set_property IOSTANDARD LVCMOS33 [get_ports {SEG[0]}]
    25. set_property PACKAGE_PIN P15 [get_ports rst_n]
    26. set_property PACKAGE_PIN K17 [get_ports sys_clk]
    27. set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
    28. set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
    29. set_property IOSTANDARD LVCMOS33 [get_ports rx_data]
    30. set_property PACKAGE_PIN W18 [get_ports rx_data]

    六、实验结果

    0623

  • 相关阅读:
    怒刷LeetCode的第28天(Java版)
    测试工程师的4层技术发展路线,需要掌握哪些技能?
    Nacos注册中心
    【C++进阶学习】第二弹——继承(下)——挖掘继承深处的奥秘
    【Qt炫酷动画】demo01-仿购物APP弹出和消去的菜单动画
    【每日一读】Deep Variational Network Embedding in Wasserstein Space
    数据湖:分布式开源处理引擎Spark
    第一百三十九回 介绍三个BLE包
    vue中使用vue-property-decorator
    考研408-计算机网络 第一章-计算机网络体系结构学习笔记及习题
  • 原文地址:https://blog.csdn.net/loveyousosad/article/details/139900627