//----------------------------------------------------- // Design Name : uart // File Name : uart.v // Function : Simple UART // Coder : Deepak Kumar Tala //----------------------------------------------------- module uart ( reset , txclk , ld_tx_data , tx_data , tx_enable , tx_out , tx_empty , rxclk , uld_rx_data , rx_data , rx_enable , rx_in , rx_empty ); // Port declarations input reset ; input txclk ; input ld_tx_data ; input [7:0] tx_data ; input tx_enable ; output tx_out ; output tx_empty ; input rxclk ; input uld_rx_data ; output [7:0] rx_data ; input rx_enable ; input rx_in ; output rx_empty ; // Internal Variables reg [7:0] tx_reg ; reg tx_empty ; reg tx_over_run ; reg [3:0] tx_cnt ; reg tx_out ; reg [7:0] rx_reg ; reg [7:0] rx_data ; reg [3:0] rx_sample_cnt ; reg [3:0] rx_cnt ; reg rx_frame_err ; reg rx_over_run ; reg rx_empty ; reg rx_d1 ; reg rx_d2 ; reg rx_busy ; // UART RX Logic always @ (posedge rxclk or posedge reset) if (reset) begin rx_reg <= 0; rx_data <= 0; rx_sample_cnt <= 0; rx_cnt <= 0; rx_frame_err <= 0; rx_over_run <= 0; rx_empty <= 1; rx_d1 <= 1; rx_d2 <= 1; rx_busy <= 0; end else begin // Synchronize the asynch signal rx_d1 <= rx_in; rx_d2 <= rx_d1; // Uload the rx data if (uld_rx_data) begin rx_data <= rx_reg; rx_empty <= 1; end // Receive data only when rx is enabled if (rx_enable) begin // Check if just received start of frame if (!rx_busy && !rx_d2) begin rx_busy <= 1; rx_sample_cnt <= 1; rx_cnt <= 0; end // Start of frame detected, Proceed with rest of data if (rx_busy) begin rx_sample_cnt <= rx_sample_cnt + 1; // Logic to sample at middle of data if (rx_sample_cnt == 7) begin if ((rx_d2 == 1) && (rx_cnt == 0)) begin rx_busy <= 0; end else begin rx_cnt <= rx_cnt + 1; // Start storing the rx data if (rx_cnt > 0 && rx_cnt < 9) begin rx_reg[rx_cnt - 1] <= rx_d2; end if (rx_cnt == 9) begin rx_busy <= 0; // Check if End of frame received correctly if (rx_d2 == 0) begin rx_frame_err <= 1; end else begin rx_empty <= 0; rx_frame_err <= 0; // Check if last rx data was not unloaded, rx_over_run <= (rx_empty) ? 0 : 1; end end end end end end if (!rx_enable) begin rx_busy <= 0; end end // UART TX Logic always @ (posedge txclk or posedge reset) if (reset) begin tx_reg <= 0; tx_empty <= 1; tx_over_run <= 0; tx_out <= 1; tx_cnt <= 0; end else begin if (ld_tx_data) begin if (!tx_empty) begin tx_over_run <= 0; end else begin tx_reg <= tx_data; tx_empty <= 0; end end if (tx_enable && !tx_empty) begin tx_cnt <= tx_cnt + 1; if (tx_cnt == 0) begin tx_out <= 0; end if (tx_cnt > 0 && tx_cnt < 9) begin tx_out <= tx_reg[tx_cnt -1]; end if (tx_cnt == 9) begin tx_out <= 1; tx_cnt <= 0; tx_empty <= 1; end end if (!tx_enable) begin tx_cnt <= 0; end end endmodule 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78