Verilog UART Transmitter
I would recommend your outputs be flops. It would be a cleaner output signal and easier to do timing analyses. It takes time (few nano seconds) to calculate the tx value after the clock with combinational logic. During that time the intermediate values are being transmitted and causing noise. This noise will can get worse from resistance an capacitance in your USB cable; lowers the signal quality. It seems your running at low speeds, so you wouldn't see a problem, but at higher speeds you may run into trouble. 

Be aware that many synthesizers treat conditional operators (the ? : syntax) as explicit 2:1 muxes. So your current tx logic will always be a chain of 2:1 muxes even when a 4:1 is more suitable. A case statement within an always block tend to synthesize more optimally. I have a more detail answer for ? : vs case() on here on Electronics StackExchange.

Usually a FSM is written as a case statement; not if-else statements. The synthesizer doesn't really care. It is more of a common practice with RTL designers. It makes the FSM easier to identify and control how it synthesizes (full_case, parallel_case, onehot, encoding, etc.).

For a more optimzed design, your code should look something like the below. Or you can use two always blocks (my preference); one for calculating the next states for the flops, the other for simple flop assignment.

module uart_send #(parameter BAUD_RATE = 9600,
                   parameter CLOCK_SPEED_MHZ = 100)
                  (input [7:0] data_byte, 
                  input start_send, 
                  input clk, 
                  output reg tx, // &lt;-- reg outputs
                  output reg ready); // &lt;-- reg outputs

  /* ... local parameter and reg declarations here ... */

  always @(posedge clk) begin
    case(state)
      IDLE : begin
          /*your IDLE code here*/
        end
      START_BIT : begin
          /*your START_BIT code here*/
        end
      END_BIT : begin
          /*your END_BIT code here*/
        end
      DATA_BIT : begin
          /*your DATA_BIT code here*/
        end
    endcase
  end

endmodule




I will also suggest changing the uart_send instantiation form connect by port order to connect by name.

uart_send sender("X", count == 100000000, clk, tx, ready);


to (port order does not matter)

uart_send sender( .data_byte("X"), .start_send(count == 100000000),
                  .clk(clk), .tx(tx), .ready(ready) );


or even cleaner (width matching)

wire [7:0] data_byte = "X";
wire start_send = (count == 100000000);
uart_send sender( .data_byte(data_byte), .start_send(start_send),
                  .clk(clk), .tx(tx), .ready(ready) );


I believe you can abbreviate matching name and size to just .name (ex .clk is the same as .clk(clk)) but I do not remember if that if Verilog or an added feature in SystemVerilog. I not have my copy if the LRMs with me.

wire [7:0] data_byte = "X";
wire start_send = (count == 100000000);
uart_send sender( .data_byte, .start_send, .clk, .tx, .ready );