UART通信实验-------深入浅出玩转FPGA(转)
1 module uart_tx
2 (
3 clk,
4 rst_n,
5 rx_data,
6 rx_int,
7 rs232_tx,
8 clk_bps,
9 bps_start
10 );
11
12 input clk;
13 input rst_n;
14 input clk_bps; // 接收或者发送数据位的中间采样点
15 input [ 7 : 0 ] rx_data; // 接收数据寄存器
16 input rx_int; // 接收数据中断信号,接收到数据期间始终为高电平
17 output rs232_tx; // RS232发送数据信号
18 output bps_start; // 接收到数据后,波特率时钟启动信号置位
19
20 reg rx_int0,rx_int1,rx_int2;
21 wire neg_rx_int;
22
23 always @ ( posedge clk or negedge rst_n)
24 begin
25 if ( ! rst_n)
26 begin
27 rx_int0 <= 1 ' b0;
28 rx_int1 <= 1 ' b0;
29 rx_int2 <= 1 ' b0;
30 end
31
32 else
33 begin
34 rx_int0 <= rx_int;
35 rx_int1 <= rx_int0;
36 rx_int2 <= rx_int1;
37 end
38 end
39
40 assign neg_rx_int = ~ rx_int1 & rx_int2;
41
42 reg [ 7 : 0 ] tx_data;
43 reg bps_start_r;
44 reg tx_en;
45 reg [ 3 : 0 ] num;
46
47 always @ ( posedge clk or negedge rst_n)
48 begin
49 if ( ! rst_n)
50 begin
51 bps_start_r <= 1 ' bz;
52 tx_en <= 1 ' b0;
53 tx_data <= 8 ' d0;
54 end
55
56 else if (neg_rx_int)
57 begin
58 bps_start_r <= 1 ' b1;
59 tx_data <= rx_data;
60 tx_en <= 1 ' b1;
61 end
62
63 else if (num == 4 ' d11)
64 begin
65 bps_start_r <= 1 ' b0;
66 tx_en <= 1 ' b0;
67 end
68
69 end
70
71 assign bps_start = bps_start_r;
72
73 reg rs232_tx_r;
74
75 always @ ( posedge clk or negedge rst_n)
76 begin
77 if ( ! rst_n)
78 begin
79 num <= 4 ' d0;
80 rs232_tx_r <= 1 ' b1;
81 end
82
83 else if (tx_en)
84 begin
85 if (clk_bps)
86 begin
87 num <= num + 1 ' b1;
88 case (num)
89 4 ' d0 : rs232_tx_r <= 1 ' b0;
90 4 ' d1 : rs232_tx_r <= tx_data[0];
91 4 ' d2 : rs232_tx_r <= tx_data[1];
92 4 ' d3 : rs232_tx_r <= tx_data[2];
93 4 ' d4 : rs232_tx_r <= tx_data[3];
94 4 ' d5 : rs232_tx_r <= tx_data[4];
95 4 ' d6 : rs232_tx_r <= tx_data[5];
96 4 ' d7 : rs232_tx_r <= tx_data[6];
97 4 ' d8 : rs232_tx_r <= tx_data[7];
98 4 ' d9 : rs232_tx_r <= 1 ' b1;
99 default : rs232_tx_r <= 1 ' b1;
100 endcase
101 end
102
103 else if (num == 4 ' d11) num <= 4 ' d0;
104 end
105 end
106
107 assign rs232_tx = rs232_tx_r;
108
109 endmodule
110
111
1 module uart_rx
2 (
3 clk,
4 rst_n,
5 rs232_rx,
6 rx_data,
7 rx_int,
8 clk_bps,
9 bps_start
10 ) /* synthesis noprune */ ;
11
12 input clk;
13 input rst_n;
14 input rs232_rx; // RS232接收数据信号
15 input clk_bps; // 接收或者发送数据位的中间采样点
16 output bps_start; // 接收到数据后,波特率时钟启动信号置位
17 output [ 7 : 0 ] rx_data; // 接收数据寄存器,保存直至下一个数据到来
18 output rx_int; // 接收数据中断信号,接收到数据期间始终为高电平
19
20 reg rs232_rx0,rs232_rx1,rs232_rx2,rs232_rx3;
21 wire neg_rs232_rx; // 表示数据线接收到下降沿
22
23 always @ ( posedge clk or negedge rst_n)
24 begin
25 if ( ! rst_n)
26 begin
27 rs232_rx0 <= 1 ' b0;
28 rs232_rx1 <= 1 ' b0;
29 rs232_rx2 <= 1 ' b0;
30 rs232_rx3 <= 1 ' b0;
31 end
32
33 else
34 begin
35 rs232_rx0 <= rs232_rx;
36 rs232_rx1 <= rs232_rx0;
37 rs232_rx2 <= rs232_rx1;
38 rs232_rx3 <= rs232_rx2;
39 end
40 end
41
42 assign neg_rs232_rx = rs232_rx3 & rs232_rx2 & ~ rs232_rx1 & ~ rs232_rx0;
43
44 reg bps_start_r;
45 reg [ 3 : 0 ] num;
46 reg rx_int;
47
48 always @ ( posedge clk or negedge rst_n)
49 if ( ! rst_n)
50 begin
51 bps_start_r <= 1 ' bz;
52 rx_int <= 1 ' b0;
53 end
54
55 else if (neg_rs232_rx)
56 begin
57 bps_start_r <= 1 ' b1;
58 rx_int <= 1 ' b1;
59 end
60
61 else if (num == 4 ' d12)
62 begin
63 bps_start_r <= 1 ' b0;
64 rx_int <= 1 ' b0;
65 end
66
67 assign bps_start = bps_start_r;
68
69 reg [ 7 : 0 ] rx_data_r;
70 reg [ 7 : 0 ] rx_tmp_data;
71
72 always @ ( posedge clk or negedge rst_n)
73 if ( ! rst_n)
74 begin
75 rx_tmp_data <= 8 ' d0;
76 num <= 4 ' d0;
77 rx_data_r <= 8 ' d0;
78 end
79
80 else if (rx_int)
81 begin
82 if (clk_bps)
83 begin
84 num <= num + 1 ' b1;
85 case (num)
86 4 ' d1: rx_tmp_data[0] <= rs232_rx;
87 4 ' d2: rx_tmp_data[1] <= rs232_rx;
88 4 ' d3: rx_tmp_data[2] <= rs232_rx;
89 4 ' d4: rx_tmp_data[3] <= rs232_rx;
90 4 ' d5: rx_tmp_data[4] <= rs232_rx;
91 4 ' d6: rx_tmp_data[5] <= rs232_rx;
92 4 ' d7: rx_tmp_data[6] <= rs232_rx;
93 4 ' d8: rx_tmp_data[7] <= rs232_rx;
94 default : ;
95 endcase
96 end
97
98 else if (num == 4 ' d12)
99 begin
100 num <= 4 ' d0;
101 rx_data_r <= rx_tmp_data;
102 end
103 end
104 assign rx_data = rx_data_r;
105
106 endmodule
107
1 module speed_slect
2 (
3 clk,
4 rst_n,
5 bps_start,
6 clk_bps
7 ) /* synthesis noprune */ ;
8
9 input clk; // 50MHZ
10 input rst_n; // the low level is valid
11 input bps_start; // 接收到数据后,波特率时钟启动信号置位,波特率时钟启动信号
12 output clk_bps; // 接收或者发送数据位的中间采样点
13
14 parameter BPS_PARA = 5207 ; // 10^6/9600*1000/20
15 parameter BPS_PARA_2 = 2603 ;
16
17
18 reg clk_bps_r;
19 reg [ 12 : 0 ] cnt;
20
21 always @( posedge clk or negedge rst_n)
22 if ( ! rst_n) cnt <= 13 ' d0;
23 else if ((cnt == BPS_PARA) || ! bps_start) cnt <= 13 ' d0;
24 else cnt <= cnt + 1 ' b1;
25
26 always @ ( posedge clk or negedge rst_n)
27 if ( ! rst_n) clk_bps_r <= 1 ' b0;
28 else if (cnt == BPS_PARA_2) clk_bps_r <= 1 ' b1;
29 else clk_bps_r <= 1 ' b0;
30
31 assign clk_bps = clk_bps_r;
32
33 endmodule
34 /*
35 parameter bps9600 = 5207, //波特率为9600bps
36 bps19200 = 2603, //波特率为19200bps
37 bps38400 = 1301, //波特率为38400bps
38 bps57600 = 867, //波特率为57600bps
39 bps115200 = 433; //波特率为115200bps
40
41 parameter bps9600_2 = 2603,
42 bps19200_2 = 1301,
43 bps38400_2 = 650,
44 bps57600_2 = 433,
45 bps115200_2 = 216;
46 */
47
48
1 module uart_top
2 (
3 clk,
4 rst_n,
5 rs232_rx,
6 rs232_tx
7 );
8
9 input clk;
10 input rst_n;
11 input rs232_rx;
12 output rs232_tx;
13
14 wire bps_start1,bps_start2;
15 wire clk_bps1,clk_bps2;
16 wire [ 7 : 0 ] rx_data /* synthesis keep */ ;
17 wire rx_int;
18
19 speed_slect speed_rx(
20 .clk(clk),
21 .rst_n(rst_n),
22 .bps_start(bps_start1),
23 .clk_bps(clk_bps1)
24 );
25
26 uart_rx uart_rx(
27 .clk(clk),
28 .rst_n(rst_n),
29 .rs232_rx(rs232_rx),
30 .rx_data(rx_data),
31 .rx_int(rx_int),
32 .clk_bps(clk_bps1),
33 .bps_start(bps_start1)
34 );
35
36 speed_slect speed_tx(
37 .clk(clk),
38 .rst_n(rst_n),
39 .bps_start(bps_start2),
40 .clk_bps(clk_bps2)
41 );
42
43 uart_tx uart_tx(
44 .clk(clk),
45 .rst_n(rst_n),
46 .rx_data(rx_data),
47 .rx_int(rx_int),
48 .rs232_tx(rs232_tx),
49 .clk_bps(clk_bps2),
50 .bps_start(bps_start2)
51 );
52
53 endmodule