Uart 串口通訊協議發送設計

 

                                                     

                                                           

  1. module uart_tx(
  2.      rst,
  3.      clk,
  4.      baud_set,  //波特率設置
  5.      din,            //欲發送的數據
  6.      tx,              //發送數據
  7.      done          //發送結束時done為1
  8. ); 
  9.   
  10. input  rst,clk;
  11. input  [7:0] din;
  12. input  [2:0] baud_set;
  13. output tx;
  14. output done;
  15.  
  16. reg [12:0] div_cnt;
  17. reg [3:0] bps_cnt;
  18. reg [7:0] reg0_din;
  19. reg [7:0] reg1_din;
  20. reg tx;
  21. reg en;
  22. reg [12:0] bps_DR;  //分频计数最大值 
  23.  
  24. //=============================================
  25. // 狀態機
  26. //=============================================
  27.  
  28. parameter  trans  = 1'b0//發送數據
  29.                    finish  = 1'b1; //發送結束
  30.                  
  31. reg  present_state, next_state;
  32.  
  33. always@(posedge clk or negedge rst)
  34. begin
  35.     if(!rst)  present_state <= trans;
  36.     else     present_state <= next_state;
  37. end
  38.  
  39. always@(bps_cnt  or  div_cnt  or  present_state)
  40. begin
  41.     case(present_state)
  42.     trans : if(div_cnt == 13'd5207 && bps_cnt == 4'd11
  43.                    next_state = finish;
  44.                 else   
  45.                    next_state = trans;
  46.     finish : next_state = finish;
  47.     endcase
  48. end
  49.  
  50. always@(posedge clk or negedge rst)
  51. begin
  52.     if(!rst) en <= 1'b0;
  53.     else
  54.     begin
  55.         case(present_state)
  56.         trans   : en <= 1'b1;            
  57.         finish  : en <= 1'b0;
  58.         endcase
  59.     end
  60. end
  61.  
  62. //=============================================
  63. // 分频設置
  64. //=============================================
  65.  
  66. always@(posedge clk or negedge rst)
  67. if(!rst)
  68.     bps_DR <= 13'd5207;
  69. else 
  70. begin
  71.     case(baud_set)
  72.     0 : bps_DR <= 13'd5207; //9600 bps
  73.     1 : bps_DR <= 13'd2603; //19200 bps
  74.     2 : bps_DR <= 13'd1301; //38400 bps
  75.     3 : bps_DR <= 13'd867;   //57600 bps
  76.     4 : bps_DR <= 13'd433;   //115200 bps
  77.     default : bps_DR <= 13'd5207;
  78.     endcase
  79. end
  80.  
  81. //=============================================
  82. //為求信號穩定消除亞穩態加兩級寄存器
  83. //=============================================
  84.  
  85. always@(posedge clk)   
  86. begin
  87.     reg0_din <= din;
  88.     reg1_din <= reg0_din;
  89. end
  90.  
  91. //=============================================
  92. // 分頻計數器
  93. //=============================================
  94.  
  95. always@(posedge clk or negedge rst)   
  96. begin
  97.     if(!rst)                                   div_cnt <= 13'd0;
  98.     else if(en)
  99.     begin
  100.         if(div_cnt == bps_DR)    div_cnt <= 13'd0;
  101.         else                                  div_cnt <= div_cnt + 13'd1;
  102.     end 
  103.     else                                      div_cnt <= div_cnt;   
  104. end
  105.  
  106. always@(posedge clk or negedge rst)   
  107. begin
  108.     if(!rst)                                      bps_cnt <= 4'd0;
  109.     else if(div_cnt == bps_DR)
  110.        begin
  111.            if(bps_cnt == 4'd11)        bps_cnt <= 4'd0;
  112.            else                                  bps_cnt <= bps_cnt + 4'd1;
  113.        end
  114.     else                                         bps_cnt <= bps_cnt;
  115. end 
  116.  
  117. //=============================================
  118. // 用多工器將數據發送出去
  119. //=============================================
  120.  
  121. always@(posedge clk or negedge rst)
  122. begin
  123.     if(!rst)
  124.     tx <= 1'b1;
  125.     else
  126.     begin
  127.         case(bps_cnt)
  128.         0 : tx <= 1'b1;
  129.         1 : tx <= 1'b0;         //起始位
  130.         2 : tx <= reg1_din[0];
  131.         3 : tx <= reg1_din[1];
  132.         4 : tx <= reg1_din[2];
  133.         5 : tx <= reg1_din[3];
  134.         6 : tx <= reg1_din[4];
  135.         7 : tx <= reg1_din[5];
  136.         8 : tx <= reg1_din[6];
  137.         9 : tx <= reg1_din[7];
  138.         10: tx <= 1'b1;         //停止位
  139.         default: tx <= 1'b1;
  140.         endcase
  141.     end
  142. end
  143.  
  144. //=============================================
  145. //傳輸結束時done為1
  146. //=============================================
  147.  
  148. assign done = (bps_cnt == 4'd11) ? 1'b1 : 1'b0;
  149.  
  150. //=============================================
  151.  
  152. endmodule
     


  1. //仿真testbench
  2.  
  3. `timescale 1ns/100ps
  4.  
  5. module uart_tx_test1;
  6. reg  rst,clk;
  7. reg  [7:0] din;
  8. reg  [2:0] baud_set;
  9. wire tx;
  10. wire done;
  11.  
  12. uart_tx  uart_tx(
  13.     .rst(rst),
  14.     .clk(clk),
  15.     .din(din),
  16.     .baud_set(baud_set),
  17.     .tx(tx),
  18.     .done(done)
  19. );
  20.  
  21. initial
  22. begin
  23.     clk = 1'b1;
  24.     forever #10 clk = ~clk;  //頻率為50M Hz
  25. end
  26.  
  27. initial
  28. begin
  29.     #0  
  30.     rst = 1'b0;
  31.     baud_set = 3'd0;    // 波特率為9600 bps
  32.     din = 8'b01010101;
  33.     #1  
  34.     rst = 1'b1;
  35.     #200000
  36.     $stop;
  37.     #10 
  38.     $finish;
  39. end
  40.  
  41. endmodule

 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值