go-board-code/uart_tx.v

99 lines
2.3 KiB
Verilog

module UART_TX (
input i_Reset_Low,
input i_Clk,
input i_TransmitReady,
input [7:0] i_TransmitByte,
output reg o_Active,
output reg o_Output,
output reg o_Done
);
parameter CLOCKS_PER_SECOND = 25000000;
parameter BAUD_RATE = 115200;
localparam integer CLOCKS_PER_BIT = CLOCKS_PER_SECOND / BAUD_RATE;
localparam IDLE = 0;
localparam SEND_START_BIT = 1;
localparam SEND_DATA_BITS = 2;
localparam SEND_STOP_BIT = 3;
reg [$clog2(SEND_STOP_BIT)-1:0] r_currentState = IDLE;
reg [$clog2(CLOCKS_PER_BIT)-1:0] r_clockCount = 0;
reg [$clog2(8)-1:0] r_bitIndex = 0;
reg [7:0] r_transmitData;
always @(posedge i_Clk or negedge i_Reset_Low) begin
if (!i_Reset_Low) begin
r_currentState <= IDLE;
end else begin
o_Done <= 0;
case (r_currentState)
IDLE:
begin
// Drive line high for idle
o_Output <= 1;
r_clockCount <= 0;
r_bitIndex <= 0;
if (i_TransmitReady) begin
o_Active <= 1;
r_transmitData <= i_TransmitByte;
r_currentState <= SEND_START_BIT;
end
end
SEND_START_BIT:
begin
o_Output <= 0;
if (r_clockCount < CLOCKS_PER_BIT - 1) begin
r_clockCount <= r_clockCount + 1;
end else begin
r_clockCount <= 0;
r_currentState <= SEND_DATA_BITS;
end
end
SEND_DATA_BITS:
begin
o_Output <= r_transmitData[r_bitIndex];
if (r_clockCount < CLOCKS_PER_BIT - 1) begin
r_clockCount <= r_clockCount + 1;
end else begin
r_clockCount <= 0;
if (r_bitIndex == 7) begin
r_bitIndex <= 0;
r_currentState <= SEND_STOP_BIT;
end else begin
r_bitIndex <= r_bitIndex + 1;
end
end
end
SEND_STOP_BIT:
begin
o_Output <= 1;
if (r_clockCount < CLOCKS_PER_BIT - 1) begin
r_clockCount <= r_clockCount + 1;
end else begin
o_Done <= 1;
r_clockCount <= 0;
r_currentState <= IDLE;
o_Output <= 0;
end
end
default:
begin
r_currentState <= IDLE;
end
endcase
end
end
endmodule