§ Принцип работы
§ Как пользоваться
§ Пример ECHO
Ниже приведен код, который реализует простое "эхо" - принимает байт и отсылает его обратно.
1reg [7:0] txb = 0;
2reg txs = 0;
3wire [7:0] rx_byte;
4wire rx_ready;
5wire locked = 1;
6
7always @(posedge clock_25)
8
9 if (rx_ready) begin
10 txb <= rx_byte;
11 txs <= 1;
12 end
13 else if (tx_ready) begin
14 txs <= 0;
15 end
16
17uart UART
18(
19
20 .reset_n (locked),
21 .clock_25 (clock_25),
22 .rx (SERIAL_RX),
23 .tx (SERIAL_TX),
24
25
26 .rx_ready (rx_ready),
27 .rx_byte (rx_byte),
28
29
30 .tx_byte (txb),
31 .tx_send (txs),
32 .tx_ready (tx_ready)
33);
§ Код модуля
Передача данных идет так:
Имя Бит
start = 0
data0 = 1
..
data7 = 8
parity = 9
stop = 10
Всего 11 бит на 8 байт, то есть при скорости 460800 бод будет передано примерно 41 891 байт или ~40 кб в секунду.
1
2module uart(
3
4 input wire reset_n,
5 input wire clock_25,
6
7
8 input rx,
9 output reg rx_ready,
10 output reg [7:0] rx_byte,
11
12
13 output reg tx,
14 input [7:0] tx_byte,
15 input tx_send,
16 output reg tx_ready
17);
18
19
20
21 parameter bit_parity = 0;
22
23 parameter size = 217;
24
25
26
27
28reg [7:0] cnt = 0;
29reg [3:0] num = 0;
30reg rdy = 0;
31reg rtx = 0;
32reg [1:0] latrx = 0;
33
34
35reg [1:0] lattx = 0;
36reg [7:0] cnt_tx = 0;
37reg [3:0] num_tx = 0;
38reg parity = 0;
39reg [7:0] tbyte;
40
41initial rx_ready = 0;
42initial rx_byte = 0;
43initial tx_ready = 0;
44initial tx = 0;
45
46
47always @(posedge clock_25) begin
48
49 rx_ready <= 0;
50
51 if (rdy) begin
52
53 cnt <= cnt + 1;
54
55
56 if (cnt == size/2) begin
57
58
59 if (num == 9 + bit_parity)
60
61 begin rdy <= 0; rx_ready <= 1; end
62
63 else if (num < 9) rx_byte <= {rx, rx_byte[7:1]};
64
65 num <= num + 1;
66
67 end
68 else if (cnt == size-1) cnt <= 0;
69
70 end
71
72 else if (latrx == 2'b10) begin rdy <= 1; {cnt, num, rx_byte} <= 0; end
73
74
75 latrx <= {latrx[0], rx};
76
77end
78
79
80always @(posedge clock_25) begin
81
82if (reset_n == 0) begin tx <= 1; end
83else begin
84
85 tx_ready <= 1'b0;
86
87
88 if (rtx) begin
89
90 cnt_tx <= cnt_tx + 1;
91
92
93 if (cnt_tx == 0) begin
94
95 num_tx <= num_tx + 1;
96
97 case (num_tx)
98
99 0: tx <= 0;
100
101 9: tx <= parity;
102 10: tx <= 1;
103 11: begin rtx <= 0; tx_ready <= 1; end
104 default: begin
105
106 tx <= tbyte[0];
107 tbyte <= tbyte[7:1];
108 parity <= parity ^ tbyte[0];
109
110
111 if (num_tx == 8 + bit_parity) num_tx <= 10;
112
113 end
114
115 endcase
116
117 end
118 else if (cnt_tx == size-1) cnt_tx <= 0;
119
120 end
121
122 else if (lattx == 2'b01) begin
123
124 rtx <= 1;
125 {cnt_tx, num_tx, parity} <= 0;
126 tbyte <= tx_byte;
127
128 end
129
130
131 lattx <= {lattx[0], tx_send};
132
133end
134
135end
136
137endmodule