接收模块

变量

完整流程:

举例子:

理解:

Image

//uart_rx.v
`timescale 1ns / 1ps

module uart_rx #(
	parameter 		   CLK_FREQ  = 50000000,
	parameter 		   BAUD_RATE = 115200
)(
	input	           clk,
	input              reset,
	input              uart_rxd,      //串口接收RX

	output reg         uart_rx_en,    //接收数据使能
	output reg [7:0]   uart_rx_data	  //接受的数据	

    );
localparam BAUD_CNT_MAX        = CLK_FREQ  / BAUD_RATE;  //复位之前已经计算好了
localparam BAUD_CNT_MAX_HALF   = BAUD_CNT_MAX / 2;      //复位之前已经计算好了

reg  		uart_rxd_d0;
reg  		uart_rxd_d1;

reg [12:0] 	baud_cnt;
reg [3:0]  	bit_cnt;

reg         rx_flag;
reg         bit_flag;

//FPGA外部信号传入,打两拍,防止亚稳态
always @(posedge clk) begin
	uart_rxd_d0 <= uart_rxd;
    uart_rxd_d1 <= uart_rxd_d0;
end

always @(posedge clk ) begin
	if (~uart_rxd_d0 && uart_rxd_d1) 
		rx_flag <= 1'b1;
	else if (rx_flag && baud_cnt == BAUD_CNT_MAX && bit_cnt == 'd9) 
		rx_flag <= 1'b0;
end

always @(posedge clk) begin
	if (reset) 
		baud_cnt <= 13'd0;
	else if (~rx_flag) 
		baud_cnt <= 13'd0;
	else if (rx_flag && baud_cnt == BAUD_CNT_MAX)
		baud_cnt <= 13'd0;
	else if (rx_flag) 
		baud_cnt <= baud_cnt + 1'b1;
	else 
		baud_cnt <= baud_cnt;
end

always @(posedge clk ) begin
	if (reset) 
		bit_cnt <= 'd0;
	else if (~rx_flag)
		bit_cnt <= 'd0;
	else if (rx_flag && baud_cnt == BAUD_CNT_MAX)	
		bit_cnt <= bit_cnt + 1'b1;
	else 
		bit_cnt <= bit_cnt;	
end

always @(posedge clk ) begin
	if (bit_cnt >= 1 && bit_cnt <= 8 && baud_cnt == BAUD_CNT_MAX_HALF) 
		bit_flag <= 1'b1;
	else 
		bit_flag <= 1'b0;	
end

always @(posedge clk ) begin
	if (reset) 
		uart_rx_en <= 1'b0;
	else if (rx_flag && baud_cnt == BAUD_CNT_MAX && bit_cnt == 'd9) 
		uart_rx_en <= 1'b1;
	else 
		uart_rx_en <= 1'b0;	
end

//写法1
always @(posedge clk ) begin
	if (bit_flag) 
		uart_rx_data[bit_cnt - 1] <= uart_rxd_d1;
	else 
		uart_rx_data <= uart_rx_data;
end

//写法2,移位写法
/*always @(posedge clk ) begin
	if (bit_flag)
		uart_rx_data <= {uart_rxd_d1,uart_rx_data[7:1]};
	else 
		uart_rx_data <= uart_rx_data;
end*/
endmodule