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