§ Принцип работы

§ Как пользоваться

§ Пример 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;         // Строб 01 на отсылку
12    end
13    else if (tx_ready) begin // Байт отослан
14        txs <= 0;            // Строб 10 на будущий прием байта
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// 8N1 - без бита четности
2module uart(
3
4    input wire       reset_n,   // =0 Сброс схемы
5    input wire       clock_25,  // Тактовая частота 25 mhz
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// Частота 460800 бод, 25000000 / 460800 = 54
20
21   parameter bit_parity = 0; // Проверка четности (=1)
22
23   parameter size = 217;    // 115200
24// parameter size = 434;    // 57600
25// parameter size = 2604;   // 9600
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            // 11/10 бит = start(1) + data(8) + [parity(1)] + stop(1)
59            if (num == 9 + bit_parity)
60            // Прием данных окончен
61            begin rdy <= 0; rx_ready <= 1; end
62            // Сдвиг LSB
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                /* 1..8 DATA-биты */
101                9:  tx <= parity; // Бит четности
102                10: tx <= 1;      // Стоповый бит
103                11: begin rtx <= 0; tx_ready <= 1; end // Завершить передачу
104                default: begin    // Задвигается новый бит (LSB)
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    // Зарегистрировать позитивный фронт SEND
131    lattx <= {lattx[0], tx_send};
132
133end
134
135end
136
137endmodule