From d6d6edfd57c3dc4db01666034d11ac84d31ec2ef Mon Sep 17 00:00:00 2001 From: Julian Blake Kongslie Date: Sun, 22 May 2022 15:42:55 -0700 Subject: Only sample RS232 signals once per clock; use a delayed flop internally. This removes metastability issues on inputs and makes everything work. --- hdl/rs232.sv | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) (limited to 'hdl/rs232.sv') diff --git a/hdl/rs232.sv b/hdl/rs232.sv index 29ccb6c..d163cda 100644 --- a/hdl/rs232.sv +++ b/hdl/rs232.sv @@ -36,6 +36,8 @@ module rs232_tx bit [RTS_BITS-1:0] rts_samples; + bit old_rts; + always @(posedge clock, posedge reset) begin if (reset) begin out_ready = 0; @@ -46,6 +48,7 @@ module rs232_tx data_bits = 0; stop_bits = 0; rts_samples = 0; + old_rts = 0; end else begin if (out_ready && out_valid) begin hold_valid = 1; @@ -57,7 +60,7 @@ module rs232_tx end rts_samples = rts_samples << 1; - rts_samples[0] = rts; + rts_samples[0] = old_rts; if (hold_valid) begin case (state) @@ -100,6 +103,8 @@ module rs232_tx end out_ready = !hold_valid; + + old_rts = rts; end end @@ -140,6 +145,8 @@ module rs232_rx bit [$clog2(OVERSAMPLE+1):0] clock_counter; bit [$clog2(OVERSAMPLE+1):0] next_clock_counter; + bit old_txd; + always @(posedge clock, posedge reset) begin if (reset) begin clock_out = 0; @@ -152,6 +159,7 @@ module rs232_rx sample = 0; clock_counter = 0; next_clock_counter = 0; + old_txd = 0; end else begin automatic bit ok = 0; @@ -190,7 +198,7 @@ module rs232_rx case (state) START: begin - if (txd == 0) begin + if (old_txd == 0) begin state = state.next; if (OVERSAMPLE == 0) state = state.next; @@ -205,8 +213,8 @@ module rs232_rx DATA: begin buffer = buffer >> 1; - buffer[`UART_BYTE_BITS-1] = txd; - parity = parity ^ txd; + buffer[`UART_BYTE_BITS-1] = old_txd; + parity = parity ^ old_txd; if (data_bits == `UART_BYTE_BITS-1) state = state.next; else @@ -214,26 +222,26 @@ module rs232_rx end PARITY_BIT: begin - parity = parity ^ txd; + parity = parity ^ old_txd; state = state.next; end STOP: begin - if (!in_valid && txd == 1 && parity == 0) begin + if (!in_valid && old_txd == 1 && parity == 0) begin in_valid = 1; in_data = buffer; end - if (txd == 1 && parity == 0) begin + if (old_txd == 1 && parity == 0) begin next_clock_counter = (OVERSAMPLE+1)/2; end - if (txd == 1) + if (old_txd == 1) state = state.first; else state = state.next; end REALSTOP: begin - if (txd == 1) + if (old_txd == 1) state = state.first; end @@ -241,6 +249,8 @@ module rs232_rx end cts = !(state == state.first && !in_valid); + + old_txd = txd; end end -- cgit v1.2.3