`timescale 1ns / 1ps module uart_rx (clk, rstn, rx, read_en, data, data_ready); input wire clk; input wire rstn; input wire rx; input wire read_en; output reg [7:0] data; output wire data_ready; reg rx_ff1, rx_ff2; //Отслеживание старта передачи reg receive; //Состояние приемника reg [2:0] count; //Делитель reg [3:0] count_byte; //Счетчик принятых данных. Как примем 9 бит - можно останавливаться wire spad = ~rx_ff1 & rx_ff2; //Отлавливаем старт-бит wire start = ~receive & spad; //Сигнал начала приема. Для инициализации счетчиков. //wire get_bit = ~|count; //При переполнении счетчика-делителя выдираем бит из входных данных wire get_bit = (count == 3); assign data_ready = (count_byte == 10); always @(posedge clk) begin if(read_en) begin rx_ff1 <= rx; rx_ff2 <= rx_ff1; end end always @(negedge rstn) if(~rstn) begin receive <= 0; rx_ff1 <= 0; rx_ff2 <= 0; count <= 0; count_byte <= 0; end //Режим приема, если появился стартовый бит always @(posedge clk) if(read_en) begin if (spad) receive <= 1'b1; else if (data_ready) receive <= 1'b0; if (start) count <= 4'b0; else if(receive) count <= count + 1'b1; end always @(posedge get_bit or posedge start) begin if(read_en) begin if (start) count_byte <= 0; else count_byte <= count_byte + 4'b1; end end //Сдвигаем регистр данных на одну позицию вправо, //и пишем принятый бит в старший бит always @(posedge get_bit) if(read_en) if(count_byte !=0 & count_byte!=9) if (!data_ready) data <= {rx_ff1, data[7:1]}; endmodule