added missing rtl
diff --git a/verilog/rtl/uart_rx_prog.v b/verilog/rtl/uart_rx_prog.v
new file mode 100644
index 0000000..23016da
--- /dev/null
+++ b/verilog/rtl/uart_rx_prog.v
@@ -0,0 +1,157 @@
+`timescale 1ns / 1ps
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+// Set Parameter CLKS_PER_BIT as follows:
+// CLKS_PER_BIT = (Frequency of i_Clock)/(Frequency of UART)
+// Example: 10 MHz Clock, 115200 baud UART
+// (10000000)/(115200) = 87
+
+module uart_rx_prog (
+ input wire clk_i,
+ input wire rst_ni,
+ input wire i_Rx_Serial,
+ input wire [15:0] CLKS_PER_BIT,
+ output wire o_Rx_DV,
+ output wire [7:0] o_Rx_Byte
+ );
+
+ parameter s_IDLE = 3'b000;
+ parameter s_RX_START_BIT = 3'b001;
+ parameter s_RX_DATA_BITS = 3'b010;
+ parameter s_RX_STOP_BIT = 3'b011;
+ parameter s_CLEANUP = 3'b100;
+
+ reg r_Rx_Data_R ;
+ reg r_Rx_Data ;
+
+ reg [15:0] r_Clock_Count ;
+ reg [2:0] r_Bit_Index ; //8 bits total
+ reg [7:0] r_Rx_Byte ;
+ reg r_Rx_DV ;
+ reg [2:0] r_SM_Main ;
+
+ // Purpose: Double-register the incoming data.
+ // This allows it to be used in the UART RX Clock Domain.
+ // (It removes problems caused by metastability)
+ always @(posedge clk_i)
+ begin
+ if (~rst_ni) begin
+ r_Rx_Data_R <= 1'b1;
+ r_Rx_Data <= 1'b1;
+ end else begin
+ r_Rx_Data_R <= i_Rx_Serial;
+ r_Rx_Data <= r_Rx_Data_R;
+ end
+ end
+
+
+ // Purpose: Control RX state machine
+ always @(posedge clk_i or negedge rst_ni)
+ begin
+ if (~rst_ni) begin
+ r_SM_Main <= s_IDLE;
+ r_Rx_DV <= 1'b0;
+ r_Clock_Count <= 16'b0;
+ r_Bit_Index <= 3'b0;
+ r_Rx_Byte <= 8'b0;
+ end else begin
+ case (r_SM_Main)
+ s_IDLE :
+ begin
+ r_Rx_DV <= 1'b0;
+ r_Clock_Count <= 16'b0;
+ r_Bit_Index <= 3'b0;
+ r_Rx_Byte <= 8'b0;
+ if (r_Rx_Data == 1'b0) // Start bit detected
+ r_SM_Main <= s_RX_START_BIT;
+ else
+ r_SM_Main <= s_IDLE;
+ end
+
+ // Check middle of start bit to make sure it's still low
+ s_RX_START_BIT :
+ begin
+ if (r_Clock_Count == ((CLKS_PER_BIT-1)>>1))
+ begin
+ if (r_Rx_Data == 1'b0)
+ begin
+ r_Clock_Count <= 16'b0; // reset counter, found the middle
+ r_SM_Main <= s_RX_DATA_BITS;
+ end
+ else
+ r_SM_Main <= s_IDLE;
+ end
+ else
+ begin
+ r_Clock_Count <= r_Clock_Count + 16'b1;
+ r_SM_Main <= s_RX_START_BIT;
+ end
+ end // case: s_RX_START_BIT
+
+
+ // Wait CLKS_PER_BIT-1 clock cycles to sample serial data
+ s_RX_DATA_BITS :
+ begin
+ if (r_Clock_Count < CLKS_PER_BIT-1)
+ begin
+ r_Clock_Count <= r_Clock_Count + 16'b1;
+ r_SM_Main <= s_RX_DATA_BITS;
+ end
+ else
+ begin
+ r_Clock_Count <= 16'b0;
+ r_Rx_Byte[r_Bit_Index] <= r_Rx_Data;
+
+ // Check if we have received all bits
+ if (r_Bit_Index < 7)
+ begin
+ r_Bit_Index <= r_Bit_Index + 3'b1;
+ r_SM_Main <= s_RX_DATA_BITS;
+ end
+ else
+ begin
+ r_Bit_Index <= 3'b0;
+ r_SM_Main <= s_RX_STOP_BIT;
+ end
+ end
+ end // case: s_RX_DATA_BITS
+
+
+ // Receive Stop bit. Stop bit = 1
+ s_RX_STOP_BIT :
+ begin
+ // Wait CLKS_PER_BIT-1 clock cycles for Stop bit to finish
+ if (r_Clock_Count < CLKS_PER_BIT-1)
+ begin
+ r_Clock_Count <= r_Clock_Count + 16'b1;
+ r_SM_Main <= s_RX_STOP_BIT;
+ end
+ else
+ begin
+ r_Rx_DV <= 1'b1;
+ r_Clock_Count <= 16'b0;
+ r_SM_Main <= s_CLEANUP;
+ end
+ end // case: s_RX_STOP_BIT
+
+
+ // Stay here 1 clock
+ s_CLEANUP :
+ begin
+ r_SM_Main <= s_IDLE;
+ r_Rx_DV <= 1'b0;
+ end
+
+
+ default :
+ r_SM_Main <= s_IDLE;
+
+ endcase
+ end
+ end
+
+ assign o_Rx_DV = r_Rx_DV;
+ assign o_Rx_Byte = r_Rx_Byte;
+
+endmodule // uart_rx