// Copyright (c) 2014 Sergiusz 'q3k' BazaƄski // Released under the 2-clause BSD license - see the COPYING file `timescale 1ns / 1ps /// This is not the prettiest UART you've seen... module uart_controller( // Data input input [7:0] tx_data_in, // Data input latch input tx_data_latch, // baud rate clock input clock, // reset line input reset, // goes 1 when the UART finished transmitting output reg tx_transmitted, // the actual UART transmitter output output reg tx_signal, output reg rx_present, input rx_present_clear, output reg [7:0] rx_data, input rx_signal ); // Internal TX data (latched from tx_data_in) reg [7:0] tx_data; reg [3:0] tx_state; reg [3:0] rx_state; `define IDLE 0 `define START 1 `define BIT0 2 `define BIT1 3 `define BIT2 4 `define BIT3 5 `define BIT4 6 `define BIT5 7 `define BIT6 8 `define BIT7 9 `define STOP 10 /// Receiver always @(posedge clock) begin if (reset) begin rx_state <= `IDLE; rx_present <= 0; rx_data <= 0; end else begin if (rx_present_clear) rx_present <= 0; case (rx_state) `IDLE: begin if (!rx_signal) begin // We received a start bit rx_state <= `BIT0; rx_present <= 0; end end `BIT0: begin rx_data[0] <= rx_signal; rx_state <= `BIT1; end `BIT1: begin rx_data[1] <= rx_signal; rx_state <= `BIT2; end `BIT2: begin rx_data[2] <= rx_signal; rx_state <= `BIT3; end `BIT3: begin rx_data[3] <= rx_signal; rx_state <= `BIT4; end `BIT4: begin rx_data[4] <= rx_signal; rx_state <= `BIT5; end `BIT5: begin rx_data[5] <= rx_signal; rx_state <= `BIT6; end `BIT6: begin rx_data[6] <= rx_signal; rx_state <= `BIT7; end `BIT7: begin rx_data[7] <= rx_signal; rx_state <= `STOP; end `STOP: begin rx_present <= 1; rx_state <= `IDLE; end endcase end end /// Transmitter always @(posedge clock) begin if (reset) begin tx_state <= `IDLE; tx_signal <= 1; tx_data <= 0; tx_transmitted <= 1; end else begin case (tx_state) `IDLE: begin if (tx_data_latch) begin tx_data <= tx_data_in; tx_state <= `START; tx_transmitted <= 0; end end `START: begin tx_signal <= 0; tx_state <= `BIT0; end `BIT0: begin tx_signal <= tx_data[0]; tx_state <= `BIT1; end `BIT1: begin tx_signal <= tx_data[1]; tx_state <= `BIT2; end `BIT2: begin tx_signal <= tx_data[2]; tx_state <= `BIT3; end `BIT3: begin tx_signal <= tx_data[3]; tx_state <= `BIT4; end `BIT4: begin tx_signal <= tx_data[4]; tx_state <= `BIT5; end `BIT5: begin tx_signal <= tx_data[5]; tx_state <= `BIT6; end `BIT6: begin tx_signal <= tx_data[6]; tx_state <= `BIT7; end `BIT7: begin tx_signal <= tx_data[7]; tx_state <= `STOP; end `STOP: begin tx_signal <= 1; tx_state <= `IDLE; tx_transmitted <= 1; end endcase end end endmodule