//----------------------------------------------------- // Имямодуля : uart // Имяфайла : uart.v // Функц. назначение : Простой UART // Программист : www.dev-engineer.ru //----------------------------------------------------- module uart ( reset , txclk , ld_tx_data , tx_data , tx_enable , tx_out , tx_empty , rxclk , uld_rx_data , rx_data , rx_enable , rx_in , rx_empty ); // Объявление портов input reset ; input txclk ; input ld_tx_data ; input [7:0] tx_data ; input tx_enable ; output tx_out ; output tx_empty ; input rxclk ; input uld_rx_data ; output [7:0] rx_data ; input rx_enable ; input rx_in ; output rx_empty ; // Внутренние переменные reg [7:0] tx_reg ; reg tx_empty ; reg tx_over_run ; reg [3:0] tx_cnt ; reg tx_out ; reg [7:0] rx_reg ; reg [7:0] rx_data ; reg [3:0] rx_sample_cnt ; reg [3:0] rx_cnt ; reg rx_frame_err ; reg rx_over_run ; reg rx_empty ; reg rx_d1 ; reg rx_d2 ; reg rx_busy ; // Логика UARTприема always @ (posedge rxclk or posedge reset) if (reset) begin rx_reg <= 0; rx_data <= 0; rx_sample_cnt <= 0; rx_cnt <= 0; rx_frame_err <= 0; rx_over_run <= 0; rx_empty <= 1; rx_d1 <= 1; rx_d2 <= 1; rx_busy <= 0; end else begin // Синхронныйиасинхронныйсигнал rx_d1 <= rx_in; rx_d2 <= rx_d1; // Загрузка принятых данных if (uld_rx_data) begin rx_data <= rx_reg; rx_empty <= 1; end // Приём данных только тогда, когда разрешен приём if (rx_enable) begin // Проверка того, что получено начало кадра if (!rx_busy && !rx_d2) begin rx_busy <= 1; rx_sample_cnt <= 1; rx_cnt <= 0; end // Начало кадра обнаружено, переходим к остальным данным if (rx_busy) begin rx_sample_cnt <= rx_sample_cnt + 1; if (rx_sample_cnt == 7) begin if ((rx_d2 == 1) && (rx_cnt == 0)) begin rx_busy <= 0; end else begin rx_cnt <= rx_cnt + 1; // Начало сохранения данных приёма if (rx_cnt > 0 && rx_cnt < 9) begin rx_reg[rx_cnt - 1] <= rx_d2; end if (rx_cnt == 9) begin rx_busy <= 0; // Проверка конца кадра, т.е. кадр принят корректно if (rx_d2 == 0) begin rx_frame_err <= 1; end else begin rx_empty <= 0; rx_frame_err <= 0; rx_over_run <= (rx_empty) ? 0 : 1; end end end end end end if (!rx_enable) begin rx_busy <= 0; end end // UART передатчик always @ (posedge txclk or posedge reset) if (reset) begin tx_reg <= 0; tx_empty <= 1; tx_over_run <= 0; tx_out <= 1; tx_cnt <= 0; end else begin if (ld_tx_data) begin if (!tx_empty) begin tx_over_run <= 0; end else begin tx_reg <= tx_data; tx_empty <= 0; end end if (tx_enable && !tx_empty) begin tx_cnt <= tx_cnt + 1; if (tx_cnt == 0) begin tx_out <= 0; end if (tx_cnt > 0 && tx_cnt < 9) begin tx_out <= tx_reg[tx_cnt -1]; end if (tx_cnt == 9) begin tx_out <= 1; tx_cnt <= 0; tx_empty <= 1; end end if (!tx_enable) begin tx_cnt <= 0; end end endmodule