| // SPDX-License-Identifier: Apache-2.0 |
| |
| module uart_tx |
| #(parameter CLKS_PER_BIT) |
| ( |
| input i_Clock, |
| input i_Tx_DV, |
| input [7:0] i_Tx_Byte, |
| output o_Tx_Active, |
| output reg o_Tx_Serial, |
| output o_Tx_Done |
| ); |
| |
| parameter s_IDLE = 3'b000; |
| parameter s_TX_START_BIT = 3'b001; |
| parameter s_TX_DATA_BITS = 3'b010; |
| parameter s_TX_STOP_BIT = 3'b011; |
| parameter s_CLEANUP = 3'b100; |
| |
| reg [2:0] r_SM_Main = 0; |
| reg [7:0] r_Clock_Count = 0; |
| reg [2:0] r_Bit_Index = 0; |
| reg [7:0] r_Tx_Data = 0; |
| reg r_Tx_Done = 0; |
| reg r_Tx_Active = 0; |
| |
| always @(posedge i_Clock) |
| begin |
| |
| case (r_SM_Main) |
| s_IDLE : |
| begin |
| o_Tx_Serial <= 1'b1; // Drive Line High for Idle |
| r_Tx_Done <= 1'b0; |
| r_Clock_Count <= 0; |
| r_Bit_Index <= 0; |
| |
| if (i_Tx_DV == 1'b1) |
| begin |
| r_Tx_Active <= 1'b1; |
| r_Tx_Data <= i_Tx_Byte; |
| r_SM_Main <= s_TX_START_BIT; |
| end |
| else |
| r_SM_Main <= s_IDLE; |
| end // case: s_IDLE |
| |
| |
| // Send out Start Bit. Start bit = 0 |
| s_TX_START_BIT : |
| begin |
| o_Tx_Serial <= 1'b0; |
| |
| // Wait CLKS_PER_BIT-1 clock cycles for start bit to finish |
| if (r_Clock_Count < CLKS_PER_BIT-1) |
| begin |
| r_Clock_Count <= r_Clock_Count + 1; |
| r_SM_Main <= s_TX_START_BIT; |
| end |
| else |
| begin |
| r_Clock_Count <= 0; |
| r_SM_Main <= s_TX_DATA_BITS; |
| end |
| end // case: s_TX_START_BIT |
| |
| |
| // Wait CLKS_PER_BIT-1 clock cycles for data bits to finish |
| s_TX_DATA_BITS : |
| begin |
| o_Tx_Serial <= r_Tx_Data[r_Bit_Index]; |
| |
| if (r_Clock_Count < CLKS_PER_BIT-1) |
| begin |
| r_Clock_Count <= r_Clock_Count + 1; |
| r_SM_Main <= s_TX_DATA_BITS; |
| end |
| else |
| begin |
| r_Clock_Count <= 0; |
| |
| // Check if we have sent out all bits |
| if (r_Bit_Index < 7) |
| begin |
| r_Bit_Index <= r_Bit_Index + 1; |
| r_SM_Main <= s_TX_DATA_BITS; |
| end |
| else |
| begin |
| r_Bit_Index <= 0; |
| r_SM_Main <= s_TX_STOP_BIT; |
| end |
| end |
| end // case: s_TX_DATA_BITS |
| |
| |
| // Send out Stop bit. Stop bit = 1 |
| s_TX_STOP_BIT : |
| begin |
| o_Tx_Serial <= 1'b1; |
| |
| // Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish |
| if (r_Clock_Count < CLKS_PER_BIT-1) |
| begin |
| r_Clock_Count <= r_Clock_Count + 1; |
| r_SM_Main <= s_TX_STOP_BIT; |
| end |
| else |
| begin |
| r_Tx_Done <= 1'b1; |
| r_Clock_Count <= 0; |
| r_SM_Main <= s_CLEANUP; |
| r_Tx_Active <= 1'b0; |
| end |
| end // case: s_Tx_STOP_BIT |
| |
| |
| // Stay here 1 clock |
| s_CLEANUP : |
| begin |
| r_Tx_Done <= 1'b1; |
| r_SM_Main <= s_IDLE; |
| end |
| |
| |
| default : |
| r_SM_Main <= s_IDLE; |
| |
| endcase |
| end |
| |
| assign o_Tx_Active = r_Tx_Active; |
| assign o_Tx_Done = r_Tx_Done; |
| |
| endmodule |