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