`include "defs.svh" module rs232_tx ( input bit clock , input bit reset , output bit out_ready , input bit out_valid , input uart_byte_t out_data , output bit tx ); bit hold_valid; uart_byte_t hold; bit parity; (* syn_encoding = "one-hot" *) enum int unsigned { START , DATA , PARITY , STOP1 , STOP2 } state; bit [$clog2(`UART_BYTE_BITS):0] data_bits; always @(posedge clock, posedge reset) begin if (reset) begin out_ready = 0; tx = 1; hold_valid = 0; parity = 0; state = state.first; data_bits = 0; end else begin if (out_ready && out_valid) begin hold_valid = 1; hold = out_data; parity = 0; state = state.first; data_bits = 0; end if (hold_valid) begin case (state) START: begin tx = 0; state = state.next; end DATA: begin tx = hold[data_bits]; parity = parity ^ tx; if (data_bits == `UART_BYTE_BITS-1) state = state.next; else ++data_bits; end PARITY: begin tx = parity; state = state.next; end STOP1: begin tx = 1; state = state.next; end STOP2: begin hold_valid = 0; tx = 1; state = state.next; end endcase end else begin tx = 1; end out_ready = !hold_valid; end end endmodule module rs232_rx #( OVERSAMPLE = 0 ) ( input bit clock , input bit reset , input bit in_ready , output bit in_valid , output uart_byte_t in_data , input bit rx ); (* syn_encoding = "one-hot" *) enum int unsigned { START , DATA , PARITY , STOP } state; uart_byte_t buffer; bit [$clog2(`UART_BYTE_BITS):0] data_bits; bit parity; bit [$clog2(OVERSAMPLE+1):0] sample; always @(posedge clock, posedge reset) begin if (reset) begin in_valid = 0; state = state.first; buffer = 0; data_bits = 0; parity = 0; sample = 0; end else begin automatic bit ok = 0; if (in_ready && in_valid) in_valid = 0; if (state == state.first) begin ok = 1; end else begin ++sample; if (sample == OVERSAMPLE+1) begin sample = 0; ok = 1; end end if (ok) begin case (state) START: begin if (rx == 0) begin state = state.next; buffer = 0; data_bits = 0; parity = 0; end end DATA: begin buffer[data_bits] = rx; parity = parity ^ rx; if (data_bits == `UART_BYTE_BITS-1) state = state.next; else ++data_bits; end PARITY: begin parity = parity ^ rx; if (parity == 0) state = state.next; else state = state.first; end STOP: begin if (!in_valid && rx == 1) begin in_valid = 1; in_data = buffer; end state = state.next; end endcase end end end endmodule