• FPGA project : usrt_rs232


     

     

    1. module uart_rx
    2. #(
    3. parameter UART_BPS = 'd9600 ,
    4. CLK_FREQ = 'd50_000_000
    5. )(
    6. input wire sys_clk ,
    7. input wire sys_rst_n ,
    8. input wire rx ,
    9. output reg [7:0] po_data ,
    10. output reg po_flag
    11. );
    12. parameter BAUD_CNT_MAX = CLK_FREQ / UART_BPS ;
    13. // reg define signal
    14. reg rx_reg1 ;
    15. reg rx_reg2 ;
    16. reg rx_reg3 ;
    17. reg start ;
    18. reg work_en ;
    19. reg [12:00] baud_cnt ;
    20. reg bit_flag ;
    21. reg [ 3: 0] bit_cnt ;
    22. reg [ 7: 0] rx_data ;
    23. reg rx_flag ;
    24. // rx_reg1 ;rx_reg2 ;rx_reg3 ;
    25. always @(posedge sys_clk or negedge sys_rst_n) begin
    26. if(~sys_rst_n) begin
    27. rx_reg1 <= 1'b1 ;
    28. rx_reg2 <= 1'b1 ;
    29. rx_reg3 <= 1'b1 ;
    30. end else begin
    31. rx_reg1 <= rx ;
    32. rx_reg2 <= rx_reg1 ;
    33. rx_reg3 <= rx_reg2 ;
    34. end
    35. end
    36. // start ;
    37. always @(posedge sys_clk or negedge sys_rst_n) begin
    38. if(~sys_rst_n) begin
    39. start <= 1'b0 ;
    40. end else begin
    41. if(rx_reg3 == 1'b1 && rx_reg2 == 1'b0 && bit_cnt == 4'd0) begin // 或者bit_cnt换成 work_en == 0
    42. start <= 1'b1 ;
    43. end else begin
    44. start <= 1'b0 ;
    45. end
    46. end
    47. end
    48. // work_en ;
    49. always @(posedge sys_clk or negedge sys_rst_n) begin
    50. if(~sys_rst_n) begin
    51. work_en <= 1'b0 ;
    52. end else begin
    53. if(start == 1'b1) begin
    54. work_en <= 1'b1 ;
    55. end else begin
    56. if((bit_cnt == 4'd8) && (bit_flag == 1'b1)) begin
    57. work_en <= 1'b0 ;
    58. end else begin
    59. work_en <= work_en ;
    60. end
    61. end
    62. end
    63. end
    64. // [12:00] baud_cnt ;
    65. always @(posedge sys_clk or negedge sys_rst_n) begin
    66. if(~sys_rst_n) begin
    67. baud_cnt <= 13'd0 ;
    68. end else begin
    69. if(work_en == 1'b1 && baud_cnt == BAUD_CNT_MAX - 1'b1) begin
    70. baud_cnt <= 13'd0 ;
    71. end else begin
    72. if(work_en == 1'b1) begin
    73. baud_cnt <= baud_cnt + 1'b1 ;
    74. end else begin
    75. baud_cnt <= 13'd0 ;
    76. end
    77. end
    78. end
    79. end
    80. // always @(posedge sys_clk or negedge sys_rst_n) begin
    81. // if(~sys_rst_n) begin
    82. // baud_cnt <= 13'd0 ;
    83. // end else begin
    84. // if(work_en == 1'b1 && baud_cnt == BAUD_CNT_MAX - 1'b1 || work_en == 1'b0) begin
    85. // baud_cnt <= 13'd0 ;
    86. // end else begin
    87. // baud_cnt <= baud_cnt + 1'b1 ;
    88. // end
    89. // end
    90. // end
    91. // bit_flag ;
    92. always @(posedge sys_clk or negedge sys_rst_n) begin
    93. if(~sys_rst_n) begin
    94. bit_flag <= 1'b0 ;
    95. end else begin
    96. if(baud_cnt == BAUD_CNT_MAX - 1'b1) begin // 也可以写成baud_cnt == BAUD_CNT_MAX / 2 - 1'b1
    97. bit_flag <= 1'b1 ; // 这样后面赋值时,就可以直接用bit_flag .
    98. end else begin
    99. bit_flag <= 1'b0 ;
    100. end
    101. end
    102. end
    103. // [ 2: 0] bit_cnt ;
    104. always @(posedge sys_clk or negedge sys_rst_n) begin
    105. if(~sys_rst_n) begin
    106. bit_cnt <= 4'd0 ;
    107. end else begin
    108. if(bit_flag == 1'b1 && work_en == 1'b1 && bit_cnt == 4'd8) begin
    109. bit_cnt <= 4'd0 ;
    110. end else begin
    111. if(bit_flag == 1'b1 && work_en == 1'b1) begin
    112. bit_cnt <= bit_cnt + 1'b1 ;
    113. end else begin
    114. if(work_en == 1'b1) begin
    115. bit_cnt <= bit_cnt ;
    116. end else begin
    117. bit_cnt <= 3'd0 ;
    118. end
    119. end
    120. end
    121. end
    122. end
    123. // [7:0] rx_data ,
    124. always @(posedge sys_clk or negedge sys_rst_n) begin
    125. if(~sys_rst_n) begin
    126. rx_data <= 8'd0 ;
    127. end else begin
    128. if(bit_cnt >= 4'd1 && bit_cnt <= 4'd8 && baud_cnt == 13'd3000) begin
    129. rx_data <= {rx_reg3, rx_data[7:1]} ;
    130. end else begin
    131. rx_data <= rx_data ;
    132. end
    133. end
    134. end
    135. // rx_flag
    136. always @(posedge sys_clk or negedge sys_rst_n) begin
    137. if(~sys_rst_n) begin
    138. rx_flag <= 1'b0 ;
    139. end else begin
    140. if(bit_cnt == 4'd8 && bit_flag == 1'b1) begin
    141. rx_flag <= 1'b1 ;
    142. end else begin
    143. rx_flag <= 1'b0 ;
    144. end
    145. end
    146. end
    147. // output signal
    148. // po_flag
    149. always @(posedge sys_clk or negedge sys_rst_n) begin
    150. if(~sys_rst_n) begin
    151. po_flag <= 1'b0 ;
    152. end else begin
    153. if(rx_flag == 1'b1) begin
    154. po_flag <= 1'b1 ;
    155. end else begin
    156. po_flag <= 1'b0 ;
    157. end
    158. end
    159. end
    160. // po_data
    161. always @(posedge sys_clk or negedge sys_rst_n) begin
    162. if(~sys_rst_n) begin
    163. po_data <= 8'd0 ;
    164. end else begin
    165. if(rx_flag == 1'b1) begin
    166. po_data <= rx_data ;
    167. end else begin
    168. po_data <= 8'd0 ;
    169. end
    170. end
    171. end
    172. endmodule
    1. module uart_tx (
    2. input wire sys_clk ,
    3. input wire sys_rst_n ,
    4. input wire [7:0] pi_data ,
    5. input wire pi_flag ,
    6. output reg tx
    7. );
    8. // reg signal define
    9. reg pi_flag_r ;
    10. reg [7:0] pi_data_r ;
    11. reg work_en ;
    12. reg [12:00] baud_cnt ;
    13. reg bit_flag ;
    14. reg [ 3: 0] bit_cnt ;
    15. // pi_flag_r ;
    16. always @(posedge sys_clk or negedge sys_rst_n) begin
    17. if(~sys_rst_n) begin
    18. pi_flag_r <= 1'b0 ;
    19. end else begin
    20. if(pi_flag == 1'b1) begin
    21. pi_flag_r <= 1'b1 ;
    22. end else begin
    23. pi_flag_r <= 1'b0 ;
    24. end
    25. end
    26. end
    27. // [7:0] pi_data_r ;
    28. always @(posedge sys_clk or negedge sys_rst_n) begin
    29. if(~sys_rst_n) begin
    30. pi_data_r <= 1'b0 ;
    31. end else begin
    32. if(pi_flag == 1'b1) begin
    33. pi_data_r <= pi_data ;
    34. end else begin
    35. pi_data_r <= pi_data_r ;
    36. end
    37. end
    38. end
    39. // work_en ;
    40. always @(posedge sys_clk or negedge sys_rst_n) begin
    41. if(~sys_rst_n) begin
    42. work_en <= 1'b0 ;
    43. end else begin
    44. if(baud_cnt == 13'd5027 && bit_cnt == 4'd9) begin
    45. work_en <= 1'b0 ;
    46. end else begin
    47. if(pi_flag_r == 1'b1) begin
    48. work_en <= 1'b1 ;
    49. end else begin
    50. work_en <= work_en ;
    51. end
    52. end
    53. end
    54. end
    55. // [12:00] baud_cnt ;
    56. always @(posedge sys_clk or negedge sys_rst_n) begin
    57. if(~sys_rst_n) begin
    58. baud_cnt <= 13'd0 ;
    59. end else begin
    60. if(work_en == 1'b1 && baud_cnt == 13'd5027 || work_en == 1'b0) begin
    61. baud_cnt <= 13'd0 ;
    62. end else begin
    63. if(work_en == 1'b1) begin
    64. baud_cnt <= baud_cnt + 1'b1 ;
    65. end else begin
    66. baud_cnt <= 13'd0 ;
    67. end
    68. end
    69. end
    70. end
    71. // bit_flag ;
    72. always @(posedge sys_clk or negedge sys_rst_n) begin
    73. if(~sys_rst_n) begin
    74. bit_flag <= 1'b0 ;
    75. end else begin
    76. if(baud_cnt == 13'd5026) begin // 野火上是等于 1 .
    77. bit_flag <= 1'b1 ;
    78. end else begin
    79. bit_flag <= 1'b0 ;
    80. end
    81. end
    82. end
    83. // [ 3: 0] bit_cnt ;
    84. always @(posedge sys_clk or negedge sys_rst_n) begin
    85. if(~sys_rst_n) begin
    86. bit_cnt <= 4'd0 ;
    87. end else begin
    88. if(bit_flag == 1'b1 && bit_cnt == 4'd9 || work_en == 1'b0) begin
    89. bit_cnt <= 4'd0 ;
    90. end else begin
    91. if(bit_flag == 1'b1) begin
    92. bit_cnt <= bit_cnt + 1'b1 ;
    93. end else begin
    94. bit_cnt <= bit_cnt ;
    95. end
    96. end
    97. end
    98. end
    99. // output signal
    100. // tx
    101. always @(posedge sys_clk or negedge sys_rst_n) begin
    102. if(~sys_rst_n) begin
    103. tx <= 1'b1 ;
    104. end else begin
    105. if(work_en == 1'b1 && bit_cnt == 4'd0) begin
    106. tx <= 1'b0 ;
    107. end else begin
    108. if(work_en == 1'b1 && bit_cnt == 4'd9 || work_en == 1'b0) begin
    109. tx <= 1'b1 ;
    110. end else begin
    111. tx <= pi_data_r[bit_cnt - 1'b1] ;
    112. end
    113. end
    114. end
    115. end
    116. endmodule
    1. module top_uart(
    2. input wire sys_clk ,
    3. input wire sys_rst_n ,
    4. input wire rx ,
    5. output wire tx
    6. );
    7. // 模块间连线
    8. wire [7:0] po_data ;
    9. wire po_flag ;
    10. uart_rx uart_rx_insert_top(
    11. .sys_clk ( sys_clk ) ,
    12. .sys_rst_n ( sys_rst_n ) ,
    13. .rx ( rx ) ,
    14. .po_data ( po_data ) ,
    15. .po_flag ( po_flag )
    16. );
    17. uart_tx uart_tx_insert_top(
    18. .sys_clk ( sys_clk ) ,
    19. .sys_rst_n ( sys_rst_n ) ,
    20. .pi_data ( po_data ) ,
    21. .pi_flag ( po_flag ) ,
    22. .tx ( tx )
    23. );
    24. endmodule

     

    1. `timescale 1ns/1ns
    2. module test_top();
    3. reg sys_clk ;
    4. reg sys_rst_n ;
    5. reg rx ;
    6. wire tx ;
    7. // Instantiation
    8. top_uart top_uart_insert(
    9. .sys_clk ( sys_clk ) ,
    10. .sys_rst_n ( sys_rst_n ) ,
    11. .rx ( rx ) ,
    12. .tx ( tx )
    13. );
    14. parameter CYCLE = 20 ;
    15. task rx_bit ;
    16. input [7:0] data ;
    17. integer i ;
    18. for (i = 0;i <= 9 ;i = i + 1 ) begin
    19. case (i)
    20. 0: rx <= 1'b0 ;
    21. 1: rx <= data[i - 1];
    22. 2: rx <= data[i - 1];
    23. 3: rx <= data[i - 1];
    24. 4: rx <= data[i - 1];
    25. 5: rx <= data[i - 1];
    26. 6: rx <= data[i - 1];
    27. 7: rx <= data[i - 1];
    28. 8: rx <= data[i - 1];
    29. 9: rx <= 1'b1 ;
    30. default: rx <= 1'b1 ;
    31. endcase
    32. #(CYCLE * 5207) ;
    33. end
    34. endtask
    35. initial begin
    36. sys_clk = 1'b1 ;
    37. sys_rst_n <= 1'b0 ;
    38. rx <= 1'b1 ;
    39. #( CYCLE * 10 ) ;
    40. sys_rst_n <= 1'b1 ;
    41. #( 210 ) ;
    42. sys_rst_n <= 1'b0 ;
    43. #( 10 ) ;
    44. #( CYCLE * 10 ) ;
    45. sys_rst_n <= 1'b1 ;
    46. #( CYCLE * 100 ) ;
    47. rx_bit(8'd1) ;
    48. rx_bit(8'd2) ;
    49. rx_bit(8'd3) ;
    50. rx_bit(8'd4) ;
    51. rx_bit(8'd5) ;
    52. rx_bit(8'd6) ;
    53. rx_bit(8'd7) ;
    54. rx_bit(8'd8) ;
    55. rx_bit(8'd9) ;
    56. rx_bit(8'd9) ;
    57. $stop ;
    58. end
    59. always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
    60. // initial begin
    61. // $timeformat(-9,0,"ns",6) ;
    62. // /* (第一个位置)
    63. // -9 是10 的负9次方 表示纳秒
    64. // -3 表示毫秒
    65. // */
    66. // /* (第二个位置)
    67. // 0 表示,小数点后显示的位数
    68. // */
    69. // /* (第三个位置)
    70. // “打印字符” 与单位相对应
    71. // */
    72. // /* (第四个位置)
    73. // 6 表示 打印的最小数字字符 是6个
    74. // */
    75. // $monitor("@time %t:sel=%b,seg=%b,cnt_16=%b,sum_tb=%b",$time,sel,seg,cnt_16) ; // 监测函数
    76. // end
    77. endmodule

     

    1. `timescale 1ns/1ns
    2. module test_uart();
    3. reg sys_clk ;
    4. reg sys_rst_n ;
    5. reg rx ;
    6. wire [7:0] po_data ;
    7. wire po_flag ;
    8. wire tx ;
    9. // Instantiation
    10. uart_rx uart_rx_insert(
    11. .sys_clk ( sys_clk ) ,
    12. .sys_rst_n ( sys_rst_n ) ,
    13. .rx ( rx ) ,
    14. .po_data ( po_data ) ,
    15. .po_flag ( po_flag )
    16. );
    17. parameter CYCLE = 20 ;
    18. initial begin
    19. sys_clk = 1'b1 ;
    20. sys_rst_n <= 1'b0 ;
    21. rx <= 1'b1 ;
    22. #( CYCLE * 10 ) ;
    23. sys_rst_n <= 1'b1 ;
    24. #( 210 ) ;
    25. sys_rst_n <= 1'b0 ;
    26. #( 10 ) ;
    27. #( CYCLE * 10 ) ;
    28. sys_rst_n <= 1'b1 ;
    29. #( CYCLE * 100 ) ;
    30. rx <= 1'b0; // 起始位
    31. #( CYCLE * 5207 ) ;
    32. rx <= 1'b1; // 1
    33. #( CYCLE * 5207 ) ;
    34. rx <= 1'b0; // 2
    35. #( CYCLE * 5207 ) ;
    36. rx <= 1'b1; // 3
    37. #( CYCLE * 5207 ) ;
    38. rx <= 1'b0; // 4
    39. #( CYCLE * 5207 ) ;
    40. rx <= 1'b1; // 5
    41. #( CYCLE * 5207 ) ;
    42. rx <= 1'b0; // 6
    43. #( CYCLE * 5207 ) ;
    44. rx <= 1'b1; // 7
    45. #( CYCLE * 5207 ) ;
    46. rx <= 1'b0; // 8
    47. #( CYCLE * 5207 ) ;
    48. rx <= 1'b1; // 终止位
    49. #( CYCLE * 5207 ) ;
    50. $stop ;
    51. end
    52. always #( CYCLE / 2 ) sys_clk = ~sys_clk ;
    53. uart_tx uart_tx_insert(
    54. .sys_clk ( sys_clk ) ,
    55. .sys_rst_n ( sys_rst_n ) ,
    56. .pi_data ( po_data ) ,
    57. .pi_flag ( po_flag ) ,
    58. .tx ( tx )
    59. );
    60. // initial begin
    61. // $timeformat(-9,0,"ns",6) ;
    62. // /* (第一个位置)
    63. // -910 的负9次方 表示纳秒
    64. // -3 表示毫秒
    65. // */
    66. // /* (第二个位置)
    67. // 0 表示,小数点后显示的位数
    68. // */
    69. // /* (第三个位置)
    70. // “打印字符” 与单位相对应
    71. // */
    72. // /* (第四个位置)
    73. // 6 表示 打印的最小数字字符 是6
    74. // */
    75. // $monitor("@time %t:sel=%b,seg=%b,cnt_16=%b,sum_tb=%b",$time,sel,seg,cnt_16) ; // 监测函数
    76. // end
    77. endmodule

     

     

     

     

     

  • 相关阅读:
    线程池自义定参数设置及预估
    Leetcode682:棒球比赛
    微服务架构10个最重要的设计模式,带你了解,完全熟悉
    windows、ubuntu双系统安装教程
    EasyExcel 修改导出的文件属性
    MySQL-进阶CRUD
    leetCode 583.两个字符串的删除操作 动态规划 + 优化空间复杂度(二维dp、一维dp)
    Java实现 leetcode-946. 验证栈序列
    在使用 sqlite 时遇到的奇怪问题的正解
    多线程的重要资料-信号量
  • 原文地址:https://blog.csdn.net/Meng_long2022/article/details/132841325