| //----------------------------------------------------- |
| // 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 |