[Verilog HDL] VERILOG实现串口传输UART

[复制链接]
11244|32
 楼主| gaochy1126 发表于 2023-5-29 14:41 | 显示全部楼层 |阅读模式
1.接收模块



  1. //****************uart receive module******************//
  2. //********************************************************//
  3. `define SIM
  4. module uart_rx#(
  5.         parameter DATAWIDTH                 = 8,
  6.         parameter BAUD_CNT_WIDTH         = 12,
  7.         parameter BIT_CNT_WIDTH         = 4
  8. )
  9. (
  10.         input                                                                 CLK,
  11.         input                                                                 RSTn,
  12.         input                                                                 rs232_rx,//input data
  13.         output reg         [ DATAWIDTH - 1 : 0 ]         rx_data,//receive data
  14.         output reg                                                         po_flag //finish sig
  15. );
  16. `ifndef SIM
  17. localparam BAUD_END = 5207;//simulate time too long,change to 56(560)
  18. `else
  19. localparam BAUD_END = 56;
  20. `endif
  21. localparam BAUD_M         = BAUD_END / 2 - 1;
  22. localparam BIT_END         = 8;

  23. reg                                                         rx_r1;
  24. reg                                                         rx_r2;
  25. reg                                                         rx_r3;
  26. reg                                                         rx_flag;
  27. reg [ BAUD_CNT_WIDTH - 1 : 0 ]         baud_cnt;
  28. reg                                                         bit_flag;
  29. reg [ BIT_CNT_WIDTH - 1 : 0 ]         bit_cnt;
  30. wire                                                         rx_neg;//rx negedge

  31. assign rx_neg = ~rx_r2 & rx_r3;

  32. always @(posedge CLK or negedge RSTn) begin
  33.         rx_r1 <= 0;
  34.         rx_r2 <= 0;
  35.         rx_r3 <= 0;
  36. end

  37. always @(posedge CLK) begin
  38.         rx_r1 <= rs232_rx;
  39.         rx_r2 <= rx_r1;
  40.         rx_r3 <= rx_r2;
  41. end

  42. //rx_flag
  43. always @(posedge CLK or negedge RSTn) begin
  44.         if (!RSTn) begin
  45.                 // reset
  46.                 rx_flag <= 0;
  47.         end
  48.         else if (rx_neg) begin
  49.                 rx_flag <= 1;
  50.         end
  51.         else if (bit_cnt == 0 && baud_cnt == BAUD_END) begin
  52.                 rx_flag <= 0;
  53.         end
  54. end

  55. //baud_cnt
  56. always @(posedge CLK or  negedge RSTn) begin
  57.         if (!RSTn) begin
  58.                 // reset
  59.                 baud_cnt <= 0;
  60.         end
  61.         else if (baud_cnt == BAUD_END) begin
  62.                 baud_cnt <= 0;
  63.         end
  64.         else if (rx_flag) begin
  65.                 baud_cnt <= baud_cnt + 1;
  66.         end
  67.         else begin
  68.                 baud_cnt <= 0;
  69.         end
  70. end

  71. //bit_flag
  72. always @(posedge CLK or negedge RSTn) begin
  73.         if (!RSTn) begin
  74.                 // reset
  75.                 bit_flag <= 0;
  76.         end
  77.         else if (baud_cnt == BAUD_M ) begin
  78.                 bit_flag <= 1;
  79.         end
  80.         else begin
  81.                 bit_flag <= 0;
  82.         end
  83. end

  84. //bit_cnt
  85. always @(posedge CLK or negedge RSTn) begin
  86.         if (!RSTn) begin
  87.                 // reset
  88.                 bit_cnt <= 0;
  89.         end
  90.         else if (bit_flag == 1 && bit_cnt == BIT_END) begin
  91.                 bit_cnt <= 0;
  92.         end
  93.         else if (bit_flag) begin
  94.                 bit_cnt <= bit_cnt + 1;
  95.         end
  96. end

  97. //rx_data
  98. always @(posedge CLK or negedge RSTn) begin
  99.         if (!RSTn) begin
  100.                 // reset
  101.                 rx_data <= 0;
  102.         end
  103.         else if (bit_flag == 1 && bit_cnt >= 1) begin
  104.                 rx_data <= { rx_r2, rx_data [ DATAWIDTH - 1 : 1 ] };
  105.         end
  106. end

  107. //po_flag
  108. always @(posedge CLK or negedge RSTn) begin
  109.         if (!RSTn) begin
  110.                 // reset
  111.                 po_flag <= 0;
  112.         end
  113.         else if (bit_cnt == BIT_END && bit_flag == 1) begin
  114.                 po_flag <= 1;
  115.         end
  116.         else begin
  117.                 po_flag <= 0;
  118.         end
  119. end
  120. endmodule


 楼主| gaochy1126 发表于 2023-5-29 14:42 | 显示全部楼层
testbench:
  1. module uart_rx_tb;
  2.         reg                         CLK;
  3.         reg                         RSTn;
  4.         reg                         rs232_tx;

  5.         wire                         po_flag;
  6.         wire [7:0]                 rx_data;

  7.         reg  [7:0]                 mem [4:0];

  8. initial $readmemh ("D:/Project/verilog_pro/project_module/sdram_controller/src/tx_data.txt",mem);

  9. initial
  10.         begin
  11.                 CLK = 1;
  12.                 forever #5 CLK = ~CLK;
  13.         end

  14. initial
  15.         begin
  16.                 RSTn = 0;
  17.                 rs232_tx <= 1;
  18.                 #100
  19.                 RSTn = 1;
  20.                 #100
  21.                 tx_byte();
  22.         end

  23. task tx_byte();
  24.         integer i;
  25.         for (i = 0; i < 5;i=i+1 )
  26.                 begin
  27.                         tx_bit(mem[i]);
  28.                 end
  29. endtask

  30. task tx_bit(
  31.         input [7:0] data
  32. );
  33.         integer i;
  34.         for (i = 0; i < 10;i=i+1 )
  35.                 begin
  36.                         case(i)
  37.                                 0:        rs232_tx <= 1'b0;
  38.                                 1:        rs232_tx <= data [0];
  39.                                 2:        rs232_tx <= data [1];
  40.                                 3:        rs232_tx <= data [2];
  41.                                 4:        rs232_tx <= data [3];
  42.                                 5:        rs232_tx <= data [4];
  43.                                 6:        rs232_tx <= data [5];
  44.                                 7:        rs232_tx <= data [6];
  45.                                 8:        rs232_tx <= data [7];
  46.                                 9:        rs232_tx <= 1'b1;
  47.                         endcase
  48.                         #560;
  49.                 end

  50. endtask

  51. uart_rx uart_rx_inst(.CLK                (CLK                ),
  52.                                          .RSTn                (RSTn                ),
  53.                                          .rs232_rx        (rs232_tx        ),
  54.                                          .rx_data        (rx_data        ),
  55.                                          .po_flag        (po_flag        ));

  56. endmodule


评论

赞一个  发表于 2023-5-29 16:59
 楼主| gaochy1126 发表于 2023-5-29 14:42 | 显示全部楼层
txt文件:


评论

赞一个  发表于 2023-5-29 16:59
 楼主| gaochy1126 发表于 2023-5-29 14:43 | 显示全部楼层
2.发送模块

代码:
  1. //******************uart transfer module******************//
  2. //***********************************************************//
  3. `define SIM
  4. module uart_tx#(
  5.         parameter DATAWIDTH                 = 8,
  6.         parameter BAUD_CNT_WIDTH         = 32,
  7.         parameter BIT_CNT_WIDTH         = 4

  8. )
  9. (
  10.         input                                                                 CLK,
  11.         input                                                                 RSTn,
  12.         input                 [ DATAWIDTH - 1 : 0 ]         tx_data,//data
  13.         input                                                                 tx_trig,//transfer sig
  14.         output  reg                                                        rs232_tx//transfer data
  15. );
  16. `ifndef SIM
  17. localparam BAUD_END = 5207;//simulate time too long,change to 56(560)
  18. `else
  19. localparam BAUD_END = 56;
  20. `endif
  21. localparam BAUD_M         = BAUD_END / 2 - 1;
  22. localparam BIT_END         = 8;

  23. reg [ DATAWIDTH - 1 : 0          ]         tx_data_r;
  24. reg                                                         tx_flag;
  25. reg [ BAUD_CNT_WIDTH - 1 : 0 ]         baud_cnt;
  26. reg                                                         bit_flag;
  27. reg [ BIT_CNT_WIDTH - 1 : 0  ]         bit_cnt;
  28. //reg                             rs232_tx_t;

  29. //tx_data_r
  30. always @(posedge CLK or  negedge RSTn) begin
  31.         if (!RSTn) begin
  32.                 // reset
  33.                 tx_data_r <= 0;
  34.         end
  35.         else if (tx_trig == 1 && tx_flag == 0) begin
  36.                 tx_data_r <= tx_data;
  37.         end
  38. end


  39. //tx_flag
  40. always @(posedge CLK or negedge RSTn) begin
  41.         if (!RSTn) begin
  42.                 // reset
  43.                 tx_flag <= 0;
  44.         end
  45.         else if (tx_trig == 1 && tx_flag == 0) begin
  46.                 tx_flag <= 1;
  47.         end
  48.         else if (bit_cnt == BIT_END && bit_flag == 1) begin
  49.                 tx_flag <= 0;
  50.         end
  51. end
  52. //baud_cnt
  53. always @(posedge CLK or  negedge RSTn) begin
  54.         if (!RSTn) begin
  55.                 // reset
  56.                 baud_cnt <= 0;
  57.         end
  58.         else if (baud_cnt == BAUD_END) begin
  59.                 baud_cnt <= 0;
  60.         end
  61.         else if (tx_flag) begin
  62.                 baud_cnt <= baud_cnt + 1;
  63.         end
  64.         else begin
  65.                 baud_cnt <= 0;
  66.         end

  67. end
  68. //bit_flag
  69. always @(posedge CLK or  negedge RSTn) begin
  70.         if (!RSTn) begin
  71.                 // reset
  72.                 bit_flag <= 0;
  73.         end
  74.         else if (baud_cnt == BAUD_END) begin
  75.                 bit_flag <= 1;
  76.         end
  77.         else begin
  78.                 bit_flag <= 0;
  79.         end
  80. end
  81. //bit_cnt
  82. always @(posedge CLK or negedge RSTn) begin
  83.         if (!RSTn) begin
  84.                 // reset
  85.                 bit_cnt <= 0;
  86.         end
  87.         else if (bit_flag == 1 && bit_cnt == BIT_END) begin
  88.                 bit_cnt <= 0;
  89.         end
  90.         else if (bit_flag) begin
  91.                 bit_cnt <= bit_cnt + 1;
  92.         end
  93. end
  94. //rs232_tx
  95. always @(posedge CLK or negedge RSTn) begin
  96.         if (!RSTn) begin
  97.                 // reset
  98.                 rs232_tx <= 1;
  99.         end
  100.         else if (tx_flag) begin
  101.                 case(bit_cnt)
  102.                 0:                rs232_tx <= 0;
  103.                 1:                rs232_tx <= tx_data_r[0];
  104.                 2:                rs232_tx <= tx_data_r[1];
  105.                 3:                rs232_tx <= tx_data_r[2];
  106.                 4:                rs232_tx <= tx_data_r[3];
  107.                 5:                rs232_tx <= tx_data_r[4];
  108.                 6:                rs232_tx <= tx_data_r[5];
  109.                 7:                rs232_tx <= tx_data_r[6];
  110.                 8:                rs232_tx <= tx_data_r[7];
  111.                 default:rs232_tx <= 1;

  112.                 endcase
  113.         end
  114.         else begin
  115.                 rs232_tx <= 1;
  116.         end
  117. end

  118. //assign rs232_tx = rs232_tx_t;
  119. endmodule


评论

赞一个  发表于 2023-5-29 17:00
 楼主| gaochy1126 发表于 2023-5-29 14:44 | 显示全部楼层
testbench:、
  1. module uart_tx_tb;
  2.         reg CLK;
  3.         reg RSTn;
  4.         reg tx_trig;
  5.         reg [7:0] tx_data;

  6.         wire rs232_tx;

  7. initial
  8.         begin
  9.                 CLK = 1;
  10.                 forever #5 CLK = ~CLK;
  11.         end

  12. initial
  13.         begin
  14.                 RSTn = 0;
  15.                 #100
  16.                 RSTn = 1;
  17.         end

  18. initial
  19.         begin
  20.                 tx_data <= 0;
  21.                 tx_trig <= 0;
  22.                 #200
  23.                 tx_trig <= 1;
  24.                 tx_data <= 8'h55;
  25.                 #10
  26.                 tx_trig <= 0;
  27.         end
  28. uart_tx uart_tx_inst(.CLK(CLK),
  29.                                          .RSTn(RSTn),
  30.                                          .tx_data(tx_data),
  31.                                          .tx_trig(tx_trig),
  32.                                          .rs232_tx(rs232_tx)
  33.         );
  34. endmodule

评论

赞一个  发表于 2023-5-29 17:00
 楼主| gaochy1126 发表于 2023-5-29 14:45 | 显示全部楼层
3.顶层
  1. module uart_top(
  2.         input                 CLK,
  3.         input                 RSTn,
  4.         input                 rs232_rx,
  5.         output            rs232_tx
  6. );

  7. //***************Main Code*************//
  8. wire [7:0] rx_data;
  9. wire tx_trig;
  10. //reg  rs232_tx_t;

  11. uart_rx uart_rx_inst(.CLK                (CLK                ),
  12.                                          .RSTn                (RSTn                ),
  13.                                          .rs232_rx        (rs232_rx        ),
  14.                                          .rx_data        (rx_data        ),
  15.                                          .po_flag        (tx_trig        ));

  16. uart_tx uart_tx_inst(.CLK                (CLK                ),
  17.                                          .RSTn                (RSTn                ),
  18.                                          .tx_data        (rx_data        ),
  19.                                          .tx_trig        (tx_trig        ),
  20.                                          .rs232_tx        (rs232_tx         ));

  21. endmodule
testbench:
  1. module uart_tb;
  2.         reg CLK;
  3.         reg RSTn;
  4.         reg rs232_rx;
  5.         wire rs232_tx;

  6.         reg  [7:0]                 mem [4:0];

  7. initial $readmemh ("D:/Project/verilog_pro/project_module/sdram_controller/src/tx_data.txt",mem);

  8. initial
  9.         begin
  10.                 RSTn = 0;
  11.                 //rs232_tx = 1;
  12.                 #100
  13.                 RSTn = 1;
  14.                 #100
  15.                 tx_byte();
  16.         end


  17. initial
  18.         begin
  19.                 CLK = 0;
  20.                 forever #5 CLK = ~CLK;
  21.         end
  22. task tx_byte();
  23.         integer i;
  24.         for (i = 0; i < 5;i=i+1 )
  25.                 begin
  26.                         tx_bit(mem[i]);
  27.                 end
  28. endtask

  29. task tx_bit(
  30.         input [7:0] data
  31. );
  32.         integer i;
  33.         for (i = 0; i < 10;i=i+1 )
  34.                 begin
  35.                         case(i)
  36.                                 0:        rs232_rx <= 1'b0;
  37.                                 1:        rs232_rx <= data [0];
  38.                                 2:        rs232_rx <= data [1];
  39.                                 3:        rs232_rx <= data [2];
  40.                                 4:        rs232_rx <= data [3];
  41.                                 5:        rs232_rx <= data [4];
  42.                                 6:        rs232_rx <= data [5];
  43.                                 7:        rs232_rx <= data [6];
  44.                                 8:        rs232_rx <= data [7];
  45.                                 9:        rs232_rx <= 1'b1;
  46.                         endcase
  47.                         #560;
  48.                 end

  49. endtask

  50. uart_top uart_inst(.CLK                        (CLK),
  51.                                         .RSTn                (RSTn),
  52.                                         .rs232_rx        (rs232_rx),
  53.                                         .rs232_tx        (rs232_tx));
  54. endmodule


评论

赞一个  发表于 2023-5-29 17:00
hilahope 发表于 2023-5-29 16:48 来自手机 | 显示全部楼层
资料很实用,谢谢楼主!                                 

评论

赞一个  发表于 2023-5-29 17:00
qiufengsd 发表于 2023-5-29 16:49 来自手机 | 显示全部楼层
资料的确是很全面                                 

评论

赞一个  发表于 2023-5-29 17:00
claretttt 发表于 2023-5-29 16:49 来自手机 | 显示全部楼层
相当全的资料,很适合初学者                                 

评论

赞一个  发表于 2023-5-29 17:00
earlmax 发表于 2023-5-29 16:49 来自手机 | 显示全部楼层
资料很实用,谢谢楼主!                                 

评论

赞一个  发表于 2023-5-29 17:01
maudlu 发表于 2023-5-29 16:49 来自手机 | 显示全部楼层
谢谢lz分享,很有用                                 

评论

赞一个  发表于 2023-5-29 17:01
adolphcocker 发表于 2023-5-29 16:50 来自手机 | 显示全部楼层
很详细的资料                                 

评论

赞一个  发表于 2023-5-29 17:01
tabmone 发表于 2023-5-29 16:50 来自手机 | 显示全部楼层
资料 好好收藏一下                                 

评论

赞一个  发表于 2023-5-29 17:01
louliana 发表于 2023-5-29 16:51 来自手机 | 显示全部楼层
这些资料太全了!!!                 

评论

赞一个  发表于 2023-5-29 17:01
jonas222 发表于 2023-5-29 16:51 来自手机 | 显示全部楼层
很详细的资料                                 

评论

赞一个  发表于 2023-5-29 17:01
everyrobin 发表于 2023-5-29 16:51 来自手机 | 显示全部楼层
谢谢lz分享,很有用                                 

评论

赞一个  发表于 2023-5-29 17:02
wilhelmina2 发表于 2023-5-29 16:51 来自手机 | 显示全部楼层
谢谢lz分享,很有用                                 

评论

赞一个  发表于 2023-5-29 17:02
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:这个社会混好的两种人:一是有权有势,二是没脸没皮的。

1205

主题

11937

帖子

26

粉丝
快速回复 在线客服 返回列表 返回顶部