hw/ip/uart/rtl/uart_tx.sv Cov: 100%

   1: // Copyright lowRISC contributors.
   2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
   3: // SPDX-License-Identifier: Apache-2.0
   4: //
   5: // Description: UART Transmit Module
   6: //
   7: 
   8: module uart_tx (
   9:   input               clk_i,
  10:   input               rst_ni,
  11: 
  12:   input               tx_enable,
  13:   input               tick_baud_x16,
  14:   input  logic        parity_enable,
  15: 
  16:   input               wr,
  17:   input  logic        wr_parity,
  18:   input   [7:0]       wr_data,
  19:   output              idle,
  20: 
  21:   output logic        tx
  22: );
  23: 
  24: 
  25:   logic    [3:0] baud_div_q;
  26:   logic          tick_baud_q;
  27: 
  28:   logic    [3:0] bit_cnt_q, bit_cnt_d;
  29:   logic   [10:0] sreg_q, sreg_d;
  30:   logic          tx_q, tx_d;
  31: 
  32:   assign tx = tx_q;
  33: 
  34:   always_ff @(posedge clk_i or negedge rst_ni) begin
  35:     if (!rst_ni) begin
  36:       baud_div_q  <= 4'h0;
  37:       tick_baud_q <= 1'b0;
  38:     end else if (tick_baud_x16) begin
  39:       {tick_baud_q, baud_div_q} <= {1'b0,baud_div_q} + 5'h1;
  40:     end else begin
  41:       tick_baud_q <= 1'b0;
  42:     end
  43:   end
  44: 
  45:   always_ff @(posedge clk_i or negedge rst_ni) begin
  46:     if (!rst_ni) begin
  47:       bit_cnt_q <= 4'h0;
  48:       sreg_q    <= 11'h7ff;
  49:       tx_q      <= 1'b1;
  50:     end else begin
  51:       bit_cnt_q <= bit_cnt_d;
  52:       sreg_q    <= sreg_d;
  53:       tx_q      <= tx_d;
  54:     end
  55:   end
  56: 
  57:   always_comb begin
  58:     if (!tx_enable) begin
  59:       bit_cnt_d = 4'h0;
  60:       sreg_d    = 11'h7ff;
  61:       tx_d      = 1'b1;
  62:     end else begin
  63:       bit_cnt_d = bit_cnt_q;
  64:       sreg_d    = sreg_q;
  65:       tx_d      = tx_q;
  66:       if (wr) begin
  67:         sreg_d    = {1'b1, (parity_enable ? wr_parity : 1'b1), wr_data, 1'b0};
  68:         bit_cnt_d = (parity_enable ? 4'd11 : 4'd10);
  69:       end else if (tick_baud_q && (bit_cnt_q != 4'h0)) begin
  70:         sreg_d    = {1'b1, sreg_q[10:1]};
  71:         tx_d      = sreg_q[0];
  72:         bit_cnt_d = bit_cnt_q - 4'h1;
  73:       end
  74:     end
  75:   end
  76: 
  77:   assign idle = (tx_enable) ? (bit_cnt_q == 4'h0) : 1'b1;
  78: 
  79: endmodule
  80: