i2cm integrated and share same uart io
diff --git a/openlane/uart_i2cm/base.sdc b/openlane/uart_i2cm/base.sdc
new file mode 100644
index 0000000..5a0d2fe
--- /dev/null
+++ b/openlane/uart_i2cm/base.sdc
@@ -0,0 +1,74 @@
+# SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+
+set_units -time ns
+set ::env(CORE_CLOCK_PERIOD) "10"
+set ::env(CORE_CLOCK_PORT)   "app_clk"
+set ::env(CORE_CLOCK_NAME)   "app_clk"
+
+set ::env(LINE_CLOCK_PERIOD) "100"
+set ::env(LINE_CLOCK_PORT)   "u_lineclk_buf/X"
+set ::env(LINE_CLOCK_NAME)   "line_clk"
+
+######################################
+# WB Clock domain input output
+######################################
+create_clock [get_ports $::env(CORE_CLOCK_PORT)]  -name $::env(CORE_CLOCK_NAME)  -period $::env(CORE_CLOCK_PERIOD)
+create_clock [get_pins  $::env(LINE_CLOCK_PORT)]  -name $::env(LINE_CLOCK_NAME)  -period $::env(LINE_CLOCK_PERIOD)
+
+set core_input_delay_value [expr $::env(CORE_CLOCK_PERIOD) * 0.6]
+set core_output_delay_value [expr $::env(CORE_CLOCK_PERIOD) * 0.6]
+
+set line_input_delay_value  [expr $::env(LINE_CLOCK_PERIOD) * 0.6]
+set line_output_delay_value [expr $::env(LINE_CLOCK_PERIOD) * 0.6]
+puts "\[INFO\]: Setting wb output delay to:$core_output_delay_value"
+puts "\[INFO\]: Setting wb input delay to: $core_input_delay_value"
+
+
+set_input_delay 2.0 -clock [get_clocks $::env(CORE_CLOCK_NAME)] {uart_rstn}
+set_input_delay 2.0 -clock [get_clocks $::env(CORE_CLOCK_NAME)] {i2c_rstn}
+set_input_delay 2.0 -clock [get_clocks $::env(CORE_CLOCK_NAME)] {uart_i2c_sel}
+
+set_input_delay  $core_input_delay_value   -clock [get_clocks $::env(CORE_CLOCK_NAME)] [get_port reg_cs*]
+set_input_delay  $core_input_delay_value   -clock [get_clocks $::env(CORE_CLOCK_NAME)] [get_port reg_addr*]
+set_input_delay  $core_input_delay_value   -clock [get_clocks $::env(CORE_CLOCK_NAME)] [get_port reg_wr*]
+set_input_delay  $core_input_delay_value   -clock [get_clocks $::env(CORE_CLOCK_NAME)] [get_port reg_be*]
+set_input_delay  $core_input_delay_value   -clock [get_clocks $::env(CORE_CLOCK_NAME)] [get_port reg_wdata*]
+
+
+set_output_delay $core_output_delay_value  -clock [get_clocks $::env(CORE_CLOCK_NAME)] [get_port reg_rdata*]
+set_output_delay $core_output_delay_value  -clock [get_clocks $::env(CORE_CLOCK_NAME)] [get_port reg_ack*]
+
+set_input_delay  $line_input_delay_value   -clock [get_clocks $::env(LINE_CLOCK_NAME)] [get_port io_in*]
+set_output_delay $line_input_delay_value   -clock [get_clocks $::env(LINE_CLOCK_NAME)] [get_port io_oeb*]
+set_output_delay $line_output_delay_value  -clock [get_clocks $::env(LINE_CLOCK_NAME)] [get_port io_out*]
+
+
+set_clock_groups -name async_clock -asynchronous -comment "Async Clock group" -group [get_clocks $::env(CORE_CLOCK_NAME)] -group [get_clocks $::env(LINE_CLOCK_NAME)] 
+
+set_clock_uncertainty -from $::env(CORE_CLOCK_NAME)   -to $::env(CORE_CLOCK_NAME)  -setup 0.400
+set_clock_uncertainty -from $::env(LINE_CLOCK_NAME)   -to $::env(LINE_CLOCK_NAME) -setup 0.400
+
+set_clock_uncertainty -from $::env(CORE_CLOCK_NAME)   -to $::env(CORE_CLOCK_NAME)  -hold 0.050
+set_clock_uncertainty -from $::env(LINE_CLOCK_NAME)   -to $::env(LINE_CLOCK_NAME) -hold 0.050
+
+# TODO set this as parameter
+set_driving_cell -lib_cell $::env(SYNTH_DRIVING_CELL) -pin $::env(SYNTH_DRIVING_CELL_PIN) [all_inputs]
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load  $cap_load [all_outputs]
+
diff --git a/openlane/uart_i2cm/config.tcl b/openlane/uart_i2cm/config.tcl
new file mode 100644
index 0000000..088a579
--- /dev/null
+++ b/openlane/uart_i2cm/config.tcl
@@ -0,0 +1,95 @@
+# SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+set ::env(DESIGN_NAME) uart_i2c_top
+
+
+set ::env(DESIGN_IS_CORE) "0"
+set ::env(FP_PDN_CORE_RING) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "app_clk"
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+    $script_dir/../../verilog/rtl/uart/src/uart_core.sv  \
+    $script_dir/../../verilog/rtl/uart/src/uart_cfg.sv   \
+    $script_dir/../../verilog/rtl/uart/src/uart_rxfsm.sv \
+    $script_dir/../../verilog/rtl/uart/src/uart_txfsm.sv \
+    $script_dir/../../verilog/rtl/lib/async_fifo_th.sv   \
+    $script_dir/../../verilog/rtl/lib/reset_sync.sv      \
+    $script_dir/../../verilog/rtl/lib/double_sync_low.v  \
+    $script_dir/../../verilog/rtl/lib/clk_ctl.v          \
+    $script_dir/../../verilog/rtl/lib/registers.v        \
+    $script_dir/../../verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v      \
+    $script_dir/../../verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v     \
+    $script_dir/../../verilog/rtl/i2cm/src/core/i2cm_top.v           \
+    $script_dir/../../verilog/rtl/uart_i2c/src/uart_i2c_top.sv       \
+    "
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(VERILOG_INCLUDE_DIRS) [glob $script_dir/../../verilog/rtl/i2cm/src/includes ]
+
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+set ::env(FP_SIZING) "absolute"
+set ::env(DIE_AREA) [list 0.0 0.0 300.0 400.0]
+
+
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 0
+
+#set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+
+set ::env(PL_ROUTABILITY_DRIVEN) 1
+
+set ::env(FP_IO_VEXTEND) 4
+set ::env(FP_IO_HEXTEND) 4
+
+
+set ::env(GLB_RT_MAXLAYER) 4
+set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+set ::env(FP_PDN_VPITCH) 100
+set ::env(FP_PDN_HPITCH) 100
+set ::env(FP_PDN_VWIDTH) 5
+set ::env(FP_PDN_HWIDTH) 5
diff --git a/openlane/uart_i2cm/pdn.tcl b/openlane/uart_i2cm/pdn.tcl
new file mode 100644
index 0000000..1fe689b
--- /dev/null
+++ b/openlane/uart_i2cm/pdn.tcl
@@ -0,0 +1,49 @@
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+
+# Power nets
+set ::power_nets $::env(VDD_PIN)
+set ::ground_nets $::env(GND_PIN)
+
+set ::macro_blockage_layer_list "li1 met1 met2 met3 met4 met5"
+
+pdngen::specify_grid stdcell {
+    name grid
+    rails {
+	    met1 {width 0.48 pitch $::env(PLACE_SITE_HEIGHT) offset 0}
+    }
+    straps {
+	    met4 {width 1.6 pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
+	    met5 {width 1.6 pitch $::env(FP_PDN_HPITCH) offset $::env(FP_PDN_HOFFSET)}
+    }
+    connect {{met1 met4} {met4 met5}}
+}
+
+pdngen::specify_grid macro {
+    power_pins "VPWR"
+    ground_pins "VGND"
+    blockages "li1 met1 met2 met3 met4"
+    straps { 
+    } 
+    connect {{met4_PIN_ver met5}}
+}
+
+set ::halo 5
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
diff --git a/openlane/uart_i2cm/pin_order.cfg b/openlane/uart_i2cm/pin_order.cfg
new file mode 100644
index 0000000..870fa34
--- /dev/null
+++ b/openlane/uart_i2cm/pin_order.cfg
@@ -0,0 +1,40 @@
+#BUS_SORT
+#MANUAL_PLACE
+
+#S
+app_clk                0000 0
+uart_rstn    
+i2c_rstn 
+uart_i2c_sel            
+io_in\[1\]             
+io_out\[1\]             
+io_oeb\[1\]             
+io_in\[0\]             
+io_out\[0\]             
+io_oeb\[0\]             
+
+#N
+reg_cs                 0000 0
+reg_wr                 0000 1
+reg_addr\[3\]          0000 4
+reg_addr\[2\]          0000 5
+reg_addr\[1\]          0000 6
+reg_addr\[0\]          0000 7
+reg_be                 0000 10
+reg_wdata\[7\]         0000 11
+reg_wdata\[6\]         0000 12
+reg_wdata\[5\]         0000 13
+reg_wdata\[4\]         0000 14
+reg_wdata\[3\]         0000 15
+reg_wdata\[2\]         0000 16
+reg_wdata\[1\]         0000 17
+reg_wdata\[0\]         0000 18
+reg_rdata\[7\]         0000 19
+reg_rdata\[6\]         0000 20
+reg_rdata\[5\]         0000 21
+reg_rdata\[4\]         0000 22
+reg_rdata\[3\]         0000 23
+reg_rdata\[2\]         0000 24
+reg_rdata\[1\]         0000 25
+reg_rdata\[0\]         0000 26
+reg_ack                0000 27
diff --git a/openlane/uart_i2cm/sta.tcl b/openlane/uart_i2cm/sta.tcl
new file mode 100644
index 0000000..ef1ab52
--- /dev/null
+++ b/openlane/uart_i2cm/sta.tcl
@@ -0,0 +1,56 @@
+# SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+set ::env(LIB_FASTEST) "/home/dinesha/workarea/pdk/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_SLOWEST) "/home/dinesha/workarea/pdk/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(CURRENT_NETLIST) /project/openlane/uart_i2cm/runs/uart_i2cm/results/lvs/uart_i2c_top.lvs.powered.v
+set ::env(DESIGN_NAME) "uart_i2c_top"
+set ::env(CURRENT_SPEF) /project/openlane/uart_i2cm/runs/uart_i2cm/results/routing/uart_i2c_top.spef
+set ::env(BASE_SDC_FILE) "/project/openlane/uart_i2cm/base.sdc"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+read_liberty -min $::env(LIB_FASTEST)
+read_liberty -max $::env(LIB_SLOWEST)
+read_verilog $::env(CURRENT_NETLIST)
+link_design  $::env(DESIGN_NAME)
+
+read_spef  $::env(CURRENT_SPEF)
+
+read_sdc -echo $::env(BASE_SDC_FILE)
+
+# check for missing constraints
+#check_setup  -verbose > unconstraints.rpt
+
+set_operating_conditions -analysis_type bc_wc
+# Propgate the clock
+set_propagated_clock [all_clocks]
+
+report_tns
+report_wns
+report_power 
+report_checks -unique -slack_max -0.0 -group_count 100 
+report_checks -unique -slack_min -0.0 -group_count 100 
+report_checks -path_delay min_max 
+report_checks -group_count 100  -slack_max -0.01 
+
+
+
+
diff --git a/openlane/user_project_wrapper/config.tcl b/openlane/user_project_wrapper/config.tcl
index 9c9e20a..acb43f8 100644
--- a/openlane/user_project_wrapper/config.tcl
+++ b/openlane/user_project_wrapper/config.tcl
@@ -59,7 +59,7 @@
         $script_dir/../../verilog/gl/spi_master.v \
         $script_dir/../../verilog/gl/wb_interconnect.v \
         $script_dir/../../verilog/gl/glbl_cfg.v     \
-        $script_dir/../../verilog/gl/uart.v     \
+        $script_dir/../../verilog/gl/uart_i2cm.v     \
 	$script_dir/../../verilog/gl/sdram.v \
 	$script_dir/../../verilog/gl/wb_host.v \
 	$script_dir/../../verilog/gl/clk_skew_adjust.v \
@@ -71,7 +71,7 @@
 	$lef_root/glbl_cfg.lef \
 	$lef_root/wb_interconnect.lef \
 	$lef_root/sdram.lef \
-	$lef_root/uart.lef \
+	$lef_root/uart_i2cm.lef \
 	$lef_root/wb_host.lef \
 	$lef_root/clk_skew_adjust.lef \
 	$lef_root/syntacore.lef \
@@ -81,7 +81,7 @@
 	$gds_root/spi_master.gds \
 	$gds_root/glbl_cfg.gds \
 	$gds_root/wb_interconnect.gds \
-	$gds_root/uart.gds \
+	$gds_root/uart_i2cm.gds \
 	$gds_root/sdram.gds \
 	$gds_root/wb_host.gds \
 	$gds_root/clk_skew_adjust.gds \
diff --git a/openlane/user_project_wrapper/macro.cfg b/openlane/user_project_wrapper/macro.cfg
index 7a9c10f..0d6ef5c 100644
--- a/openlane/user_project_wrapper/macro.cfg
+++ b/openlane/user_project_wrapper/macro.cfg
@@ -2,7 +2,7 @@
 u_sdram_ctrl            1000            2700            N
 u_glbl_cfg              2000            2700            N
 u_riscv_top	        500	        800	        N
-u_uart_core             2200            1600            N
+u_uart_i2c              2200            1600            N
 u_intercon              300             2300            N
 u_wb_host               300             300             N
 u_skew_wi               2600            2300            N
diff --git a/openlane/wb_host/pin_order.cfg b/openlane/wb_host/pin_order.cfg
index 6b90110..41f63b5 100644
--- a/openlane/wb_host/pin_order.cfg
+++ b/openlane/wb_host/pin_order.cfg
@@ -17,7 +17,7 @@
 
 
 #S
-user_clock2     
+user_clock2         0000 0  2
 user_clock1     
 wbm_clk_i       
 wbm_rst_i       
@@ -140,7 +140,6 @@
 wbs_clk_out   
 cpu_clk
 rtc_clk
-wbd_int_rst_n
 
 #N
 wbs_stb_o        0000 0 2
@@ -302,3 +301,7 @@
 cfg_clk_ctrl2\[1\]
 cfg_clk_ctrl2\[0\]
 
+uart_rst_n
+i2cm_rst_n
+uart_i2c_sel
+wbd_int_rst_n
diff --git a/signoff/uart_i2cm/OPENLANE_VERSION b/signoff/uart_i2cm/OPENLANE_VERSION
new file mode 100644
index 0000000..a2633b1
--- /dev/null
+++ b/signoff/uart_i2cm/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane rc7
diff --git a/signoff/uart_i2cm/PDK_SOURCES b/signoff/uart_i2cm/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/uart_i2cm/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane 
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk 
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks 
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/uart_i2cm/final_summary_report.csv b/signoff/uart_i2cm/final_summary_report.csv
new file mode 100644
index 0000000..6a4c74e
--- /dev/null
+++ b/signoff/uart_i2cm/final_summary_report.csv
@@ -0,0 +1,2 @@
+,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
+0,/project/openlane/uart_i2cm,uart_i2c_top,uart_i2cm,Flow_completed,0h5m42s,0h3m37s,59350.0,0.12,29675.0,47,561.56,3561,0,0,0,0,0,0,0,0,0,-1,0,124117,27523,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,81974377,0.0,25.57,25.46,0.33,-1,-1,3562,3582,623,643,0,0,0,3561,98,10,58,70,423,155,27,836,589,556,17,278,1410,0,1688,100.0,10.0,10,AREA 0,4,50,1,100,100,0.55,0,sky130_fd_sc_hd,4,4
diff --git a/signoff/user_project_wrapper/final_summary_report.csv b/signoff/user_project_wrapper/final_summary_report.csv
index b467fd5..cca124b 100644
--- a/signoff/user_project_wrapper/final_summary_report.csv
+++ b/signoff/user_project_wrapper/final_summary_report.csv
@@ -1,2 +1,2 @@
 ,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
-0,/project/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,Flow_completed,0h41m39s,0h4m37s,3.3079078455790785,10.2784,1.6539539227895392,0,552.52,17,0,0,0,0,0,0,0,0,1,-1,-1,1190352,4009,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1,0.0,1.26,4.32,0.78,1.93,-1,848,1466,848,1466,0,0,0,17,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,100.0,10.0,10,AREA 0,5,50,1,80,80,0.55,0,sky130_fd_sc_hd,4,0
+0,/project/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,Flow_completed,0h41m53s,0h4m38s,3.3079078455790785,10.2784,1.6539539227895392,0,553.94,17,0,0,0,0,0,0,0,0,1,-1,-1,1198068,3955,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1,0.0,1.28,4.34,0.79,1.93,-1,851,1469,851,1469,0,0,0,17,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,100.0,10.0,10,AREA 0,5,50,1,80,80,0.55,0,sky130_fd_sc_hd,4,0
diff --git a/signoff/wb_host/final_summary_report.csv b/signoff/wb_host/final_summary_report.csv
index 02deb7d..2002da3 100644
--- a/signoff/wb_host/final_summary_report.csv
+++ b/signoff/wb_host/final_summary_report.csv
@@ -1,2 +1,2 @@
 ,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
-0,/project/openlane/wb_host,wb_host,wb_host,Flow_completed,0h6m19s,0h4m12s,61400.0,0.1,30700.0,49,584.38,3070,0,0,0,0,0,0,0,1,0,-1,0,172826,26248,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,140873672,0.0,49.1,23.43,16.91,-1,-1,2926,3180,551,805,0,0,0,3070,78,0,3,11,50,27,10,799,605,775,14,130,1139,0,1269,100.0,10.0,10,AREA 0,4,50,1,100,100,0.55,0,sky130_fd_sc_hd,4,5
+0,/project/openlane/wb_host,wb_host,wb_host,Flow_completed,0h5m27s,0h3m34s,61460.0,0.1,30730.0,49,592.54,3073,0,0,0,0,0,0,0,4,0,-1,0,173324,26294,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,139681646,0.0,48.89,23.41,17.83,-1,-1,2929,3183,554,808,0,0,0,3073,77,0,3,11,49,26,11,799,605,775,14,130,1139,0,1269,100.0,10.0,10,AREA 0,4,50,1,100,100,0.55,0,sky130_fd_sc_hd,4,5
diff --git a/verilog/dv/Makefile b/verilog/dv/Makefile
index db261ec..4076ba9 100644
--- a/verilog/dv/Makefile
+++ b/verilog/dv/Makefile
@@ -19,7 +19,7 @@
 .SUFFIXES:
 .SILENT: clean all
 
-PATTERNS = io_ports la_test1 la_test2 wb_port mprj_stimulus risc_boot user_risc_boot user_uart user_spi
+PATTERNS = io_ports la_test1 la_test2 wb_port mprj_stimulus risc_boot user_risc_boot user_uart user_spi user_i2cm
 
 all:  ${PATTERNS}
 	for i in ${PATTERNS}; do \
diff --git a/verilog/dv/model/i2c_slave_model.v b/verilog/dv/model/i2c_slave_model.v
new file mode 100755
index 0000000..1271127
--- /dev/null
+++ b/verilog/dv/model/i2c_slave_model.v
@@ -0,0 +1,356 @@
+/////////////////////////////////////////////////////////////////////
+////                                                             ////
+////  WISHBONE rev.B2 compliant synthesizable I2C Slave model    ////
+////                                                             ////
+////                                                             ////
+////  Authors: Richard Herveille (richard@asics.ws) www.asics.ws ////
+////           John Sheahan (jrsheahan@optushome.com.au)         ////
+////                                                             ////
+////  Downloaded from: http://www.opencores.org/projects/i2c/    ////
+////                                                             ////
+/////////////////////////////////////////////////////////////////////
+////                                                             ////
+//// Copyright (C) 2001,2002 Richard Herveille                   ////
+////                         richard@asics.ws                    ////
+////                                                             ////
+//// This source file may be used and distributed without        ////
+//// restriction provided that this copyright statement is not   ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer.////
+////                                                             ////
+////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
+//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
+//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
+//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
+//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
+//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
+//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
+//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
+//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
+//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
+//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
+//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
+//// POSSIBILITY OF SUCH DAMAGE.                                 ////
+////                                                             ////
+/////////////////////////////////////////////////////////////////////
+
+//  CVS Log
+//
+//  $Id: i2c_slave_model.v,v 1.7 2006-09-04 09:08:51 rherveille Exp $
+//
+//  $Date: 2006-09-04 09:08:51 $
+//  $Revision: 1.7 $
+//  $Author: rherveille $
+//  $Locker:  $
+//  $State: Exp $
+//
+// Change History:
+//               $Log: not supported by cvs2svn $
+//               Revision 1.6  2005/02/28 11:33:48  rherveille
+//               Fixed Tsu:sta timing check.
+//               Added Thd:sta timing check.
+//
+//               Revision 1.5  2003/12/05 11:05:19  rherveille
+//               Fixed slave address MSB='1' bug
+//
+//               Revision 1.4  2003/09/11 08:25:37  rherveille
+//               Fixed a bug in the timing section. Changed 'tst_scl' into 'tst_sto'.
+//
+//               Revision 1.3  2002/10/30 18:11:06  rherveille
+//               Added timing tests to i2c_model.
+//               Updated testbench.
+//
+//               Revision 1.2  2002/03/17 10:26:38  rherveille
+//               Fixed some race conditions in the i2c-slave model.
+//               Added debug information.
+//               Added headers.
+//
+
+
+module i2c_slave_model (scl, sda);
+
+	//
+	// parameters
+	//
+	parameter I2C_ADR = 7'b001_0000;
+
+	//
+	// input && outpus
+	//
+	input scl;
+	inout sda;
+
+	//
+	// Variable declaration
+	//
+	wire debug = 1'b1;
+
+	reg [7:0] mem [255:0]; // initiate memory
+	reg [7:0] mem_adr;   // memory address
+	reg [7:0] mem_do;    // memory data output
+
+	reg sta, d_sta;
+	reg sto, d_sto;
+
+	reg [7:0] sr;        // 8bit shift register
+	reg       rw;        // read/write direction
+
+	wire      my_adr;    // my address called ??
+	wire      i2c_reset; // i2c-statemachine reset
+	reg [2:0] bit_cnt;   // 3bit downcounter
+	wire      acc_done;  // 8bits transfered
+	reg       ld;        // load downcounter
+
+	reg       sda_o;     // sda-drive level
+	wire      sda_dly;   // delayed version of sda
+
+	// statemachine declaration
+	parameter idle        = 3'b000;
+	parameter slave_ack   = 3'b001;
+	parameter get_mem_adr = 3'b010;
+	parameter gma_ack     = 3'b011;
+	parameter data        = 3'b100;
+	parameter data_ack    = 3'b101;
+
+	reg [2:0] state; // synopsys enum_state
+
+	//
+	// module body
+	//
+
+	initial
+	begin
+	   sda_o = 1'b1;
+	   state = idle;
+	end
+
+	// generate shift register
+	always @(posedge scl)
+	  sr <= #1 {sr[6:0],sda};
+
+	//detect my_address
+	assign my_adr = (sr[7:1] == I2C_ADR);
+	// FIXME: This should not be a generic assign, but rather
+	// qualified on address transfer phase and probably reset by stop
+
+	//generate bit-counter
+	always @(posedge scl)
+	  if(ld)
+	    bit_cnt <= #1 3'b111;
+	  else
+	    bit_cnt <= #1 bit_cnt - 3'h1;
+
+	//generate access done signal
+	assign acc_done = !(|bit_cnt);
+
+	// generate delayed version of sda
+	// this model assumes a hold time for sda after the falling edge of scl.
+	// According to the Phillips i2c spec, there s/b a 0 ns hold time for sda
+	// with regards to scl. If the data changes coincident with the clock, the
+	// acknowledge is missed
+	// Fix by Michael Sosnoski
+	assign #1 sda_dly = sda;
+
+
+	//detect start condition
+	always @(negedge sda)
+	  if(scl)
+	    begin
+	        sta   <= #1 1'b1;
+		d_sta <= #1 1'b0;
+		sto   <= #1 1'b0;
+
+	        if(debug)
+	          $display("DEBUG i2c_slave; start condition detected at %t", $time);
+	    end
+	  else
+	    sta <= #1 1'b0;
+
+	always @(posedge scl)
+	  d_sta <= #1 sta;
+
+	// detect stop condition
+	always @(posedge sda)
+	  if(scl)
+	    begin
+	       sta <= #1 1'b0;
+	       sto <= #1 1'b1;
+
+	       if(debug)
+	         $display("DEBUG i2c_slave; stop condition detected at %t", $time);
+	    end
+	  else
+	    sto <= #1 1'b0;
+
+	//generate i2c_reset signal
+	assign i2c_reset = sta || sto;
+
+	// generate statemachine
+	always @(negedge scl or posedge sto)
+	  if (sto || (sta && !d_sta) )
+	    begin
+	        state <= #1 idle; // reset statemachine
+
+	        sda_o <= #1 1'b1;
+	        ld    <= #1 1'b1;
+	    end
+	  else
+	    begin
+	        // initial settings
+	        sda_o <= #1 1'b1;
+	        ld    <= #1 1'b0;
+
+	        case(state) // synopsys full_case parallel_case
+	            idle: // idle state
+	              if (acc_done && my_adr)
+	                begin
+	                    state <= #1 slave_ack;
+	                    rw <= #1 sr[0];
+	                    sda_o <= #1 1'b0; // generate i2c_ack
+
+	                    #2;
+	                    if(debug && rw)
+	                      $display("DEBUG i2c_slave; command byte received (read) at %t", $time);
+	                    if(debug && !rw)
+	                      $display("DEBUG i2c_slave; command byte received (write) at %t", $time);
+
+	                    if(rw)
+	                      begin
+	                          mem_do <= #1 mem[mem_adr];
+
+	                          if(debug)
+	                            begin
+	                                #2 $display("DEBUG i2c_slave; data block read %x from address %x (1)", mem_do, mem_adr);
+	                                #2 $display("DEBUG i2c_slave; memcheck [%x]=%x", mem_adr, mem[mem_adr]);
+	                            end
+	                      end
+	                end
+
+	            slave_ack:
+	              begin
+	                  if(rw)
+	                    begin
+	                        state <= #1 data;
+	                        sda_o <= #1 mem_do[7];
+	                    end
+	                  else
+	                    state <= #1 get_mem_adr;
+
+	                  ld    <= #1 1'b1;
+	              end
+
+	            get_mem_adr: // wait for memory address
+	              if(acc_done)
+	                begin
+	                    state <= #1 gma_ack;
+	                    mem_adr <= #1 sr; // store memory address
+	                    sda_o <= #1 !(sr <= 255); // generate i2c_ack, for valid address
+
+	                    if(debug)
+	                      #1 $display("DEBUG i2c_slave; address received. adr=%x, ack=%b", sr, sda_o);
+	                end
+
+	            gma_ack:
+	              begin
+	                  state <= #1 data;
+	                  ld    <= #1 1'b1;
+	              end
+
+	            data: // receive or drive data
+	              begin
+	                  if(rw)
+	                    sda_o <= #1 mem_do[7];
+
+	                  if(acc_done)
+	                    begin
+	                        state <= #1 data_ack;
+	                        mem_adr <= #2 mem_adr + 8'h1;
+	                        sda_o <= #1 (rw && (mem_adr <= 255) ); // send ack on write, receive ack on read
+
+	                        if(rw)
+	                          begin
+	                              #3 mem_do <= mem[mem_adr];
+
+	                              if(debug)
+	                                #5 $display("DEBUG i2c_slave; data block read %x from address %x (2)", mem_do, mem_adr);
+	                          end
+
+	                        if(!rw)
+	                          begin
+	                              mem[ mem_adr ] <= #1 sr; // store data in memory
+
+	                              if(debug)
+	                                #2 $display("DEBUG i2c_slave; data block write %x to address %x", sr, mem_adr);
+	                          end
+	                    end
+	              end
+
+	            data_ack:
+	              begin
+	                  ld <= #1 1'b1;
+
+	                  if(rw)
+	                    if(sr[0]) // read operation && master send NACK
+	                      begin
+	                          state <= #1 idle;
+	                          sda_o <= #1 1'b1;
+	                      end
+	                    else
+	                      begin
+	                          state <= #1 data;
+	                          sda_o <= #1 mem_do[7];
+	                      end
+	                  else
+	                    begin
+	                        state <= #1 data;
+	                        sda_o <= #1 1'b1;
+	                    end
+	              end
+
+	        endcase
+	    end
+
+	// read data from memory
+	always @(posedge scl)
+	  if(!acc_done && rw)
+	    mem_do <= #1 {mem_do[6:0], 1'b1}; // insert 1'b1 for host ack generation
+
+	// generate tri-states
+	assign sda = sda_o ? 1'bz : 1'b0;
+
+
+	//
+	// Timing checks
+	//
+
+	wire tst_sto = sto;
+	wire tst_sta = sta;
+
+	specify
+	  specparam normal_scl_low  = 4700,
+	            normal_scl_high = 4000,
+	            normal_tsu_sta  = 4700,
+	            normal_thd_sta  = 4000,
+	            normal_tsu_sto  = 4000,
+	            normal_tbuf     = 4700,
+
+	            fast_scl_low  = 1300,
+	            fast_scl_high =  600,
+	            fast_tsu_sta  = 1300,
+	            fast_thd_sta  =  600,
+	            fast_tsu_sto  =  600,
+	            fast_tbuf     = 1300;
+
+	  $width(negedge scl, normal_scl_low);  // scl low time
+	  $width(posedge scl, normal_scl_high); // scl high time
+
+	  $setup(posedge scl, negedge sda &&& scl, normal_tsu_sta); // setup start
+	  $setup(negedge sda &&& scl, negedge scl, normal_thd_sta); // hold start
+	  $setup(posedge scl, posedge sda &&& scl, normal_tsu_sto); // setup stop
+
+	  $setup(posedge tst_sta, posedge tst_sto, normal_tbuf); // stop to start time
+	endspecify
+
+endmodule
+
+
diff --git a/verilog/dv/risc_boot/Makefile b/verilog/dv/risc_boot/Makefile
index 635b188..5289713 100644
--- a/verilog/dv/risc_boot/Makefile
+++ b/verilog/dv/risc_boot/Makefile
@@ -30,6 +30,7 @@
 UPRJ_BEHAVIOURAL_AGENTS = ../agents
 UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
 UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
 
 ## SYNTACORE FIRMWARE
 SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
@@ -65,7 +66,7 @@
 	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
 	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH)  \
 	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
-	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
 	$< -o $@ 
 else  
 	iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/risc_boot/risc_boot.c b/verilog/dv/risc_boot/risc_boot.c
index dadfcab..e5253b2 100644
--- a/verilog/dv/risc_boot/risc_boot.c
+++ b/verilog/dv/risc_boot/risc_boot.c
@@ -180,7 +180,7 @@
     reg_mprj_globl_reg4  = 0x2F172242;
 
     // Remove All Reset
-    reg_mprj_wbhost_reg0 = 0xF;
+    reg_mprj_wbhost_reg0 = 0x1F;
 
 
     // configure the user uart
diff --git a/verilog/dv/risc_boot/risc_boot_tb.v b/verilog/dv/risc_boot/risc_boot_tb.v
index 169f2a8..6d503fc 100644
--- a/verilog/dv/risc_boot/risc_boot_tb.v
+++ b/verilog/dv/risc_boot/risc_boot_tb.v
@@ -437,10 +437,10 @@
 	force uut.mprj.u_spi_master.u_buf_sdio3.VGND    =VSS;
 	force uut.mprj.u_spi_master.u_buf_sdio3.VNB     =VSS;
           
-	force uut.mprj.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
-	force uut.mprj.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
-	force uut.mprj.u_uart_core.u_lineclk_buf.VGND =VSS;
-	force uut.mprj.u_uart_core.u_lineclk_buf.VNB = VSS;
+	force uut.mprj.u_uart_i2c.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+	force uut.mprj.u_uart_i2c.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
+	force uut.mprj.u_uart_i2c.u_uart_core.u_lineclk_buf.VGND =VSS;
+	force uut.mprj.u_uart_i2c.u_uart_core.u_lineclk_buf.VNB = VSS;
 
 	force uut.mprj.u_wb_host.u_buf_wb_rst.VPWR =USER_VDD1V8;
 	force uut.mprj.u_wb_host.u_buf_wb_rst.VPB  =USER_VDD1V8;
@@ -462,6 +462,21 @@
 	force uut.mprj.u_wb_host.u_buf_sdram_rst.VGND =VSS;
 	force uut.mprj.u_wb_host.u_buf_sdram_rst.VNB = VSS;
 
+	force uut.mprj.u_wb_host.u_buf_uart_rst.VPWR =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_uart_rst.VPB  =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_uart_rst.VGND =VSS;
+	force uut.mprj.u_wb_host.u_buf_uart_rst.VNB = VSS;
+
+	force uut.mprj.u_wb_host.u_buf_i2cm_rst.VPWR =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_i2cm_rst.VPB  =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_i2cm_rst.VGND =VSS;
+	force uut.mprj.u_wb_host.u_buf_i2cm_rst.VNB = VSS;
+
+	force uut.mprj.u_wb_host.u_buf_uart_i2c_sel.VPWR =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_uart_i2c_sel.VPB  =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_uart_i2c_sel.VGND =VSS;
+	force uut.mprj.u_wb_host.u_buf_uart_i2c_sel.VNB = VSS;
+
 	force uut.mprj.u_wb_host.u_clkbuf_sdram.VPWR =USER_VDD1V8;
 	force uut.mprj.u_wb_host.u_clkbuf_sdram.VPB  =USER_VDD1V8;
 	force uut.mprj.u_wb_host.u_clkbuf_sdram.VGND =VSS;
diff --git a/verilog/dv/user_i2cm/Makefile b/verilog/dv/user_i2cm/Makefile
new file mode 100644
index 0000000..7955725
--- /dev/null
+++ b/verilog/dv/user_i2cm/Makefile
@@ -0,0 +1,97 @@
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+## Caravel Pointers
+CARAVEL_ROOT ?= ../../../caravel
+CARAVEL_PATH ?= $(CARAVEL_ROOT)
+CARAVEL_FIRMWARE_PATH = $(CARAVEL_PATH)/verilog/dv/caravel
+CARAVEL_VERILOG_PATH  = $(CARAVEL_PATH)/verilog
+CARAVEL_RTL_PATH = $(CARAVEL_VERILOG_PATH)/rtl
+CARAVEL_BEHAVIOURAL_MODELS = $(CARAVEL_VERILOG_PATH)/dv/caravel
+
+
+## User Project Pointers
+UPRJ_VERILOG_PATH ?= ../../../verilog
+UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
+UPRJ_GL_PATH = $(UPRJ_VERILOG_PATH)/gl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_BEHAVIOURAL_AGENTS = ../agents
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
+
+## SYNTACORE FIRMWARE
+SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
+GCC64_PREFIX?=riscv64-unknown-elf
+
+## RISCV GCC 
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv32-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+
+.SUFFIXES:
+
+PATTERN = user_i2cm
+
+all:  ${PATTERN:=.vcd}
+
+hex:  ${PATTERN:=.hex}
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+	riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common  user_uart.c -o user_uart.o
+	riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -D__ASSEMBLY__=1 -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common/  ../../rtl/syntacore/scr1/sim/tests/common/crt_tcm.S -o crt_tcm.o
+	riscv64-unknown-elf-gcc -o user_uart.elf -T ../../rtl/syntacore/scr1/sim/tests/common/link_tcm.ld user_uart.o crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32
+	riscv64-unknown-elf-objcopy -O verilog user_uart.elf user_uart.hex
+	riscv64-unknown-elf-objdump -D user_uart.elf > user_uart.dump
+	rm crt_tcm.o user_uart.o
+ifeq ($(SIM),RTL)
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
+	$< -o $@ 
+else  
+	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \
+	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
+	$< -o $@ 
+endif
+
+%.vcd: %.vvp
+	vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+	${GCC_PREFIX}-gcc -I $(CARAVEL_PATH) -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(CARAVEL_FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(CARAVEL_FIRMWARE_PATH)/start.s $<
+
+%.hex: 
+	echo @"This is user boot test, noting to compile the mangment core code"
+
+%.bin: %.elf
+	${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_i2cm/run_iverilog b/verilog/dv/user_i2cm/run_iverilog
new file mode 100755
index 0000000..3ae1ffd
--- /dev/null
+++ b/verilog/dv/user_i2cm/run_iverilog
@@ -0,0 +1,37 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // SPDX-FileCopyrightText: 2021, Dinesh Annayya
+# // 
+# // Licensed under the Apache License, Version 2.0 (the "License");
+# // you may not use this file except in compliance with the License.
+# // You may obtain a copy of the License at
+# //
+# //      http://www.apache.org/licenses/LICENSE-2.0
+# //
+# // Unless required by applicable law or agreed to in writing, software
+# // distributed under the License is distributed on an "AS IS" BASIS,
+# // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# // See the License for the specific language governing permissions and
+# // limitations under the License.
+# // SPDX-License-Identifier: Apache-2.0
+# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common  user_uart.c -o user_uart.o
+
+riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las  -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\"  -D__ASSEMBLY__=1 -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common/  ../../rtl/syntacore/scr1/sim/tests/common/crt_tcm.S -o crt_tcm.o
+
+riscv64-unknown-elf-gcc -o user_uart.elf -T ../../rtl/syntacore/scr1/sim/tests/common/link_tcm.ld user_uart.o crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32
+
+riscv64-unknown-elf-objcopy -O verilog user_uart.elf user_uart.hex
+
+riscv64-unknown-elf-objdump -D user_uart.elf > user_uart.dump
+
+rm crt_tcm.o user_uart.o
+
+#iverilog with waveform dump
+iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/rtl -I ../ -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I ../../../verilog/rtl/i2cm/src/includes -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_i2cm_tb.v -o user_i2cm_tb.vvp
+
+
+
+vvp user_i2cm_tb.vvp | tee test.log
+
+\rm -rf user_i2cm_tb.vvp
diff --git a/verilog/dv/user_i2cm/uprj_netlists.v b/verilog/dv/user_i2cm/uprj_netlists.v
new file mode 100644
index 0000000..bea5a49
--- /dev/null
+++ b/verilog/dv/user_i2cm/uprj_netlists.v
@@ -0,0 +1,130 @@
+// SPDX-FileCopyrightText: 2020 Efabless Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+
+// Include caravel global defines for the number of the user project IO pads 
+`include "defines.v"
+       `define USE_POWER_PINS
+       `define UNIT_DELAY #0.1
+
+`ifdef GL
+       `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
+       `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
+       `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
+       `include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v"
+       `include "libs.ref//sky130_fd_sc_hd/verilog/sky130_ef_sc_hd__fakediode_2.v"
+
+        `include "glbl_cfg.v"
+        `include "sdram.v"
+        `include "spi_master.v"
+        `include "uart_i2cm.v"
+        `include "wb_interconnect.v"
+        `include "user_project_wrapper.v"
+        `include "syntacore.v"
+        `include "wb_host.v"
+	`include "clk_skew_adjust.v"
+	`include "clk_buf.v"
+
+`else
+     `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
+     `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
+     `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
+     `include "libs.ref/sky130_fd_sc_hvl/verilog/sky130_fd_sc_hvl.v"
+
+
+     `include "spi_master/src/spim_top.sv"
+     `include "spi_master/src/spim_if.sv"
+     `include "spi_master/src/spim_fifo.sv"
+     `include "spi_master/src/spim_regs.sv"
+     `include "spi_master/src/spim_clkgen.sv"
+     `include "spi_master/src/spim_ctrl.sv"
+     `include "spi_master/src/spim_rx.sv"
+     `include "spi_master/src/spim_tx.sv"
+
+     `include "uart/src/uart_core.sv"
+     `include "uart/src/uart_cfg.sv"
+     `include "uart/src/uart_rxfsm.sv"
+     `include "uart/src/uart_txfsm.sv"
+     `include "lib/async_fifo_th.sv"  
+     `include "lib/reset_sync.sv"  
+     `include "lib/double_sync_low.v"  
+     `include "lib/clk_buf.v"  
+
+     `include "i2cm/src/core/i2cm_bit_ctrl.v"
+     `include "i2cm/src/core/i2cm_byte_ctrl.v"
+     `include "i2cm/src/core/i2cm_top.v"
+
+     `include "uart_i2c/src/uart_i2c_top.sv"
+
+     `include "sdram_ctrl/src/top/sdrc_top.v" 
+     `include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v" 
+     `include "lib/async_fifo.sv"  
+     `include "sdram_ctrl/src/core/sdrc_core.v"
+     `include "sdram_ctrl/src/core/sdrc_bank_ctl.v"
+     `include "sdram_ctrl/src/core/sdrc_bank_fsm.v"
+     `include "sdram_ctrl/src/core/sdrc_bs_convert.v"
+     `include "sdram_ctrl/src/core/sdrc_req_gen.v"
+     `include "sdram_ctrl/src/core/sdrc_xfr_ctl.v"
+
+     `include "lib/registers.v"
+     `include "lib/clk_ctl.v"
+     `include "digital_core/src/glbl_cfg.sv"
+
+     `include "wb_host/src/wb_host.sv"
+     `include "lib/async_wb.sv"
+
+     `include "lib/wb_stagging.sv"
+     `include "wb_interconnect/src/wb_arb.sv"
+     `include "wb_interconnect/src/wb_interconnect.sv"
+
+
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_hdu.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_tdu.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_ipic.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_csr.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_exu.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_ialu.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_idu.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_ifu.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_lsu.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_mprf.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_mul.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_div.sv"
+     `include "syntacore/scr1/src/core/pipeline/scr1_pipe_top.sv"
+     `include "syntacore/scr1/src/core/primitives/scr1_reset_cells.sv"
+     `include "syntacore/scr1/src/core/primitives/scr1_cg.sv"
+     `include "syntacore/scr1/src/core/scr1_clk_ctrl.sv"
+     `include "syntacore/scr1/src/core/scr1_tapc_shift_reg.sv"
+     `include "syntacore/scr1/src/core/scr1_tapc.sv"
+     `include "syntacore/scr1/src/core/scr1_tapc_synchronizer.sv"
+     `include "syntacore/scr1/src/core/scr1_core_top.sv"
+     `include "syntacore/scr1/src/core/scr1_dm.sv"
+     `include "syntacore/scr1/src/core/scr1_dmi.sv"
+     `include "syntacore/scr1/src/core/scr1_scu.sv"
+      
+     `include "syntacore/scr1/src/top/scr1_dmem_router.sv"
+     `include "syntacore/scr1/src/top/scr1_dp_memory.sv"
+     `include "syntacore/scr1/src/top/scr1_tcm.sv"
+     `include "syntacore/scr1/src/top/scr1_timer.sv"
+     `include "syntacore/scr1/src/top/scr1_dmem_wb.sv"
+     `include "syntacore/scr1/src/top/scr1_imem_wb.sv"
+     `include "syntacore/scr1/src/top/scr1_intf.sv"
+     `include "syntacore/scr1/src/top/scr1_top_wb.sv"
+     `include "lib/sync_fifo.sv"
+
+     `include "user_project_wrapper.v"
+     // we are using netlist file for clk_skew_adjust as it has 
+     // standard cell + power pin
+     `include "gl/clk_skew_adjust.v"
+`endif
diff --git a/verilog/dv/user_i2cm/user_i2cm_tb.v b/verilog/dv/user_i2cm/user_i2cm_tb.v
new file mode 100644
index 0000000..b518419
--- /dev/null
+++ b/verilog/dv/user_i2cm/user_i2cm_tb.v
@@ -0,0 +1,700 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText:  2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  Standalone User validation Test bench                       ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////                                                              ////
+////  Description                                                 ////
+////   This is a standalone test bench to validate the            ////
+////   i2c Master .                                               ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////    0.1 - 16th Feb 2021, Dinesh A                             ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ns
+
+`include "s25fl256s.sv"
+`include "uprj_netlists.v"
+`include "mt48lc8m8a2.v"
+`include "i2c_slave_model.v"
+
+
+`define ADDR_SPACE_UART  32'h3001_0000
+`define ADDR_SPACE_I2CM  32'h3001_0000
+
+
+module tb_top;
+
+reg            clock         ;
+reg            wb_rst_i      ;
+reg            power1, power2;
+reg            power3, power4;
+
+reg            wbd_ext_cyc_i;  // strobe/request
+reg            wbd_ext_stb_i;  // strobe/request
+reg [31:0]     wbd_ext_adr_i;  // address
+reg            wbd_ext_we_i;  // write
+reg [31:0]     wbd_ext_dat_i;  // data output
+reg [3:0]      wbd_ext_sel_i;  // byte enable
+
+wire [31:0]    wbd_ext_dat_o;  // data input
+wire           wbd_ext_ack_o;  // acknowlegement
+wire           wbd_ext_err_o;  // error
+
+// User I/O
+wire [37:0]    io_oeb        ;
+wire [37:0]    io_out        ;
+wire [37:0]    io_in         ;
+
+wire [37:0]    mprj_io       ;
+wire [7:0]     mprj_io_0     ;
+reg            test_fail     ;
+reg [31:0]     read_data     ;
+//----------------------------------
+// Uart Configuration
+// ---------------------------------
+
+integer i,j;
+
+	// External clock is used by default.  Make this artificially fast for the
+	// simulation.  Normally this would be a slow clock and the digital PLL
+	// would be the fast clock.
+
+	always #12.5 clock <= (clock === 1'b0);
+
+	initial begin
+		clock = 0;
+                wbd_ext_cyc_i ='h0;  // strobe/request
+                wbd_ext_stb_i ='h0;  // strobe/request
+                wbd_ext_adr_i ='h0;  // address
+                wbd_ext_we_i  ='h0;  // write
+                wbd_ext_dat_i ='h0;  // data output
+                wbd_ext_sel_i ='h0;  // byte enable
+	end
+
+	`ifdef WFDUMP
+	   initial begin
+	   	$dumpfile("tb_top.vcd");
+	   	$dumpvars(0, tb_top);
+	   end
+       `endif
+
+	initial begin
+		wb_rst_i <= 1'b1;
+		#100;
+		wb_rst_i <= 1'b0;	    	// Release reset
+	end
+initial
+begin
+   test_fail = 0;
+
+   #200; // Wait for reset removal
+   repeat (10) @(posedge clock);
+   $display("############################################");
+   $display("   Testing I2CM Read/Write Access           ");
+   $display("############################################");
+   
+
+   repeat (10) @(posedge clock);
+   #1;
+   // Enable I2M Block & WB Reset and Enable I2CM Mux Select
+   wb_user_core_write('h3080_0000,'hA1);
+
+   repeat (100) @(posedge clock);  
+
+    @(posedge  clock);
+    $display("---------- Initialize I2C Master ----------"); 
+
+    //Wrire Prescale registers
+     wb_user_core_write(`ADDR_SPACE_I2CM+(8'h0<<2),8'hC7);  
+     wb_user_core_write(`ADDR_SPACE_I2CM+(8'h1<<2),8'h00);  
+    // Core Enable
+     wb_user_core_write(`ADDR_SPACE_I2CM+(8'h2<<2),8'h80);  
+    
+    // Writing Data
+
+    $display("---------- Writing Data ----------"); 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h20); // Slave Addr + WR  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h90);  
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+     
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h66);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h10);  
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+   
+   /* Byte1: 12 */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h12);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h10); // No Stop + Write  
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+   
+   /* Byte1: 34 */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h34);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h10); // No Stop + Write 
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+   /* Byte1: 56 */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h56);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h10); // No Stop + Write 
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+   /* Byte1: 78 */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h78);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h50); // Stop + Write 
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Reading Data
+    
+    //Wrire Address
+    $display("---------- Writing Data ----------"); 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h20);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h90);  
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+     
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h66);  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h50);  
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Generate Read
+    $display("---------- Writing Data ----------"); 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h3<<2),8'h21); // Slave Addr + RD  
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h90);  
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    /* BYTE-1 : 0x12  */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h20);  // RD + ACK
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Compare received data
+    wb_user_core_read_cmp(`ADDR_SPACE_I2CM+(8'h3<<2),8'h12);  
+     
+    /* BYTE-2 : 0x34  */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h20);  // RD + ACK
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Compare received data
+    wb_user_core_read_cmp(`ADDR_SPACE_I2CM+(8'h3<<2),8'h34);  
+
+    /* BYTE-3 : 0x56  */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4 <<2),8'h20);  // RD + ACK
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4<<2),read_data);  
+
+    //Compare received data
+    wb_user_core_read_cmp(`ADDR_SPACE_I2CM+(8'h3<<2),8'h56);  
+
+    /* BYTE-4 : 0x78  */ 
+    wb_user_core_write(`ADDR_SPACE_I2CM+(8'h4<<2),8'h68);  // STOP + RD + NACK 
+
+    read_data[1] = 1'b1;
+    while(read_data[1]==1)
+      wb_user_core_read(`ADDR_SPACE_I2CM+(8'h4 <<2),read_data);  
+
+    //Compare received data
+    wb_user_core_read_cmp(`ADDR_SPACE_I2CM+(8'h3 <<2),8'h78);  
+
+    repeat(100)@(posedge clock);
+
+
+
+     $display("###################################################");
+     if(test_fail == 0) begin
+        `ifdef GL
+            $display("Monitor: Standalone User I2M Test (GL) Passed");
+        `else
+            $display("Monitor: Standalone User I2M Test (RTL) Passed");
+        `endif
+     end else begin
+         `ifdef GL
+             $display("Monitor: Standalone User I2M Test (GL) Failed");
+         `else
+             $display("Monitor: Standalone User I2M Test (RTL) Failed");
+         `endif
+      end
+     $display("###################################################");
+     #100
+     $finish;
+end
+
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+    .vccd1(USER_VDD1V8),	// User area 1 1.8V supply
+    .vssd1(VSS),	// User area 1 digital ground
+`endif
+    .wb_clk_i        (clock),  // System clock
+    .user_clock2     (1'b1),  // Real-time clock
+    .wb_rst_i        (wb_rst_i),  // Regular Reset signal
+
+    .wbs_cyc_i   (wbd_ext_cyc_i),  // strobe/request
+    .wbs_stb_i   (wbd_ext_stb_i),  // strobe/request
+    .wbs_adr_i   (wbd_ext_adr_i),  // address
+    .wbs_we_i    (wbd_ext_we_i),  // write
+    .wbs_dat_i   (wbd_ext_dat_i),  // data output
+    .wbs_sel_i   (wbd_ext_sel_i),  // byte enable
+
+    .wbs_dat_o   (wbd_ext_dat_o),  // data input
+    .wbs_ack_o   (wbd_ext_ack_o),  // acknowlegement
+
+ 
+    // Logic Analyzer Signals
+    .la_data_in      ('0) ,
+    .la_data_out     (),
+    .la_oenb         ('0),
+ 
+
+    // IOs
+    .io_in          (io_in)  ,
+    .io_out         (io_out) ,
+    .io_oeb         (io_oeb) ,
+
+    .user_irq       () 
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+    // All standard cell need power hook-up for functionality work
+    initial begin
+	force u_top.u_spi_master.u_delay1_sdio0.VPWR =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay1_sdio0.VPB  =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay1_sdio0.VGND =VSS;
+	force u_top.u_spi_master.u_delay1_sdio0.VNB = VSS;
+	force u_top.u_spi_master.u_delay2_sdio0.VPWR =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay2_sdio0.VPB  =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay2_sdio0.VGND =VSS;
+	force u_top.u_spi_master.u_delay2_sdio0.VNB = VSS;
+	force u_top.u_spi_master.u_buf_sdio0.VPWR   =USER_VDD1V8;
+	force u_top.u_spi_master.u_buf_sdio0.VPB    =USER_VDD1V8;
+	force u_top.u_spi_master.u_buf_sdio0.VGND   =VSS;
+	force u_top.u_spi_master.u_buf_sdio0.VNB    =VSS;
+
+	force u_top.u_spi_master.u_delay1_sdio1.VPWR =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay1_sdio1.VPB  =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay1_sdio1.VGND =VSS;
+	force u_top.u_spi_master.u_delay1_sdio1.VNB = VSS;
+	force u_top.u_spi_master.u_delay2_sdio1.VPWR =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay2_sdio1.VPB  =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay2_sdio1.VGND =VSS;
+	force u_top.u_spi_master.u_delay2_sdio1.VNB = VSS;
+	force u_top.u_spi_master.u_buf_sdio1.VPWR   =USER_VDD1V8;
+	force u_top.u_spi_master.u_buf_sdio1.VPB    =USER_VDD1V8;
+	force u_top.u_spi_master.u_buf_sdio1.VGND   =VSS;
+	force u_top.u_spi_master.u_buf_sdio1.VNB    =VSS;
+
+	force u_top.u_spi_master.u_delay1_sdio2.VPWR =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay1_sdio2.VPB  =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay1_sdio2.VGND =VSS;
+	force u_top.u_spi_master.u_delay1_sdio2.VNB = VSS;
+	force u_top.u_spi_master.u_delay2_sdio2.VPWR =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay2_sdio2.VPB  =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay2_sdio2.VGND =VSS;
+	force u_top.u_spi_master.u_delay2_sdio2.VNB = VSS;
+	force u_top.u_spi_master.u_buf_sdio2.VPWR   =USER_VDD1V8;
+	force u_top.u_spi_master.u_buf_sdio2.VPB    =USER_VDD1V8;
+	force u_top.u_spi_master.u_buf_sdio2.VGND   =VSS;
+	force u_top.u_spi_master.u_buf_sdio2.VNB    =VSS;
+
+	force u_top.u_spi_master.u_delay1_sdio3.VPWR =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay1_sdio3.VPB  =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay1_sdio3.VGND =VSS;
+	force u_top.u_spi_master.u_delay1_sdio3.VNB = VSS;
+	force u_top.u_spi_master.u_delay2_sdio3.VPWR =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay2_sdio3.VPB  =USER_VDD1V8;
+	force u_top.u_spi_master.u_delay2_sdio3.VGND =VSS;
+	force u_top.u_spi_master.u_delay2_sdio3.VNB = VSS;
+	force u_top.u_spi_master.u_buf_sdio3.VPWR   =USER_VDD1V8;
+	force u_top.u_spi_master.u_buf_sdio3.VPB    =USER_VDD1V8;
+	force u_top.u_spi_master.u_buf_sdio3.VGND   =VSS;
+	force u_top.u_spi_master.u_buf_sdio3.VNB    =VSS;
+          
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VGND =VSS;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_wb_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_wb_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_wb_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_wb_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_cpu_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_cpu_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_cpu_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_cpu_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_spi_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_spi_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_spi_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_spi_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_sdram_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_sdram_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_sdram_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_sdram_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_uart_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_uart_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_i2cm_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VGND =VSS;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VNB = VSS;
+
+	force u_top.u_wb_host.u_clkbuf_sdram.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_clkbuf_sdram.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_clkbuf_sdram.VGND =VSS;
+	force u_top.u_wb_host.u_clkbuf_sdram.VNB = VSS;
+
+	force u_top.u_wb_host.u_clkbuf_cpu.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_clkbuf_cpu.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_clkbuf_cpu.VGND =VSS;
+	force u_top.u_wb_host.u_clkbuf_cpu.VNB = VSS;
+
+	force u_top.u_wb_host.u_clkbuf_rtc.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_clkbuf_rtc.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_clkbuf_rtc.VGND =VSS;
+	force u_top.u_wb_host.u_clkbuf_rtc.VNB = VSS;
+
+    end
+`endif    
+//------------------------------------------------------
+//  Integrate the Serial flash with qurd support to
+//  user core using the gpio pads
+//  ----------------------------------------------------
+
+   wire flash_clk = io_out[30];
+   wire flash_csb = io_out[31];
+   // Creating Pad Delay
+   wire #1 io_oeb_32 = io_oeb[32];
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   tri  flash_io0 = (io_oeb_32== 1'b0) ? io_out[32] : 1'bz;
+   tri  flash_io1 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  flash_io2 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  flash_io3 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+
+   assign io_in[32] = flash_io0;
+   assign io_in[33] = flash_io1;
+   assign io_in[34] = flash_io2;
+   assign io_in[35] = flash_io3;
+
+
+   // Quard flash
+     s25fl256s #(.mem_file_name("user_uart.hex"),
+	         .otp_file_name("none"), 
+                 .TimingModel("S25FL512SAGMFI010_F_30pF")) 
+		 u_spi_flash_256mb
+       (
+           // Data Inputs/Outputs
+       .SI      (flash_io0),
+       .SO      (flash_io1),
+       // Controls
+       .SCK     (flash_clk),
+       .CSNeg   (flash_csb),
+       .WPNeg   (flash_io2),
+       .HOLDNeg (flash_io3),
+       .RSTNeg  (!wb_rst_i)
+
+       );
+
+
+
+//------------------------------------------------
+// Integrate the SDRAM 8 BIT Memory
+// -----------------------------------------------
+
+wire [7:0]    Dq                 ; // SDRAM Read/Write Data Bus
+wire [0:0]    sdr_dqm            ; // SDRAM DATA Mask
+wire [1:0]    sdr_ba             ; // SDRAM Bank Select
+wire [12:0]   sdr_addr           ; // SDRAM ADRESS
+wire          sdr_cs_n           ; // chip select
+wire          sdr_cke            ; // clock gate
+wire          sdr_ras_n          ; // ras
+wire          sdr_cas_n          ; // cas
+wire          sdr_we_n           ; // write enable        
+wire          sdram_clk         ;      
+
+assign  Dq[7:0]           =  (io_oeb[7:0] == 8'h0) ? io_out [7:0] : 8'hZZ;
+assign  sdr_addr[12:0]    =    io_out [20:8]     ;
+assign  sdr_ba[1:0]       =    io_out [22:21]    ;
+assign  sdr_dqm[0]        =    io_out [23]       ;
+assign  sdr_we_n          =    io_out [24]       ;
+assign  sdr_cas_n         =    io_out [25]       ;
+assign  sdr_ras_n         =    io_out [26]       ;
+assign  sdr_cs_n          =    io_out [27]       ;
+assign  sdr_cke           =    io_out [28]       ;
+assign  sdram_clk         =    io_out [29]       ;
+assign  io_in[29]         =    sdram_clk;
+assign  #(1) io_in[7:0]   =    Dq;
+
+// to fix the sdram interface timing issue
+wire #(1) sdram_clk_d   = sdram_clk;
+
+	// SDRAM 8bit
+mt48lc8m8a2 #(.data_bits(8)) u_sdram8 (
+          .Dq                 (Dq                 ) , 
+          .Addr               (sdr_addr[11:0]     ), 
+          .Ba                 (sdr_ba             ), 
+          .Clk                (sdram_clk_d        ), 
+          .Cke                (sdr_cke            ), 
+          .Cs_n               (sdr_cs_n           ), 
+          .Ras_n              (sdr_ras_n          ), 
+          .Cas_n              (sdr_cas_n          ), 
+          .We_n               (sdr_we_n           ), 
+          .Dqm                (sdr_dqm            )
+     );
+
+
+//---------------------------
+//  UART Agent integration
+// --------------------------
+tri scl,sda;
+
+assign scl   = (io_oeb[36] == 1'b0) ? io_out[36]: 1'bz;
+assign sda  =  (io_oeb[37] == 1'b0) ? io_out[37] : 1'bz;
+assign io_in[37]  =  sda;
+assign io_in[36]  =  scl;
+
+pullup p1(scl); // pullup scl line
+pullup p2(sda); // pullup sda line
+
+ 
+i2c_slave_model u_i2c_slave (
+	.scl   (scl), 
+	.sda   (sda)
+       );
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h1;  // write
+  wbd_ext_dat_i =data;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  //$display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+  repeat (2) @(posedge clock);
+end
+endtask
+
+task  wb_user_core_read_cmp;
+input [31:0] address;
+input [31:0] cmp_data;
+reg    [31:0] data;
+begin
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_adr_i =address;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='0;  // data output
+  wbd_ext_sel_i ='hF;  // byte enable
+  wbd_ext_cyc_i ='h1;  // strobe/request
+  wbd_ext_stb_i ='h1;  // strobe/request
+  wait(wbd_ext_ack_o == 1);
+  data  = wbd_ext_dat_o;  
+  repeat (1) @(posedge clock);
+  #1;
+  wbd_ext_cyc_i ='h0;  // strobe/request
+  wbd_ext_stb_i ='h0;  // strobe/request
+  wbd_ext_adr_i ='h0;  // address
+  wbd_ext_we_i  ='h0;  // write
+  wbd_ext_dat_i ='h0;  // data output
+  wbd_ext_sel_i ='h0;  // byte enable
+  if(data === cmp_data) begin
+     $display("STATUS: DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+  end else begin
+     $display("ERROR: DEBUG WB USER ACCESS READ Address : %x, Exp Data : %x Rxd Data: ",address,cmp_data,data);
+     test_fail= 1;
+     #100
+     $finish;
+  end
+  repeat (2) @(posedge clock);
+end
+endtask
+
+`ifdef GL
+
+wire        wbd_spi_stb_i   = u_top.u_spi_master.wbd_stb_i;
+wire        wbd_spi_ack_o   = u_top.u_spi_master.wbd_ack_o;
+wire        wbd_spi_we_i    = u_top.u_spi_master.wbd_we_i;
+wire [31:0] wbd_spi_adr_i   = u_top.u_spi_master.wbd_adr_i;
+wire [31:0] wbd_spi_dat_i   = u_top.u_spi_master.wbd_dat_i;
+wire [31:0] wbd_spi_dat_o   = u_top.u_spi_master.wbd_dat_o;
+wire [3:0]  wbd_spi_sel_i   = u_top.u_spi_master.wbd_sel_i;
+
+wire        wbd_sdram_stb_i = u_top.u_sdram_ctrl.wb_stb_i;
+wire        wbd_sdram_ack_o = u_top.u_sdram_ctrl.wb_ack_o;
+wire        wbd_sdram_we_i  = u_top.u_sdram_ctrl.wb_we_i;
+wire [31:0] wbd_sdram_adr_i = u_top.u_sdram_ctrl.wb_addr_i;
+wire [31:0] wbd_sdram_dat_i = u_top.u_sdram_ctrl.wb_dat_i;
+wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
+wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
+
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c.u_uart_core.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c.u_uart_core.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c.u_uart_core.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c.u_uart_core.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c.u_uart_core.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c.u_uart_core.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c.u_uart_core.reg_be;
+
+`endif
+
+/**
+`ifdef GL
+//-----------------------------------------------------------------------------
+// RISC IMEM amd DMEM Monitoring TASK
+//-----------------------------------------------------------------------------
+
+`define RISC_CORE  user_uart_tb.u_top.u_core.u_riscv_top
+
+always@(posedge `RISC_CORE.wb_clk) begin
+    if(`RISC_CORE.wbd_imem_ack_i)
+          $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x", `RISC_CORE.wbd_imem_adr_o,`RISC_CORE.wbd_imem_dat_i);
+    if(`RISC_CORE.wbd_dmem_ack_i && `RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_o);
+    if(`RISC_CORE.wbd_dmem_ack_i && !`RISC_CORE.wbd_dmem_we_o)
+          $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", `RISC_CORE.wbd_dmem_adr_o,`RISC_CORE.wbd_dmem_dat_i);
+end
+
+`endif
+**/
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_i2cm/user_uart.c b/verilog/dv/user_i2cm/user_uart.c
new file mode 100644
index 0000000..b60311c
--- /dev/null
+++ b/verilog/dv/user_i2cm/user_uart.c
@@ -0,0 +1,59 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021, Dinesh Annayya
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org>
+// //////////////////////////////////////////////////////////////////////////
+#define SC_SIM_OUTPORT (0xf0000000)
+#define uint32_t  long
+
+#define reg_mprj_globl_reg0  (*(volatile uint32_t*)0x30000000)
+#define reg_mprj_globl_reg1  (*(volatile uint32_t*)0x30000004)
+#define reg_mprj_globl_reg2  (*(volatile uint32_t*)0x30000008)
+#define reg_mprj_globl_reg3  (*(volatile uint32_t*)0x3000000C)
+#define reg_mprj_globl_reg4  (*(volatile uint32_t*)0x30000010)
+#define reg_mprj_globl_reg5  (*(volatile uint32_t*)0x30000014)
+#define reg_mprj_globl_reg6  (*(volatile uint32_t*)0x30000018)
+#define reg_mprj_globl_reg7  (*(volatile uint32_t*)0x3000001C)
+#define reg_mprj_globl_reg8  (*(volatile uint32_t*)0x30000020)
+#define reg_mprj_globl_reg9  (*(volatile uint32_t*)0x30000024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x30000028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x3000002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x30000030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x30000034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x30000038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x3000003C)
+
+#define reg_mprj_uart_reg0 (*(volatile uint32_t*)0x30010000)
+#define reg_mprj_uart_reg1 (*(volatile uint32_t*)0x30010004)
+#define reg_mprj_uart_reg2 (*(volatile uint32_t*)0x30010008)
+#define reg_mprj_uart_reg3 (*(volatile uint32_t*)0x3001000C)
+#define reg_mprj_uart_reg4 (*(volatile uint32_t*)0x30010010)
+#define reg_mprj_uart_reg5 (*(volatile uint32_t*)0x30010014)
+#define reg_mprj_uart_reg6 (*(volatile uint32_t*)0x30010018)
+#define reg_mprj_uart_reg7 (*(volatile uint32_t*)0x3001001C)
+#define reg_mprj_uart_reg8 (*(volatile uint32_t*)0x30010020)
+
+int main()
+{
+
+    while(1) {
+       // Check UART RX fifo has data, if available loop back the data
+       if(reg_mprj_uart_reg8 != 0) { 
+	   reg_mprj_uart_reg5 = reg_mprj_uart_reg6;
+       }
+    }
+
+    return 0;
+}
diff --git a/verilog/dv/user_risc_boot/Makefile b/verilog/dv/user_risc_boot/Makefile
index a3a1ac8..79260aa 100644
--- a/verilog/dv/user_risc_boot/Makefile
+++ b/verilog/dv/user_risc_boot/Makefile
@@ -31,6 +31,7 @@
 UPRJ_BEHAVIOURAL_AGENTS = ../agents
 UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
 UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
 
 ## SYNTACORE FIRMWARE
 SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
@@ -66,7 +67,7 @@
 	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
 	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
 	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
-	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
 	$< -o $@ 
 else  
 	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/user_risc_boot/uprj_netlists.v b/verilog/dv/user_risc_boot/uprj_netlists.v
index ea393bf..bea5a49 100644
--- a/verilog/dv/user_risc_boot/uprj_netlists.v
+++ b/verilog/dv/user_risc_boot/uprj_netlists.v
@@ -15,11 +15,10 @@
 
 // Include caravel global defines for the number of the user project IO pads 
 `include "defines.v"
-`define USE_POWER_PINS
-`define UNIT_DELAY #0.1
+       `define USE_POWER_PINS
+       `define UNIT_DELAY #0.1
 
 `ifdef GL
-
        `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
        `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
        `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
@@ -29,7 +28,7 @@
         `include "glbl_cfg.v"
         `include "sdram.v"
         `include "spi_master.v"
-        `include "uart.v"
+        `include "uart_i2cm.v"
         `include "wb_interconnect.v"
         `include "user_project_wrapper.v"
         `include "syntacore.v"
@@ -38,7 +37,6 @@
 	`include "clk_buf.v"
 
 `else
-
      `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
      `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
      `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
@@ -63,6 +61,12 @@
      `include "lib/double_sync_low.v"  
      `include "lib/clk_buf.v"  
 
+     `include "i2cm/src/core/i2cm_bit_ctrl.v"
+     `include "i2cm/src/core/i2cm_byte_ctrl.v"
+     `include "i2cm/src/core/i2cm_top.v"
+
+     `include "uart_i2c/src/uart_i2c_top.sv"
+
      `include "sdram_ctrl/src/top/sdrc_top.v" 
      `include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v" 
      `include "lib/async_fifo.sv"  
diff --git a/verilog/dv/user_risc_boot/user_risc_boot_tb.v b/verilog/dv/user_risc_boot/user_risc_boot_tb.v
index e11cffd..0f0cf53 100644
--- a/verilog/dv/user_risc_boot/user_risc_boot_tb.v
+++ b/verilog/dv/user_risc_boot/user_risc_boot_tb.v
@@ -307,10 +307,10 @@
 	force u_top.u_spi_master.u_buf_sdio3.VGND   =VSS;
 	force u_top.u_spi_master.u_buf_sdio3.VNB    =VSS;
           
-	force u_top.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
-	force u_top.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
-	force u_top.u_uart_core.u_lineclk_buf.VGND =VSS;
-	force u_top.u_uart_core.u_lineclk_buf.VNB = VSS;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VGND =VSS;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VNB = VSS;
 
 	force u_top.u_wb_host.u_buf_wb_rst.VPWR =USER_VDD1V8;
 	force u_top.u_wb_host.u_buf_wb_rst.VPB  =USER_VDD1V8;
@@ -332,6 +332,21 @@
 	force u_top.u_wb_host.u_buf_sdram_rst.VGND =VSS;
 	force u_top.u_wb_host.u_buf_sdram_rst.VNB = VSS;
 
+	force u_top.u_wb_host.u_buf_uart_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_uart_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_i2cm_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VGND =VSS;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VNB = VSS;
+
 	force u_top.u_wb_host.u_clkbuf_sdram.VPWR =USER_VDD1V8;
 	force u_top.u_wb_host.u_clkbuf_sdram.VPB  =USER_VDD1V8;
 	force u_top.u_wb_host.u_clkbuf_sdram.VGND =VSS;
@@ -509,13 +524,13 @@
 wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
 wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
 
-wire        wbd_uart_stb_i  = u_top.u_uart_core.reg_cs;
-wire        wbd_uart_ack_o  = u_top.u_uart_core.reg_ack;
-wire        wbd_uart_we_i   = u_top.u_uart_core.reg_wr;
-wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_core.reg_addr;
-wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_core.reg_wdata;
-wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_core.reg_rdata;
-wire        wbd_uart_sel_i  = u_top.u_uart_core.reg_be;
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c.u_uart_core.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c.u_uart_core.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c.u_uart_core.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c.u_uart_core.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c.u_uart_core.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c.u_uart_core.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c.u_uart_core.reg_be;
 
 `endif
 
diff --git a/verilog/dv/user_spi/Makefile b/verilog/dv/user_spi/Makefile
index 7fca4c3..04cb921 100644
--- a/verilog/dv/user_spi/Makefile
+++ b/verilog/dv/user_spi/Makefile
@@ -31,6 +31,7 @@
 UPRJ_BEHAVIOURAL_AGENTS = ../agents
 UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
 UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
 
 ## SYNTACORE FIRMWARE
 SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
@@ -66,7 +67,7 @@
 	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
 	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
 	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
-	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
 	$< -o $@ 
 else  
 	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/user_spi/uprj_netlists.v b/verilog/dv/user_spi/uprj_netlists.v
index ea393bf..bea5a49 100644
--- a/verilog/dv/user_spi/uprj_netlists.v
+++ b/verilog/dv/user_spi/uprj_netlists.v
@@ -15,11 +15,10 @@
 
 // Include caravel global defines for the number of the user project IO pads 
 `include "defines.v"
-`define USE_POWER_PINS
-`define UNIT_DELAY #0.1
+       `define USE_POWER_PINS
+       `define UNIT_DELAY #0.1
 
 `ifdef GL
-
        `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
        `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
        `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
@@ -29,7 +28,7 @@
         `include "glbl_cfg.v"
         `include "sdram.v"
         `include "spi_master.v"
-        `include "uart.v"
+        `include "uart_i2cm.v"
         `include "wb_interconnect.v"
         `include "user_project_wrapper.v"
         `include "syntacore.v"
@@ -38,7 +37,6 @@
 	`include "clk_buf.v"
 
 `else
-
      `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
      `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
      `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
@@ -63,6 +61,12 @@
      `include "lib/double_sync_low.v"  
      `include "lib/clk_buf.v"  
 
+     `include "i2cm/src/core/i2cm_bit_ctrl.v"
+     `include "i2cm/src/core/i2cm_byte_ctrl.v"
+     `include "i2cm/src/core/i2cm_top.v"
+
+     `include "uart_i2c/src/uart_i2c_top.sv"
+
      `include "sdram_ctrl/src/top/sdrc_top.v" 
      `include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v" 
      `include "lib/async_fifo.sv"  
diff --git a/verilog/dv/user_spi/user_spi_tb.v b/verilog/dv/user_spi/user_spi_tb.v
index 17d3292..ca0fd97 100644
--- a/verilog/dv/user_spi/user_spi_tb.v
+++ b/verilog/dv/user_spi/user_spi_tb.v
@@ -1169,10 +1169,10 @@
 	force u_top.u_spi_master.u_buf_sdio3.VGND   =VSS;
 	force u_top.u_spi_master.u_buf_sdio3.VNB    =VSS;
           
-	force u_top.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
-	force u_top.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
-	force u_top.u_uart_core.u_lineclk_buf.VGND =VSS;
-	force u_top.u_uart_core.u_lineclk_buf.VNB = VSS;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VGND =VSS;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VNB = VSS;
 
 	force u_top.u_wb_host.u_buf_wb_rst.VPWR =USER_VDD1V8;
 	force u_top.u_wb_host.u_buf_wb_rst.VPB  =USER_VDD1V8;
@@ -1194,6 +1194,21 @@
 	force u_top.u_wb_host.u_buf_sdram_rst.VGND =VSS;
 	force u_top.u_wb_host.u_buf_sdram_rst.VNB = VSS;
 
+	force u_top.u_wb_host.u_buf_uart_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_uart_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_i2cm_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VGND =VSS;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VNB = VSS;
+
 	force u_top.u_wb_host.u_clkbuf_sdram.VPWR =USER_VDD1V8;
 	force u_top.u_wb_host.u_clkbuf_sdram.VPB  =USER_VDD1V8;
 	force u_top.u_wb_host.u_clkbuf_sdram.VGND =VSS;
@@ -1405,13 +1420,13 @@
 wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
 wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
 
-wire        wbd_uart_stb_i  = u_top.u_uart_core.reg_cs;
-wire        wbd_uart_ack_o  = u_top.u_uart_core.reg_ack;
-wire        wbd_uart_we_i   = u_top.u_uart_core.reg_wr;
-wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_core.reg_addr;
-wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_core.reg_wdata;
-wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_core.reg_rdata;
-wire        wbd_uart_sel_i  = u_top.u_uart_core.reg_be;
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c.reg_be;
 
 `endif
 
diff --git a/verilog/dv/user_uart/Makefile b/verilog/dv/user_uart/Makefile
index 1f5b0c3..c9afd5e 100644
--- a/verilog/dv/user_uart/Makefile
+++ b/verilog/dv/user_uart/Makefile
@@ -31,6 +31,7 @@
 UPRJ_BEHAVIOURAL_AGENTS = ../agents
 UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
 UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
 
 ## SYNTACORE FIRMWARE
 SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
@@ -66,7 +67,7 @@
 	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
 	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
 	-I $(UPRJ_BEHAVIOURAL_AGENTS)    \
-	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
 	$< -o $@ 
 else  
 	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/user_uart/run_iverilog b/verilog/dv/user_uart/run_iverilog
index 15548a4..3ce562e 100755
--- a/verilog/dv/user_uart/run_iverilog
+++ b/verilog/dv/user_uart/run_iverilog
@@ -28,7 +28,7 @@
 rm crt_tcm.o user_uart.o
 
 #iverilog with waveform dump
-iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/rtl -I ../ -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $PDK_PATH -I  ../../../caravel/verilog/rtl  -I ../ -I ../../../verilog/rtl -I ../ -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I ../../../verilog/rtl/i2cm/src/includes -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
 
 
 #iverilog -g2005-sv -I $PDK_PATH -DFUNCTIONAL -DSIM -I  ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/rtl -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes   -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
diff --git a/verilog/dv/user_uart/uprj_netlists.v b/verilog/dv/user_uart/uprj_netlists.v
index aedc4d8..bea5a49 100644
--- a/verilog/dv/user_uart/uprj_netlists.v
+++ b/verilog/dv/user_uart/uprj_netlists.v
@@ -28,7 +28,7 @@
         `include "glbl_cfg.v"
         `include "sdram.v"
         `include "spi_master.v"
-        `include "uart.v"
+        `include "uart_i2cm.v"
         `include "wb_interconnect.v"
         `include "user_project_wrapper.v"
         `include "syntacore.v"
@@ -61,6 +61,12 @@
      `include "lib/double_sync_low.v"  
      `include "lib/clk_buf.v"  
 
+     `include "i2cm/src/core/i2cm_bit_ctrl.v"
+     `include "i2cm/src/core/i2cm_byte_ctrl.v"
+     `include "i2cm/src/core/i2cm_top.v"
+
+     `include "uart_i2c/src/uart_i2c_top.sv"
+
      `include "sdram_ctrl/src/top/sdrc_top.v" 
      `include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v" 
      `include "lib/async_fifo.sv"  
diff --git a/verilog/dv/user_uart/user_uart_tb.v b/verilog/dv/user_uart/user_uart_tb.v
index 85c0aa7..c3efb15 100644
--- a/verilog/dv/user_uart/user_uart_tb.v
+++ b/verilog/dv/user_uart/user_uart_tb.v
@@ -150,7 +150,7 @@
 	   initial begin
 	   	$dumpfile("risc_boot.vcd");
 	   	$dumpvars(1, user_uart_tb);
-	   	$dumpvars(0, user_uart_tb.u_top.u_riscv_top);
+	   	$dumpvars(0, user_uart_tb.u_top);
 	   end
        `endif
 
@@ -189,7 +189,7 @@
    repeat (2) @(posedge clock);
    #1;
    // Remove all the reset
-   wb_user_core_write('h3080_0000,'hF);
+   wb_user_core_write('h3080_0000,'h1F);
 
    repeat (16000) @(posedge clock);  // wait for Processor Get Ready
    tb_uart.uart_init;
@@ -347,10 +347,10 @@
 	force u_top.u_spi_master.u_buf_sdio3.VGND   =VSS;
 	force u_top.u_spi_master.u_buf_sdio3.VNB    =VSS;
           
-	force u_top.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
-	force u_top.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
-	force u_top.u_uart_core.u_lineclk_buf.VGND =VSS;
-	force u_top.u_uart_core.u_lineclk_buf.VNB = VSS;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VGND =VSS;
+	force u_top.u_uart_i2c.u_uart_core.u_lineclk_buf.VNB = VSS;
 
 	force u_top.u_wb_host.u_buf_wb_rst.VPWR =USER_VDD1V8;
 	force u_top.u_wb_host.u_buf_wb_rst.VPB  =USER_VDD1V8;
@@ -372,6 +372,21 @@
 	force u_top.u_wb_host.u_buf_sdram_rst.VGND =VSS;
 	force u_top.u_wb_host.u_buf_sdram_rst.VNB = VSS;
 
+	force u_top.u_wb_host.u_buf_uart_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_uart_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_i2cm_rst.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VGND =VSS;
+	force u_top.u_wb_host.u_buf_i2cm_rst.VNB = VSS;
+
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VPWR =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VPB  =USER_VDD1V8;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VGND =VSS;
+	force u_top.u_wb_host.u_buf_uart_i2c_sel.VNB = VSS;
+
 	force u_top.u_wb_host.u_clkbuf_sdram.VPWR =USER_VDD1V8;
 	force u_top.u_wb_host.u_clkbuf_sdram.VPB  =USER_VDD1V8;
 	force u_top.u_wb_host.u_clkbuf_sdram.VGND =VSS;
@@ -565,13 +580,13 @@
 wire [31:0] wbd_sdram_dat_o = u_top.u_sdram_ctrl.wb_dat_o;
 wire [3:0]  wbd_sdram_sel_i = u_top.u_sdram_ctrl.wb_sel_i;
 
-wire        wbd_uart_stb_i  = u_top.u_uart_core.reg_cs;
-wire        wbd_uart_ack_o  = u_top.u_uart_core.reg_ack;
-wire        wbd_uart_we_i   = u_top.u_uart_core.reg_wr;
-wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_core.reg_addr;
-wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_core.reg_wdata;
-wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_core.reg_rdata;
-wire        wbd_uart_sel_i  = u_top.u_uart_core.reg_be;
+wire        wbd_uart_stb_i  = u_top.u_uart_i2c.reg_cs;
+wire        wbd_uart_ack_o  = u_top.u_uart_i2c.reg_ack;
+wire        wbd_uart_we_i   = u_top.u_uart_i2c.reg_wr;
+wire [7:0]  wbd_uart_adr_i  = u_top.u_uart_i2c.reg_addr;
+wire [7:0]  wbd_uart_dat_i  = u_top.u_uart_i2c.reg_wdata;
+wire [7:0]  wbd_uart_dat_o  = u_top.u_uart_i2c.reg_rdata;
+wire        wbd_uart_sel_i  = u_top.u_uart_i2c.reg_be;
 
 `endif
 
diff --git a/verilog/dv/wb_port/Makefile b/verilog/dv/wb_port/Makefile
index d156539..cb66907 100644
--- a/verilog/dv/wb_port/Makefile
+++ b/verilog/dv/wb_port/Makefile
@@ -29,6 +29,7 @@
 UPRJ_BEHAVIOURAL_MODELS = ../
 UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
 UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes
 
 ## RISCV GCC 
 GCC_PATH?=/ef/apps/bin
@@ -53,7 +54,7 @@
 	iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
 	-I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
 	-I $(UPRJ_BEHAVIOURAL_MODELS)    -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
-	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) \
+	-I $(UPRJ_INCLUDE_PATH1)    -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \
 	$< -o $@ 
 else  
 	iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/wb_port/wb_port_tb.v b/verilog/dv/wb_port/wb_port_tb.v
index 7b12e0e..80538fe 100644
--- a/verilog/dv/wb_port/wb_port_tb.v
+++ b/verilog/dv/wb_port/wb_port_tb.v
@@ -221,10 +221,10 @@
 	force uut.mprj.u_spi_master.u_buf_sdio3.VGND    =VSS;
 	force uut.mprj.u_spi_master.u_buf_sdio3.VNB     =VSS;
           
-	force uut.mprj.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
-	force uut.mprj.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
-	force uut.mprj.u_uart_core.u_lineclk_buf.VGND =VSS;
-	force uut.mprj.u_uart_core.u_lineclk_buf.VNB = VSS;
+	force uut.mprj.u_uart_i2c.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+	force uut.mprj.u_uart_i2c.u_uart_core.u_lineclk_buf.VPB  =USER_VDD1V8;
+	force uut.mprj.u_uart_i2c.u_uart_core.u_lineclk_buf.VGND =VSS;
+	force uut.mprj.u_uart_i2c.u_uart_core.u_lineclk_buf.VNB = VSS;
 
 	force uut.mprj.u_wb_host.u_buf_wb_rst.VPWR =USER_VDD1V8;
 	force uut.mprj.u_wb_host.u_buf_wb_rst.VPB  =USER_VDD1V8;
@@ -246,6 +246,21 @@
 	force uut.mprj.u_wb_host.u_buf_sdram_rst.VGND =VSS;
 	force uut.mprj.u_wb_host.u_buf_sdram_rst.VNB = VSS;
 
+	force uut.mprj.u_wb_host.u_buf_uart_rst.VPWR =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_uart_rst.VPB  =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_uart_rst.VGND =VSS;
+	force uut.mprj.u_wb_host.u_buf_uart_rst.VNB = VSS;
+
+	force uut.mprj.u_wb_host.u_buf_i2cm_rst.VPWR =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_i2cm_rst.VPB  =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_i2cm_rst.VGND =VSS;
+	force uut.mprj.u_wb_host.u_buf_i2cm_rst.VNB = VSS;
+
+	force uut.mprj.u_wb_host.u_buf_uart_i2c_sel.VPWR =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_uart_i2c_sel.VPB  =USER_VDD1V8;
+	force uut.mprj.u_wb_host.u_buf_uart_i2c_sel.VGND =VSS;
+	force uut.mprj.u_wb_host.u_buf_uart_i2c_sel.VNB = VSS;
+
 	force uut.mprj.u_wb_host.u_clkbuf_sdram.VPWR =USER_VDD1V8;
 	force uut.mprj.u_wb_host.u_clkbuf_sdram.VPB  =USER_VDD1V8;
 	force uut.mprj.u_wb_host.u_clkbuf_sdram.VGND =VSS;
diff --git a/verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v b/verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v
new file mode 100755
index 0000000..35c2146
--- /dev/null
+++ b/verilog/rtl/i2cm/src/core/i2cm_bit_ctrl.v
@@ -0,0 +1,545 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya                          
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  OMS8051 I2C Master bit-controller Module                    ////
+////  WISHBONE rev.B2 compliant I2C Master bit-controller         ////
+////                                                              ////
+////  This file is part of the OMS 8051 cores project             ////
+////  http://www.opencores.org/cores/oms8051mini/                 ////
+////                                                              ////
+////  Description                                                 ////
+////  OMS 8051 definitions.                                       ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      -Richard Herveille ,  richard@asics.ws, www.asics.ws    ////
+////      -Dinesh Annayya, dinesha@opencores.org                  ////
+////                                                              ////
+////  Revision : Jan 6, 2017                                      //// 
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+//     v0.0 - Dinesh A, 6th Jan 2017
+//          1. Initail version picked from
+//              http://www.opencores.org/projects/i2c/
+//     v0.1 - Dinesh A, 19th Jan 2017
+//          1. Lint warning clean up
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+/////////////////////////////////////
+// Bit controller section
+/////////////////////////////////////
+//
+// Translate simple commands into SCL/SDA transitions
+// Each command has 5 states, A/B/C/D/idle
+//
+// start:	SCL	~~~~~~~~~~\____
+//	SDA	~~~~~~~~\______
+//		 x | A | B | C | D | i
+//
+// repstart	SCL	____/~~~~\___
+//	SDA	__/~~~\______
+//		 x | A | B | C | D | i
+//
+// stop	SCL	____/~~~~~~~~
+//	SDA	==\____/~~~~~
+//		 x | A | B | C | D | i
+//
+//- write	SCL	____/~~~~\____
+//	SDA	==X=========X=
+//		 x | A | B | C | D | i
+//
+//- read	SCL	____/~~~~\____
+//	SDA	XXXX=====XXXX
+//		 x | A | B | C | D | i
+//
+
+// Timing:     Normal mode      Fast mode
+///////////////////////////////////////////////////////////////////////
+// Fscl        100KHz           400KHz
+// Th_scl      4.0us            0.6us   High period of SCL
+// Tl_scl      4.7us            1.3us   Low period of SCL
+// Tsu:sta     4.7us            0.6us   setup time for a repeated start condition
+// Tsu:sto     4.0us            0.6us   setup time for a stop conditon
+// Tbuf        4.7us            1.3us   Bus free time between a stop and start condition
+//
+
+
+`include "i2cm_defines.v"
+
+module i2cm_bit_ctrl (
+    input             clk,      // system clock
+    input             sresetn,  // synchronous active low reset
+    input             aresetn,  // asynchronous active low reset
+    input             ena,      // core enable signal
+
+    input      [15:0] clk_cnt,  // clock prescale value
+
+    input      [ 3:0] cmd,      // command (from byte controller)
+    output reg        cmd_ack,  // command complete acknowledge
+    output reg        busy,     // i2c bus busy
+    output reg        al,       // i2c bus arbitration lost
+
+    input             din,
+    output reg        dout,
+
+    input             scl_i,    // i2c clock line input
+    output            scl_o,    // i2c clock line output
+    output reg        scl_oen,  // i2c clock line output enable (active low)
+    input             sda_i,    // i2c data line input
+    output            sda_o,    // i2c data line output
+    output reg        sda_oen   // i2c data line output enable (active low)
+);
+
+
+    //
+    // variable declarations
+    //
+
+    reg [ 1:0] cSCL, cSDA;      // capture SCL and SDA
+    reg [ 2:0] fSCL, fSDA;      // SCL and SDA filter inputs
+    reg        sSCL, sSDA;      // filtered and synchronized SCL and SDA inputs
+    reg        dSCL, dSDA;      // delayed versions of sSCL and sSDA
+    reg        dscl_oen;        // delayed scl_oen
+    reg        sda_chk;         // check SDA output (Multi-master arbitration)
+    reg        clk_en;          // clock generation signals
+    reg        slave_wait;      // slave inserts wait states
+    reg [15:0] cnt;             // clock divider counter (synthesis)
+    reg [13:0] filter_cnt;      // clock divider for filter
+
+
+    // state machine variable
+    reg [17:0] c_state; // synopsys enum_state
+
+    //
+    // module body
+    //
+
+    // whenever the slave is not ready it can delay the cycle by pulling SCL low
+    // delay scl_oen
+    always @(posedge clk)
+      dscl_oen <= scl_oen;
+
+    // slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
+    // slave_wait remains asserted until the slave releases SCL
+    always @(posedge clk or negedge aresetn)
+      if (!aresetn) slave_wait <= 1'b0;
+      else         slave_wait <= (scl_oen & ~dscl_oen & ~sSCL) | (slave_wait & ~sSCL);
+
+    // master drives SCL high, but another master pulls it low
+    // master start counting down its low cycle now (clock synchronization)
+    wire scl_sync   = dSCL & ~sSCL & scl_oen;
+
+
+    // generate clk enable signal
+    always @(posedge clk or negedge aresetn)
+      if (~aresetn)
+      begin
+          cnt    <= 16'h0;
+          clk_en <= 1'b1;
+      end
+      else if (!sresetn || ~|cnt || !ena || scl_sync)
+      begin
+          cnt    <= clk_cnt;
+          clk_en <= 1'b1;
+      end
+      else if (slave_wait)
+      begin
+          cnt    <= cnt;
+          clk_en <= 1'b0;    
+      end
+      else
+      begin
+          cnt    <= cnt - 16'h1;
+          clk_en <= 1'b0;
+      end
+
+
+    // generate bus status controller
+
+    // capture SDA and SCL
+    // reduce metastability risk
+    always @(posedge clk or negedge aresetn)
+      if (!aresetn)
+      begin
+          cSCL <= 2'b00;
+          cSDA <= 2'b00;
+      end
+      else if (!sresetn)
+      begin
+          cSCL <= 2'b00;
+          cSDA <= 2'b00;
+      end
+      else
+      begin
+          cSCL <= {cSCL[0],scl_i};
+          cSDA <= {cSDA[0],sda_i};
+      end
+
+
+    // filter SCL and SDA signals; (attempt to) remove glitches
+    always @(posedge clk or negedge aresetn)
+      if      (!aresetn     ) filter_cnt <= 14'h0;
+      else if (!sresetn || !ena ) filter_cnt <= 14'h0;
+      else if (~|filter_cnt) filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency
+      else                   filter_cnt <= filter_cnt -1;
+
+
+    always @(posedge clk or negedge aresetn)
+      if (!aresetn)
+      begin
+          fSCL <= 3'b111;
+          fSDA <= 3'b111;
+      end
+      else if (!sresetn)
+      begin
+          fSCL <= 3'b111;
+          fSDA <= 3'b111;
+      end
+      else if (~|filter_cnt)
+      begin
+          fSCL <= {fSCL[1:0],cSCL[1]};
+          fSDA <= {fSDA[1:0],cSDA[1]};
+      end
+
+
+    // generate filtered SCL and SDA signals
+    always @(posedge clk or negedge aresetn)
+      if (~aresetn)
+      begin
+          sSCL <= 1'b1;
+          sSDA <= 1'b1;
+
+          dSCL <= 1'b1;
+          dSDA <= 1'b1;
+      end
+      else if (!sresetn)
+      begin
+          sSCL <= 1'b1;
+          sSDA <= 1'b1;
+
+          dSCL <= 1'b1;
+          dSDA <= 1'b1;
+      end
+      else
+      begin
+          sSCL <= &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
+          sSDA <= &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
+
+          dSCL <= sSCL;
+          dSDA <= sSDA;
+      end
+
+    // detect start condition => detect falling edge on SDA while SCL is high
+    // detect stop condition => detect rising edge on SDA while SCL is high
+    reg sta_condition;
+    reg sto_condition;
+    always @(posedge clk or negedge aresetn)
+      if (~aresetn)
+      begin
+          sta_condition <= 1'b0;
+          sto_condition <= 1'b0;
+      end
+      else if (!sresetn)
+      begin
+          sta_condition <= 1'b0;
+          sto_condition <= 1'b0;
+      end
+      else
+      begin
+          sta_condition <= ~sSDA &  dSDA & sSCL;
+          sto_condition <=  sSDA & ~dSDA & sSCL;
+      end
+
+
+    // generate i2c bus busy signal
+    always @(posedge clk or negedge aresetn)
+      if      (!aresetn) busy <= 1'b0;
+      else if (!sresetn    ) busy <= 1'b0;
+      else              busy <= (sta_condition | busy) & ~sto_condition;
+
+
+    // generate arbitration lost signal
+    // aribitration lost when:
+    // 1) master drives SDA high, but the i2c bus is low
+    // 2) stop detected while not requested
+    reg cmd_stop;
+    always @(posedge clk or negedge aresetn)
+      if (~aresetn)
+          cmd_stop <= 1'b0;
+      else if (!sresetn)
+          cmd_stop <= 1'b0;
+      else if (clk_en)
+          cmd_stop <= cmd == `I2C_CMD_STOP;
+
+    always @(posedge clk or negedge aresetn)
+      if (~aresetn)
+          al <= 1'b0;
+      else if (!sresetn)
+          al <= 1'b0;
+      else
+          al <= (sda_chk & ~sSDA & sda_oen) | (|c_state & sto_condition & ~cmd_stop);
+
+
+    // generate dout signal (store SDA on rising edge of SCL)
+    always @(posedge clk)
+      if (sSCL & ~dSCL) dout <= sSDA;
+
+
+    // generate statemachine
+
+    // nxt_state decoder
+    parameter [17:0] idle    = 18'b0_0000_0000_0000_0000;
+    parameter [17:0] start_a = 18'b0_0000_0000_0000_0001;
+    parameter [17:0] start_b = 18'b0_0000_0000_0000_0010;
+    parameter [17:0] start_c = 18'b0_0000_0000_0000_0100;
+    parameter [17:0] start_d = 18'b0_0000_0000_0000_1000;
+    parameter [17:0] start_e = 18'b0_0000_0000_0001_0000;
+    parameter [17:0] stop_a  = 18'b0_0000_0000_0010_0000;
+    parameter [17:0] stop_b  = 18'b0_0000_0000_0100_0000;
+    parameter [17:0] stop_c  = 18'b0_0000_0000_1000_0000;
+    parameter [17:0] stop_d  = 18'b0_0000_0001_0000_0000;
+    parameter [17:0] rd_a    = 18'b0_0000_0010_0000_0000;
+    parameter [17:0] rd_b    = 18'b0_0000_0100_0000_0000;
+    parameter [17:0] rd_c    = 18'b0_0000_1000_0000_0000;
+    parameter [17:0] rd_d    = 18'b0_0001_0000_0000_0000;
+    parameter [17:0] wr_a    = 18'b0_0010_0000_0000_0000;
+    parameter [17:0] wr_b    = 18'b0_0100_0000_0000_0000;
+    parameter [17:0] wr_c    = 18'b0_1000_0000_0000_0000;
+    parameter [17:0] wr_d    = 18'b1_0000_0000_0000_0000;
+
+    always @(posedge clk or negedge aresetn)
+      if (!aresetn)
+      begin
+          c_state <= idle;
+          cmd_ack <= 1'b0;
+          scl_oen <= 1'b1;
+          sda_oen <= 1'b1;
+          sda_chk <= 1'b0;
+      end
+      else if (!sresetn | al)
+      begin
+          c_state <= idle;
+          cmd_ack <= 1'b0;
+          scl_oen <= 1'b1;
+          sda_oen <= 1'b1;
+          sda_chk <= 1'b0;
+      end
+      else
+      begin
+          cmd_ack   <= 1'b0; // default no command acknowledge + assert cmd_ack only 1clk cycle
+
+          if (clk_en)
+              case (c_state) // synopsys full_case parallel_case
+                    // idle state
+                    idle:
+                    begin
+                        case (cmd) // synopsys full_case parallel_case
+                             `I2C_CMD_START: c_state <= start_a;
+                             `I2C_CMD_STOP:  c_state <= stop_a;
+                             `I2C_CMD_WRITE: c_state <= wr_a;
+                             `I2C_CMD_READ:  c_state <= rd_a;
+                             default:        c_state <= idle;
+                        endcase
+
+                        scl_oen <= scl_oen; // keep SCL in same state
+                        sda_oen <= sda_oen; // keep SDA in same state
+                        sda_chk <= 1'b0;    // don't check SDA output
+                    end
+
+                    // start
+                    start_a:
+                    begin
+                        c_state <= start_b;
+                        scl_oen <= scl_oen; // keep SCL in same state
+                        sda_oen <= 1'b1;    // set SDA high
+                        sda_chk <= 1'b0;    // don't check SDA output
+                    end
+
+                    start_b:
+                    begin
+                        c_state <= start_c;
+                        scl_oen <= 1'b1; // set SCL high
+                        sda_oen <= 1'b1; // keep SDA high
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    start_c:
+                    begin
+                        c_state <= start_d;
+                        scl_oen <= 1'b1; // keep SCL high
+                        sda_oen <= 1'b0; // set SDA low
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    start_d:
+                    begin
+                        c_state <= start_e;
+                        scl_oen <= 1'b1; // keep SCL high
+                        sda_oen <= 1'b0; // keep SDA low
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    start_e:
+                    begin
+                        c_state <= idle;
+                        cmd_ack <= 1'b1;
+                        scl_oen <= 1'b0; // set SCL low
+                        sda_oen <= 1'b0; // keep SDA low
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    // stop
+                    stop_a:
+                    begin
+                        c_state <= stop_b;
+                        scl_oen <= 1'b0; // keep SCL low
+                        sda_oen <= 1'b0; // set SDA low
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    stop_b:
+                    begin
+                        c_state <= stop_c;
+                        scl_oen <= 1'b1; // set SCL high
+                        sda_oen <= 1'b0; // keep SDA low
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    stop_c:
+                    begin
+                        c_state <= stop_d;
+                        scl_oen <= 1'b1; // keep SCL high
+                        sda_oen <= 1'b0; // keep SDA low
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    stop_d:
+                    begin
+                        c_state <= idle;
+                        cmd_ack <= 1'b1;
+                        scl_oen <= 1'b1; // keep SCL high
+                        sda_oen <= 1'b1; // set SDA high
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    // read
+                    rd_a:
+                    begin
+                        c_state <= rd_b;
+                        scl_oen <= 1'b0; // keep SCL low
+                        sda_oen <= 1'b1; // tri-state SDA
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    rd_b:
+                    begin
+                        c_state <= rd_c;
+                        scl_oen <= 1'b1; // set SCL high
+                        sda_oen <= 1'b1; // keep SDA tri-stated
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    rd_c:
+                    begin
+                        c_state <= rd_d;
+                        scl_oen <= 1'b1; // keep SCL high
+                        sda_oen <= 1'b1; // keep SDA tri-stated
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    rd_d:
+                    begin
+                        c_state <= idle;
+                        cmd_ack <= 1'b1;
+                        scl_oen <= 1'b0; // set SCL low
+                        sda_oen <= 1'b1; // keep SDA tri-stated
+                        sda_chk <= 1'b0; // don't check SDA output
+                    end
+
+                    // write
+                    wr_a:
+                    begin
+                        c_state <= wr_b;
+                        scl_oen <= 1'b0; // keep SCL low
+                        sda_oen <= din;  // set SDA
+                        sda_chk <= 1'b0; // don't check SDA output (SCL low)
+                    end
+
+                    wr_b:
+                    begin
+                        c_state <= wr_c;
+                        scl_oen <= 1'b1; // set SCL high
+                        sda_oen <= din;  // keep SDA
+                        sda_chk <= 1'b0; // don't check SDA output yet
+                                            // allow some time for SDA and SCL to settle
+                    end
+
+                    wr_c:
+                    begin
+                        c_state <= wr_d;
+                        scl_oen <= 1'b1; // keep SCL high
+                        sda_oen <= din;
+                        sda_chk <= 1'b1; // check SDA output
+                    end
+
+                    wr_d:
+                    begin
+                        c_state <= idle;
+                        cmd_ack <= 1'b1;
+                        scl_oen <= 1'b0; // set SCL low
+                        sda_oen <= din;
+                        sda_chk <= 1'b0; // don't check SDA output (SCL low)
+                    end
+
+              endcase
+      end
+
+
+    // assign scl and sda output (always gnd)
+    assign scl_o = 1'b0;
+    assign sda_o = 1'b0;
+
+endmodule
diff --git a/verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v b/verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v
new file mode 100755
index 0000000..002b51e
--- /dev/null
+++ b/verilog/rtl/i2cm/src/core/i2cm_byte_ctrl.v
@@ -0,0 +1,343 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya                          
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  OMS8051 I2C Master byte-controller Module                  ////
+////  WISHBONE rev.B2 compliant I2C Master byte-controller       ////
+////                                                              ////
+////  This file is part of the OMS 8051 cores project             ////
+////  http://www.opencores.org/cores/oms8051mini/                 ////
+////                                                              ////
+////  Description                                                 ////
+////  OMS 8051 definitions.                                       ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      -Richard Herveille ,  richard@asics.ws, www.asics.ws    ////
+////      -Dinesh Annayya, dinesha@opencores.org                  ////
+////                                                              ////
+////  Revision : Jan 6, 2017                                      //// 
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////   v0.0 - Dinesh A, 6th Jan 2017
+////        1. Initail version picked from
+////            http://www.opencores.org/projects/i2c/
+////        2. renaming of reset signal to aresetn and sresetn
+////   v0.1 - Dinesh.A, 19th Jan 2017
+////        1. Lint Error fixes
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`include "i2cm_defines.v"
+
+module i2cm_byte_ctrl (
+	//
+	// inputs & outputs
+	//
+	input        clk,     // master clock
+	input        sresetn, // synchronous active high reset
+	input        aresetn, // asynchronous active low reset
+	input        ena,     // core enable signal
+
+	input [15:0] clk_cnt, // 4x SCL
+
+	// control inputs
+	input        start,
+	input        stop,
+	input        read,
+	input        write,
+	input        ack_in,
+	input [7:0]  din,
+
+	// status outputs
+	output reg   cmd_ack,
+	output reg   ack_out,
+	output       i2c_busy,
+	output       i2c_al,
+	output [7:0] dout,
+
+	// I2C signals
+	input        scl_i,
+	output       scl_o,
+	output       scl_oen,
+	input        sda_i,
+	output       sda_o,
+	output       sda_oen
+
+       );
+
+
+
+	//
+	// Variable declarations
+	//
+
+	// statemachine
+	parameter [4:0] ST_IDLE  = 5'b0_0000;
+	parameter [4:0] ST_START = 5'b0_0001;
+	parameter [4:0] ST_READ  = 5'b0_0010;
+	parameter [4:0] ST_WRITE = 5'b0_0100;
+	parameter [4:0] ST_ACK   = 5'b0_1000;
+	parameter [4:0] ST_STOP  = 5'b1_0000;
+
+	// signals for bit_controller
+	reg  [3:0] core_cmd;
+	reg        core_txd;
+	wire       core_ack, core_rxd;
+
+	// signals for shift register
+	reg [7:0] sr; //8bit shift register
+	reg       shift, ld;
+
+	// signals for state machine
+	wire       go;
+	reg  [2:0] dcnt;
+	wire       cnt_done;
+
+	//
+	// Module body
+	//
+
+	// hookup bit_controller
+	i2cm_bit_ctrl u_bit_ctrl (
+		.clk     ( clk      ),
+		.sresetn ( sresetn  ),
+		.aresetn ( aresetn ),
+		.ena     ( ena      ),
+		.clk_cnt ( clk_cnt  ),
+		.cmd     ( core_cmd ),
+		.cmd_ack ( core_ack ),
+		.busy    ( i2c_busy ),
+		.al      ( i2c_al   ),
+		.din     ( core_txd ),
+		.dout    ( core_rxd ),
+		.scl_i   ( scl_i    ),
+		.scl_o   ( scl_o    ),
+		.scl_oen ( scl_oen  ),
+		.sda_i   ( sda_i    ),
+		.sda_o   ( sda_o    ),
+		.sda_oen ( sda_oen  )
+	);
+
+	// generate go-signal
+	assign go = (read | write | stop) & ~cmd_ack;
+
+	// assign dout output to shift-register
+	assign dout = sr;
+
+	// generate shift register
+	always @(posedge clk or negedge aresetn)
+	  if (!aresetn)
+	    sr <= 8'h0;
+	  else if (!sresetn)
+	    sr <= 8'h0;
+	  else if (ld)
+	    sr <= din;
+	  else if (shift)
+	    sr <= {sr[6:0], core_rxd};
+
+	// generate counter
+	always @(posedge clk or negedge aresetn)
+	  if (!aresetn)
+	    dcnt <= 3'h0;
+	  else if (!sresetn)
+	    dcnt <= 3'h0;
+	  else if (ld)
+	    dcnt <= 3'h7;
+	  else if (shift)
+	    dcnt <= dcnt - 3'h1;
+
+	assign cnt_done = ~(|dcnt);
+
+	//
+	// state machine
+	//
+	reg [4:0] c_state; // synopsys enum_state
+
+	always @(posedge clk or negedge aresetn)
+	  if (!aresetn)
+	    begin
+	        core_cmd <= `I2C_CMD_NOP;
+	        core_txd <= 1'b0;
+	        shift    <= 1'b0;
+	        ld       <= 1'b0;
+	        cmd_ack  <= 1'b0;
+	        c_state  <= ST_IDLE;
+	        ack_out  <= 1'b0;
+	    end
+	  else if (!sresetn | i2c_al)
+	   begin
+	       core_cmd <= `I2C_CMD_NOP;
+	       core_txd <= 1'b0;
+	       shift    <= 1'b0;
+	       ld       <= 1'b0;
+	       cmd_ack  <= 1'b0;
+	       c_state  <= ST_IDLE;
+	       ack_out  <= 1'b0;
+	   end
+	else
+	  begin
+	      // initially reset all signals
+	      core_txd <= sr[7];
+	      shift    <= 1'b0;
+	      ld       <= 1'b0;
+	      cmd_ack  <= 1'b0;
+
+	      case (c_state) // synopsys full_case parallel_case
+	        ST_IDLE:
+	          if (go)
+	            begin
+	                if (start)
+	                  begin
+	                      c_state  <= ST_START;
+	                      core_cmd <= `I2C_CMD_START;
+	                  end
+	                else if (read)
+	                  begin
+	                      c_state  <= ST_READ;
+	                      core_cmd <= `I2C_CMD_READ;
+	                  end
+	                else if (write)
+	                  begin
+	                      c_state  <= ST_WRITE;
+	                      core_cmd <= `I2C_CMD_WRITE;
+	                  end
+	                else // stop
+	                  begin
+	                      c_state  <= ST_STOP;
+	                      core_cmd <= `I2C_CMD_STOP;
+	                  end
+
+	                ld <= 1'b1;
+	            end
+
+	        ST_START:
+	          if (core_ack)
+	            begin
+	                if (read)
+	                  begin
+	                      c_state  <= ST_READ;
+	                      core_cmd <= `I2C_CMD_READ;
+	                  end
+	                else
+	                  begin
+	                      c_state  <= ST_WRITE;
+	                      core_cmd <= `I2C_CMD_WRITE;
+	                  end
+
+	                ld <= 1'b1;
+	            end
+
+	        ST_WRITE:
+	          if (core_ack)
+	            if (cnt_done)
+	              begin
+	                  c_state  <= ST_ACK;
+	                  core_cmd <= `I2C_CMD_READ;
+	              end
+	            else
+	              begin
+	                  c_state  <= ST_WRITE;       // stay in same state
+	                  core_cmd <= `I2C_CMD_WRITE; // write next bit
+	                  shift    <= 1'b1;
+	              end
+
+	        ST_READ:
+	          if (core_ack)
+	            begin
+	                if (cnt_done)
+	                  begin
+	                      c_state  <= ST_ACK;
+	                      core_cmd <= `I2C_CMD_WRITE;
+	                  end
+	                else
+	                  begin
+	                      c_state  <= ST_READ;       // stay in same state
+	                      core_cmd <= `I2C_CMD_READ; // read next bit
+	                  end
+
+	                shift    <= 1'b1;
+	                core_txd <= ack_in;
+	            end
+
+	        ST_ACK:
+	          if (core_ack)
+	            begin
+	               if (stop)
+	                 begin
+	                     c_state  <= ST_STOP;
+	                     core_cmd <= `I2C_CMD_STOP;
+	                 end
+	               else
+	                 begin
+	                     c_state  <= ST_IDLE;
+	                     core_cmd <= `I2C_CMD_NOP;
+
+	                     // generate command acknowledge signal
+	                     cmd_ack  <= 1'b1;
+	                 end
+
+	                 // assign ack_out output to bit_controller_rxd (contains last received bit)
+	                 ack_out <=  core_rxd;
+
+	                 core_txd <=  1'b1;
+	             end
+	           else
+	             core_txd <= ack_in;
+
+	        ST_STOP:
+	          if (core_ack)
+	            begin
+	                c_state  <= ST_IDLE;
+	                core_cmd <= `I2C_CMD_NOP;
+
+	                // generate command acknowledge signal
+	                cmd_ack  <= 1'b1;
+	            end
+               default: c_state  <= ST_IDLE;
+
+	      endcase
+	  end
+endmodule
diff --git a/verilog/rtl/i2cm/src/core/i2cm_top.v b/verilog/rtl/i2cm/src/core/i2cm_top.v
new file mode 100755
index 0000000..3b32db9
--- /dev/null
+++ b/verilog/rtl/i2cm/src/core/i2cm_top.v
@@ -0,0 +1,280 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya                          
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  OMS8051 I2C Master Core Module                              ////
+////  WISHBONE revB.2 compliant I2C Master controller Top-level   ////
+////                                                              ////
+////  This file is part of the OMS 8051 cores project             ////
+////  http://www.opencores.org/cores/oms8051mini/                 ////
+////                                                              ////
+////  Description                                                 ////
+////  OMS 8051 definitions.                                       ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      -Richard Herveille ,  richard@asics.ws, www.asics.ws    ////
+////      -Dinesh Annayya, dinesha@opencores.org                  ////
+////                                                              ////
+////  Revision : Jan 6, 2017                                      //// 
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+//     v0.0 - Dinesh A, 6th Jan 2017
+//          1. Initail version picked from
+//              http://www.opencores.org/projects/i2c/
+//          2. renaming of reset signal to aresetn and sresetn
+//
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+`include "i2cm_defines.v"
+
+module i2cm_top(
+	// wishbone signals
+	input        wb_clk_i,     // master clock input
+	input        sresetn,      // synchronous reset
+	input        aresetn,      // asynchronous reset
+	input  [2:0] wb_adr_i,     // lower address bits
+	input  [7:0] wb_dat_i,     // databus input
+	output reg [7:0] wb_dat_o,     // databus output
+	input        wb_we_i,      // write enable input
+	input        wb_stb_i,     // stobe/core select signal
+	input        wb_cyc_i,     // valid bus cycle input
+	output reg   wb_ack_o,     // bus cycle acknowledge output
+	output reg  wb_inta_o,    // interrupt request signal output
+
+	// I2C signals
+	// i2c clock line
+	input        scl_pad_i,    // SCL-line input
+	output       scl_pad_o,    // SCL-line output (always 1'b0)
+	output       scl_padoen_o, // SCL-line output enable (active low)
+
+	// i2c data line
+	input        sda_pad_i,    // SDA-line input
+	output       sda_pad_o,    // SDA-line output (always 1'b0)
+	output       sda_padoen_o  // SDA-line output enable (active low)
+
+         );
+
+
+	//
+	// variable declarations
+	//
+
+	// registers
+	reg  [15:0] prer; // clock prescale register
+	reg  [ 7:0] ctr;  // control register
+	reg  [ 7:0] txr;  // transmit register
+	wire [ 7:0] rxr;  // receive register
+	reg  [ 7:0] cr;   // command register
+	wire [ 7:0] sr;   // status register
+
+	// done signal: command completed, clear command register
+	wire done;
+
+	// core enable signal
+	wire core_en;
+	wire ien;
+
+	// status register signals
+	wire irxack;
+	reg  rxack;       // received aknowledge from slave
+	reg  tip;         // transfer in progress
+	reg  irq_flag;    // interrupt pending flag
+	wire i2c_busy;    // bus busy (start signal detected)
+	wire i2c_al;      // i2c bus arbitration lost
+	reg  al;          // status register arbitration lost bit
+
+	//
+	// module body
+	//
+
+
+	// generate wishbone signals
+	wire wb_wacc = wb_we_i & wb_ack_o;
+
+	// generate acknowledge output signal
+	always @(posedge wb_clk_i)
+	  wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored
+
+	// assign DAT_O
+	always @(posedge wb_clk_i)
+	begin
+	  case (wb_adr_i) // synopsys parallel_case
+	    3'b000: wb_dat_o <= #1 prer[ 7:0];
+	    3'b001: wb_dat_o <= #1 prer[15:8];
+	    3'b010: wb_dat_o <= #1 ctr;
+	    3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr)
+	    3'b100: wb_dat_o <= #1 sr;  // write is command register (cr)
+	    3'b101: wb_dat_o <= #1 txr;
+	    3'b110: wb_dat_o <= #1 cr;
+	    3'b111: wb_dat_o <= #1 0;   // reserved
+	  endcase
+	end
+
+	// generate registers
+	always @(posedge wb_clk_i or negedge aresetn)
+	  if (!aresetn)
+	    begin
+	        prer <= #1 16'hffff;
+	        ctr  <= #1  8'h0;
+	        txr  <= #1  8'h0;
+	    end
+	  else if (!sresetn)
+	    begin
+	        prer <= #1 16'hffff;
+	        ctr  <= #1  8'h0;
+	        txr  <= #1  8'h0;
+	    end
+	  else
+	    if (wb_wacc)
+	      case (wb_adr_i) // synopsys parallel_case
+	         3'b000 : prer [ 7:0] <= #1 wb_dat_i;
+	         3'b001 : prer [15:8] <= #1 wb_dat_i;
+	         3'b010 : ctr         <= #1 wb_dat_i;
+	         3'b011 : txr         <= #1 wb_dat_i;
+	         default: ;
+	      endcase
+
+	// generate command register (special case)
+	always @(posedge wb_clk_i or negedge aresetn)
+	  if (!aresetn)
+	    cr <= #1 8'h0;
+	  else if (!sresetn)
+	    cr <= #1 8'h0;
+	  else if (wb_wacc)
+	    begin
+	        if (core_en & (wb_adr_i == 3'b100) )
+	          cr <= #1 wb_dat_i;
+	    end
+	  else
+	    begin
+	        if (done | i2c_al)
+	          cr[7:4] <= #1 4'h0;           // clear command bits when done
+	                                        // or when aribitration lost
+	        cr[2:1] <= #1 2'b0;             // reserved bits
+	        cr[0]   <= #1 1'b0;             // clear IRQ_ACK bit
+	    end
+
+
+	// decode command register
+	wire sta  = cr[7];
+	wire sto  = cr[6];
+	wire rd   = cr[5];
+	wire wr   = cr[4];
+	wire ack  = cr[3];
+	wire iack = cr[0];
+
+	// decode control register
+	assign core_en = ctr[7];
+	assign ien = ctr[6];
+
+	// hookup byte controller block
+	i2cm_byte_ctrl u_byte_ctrl (
+		.clk      ( wb_clk_i     ),
+		.sresetn  ( sresetn      ),
+		.aresetn  ( aresetn      ),
+		.ena      ( core_en      ),
+		.clk_cnt  ( prer         ),
+		.start    ( sta          ),
+		.stop     ( sto          ),
+		.read     ( rd           ),
+		.write    ( wr           ),
+		.ack_in   ( ack          ),
+		.din      ( txr          ),
+		.cmd_ack  ( done         ),
+		.ack_out  ( irxack       ),
+		.dout     ( rxr          ),
+		.i2c_busy ( i2c_busy     ),
+		.i2c_al   ( i2c_al       ),
+		.scl_i    ( scl_pad_i    ),
+		.scl_o    ( scl_pad_o    ),
+		.scl_oen  ( scl_padoen_o ),
+		.sda_i    ( sda_pad_i    ),
+		.sda_o    ( sda_pad_o    ),
+		.sda_oen  ( sda_padoen_o )
+	);
+
+	// status register block + interrupt request signal
+	always @(posedge wb_clk_i or negedge aresetn)
+	  if (!aresetn)
+	    begin
+	        al       <= #1 1'b0;
+	        rxack    <= #1 1'b0;
+	        tip      <= #1 1'b0;
+	        irq_flag <= #1 1'b0;
+	    end
+	  else if (!sresetn)
+	    begin
+	        al       <= #1 1'b0;
+	        rxack    <= #1 1'b0;
+	        tip      <= #1 1'b0;
+	        irq_flag <= #1 1'b0;
+	    end
+	  else
+	    begin
+	        al       <= #1 i2c_al | (al & ~sta);
+	        rxack    <= #1 irxack;
+	        tip      <= #1 (rd | wr);
+	        irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated
+	    end
+
+	// generate interrupt request signals
+	always @(posedge wb_clk_i or negedge aresetn)
+	  if (!aresetn)
+	    wb_inta_o <= #1 1'b0;
+	  else if (!sresetn)
+	    wb_inta_o <= #1 1'b0;
+	  else
+	    wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set)
+
+	// assign status register bits
+	assign sr[7]   = rxack;
+	assign sr[6]   = i2c_busy;
+	assign sr[5]   = al;
+	assign sr[4:2] = 3'h0; // reserved
+	assign sr[1]   = tip;
+	assign sr[0]   = irq_flag;
+
+endmodule
diff --git a/verilog/rtl/i2cm/src/includes/i2cm_defines.v b/verilog/rtl/i2cm/src/includes/i2cm_defines.v
new file mode 100755
index 0000000..dd2ba88
--- /dev/null
+++ b/verilog/rtl/i2cm/src/includes/i2cm_defines.v
@@ -0,0 +1,9 @@
+
+// I2C registers wishbone addresses
+
+// bitcontroller states
+`define I2C_CMD_NOP   4'b0000
+`define I2C_CMD_START 4'b0001
+`define I2C_CMD_STOP  4'b0010
+`define I2C_CMD_WRITE 4'b0100
+`define I2C_CMD_READ  4'b1000
diff --git a/verilog/rtl/uart/src/uart_core.sv b/verilog/rtl/uart/src/uart_core.sv
index 79c0b47..15cb568 100644
--- a/verilog/rtl/uart/src/uart_core.sv
+++ b/verilog/rtl/uart/src/uart_core.sv
@@ -85,9 +85,8 @@
    output logic        reg_ack,
 
        // Pad Control
-   input  logic [1:0]  io_in,
-   output logic [1:0]  io_out,
-   output logic [1:0]  io_oeb
+   input  logic        rxd,
+   output logic        txd
 
      );
 
@@ -141,20 +140,6 @@
 wire           si_ss                 ;
 
 
-/////////////////////////////////////////////////////////
-// uart interface
-///////////////////////////////////////////////////////
-
-wire            si                  ; 
-wire            so                  ;
-
-// for uart
-assign  io_oeb[0] =  1'b1; // Uart RX
-assign  si        =  io_in[0];
-assign  io_out[0] =  1'b0;
-
-assign  io_oeb[1] =  1'b0; // Uart TX
-assign  io_out[1]  =  so;
 
 uart_cfg u_cfg (
 
@@ -254,7 +239,7 @@
                .fifo_data         ( tx_fifo_rd_data   ),
 
           // Line Interface
-               .so                ( so                )
+               .so                ( txd               )
           );
 
 
@@ -311,7 +296,7 @@
 
 
 double_sync_low   u_si_sync (
-               .in_data           ( si                ),
+               .in_data           (rxd                ),
                .out_clk           (line_clk_16x       ),
                .out_rst_n         (line_reset_n       ),
                .out_data          (si_ss              ) 
diff --git a/verilog/rtl/uart_i2c/src/uart_i2c_top.sv b/verilog/rtl/uart_i2c/src/uart_i2c_top.sv
new file mode 100644
index 0000000..c0b68c5
--- /dev/null
+++ b/verilog/rtl/uart_i2c/src/uart_i2c_top.sv
@@ -0,0 +1,179 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya                          
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  UART CORE with TX/RX 16 Byte Buffer                         ////
+////  I2C Master                                                  ////
+////                                                              ////
+////  This file is part of the YIFive cores project               ////
+////  https://github.com/dineshannayya/yifive_r0.git              ////
+////                                                              ////
+////  Description: This module integarte Uart and I2C Master      ////
+////    Both these block share common two pins, effectly only     ////
+////    one block active at time. This is due to top-level pin    ////
+////    restriction.                                              ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision :                                                  ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_i2c_top 
+
+     (  
+
+   input logic         uart_rstn  , // async reset
+   input logic         i2c_rstn  , // async reset
+   input logic         app_clk ,
+   input logic         uart_i2c_sel, // Uart Or I2C Interface Select
+
+        // Reg Bus Interface Signal
+   input logic         reg_cs,
+   input logic         reg_wr,
+   input logic [3:0]   reg_addr,
+   input logic [7:0]   reg_wdata,
+   input logic         reg_be,
+
+        // Outputs
+   output logic [7:0]  reg_rdata,
+   output logic        reg_ack,
+
+       // Pad Control
+   input  logic [1:0]  io_in,
+   output logic [1:0]  io_out,
+   output logic [1:0]  io_oeb
+
+     );
+
+/////////////////////////////////////////////////////////
+// uart interface
+///////////////////////////////////////////////////////
+
+logic             uart_rxd                  ; 
+logic             uart_txd                  ;
+/////////////////////////////////////////////////////////
+// i2c interface
+///////////////////////////////////////////////////////
+logic             scl_pad_i                 ; // SCL-line input
+logic             scl_pad_o                 ; // SCL-line output (always 1'b0)
+logic             scl_pad_oen_o             ; // SCL-line output enable (active low)
+
+logic             sda_pad_i                 ; // SDA-line input
+logic             sda_pad_o                 ; // SDA-line output (always 1'b0)
+logic             sda_padoen_o              ; // SDA-line output enable (active low)
+
+
+
+assign  io_oeb[0]  =  (uart_i2c_sel == 0) ? 1'b1 : scl_pad_oen_o ; // Uart RX
+assign  uart_rxd   =  (uart_i2c_sel == 0) ? io_in[0]: 1'b0;
+assign  scl_pad_i  =  (uart_i2c_sel == 1) ? io_in[0]: 1'b0;
+assign  io_out[0]  =  (uart_i2c_sel == 0) ? 1'b0 : scl_pad_o ;
+
+assign  io_oeb[1] =  (uart_i2c_sel == 0) ? 1'b0 : sda_padoen_o ; // Uart TX & I2C Clock
+assign  io_out[1]  = (uart_i2c_sel == 0) ? uart_txd: sda_pad_o ;
+assign  sda_pad_i =  (uart_i2c_sel == 1) ? io_in[1] : 1'b0;
+
+logic [7:0]   reg_uart_rdata;
+logic [7:0]   reg_i2c_rdata;
+logic         reg_uart_ack;
+logic         reg_i2c_ack;
+
+
+assign reg_rdata = (uart_i2c_sel == 0) ? reg_uart_rdata : reg_i2c_rdata;
+assign reg_ack   = (uart_i2c_sel == 0) ? reg_uart_ack   : reg_i2c_ack;
+
+uart_core  u_uart_core (  
+
+        .arst_n      (uart_rstn        ), // async reset
+        .app_clk     (app_clk          ),
+
+        // Reg Bus Interface Signal
+        .reg_cs      (reg_cs           ),
+        .reg_wr      (reg_wr           ),
+        .reg_addr    (reg_addr[3:0]    ),
+        .reg_wdata   (reg_wdata[7:0]   ),
+        .reg_be      (reg_be           ),
+
+        // Outputs
+        .reg_rdata   (reg_uart_rdata[7:0]),
+        .reg_ack     (reg_uart_ack     ),
+
+            // Pad Control
+        .rxd          (uart_rxd        ),
+        .txd          (uart_txd        )
+     );
+
+i2cm_top  u_i2cm (
+	// wishbone signals
+	.wb_clk_i      (app_clk        ), // master clock input
+	.sresetn       (1'b1           ), // synchronous reset
+	.aresetn       (i2c_rstn       ), // asynchronous reset
+	.wb_adr_i      (reg_addr[2:0]  ), // lower address bits
+	.wb_dat_i      (reg_wdata      ), // databus input
+	.wb_dat_o      (reg_i2c_rdata  ), // databus output
+	.wb_we_i       (reg_wr         ), // write enable input
+	.wb_stb_i      (reg_cs         ), // stobe/core select signal
+	.wb_cyc_i      (reg_cs         ), // valid bus cycle input
+	.wb_ack_o      (reg_i2c_ack    ), // bus cycle acknowledge output
+	.wb_inta_o     (               ), // interrupt request signal output
+
+	// I2C signals
+	// i2c clock line
+	.scl_pad_i     (scl_pad_i      ), // SCL-line input
+	.scl_pad_o     (scl_pad_o      ), // SCL-line output (always 1'b0)
+	.scl_padoen_o  (scl_pad_oen_o  ), // SCL-line output enable (active low)
+
+	// i2c data line
+	.sda_pad_i     (sda_pad_i      ), // SDA-line input
+	.sda_pad_o     (sda_pad_o      ), // SDA-line output (always 1'b0)
+	.sda_padoen_o  (sda_padoen_o   )  // SDA-line output enable (active low)
+
+         );
+
+endmodule
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v
index ea393bf..07f2cda 100644
--- a/verilog/rtl/uprj_netlists.v
+++ b/verilog/rtl/uprj_netlists.v
@@ -19,7 +19,6 @@
 `define UNIT_DELAY #0.1
 
 `ifdef GL
-
        `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
        `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
        `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
@@ -29,7 +28,7 @@
         `include "glbl_cfg.v"
         `include "sdram.v"
         `include "spi_master.v"
-        `include "uart.v"
+        `include "uart_i2cm.v"
         `include "wb_interconnect.v"
         `include "user_project_wrapper.v"
         `include "syntacore.v"
@@ -38,7 +37,6 @@
 	`include "clk_buf.v"
 
 `else
-
      `include "libs.ref/sky130_fd_sc_hd/verilog/primitives.v"
      `include "libs.ref/sky130_fd_sc_hd/verilog/sky130_fd_sc_hd.v"
      `include "libs.ref/sky130_fd_sc_hvl/verilog/primitives.v"
@@ -63,6 +61,12 @@
      `include "lib/double_sync_low.v"  
      `include "lib/clk_buf.v"  
 
+     `include "i2cm/src/core/i2cm_bit_ctrl.v"
+     `include "i2cm/src/core/i2cm_byte_ctrl.v"
+     `include "i2cm/src/core/i2cm_top.v"
+
+     `include "uart_i2c/src/uart_i2c_top.sv"
+
      `include "sdram_ctrl/src/top/sdrc_top.v" 
      `include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v" 
      `include "lib/async_fifo.sv"  
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 99d5b86..80deff9 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -91,6 +91,10 @@
 ////    0.9 - 7th July 2021, Dinesh A                             ////
 ////          Removed 2 Unused port connection io_in[31:30] to    ////
 ////          spi_master to avoid lvs issue                       ////
+////    1.0 - 28th July 2021, Dinesh A                            ////
+////          i2cm integrated part of uart_i2cm module,           ////
+////          due to number of IO pin limitation,                 ////
+////          Only UART OR I2C selected based on config mode      ////
 ////                                                              ////
 //////////////////////////////////////////////////////////////////////
 ////                                                              ////
@@ -267,6 +271,9 @@
 wire                              cpu_rst_n     ;
 wire                              spi_rst_n     ;
 wire                              sdram_rst_n   ;
+wire                              uart_rst_n    ;// uart reset
+wire                              i2c_rst_n     ;// i2c reset
+wire                              uart_i2c_sel  ;// 0 - uart, 1 - I2C
 wire                              sdram_clk           ;
 wire                              cpu_clk       ;
 wire                              rtc_clk       ;
@@ -370,6 +377,9 @@
        .cpu_rst_n        (cpu_rst_n            ),
        .spi_rst_n        (spi_rst_n            ),
        .sdram_rst_n      (sdram_rst_n          ),
+       .uart_rst_n       (uart_rst_n           ), // uart reset
+       .i2cm_rst_n       (i2c_rst_n            ), // i2c reset
+       .uart_i2c_sel     (uart_i2c_sel         ), // 0 - uart, 1 - I2C
 
     // Master Port
        .wbm_rst_i        (wb_rst_i             ),  
@@ -668,8 +678,10 @@
 
         );
 
-uart_core   u_uart_core (
-        .arst_n                 (wbd_int_rst_n            ), // async reset
+uart_i2c_top   u_uart_i2c (
+        .uart_rstn              (uart_rst_n               ), // uart reset
+        .i2c_rstn               (i2c_rst_n                ), // i2c reset
+	.uart_i2c_sel           (uart_i2c_sel             ), // 0 - uart, 1 - I2C
         .app_clk                (wbd_clk_uart             ),
 
         // Reg Bus Interface Signal
diff --git a/verilog/rtl/wb_host/src/wb_host.sv b/verilog/rtl/wb_host/src/wb_host.sv
index e91913b..7605087 100644
--- a/verilog/rtl/wb_host/src/wb_host.sv
+++ b/verilog/rtl/wb_host/src/wb_host.sv
@@ -80,6 +80,9 @@
        output logic                cpu_rst_n        ,
        output logic                spi_rst_n        ,
        output logic                sdram_rst_n      ,
+       output logic                uart_rst_n       ,
+       output logic                i2cm_rst_n       ,
+       output logic                uart_i2c_sel     ,
 
     // Master Port
        input   logic               wbm_rst_i        ,  // Regular Reset signal
@@ -152,10 +155,13 @@
 assign wbm_rst_n = !wbm_rst_i;
 assign wbs_rst_n = !wbm_rst_i;
 
-sky130_fd_sc_hd__bufbuf_16 u_buf_wb_rst     (.A(cfg_glb_ctrl[0]),.X(wbd_int_rst_n));
-sky130_fd_sc_hd__bufbuf_16 u_buf_cpu_rst    (.A(cfg_glb_ctrl[1]),.X(cpu_rst_n));
-sky130_fd_sc_hd__bufbuf_16 u_buf_spi_rst    (.A(cfg_glb_ctrl[2]),.X(spi_rst_n));
-sky130_fd_sc_hd__bufbuf_16 u_buf_sdram_rst  (.A(cfg_glb_ctrl[3]),.X(sdram_rst_n));
+sky130_fd_sc_hd__bufbuf_16 u_buf_wb_rst        (.A(cfg_glb_ctrl[0]),.X(wbd_int_rst_n));
+sky130_fd_sc_hd__bufbuf_16 u_buf_cpu_rst       (.A(cfg_glb_ctrl[1]),.X(cpu_rst_n));
+sky130_fd_sc_hd__bufbuf_16 u_buf_spi_rst       (.A(cfg_glb_ctrl[2]),.X(spi_rst_n));
+sky130_fd_sc_hd__bufbuf_16 u_buf_sdram_rst     (.A(cfg_glb_ctrl[3]),.X(sdram_rst_n));
+sky130_fd_sc_hd__bufbuf_16 u_buf_uart_rst      (.A(cfg_glb_ctrl[4]),.X(uart_rst_n));
+sky130_fd_sc_hd__bufbuf_16 u_buf_i2cm_rst       (.A(cfg_glb_ctrl[5]),.X(i2cm_rst_n));
+sky130_fd_sc_hd__bufbuf_16 u_buf_uart_i2c_sel  (.A(cfg_glb_ctrl[7]),.X(uart_i2c_sel));
 
 // To reduce the load/Timing Wishbone I/F, Strobe is register to create
 // multi-cycle