thermometer_digital/rtl/uart/uart_byte_rx.v

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