You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
108 lines
2.8 KiB
Verilog
108 lines
2.8 KiB
Verilog
`include "param.v"
|
|
module uart_rx(
|
|
input wire sys_clk ,
|
|
input wire sys_rst_n ,
|
|
input wire rx_din ,//数据串行输入
|
|
input wire rcv_start ,
|
|
|
|
output wire [7: 0] rx_dout ,//数据并行输出
|
|
output wire rx_vld //输出信号有效
|
|
);
|
|
parameter BAUD = `SYS_FRQ / `MAX;//获取1bit时钟振动的次数
|
|
reg din_reg0;//同步外来信号,和本时钟域同步
|
|
reg din_reg1;//打拍,获取下降沿
|
|
wire nedge;//下降沿标志
|
|
|
|
reg rx_flag;//开始接受标志
|
|
|
|
//对bit进行计数寄存器
|
|
reg [3: 0] cnt_bit ;
|
|
wire add_cnt_bit;
|
|
wire end_cnt_bit;
|
|
//对波特率进行计数寄存器
|
|
reg [12: 0] cnt_bps ;
|
|
wire add_cnt_bps ;
|
|
wire end_cnt_bps ;
|
|
|
|
//数据寄存器
|
|
reg [7: 0] data_reg;
|
|
always @(posedge sys_clk or negedge sys_rst_n) begin
|
|
if(!sys_rst_n)begin
|
|
din_reg0 <= 1'b1;
|
|
din_reg1 <= 1'b1;
|
|
end
|
|
else begin
|
|
din_reg0 <= rx_din;
|
|
din_reg1 <= din_reg0;
|
|
end
|
|
end
|
|
assign nedge = ~din_reg0 && din_reg1;//下降沿
|
|
|
|
//rx_flag信号约束
|
|
always @(posedge sys_clk or negedge sys_rst_n)begin
|
|
if(!sys_rst_n)begin
|
|
rx_flag <= 1'b0;
|
|
end
|
|
else if(nedge && rcv_start)begin//检测到下降沿
|
|
rx_flag <= 1'b1;
|
|
end
|
|
else if(end_cnt_bit)begin//传输完成标志
|
|
rx_flag <= 1'b0;
|
|
end
|
|
else begin
|
|
rx_flag <= rx_flag;//其他时刻保持
|
|
end
|
|
end
|
|
//cnt_bps计数器设计
|
|
always @(posedge sys_clk or negedge sys_rst_n)begin
|
|
if(!sys_rst_n)begin
|
|
cnt_bps <= 13'd0;
|
|
end
|
|
else if(add_cnt_bps)begin
|
|
if(end_cnt_bps)begin
|
|
cnt_bps <= 13'd0;
|
|
end
|
|
else begin
|
|
cnt_bps <= cnt_bps + 1'd1;
|
|
end
|
|
end
|
|
else begin
|
|
cnt_bps <= cnt_bps;
|
|
end
|
|
end
|
|
assign add_cnt_bps = rx_flag;
|
|
assign end_cnt_bps = add_cnt_bps && cnt_bps == BAUD - 1'd1;
|
|
//cnt_bit计数器设计
|
|
always @(posedge sys_clk or negedge sys_rst_n)begin
|
|
if(!sys_rst_n)begin
|
|
cnt_bit <= 4'd0;
|
|
end
|
|
else if(add_cnt_bit)begin
|
|
if(end_cnt_bit)begin
|
|
cnt_bit <= 4'd0;
|
|
end
|
|
else begin
|
|
cnt_bit <= cnt_bit + 1'd1;
|
|
end
|
|
end
|
|
else begin
|
|
cnt_bit <= cnt_bit;
|
|
end
|
|
end
|
|
assign add_cnt_bit = end_cnt_bps;//比特计数开始条件
|
|
assign end_cnt_bit = add_cnt_bit && cnt_bit == 4'd8;//0-8
|
|
//对data_reg进行约束
|
|
always @(posedge sys_clk or negedge sys_rst_n)begin
|
|
if(!sys_rst_n)begin
|
|
data_reg <= 8'hx;
|
|
end
|
|
else if((cnt_bit >= 4'd1 && cnt_bit <= 4'd8) && (cnt_bps == BAUD >> 1))begin
|
|
data_reg[cnt_bit - 1'd1] = din_reg0;//对输入数据进行采样
|
|
end
|
|
else begin
|
|
data_reg <= data_reg;
|
|
end
|
|
end
|
|
assign rx_dout = data_reg;//数据输出
|
|
assign rx_vld = end_cnt_bit;//串转并结束标志
|
|
endmodule
|