UART通信实验-------深入浅出玩转FPGA(转)
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