module receive(
input sys_clk,
input rst_n,
input uart_rxd,
output uart_done,
output [7:0]uart_data
);
wire uart_en;
wire [7:0]uart_din;
parameter bps=115200;
parameter clk_freq=50000000;
localparam cnt=434;
parameter sum=4340;
reg start_flag;
reg rx_flag;
reg [15:0]clk_cnt;
reg [3:0] rx_cnt;//数据计数
reg [15:0]cnt_sum;//为rx_flag计数
reg data_done;
reg [7:0]data;
reg [7:0]dataout;
wire signal_down;
reg signal_delay_down;
//下降沿 start_flag
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
signal_delay_down <= 1'b1;
else
signal_delay_down <= uart_rxd;
end
assign signal_down = (signal_delay_down && ~uart_rxd);
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
start_flag<=1'b0;
else if(clk_cnt<200)
start_flag<=signal_down;
else start_flag<=1'b0;
end
//rx_flag
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
cnt_sum<=15'd0;
else if(start_flag)
cnt_sum<=15'd1;
else if(cnt_sum>15'd0 && cnt_sum<(sum-1))
cnt_sum<=cnt_sum+1'b1;
else cnt_sum<=15'd0;
end
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
rx_flag<=1'b0;
else if(cnt_sum>15'd0 && cnt_sum<(sum-1))
rx_flag<=1'b1;
else if(rx_cnt==4'd9 && clk_cnt==cnt-1)
rx_flag<=1'b0;
else
rx_flag<=rx_flag;
end
//clk_cnt
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
clk_cnt<=16'd0;
else if(rx_flag && clk_cnt<(cnt-1))
clk_cnt<=clk_cnt+1'b1;
else if(clk_cnt==cnt-1)
clk_cnt<=16'd0;
end
//rx_cnt
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
rx_cnt<=4'd0;
else if(rx_flag && clk_cnt==(cnt-1))
rx_cnt<=rx_cnt+1'b1;
else if(rx_cnt==4'd10)
rx_cnt<=4'd0;
end
//uart_done
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
data_done<=1'b0;
else if(rx_cnt==4'd9)
data_done<=1'b1;
else
data_done<=1'b0;
end
assign uart_done=data_done;
//输出数据
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
data<=8'd0;
else if(rx_flag)
if(clk_cnt==cnt/2) begin //判断系统时钟计数器计数到数据位中间
case (rx_cnt)
4'd1 :data[0] <=uart_rxd; //寄存数据位最低位
4'd2 :data[1] <=uart_rxd;
4'd3 :data[2] <=uart_rxd;
4'd4 :data[3] <=uart_rxd;
4'd5 :data[4] <=uart_rxd;
4'd6 :data[5] <=uart_rxd;
4'd7 :data[6] <=uart_rxd;
4'd8 :data[7] <=uart_rxd; //寄存数据位最高位
default:;
endcase
end
else
data<= data;
else
data<= 8'd0;
end
always@(posedge sys_clk or negedge rst_n)begin
if(!rst_n)
dataout<=8'd0;
else if(uart_done)
dataout<=data;
else dataout<=8'd0;
end
assign uart_data=dataout;
endmodule