blob: d10d16a6f9abc6cc939c2105a0d0504b9088a2a4 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Description: UART Transmit Module
//
module uart_tx (
input clk_i,
input rst_ni,
input tx_enable,
input tick_baud_x16,
input logic parity_enable,
input wr,
input logic wr_parity,
input [7:0] wr_data,
output idle,
output logic tx
);
logic [3:0] baud_div_q;
logic tick_baud_q;
logic [3:0] bit_cnt_q, bit_cnt_d;
logic [10:0] sreg_q, sreg_d;
logic tx_q, tx_d;
assign tx = tx_q;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
baud_div_q <= 4'h0;
tick_baud_q <= 1'b0;
end else if (tick_baud_x16) begin
{tick_baud_q, baud_div_q} <= {1'b0,baud_div_q} + 5'h1;
end else begin
tick_baud_q <= 1'b0;
end
end
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
bit_cnt_q <= 4'h0;
sreg_q <= 11'h7ff;
tx_q <= 1'b1;
end else begin
bit_cnt_q <= bit_cnt_d;
sreg_q <= sreg_d;
tx_q <= tx_d;
end
end
always_comb begin
if (!tx_enable) begin
bit_cnt_d = 4'h0;
sreg_d = 11'h7ff;
tx_d = 1'b1;
end else begin
bit_cnt_d = bit_cnt_q;
sreg_d = sreg_q;
tx_d = tx_q;
if (wr) begin
sreg_d = {1'b1, (parity_enable ? wr_parity : 1'b1), wr_data, 1'b0};
bit_cnt_d = (parity_enable ? 4'd11 : 4'd10);
end else if (tick_baud_q && (bit_cnt_q != 4'h0)) begin
sreg_d = {1'b1, sreg_q[10:1]};
tx_d = sreg_q[0];
bit_cnt_d = bit_cnt_q - 4'h1;
end
end
end
assign idle = (tx_enable) ? (bit_cnt_q == 4'h0) : 1'b1;
endmodule