// SPDX-License-Identifier: AGPL-3.0-Only /* * Copyright (C) 2022 Sean Anderson * * 8n1@115200; no one uses anything else (and neither do I) */ `include "common.vh" module uart_tx ( input clk, rst, input [7:0] data, output reg ready, input valid, output reg tx, /* Run at 4M for testing */ input high_speed ); /* 1085 cycles, for 115200 baud with a 125 MHz clock */ parameter SLOW_VALUE = 11'h78c; /* 31 cycles, for 4M baud with a 125 MHz clock */ parameter FAST_VALUE = 11'h68e; reg [7:0] data_last; reg valid_last, ready_next; reg [10:0] lfsr, lfsr_next; reg [3:0] counter, counter_next; reg [8:0] bits, bits_next; always @(*) begin tx = bits[0]; ready_next = ready; counter_next = counter; lfsr_next = { lfsr[9:0], lfsr[10] ^ lfsr[8] }; bits_next = bits; if (&lfsr) begin if (counter) counter_next = counter - 1; else ready_next = 1; lfsr_next = high_speed ? FAST_VALUE : SLOW_VALUE; bits_next = { 1'b1, bits[8:1] }; end if (valid_last && ready) begin ready_next = 0; counter_next = 9; lfsr_next = high_speed ? FAST_VALUE : SLOW_VALUE; bits_next = { data_last, 1'b0 }; end end always @(posedge clk) begin data_last <= data; counter <= counter_next; lfsr <= lfsr_next; end always @(posedge clk, posedge rst) begin if (rst) begin ready <= 1'b1; valid_last <= 1'b0; bits <= 9'h1ff; end else begin ready <= ready_next; valid_last <= valid; bits <= bits_next; end end endmodule