86 lines
2.3 KiB
Verilog
86 lines
2.3 KiB
Verilog
module uart_rx(
|
|
input wire clk,
|
|
input wire rst_n,
|
|
input wire rx_en,
|
|
input wire rx_pin,
|
|
output reg rx_rdy,
|
|
output reg [7:0] rx_data
|
|
);
|
|
|
|
parameter DIV = 50;
|
|
parameter COUNT_WITH = 6;
|
|
reg [COUNT_WITH-1:0] count;
|
|
|
|
|
|
reg [7:0] rx_reg;
|
|
reg [3:0] rx_cnt;
|
|
reg[1:0] rx_state;
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if(~rst_n) begin
|
|
count <= 0;
|
|
rx_state <= 0;
|
|
rx_cnt <= 0;
|
|
rx_rdy <= 1'd0;
|
|
rx_reg <= 8'd0;
|
|
rx_data <= 8'd0;
|
|
end else begin
|
|
if(rx_en == 0) begin
|
|
count <= 0;
|
|
rx_state <= 0;
|
|
rx_cnt <= 0;
|
|
rx_rdy <= 1'd0;
|
|
rx_reg <= 8'd0;
|
|
rx_data <= 8'd0;
|
|
end else begin
|
|
case(rx_state)
|
|
0: begin
|
|
if(rx_pin == 0) begin
|
|
rx_state <= 1'd1;
|
|
count <= 1;
|
|
end
|
|
end
|
|
1: begin
|
|
if(count == (DIV-1)) begin
|
|
rx_state <= 2;
|
|
rx_cnt <= 0;
|
|
count <= 0;
|
|
rx_reg <= 8'd0;
|
|
end else begin
|
|
count <= count + 1'd1;
|
|
end
|
|
end
|
|
2: begin
|
|
if(count == (DIV-1)) begin
|
|
count <= 0;
|
|
if(rx_cnt == 8) begin
|
|
rx_state <= 3;
|
|
end
|
|
end else if(count == (DIV/2-1))begin
|
|
rx_reg[rx_cnt] <= rx_pin;
|
|
rx_cnt <= rx_cnt + 1'd1;
|
|
count <= count + 1'd1;
|
|
end else begin
|
|
count <= count + 1'd1;
|
|
end
|
|
end
|
|
3: begin
|
|
if(count == (DIV-1)) begin
|
|
count <= 0;
|
|
rx_state <= 0;
|
|
rx_rdy <= 1'd0;
|
|
end else begin
|
|
count <= count + 1'd1;
|
|
rx_rdy <= 1'd1;
|
|
rx_data <= rx_reg;
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
endmodule |