FPGA——9600波特率UART串口收发

一、RTL Viewer

 

 二、引脚描述

 

 

 三.波特率计算

系统时钟50MHz

(1bit/波特率bit/s)秒 / (1/50MHz)秒

 

 

 

 四.verilog代码

 1 module uart_rx(
 2     clk     ,
 3     rst_n   ,
 4     rx_uart ,
 5     rx_data
 6 );
 7 
 8 parameter   DATA_R =    8;
 9 parameter   DATA_0 =   13;
10 parameter   DATA_1 =    4;
11 input                               clk;
12 input                             rst_n;
13 input                           rx_uart;
14 output      [DATA_R-1:0]        rx_data;
15 
16 reg         [DATA_R-1:0]        rx_data;
17 
18 reg         [DATA_0-1:0]           cnt0;
19 wire                           add_cnt0;
20 wire                           end_cnt0;
21 
22 reg         [DATA_1-1:0]       cnt1    ;
23 wire                           add_cnt1;
24 wire                           end_cnt1;
25 
26 wire                              nedge;
27 reg                                    flag_add;
28 
29 //9600比特率计数
30 always @(posedge clk or negedge rst_n)begin
31     if(!rst_n)begin
32         cnt0 <= 0;
33     end
34     else if(add_cnt0)begin
35         if(end_cnt0)
36             cnt0 <= 0;
37         else
38             cnt0 = cnt0 + 1'b1;
39     end
40 end
41 assign add_cnt0 = flag_add;
42 assign end_cnt0 = add_cnt0 && cnt0 == 5208 - 1;
43 
44 //9比特串口数据计数
45 always @(posedge clk or negedge rst_n)begin
46     if(!rst_n)begin
47         cnt1 <= 0;
48     end
49     else if(add_cnt1)begin
50         if(end_cnt1)
51             cnt1 <= 0;
52         else
53             cnt1 <= cnt1 + 1'b1;
54     end
55 end
56 assign add_cnt1 = end_cnt0;
57 assign end_cnt1 = add_cnt1 && cnt1 == 9 - 1;
58 
59 
60 
61 //边沿检测,接D触发器
62 //异步信号同步化,防止亚稳态,打两拍
63 reg[2:0]        uart_sync;
64 always @(posedge clk or negedge rst_n)begin
65     if(!rst_n)begin
66         uart_sync <= 3'b111;
67     end
68     else
69         uart_sync <= {uart_sync[1:0],rx_uart};
70 end
71 assign nedge = uart_sync[2:1] == 2'b10;
72 
73 //当接收到的串口由1变0时,flag_add置位
74 //当计数结束时,flag_add复位
75 always @(posedge clk or negedge rst_n)begin
76     if(!rst_n)begin
77         flag_add <= 0;
78     end
79     else if(nedge)begin
80         flag_add <= 1;
81     end
82     else if(end_cnt1)begin
83         flag_add <= 0;
84     end
85 end
86 
87 //cnt1 == 0时,接收的是起始位0,1-8才是数据位
88 always @(posedge clk or negedge rst_n)begin
89     if(!rst_n)begin
90         rx_data <= 8'h00;
91     end
92     else if (add_cnt0 && cnt0 == 5208/2 - 1 && cnt1 > 0) begin
93         rx_data[cnt1 - 1] <= rx_uart;
94     end
95 end
96 
97 endmodule
UART_RX
  1 module uart_tx(
  2     clk     ,
  3     rst_n   ,
  4     tx_vld  ,
  5     tx_data ,
  6     uart_tx
  7 // tx_rdy  
  8 );
  9 
 10 parameter   DATA_T =            8;
 11 parameter   DATA_0 =           13;
 12 parameter   DATA_1 =            4;
 13 
 14 input                         clk;
 15 input                       rst_n;
 16 input                      tx_vld;
 17 input       [DATA_T-1:0]  tx_data;
 18 output                    uart_tx;
 19 // output                     tx_rdy;
 20 
 21 reg                          uart_tx;
 22 // reg                        tx_rdy;
 23 
 24 reg         [DATA_0-1:0]     cnt0;
 25 wire                     add_cnt0;
 26 wire                     end_cnt0;
 27 
 28 reg         [DATA_1-1:0]     cnt1;
 29 wire                     add_cnt1;
 30 wire                     end_cnt1;
 31 
 32 reg                      add_flag;
 33 
 34 reg         [9:0]    tx_data_temp;
 35 wire                    load_data;
 36 
 37 wire                      en_send;
 38 
 39 //9600波特率计数器
 40 always @(posedge clk or negedge rst_n)begin
 41     if(!rst_n)begin
 42         cnt0 <= 0;
 43     end
 44     else if(add_cnt0)begin
 45         if(end_cnt0)
 46             cnt0 <= 0;
 47         else
 48             cnt0 <= cnt0 + 1'b1;
 49     end
 50 end
 51 assign add_cnt0 = add_flag;
 52 assign end_cnt0 = add_cnt0 && cnt0 == 5208 - 1;
 53 
 54 //10比特数据发送计数器
 55 always @(posedge clk or negedge rst_n)begin
 56     if(!rst_n)begin
 57         cnt1 <= 0;
 58     end
 59     else if(add_cnt1)begin
 60         if(end_cnt1)
 61             cnt1 <= 0;
 62         else
 63             cnt1 <= cnt1 + 1'b1;
 64     end
 65 end
 66 assign add_cnt1 = end_cnt0;
 67 assign end_cnt1 = add_cnt1 && cnt1 == 10 - 1;
 68 
 69 //add_flag
 70 always @(posedge clk or negedge rst_n)begin
 71     if(!rst_n)begin
 72         add_flag <= 0;
 73     end
 74     else if(tx_vld)begin
 75         add_flag <= 1;
 76     end
 77     else if(end_cnt1)begin
 78         add_flag <= 0;
 79     end
 80 end
 81 
 82 //装载数据
 83 always @(posedge clk or negedge rst_n)begin
 84     if(!rst_n)begin
 85         tx_data_temp <= 0;
 86     end
 87     else if(load_data)begin
 88         tx_data_temp <= {1'b1,tx_data,1'b0};
 89     end
 90 end
 91 assign load_data = tx_vld && !add_flag;
 92 
 93 //发送数据
 94 always @(posedge clk or negedge rst_n)begin
 95     if(!rst_n)begin
 96         uart_tx <= 1;//1空闲位
 97     end
 98     else if(en_send)begin
 99         uart_tx <= tx_data_temp[cnt1];
100     end
101 end
102 assign en_send = add_cnt0 && cnt0 == 0;
103 
104 
105 // always @(*)begin
106 //     if(add_flag || tx_vld)
107 //         tx_rdy = 0;
108 //     else
109 //         tx_rdy = 1;
110 // end
111 
112 endmodule
UART_TX
 1 module UART_PORT(
 2     clk        ,
 3     rst_n    ,
 4     rx_uart    ,
 5     tx_vld    ,
 6     tx_data    ,    
 7     rx_data    ,
 8     uart_tx
 9 );
10 input                      clk;
11 input                        rst_n;
12 input                      rx_uart;
13 input                    tx_vld;
14 input    [8-1:0]        tx_data;
15 output[8-1:0]        rx_data;
16 output               uart_tx;
17 
18 wire     [8-1:0]         rx_data;
19 wire                     uart_tx;
20 
21 uart_rx UART_RX(
22     .clk    (clk),
23     .rst_n    (rst_n),
24     .rx_uart(rx_uart),
25     .rx_data(rx_data)
26 );
27 
28 uart_tx UART_TX(
29     .clk    (clk),
30     .rst_n    (rst_n),
31     .tx_vld    (tx_vld),
32     .tx_data(tx_data),
33     .uart_tx(uart_tx)
34 );
35 
36 endmodule
UART_PORT

 

posted @ 2021-01-03 22:02  AdriftCore  阅读(886)  评论(0编辑  收藏  举报