module UART_PC(clk,rst_n,rx_in,led_data,bell);
input clk;
input rst_n;
input rx_in;
output[7:0] led_data;
output bell;
wire bps_sign;
wire bps_start;
reg[7:0] rx_data;
//波特率发生模块
bps_select bps_rx(
.clk(clk),
.rst_n(rst_n),
.bps_sign(bps_sign),
.bps_start(bps_start),
.bell(bell)
);
//串口接收模块
UART_rx my_uart_rx(
.clk(clk),
.rst_n(rst_n),
.bps_sign(bps_sign),
.bps_start(bps_start),
.RX_data(led_data),
.rx_in(rx_in)
);
endmodule
//=====================================================================================
//波特率发生模块
module bps_select(clk,rst_n,bps_sign,bps_start,bell);
input clk;
input rst_n;
input bps_start;
output bps_sign;
output reg bell;
reg bps_sign_r;
parameter T1=5207; //50MHZ
parameter T1_2=2603; //一个周期内的中点采样
initial begin
bell=1'b1;
end
reg[12:0] cnt;
always @(posedge clk or negedge rst_n)
if(!rst_n)
cnt=13'd0;
else if(cnt==T1)
cnt=13'd0;
else if(bps_start)
cnt=cnt+1'b1;
else cnt=13'd0;
assign bps_sign=(cnt==T1_2)?1'b1:1'b0;
endmodule
//================================================================================
//串口接收模块
module UART_rx(clk,rst_n,bps_sign,bps_start,RX_data,rx_in);
input clk;
input rst_n;
input bps_sign;
input rx_in;
output[7:0] RX_data;
output bps_start;
reg bps_start_r;
reg rx_in_r1,rx_in_r2,rx_in_r3;
wire neg_rx_in;
reg[7:0] rx_data;
//-------------------------------------------------
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
rx_in_r1<=1'b0;
rx_in_r2<=1'b0;
rx_in_r3<=1'b0;
end
else
begin
rx_in_r1<=rx_in;
rx_in_r2<=rx_in_r1;
rx_in_r3<=rx_in_r2;
end
assign neg_rx_in=rx_in_r3&~rx_in_r2;
//------------------------------------------------
always @(posedge clk or negedge rst_n)
if(!rst_n)
bps_start_r<=1'b0;
else if(neg_rx_in)
bps_start_r<=1'b1;
else if(num==4'd9)
bps_start_r<=1'b0;
assign bps_start=bps_start_r;
//-------------------------------------------------
reg bps_sign_r1,bps_sign_r2,bps_sign_r3;
wire pos_bps_sign;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
bps_sign_r1<=1'b0;
bps_sign_r2<=1'b0;
bps_sign_r3<=1'b0;
end
else
begin
bps_sign_r1<=bps_sign;
bps_sign_r2<=bps_sign_r1;
bps_sign_r3<=bps_sign_r2;
end
assign pos_bps_sign=~bps_sign_r3&bps_sign_r2;
reg[3:0] num;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
num<=4'd0;
rx_data<=8'b11001100;
end
else if(pos_bps_sign)
begin
case(num)
4'd0: num <= num+1'b1;
4'd1: begin
num <= num+1'b1;
rx_data[0] <= rx_in;
end
4'd2: begin
num <= num+1'b1;
rx_data[1] <= rx_in;
end
4'd3: begin
num <= num+1'b1;
rx_data[2] <= rx_in;
end
4'd4: begin
num <= num+1'b1;
rx_data[3] <= rx_in;
end
4'd5: begin
num <= num+1'b1;
rx_data[4] <= rx_in;
end
4'd6: begin
num <= num+1'b1;
rx_data[5] <= rx_in;
end
4'd7: begin
num <= num+1'b1;
rx_data[6] <= rx_in;
end
4'd8: begin
num <= num+1'b1;
rx_data[7] <= rx_in;
end
4'd9: num<=4'd0;
default: ;
endcase
end
assign RX_data=rx_data;
endmodule
|