112 lines
2.6 KiB
Verilog
112 lines
2.6 KiB
Verilog
module uart_byte_rx #(
|
|
parameter CLOCK_FREQ = 50_000_000,
|
|
parameter BAUD = 9600
|
|
)
|
|
(
|
|
Clk,
|
|
Reset_n,
|
|
uart_rx,
|
|
Rx_Done,
|
|
Rx_Data
|
|
);
|
|
|
|
input Clk;
|
|
input Reset_n;
|
|
input uart_rx;
|
|
output reg Rx_Done;
|
|
output reg[7:0]Rx_Data;
|
|
|
|
|
|
parameter MCNT_BAUD = CLOCK_FREQ / BAUD - 1;
|
|
|
|
reg [7:0]r_Rx_Data;
|
|
|
|
reg [29:0]baud_div_cnt;
|
|
reg en_baud_cnt;
|
|
reg [3:0]bit_cnt;
|
|
|
|
wire w_Rx_Done;
|
|
wire nedge_uart_rx;
|
|
|
|
reg r_uart_rx;
|
|
|
|
reg dff0_uart_rx,dff1_uart_rx;
|
|
//波特率计数器逻辑
|
|
always@(posedge Clk or negedge Reset_n)
|
|
if(!Reset_n)
|
|
baud_div_cnt <= 0;
|
|
else if(en_baud_cnt)begin
|
|
if(baud_div_cnt == MCNT_BAUD)
|
|
baud_div_cnt <= 0;
|
|
else
|
|
baud_div_cnt <= baud_div_cnt + 1'd1;
|
|
end
|
|
else
|
|
baud_div_cnt <= 0;
|
|
|
|
|
|
//UART 信号边沿检测逻辑
|
|
always@(posedge Clk)
|
|
dff0_uart_rx <= uart_rx;
|
|
|
|
always@(posedge Clk)
|
|
dff1_uart_rx <= dff0_uart_rx;
|
|
|
|
always@(posedge Clk)
|
|
r_uart_rx <= dff1_uart_rx;
|
|
|
|
assign nedge_uart_rx = (dff1_uart_rx == 0) && (r_uart_rx == 1);
|
|
|
|
//波特率计数器使能逻辑
|
|
always@(posedge Clk or negedge Reset_n)
|
|
if(!Reset_n)
|
|
en_baud_cnt <= 0;
|
|
else if(nedge_uart_rx)
|
|
en_baud_cnt <= 1;
|
|
else if((baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 0) && (dff1_uart_rx == 1))
|
|
en_baud_cnt <= 0;
|
|
else if((baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 9))
|
|
en_baud_cnt <= 0;
|
|
|
|
|
|
//位计数器逻辑
|
|
always@(posedge Clk or negedge Reset_n)
|
|
if(!Reset_n)
|
|
bit_cnt <= 0;
|
|
else if((bit_cnt == 9) && (baud_div_cnt == MCNT_BAUD/2))
|
|
bit_cnt <= 0;
|
|
else if(baud_div_cnt == MCNT_BAUD)
|
|
bit_cnt <= bit_cnt + 1'd1;
|
|
|
|
//位接收逻辑
|
|
|
|
always@(posedge Clk or negedge Reset_n)
|
|
if(!Reset_n)
|
|
r_Rx_Data <= 8'd0;
|
|
else if(baud_div_cnt == MCNT_BAUD/2)begin
|
|
case(bit_cnt)
|
|
1:r_Rx_Data[0] <= dff1_uart_rx;
|
|
2:r_Rx_Data[1] <= dff1_uart_rx;
|
|
3:r_Rx_Data[2] <= dff1_uart_rx;
|
|
4:r_Rx_Data[3] <= dff1_uart_rx;
|
|
5:r_Rx_Data[4] <= dff1_uart_rx;
|
|
6:r_Rx_Data[5] <= dff1_uart_rx;
|
|
7:r_Rx_Data[6] <= dff1_uart_rx;
|
|
8:r_Rx_Data[7] <= dff1_uart_rx;
|
|
default: r_Rx_Data <= r_Rx_Data;
|
|
endcase
|
|
end
|
|
|
|
//接收完成标志信号
|
|
assign w_Rx_Done = (baud_div_cnt == MCNT_BAUD/2) && (bit_cnt == 9);
|
|
|
|
always@(posedge Clk)
|
|
Rx_Done <= w_Rx_Done;
|
|
|
|
always@(posedge Clk)
|
|
if(w_Rx_Done)
|
|
Rx_Data <= r_Rx_Data;
|
|
|
|
|
|
endmodule
|