forked from tanchou/Verilog
75 lines
1.9 KiB
Verilog
75 lines
1.9 KiB
Verilog
module uart_tx(
|
|
input wire clk,
|
|
input wire start,
|
|
input wire [7:0] data,
|
|
|
|
output reg tx = 1,
|
|
output reg busy = 0
|
|
);
|
|
|
|
parameter CLK_FREQ = 27_000_000;
|
|
parameter BAUD_RATE = 115_200;
|
|
localparam BIT_PERIOD = CLK_FREQ / BAUD_RATE;
|
|
|
|
localparam IDLE = 2'b00;
|
|
localparam START = 2'b01;
|
|
localparam DATA = 2'b10;
|
|
localparam STOP = 2'b11;
|
|
|
|
reg [1:0] state = IDLE;
|
|
reg [3:0] bit_index = 0;
|
|
reg [15:0] clk_count = 0;
|
|
reg [7:0] tx_data = 0;
|
|
|
|
always @(posedge clk) begin
|
|
case(state)
|
|
IDLE: begin
|
|
tx <= 1;
|
|
|
|
if (start) begin
|
|
tx_data <= data;
|
|
bit_index <= 0;
|
|
clk_count <= 0;
|
|
busy <= 1;
|
|
state <= START;
|
|
end
|
|
end
|
|
|
|
START: begin
|
|
if (clk_count < BIT_PERIOD - 1) begin
|
|
clk_count <= clk_count + 1;
|
|
tx <= 0;
|
|
end else begin
|
|
state <= DATA;
|
|
clk_count <= 0;
|
|
end
|
|
end
|
|
|
|
DATA: begin
|
|
if (clk_count < BIT_PERIOD - 1) begin
|
|
clk_count <= clk_count + 1;
|
|
|
|
end else if (bit_index < 8) begin
|
|
tx <= tx_data[bit_index];
|
|
bit_index <= bit_index + 1;
|
|
clk_count <= 0;
|
|
|
|
end else begin
|
|
state <= STOP;
|
|
end
|
|
end
|
|
|
|
STOP: begin
|
|
tx <= 1;
|
|
if (clk_count < BIT_PERIOD - 1) begin
|
|
clk_count <= clk_count + 1;
|
|
end else begin
|
|
clk_count <= 0;
|
|
busy <= 0;
|
|
state <= IDLE;
|
|
end
|
|
end
|
|
endcase
|
|
end
|
|
endmodule
|