always@(negedge rst_n,posedge clk)
begin
if(!rst_n)
begin
cnt_div<=8'd0;
clk16<=1'b0;
end
else
begin
if(cnt_div==clk_prescaler)
begin
clk16<=~clk16;
cnt_div<=8'd0;
end
else
begin
cnt_div<=cnt_div+1'd1;
end
end
end
always@(negedge rst_n,posedge clk16)
begin
if(!rst_n)
begin
rxd_start<=1'b0;
cnt_div16<=4'h0;
cnt_bit<=4'h0;
rxd_data_ready<=1'b0;
end
else
if(rxd_start==1'b0)
begin
if(rxd==1'b0)
begin
rxd_start<=1'b1;
cnt_div16<=4'h0;
cnt_bit<=4'h0;
rxd_data_ready<=1'b0;
end
else
begin
cnt_div16<=4'h0;
cnt_bit<=4'h0;
rxd_data_ready<=1'b0;
end
end
else
begin
if(cnt_bit<=4'd9)
begin
case(cnt_div16)
4'd0: cnt_div16<=cnt_div16+1'd1;
4'd1: cnt_div16<=cnt_div16+1'd1;
4'd2: cnt_div16<=cnt_div16+1'd1;
4'd3: cnt_div16<=cnt_div16+1'd1;
4'd4: cnt_div16<=cnt_div16+1'd1;
4'd5: cnt_div16<=cnt_div16+1'd1;
4'd6: begin
collect_bit[0]<=rxd;
cnt_div16<=cnt_div16+1'd1;
end
4'd7: begin
collect_bit[1]<=rxd;
cnt_div16<=cnt_div16+1'd1;
end
4'd8: begin
collect_bit[2]<=rxd;
cnt_div16<=cnt_div16+1'd1;
end
4'd9: begin
rxd_shift_reg[8:0]<=rxd_shift_reg[9:1];
rxd_shift_reg[9]<=(collect_bit[0] & collect_bit[1]) |
(collect_bit[0] & collect_bit[2]) |
(collect_bit[1] & collect_bit[2]);
cnt_bit<=cnt_bit+1'b1;
cnt_div16<=cnt_div16+1'd1;
end
4'd10: cnt_div16<=cnt_div16+1'd1;
4'd11: cnt_div16<=cnt_div16+1'd1;
4'd12: cnt_div16<=cnt_div16+1'd1;
4'd13: cnt_div16<=cnt_div16+1'd1;
4'd14: cnt_div16<=cnt_div16+1'd1;
default: cnt_div16<=4'd0;
endcase
if((cnt_bit==1'b1) && (rxd_shift_reg[9]==1'b1)) //假的起始位,丢弃
begin
rxd_start<=1'b0;
end
end
else
begin
rxd_start<=1'b0;
rxd_data_ready<=1'b1;
rxd_hold_reg<=rxd_shift_reg;
end
end
end
reg rxd_ready1,rxd_ready2,rxd_ready3;
wire rxd_ready4;
always@(negedge rst_n,posedge clk50M)
begin
if(!rst_n)
begin
rxd_ready1<=1'b0;
rxd_ready2<=1'b0;
rxd_ready3<=1'b0;
end
else
begin
rxd_ready1<=rxd_data_ready;
rxd_ready2<=rxd_ready1;
rxd_ready3<=rxd_ready2;
end
end
/*
rxd_data_ready信号相对于clk50M时钟来说,是慢速时钟域的信号,这里采用检测上升沿的方法
*/
assign rxd_ready4= rxd_ready2 & (!rxd_ready3);
always@(negedge rst_n,posedge clk50M)
begin
if(!rst_n)
begin
dig0<=4'h0;
dig1<=4'h0;
dig2<=4'h0;
dig3<=4'h0;
end
else
begin
if(rxd_ready4==1'b1)
begin
if(dig0==8'h9)
begin
if(dig1==8'h9)
begin
if(dig2==8'h9)
begin
dig3<=dig3+1'b1;
dig2<=4'h0;
end
else
dig2<=dig2+1'b1;
dig1<=4'h0;
end
else
dig1<=dig1+1'b1;
dig0<=4'h0;
end
else
dig0<=dig0+1'b1;
end
end
end