§ Верхний уровень
serial SERIAL( .clk12 (), // Частота .rx (), // Входящие данные .rx_byte (), // Исходящий байт (8 bit) .rx_ready () // Строб готовности );
§ Код модуля
- Модуль приёмопередатчика UART (FTDI Marsohod)
- Скорость: 460800 бод, эквивалентно 51200 байт в секунду (50 кб в секунду)
- Длина: 1 старт бит + 8 бит (байт) + 1 (бит чётности)
module serial( input wire clk12, // Частота 12,00 MHZ input wire rx, // Входящие данные output reg [7:0] rx_byte, // Исходящий байт output wire rx_ready // Бит готовности ); // 460800 baud parameter R_COUNT = 26; // Полный период (12'000'000 / 26 ~ 460800 бод) reg [8:0] rc_data; // Исходящие данные reg [1:0] latch; // Детектор спада фронта reg [6:0] period = 1'b0; // Период между битами reg [3:0] num_bits = 1'b0; // Количество считанных битов (0..8) reg [1:0] flg = 1'b0; // Логика, позволяющая установить строб готовности reg waiting = 1'b1; // По умолчанию, режим приёма включён // Формируется строб готовности после 1 такта по приёму assign rx_ready = (flg == 2'b10); // С помощью двух подряд идущих битов определяем, когда будет спад, чтобы начать приём always @(posedge clk12) latch <= {latch[0], rx}; // Признак окончания данных wire eof = (period == R_COUNT-1 && num_bits == 4'd9); // Распределение входящих битов данных // num_bits = 9 8 7 6 5 4 3 2 1 0 <--- справа налево // Четность [ Данные ] Старт // Основной модуль приёма always @(posedge clk12) begin // Обнаружен спад во время ожидания данных - это стартовый бит. // Переключаемся в режим приёма данных if (waiting && latch[1:0] == 2'b10) begin waiting <= 1'b0; end // Сейчас мы в режиме приема данных else if (!waiting) begin // Сброс периода, и просмотр результатов if (period == R_COUNT-1) begin period <= 1'b0; // Был принят последний бит, в режим ожидания if (num_bits == 4'd9) begin waiting <= 1'b1; // В режим ожидания спада (старт-бита) num_bits <= 1'b0; // Для следующего раза rx_byte <= rc_data[7:0]; // Берем итоговые данные (без старт бита и бита чётности, 8-я позиция) // К следующему биту end else num_bits <= num_bits + 1'b1; end else begin // Обнаружен полупериод - пишет данные if (period == R_COUNT / 2) rc_data <= {latch[1], rc_data[8:1]}; // Считаем количество тиков period <= period + 1'b1; end end // Пишется бит EOF, на следующем такте будет выставлен 1 (строб), который потом исчезнет на ещё одном такте flg <= {flg[0], eof}; end endmodule
5 окт, 2020
© 2007-2023 Все коты классно переколочены