| 
									
										
										
										
											2025-05-05 09:51:23 +02:00
										 |  |  | module other_uart_rx | 
					
						
							| 
									
										
										
										
											2025-05-05 09:26:41 +02:00
										 |  |  | #( | 
					
						
							|  |  |  | 	parameter CLK_FRE = 27,      //clock frequency(Mhz) | 
					
						
							|  |  |  | 	parameter BAUD_RATE = 115200 //serial baud rate | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | ( | 
					
						
							|  |  |  | 	input                        clk,              //clock input | 
					
						
							|  |  |  | 	input                        rst_n,            //asynchronous reset input, low active  | 
					
						
							|  |  |  | 	output reg[7:0]              rx_data,          //received serial data | 
					
						
							|  |  |  | 	output reg                   rx_data_valid,    //received serial data is valid | 
					
						
							|  |  |  | 	input                        rx_data_ready,    //data receiver module ready | 
					
						
							|  |  |  | 	input                        rx_pin            //serial data input | 
					
						
							|  |  |  | ); | 
					
						
							|  |  |  | //calculates the clock cycle for baud rate  | 
					
						
							|  |  |  | localparam                       CYCLE = CLK_FRE * 1000000 / BAUD_RATE; | 
					
						
							|  |  |  | //state machine code | 
					
						
							|  |  |  | localparam                       S_IDLE      = 1; | 
					
						
							|  |  |  | localparam                       S_START     = 2; //start bit | 
					
						
							|  |  |  | localparam                       S_REC_BYTE  = 3; //data bits | 
					
						
							|  |  |  | localparam                       S_STOP      = 4; //stop bit | 
					
						
							|  |  |  | localparam                       S_DATA      = 5; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | reg[2:0]                         state; | 
					
						
							|  |  |  | reg[2:0]                         next_state; | 
					
						
							|  |  |  | reg                              rx_d0;            //delay 1 clock for rx_pin | 
					
						
							|  |  |  | reg                              rx_d1;            //delay 1 clock for rx_d0 | 
					
						
							|  |  |  | wire                             rx_negedge;       //negedge of rx_pin | 
					
						
							|  |  |  | reg[7:0]                         rx_bits;          //temporary storage of received data | 
					
						
							|  |  |  | reg[15:0]                        cycle_cnt;        //baud counter | 
					
						
							|  |  |  | reg[2:0]                         bit_cnt;          //bit counter | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | assign rx_negedge = rx_d1 && ~rx_d0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | always@(posedge clk or negedge rst_n) | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | 	if(rst_n == 1'b0) | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		rx_d0 <= 1'b0; | 
					
						
							|  |  |  | 		rx_d1 <= 1'b0;	 | 
					
						
							|  |  |  | 	end | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 	begin | 
					
						
							|  |  |  | 		rx_d0 <= rx_pin; | 
					
						
							|  |  |  | 		rx_d1 <= rx_d0; | 
					
						
							|  |  |  | 	end | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | always@(posedge clk or negedge rst_n) | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | 	if(rst_n == 1'b0) | 
					
						
							|  |  |  | 		state <= S_IDLE; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		state <= next_state; | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | always@(*)
 | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | 	case(state) | 
					
						
							|  |  |  | 		S_IDLE: | 
					
						
							|  |  |  | 			if(rx_negedge) | 
					
						
							|  |  |  | 				next_state <= S_START; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				next_state <= S_IDLE; | 
					
						
							|  |  |  | 		S_START: | 
					
						
							|  |  |  | 			if(cycle_cnt == CYCLE - 1)//one data cycle  | 
					
						
							|  |  |  | 				next_state <= S_REC_BYTE; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				next_state <= S_START; | 
					
						
							|  |  |  | 		S_REC_BYTE: | 
					
						
							|  |  |  | 			if(cycle_cnt == CYCLE - 1  && bit_cnt == 3'd7)  //receive 8bit data | 
					
						
							|  |  |  | 				next_state <= S_STOP; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				next_state <= S_REC_BYTE; | 
					
						
							|  |  |  | 		S_STOP: | 
					
						
							|  |  |  | 			if(cycle_cnt == CYCLE/2 - 1)//half bit cycle,to avoid missing the next byte receiver | 
					
						
							|  |  |  | 				next_state <= S_DATA; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				next_state <= S_STOP; | 
					
						
							|  |  |  | 		S_DATA: | 
					
						
							|  |  |  | 			if(rx_data_ready)    //data receive complete | 
					
						
							|  |  |  | 				next_state <= S_IDLE; | 
					
						
							|  |  |  | 			else | 
					
						
							|  |  |  | 				next_state <= S_DATA; | 
					
						
							|  |  |  | 		default: | 
					
						
							|  |  |  | 			next_state <= S_IDLE; | 
					
						
							|  |  |  | 	endcase | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | always@(posedge clk or negedge rst_n) | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | 	if(rst_n == 1'b0) | 
					
						
							|  |  |  | 		rx_data_valid <= 1'b0; | 
					
						
							|  |  |  | 	else if(state == S_STOP && next_state != state) | 
					
						
							|  |  |  | 		rx_data_valid <= 1'b1; | 
					
						
							|  |  |  | 	else if(state == S_DATA && rx_data_ready) | 
					
						
							|  |  |  | 		rx_data_valid <= 1'b0; | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | always@(posedge clk or negedge rst_n) | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | 	if(rst_n == 1'b0) | 
					
						
							|  |  |  | 		rx_data <= 8'd0; | 
					
						
							|  |  |  | 	else if(state == S_STOP && next_state != state) | 
					
						
							|  |  |  | 		rx_data <= rx_bits;//latch received data | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | always@(posedge clk or negedge rst_n) | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | 	if(rst_n == 1'b0) | 
					
						
							|  |  |  | 		begin | 
					
						
							|  |  |  | 			bit_cnt <= 3'd0; | 
					
						
							|  |  |  | 		end | 
					
						
							|  |  |  | 	else if(state == S_REC_BYTE) | 
					
						
							|  |  |  | 		if(cycle_cnt == CYCLE - 1) | 
					
						
							|  |  |  | 			bit_cnt <= bit_cnt + 3'd1; | 
					
						
							|  |  |  | 		else | 
					
						
							|  |  |  | 			bit_cnt <= bit_cnt; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		bit_cnt <= 3'd0; | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | always@(posedge clk or negedge rst_n) | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | 	if(rst_n == 1'b0) | 
					
						
							|  |  |  | 		cycle_cnt <= 16'd0; | 
					
						
							|  |  |  | 	else if((state == S_REC_BYTE && cycle_cnt == CYCLE - 1) || next_state != state) | 
					
						
							|  |  |  | 		cycle_cnt <= 16'd0; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		cycle_cnt <= cycle_cnt + 16'd1;	 | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | //receive serial data bit data | 
					
						
							|  |  |  | always@(posedge clk or negedge rst_n) | 
					
						
							|  |  |  | begin | 
					
						
							|  |  |  | 	if(rst_n == 1'b0) | 
					
						
							|  |  |  | 		rx_bits <= 8'd0; | 
					
						
							|  |  |  | 	else if(state == S_REC_BYTE && cycle_cnt == CYCLE/2 - 1) | 
					
						
							|  |  |  | 		rx_bits[bit_cnt] <= rx_pin; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		rx_bits <= rx_bits;  | 
					
						
							|  |  |  | end | 
					
						
							|  |  |  | endmodule  |