usb1 host is integrated
diff --git a/openlane/uart_i2cm_usb/base.sdc b/openlane/uart_i2cm_usb/base.sdc
new file mode 100644
index 0000000..e5db97c
--- /dev/null
+++ b/openlane/uart_i2cm_usb/base.sdc
@@ -0,0 +1,83 @@
+# 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_uart_core.u_lineclk_buf/X"
+set ::env(LINE_CLOCK_NAME) "line_clk"
+
+set ::env(USB_CLOCK_PERIOD) "100"
+set ::env(USB_CLOCK_PORT) "usb_clk"
+set ::env(USB_CLOCK_NAME) "usb_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)
+create_clock [get_ports $::env(USB_CLOCK_PORT)] -name $::env(USB_CLOCK_NAME) -period $::env(USB_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]
+
+set usb_input_delay_value [expr $::env(USB_CLOCK_PERIOD) * 0.6]
+set usb_output_delay_value [expr $::env(USB_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)] {usb_rstn}
+set_input_delay 2.0 -clock [get_clocks $::env(CORE_CLOCK_NAME)] {uart_i2c_usb_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_usb/config.tcl b/openlane/uart_i2cm_usb/config.tcl
new file mode 100644
index 0000000..2d2c5f3
--- /dev/null
+++ b/openlane/uart_i2cm_usb/config.tcl
@@ -0,0 +1,106 @@
+# 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_usb_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 usb_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_wb.sv \
+ $script_dir/../../verilog/rtl/lib/async_fifo.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/usb1_host/src/core/usbh_core.sv \
+ $script_dir/../../verilog/rtl/usb1_host/src/core/usbh_crc16.sv \
+ $script_dir/../../verilog/rtl/usb1_host/src/core/usbh_crc5.sv \
+ $script_dir/../../verilog/rtl/usb1_host/src/core/usbh_fifo.sv \
+ $script_dir/../../verilog/rtl/usb1_host/src/core/usbh_sie.sv \
+ $script_dir/../../verilog/rtl/usb1_host/src/phy/usb_fs_phy.v \
+ $script_dir/../../verilog/rtl/usb1_host/src/phy/usb_transceiver.v\
+ $script_dir/../../verilog/rtl/usb1_host/src/top/usb1_host.sv \
+ $script_dir/../../verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv\
+ "
+
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(VERILOG_INCLUDE_DIRS) [glob $script_dir/../../verilog/rtl/i2cm/src/includes $script_dir/../../verilog/rtl/usb1_host/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 600.0 700.0]
+
+set ::env(PL_TARGET_DENSITY) "0.45"
+
+
+# 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_usb/pdn.tcl b/openlane/uart_i2cm_usb/pdn.tcl
new file mode 100644
index 0000000..1fe689b
--- /dev/null
+++ b/openlane/uart_i2cm_usb/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_usb/pin_order.cfg b/openlane/uart_i2cm_usb/pin_order.cfg
new file mode 100644
index 0000000..394ddc6
--- /dev/null
+++ b/openlane/uart_i2cm_usb/pin_order.cfg
@@ -0,0 +1,92 @@
+#BUS_SORT
+#MANUAL_PLACE
+
+#S
+app_clk 0000 0
+usb_clk
+uart_rstn
+i2c_rstn
+usb_rstn
+uart_i2c_usb_sel\[1\]
+uart_i2c_usb_sel\[0\]
+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
+reg_addr\[3\]
+reg_addr\[2\]
+reg_addr\[1\]
+reg_addr\[0\]
+reg_be
+reg_wdata\[31\]
+reg_wdata\[30\]
+reg_wdata\[29\]
+reg_wdata\[28\]
+reg_wdata\[27\]
+reg_wdata\[26\]
+reg_wdata\[25\]
+reg_wdata\[24\]
+reg_wdata\[23\]
+reg_wdata\[22\]
+reg_wdata\[21\]
+reg_wdata\[20\]
+reg_wdata\[19\]
+reg_wdata\[18\]
+reg_wdata\[17\]
+reg_wdata\[16\]
+reg_wdata\[15\]
+reg_wdata\[14\]
+reg_wdata\[13\]
+reg_wdata\[12\]
+reg_wdata\[11\]
+reg_wdata\[10\]
+reg_wdata\[9\]
+reg_wdata\[8\]
+reg_wdata\[7\]
+reg_wdata\[6\]
+reg_wdata\[5\]
+reg_wdata\[4\]
+reg_wdata\[3\]
+reg_wdata\[2\]
+reg_wdata\[1\]
+reg_wdata\[0\]
+
+reg_rdata\[31\]
+reg_rdata\[30\]
+reg_rdata\[29\]
+reg_rdata\[28\]
+reg_rdata\[27\]
+reg_rdata\[26\]
+reg_rdata\[25\]
+reg_rdata\[24\]
+reg_rdata\[23\]
+reg_rdata\[22\]
+reg_rdata\[21\]
+reg_rdata\[20\]
+reg_rdata\[19\]
+reg_rdata\[18\]
+reg_rdata\[17\]
+reg_rdata\[16\]
+reg_rdata\[15\]
+reg_rdata\[14\]
+reg_rdata\[13\]
+reg_rdata\[12\]
+reg_rdata\[11\]
+reg_rdata\[10\]
+reg_rdata\[9\]
+reg_rdata\[8\]
+reg_rdata\[7\]
+reg_rdata\[6\]
+reg_rdata\[5\]
+reg_rdata\[4\]
+reg_rdata\[3\]
+reg_rdata\[2\]
+reg_rdata\[1\]
+reg_rdata\[0\]
+reg_ack
diff --git a/openlane/uart_i2cm_usb/sta.tcl b/openlane/uart_i2cm_usb/sta.tcl
new file mode 100644
index 0000000..ef1ab52
--- /dev/null
+++ b/openlane/uart_i2cm_usb/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 acb43f8..908108a 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_i2cm.v \
+ $script_dir/../../verilog/gl/uart_i2cm_usb.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_i2cm.lef \
+ $lef_root/uart_i2cm_usb.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_i2cm.gds \
+ $gds_root/uart_i2cm_usb.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 0d6ef5c..890ad90 100644
--- a/openlane/user_project_wrapper/macro.cfg
+++ b/openlane/user_project_wrapper/macro.cfg
@@ -2,12 +2,12 @@
u_sdram_ctrl 1000 2700 N
u_glbl_cfg 2000 2700 N
u_riscv_top 500 800 N
-u_uart_i2c 2200 1600 N
+u_uart_i2c_usb 2200 1000 N
u_intercon 300 2300 N
u_wb_host 300 300 N
u_skew_wi 2600 2300 N
u_skew_riscv 500 600 N
-u_skew_uart 2200 1400 N
+u_skew_uart 2200 800 N
u_skew_spi 150 2700 N
u_skew_sdram 800 2700 N
u_skew_glbl 1850 2850 N
diff --git a/openlane/wb_host/pin_order.cfg b/openlane/wb_host/pin_order.cfg
index 41f63b5..4b8ace2 100644
--- a/openlane/wb_host/pin_order.cfg
+++ b/openlane/wb_host/pin_order.cfg
@@ -303,5 +303,8 @@
uart_rst_n
i2cm_rst_n
-uart_i2c_sel
+usb_rst_n
+usb_clk
+uart_i2c_usb_sel\[1\]
+uart_i2c_usb_sel\[0\]
wbd_int_rst_n
diff --git a/openlane/wb_interconnect/config.tcl b/openlane/wb_interconnect/config.tcl
index 31e4c0c..14cc00b 100755
--- a/openlane/wb_interconnect/config.tcl
+++ b/openlane/wb_interconnect/config.tcl
@@ -58,7 +58,7 @@
set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
set ::env(FP_SIZING) absolute
-set ::env(DIE_AREA) "0 0 2200 200"
+set ::env(DIE_AREA) "0 0 2200 150"
# If you're going to use multiple power domains, then keep this disabled.
@@ -68,14 +68,14 @@
set ::env(PL_ROUTABILITY_DRIVEN) 1
-set ::env(FP_CORE_UTIL) "40"
+set ::env(FP_CORE_UTIL) "50"
set ::env(PL_TARGET_DENSITY) "0.50"
set ::env(FP_IO_VEXTEND) 4
set ::env(FP_IO_HEXTEND) 4
-set ::env(FP_PDN_VPITCH) 100
-set ::env(FP_PDN_HPITCH) 100
+set ::env(FP_PDN_VPITCH) 180
+set ::env(FP_PDN_HPITCH) 180
set ::env(FP_PDN_VWIDTH) 3
set ::env(FP_PDN_HWIDTH) 3
diff --git a/openlane/wb_interconnect/pin_order.cfg b/openlane/wb_interconnect/pin_order.cfg
index d9a23b2..6c64bb6 100644
--- a/openlane/wb_interconnect/pin_order.cfg
+++ b/openlane/wb_interconnect/pin_order.cfg
@@ -339,6 +339,30 @@
s3_wbd_adr_o\[1\]
s3_wbd_adr_o\[0\]
s3_wbd_sel_o
+s3_wbd_dat_o\[31\]
+s3_wbd_dat_o\[30\]
+s3_wbd_dat_o\[29\]
+s3_wbd_dat_o\[28\]
+s3_wbd_dat_o\[27\]
+s3_wbd_dat_o\[26\]
+s3_wbd_dat_o\[25\]
+s3_wbd_dat_o\[24\]
+s3_wbd_dat_o\[23\]
+s3_wbd_dat_o\[22\]
+s3_wbd_dat_o\[21\]
+s3_wbd_dat_o\[20\]
+s3_wbd_dat_o\[19\]
+s3_wbd_dat_o\[18\]
+s3_wbd_dat_o\[17\]
+s3_wbd_dat_o\[16\]
+s3_wbd_dat_o\[15\]
+s3_wbd_dat_o\[14\]
+s3_wbd_dat_o\[13\]
+s3_wbd_dat_o\[12\]
+s3_wbd_dat_o\[11\]
+s3_wbd_dat_o\[10\]
+s3_wbd_dat_o\[9\]
+s3_wbd_dat_o\[8\]
s3_wbd_dat_o\[7\]
s3_wbd_dat_o\[6\]
s3_wbd_dat_o\[5\]
@@ -347,6 +371,30 @@
s3_wbd_dat_o\[2\]
s3_wbd_dat_o\[1\]
s3_wbd_dat_o\[0\]
+s3_wbd_dat_i\[31\]
+s3_wbd_dat_i\[30\]
+s3_wbd_dat_i\[29\]
+s3_wbd_dat_i\[28\]
+s3_wbd_dat_i\[27\]
+s3_wbd_dat_i\[26\]
+s3_wbd_dat_i\[25\]
+s3_wbd_dat_i\[24\]
+s3_wbd_dat_i\[23\]
+s3_wbd_dat_i\[22\]
+s3_wbd_dat_i\[21\]
+s3_wbd_dat_i\[20\]
+s3_wbd_dat_i\[19\]
+s3_wbd_dat_i\[18\]
+s3_wbd_dat_i\[17\]
+s3_wbd_dat_i\[16\]
+s3_wbd_dat_i\[15\]
+s3_wbd_dat_i\[14\]
+s3_wbd_dat_i\[13\]
+s3_wbd_dat_i\[12\]
+s3_wbd_dat_i\[11\]
+s3_wbd_dat_i\[10\]
+s3_wbd_dat_i\[9\]
+s3_wbd_dat_i\[8\]
s3_wbd_dat_i\[7\]
s3_wbd_dat_i\[6\]
s3_wbd_dat_i\[5\]
diff --git a/signoff/uart_i2cm_usb/OPENLANE_VERSION b/signoff/uart_i2cm_usb/OPENLANE_VERSION
new file mode 100644
index 0000000..a2633b1
--- /dev/null
+++ b/signoff/uart_i2cm_usb/OPENLANE_VERSION
@@ -0,0 +1 @@
+openlane rc7
diff --git a/signoff/uart_i2cm_usb/PDK_SOURCES b/signoff/uart_i2cm_usb/PDK_SOURCES
new file mode 100644
index 0000000..8b58bd5
--- /dev/null
+++ b/signoff/uart_i2cm_usb/PDK_SOURCES
@@ -0,0 +1,6 @@
+-ne openlane
+a68c95289612a361870acedb7f6478fcfae32e49
+-ne skywater-pdk
+f6f76f3dc99526c6fc2cfede19b5b1227d4ebde7
+-ne open_pdks
+522a373441a865fee9d6e3783015b4445f11afe6
diff --git a/signoff/uart_i2cm_usb/final_summary_report.csv b/signoff/uart_i2cm_usb/final_summary_report.csv
new file mode 100644
index 0000000..13363a8
--- /dev/null
+++ b/signoff/uart_i2cm_usb/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_usb,uart_i2c_usb_top,uart_i2cm_usb,Flow_completed,0h16m6s,0h9m12s,59161.90476190476,0.42,29580.95238095238,45,750.65,12424,0,0,0,0,0,0,0,5,0,-1,0,545243,100005,-3.02,-3.02,-2.96,-2.96,-2.99,-3.02,-3.02,-2.96,-2.96,-2.99,401510839,0.0,32.16,31.62,0.14,-1,-1,12403,12472,2256,2325,0,0,0,12424,357,10,210,251,2101,326,79,2682,2216,2171,28,498,5146,0,5644,76.98229407236336,12.99,10,AREA 0,4,50,1,100,100,0.45,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 cca124b..372147b 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,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
+0,/project/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,Flow_completed,0h47m26s,0h5m5s,3.3079078455790785,10.2784,1.6539539227895392,0,535.21,17,0,0,0,0,0,0,0,0,1,-1,-1,1233077,4164,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1,0.0,1.32,4.38,0.91,2.49,-1,902,1520,902,1520,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 2002da3..6cfa445 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,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
+0,/project/openlane/wb_host,wb_host,wb_host,Flow_completed,0h5m45s,0h3m52s,61420.0,0.1,30710.0,49,584.24,3071,0,0,0,0,0,0,0,1,0,-1,0,169825,26579,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,137139540,0.0,48.41,23.36,15.76,-1,-1,2926,3181,554,809,0,0,0,3071,78,0,3,11,50,27,10,797,605,773,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/signoff/wb_interconnect/final_summary_report.csv b/signoff/wb_interconnect/final_summary_report.csv
index 078e36d..d112ceb 100644
--- a/signoff/wb_interconnect/final_summary_report.csv
+++ b/signoff/wb_interconnect/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_interconnect,wb_interconnect,wb_interconnect,Flow_completed,0h8m12s,0h4m43s,7824.242424242424,0.33,3912.121212121212,7,548.17,1291,0,0,0,0,0,0,0,1,0,-1,0,392265,17144,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,341299996,0.0,36.24,7.66,20.54,-1,-1,1041,1614,204,777,0,0,0,1291,244,0,75,15,111,0,0,180,431,414,11,94,3794,0,3888,100.0,10.0,10,AREA 0,4,50,1,180,180,0.55,0,sky130_fd_sc_hd,4,4
+0,/project/openlane/wb_interconnect,wb_interconnect,wb_interconnect,Flow_completed,0h7m34s,0h4m2s,8309.090909090908,0.33,4154.545454545454,7,560.27,1371,0,0,0,0,0,0,0,3,0,-1,0,437491,18179,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,388524110,0.0,40.74,7.91,23.43,-1,-1,1097,1718,204,825,0,0,0,1371,244,0,75,15,135,0,0,180,455,438,11,94,3794,0,3888,100.0,10.0,10,AREA 0,4,50,1,180,180,0.5,0,sky130_fd_sc_hd,4,4
diff --git a/verilog/dv/risc_boot/Makefile b/verilog/dv/risc_boot/Makefile
index 5289713..8930c81 100644
--- a/verilog/dv/risc_boot/Makefile
+++ b/verilog/dv/risc_boot/Makefile
@@ -31,6 +31,7 @@
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
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
## SYNTACORE FIRMWARE
SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
@@ -67,6 +68,7 @@
-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) \
+ -I $(UPRJ_INCLUDE_PATH4) \
$< -o $@
else
iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/risc_boot/risc_boot_tb.v b/verilog/dv/risc_boot/risc_boot_tb.v
index 6d503fc..fca35ca 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_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_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+ force uut.mprj.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPB =USER_VDD1V8;
+ force uut.mprj.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VGND =VSS;
+ force uut.mprj.u_uart_i2c_usb.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;
@@ -472,10 +472,10 @@
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_buf_usb_rst.VPWR =USER_VDD1V8;
+ force uut.mprj.u_wb_host.u_buf_usb_rst.VPB =USER_VDD1V8;
+ force uut.mprj.u_wb_host.u_buf_usb_rst.VGND =VSS;
+ force uut.mprj.u_wb_host.u_buf_usb_rst.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;
@@ -492,6 +492,11 @@
force uut.mprj.u_wb_host.u_clkbuf_rtc.VGND =VSS;
force uut.mprj.u_wb_host.u_clkbuf_rtc.VNB = VSS;
+ force uut.mprj.u_wb_host.u_clkbuf_usb.VPWR =USER_VDD1V8;
+ force uut.mprj.u_wb_host.u_clkbuf_usb.VPB =USER_VDD1V8;
+ force uut.mprj.u_wb_host.u_clkbuf_usb.VGND =VSS;
+ force uut.mprj.u_wb_host.u_clkbuf_usb.VNB = VSS;
+
end
`endif
diff --git a/verilog/dv/user_i2cm/Makefile b/verilog/dv/user_i2cm/Makefile
index 7955725..f27ba34 100644
--- a/verilog/dv/user_i2cm/Makefile
+++ b/verilog/dv/user_i2cm/Makefile
@@ -32,6 +32,7 @@
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
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
## SYNTACORE FIRMWARE
SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
@@ -68,6 +69,7 @@
-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) \
+ -I $(UPRJ_INCLUDE_PATH4) \
$< -o $@
else
iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
diff --git a/verilog/dv/user_i2cm/uprj_netlists.v b/verilog/dv/user_i2cm/uprj_netlists.v
index bea5a49..647e7c5 100644
--- a/verilog/dv/user_i2cm/uprj_netlists.v
+++ b/verilog/dv/user_i2cm/uprj_netlists.v
@@ -65,7 +65,16 @@
`include "i2cm/src/core/i2cm_byte_ctrl.v"
`include "i2cm/src/core/i2cm_top.v"
- `include "uart_i2c/src/uart_i2c_top.sv"
+ `include "usb1_host/src/core/usbh_core.sv"
+ `include "usb1_host/src/core/usbh_crc16.sv"
+ `include "usb1_host/src/core/usbh_crc5.sv"
+ `include "usb1_host/src/core/usbh_fifo.sv"
+ `include "usb1_host/src/core/usbh_sie.sv"
+ `include "usb1_host/src/phy/usb_fs_phy.v"
+ `include "usb1_host/src/phy/usb_transceiver.v"
+ `include "usb1_host/src/top/usb1_host.sv"
+
+ `include "uart_i2c_usb/src/uart_i2c_usb.sv"
`include "sdram_ctrl/src/top/sdrc_top.v"
`include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v"
diff --git a/verilog/dv/user_i2cm/user_i2cm_tb.v b/verilog/dv/user_i2cm/user_i2cm_tb.v
index b518419..650c9de 100644
--- a/verilog/dv/user_i2cm/user_i2cm_tb.v
+++ b/verilog/dv/user_i2cm/user_i2cm_tb.v
@@ -394,10 +394,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_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_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPB =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VGND =VSS;
+ force u_top.u_uart_i2c_usb.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;
@@ -429,10 +429,10 @@
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_buf_usb_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_usb_rst.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;
@@ -449,6 +449,10 @@
force u_top.u_wb_host.u_clkbuf_rtc.VGND =VSS;
force u_top.u_wb_host.u_clkbuf_rtc.VNB = VSS;
+ force u_top.u_wb_host.u_clkbuf_usb.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VGND =VSS;
+ force u_top.u_wb_host.u_clkbuf_usb.VNB = VSS;
end
`endif
//------------------------------------------------------
diff --git a/verilog/dv/user_risc_boot/Makefile b/verilog/dv/user_risc_boot/Makefile
index 79260aa..9a747be 100644
--- a/verilog/dv/user_risc_boot/Makefile
+++ b/verilog/dv/user_risc_boot/Makefile
@@ -32,6 +32,7 @@
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
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
## SYNTACORE FIRMWARE
SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
@@ -68,6 +69,7 @@
-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) \
+ -I $(UPRJ_INCLUDE_PATH4) \
$< -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 bea5a49..647e7c5 100644
--- a/verilog/dv/user_risc_boot/uprj_netlists.v
+++ b/verilog/dv/user_risc_boot/uprj_netlists.v
@@ -65,7 +65,16 @@
`include "i2cm/src/core/i2cm_byte_ctrl.v"
`include "i2cm/src/core/i2cm_top.v"
- `include "uart_i2c/src/uart_i2c_top.sv"
+ `include "usb1_host/src/core/usbh_core.sv"
+ `include "usb1_host/src/core/usbh_crc16.sv"
+ `include "usb1_host/src/core/usbh_crc5.sv"
+ `include "usb1_host/src/core/usbh_fifo.sv"
+ `include "usb1_host/src/core/usbh_sie.sv"
+ `include "usb1_host/src/phy/usb_fs_phy.v"
+ `include "usb1_host/src/phy/usb_transceiver.v"
+ `include "usb1_host/src/top/usb1_host.sv"
+
+ `include "uart_i2c_usb/src/uart_i2c_usb.sv"
`include "sdram_ctrl/src/top/sdrc_top.v"
`include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v"
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 0f0cf53..f7539a2 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_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_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPB =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VGND =VSS;
+ force u_top.u_uart_i2c_usb.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;
@@ -342,10 +342,10 @@
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_buf_usb_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_usb_rst.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;
@@ -361,6 +361,11 @@
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;
+
+ force u_top.u_wb_host.u_clkbuf_usb.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VGND =VSS;
+ force u_top.u_wb_host.u_clkbuf_usb.VNB = VSS;
end
`endif
diff --git a/verilog/dv/user_spi/Makefile b/verilog/dv/user_spi/Makefile
index 04cb921..273745d 100644
--- a/verilog/dv/user_spi/Makefile
+++ b/verilog/dv/user_spi/Makefile
@@ -32,6 +32,7 @@
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
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
## SYNTACORE FIRMWARE
SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
@@ -68,6 +69,7 @@
-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) \
+ -I $(UPRJ_INCLUDE_PATH4) \
$< -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 bea5a49..647e7c5 100644
--- a/verilog/dv/user_spi/uprj_netlists.v
+++ b/verilog/dv/user_spi/uprj_netlists.v
@@ -65,7 +65,16 @@
`include "i2cm/src/core/i2cm_byte_ctrl.v"
`include "i2cm/src/core/i2cm_top.v"
- `include "uart_i2c/src/uart_i2c_top.sv"
+ `include "usb1_host/src/core/usbh_core.sv"
+ `include "usb1_host/src/core/usbh_crc16.sv"
+ `include "usb1_host/src/core/usbh_crc5.sv"
+ `include "usb1_host/src/core/usbh_fifo.sv"
+ `include "usb1_host/src/core/usbh_sie.sv"
+ `include "usb1_host/src/phy/usb_fs_phy.v"
+ `include "usb1_host/src/phy/usb_transceiver.v"
+ `include "usb1_host/src/top/usb1_host.sv"
+
+ `include "uart_i2c_usb/src/uart_i2c_usb.sv"
`include "sdram_ctrl/src/top/sdrc_top.v"
`include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v"
diff --git a/verilog/dv/user_spi/user_spi_tb.v b/verilog/dv/user_spi/user_spi_tb.v
index ca0fd97..1a44919 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_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_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPB =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VGND =VSS;
+ force u_top.u_uart_i2c_usb.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;
@@ -1204,10 +1204,10 @@
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_buf_usb_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_usb_rst.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;
@@ -1223,6 +1223,11 @@
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;
+
+ force u_top.u_wb_host.u_clkbuf_usb.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VGND =VSS;
+ force u_top.u_wb_host.u_clkbuf_usb.VNB = VSS;
end
`endif
diff --git a/verilog/dv/user_uart/Makefile b/verilog/dv/user_uart/Makefile
index c9afd5e..273e55e 100644
--- a/verilog/dv/user_uart/Makefile
+++ b/verilog/dv/user_uart/Makefile
@@ -32,6 +32,7 @@
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
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
## SYNTACORE FIRMWARE
SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common
@@ -68,6 +69,7 @@
-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) \
+ -I $(UPRJ_INCLUDE_PATH4) \
$< -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 3ce562e..e461fd1 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 ../../../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 -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 ../../../verilog/rtl/usb1_host/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 bea5a49..647e7c5 100644
--- a/verilog/dv/user_uart/uprj_netlists.v
+++ b/verilog/dv/user_uart/uprj_netlists.v
@@ -65,7 +65,16 @@
`include "i2cm/src/core/i2cm_byte_ctrl.v"
`include "i2cm/src/core/i2cm_top.v"
- `include "uart_i2c/src/uart_i2c_top.sv"
+ `include "usb1_host/src/core/usbh_core.sv"
+ `include "usb1_host/src/core/usbh_crc16.sv"
+ `include "usb1_host/src/core/usbh_crc5.sv"
+ `include "usb1_host/src/core/usbh_fifo.sv"
+ `include "usb1_host/src/core/usbh_sie.sv"
+ `include "usb1_host/src/phy/usb_fs_phy.v"
+ `include "usb1_host/src/phy/usb_transceiver.v"
+ `include "usb1_host/src/top/usb1_host.sv"
+
+ `include "uart_i2c_usb/src/uart_i2c_usb.sv"
`include "sdram_ctrl/src/top/sdrc_top.v"
`include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v"
diff --git a/verilog/dv/user_uart/user_uart_tb.v b/verilog/dv/user_uart/user_uart_tb.v
index c3efb15..3a70b08 100644
--- a/verilog/dv/user_uart/user_uart_tb.v
+++ b/verilog/dv/user_uart/user_uart_tb.v
@@ -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_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_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPB =USER_VDD1V8;
+ force u_top.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VGND =VSS;
+ force u_top.u_uart_i2c_usb.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;
@@ -382,10 +382,10 @@
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_buf_usb_rst.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_buf_usb_rst.VGND =VSS;
+ force u_top.u_wb_host.u_buf_usb_rst.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;
@@ -402,6 +402,10 @@
force u_top.u_wb_host.u_clkbuf_rtc.VGND =VSS;
force u_top.u_wb_host.u_clkbuf_rtc.VNB = VSS;
+ force u_top.u_wb_host.u_clkbuf_usb.VPWR =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VPB =USER_VDD1V8;
+ force u_top.u_wb_host.u_clkbuf_usb.VGND =VSS;
+ force u_top.u_wb_host.u_clkbuf_usb.VNB = VSS;
end
`endif
//------------------------------------------------------
diff --git a/verilog/dv/wb_port/Makefile b/verilog/dv/wb_port/Makefile
index cb66907..ca3c53e 100644
--- a/verilog/dv/wb_port/Makefile
+++ b/verilog/dv/wb_port/Makefile
@@ -30,6 +30,7 @@
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
+UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes
## RISCV GCC
GCC_PATH?=/ef/apps/bin
@@ -55,6 +56,7 @@
-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_PATH3) \
+ -I $(UPRJ_INCLUDE_PATH4) \
$< -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 80538fe..aaef0a1 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_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_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPWR =USER_VDD1V8;
+ force uut.mprj.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VPB =USER_VDD1V8;
+ force uut.mprj.u_uart_i2c_usb.u_uart_core.u_lineclk_buf.VGND =VSS;
+ force uut.mprj.u_uart_i2c_usb.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;
@@ -256,10 +256,10 @@
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_buf_usb_rst.VPWR =USER_VDD1V8;
+ force uut.mprj.u_wb_host.u_buf_usb_rst.VPB =USER_VDD1V8;
+ force uut.mprj.u_wb_host.u_buf_usb_rst.VGND =VSS;
+ force uut.mprj.u_wb_host.u_buf_usb_rst.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;
@@ -276,6 +276,11 @@
force uut.mprj.u_wb_host.u_clkbuf_rtc.VGND =VSS;
force uut.mprj.u_wb_host.u_clkbuf_rtc.VNB = VSS;
+ force uut.mprj.u_wb_host.u_clkbuf_usb.VPWR =USER_VDD1V8;
+ force uut.mprj.u_wb_host.u_clkbuf_usb.VPB =USER_VDD1V8;
+ force uut.mprj.u_wb_host.u_clkbuf_usb.VGND =VSS;
+ force uut.mprj.u_wb_host.u_clkbuf_usb.VNB = VSS;
+
end
`endif
endmodule
diff --git a/verilog/rtl/lib/async_wb.sv b/verilog/rtl/lib/async_wb.sv
index ecad725..4e5d4a6 100644
--- a/verilog/rtl/lib/async_wb.sv
+++ b/verilog/rtl/lib/async_wb.sv
@@ -67,18 +67,22 @@
//// ////
//////////////////////////////////////////////////////////////////////
-module async_wb (
+module async_wb
+ #(parameter AW = 32,
+ parameter BW = 4,
+ parameter DW = 32)
+ (
// Master Port
input logic wbm_rst_n , // Regular Reset signal
input logic wbm_clk_i , // System clock
input logic wbm_cyc_i , // strobe/request
input logic wbm_stb_i , // strobe/request
- input logic [31:0] wbm_adr_i , // address
+ input logic [AW-1:0] wbm_adr_i , // address
input logic wbm_we_i , // write
- input logic [31:0] wbm_dat_i , // data output
- input logic [3:0] wbm_sel_i , // byte enable
- output logic [31:0] wbm_dat_o , // data input
+ input logic [DW-1:0] wbm_dat_i , // data output
+ input logic [BW-1:0] wbm_sel_i , // byte enable
+ output logic [DW-1:0] wbm_dat_o , // data input
output logic wbm_ack_o , // acknowlegement
output logic wbm_err_o , // error
@@ -87,11 +91,11 @@
input logic wbs_clk_i , // System clock
output logic wbs_cyc_o , // strobe/request
output logic wbs_stb_o , // strobe/request
- output logic [31:0] wbs_adr_o , // address
+ output logic [AW-1:0] wbs_adr_o , // address
output logic wbs_we_o , // write
- output logic [31:0] wbs_dat_o , // data output
- output logic [3:0] wbs_sel_o , // byte enable
- input logic [31:0] wbs_dat_i , // data input
+ output logic [DW-1:0] wbs_dat_o , // data output
+ output logic [BW-1:0] wbs_sel_o , // byte enable
+ input logic [DW-1:0] wbs_dat_i , // data input
input logic wbs_ack_i , // acknowlegement
input logic wbs_err_i // error
@@ -99,20 +103,21 @@
+parameter CFW = AW+DW+BW+1 ; // COMMAND FIFO WIDTH
//-------------------------------------------------
// Master Interface
// -------------------------------------------------
-logic PendingRd ; // Pending Read Transaction
-logic m_cmd_wr_en ;
-logic [68:0] m_cmd_wr_data ;
-logic m_cmd_wr_full ;
-logic m_cmd_wr_afull ;
+logic PendingRd ; // Pending Read Transaction
+logic m_cmd_wr_en ;
+logic [CFW-1:0] m_cmd_wr_data ;
+logic m_cmd_wr_full ;
+logic m_cmd_wr_afull ;
-logic m_resp_rd_empty ;
-logic m_resp_rd_aempty ;
-logic m_resp_rd_en ;
-logic [32:0] m_resp_rd_data ;
+logic m_resp_rd_empty ;
+logic m_resp_rd_aempty ;
+logic m_resp_rd_en ;
+logic [DW:0] m_resp_rd_data ;
// Master Write Interface
@@ -142,20 +147,20 @@
(wbm_stb_i && (!wbm_we_i)) ? !m_resp_rd_empty : 1'b0; // Read Logic
assign m_resp_rd_en = !m_resp_rd_empty;
-assign wbm_dat_o = m_resp_rd_data[31:0];
-assign wbm_err_o = m_resp_rd_data[32];
+assign wbm_dat_o = m_resp_rd_data[DW-1:0];
+assign wbm_err_o = m_resp_rd_data[DW];
//------------------------------
// Slave Interface
//-------------------------------
-logic [68:0] s_cmd_rd_data ;
+logic [CFW-1:0] s_cmd_rd_data ;
logic s_cmd_rd_empty ;
logic s_cmd_rd_aempty ;
logic s_cmd_rd_en ;
logic s_resp_wr_en ;
-logic [32:0] s_resp_wr_data ;
+logic [DW:0] s_resp_wr_data ;
logic s_resp_wr_full ;
logic s_resp_wr_afull ;
logic wbs_ack_f ;
@@ -185,7 +190,7 @@
assign s_resp_wr_en = wbs_stb_o & (!wbs_we_o) & wbs_ack_i & !s_resp_wr_full;
assign s_resp_wr_data = {wbs_err_i,wbs_dat_i};
-async_fifo #(.W(69), .DP(4), .WR_FAST(1), .RD_FAST(1)) u_cmd_if (
+async_fifo #(.W(CFW), .DP(4), .WR_FAST(1), .RD_FAST(1)) u_cmd_if (
// Sync w.r.t WR clock
.wr_clk (wbm_clk_i ),
.wr_reset_n (wbm_rst_n ),
@@ -206,7 +211,7 @@
// Response used only read path, read is blocking access, expect
// only one location used in return path - reduced the depth to 2
-async_fifo #(.W(33), .DP(2), .WR_FAST(1), .RD_FAST(1)) u_resp_if (
+async_fifo #(.W(DW+1), .DP(2), .WR_FAST(1), .RD_FAST(1)) u_resp_if (
// Sync w.r.t WR clock
.wr_clk (wbs_clk_i ),
.wr_reset_n (wbs_rst_n ),
diff --git a/verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv b/verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv
new file mode 100644
index 0000000..ad97a12
--- /dev/null
+++ b/verilog/rtl/uart_i2c_usb/src/uart_i2c_usb.sv
@@ -0,0 +1,245 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// integrated UART/I2C Master & USB1.1 Host ////
+//// ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// ////
+//// Description: This module integarte Uart and I2C Master ////
+//// and USB 1.1 Host. Both these block share common two pins, ////
+//// effectly only one block active at time. This is due to ////
+//// top-level pin restriction. ////
+//// ////
+//// Pin Maping UART I2C USB ////
+//// IO[1] - TXD SDA DP ////
+//// IO[0] - RXD SCL DN ////
+//// ////
+//// 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_usb_top
+
+ (
+
+ input logic uart_rstn , // async reset
+ input logic i2c_rstn , // async reset
+ input logic usb_rstn , // async reset
+ input logic app_clk ,
+ input logic usb_clk , // 48Mhz usb clock
+ input logic [1:0] uart_i2c_usb_sel, // Uart Or I2C Or USB Interface Select
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [3:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic reg_be,
+
+ // Outputs
+ output logic [31: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)
+
+/////////////////////////////////////////////////////////
+// usb interface
+///////////////////////////////////////////////////////
+logic usb_in_dp ;
+logic usb_in_dn ;
+
+logic usb_out_dp ;
+logic usb_out_dn ;
+logic usb_out_tx_oen ;
+
+`define SEL_UART 2'b00
+`define SEL_I2C 2'b01
+`define SEL_USB 2'b10
+
+assign io_oeb[0] = (uart_i2c_usb_sel == `SEL_UART) ? 1'b1 :
+ (uart_i2c_usb_sel == `SEL_I2C) ? scl_pad_oen_o : usb_out_tx_oen ;
+assign uart_rxd = (uart_i2c_usb_sel == `SEL_UART) ? io_in[0]: 1'b0;
+assign scl_pad_i = (uart_i2c_usb_sel == `SEL_I2C) ? io_in[0]: 1'b0;
+assign usb_in_dn = (uart_i2c_usb_sel == `SEL_USB) ? io_in[0]: 1'b0;
+assign io_out[0] = (uart_i2c_usb_sel == `SEL_UART) ? 1'b0 :
+ (uart_i2c_usb_sel == `SEL_I2C) ? scl_pad_o : usb_out_dn;
+
+
+assign io_oeb[1] = (uart_i2c_usb_sel == `SEL_UART) ? 1'b0 :
+ (uart_i2c_usb_sel == `SEL_I2C) ? sda_padoen_o : usb_out_tx_oen ;
+assign io_out[1] = (uart_i2c_usb_sel == `SEL_UART) ? uart_txd:
+ (uart_i2c_usb_sel == `SEL_I2C) ? sda_pad_o : usb_out_dp;
+assign sda_pad_i = (uart_i2c_usb_sel == `SEL_I2C) ? io_in[1] : 1'b0;
+assign usb_in_dp = (uart_i2c_usb_sel == `SEL_USB) ? io_in[1] : 1'b0;
+
+
+//----------------------------------------
+// Register Response Path Mux
+// --------------------------------------
+logic [7:0] reg_uart_rdata;
+logic [7:0] reg_i2c_rdata;
+logic [31:0] reg_usb_rdata;
+logic reg_uart_ack;
+logic reg_i2c_ack;
+logic reg_usb_ack;
+
+
+assign reg_rdata = (uart_i2c_usb_sel == `SEL_UART) ? {24'h0,reg_uart_rdata} :
+ (uart_i2c_usb_sel == `SEL_I2C) ? {24'h0,reg_i2c_rdata} : reg_usb_rdata;
+assign reg_ack = (uart_i2c_usb_sel == `SEL_UART) ? reg_uart_ack :
+ (uart_i2c_usb_sel == `SEL_I2C) ? reg_i2c_ack : reg_usb_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[7:0] ), // 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)
+
+ );
+
+
+usb1_host u_usb_host (
+ .usb_clk_i (usb_clk ),
+ .usb_rstn_i (usb_rstn ),
+
+ // USB D+/D-
+ .in_dp (usb_in_dp ),
+ .in_dn (usb_in_dn ),
+
+ .out_dp (usb_out_dp ),
+ .out_dn (usb_out_dn ),
+ .out_tx_oen (usb_out_tx_oen),
+
+ // Master Port
+ .wbm_rst_n (usb_rstn ), // Regular Reset signal
+ .wbm_clk_i (app_clk ), // System clock
+ .wbm_stb_i (reg_cs ), // strobe/request
+ .wbm_adr_i ({reg_addr[3:0],
+ 2'b0} ), // address
+ .wbm_we_i (reg_wr ), // write
+ .wbm_dat_i (reg_wdata ), // data output
+ .wbm_sel_i (reg_be ), // byte enable
+ .wbm_dat_o (reg_usb_rdata ), // data input
+ .wbm_ack_o (reg_usb_ack ), // acknowlegement
+ .wbm_err_o ( ), // error
+
+ // Outputs
+ .usb_intr_o ( )
+
+
+ );
+
+
+endmodule
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v
index 07f2cda..815677d 100644
--- a/verilog/rtl/uprj_netlists.v
+++ b/verilog/rtl/uprj_netlists.v
@@ -65,7 +65,16 @@
`include "i2cm/src/core/i2cm_byte_ctrl.v"
`include "i2cm/src/core/i2cm_top.v"
- `include "uart_i2c/src/uart_i2c_top.sv"
+ `include "usb1_host/src/core/usbh_core.sv"
+ `include "usb1_host/src/core/usbh_crc16.sv"
+ `include "usb1_host/src/core/usbh_crc5.sv"
+ `include "usb1_host/src/core/usbh_fifo.sv"
+ `include "usb1_host/src/core/usbh_sie.sv"
+ `include "usb1_host/src/phy/usb_fs_phy.v"
+ `include "usb1_host/src/phy/usb_transceiver.v"
+ `include "usb1_host/src/top/usb1_host.sv"
+
+ `include "uart_i2c_usb/src/uart_i2c_usb.sv"
`include "sdram_ctrl/src/top/sdrc_top.v"
`include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v"
diff --git a/verilog/rtl/usb1_host/src/core/usbh_core.sv b/verilog/rtl/usb1_host/src/core/usbh_core.sv
new file mode 100644
index 0000000..adffecb
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_core.sv
@@ -0,0 +1,1019 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+`include "usbh_host_defs.v"
+
+//-----------------------------------------------------------------
+// Module: USB Host IP
+//-----------------------------------------------------------------
+module usbh_core
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+#(
+ parameter USB_CLK_FREQ = 48000000
+)
+//-----------------------------------------------------------------
+// Ports
+//-----------------------------------------------------------------
+(
+ // Inputs
+ input logic clk_i,
+ input logic rstn_i,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [5:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ // UTMI Input
+ input logic [7:0] utmi_data_in_i,
+ input logic utmi_txready_i,
+ input logic utmi_rxvalid_i,
+ input logic utmi_rxactive_i,
+ input logic utmi_rxerror_i,
+ input logic [1:0] utmi_linestate_i,
+
+ // UTMI Outputs
+ output logic intr_o,
+ output logic [7:0] utmi_data_out_o,
+ output logic utmi_txvalid_o,
+ output logic [1:0] utmi_op_mode_o,
+ output logic [1:0] utmi_xcvrselect_o,
+ output logic utmi_termselect_o,
+ output logic utmi_dppulldown_o,
+ output logic utmi_dmpulldown_o
+);
+
+
+reg [31:0] reg_rdata_r;
+wire [15:0] usb_status_sof_time_in_w;
+wire usb_status_rx_error_in_w;
+wire [1:0] usb_status_linestate_bits_in_w;
+wire usb_irq_sts_device_detect_in_w;
+wire usb_irq_sts_err_in_w;
+wire usb_irq_sts_done_in_w;
+wire usb_irq_sts_sof_in_w;
+wire usb_rx_stat_start_pend_in_w;
+wire usb_rx_stat_crc_err_in_w;
+wire usb_rx_stat_resp_timeout_in_w;
+wire usb_rx_stat_idle_in_w;
+wire [7:0] usb_rx_stat_resp_bits_in_w;
+wire [15:0] usb_rx_stat_count_bits_in_w;
+wire [7:0] usb_rd_data_data_in_w;
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+logic cfg_wr;
+
+always @ (posedge clk_i or negedge rstn_i)
+begin : preg_out_Seq
+ if (rstn_i == 1'b0) begin
+ reg_rdata [31:0] <= 32'h0000_0000;
+ reg_ack <= 1'b0;
+ cfg_wr <= 1'b0;
+ end else if (reg_cs && (reg_wr == 0) && !reg_ack) begin
+ reg_rdata [31:0] <= reg_rdata_r [31:0];
+ reg_ack <= 1'b1;
+ end else if (reg_cs && (reg_wr == 1) && !reg_ack) begin
+ reg_ack <= 1'b1;
+ cfg_wr <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ cfg_wr <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------
+// Register usb_ctrl
+//-----------------------------------------------------------------
+reg usb_ctrl_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_wr_q <= 1'b1;
+else
+ usb_ctrl_wr_q <= 1'b0;
+
+// usb_ctrl_tx_flush [auto_clr]
+reg usb_ctrl_tx_flush_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_tx_flush_q <= 1'd`USB_CTRL_TX_FLUSH_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_tx_flush_q <= reg_wdata[`USB_CTRL_TX_FLUSH_R];
+else
+ usb_ctrl_tx_flush_q <= 1'd`USB_CTRL_TX_FLUSH_DEFAULT;
+
+wire usb_ctrl_tx_flush_out_w = usb_ctrl_tx_flush_q;
+
+
+// usb_ctrl_phy_dmpulldown [internal]
+reg usb_ctrl_phy_dmpulldown_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_dmpulldown_q <= 1'd`USB_CTRL_PHY_DMPULLDOWN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_dmpulldown_q <= reg_wdata[`USB_CTRL_PHY_DMPULLDOWN_R];
+
+wire usb_ctrl_phy_dmpulldown_out_w = usb_ctrl_phy_dmpulldown_q;
+
+
+// usb_ctrl_phy_dppulldown [internal]
+reg usb_ctrl_phy_dppulldown_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_dppulldown_q <= 1'd`USB_CTRL_PHY_DPPULLDOWN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_dppulldown_q <= reg_wdata[`USB_CTRL_PHY_DPPULLDOWN_R];
+
+wire usb_ctrl_phy_dppulldown_out_w = usb_ctrl_phy_dppulldown_q;
+
+
+// usb_ctrl_phy_termselect [internal]
+reg usb_ctrl_phy_termselect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_termselect_q <= 1'd`USB_CTRL_PHY_TERMSELECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_termselect_q <= reg_wdata[`USB_CTRL_PHY_TERMSELECT_R];
+
+wire usb_ctrl_phy_termselect_out_w = usb_ctrl_phy_termselect_q;
+
+
+// usb_ctrl_phy_xcvrselect [internal]
+reg [1:0] usb_ctrl_phy_xcvrselect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_xcvrselect_q <= 2'd`USB_CTRL_PHY_XCVRSELECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_xcvrselect_q <= reg_wdata[`USB_CTRL_PHY_XCVRSELECT_R];
+
+wire [1:0] usb_ctrl_phy_xcvrselect_out_w = usb_ctrl_phy_xcvrselect_q;
+
+
+// usb_ctrl_phy_opmode [internal]
+reg [1:0] usb_ctrl_phy_opmode_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_phy_opmode_q <= 2'd`USB_CTRL_PHY_OPMODE_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_phy_opmode_q <= reg_wdata[`USB_CTRL_PHY_OPMODE_R];
+
+wire [1:0] usb_ctrl_phy_opmode_out_w = usb_ctrl_phy_opmode_q;
+
+
+// usb_ctrl_enable_sof [internal]
+reg usb_ctrl_enable_sof_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_ctrl_enable_sof_q <= 1'd`USB_CTRL_ENABLE_SOF_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_CTRL))
+ usb_ctrl_enable_sof_q <= reg_wdata[`USB_CTRL_ENABLE_SOF_R];
+
+wire usb_ctrl_enable_sof_out_w = usb_ctrl_enable_sof_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_status
+//-----------------------------------------------------------------
+reg usb_status_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_status_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_STATUS))
+ usb_status_wr_q <= 1'b1;
+else
+ usb_status_wr_q <= 1'b0;
+
+
+
+
+//-----------------------------------------------------------------
+// Register usb_irq_ack
+//-----------------------------------------------------------------
+reg usb_irq_ack_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_wr_q <= 1'b1;
+else
+ usb_irq_ack_wr_q <= 1'b0;
+
+// usb_irq_ack_device_detect [auto_clr]
+reg usb_irq_ack_device_detect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_device_detect_q <= 1'd`USB_IRQ_ACK_DEVICE_DETECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_device_detect_q <= reg_wdata[`USB_IRQ_ACK_DEVICE_DETECT_R];
+else
+ usb_irq_ack_device_detect_q <= 1'd`USB_IRQ_ACK_DEVICE_DETECT_DEFAULT;
+
+wire usb_irq_ack_device_detect_out_w = usb_irq_ack_device_detect_q;
+
+
+// usb_irq_ack_err [auto_clr]
+reg usb_irq_ack_err_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_err_q <= 1'd`USB_IRQ_ACK_ERR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_err_q <= reg_wdata[`USB_IRQ_ACK_ERR_R];
+else
+ usb_irq_ack_err_q <= 1'd`USB_IRQ_ACK_ERR_DEFAULT;
+
+wire usb_irq_ack_err_out_w = usb_irq_ack_err_q;
+
+
+// usb_irq_ack_done [auto_clr]
+reg usb_irq_ack_done_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_done_q <= 1'd`USB_IRQ_ACK_DONE_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_done_q <= reg_wdata[`USB_IRQ_ACK_DONE_R];
+else
+ usb_irq_ack_done_q <= 1'd`USB_IRQ_ACK_DONE_DEFAULT;
+
+wire usb_irq_ack_done_out_w = usb_irq_ack_done_q;
+
+
+// usb_irq_ack_sof [auto_clr]
+reg usb_irq_ack_sof_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_ack_sof_q <= 1'd`USB_IRQ_ACK_SOF_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_ACK))
+ usb_irq_ack_sof_q <= reg_wdata[`USB_IRQ_ACK_SOF_R];
+else
+ usb_irq_ack_sof_q <= 1'd`USB_IRQ_ACK_SOF_DEFAULT;
+
+wire usb_irq_ack_sof_out_w = usb_irq_ack_sof_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_irq_sts
+//-----------------------------------------------------------------
+reg usb_irq_sts_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_sts_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_STS))
+ usb_irq_sts_wr_q <= 1'b1;
+else
+ usb_irq_sts_wr_q <= 1'b0;
+
+
+
+
+
+//-----------------------------------------------------------------
+// Register usb_irq_mask
+//-----------------------------------------------------------------
+reg usb_irq_mask_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_wr_q <= 1'b1;
+else
+ usb_irq_mask_wr_q <= 1'b0;
+
+// usb_irq_mask_device_detect [internal]
+reg usb_irq_mask_device_detect_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_device_detect_q <= 1'd`USB_IRQ_MASK_DEVICE_DETECT_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_device_detect_q <= reg_wdata[`USB_IRQ_MASK_DEVICE_DETECT_R];
+
+wire usb_irq_mask_device_detect_out_w = usb_irq_mask_device_detect_q;
+
+
+// usb_irq_mask_err [internal]
+reg usb_irq_mask_err_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_err_q <= 1'd`USB_IRQ_MASK_ERR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_err_q <= reg_wdata[`USB_IRQ_MASK_ERR_R];
+
+wire usb_irq_mask_err_out_w = usb_irq_mask_err_q;
+
+
+// usb_irq_mask_done [internal]
+reg usb_irq_mask_done_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_done_q <= 1'd`USB_IRQ_MASK_DONE_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_done_q <= reg_wdata[`USB_IRQ_MASK_DONE_R];
+
+wire usb_irq_mask_done_out_w = usb_irq_mask_done_q;
+
+
+// usb_irq_mask_sof [internal]
+reg usb_irq_mask_sof_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_irq_mask_sof_q <= 1'd`USB_IRQ_MASK_SOF_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_IRQ_MASK))
+ usb_irq_mask_sof_q <= reg_wdata[`USB_IRQ_MASK_SOF_R];
+
+wire usb_irq_mask_sof_out_w = usb_irq_mask_sof_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_xfer_data
+//-----------------------------------------------------------------
+reg usb_xfer_data_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_data_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_DATA))
+ usb_xfer_data_wr_q <= 1'b1;
+else
+ usb_xfer_data_wr_q <= 1'b0;
+
+// usb_xfer_data_tx_len [internal]
+reg [15:0] usb_xfer_data_tx_len_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_data_tx_len_q <= 16'd`USB_XFER_DATA_TX_LEN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_DATA))
+ usb_xfer_data_tx_len_q <= reg_wdata[`USB_XFER_DATA_TX_LEN_R];
+
+wire [15:0] usb_xfer_data_tx_len_out_w = usb_xfer_data_tx_len_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_xfer_token
+//-----------------------------------------------------------------
+reg usb_xfer_token_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_wr_q <= 1'b1;
+else
+ usb_xfer_token_wr_q <= 1'b0;
+
+// usb_xfer_token_start [clearable]
+reg usb_xfer_token_start_q;
+
+wire usb_xfer_token_start_ack_in_w;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_start_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_start_q <= reg_wdata[`USB_XFER_TOKEN_START_R];
+else if (usb_xfer_token_start_ack_in_w)
+ usb_xfer_token_start_q <= 1'b0;
+
+wire usb_xfer_token_start_out_w = usb_xfer_token_start_q;
+
+
+// usb_xfer_token_in [internal]
+reg usb_xfer_token_in_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_in_q <= 1'd`USB_XFER_TOKEN_IN_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_in_q <= reg_wdata[`USB_XFER_TOKEN_IN_R];
+
+wire usb_xfer_token_in_out_w = usb_xfer_token_in_q;
+
+
+// usb_xfer_token_ack [internal]
+reg usb_xfer_token_ack_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_ack_q <= 1'd`USB_XFER_TOKEN_ACK_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_ack_q <= reg_wdata[`USB_XFER_TOKEN_ACK_R];
+
+wire usb_xfer_token_ack_out_w = usb_xfer_token_ack_q;
+
+
+// usb_xfer_token_pid_datax [internal]
+reg usb_xfer_token_pid_datax_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_pid_datax_q <= 1'd`USB_XFER_TOKEN_PID_DATAX_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_pid_datax_q <= reg_wdata[`USB_XFER_TOKEN_PID_DATAX_R];
+
+wire usb_xfer_token_pid_datax_out_w = usb_xfer_token_pid_datax_q;
+
+
+// usb_xfer_token_pid_bits [internal]
+reg [7:0] usb_xfer_token_pid_bits_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_pid_bits_q <= 8'd`USB_XFER_TOKEN_PID_BITS_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_pid_bits_q <= reg_wdata[`USB_XFER_TOKEN_PID_BITS_R];
+
+wire [7:0] usb_xfer_token_pid_bits_out_w = usb_xfer_token_pid_bits_q;
+
+
+// usb_xfer_token_dev_addr [internal]
+reg [6:0] usb_xfer_token_dev_addr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_dev_addr_q <= 7'd`USB_XFER_TOKEN_DEV_ADDR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_dev_addr_q <= reg_wdata[`USB_XFER_TOKEN_DEV_ADDR_R];
+
+wire [6:0] usb_xfer_token_dev_addr_out_w = usb_xfer_token_dev_addr_q;
+
+
+// usb_xfer_token_ep_addr [internal]
+reg [3:0] usb_xfer_token_ep_addr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_xfer_token_ep_addr_q <= 4'd`USB_XFER_TOKEN_EP_ADDR_DEFAULT;
+else if (cfg_wr && (reg_addr[5:0] == `USB_XFER_TOKEN))
+ usb_xfer_token_ep_addr_q <= reg_wdata[`USB_XFER_TOKEN_EP_ADDR_R];
+
+wire [3:0] usb_xfer_token_ep_addr_out_w = usb_xfer_token_ep_addr_q;
+
+
+//-----------------------------------------------------------------
+// Register usb_rx_stat
+//-----------------------------------------------------------------
+reg usb_rx_stat_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_rx_stat_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_RX_STAT))
+ usb_rx_stat_wr_q <= 1'b1;
+else
+ usb_rx_stat_wr_q <= 1'b0;
+
+
+
+//-----------------------------------------------------------------
+// Retime write data
+//-----------------------------------------------------------------
+reg [31:0] wr_data_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ wr_data_q <= 32'b0;
+else if (cfg_wr)
+ wr_data_q <= reg_wdata;
+
+
+
+
+//-----------------------------------------------------------------
+// Register usb_wr_data
+//-----------------------------------------------------------------
+reg usb_wr_data_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_wr_data_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_WR_DATA))
+ usb_wr_data_wr_q <= 1'b1;
+else
+ usb_wr_data_wr_q <= 1'b0;
+
+// usb_wr_data_data [external]
+wire [7:0] usb_wr_data_data_out_w = wr_data_q[`USB_WR_DATA_DATA_R];
+
+//-----------------------------------------------------------------
+// Read mux
+//-----------------------------------------------------------------
+
+always @ *
+begin
+ reg_rdata_r = 32'b0;
+
+ case (reg_addr[5:0])
+
+ `USB_CTRL:
+ begin
+ reg_rdata_r[`USB_CTRL_PHY_DMPULLDOWN_R] = usb_ctrl_phy_dmpulldown_q;
+ reg_rdata_r[`USB_CTRL_PHY_DPPULLDOWN_R] = usb_ctrl_phy_dppulldown_q;
+ reg_rdata_r[`USB_CTRL_PHY_TERMSELECT_R] = usb_ctrl_phy_termselect_q;
+ reg_rdata_r[`USB_CTRL_PHY_XCVRSELECT_R] = usb_ctrl_phy_xcvrselect_q;
+ reg_rdata_r[`USB_CTRL_PHY_OPMODE_R] = usb_ctrl_phy_opmode_q;
+ reg_rdata_r[`USB_CTRL_ENABLE_SOF_R] = usb_ctrl_enable_sof_q;
+ end
+ `USB_STATUS:
+ begin
+ reg_rdata_r[`USB_STATUS_SOF_TIME_R] = usb_status_sof_time_in_w;
+ reg_rdata_r[`USB_STATUS_RX_ERROR_R] = usb_status_rx_error_in_w;
+ reg_rdata_r[`USB_STATUS_LINESTATE_BITS_R] = usb_status_linestate_bits_in_w;
+ end
+ `USB_IRQ_STS:
+ begin
+ reg_rdata_r[`USB_IRQ_STS_DEVICE_DETECT_R] = usb_irq_sts_device_detect_in_w;
+ reg_rdata_r[`USB_IRQ_STS_ERR_R] = usb_irq_sts_err_in_w;
+ reg_rdata_r[`USB_IRQ_STS_DONE_R] = usb_irq_sts_done_in_w;
+ reg_rdata_r[`USB_IRQ_STS_SOF_R] = usb_irq_sts_sof_in_w;
+ end
+ `USB_IRQ_MASK:
+ begin
+ reg_rdata_r[`USB_IRQ_MASK_DEVICE_DETECT_R] = usb_irq_mask_device_detect_q;
+ reg_rdata_r[`USB_IRQ_MASK_ERR_R] = usb_irq_mask_err_q;
+ reg_rdata_r[`USB_IRQ_MASK_DONE_R] = usb_irq_mask_done_q;
+ reg_rdata_r[`USB_IRQ_MASK_SOF_R] = usb_irq_mask_sof_q;
+ end
+ `USB_XFER_DATA:
+ begin
+ reg_rdata_r[`USB_XFER_DATA_TX_LEN_R] = usb_xfer_data_tx_len_q;
+ end
+ `USB_XFER_TOKEN:
+ begin
+ reg_rdata_r[`USB_XFER_TOKEN_IN_R] = usb_xfer_token_in_q;
+ reg_rdata_r[`USB_XFER_TOKEN_ACK_R] = usb_xfer_token_ack_q;
+ reg_rdata_r[`USB_XFER_TOKEN_PID_DATAX_R] = usb_xfer_token_pid_datax_q;
+ reg_rdata_r[`USB_XFER_TOKEN_PID_BITS_R] = usb_xfer_token_pid_bits_q;
+ reg_rdata_r[`USB_XFER_TOKEN_DEV_ADDR_R] = usb_xfer_token_dev_addr_q;
+ reg_rdata_r[`USB_XFER_TOKEN_EP_ADDR_R] = usb_xfer_token_ep_addr_q;
+ end
+ `USB_RX_STAT:
+ begin
+ reg_rdata_r[`USB_RX_STAT_START_PEND_R] = usb_rx_stat_start_pend_in_w;
+ reg_rdata_r[`USB_RX_STAT_CRC_ERR_R] = usb_rx_stat_crc_err_in_w;
+ reg_rdata_r[`USB_RX_STAT_RESP_TIMEOUT_R] = usb_rx_stat_resp_timeout_in_w;
+ reg_rdata_r[`USB_RX_STAT_IDLE_R] = usb_rx_stat_idle_in_w;
+ reg_rdata_r[`USB_RX_STAT_RESP_BITS_R] = usb_rx_stat_resp_bits_in_w;
+ reg_rdata_r[`USB_RX_STAT_COUNT_BITS_R] = usb_rx_stat_count_bits_in_w;
+ end
+ `USB_RD_DATA:
+ begin
+ reg_rdata_r[`USB_RD_DATA_DATA_R] = usb_rd_data_data_in_w;
+ end
+ default :
+ reg_rdata_r = 32'b0;
+ endcase
+end
+
+//-----------------------------------------------------------------
+// Register usb_rd_data
+//-----------------------------------------------------------------
+reg usb_rd_data_wr_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_rd_data_wr_q <= 1'b0;
+else if (cfg_wr && (reg_addr[5:0] == `USB_RD_DATA))
+ usb_rd_data_wr_q <= 1'b1;
+else
+ usb_rd_data_wr_q <= 1'b0;
+
+
+
+wire usb_rd_data_rd_req_w = reg_cs & (reg_wr==0) & (!reg_ack) & (reg_addr[5:0] == `USB_RD_DATA);
+
+wire usb_wr_data_wr_req_w = usb_wr_data_wr_q;
+wire usb_rd_data_wr_req_w = usb_rd_data_wr_q;
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+// SOF
+reg [10:0] sof_value_q;
+reg [15:0] sof_time_q;
+reg sof_irq_q;
+
+reg transfer_req_ack_q;
+
+wire [7:0] fifo_tx_data_w;
+wire fifo_tx_pop_w;
+
+wire [7:0] fifo_rx_data_w;
+wire fifo_rx_push_w;
+
+reg fifo_flush_q;
+
+wire [7:0] token_pid_w;
+wire [6:0] token_dev_w;
+wire [3:0] token_ep_w;
+
+reg transfer_start_q;
+reg in_transfer_q;
+reg sof_transfer_q;
+reg resp_expected_q;
+wire transfer_ack_w;
+
+wire status_crc_err_w;
+wire status_timeout_w;
+wire [7:0] status_response_w;
+wire [15:0] status_rx_count_w;
+wire status_sie_idle_w;
+wire status_tx_done_w;
+wire status_rx_done_w;
+
+wire send_sof_w;
+wire sof_gaurd_band_w;
+wire clear_to_send_w;
+
+reg usb_err_q;
+
+reg intr_done_q;
+reg intr_sof_q;
+reg intr_err_q;
+
+//-----------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------
+localparam SOF_ZERO = 0;
+localparam SOF_INC = 1;
+localparam SOF_THRESHOLD = (USB_CLK_FREQ/1000)-1;
+
+localparam CLKS_PER_BIT = (USB_CLK_FREQ / 12000000); // input clks per FS bit time
+
+localparam EOF1_THRESHOLD = (50 * CLKS_PER_BIT); // EOF1 + some margin
+localparam MAX_XFER_SIZE = 64;
+localparam MAX_XFER_PERIOD = ((MAX_XFER_SIZE + 6) * 10 * CLKS_PER_BIT); // Max packet transfer time (+ margin)
+localparam SOF_GAURD_LOW = (20 * CLKS_PER_BIT);
+localparam SOF_GAURD_HIGH = SOF_THRESHOLD - EOF1_THRESHOLD - MAX_XFER_PERIOD;
+
+localparam PID_SOF = 8'hA5;
+
+//-----------------------------------------------------------------
+// SIE
+//-----------------------------------------------------------------
+usbh_sie
+#( .USB_CLK_FREQ(USB_CLK_FREQ) )
+u_sie
+(
+ // Clock & reset
+ .clk_i(clk_i),
+ .rstn_i(rstn_i),
+
+ // Control
+ .start_i(transfer_start_q),
+ .in_transfer_i(in_transfer_q),
+ .sof_transfer_i(sof_transfer_q),
+ .resp_expected_i(resp_expected_q),
+ .ack_o(transfer_ack_w),
+
+ // Token packet
+ .token_pid_i(token_pid_w),
+ .token_dev_i(token_dev_w),
+ .token_ep_i(token_ep_w),
+
+ // Data packet
+ .data_len_i(usb_xfer_data_tx_len_out_w),
+ .data_idx_i(usb_xfer_token_pid_datax_out_w),
+
+ // Tx Data FIFO
+ .tx_data_i(fifo_tx_data_w),
+ .tx_pop_o(fifo_tx_pop_w),
+
+ // Rx Data FIFO
+ .rx_data_o(fifo_rx_data_w),
+ .rx_push_o(fifo_rx_push_w),
+
+ // Status
+ .rx_done_o(status_rx_done_w),
+ .tx_done_o(status_tx_done_w),
+ .crc_err_o(status_crc_err_w),
+ .timeout_o(status_timeout_w),
+ .response_o(status_response_w),
+ .rx_count_o(status_rx_count_w),
+ .idle_o(status_sie_idle_w),
+
+ // UTMI Interface
+ .utmi_data_o(utmi_data_out_o),
+ .utmi_txvalid_o(utmi_txvalid_o),
+ .utmi_txready_i(utmi_txready_i),
+ .utmi_data_i(utmi_data_in_i),
+ .utmi_rxvalid_i(utmi_rxvalid_i),
+ .utmi_rxactive_i(utmi_rxactive_i),
+ .utmi_linestate_i(utmi_linestate_i)
+);
+
+//-----------------------------------------------------------------
+// Peripheral Interface
+//-----------------------------------------------------------------
+assign usb_status_sof_time_in_w = sof_time_q;
+assign usb_status_rx_error_in_w = usb_err_q;
+assign usb_status_linestate_bits_in_w = utmi_linestate_i;
+
+assign usb_irq_sts_err_in_w = intr_err_q;
+assign usb_irq_sts_done_in_w = intr_done_q;
+assign usb_irq_sts_sof_in_w = intr_sof_q;
+
+assign usb_rx_stat_start_pend_in_w = usb_xfer_token_start_out_w;
+assign usb_rx_stat_crc_err_in_w = status_crc_err_w;
+assign usb_rx_stat_resp_timeout_in_w = status_timeout_w;
+assign usb_rx_stat_idle_in_w = status_sie_idle_w;
+assign usb_rx_stat_resp_bits_in_w = status_response_w;
+assign usb_rx_stat_count_bits_in_w = status_rx_count_w;
+
+assign usb_xfer_token_start_ack_in_w = transfer_req_ack_q;
+
+assign utmi_op_mode_o = usb_ctrl_phy_opmode_out_w;
+assign utmi_xcvrselect_o = usb_ctrl_phy_xcvrselect_out_w;
+assign utmi_termselect_o = usb_ctrl_phy_termselect_out_w;
+assign utmi_dppulldown_o = usb_ctrl_phy_dppulldown_out_w;
+assign utmi_dmpulldown_o = usb_ctrl_phy_dmpulldown_out_w;
+
+//-----------------------------------------------------------------
+// Tx FIFO (Host -> Device)
+//-----------------------------------------------------------------
+usbh_fifo
+u_fifo_tx
+(
+ .clk_i(clk_i),
+ .rstn_i(rstn_i),
+
+ .data_i(usb_wr_data_data_out_w),
+ .push_i(usb_wr_data_wr_req_w),
+
+ .flush_i(usb_ctrl_tx_flush_out_w),
+
+ .full_o(),
+ .empty_o(),
+
+ .data_o(fifo_tx_data_w),
+ .pop_i(fifo_tx_pop_w)
+);
+
+//-----------------------------------------------------------------
+// Rx FIFO (Device -> Host)
+//-----------------------------------------------------------------
+usbh_fifo
+u_fifo_rx
+(
+ .clk_i(clk_i),
+ .rstn_i(rstn_i),
+
+ // Receive from UTMI interface
+ .data_i(fifo_rx_data_w),
+ .push_i(fifo_rx_push_w),
+
+ .flush_i(fifo_flush_q),
+
+ .full_o(),
+ .empty_o(),
+
+ .data_o(usb_rd_data_data_in_w),
+ .pop_i(usb_rd_data_rd_req_w)
+);
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+assign send_sof_w = ({16'b0, sof_time_q} == SOF_THRESHOLD && usb_ctrl_enable_sof_out_w) & status_sie_idle_w;
+assign sof_gaurd_band_w = ({16'b0, sof_time_q} <= SOF_GAURD_LOW || {16'b0, sof_time_q} >= SOF_GAURD_HIGH);
+assign clear_to_send_w = (~sof_gaurd_band_w | ~usb_ctrl_enable_sof_out_w) & status_sie_idle_w;
+
+assign token_pid_w = sof_transfer_q ? PID_SOF : usb_xfer_token_pid_bits_out_w;
+
+assign token_dev_w = sof_transfer_q ?
+ {sof_value_q[0], sof_value_q[1], sof_value_q[2],
+ sof_value_q[3], sof_value_q[4], sof_value_q[5], sof_value_q[6]} :
+ {usb_xfer_token_dev_addr_out_w[0], usb_xfer_token_dev_addr_out_w[1], usb_xfer_token_dev_addr_out_w[2], usb_xfer_token_dev_addr_out_w[3], usb_xfer_token_dev_addr_out_w[4], usb_xfer_token_dev_addr_out_w[5], usb_xfer_token_dev_addr_out_w[6]};
+
+assign token_ep_w = sof_transfer_q ?
+ {sof_value_q[7], sof_value_q[8], sof_value_q[9], sof_value_q[10]} :
+ {usb_xfer_token_ep_addr_out_w[0], usb_xfer_token_ep_addr_out_w[1], usb_xfer_token_ep_addr_out_w[2], usb_xfer_token_ep_addr_out_w[3]};
+
+//-----------------------------------------------------------------
+// Control logic
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ fifo_flush_q <= 1'b0;
+ transfer_start_q <= 1'b0;
+ sof_transfer_q <= 1'b0;
+ transfer_req_ack_q <= 1'b0;
+ in_transfer_q <= 1'b0;
+ resp_expected_q <= 1'b0;
+end
+else
+begin
+ // Transfer in progress?
+ if (transfer_start_q)
+ begin
+ // Transfer accepted
+ if (transfer_ack_w)
+ transfer_start_q <= 1'b0;
+
+ fifo_flush_q <= 1'b0;
+ transfer_req_ack_q <= 1'b0;
+ end
+ // Time to send another SOF token?
+ else if (send_sof_w)
+ begin
+ // Start transfer
+ in_transfer_q <= 1'b0;
+ resp_expected_q <= 1'b0;
+ transfer_start_q <= 1'b1;
+ sof_transfer_q <= 1'b1;
+ end
+ // Not in SOF gaurd band region or SOF disabled?
+ else if (clear_to_send_w)
+ begin
+ // Transfer request
+ if (usb_xfer_token_start_out_w)
+ begin
+ // Flush un-used previous Rx data
+ fifo_flush_q <= 1'b1;
+
+ // Start transfer
+ in_transfer_q <= usb_xfer_token_in_out_w;
+ resp_expected_q <= usb_xfer_token_ack_out_w;
+ transfer_start_q <= 1'b1;
+ sof_transfer_q <= 1'b0;
+ transfer_req_ack_q <= 1'b1;
+ end
+ end
+end
+
+//-----------------------------------------------------------------
+// SOF Frame Number
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ sof_value_q <= 11'd0;
+ sof_time_q <= SOF_ZERO;
+ sof_irq_q <= 1'b0;
+end
+// Time to send another SOF token?
+else if (send_sof_w)
+begin
+ sof_time_q <= SOF_ZERO;
+ sof_value_q <= sof_value_q + 11'd1;
+
+ // Start of frame interrupt
+ sof_irq_q <= 1'b1;
+end
+else
+begin
+ // Increment the SOF timer
+ if ({16'b0, sof_time_q} != SOF_THRESHOLD)
+ sof_time_q <= sof_time_q + SOF_INC;
+
+ sof_irq_q <= 1'b0;
+end
+
+//-----------------------------------------------------------------
+// Record Errors
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ usb_err_q <= 1'b0;
+// Clear error
+else if (usb_ctrl_wr_q)
+ usb_err_q <= 1'b0;
+// Record bus errors
+else if (utmi_rxerror_i)
+ usb_err_q <= 1'b1;
+
+//-----------------------------------------------------------------
+// Interrupts
+//-----------------------------------------------------------------
+reg err_cond_q;
+reg intr_q;
+reg device_det_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ intr_done_q <= 1'b0;
+ intr_sof_q <= 1'b0;
+ intr_err_q <= 1'b0;
+ err_cond_q <= 1'b0;
+ device_det_q <= 1'b0;
+ intr_q <= 1'b0;
+end
+else
+begin
+ if (status_rx_done_w || status_tx_done_w)
+ intr_done_q <= 1'b1;
+ else if (usb_irq_ack_done_out_w)
+ intr_done_q <= 1'b0;
+
+ if (sof_irq_q)
+ intr_sof_q <= 1'b1;
+ else if (usb_irq_ack_sof_out_w)
+ intr_sof_q <= 1'b0;
+
+ if ((status_crc_err_w || status_timeout_w) && (!err_cond_q))
+ intr_err_q <= 1'b1;
+ else if (usb_irq_ack_err_out_w)
+ intr_err_q <= 1'b0;
+
+ // Line state != SE0
+ if (utmi_linestate_i != 2'b0)
+ device_det_q <= 1'b1;
+ else if (usb_irq_ack_device_detect_out_w)
+ device_det_q <= 1'b0;
+
+ err_cond_q <= (status_crc_err_w | status_timeout_w);
+
+ intr_q <= (intr_done_q & usb_irq_mask_done_out_w) |
+ (intr_err_q & usb_irq_mask_err_out_w) |
+ (intr_sof_q & usb_irq_mask_sof_out_w) |
+ (device_det_q & usb_irq_mask_device_detect_out_w);
+end
+
+assign usb_irq_sts_device_detect_in_w = 1'b0;
+
+assign intr_o = intr_q;
+
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_crc16.sv b/verilog/rtl/usb1_host/src/core/usbh_crc16.sv
new file mode 100644
index 0000000..11f767c
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_crc16.sv
@@ -0,0 +1,89 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+//-----------------------------------------------------------------
+// Module: 16-bit CRC used by USB data packets
+//-----------------------------------------------------------------
+module usbh_crc16
+(
+ input [15:0] crc_i,
+ input [7:0] data_i,
+ output [15:0] crc_o
+);
+
+//-----------------------------------------------------------------
+// Implementation
+//-----------------------------------------------------------------
+assign crc_o[15] = data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^
+ data_i[5] ^ data_i[6] ^ data_i[7] ^ crc_i[7] ^ crc_i[6] ^
+ crc_i[5] ^ crc_i[4] ^ crc_i[3] ^ crc_i[2] ^
+ crc_i[1] ^ crc_i[0];
+assign crc_o[14] = data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^ data_i[5] ^
+ data_i[6] ^ crc_i[6] ^ crc_i[5] ^ crc_i[4] ^
+ crc_i[3] ^ crc_i[2] ^ crc_i[1] ^ crc_i[0];
+assign crc_o[13] = data_i[6] ^ data_i[7] ^ crc_i[7] ^ crc_i[6];
+assign crc_o[12] = data_i[5] ^ data_i[6] ^ crc_i[6] ^ crc_i[5];
+assign crc_o[11] = data_i[4] ^ data_i[5] ^ crc_i[5] ^ crc_i[4];
+assign crc_o[10] = data_i[3] ^ data_i[4] ^ crc_i[4] ^ crc_i[3];
+assign crc_o[9] = data_i[2] ^ data_i[3] ^ crc_i[3] ^ crc_i[2];
+assign crc_o[8] = data_i[1] ^ data_i[2] ^ crc_i[2] ^ crc_i[1];
+assign crc_o[7] = data_i[0] ^ data_i[1] ^ crc_i[15] ^ crc_i[1] ^ crc_i[0];
+assign crc_o[6] = data_i[0] ^ crc_i[14] ^ crc_i[0];
+assign crc_o[5] = crc_i[13];
+assign crc_o[4] = crc_i[12];
+assign crc_o[3] = crc_i[11];
+assign crc_o[2] = crc_i[10];
+assign crc_o[1] = crc_i[9];
+assign crc_o[0] = data_i[0] ^ data_i[1] ^ data_i[2] ^ data_i[3] ^ data_i[4] ^ data_i[5] ^
+ data_i[6] ^ data_i[7] ^ crc_i[8] ^ crc_i[7] ^ crc_i[6] ^
+ crc_i[5] ^ crc_i[4] ^ crc_i[3] ^ crc_i[2] ^
+ crc_i[1] ^ crc_i[0];
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_crc5.sv b/verilog/rtl/usb1_host/src/core/usbh_crc5.sv
new file mode 100644
index 0000000..f125905
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_crc5.sv
@@ -0,0 +1,79 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+//-----------------------------------------------------------------
+// Module: 5-bit CRC used by USB tokens
+//-----------------------------------------------------------------
+module usbh_crc5
+(
+ input [4:0] crc_i,
+ input [10:0] data_i,
+ output [4:0] crc_o
+);
+
+//-----------------------------------------------------------------
+// Implementation
+//-----------------------------------------------------------------
+assign crc_o[0] = data_i[10] ^ data_i[9] ^ data_i[6] ^ data_i[5] ^ data_i[3] ^ data_i[0] ^
+ crc_i[0] ^ crc_i[3] ^ crc_i[4];
+
+assign crc_o[1] = data_i[10] ^ data_i[7] ^ data_i[6] ^ data_i[4] ^ data_i[1] ^
+ crc_i[0] ^ crc_i[1] ^ crc_i[4];
+
+assign crc_o[2] = data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[7] ^ data_i[6] ^ data_i[3] ^ data_i[2] ^ data_i[0] ^
+ crc_i[0] ^ crc_i[1] ^ crc_i[2] ^ crc_i[3] ^ crc_i[4];
+
+assign crc_o[3] = data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[7] ^ data_i[4] ^ data_i[3] ^ data_i[1] ^
+ crc_i[1] ^ crc_i[2] ^ crc_i[3] ^ crc_i[4];
+
+assign crc_o[4] = data_i[10] ^ data_i[9] ^ data_i[8] ^ data_i[5] ^ data_i[4] ^ data_i[2] ^
+ crc_i[2] ^ crc_i[3] ^ crc_i[4];
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_fifo.sv b/verilog/rtl/usb1_host/src/core/usbh_fifo.sv
new file mode 100644
index 0000000..67113c3
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_fifo.sv
@@ -0,0 +1,143 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usbh_fifo
+(
+ // Inputs
+ input clk_i
+ ,input rstn_i
+ ,input [ 7:0] data_i
+ ,input push_i
+ ,input pop_i
+ ,input flush_i
+
+ // Outputs
+ ,output full_o
+ ,output empty_o
+ ,output [ 7:0] data_o
+);
+
+
+
+parameter WIDTH = 8;
+parameter DEPTH = 64;
+parameter ADDR_W = 6;
+
+//-----------------------------------------------------------------
+// Local Params
+//-----------------------------------------------------------------
+localparam COUNT_W = ADDR_W + 1;
+
+//-----------------------------------------------------------------
+// Registers
+//-----------------------------------------------------------------
+reg [WIDTH-1:0] ram [DEPTH-1:0];
+reg [ADDR_W-1:0] rd_ptr;
+reg [ADDR_W-1:0] wr_ptr;
+reg [COUNT_W-1:0] count;
+
+//-----------------------------------------------------------------
+// Sequential
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ count <= {(COUNT_W) {1'b0}};
+ rd_ptr <= {(ADDR_W) {1'b0}};
+ wr_ptr <= {(ADDR_W) {1'b0}};
+end
+else
+begin
+
+ if (flush_i)
+ begin
+ count <= {(COUNT_W) {1'b0}};
+ rd_ptr <= {(ADDR_W) {1'b0}};
+ wr_ptr <= {(ADDR_W) {1'b0}};
+ end
+
+ // Push
+ if (push_i & ~full_o)
+ begin
+ ram[wr_ptr] <= data_i;
+ wr_ptr <= wr_ptr + 1;
+ end
+
+ // Pop
+ if (pop_i & ~empty_o)
+ begin
+ rd_ptr <= rd_ptr + 1;
+ end
+
+ // Count up
+ if ((push_i & ~full_o) & ~(pop_i & ~empty_o))
+ begin
+ count <= count + 1;
+ end
+ // Count down
+ else if (~(push_i & ~full_o) & (pop_i & ~empty_o))
+ begin
+ count <= count - 1;
+ end
+end
+
+//-------------------------------------------------------------------
+// Combinatorial
+//-------------------------------------------------------------------
+/* verilator lint_off WIDTH */
+assign full_o = (count == DEPTH);
+assign empty_o = (count == 0);
+/* verilator lint_on WIDTH */
+
+assign data_o = ram[rd_ptr];
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/core/usbh_sie.sv b/verilog/rtl/usb1_host/src/core/usbh_sie.sv
new file mode 100644
index 0000000..0d046c0
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/core/usbh_sie.sv
@@ -0,0 +1,846 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usbh_sie
+//-----------------------------------------------------------------
+// Params
+//-----------------------------------------------------------------
+#(
+ parameter USB_CLK_FREQ = 48000000
+)
+//-----------------------------------------------------------------
+// Ports
+//-----------------------------------------------------------------
+(
+ // Inputs
+ input clk_i,
+ input rstn_i,
+ input start_i,
+ input in_transfer_i,
+ input sof_transfer_i,
+ input resp_expected_i,
+ input [ 7:0] token_pid_i,
+ input [ 6:0] token_dev_i,
+ input [ 3:0] token_ep_i,
+ input [ 15:0] data_len_i,
+ input data_idx_i,
+ input [ 7:0] tx_data_i,
+ input utmi_txready_i,
+ input [ 7:0] utmi_data_i,
+ input utmi_rxvalid_i,
+ input utmi_rxactive_i,
+ input [ 1:0] utmi_linestate_i,
+
+ // Outputs
+ output ack_o,
+ output tx_pop_o,
+ output [ 7:0] rx_data_o,
+ output rx_push_o,
+ output tx_done_o,
+ output rx_done_o,
+ output crc_err_o,
+ output timeout_o,
+ output [ 7:0] response_o,
+ output [ 15:0] rx_count_o,
+ output idle_o,
+ output [ 7:0] utmi_data_o,
+ output utmi_txvalid_o
+);
+
+
+
+//-----------------------------------------------------------------
+// Registers / Wires
+//-----------------------------------------------------------------
+logic start_ack_q;
+
+// Status
+logic status_tx_done_q;
+logic status_rx_done_q;
+logic status_crc_err_q;
+logic status_timeout_q;
+logic [7:0] status_response_q;
+
+logic [15:0] byte_count_q;
+logic in_transfer_q;
+
+logic [8:0] last_tx_time_q;
+
+logic send_data1_q;
+logic send_sof_q;
+logic send_ack_q;
+
+// CRC16
+logic [15:0] crc_sum_q;
+logic [15:0] crc_out_w;
+logic [7:0] crc_data_in_w;
+
+// CRC5
+logic [4:0] crc5_out_w;
+wire [4:0] crc5_next_w = crc5_out_w ^ 5'h1F;
+
+logic [15:0] token_q;
+
+logic wait_resp_q;
+
+logic [3:0] state_q;
+
+//-----------------------------------------------------------------
+// Definitions
+//-----------------------------------------------------------------
+localparam RX_TIMEOUT = (USB_CLK_FREQ == 60000000) ? 9'd511 : 9'd255;
+ // 2 FS bit times (x5 CLKs @ 60MHz, x4 CLKs @ 48MHz)
+localparam TX_IFS = (USB_CLK_FREQ == 60000000) ? 4'd10 : 4'd7;
+
+localparam PID_OUT = 8'hE1;
+localparam PID_IN = 8'h69;
+localparam PID_SOF = 8'hA5;
+localparam PID_SETUP = 8'h2D;
+
+localparam PID_DATA0 = 8'hC3;
+localparam PID_DATA1 = 8'h4B;
+
+localparam PID_ACK = 8'hD2;
+localparam PID_NAK = 8'h5A;
+localparam PID_STALL = 8'h1E;
+
+// States
+localparam STATE_IDLE = 4'd0;
+localparam STATE_RX_DATA = 4'd1;
+localparam STATE_TX_PID = 4'd2;
+localparam STATE_TX_DATA = 4'd3;
+localparam STATE_TX_CRC1 = 4'd4;
+localparam STATE_TX_CRC2 = 4'd5;
+localparam STATE_TX_TOKEN1 = 4'd6;
+localparam STATE_TX_TOKEN2 = 4'd7;
+localparam STATE_TX_TOKEN3 = 4'd8;
+localparam STATE_TX_ACKNAK = 4'd9;
+localparam STATE_TX_WAIT = 4'd10;
+localparam STATE_RX_WAIT = 4'd11;
+localparam STATE_TX_IFS = 4'd12;
+
+//-----------------------------------------------------------------
+// Wires
+//-----------------------------------------------------------------
+// Rx data
+logic [7:0] rx_data_w;
+logic data_ready_w;
+logic crc_byte_w;
+logic rx_active_w;
+logic rx_active_rise_w;
+
+// Tx/Rx -> Tx IFS timeout
+logic ifs_busy_w;
+
+// Response timeout (no response after 500uS from transmit)
+wire rx_resp_timeout_w = (last_tx_time_q >= RX_TIMEOUT) & wait_resp_q;
+
+// CRC16 error on received data
+wire crc_error_w = (state_q == STATE_RX_DATA) && !rx_active_w && in_transfer_q &&
+ (status_response_q == PID_DATA0 || status_response_q == PID_DATA1) &&
+ (crc_sum_q != 16'hB001);
+
+//-----------------------------------------------------------------
+// State Machine
+//-----------------------------------------------------------------
+logic [3:0] next_state_r;
+
+always @ *
+begin
+ next_state_r = state_q;
+
+ //-----------------------------------------
+ // Tx State Machine
+ //-----------------------------------------
+ case (state_q)
+
+ //-----------------------------------------
+ // TX_TOKEN1 (byte 1 of token)
+ //-----------------------------------------
+ STATE_TX_TOKEN1 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_TX_TOKEN2;
+ end
+ //-----------------------------------------
+ // TX_TOKEN2 (byte 2 of token)
+ //-----------------------------------------
+ STATE_TX_TOKEN2 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_TX_TOKEN3;
+ end
+ //-----------------------------------------
+ // TX_TOKEN3 (byte 3 of token)
+ //-----------------------------------------
+ STATE_TX_TOKEN3 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ begin
+ // SOF - no data packet
+ if (send_sof_q)
+ next_state_r = STATE_TX_IFS;
+ // IN - wait for data
+ else if (in_transfer_q)
+ next_state_r = STATE_RX_WAIT;
+ // OUT/SETUP - Send data or ZLP
+ else
+ next_state_r = STATE_TX_IFS;
+ end
+ end
+ //-----------------------------------------
+ // TX_IFS
+ //-----------------------------------------
+ STATE_TX_IFS :
+ begin
+ // IFS expired
+ if (~ifs_busy_w)
+ begin
+ // SOF - no data packet
+ if (send_sof_q)
+ next_state_r = STATE_IDLE;
+ // OUT/SETUP - Send data or ZLP
+ else
+ next_state_r = STATE_TX_PID;
+ end
+ end
+ //-----------------------------------------
+ // TX_PID
+ //-----------------------------------------
+ STATE_TX_PID :
+ begin
+ // Last data byte sent?
+ if (utmi_txready_i && (byte_count_q == 16'b0))
+ next_state_r = STATE_TX_CRC1;
+ else if (utmi_txready_i)
+ next_state_r = STATE_TX_DATA;
+ end
+ //-----------------------------------------
+ // TX_DATA
+ //-----------------------------------------
+ STATE_TX_DATA :
+ begin
+ // Last data byte sent?
+ if (utmi_txready_i && (byte_count_q == 16'b0))
+ next_state_r = STATE_TX_CRC1;
+ end
+ //-----------------------------------------
+ // TX_CRC1 (first byte)
+ //-----------------------------------------
+ STATE_TX_CRC1 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_TX_CRC2;
+ end
+ //-----------------------------------------
+ // TX_CRC (second byte)
+ //-----------------------------------------
+ STATE_TX_CRC2 :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ begin
+ // If a response is expected
+ if (wait_resp_q)
+ next_state_r = STATE_RX_WAIT;
+ // No response expected (e.g ISO transfer)
+ else
+ next_state_r = STATE_IDLE;
+ end
+ end
+ //-----------------------------------------
+ // STATE_TX_WAIT
+ //-----------------------------------------
+ STATE_TX_WAIT :
+ begin
+ // Waited long enough?
+ if (~ifs_busy_w)
+ next_state_r = STATE_TX_ACKNAK;
+ end
+ //-----------------------------------------
+ // STATE_TX_ACKNAK
+ //-----------------------------------------
+ STATE_TX_ACKNAK :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_WAIT
+ //-----------------------------------------
+ STATE_RX_WAIT :
+ begin
+ // Data received?
+ if (data_ready_w)
+ next_state_r = STATE_RX_DATA;
+ // Waited long enough?
+ else if (rx_resp_timeout_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // RX_DATA
+ //-----------------------------------------
+ STATE_RX_DATA :
+ begin
+ // Receive complete
+ if (~rx_active_w)
+ begin
+ // Send ACK but incoming data had CRC error, do not ACK
+ if (send_ack_q && crc_error_w)
+ next_state_r = STATE_IDLE;
+ // Send an ACK response without CPU interaction?
+ else if (send_ack_q && (status_response_q == PID_DATA0 || status_response_q == PID_DATA1))
+ next_state_r = STATE_TX_WAIT;
+ else
+ next_state_r = STATE_IDLE;
+ end
+ end
+ //-----------------------------------------
+ // IDLE / RECEIVE BEGIN
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ // Token transfer request
+ if (start_i)
+ next_state_r = STATE_TX_TOKEN1;
+ end
+ default :
+ ;
+ endcase
+end
+
+// Update state
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ state_q <= STATE_IDLE;
+else
+ state_q <= next_state_r;
+
+//-----------------------------------------------------------------
+// Tx Token
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ token_q <= 16'h0000;
+else if (state_q == STATE_IDLE)
+ token_q <= {token_dev_i, token_ep_i, 5'b0};
+// PID of token sent, capture calculated CRC for token packet
+else if (state_q == STATE_TX_TOKEN1 && utmi_txready_i)
+ token_q[4:0] <= crc5_next_w;
+
+//-----------------------------------------------------------------
+// Tx EOP - detect end of transmit (token, data or ACK/NAK)
+//-----------------------------------------------------------------
+reg [1:0] utmi_linestate_q;
+reg se0_detect_q;
+reg wait_eop_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ utmi_linestate_q <= 2'b0;
+else
+ utmi_linestate_q <= utmi_linestate_i;
+
+// SE0 filtering (2 cycles FS)
+wire se0_detect_w = (utmi_linestate_q == 2'b00 && utmi_linestate_i == 2'b00);
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ se0_detect_q <= 1'b0;
+else
+ se0_detect_q <= se0_detect_w;
+
+// TODO: This needs updating for HS USB...
+wire eop_detected_w = se0_detect_q & (utmi_linestate_i != 2'b00);
+
+// End of transmit detection
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ wait_eop_q <= 1'b0;
+else if (eop_detected_w)
+ wait_eop_q <= 1'b0;
+else if ((state_q == STATE_TX_CRC2 && next_state_r != STATE_TX_CRC2) ||
+ (state_q == STATE_TX_TOKEN3 && next_state_r != STATE_TX_TOKEN3) ||
+ (state_q == STATE_TX_ACKNAK && next_state_r != STATE_TX_ACKNAK))
+ wait_eop_q <= 1'b1;
+else if (rx_active_rise_w)
+ wait_eop_q <= 1'b1;
+
+localparam TX_IFS_W = 4;
+reg [TX_IFS_W-1:0] tx_ifs_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ tx_ifs_q <= {(TX_IFS_W){1'b0}};
+// Start counting down from last Tx or EOP being detected at end of Rx
+else if (wait_eop_q || eop_detected_w)
+ tx_ifs_q <= TX_IFS;
+// Decrement IFS counter
+else if (tx_ifs_q != {(TX_IFS_W){1'b0}})
+ tx_ifs_q <= tx_ifs_q - 1;
+
+assign ifs_busy_w = wait_eop_q || (tx_ifs_q != {(TX_IFS_W){1'b0}});
+
+//-----------------------------------------------------------------
+// Tx Timer
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ last_tx_time_q <= 9'd0;
+// Start counting from last Tx
+else if (state_q == STATE_IDLE || (utmi_txvalid_o && utmi_txready_i))
+ last_tx_time_q <= 9'd0;
+// Increment the Tx timeout
+else if (last_tx_time_q != RX_TIMEOUT)
+ last_tx_time_q <= last_tx_time_q + 9'd1;
+
+//-----------------------------------------------------------------
+// Transmit / Receive counter
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ byte_count_q <= 16'h0000;
+// New transfer request (not automatic SOF request)
+else if (state_q == STATE_IDLE && start_i && !sof_transfer_i)
+ byte_count_q <= data_len_i;
+else if (state_q == STATE_RX_WAIT)
+ byte_count_q <= 16'h0000;
+// Transmit byte
+else if ((state_q == STATE_TX_PID || state_q == STATE_TX_DATA) && utmi_txready_i)
+begin
+ // Count down data left to send
+ if (byte_count_q != 16'd0)
+ byte_count_q <= byte_count_q - 16'd1;
+end
+// Received byte
+else if (state_q == STATE_RX_DATA && data_ready_w && !crc_byte_w)
+ byte_count_q <= byte_count_q + 16'd1;
+
+//-----------------------------------------------------------------
+// Transfer start ack
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ start_ack_q <= 1'b0;
+// First byte of PID sent, ack transfer request
+else if (state_q == STATE_TX_TOKEN1 && utmi_txready_i)
+ start_ack_q <= 1'b1;
+else
+ start_ack_q <= 1'b0;
+
+//-----------------------------------------------------------------
+// Record request details
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ in_transfer_q <= 1'b0;
+ send_ack_q <= 1'b0;
+ send_data1_q <= 1'b0;
+ send_sof_q <= 1'b0;
+end
+// Start of new request
+else if (state_q == STATE_IDLE && start_i)
+begin
+ // Transfer request
+ // e.g. (H)SOF [sof_transfer_i]
+ // (H)OUT + (H)DATA + (F)ACK/NACK/STALL [data_len_i >= 0 && !in_transfer_i]
+ // (H)IN + (F)DATA + (H)ACK [in_transfer_i]
+ // (H)IN + (F)NAK/STALL [in_transfer_i]
+ in_transfer_q <= in_transfer_i;
+
+ // Send ACK in response to IN DATA
+ send_ack_q <= in_transfer_i && resp_expected_i;
+
+ // DATA0/1
+ send_data1_q <= data_idx_i;
+
+ send_sof_q <= sof_transfer_i;
+end
+
+//-----------------------------------------------------------------
+// Response expected
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ wait_resp_q <= 1'b0;
+// Incoming data
+else if (state_q == STATE_RX_WAIT && data_ready_w)
+ wait_resp_q <= 1'b0;
+else if (state_q == STATE_IDLE && start_i)
+ wait_resp_q <= resp_expected_i;
+
+//-----------------------------------------------------------------
+// Status
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+begin
+ if (!rstn_i)
+ begin
+ status_response_q <= 8'h00;
+ status_timeout_q <= 1'b0;
+ status_rx_done_q <= 1'b0;
+ status_tx_done_q <= 1'b0;
+ end
+ else
+ begin
+ case (state_q)
+
+ //-----------------------------------------
+ // RX_WAIT
+ //-----------------------------------------
+ STATE_RX_WAIT :
+ begin
+ // Store response PID
+ if (data_ready_w)
+ status_response_q <= rx_data_w;
+
+ // Waited long enough?
+ if (rx_resp_timeout_w)
+ status_timeout_q <= 1'b1;
+
+ status_tx_done_q <= 1'b0;
+ end
+ //-----------------------------------------
+ // RX_DATA
+ //-----------------------------------------
+ STATE_RX_DATA :
+ begin
+ // Receive complete
+ if (!utmi_rxactive_i)
+ status_rx_done_q <= 1'b1;
+ else
+ status_rx_done_q <= 1'b0;
+ end
+ //-----------------------------------------
+ // TX_CRC (second byte)
+ //-----------------------------------------
+ STATE_TX_CRC2 :
+ begin
+ // Data sent?
+ if (utmi_txready_i && !wait_resp_q)
+ begin
+ // Transfer now complete
+ status_tx_done_q <= 1'b1;
+ end
+ end
+ //-----------------------------------------
+ // IDLE / RECEIVE BEGIN
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ // Transfer request
+ // e.g. (H)SOF [sof_transfer_i]
+ // (H)OUT + (H)DATA + (F)ACK/NACK/STALL [data_len_i >= 0 && !in_transfer_i]
+ // (H)IN + (F)DATA + (H)ACK [in_transfer_i]
+ // (H)IN + (F)NAK/STALL [in_transfer_i]
+ if (start_i && !sof_transfer_i) // (not automatic SOF request)
+ begin
+ // Clear status
+ status_response_q <= 8'h00;
+ status_timeout_q <= 1'b0;
+ end
+
+ status_rx_done_q <= 1'b0;
+ status_tx_done_q <= 1'b0;
+ end
+ //-----------------------------------------
+ // DEFAULT
+ //-----------------------------------------
+ default :
+ begin
+ status_rx_done_q <= 1'b0;
+ status_tx_done_q <= 1'b0;
+ end
+ endcase
+ end
+end
+
+
+//-----------------------------------------------------------------
+// Data delay (to strip the CRC16 trailing bytes)
+//-----------------------------------------------------------------
+reg [31:0] data_buffer_q;
+reg [3:0] data_valid_q;
+reg [3:0] rx_active_q;
+
+wire shift_en_w = (utmi_rxvalid_i & utmi_rxactive_i) || !utmi_rxactive_i;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_buffer_q <= 32'b0;
+else if (shift_en_w)
+ data_buffer_q <= {utmi_data_i, data_buffer_q[31:8]};
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_valid_q <= 4'b0;
+else if (shift_en_w)
+ data_valid_q <= {(utmi_rxvalid_i & utmi_rxactive_i), data_valid_q[3:1]};
+else
+ data_valid_q <= {data_valid_q[3:1], 1'b0};
+
+reg [1:0] data_crc_q;
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_crc_q <= 2'b0;
+else if (shift_en_w)
+ data_crc_q <= {!utmi_rxactive_i, data_crc_q[1]};
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rx_active_q <= 4'b0;
+else
+ rx_active_q <= {utmi_rxactive_i, rx_active_q[3:1]};
+
+assign rx_data_w = data_buffer_q[7:0];
+assign data_ready_w = data_valid_q[0];
+assign crc_byte_w = data_crc_q[0];
+assign rx_active_w = rx_active_q[0];
+
+assign rx_active_rise_w = !rx_active_q[3] && utmi_rxactive_i;
+
+//-----------------------------------------------------------------
+// CRC
+//-----------------------------------------------------------------
+
+// CRC16 (Data)
+usbh_crc16
+u_crc16
+(
+ .crc_i(crc_sum_q),
+ .data_i(crc_data_in_w),
+ .crc_o(crc_out_w)
+);
+
+// CRC5 (Token)
+usbh_crc5
+u_crc5
+(
+ .crc_i(5'h1F),
+ .data_i(token_q[15:5]),
+ .crc_o(crc5_out_w)
+);
+
+// CRC control / check
+always @ (posedge clk_i or negedge rstn_i)
+begin
+ if (!rstn_i)
+ begin
+ crc_sum_q <= 16'hFFFF;
+ status_crc_err_q <= 1'b0;
+ end
+ else
+ begin
+ case (state_q)
+ //-----------------------------------------
+ // TX_PID
+ //-----------------------------------------
+ STATE_TX_PID :
+ begin
+ // First byte is PID (not CRC'd), reset CRC16
+ crc_sum_q <= 16'hFFFF;
+ end
+ //-----------------------------------------
+ // TX_DATA
+ //-----------------------------------------
+ STATE_TX_DATA :
+ begin
+ // Data sent?
+ if (utmi_txready_i)
+ begin
+ // Next CRC start value
+ crc_sum_q <= crc_out_w;
+ end
+ end
+ //-----------------------------------------
+ // RX_WAIT
+ //-----------------------------------------
+ STATE_RX_WAIT :
+ begin
+ // Reset CRC16
+ crc_sum_q <= 16'hFFFF;
+ end
+ //-----------------------------------------
+ // RX_DATA
+ //-----------------------------------------
+ STATE_RX_DATA :
+ begin
+ // Data received?
+ if (data_ready_w)
+ begin
+ // Next CRC start value
+ crc_sum_q <= crc_out_w;
+ end
+ // Receive complete
+ else if (!rx_active_w)
+ begin
+ // If some data received, check CRC
+ if (crc_error_w)
+ status_crc_err_q <= 1'b1;
+ else
+ status_crc_err_q <= 1'b0;
+ end
+ end
+
+ //-----------------------------------------
+ // IDLE / RECEIVE BEGIN
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ // Start transfer request
+ if (start_i && !sof_transfer_i)
+ begin
+ // Clear error flag!
+ status_crc_err_q <= 1'b0;
+ end
+ end
+ default :
+ ;
+ endcase
+ end
+end
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+wire [15:0] token_rev_w;
+
+genvar i;
+generate
+for (i=0; i < 16; i=i+1)
+begin : LOOP
+ assign token_rev_w[i] = token_q[15-i];
+end
+endgenerate
+
+reg utmi_txvalid_r;
+reg [7:0] utmi_data_r;
+
+always @ *
+begin
+ if (state_q == STATE_TX_CRC1)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = crc_sum_q[7:0] ^ 8'hFF;
+ end
+ else if (state_q == STATE_TX_CRC2)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = crc_sum_q[15:8] ^ 8'hFF;
+ end
+ else if (state_q == STATE_TX_TOKEN1)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = token_pid_i;
+ end
+ else if (state_q == STATE_TX_TOKEN2)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = token_rev_w[7:0];
+ end
+ else if (state_q == STATE_TX_TOKEN3)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = token_rev_w[15:8];
+ end
+ else if (state_q == STATE_TX_PID)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = send_data1_q ? PID_DATA1 : PID_DATA0;
+ end
+ else if (state_q == STATE_TX_ACKNAK)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = PID_ACK;
+ end
+ else if (state_q == STATE_TX_DATA)
+ begin
+ utmi_txvalid_r = 1'b1;
+ utmi_data_r = tx_data_i;
+ end
+ else
+ begin
+ utmi_txvalid_r = 1'b0;
+ utmi_data_r = 8'b0;
+ end
+end
+
+assign utmi_txvalid_o = utmi_txvalid_r;
+assign utmi_data_o = utmi_data_r;
+
+// Push incoming data into FIFO (not PID or CRC)
+assign rx_data_o = rx_data_w;
+assign rx_push_o = (state_q != STATE_IDLE && state_q != STATE_RX_WAIT) & data_ready_w & !crc_byte_w;
+
+assign crc_data_in_w = (state_q == STATE_RX_DATA) ? rx_data_w : tx_data_i;
+
+assign rx_count_o = byte_count_q;
+assign idle_o = (state_q == STATE_IDLE);
+
+assign ack_o = start_ack_q;
+
+assign tx_pop_o = state_q == STATE_TX_DATA && utmi_txready_i;
+
+assign tx_done_o = status_tx_done_q;
+assign rx_done_o = status_rx_done_q;
+assign crc_err_o = status_crc_err_q;
+assign timeout_o = status_timeout_q;
+assign response_o = status_response_q;
+
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/filelist.f b/verilog/rtl/usb1_host/src/filelist.f
new file mode 100644
index 0000000..6288443
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/filelist.f
@@ -0,0 +1,10 @@
+core/usbh_core.sv
+core/usbh_crc16.sv
+core/usbh_crc5.sv
+core/usbh_fifo.sv
+core/usbh_sie.sv
+phy/usb_fs_phy.v
+phy/usb_transceiver.v
+lib/async_wb.sv
+lib/async_fifo.sv
+top/usb1_host.sv
diff --git a/verilog/rtl/usb1_host/src/includes/usbh_host_defs.v b/verilog/rtl/usb1_host/src/includes/usbh_host_defs.v
new file mode 100644
index 0000000..ac0441d
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/includes/usbh_host_defs.v
@@ -0,0 +1,325 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//-----------------------------------------------------------------
+// USB Full Speed Host
+// V0.6
+// Ultra-Embedded.com
+// Copyright 2015-2020
+//
+// Email: admin@ultra-embedded.com
+//
+// License: GPL
+// If you would like a version with a more permissive license for
+// use in closed source commercial applications please contact me
+// for details.
+//-----------------------------------------------------------------
+//
+// This file is open source HDL; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This file 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 General Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with this file; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+// USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+`define USB_CTRL 6'h0
+
+ `define USB_CTRL_TX_FLUSH 8
+ `define USB_CTRL_TX_FLUSH_DEFAULT 0
+ `define USB_CTRL_TX_FLUSH_B 8
+ `define USB_CTRL_TX_FLUSH_T 8
+ `define USB_CTRL_TX_FLUSH_W 1
+ `define USB_CTRL_TX_FLUSH_R 8:8
+
+ `define USB_CTRL_PHY_DMPULLDOWN 7
+ `define USB_CTRL_PHY_DMPULLDOWN_DEFAULT 0
+ `define USB_CTRL_PHY_DMPULLDOWN_B 7
+ `define USB_CTRL_PHY_DMPULLDOWN_T 7
+ `define USB_CTRL_PHY_DMPULLDOWN_W 1
+ `define USB_CTRL_PHY_DMPULLDOWN_R 7:7
+
+ `define USB_CTRL_PHY_DPPULLDOWN 6
+ `define USB_CTRL_PHY_DPPULLDOWN_DEFAULT 0
+ `define USB_CTRL_PHY_DPPULLDOWN_B 6
+ `define USB_CTRL_PHY_DPPULLDOWN_T 6
+ `define USB_CTRL_PHY_DPPULLDOWN_W 1
+ `define USB_CTRL_PHY_DPPULLDOWN_R 6:6
+
+ `define USB_CTRL_PHY_TERMSELECT 5
+ `define USB_CTRL_PHY_TERMSELECT_DEFAULT 0
+ `define USB_CTRL_PHY_TERMSELECT_B 5
+ `define USB_CTRL_PHY_TERMSELECT_T 5
+ `define USB_CTRL_PHY_TERMSELECT_W 1
+ `define USB_CTRL_PHY_TERMSELECT_R 5:5
+
+ `define USB_CTRL_PHY_XCVRSELECT_DEFAULT 0
+ `define USB_CTRL_PHY_XCVRSELECT_B 3
+ `define USB_CTRL_PHY_XCVRSELECT_T 4
+ `define USB_CTRL_PHY_XCVRSELECT_W 2
+ `define USB_CTRL_PHY_XCVRSELECT_R 4:3
+
+ `define USB_CTRL_PHY_OPMODE_DEFAULT 0
+ `define USB_CTRL_PHY_OPMODE_B 1
+ `define USB_CTRL_PHY_OPMODE_T 2
+ `define USB_CTRL_PHY_OPMODE_W 2
+ `define USB_CTRL_PHY_OPMODE_R 2:1
+
+ `define USB_CTRL_ENABLE_SOF 0
+ `define USB_CTRL_ENABLE_SOF_DEFAULT 0
+ `define USB_CTRL_ENABLE_SOF_B 0
+ `define USB_CTRL_ENABLE_SOF_T 0
+ `define USB_CTRL_ENABLE_SOF_W 1
+ `define USB_CTRL_ENABLE_SOF_R 0:0
+
+`define USB_STATUS 6'h4
+
+ `define USB_STATUS_SOF_TIME_DEFAULT 0
+ `define USB_STATUS_SOF_TIME_B 16
+ `define USB_STATUS_SOF_TIME_T 31
+ `define USB_STATUS_SOF_TIME_W 16
+ `define USB_STATUS_SOF_TIME_R 31:16
+
+ `define USB_STATUS_RX_ERROR 2
+ `define USB_STATUS_RX_ERROR_DEFAULT 0
+ `define USB_STATUS_RX_ERROR_B 2
+ `define USB_STATUS_RX_ERROR_T 2
+ `define USB_STATUS_RX_ERROR_W 1
+ `define USB_STATUS_RX_ERROR_R 2:2
+
+ `define USB_STATUS_LINESTATE_BITS_DEFAULT 0
+ `define USB_STATUS_LINESTATE_BITS_B 0
+ `define USB_STATUS_LINESTATE_BITS_T 1
+ `define USB_STATUS_LINESTATE_BITS_W 2
+ `define USB_STATUS_LINESTATE_BITS_R 1:0
+
+`define USB_IRQ_ACK 6'h8
+
+ `define USB_IRQ_ACK_DEVICE_DETECT 3
+ `define USB_IRQ_ACK_DEVICE_DETECT_DEFAULT 0
+ `define USB_IRQ_ACK_DEVICE_DETECT_B 3
+ `define USB_IRQ_ACK_DEVICE_DETECT_T 3
+ `define USB_IRQ_ACK_DEVICE_DETECT_W 1
+ `define USB_IRQ_ACK_DEVICE_DETECT_R 3:3
+
+ `define USB_IRQ_ACK_ERR 2
+ `define USB_IRQ_ACK_ERR_DEFAULT 0
+ `define USB_IRQ_ACK_ERR_B 2
+ `define USB_IRQ_ACK_ERR_T 2
+ `define USB_IRQ_ACK_ERR_W 1
+ `define USB_IRQ_ACK_ERR_R 2:2
+
+ `define USB_IRQ_ACK_DONE 1
+ `define USB_IRQ_ACK_DONE_DEFAULT 0
+ `define USB_IRQ_ACK_DONE_B 1
+ `define USB_IRQ_ACK_DONE_T 1
+ `define USB_IRQ_ACK_DONE_W 1
+ `define USB_IRQ_ACK_DONE_R 1:1
+
+ `define USB_IRQ_ACK_SOF 0
+ `define USB_IRQ_ACK_SOF_DEFAULT 0
+ `define USB_IRQ_ACK_SOF_B 0
+ `define USB_IRQ_ACK_SOF_T 0
+ `define USB_IRQ_ACK_SOF_W 1
+ `define USB_IRQ_ACK_SOF_R 0:0
+
+`define USB_IRQ_STS 6'hc
+
+ `define USB_IRQ_STS_DEVICE_DETECT 3
+ `define USB_IRQ_STS_DEVICE_DETECT_DEFAULT 0
+ `define USB_IRQ_STS_DEVICE_DETECT_B 3
+ `define USB_IRQ_STS_DEVICE_DETECT_T 3
+ `define USB_IRQ_STS_DEVICE_DETECT_W 1
+ `define USB_IRQ_STS_DEVICE_DETECT_R 3:3
+
+ `define USB_IRQ_STS_ERR 2
+ `define USB_IRQ_STS_ERR_DEFAULT 0
+ `define USB_IRQ_STS_ERR_B 2
+ `define USB_IRQ_STS_ERR_T 2
+ `define USB_IRQ_STS_ERR_W 1
+ `define USB_IRQ_STS_ERR_R 2:2
+
+ `define USB_IRQ_STS_DONE 1
+ `define USB_IRQ_STS_DONE_DEFAULT 0
+ `define USB_IRQ_STS_DONE_B 1
+ `define USB_IRQ_STS_DONE_T 1
+ `define USB_IRQ_STS_DONE_W 1
+ `define USB_IRQ_STS_DONE_R 1:1
+
+ `define USB_IRQ_STS_SOF 0
+ `define USB_IRQ_STS_SOF_DEFAULT 0
+ `define USB_IRQ_STS_SOF_B 0
+ `define USB_IRQ_STS_SOF_T 0
+ `define USB_IRQ_STS_SOF_W 1
+ `define USB_IRQ_STS_SOF_R 0:0
+
+`define USB_IRQ_MASK 6'h10
+
+ `define USB_IRQ_MASK_DEVICE_DETECT 3
+ `define USB_IRQ_MASK_DEVICE_DETECT_DEFAULT 0
+ `define USB_IRQ_MASK_DEVICE_DETECT_B 3
+ `define USB_IRQ_MASK_DEVICE_DETECT_T 3
+ `define USB_IRQ_MASK_DEVICE_DETECT_W 1
+ `define USB_IRQ_MASK_DEVICE_DETECT_R 3:3
+
+ `define USB_IRQ_MASK_ERR 2
+ `define USB_IRQ_MASK_ERR_DEFAULT 0
+ `define USB_IRQ_MASK_ERR_B 2
+ `define USB_IRQ_MASK_ERR_T 2
+ `define USB_IRQ_MASK_ERR_W 1
+ `define USB_IRQ_MASK_ERR_R 2:2
+
+ `define USB_IRQ_MASK_DONE 1
+ `define USB_IRQ_MASK_DONE_DEFAULT 0
+ `define USB_IRQ_MASK_DONE_B 1
+ `define USB_IRQ_MASK_DONE_T 1
+ `define USB_IRQ_MASK_DONE_W 1
+ `define USB_IRQ_MASK_DONE_R 1:1
+
+ `define USB_IRQ_MASK_SOF 0
+ `define USB_IRQ_MASK_SOF_DEFAULT 0
+ `define USB_IRQ_MASK_SOF_B 0
+ `define USB_IRQ_MASK_SOF_T 0
+ `define USB_IRQ_MASK_SOF_W 1
+ `define USB_IRQ_MASK_SOF_R 0:0
+
+`define USB_XFER_DATA 6'h14
+
+ `define USB_XFER_DATA_TX_LEN_DEFAULT 0
+ `define USB_XFER_DATA_TX_LEN_B 0
+ `define USB_XFER_DATA_TX_LEN_T 15
+ `define USB_XFER_DATA_TX_LEN_W 16
+ `define USB_XFER_DATA_TX_LEN_R 15:0
+
+`define USB_XFER_TOKEN 6'h18
+
+ `define USB_XFER_TOKEN_START 31
+ `define USB_XFER_TOKEN_START_DEFAULT 0
+ `define USB_XFER_TOKEN_START_B 31
+ `define USB_XFER_TOKEN_START_T 31
+ `define USB_XFER_TOKEN_START_W 1
+ `define USB_XFER_TOKEN_START_R 31:31
+
+ `define USB_XFER_TOKEN_IN 30
+ `define USB_XFER_TOKEN_IN_DEFAULT 0
+ `define USB_XFER_TOKEN_IN_B 30
+ `define USB_XFER_TOKEN_IN_T 30
+ `define USB_XFER_TOKEN_IN_W 1
+ `define USB_XFER_TOKEN_IN_R 30:30
+
+ `define USB_XFER_TOKEN_ACK 29
+ `define USB_XFER_TOKEN_ACK_DEFAULT 0
+ `define USB_XFER_TOKEN_ACK_B 29
+ `define USB_XFER_TOKEN_ACK_T 29
+ `define USB_XFER_TOKEN_ACK_W 1
+ `define USB_XFER_TOKEN_ACK_R 29:29
+
+ `define USB_XFER_TOKEN_PID_DATAX 28
+ `define USB_XFER_TOKEN_PID_DATAX_DEFAULT 0
+ `define USB_XFER_TOKEN_PID_DATAX_B 28
+ `define USB_XFER_TOKEN_PID_DATAX_T 28
+ `define USB_XFER_TOKEN_PID_DATAX_W 1
+ `define USB_XFER_TOKEN_PID_DATAX_R 28:28
+
+ `define USB_XFER_TOKEN_PID_BITS_DEFAULT 0
+ `define USB_XFER_TOKEN_PID_BITS_B 16
+ `define USB_XFER_TOKEN_PID_BITS_T 23
+ `define USB_XFER_TOKEN_PID_BITS_W 8
+ `define USB_XFER_TOKEN_PID_BITS_R 23:16
+
+ `define USB_XFER_TOKEN_DEV_ADDR_DEFAULT 0
+ `define USB_XFER_TOKEN_DEV_ADDR_B 9
+ `define USB_XFER_TOKEN_DEV_ADDR_T 15
+ `define USB_XFER_TOKEN_DEV_ADDR_W 7
+ `define USB_XFER_TOKEN_DEV_ADDR_R 15:9
+
+ `define USB_XFER_TOKEN_EP_ADDR_DEFAULT 0
+ `define USB_XFER_TOKEN_EP_ADDR_B 5
+ `define USB_XFER_TOKEN_EP_ADDR_T 8
+ `define USB_XFER_TOKEN_EP_ADDR_W 4
+ `define USB_XFER_TOKEN_EP_ADDR_R 8:5
+
+`define USB_RX_STAT 6'h1c
+
+ `define USB_RX_STAT_START_PEND 31
+ `define USB_RX_STAT_START_PEND_DEFAULT 0
+ `define USB_RX_STAT_START_PEND_B 31
+ `define USB_RX_STAT_START_PEND_T 31
+ `define USB_RX_STAT_START_PEND_W 1
+ `define USB_RX_STAT_START_PEND_R 31:31
+
+ `define USB_RX_STAT_CRC_ERR 30
+ `define USB_RX_STAT_CRC_ERR_DEFAULT 0
+ `define USB_RX_STAT_CRC_ERR_B 30
+ `define USB_RX_STAT_CRC_ERR_T 30
+ `define USB_RX_STAT_CRC_ERR_W 1
+ `define USB_RX_STAT_CRC_ERR_R 30:30
+
+ `define USB_RX_STAT_RESP_TIMEOUT 29
+ `define USB_RX_STAT_RESP_TIMEOUT_DEFAULT 0
+ `define USB_RX_STAT_RESP_TIMEOUT_B 29
+ `define USB_RX_STAT_RESP_TIMEOUT_T 29
+ `define USB_RX_STAT_RESP_TIMEOUT_W 1
+ `define USB_RX_STAT_RESP_TIMEOUT_R 29:29
+
+ `define USB_RX_STAT_IDLE 28
+ `define USB_RX_STAT_IDLE_DEFAULT 0
+ `define USB_RX_STAT_IDLE_B 28
+ `define USB_RX_STAT_IDLE_T 28
+ `define USB_RX_STAT_IDLE_W 1
+ `define USB_RX_STAT_IDLE_R 28:28
+
+ `define USB_RX_STAT_RESP_BITS_DEFAULT 0
+ `define USB_RX_STAT_RESP_BITS_B 16
+ `define USB_RX_STAT_RESP_BITS_T 23
+ `define USB_RX_STAT_RESP_BITS_W 8
+ `define USB_RX_STAT_RESP_BITS_R 23:16
+
+ `define USB_RX_STAT_COUNT_BITS_DEFAULT 0
+ `define USB_RX_STAT_COUNT_BITS_B 0
+ `define USB_RX_STAT_COUNT_BITS_T 15
+ `define USB_RX_STAT_COUNT_BITS_W 16
+ `define USB_RX_STAT_COUNT_BITS_R 15:0
+
+`define USB_WR_DATA 6'h20
+
+ `define USB_WR_DATA_DATA_DEFAULT 0
+ `define USB_WR_DATA_DATA_B 0
+ `define USB_WR_DATA_DATA_T 7
+ `define USB_WR_DATA_DATA_W 8
+ `define USB_WR_DATA_DATA_R 7:0
+
+`define USB_RD_DATA 6'h20
+
+ `define USB_RD_DATA_DATA_DEFAULT 0
+ `define USB_RD_DATA_DATA_B 0
+ `define USB_RD_DATA_DATA_T 7
+ `define USB_RD_DATA_DATA_W 8
+ `define USB_RD_DATA_DATA_R 7:0
+
diff --git a/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v b/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v
new file mode 100644
index 0000000..c7ac174
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v
@@ -0,0 +1,713 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//-----------------------------------------------------------------
+// USB Full Speed (12mbps) Phy
+// V0.2
+// Ultra-Embedded.com
+// Copyright 2015
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//-----------------------------------------------------------------
+//
+// 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, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usb_fs_phy
+(
+ // Inputs
+ input clk_i
+ ,input rstn_i
+ ,input [ 7:0] utmi_data_out_i
+ ,input utmi_txvalid_i
+ ,input [ 1:0] utmi_op_mode_i
+ ,input [ 1:0] utmi_xcvrselect_i
+ ,input utmi_termselect_i
+ ,input utmi_dppulldown_i
+ ,input utmi_dmpulldown_i
+ ,input usb_rx_rcv_i
+ ,input usb_rx_dp_i
+ ,input usb_rx_dn_i
+ ,input usb_reset_assert_i
+
+ // Outputs
+ ,output [ 7:0] utmi_data_in_o
+ ,output utmi_txready_o
+ ,output utmi_rxvalid_o
+ ,output utmi_rxactive_o
+ ,output utmi_rxerror_o
+ ,output [ 1:0] utmi_linestate_o
+ ,output usb_tx_dp_o
+ ,output usb_tx_dn_o
+ ,output usb_tx_oen_o
+ ,output usb_reset_detect_o
+ ,output usb_en_o
+);
+
+
+
+
+//-----------------------------------------------------------------
+// Wires / Registers
+//-----------------------------------------------------------------
+reg rx_en_q;
+
+// Xilinx placement pragmas:
+//synthesis attribute IOB of out_dp_q is "TRUE"
+//synthesis attribute IOB of out_dn_q is "TRUE"
+reg out_dp_q;
+reg out_dn_q;
+
+wire in_dp_w;
+wire in_dn_w;
+wire in_rx_w;
+
+wire in_j_w;
+wire in_k_w;
+wire in_se0_w;
+wire in_invalid_w;
+
+wire sample_w;
+
+wire bit_edge_w;
+wire bit_transition_w;
+
+reg [2:0] bit_count_q;
+reg [2:0] ones_count_q;
+reg [7:0] data_q;
+reg send_eop_q;
+
+reg sync_j_detected_q;
+
+wire bit_stuff_bit_w;
+wire next_is_bit_stuff_w;
+
+wire usb_reset_assert_w = usb_reset_assert_i |
+ (utmi_xcvrselect_i == 2'b00 &&
+ utmi_termselect_i == 1'b0 &&
+ utmi_op_mode_i == 2'b10 &&
+ utmi_dppulldown_i &&
+ utmi_dmpulldown_i);
+
+//-----------------------------------------------------------------
+// Resample async signals
+//-----------------------------------------------------------------
+reg rx_dp_ms;
+reg rx_dn_ms;
+reg rxd_ms;
+
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ rx_dp_ms <= 1'b0;
+ rx_dn_ms <= 1'b0;
+ rxd_ms <= 1'b0;
+end
+else
+begin
+ rx_dp_ms <= in_dp_w;
+ rx_dn_ms <= in_dn_w;
+ rxd_ms <= in_rx_w;
+end
+
+//-----------------------------------------------------------------
+// Edge Detection
+//-----------------------------------------------------------------
+reg rx_dp0_q;
+reg rx_dn0_q;
+reg rx_dp1_q;
+reg rx_dn1_q;
+reg rx_dp_q;
+reg rx_dn_q;
+reg rxd0_q;
+reg rxd1_q;
+reg rxd_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ rx_dp0_q <= 1'b0;
+ rx_dn0_q <= 1'b0;
+ rx_dp1_q <= 1'b0;
+ rx_dn1_q <= 1'b0;
+ rx_dp_q <= 1'b0;
+ rx_dn_q <= 1'b0;
+ rxd0_q <= 1'b0;
+ rxd1_q <= 1'b0;
+ rxd_q <= 1'b0;
+end
+else
+begin
+ // Glitch free versions
+ if (rx_dp0_q & rx_dp1_q)
+ rx_dp_q <= 1'b1;
+ else if (!rx_dp0_q & !rx_dp1_q)
+ rx_dp_q <= 1'b0;
+
+ if (rx_dn0_q & rx_dn1_q)
+ rx_dn_q <= 1'b1;
+ else if (!rx_dn0_q & !rx_dn1_q)
+ rx_dn_q <= 1'b0;
+
+ if (rxd0_q & rxd1_q)
+ rxd_q <= 1'b1;
+ else if (!rxd0_q & !rxd1_q)
+ rxd_q <= 1'b0;
+
+ // Resyncs
+ rx_dp1_q <= rx_dp0_q;
+ rx_dp0_q <= rx_dp_ms;
+
+ rx_dn1_q <= rx_dn0_q;
+ rx_dn0_q <= rx_dn_ms;
+
+ rxd1_q <= rxd0_q;
+ rxd0_q <= rxd_ms;
+end
+
+// For Full Speed USB:
+// SE0 = D+ = 0 && D- = 0
+// J = D+ = 1 && D- = 0
+// K = D+ = 0 && D- = 1
+
+assign in_j_w = in_se0_w ? 1'b0 : rxd_q;
+assign in_k_w = in_se0_w ? 1'b0 : ~rxd_q;
+assign in_se0_w = (!rx_dp_q & !rx_dn_q);
+assign in_invalid_w = (rx_dp_q & rx_dn_q);
+
+// Line state matches tx outputs if drivers enabled
+assign utmi_linestate_o = usb_tx_oen_o ? {rx_dn_q, rx_dp_q} : {usb_tx_dn_o, usb_tx_dp_o};
+
+//-----------------------------------------------------------------
+// State Machine
+//-----------------------------------------------------------------
+localparam STATE_W = 4;
+localparam STATE_IDLE = 4'd0;
+localparam STATE_RX_DETECT = 4'd1;
+localparam STATE_RX_SYNC_J = 4'd2;
+localparam STATE_RX_SYNC_K = 4'd3;
+localparam STATE_RX_ACTIVE = 4'd4;
+localparam STATE_RX_EOP0 = 4'd5;
+localparam STATE_RX_EOP1 = 4'd6;
+localparam STATE_TX_SYNC = 4'd7;
+localparam STATE_TX_ACTIVE = 4'd8;
+localparam STATE_TX_EOP_STUFF = 4'd9;
+localparam STATE_TX_EOP0 = 4'd10;
+localparam STATE_TX_EOP1 = 4'd11;
+localparam STATE_TX_EOP2 = 4'd12;
+localparam STATE_TX_RST = 4'd13;
+
+// Current state
+reg [STATE_W-1:0] state_q;
+
+reg [STATE_W-1:0] next_state_r;
+always @ *
+begin
+ next_state_r = state_q;
+
+ case (state_q)
+ //-----------------------------------------
+ // STATE_IDLE
+ //-----------------------------------------
+ STATE_IDLE :
+ begin
+ if (in_k_w)
+ next_state_r = STATE_RX_DETECT;
+ else if (utmi_txvalid_i)
+ next_state_r = STATE_TX_SYNC;
+ else if (usb_reset_assert_w)
+ next_state_r = STATE_TX_RST;
+ end
+ //-----------------------------------------
+ // STATE_RX_DETECT
+ //-----------------------------------------
+ STATE_RX_DETECT :
+ begin
+ if (in_k_w && sample_w)
+ next_state_r = STATE_RX_SYNC_K;
+ else if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_SYNC_J
+ //-----------------------------------------
+ STATE_RX_SYNC_J :
+ begin
+ if (in_k_w && sample_w)
+ next_state_r = STATE_RX_SYNC_K;
+ // K glitch followed by multiple J's - return to idle
+ else if ((bit_count_q == 3'd1) && sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_SYNC_K
+ //-----------------------------------------
+ STATE_RX_SYNC_K :
+ begin
+ // End of SYNC field ends with 2 K's
+ // Must have seen at least 1 J state first!
+ if (sync_j_detected_q && in_k_w && sample_w)
+ next_state_r = STATE_RX_ACTIVE;
+ // No J detected since IDLE, must be an error!
+ else if (!sync_j_detected_q && in_k_w && sample_w)
+ next_state_r = STATE_IDLE;
+ else if (in_j_w && sample_w)
+ next_state_r = STATE_RX_SYNC_J;
+ end
+ //-----------------------------------------
+ // STATE_RX_ACTIVE
+ //-----------------------------------------
+ STATE_RX_ACTIVE :
+ begin
+ if (in_se0_w && sample_w)
+ next_state_r = STATE_RX_EOP0;
+ // Error!
+ else if (in_invalid_w && sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_EOP0
+ //-----------------------------------------
+ STATE_RX_EOP0 :
+ begin
+ if (in_se0_w && sample_w)
+ next_state_r = STATE_RX_EOP1;
+ // Error!
+ else if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_RX_EOP1
+ //-----------------------------------------
+ STATE_RX_EOP1 :
+ begin
+ // Return to idle
+ if (in_j_w && sample_w)
+ next_state_r = STATE_IDLE;
+ // Error!
+ else if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_TX_SYNC
+ //-----------------------------------------
+ STATE_TX_SYNC :
+ begin
+ if (bit_count_q == 3'd7 && sample_w)
+ next_state_r = STATE_TX_ACTIVE;
+ end
+ //-----------------------------------------
+ // STATE_TX_ACTIVE
+ //-----------------------------------------
+ STATE_TX_ACTIVE :
+ begin
+ if (bit_count_q == 3'd7 && sample_w && (!utmi_txvalid_i || send_eop_q) && !bit_stuff_bit_w)
+ begin
+ // Bit stuff required at end of packet?
+ if (next_is_bit_stuff_w)
+ next_state_r = STATE_TX_EOP_STUFF;
+ else
+ next_state_r = STATE_TX_EOP0;
+ end
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP_STUFF
+ //-----------------------------------------
+ STATE_TX_EOP_STUFF :
+ begin
+ if (sample_w)
+ next_state_r = STATE_TX_EOP0;
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP0
+ //-----------------------------------------
+ STATE_TX_EOP0 :
+ begin
+ if (sample_w)
+ next_state_r = STATE_TX_EOP1;
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP1
+ //-----------------------------------------
+ STATE_TX_EOP1 :
+ begin
+ if (sample_w)
+ next_state_r = STATE_TX_EOP2;
+ end
+ //-----------------------------------------
+ // STATE_TX_EOP2
+ //-----------------------------------------
+ STATE_TX_EOP2 :
+ begin
+ if (sample_w)
+ next_state_r = STATE_IDLE;
+ end
+ //-----------------------------------------
+ // STATE_TX_RST
+ //-----------------------------------------
+ STATE_TX_RST :
+ begin
+ if (!usb_reset_assert_w)
+ next_state_r = STATE_IDLE;
+ end
+ default:
+ ;
+ endcase
+end
+
+// Update state
+always @ (negedge rstn_i or posedge clk_i)
+if (!rstn_i)
+ state_q <= STATE_IDLE;
+else
+ state_q <= next_state_r;
+
+//-----------------------------------------------------------------
+// SYNC detect
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ sync_j_detected_q <= 1'b0;
+// Reset sync detect state in IDLE
+else if (state_q == STATE_IDLE)
+ sync_j_detected_q <= 1'b0;
+// At least one J detected
+else if (state_q == STATE_RX_SYNC_J)
+ sync_j_detected_q <= 1'b1;
+
+//-----------------------------------------------------------------
+// Rx Error Detection
+//-----------------------------------------------------------------
+reg rx_error_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rx_error_q <= 1'b0;
+// Rx bit stuffing error
+else if (ones_count_q == 3'd7)
+ rx_error_q <= 1'b1;
+// Invalid line state detection
+else if (in_invalid_w && sample_w)
+ rx_error_q <= 1'b1;
+// Detect invalid SYNC sequence
+else if ((state_q == STATE_RX_SYNC_K) && !sync_j_detected_q && in_k_w && sample_w)
+ rx_error_q <= 1'b1;
+else
+ rx_error_q <= 1'b0;
+
+assign utmi_rxerror_o = rx_error_q;
+
+//-----------------------------------------------------------------
+// Edge Detector
+//-----------------------------------------------------------------
+reg rxd_last_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rxd_last_q <= 1'b0;
+else
+ rxd_last_q <= in_j_w;
+
+assign bit_edge_w = rxd_last_q ^ in_j_w;
+
+//-----------------------------------------------------------------
+// Sample Timer
+//-----------------------------------------------------------------
+reg [1:0] sample_cnt_q;
+reg adjust_delayed_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ sample_cnt_q <= 2'd0;
+ adjust_delayed_q <= 1'b0;
+end
+// Delayed adjustment
+else if (adjust_delayed_q)
+ adjust_delayed_q <= 1'b0;
+else if (bit_edge_w && (sample_cnt_q != 2'd0) && (state_q < STATE_TX_SYNC))
+ sample_cnt_q <= 2'd0;
+// Can't adjust sampling point now?
+else if (bit_edge_w && (sample_cnt_q == 2'd0) && (state_q < STATE_TX_SYNC))
+begin
+ // Want to reset sampling point but need to delay adjustment by 1 cycle!
+ adjust_delayed_q <= 1'b1;
+ sample_cnt_q <= sample_cnt_q + 2'd1;
+end
+else
+ sample_cnt_q <= sample_cnt_q + 2'd1;
+
+assign sample_w = (sample_cnt_q == 2'd0);
+
+//-----------------------------------------------------------------
+// NRZI Receiver
+//-----------------------------------------------------------------
+reg rxd_last_j_q;
+
+// NRZI:
+// 0 = transition between J & K
+// 1 = same state
+// After 6 consequitive 1's, a 0 is inserted to maintain the transitions
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rxd_last_j_q <= 1'b0;
+else if ((state_q == STATE_IDLE) || sample_w)
+ rxd_last_j_q <= in_j_w;
+
+assign bit_transition_w = sample_w ? rxd_last_j_q ^ in_j_w : 1'b0;
+
+//-----------------------------------------------------------------
+// Bit Counters
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ ones_count_q <= 3'd1;
+// The packet starts with a double K (no transition)
+else if (state_q == STATE_IDLE)
+ ones_count_q <= 3'd1;
+// Rx
+else if ((state_q == STATE_RX_ACTIVE) && sample_w)
+begin
+ if (bit_transition_w)
+ ones_count_q <= 3'b0;
+ else
+ ones_count_q <= ones_count_q + 3'd1;
+end
+// Tx
+else if ((state_q == STATE_TX_ACTIVE) && sample_w)
+begin
+ // Toggle output data
+ if (!data_q[0] || bit_stuff_bit_w)
+ ones_count_q <= 3'b0;
+ else
+ ones_count_q <= ones_count_q + 3'd1;
+end
+
+assign bit_stuff_bit_w = (ones_count_q == 3'd6);
+assign next_is_bit_stuff_w = (ones_count_q == 3'd5) && !bit_transition_w;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ bit_count_q <= 3'b0;
+else if ((state_q == STATE_IDLE) || (state_q == STATE_RX_SYNC_K))
+ bit_count_q <= 3'b0;
+else if ((state_q == STATE_RX_ACTIVE || state_q == STATE_TX_ACTIVE) && sample_w && !bit_stuff_bit_w)
+ bit_count_q <= bit_count_q + 3'd1;
+else if (((state_q == STATE_TX_SYNC) || (state_q == STATE_RX_SYNC_J)) && sample_w)
+ bit_count_q <= bit_count_q + 3'd1;
+
+//-----------------------------------------------------------------
+// Shift register
+//-----------------------------------------------------------------
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ data_q <= 8'b0;
+// Pre-load shift register with SYNC word
+else if (state_q == STATE_IDLE)
+ data_q <= 8'b00101010;
+else if ((state_q == STATE_RX_ACTIVE) && sample_w && !bit_stuff_bit_w)
+ data_q <= {~bit_transition_w, data_q[7:1]};
+else if ((state_q == STATE_TX_SYNC) && sample_w)
+begin
+ if (bit_count_q == 3'd7)
+ data_q <= utmi_data_out_i;
+ else
+ data_q <= {~bit_transition_w, data_q[7:1]};
+end
+else if ((state_q == STATE_TX_ACTIVE) && sample_w && !bit_stuff_bit_w)
+begin
+ if (bit_count_q == 3'd7)
+ data_q <= utmi_data_out_i;
+ else
+ data_q <= {~bit_transition_w, data_q[7:1]};
+end
+
+// Receive active (SYNC recieved)
+assign utmi_rxactive_o = (state_q == STATE_RX_ACTIVE);
+
+assign utmi_data_in_o = data_q;
+
+//-----------------------------------------------------------------
+// Rx Ready
+//-----------------------------------------------------------------
+reg rx_ready_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ rx_ready_q <= 1'b0;
+else if ((state_q == STATE_RX_ACTIVE) && sample_w && (bit_count_q == 3'd7) && !bit_stuff_bit_w)
+ rx_ready_q <= 1'b1;
+else
+ rx_ready_q <= 1'b0;
+
+assign utmi_rxvalid_o = rx_ready_q;
+
+//-----------------------------------------------------------------
+// Tx Ready
+//-----------------------------------------------------------------
+reg tx_ready_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ tx_ready_q <= 1'b0;
+else if ((state_q == STATE_TX_SYNC) && sample_w && (bit_count_q == 3'd7))
+ tx_ready_q <= 1'b1;
+else if ((state_q == STATE_TX_ACTIVE) && sample_w && !bit_stuff_bit_w && (bit_count_q == 3'd7) && !send_eop_q)
+ tx_ready_q <= 1'b1;
+else
+ tx_ready_q <= 1'b0;
+
+assign utmi_txready_o = tx_ready_q;
+
+//-----------------------------------------------------------------
+// EOP pending
+//-----------------------------------------------------------------
+always @ (negedge rstn_i or negedge clk_i)
+if (!rstn_i)
+ send_eop_q <= 1'b0;
+else if ((state_q == STATE_TX_ACTIVE) && !utmi_txvalid_i)
+ send_eop_q <= 1'b1;
+else if (state_q == STATE_TX_EOP0)
+ send_eop_q <= 1'b0;
+
+//-----------------------------------------------------------------
+// Tx
+//-----------------------------------------------------------------
+wire out_bit_w = sample_w ? data_q[0] : 1'bz;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+begin
+ out_dp_q <= 1'b0;
+ out_dn_q <= 1'b0;
+ rx_en_q <= 1'b1;
+end
+else if (state_q == STATE_IDLE)
+begin
+ // IDLE
+ out_dp_q <= 1'b1;
+ out_dn_q <= 1'b0;
+
+ if (utmi_txvalid_i || usb_reset_assert_w)
+ rx_en_q <= 1'b0;
+ else
+ rx_en_q <= 1'b1;
+end
+else if ((state_q == STATE_TX_SYNC) && sample_w)
+begin
+ out_dp_q <= data_q[0];
+ out_dn_q <= ~data_q[0];
+end
+else if ((state_q == STATE_TX_ACTIVE || state_q == STATE_TX_EOP_STUFF) && sample_w)
+begin
+ // 0 = toggle, 1 = hold
+ if (!data_q[0] || bit_stuff_bit_w)
+ begin
+ out_dp_q <= ~out_dp_q;
+ out_dn_q <= ~out_dn_q;
+ end
+end
+else if ((state_q == STATE_TX_EOP0 || state_q == STATE_TX_EOP1) && sample_w)
+begin
+ // SE0
+ out_dp_q <= 1'b0;
+ out_dn_q <= 1'b0;
+end
+else if ((state_q == STATE_TX_EOP2) && sample_w)
+begin
+ // IDLE
+ out_dp_q <= 1'b1;
+ out_dn_q <= 1'b0;
+
+ // Set bus to input
+ rx_en_q <= 1'b1;
+end
+else if (state_q == STATE_TX_RST)
+begin
+ // SE0
+ out_dp_q <= 1'b0;
+ out_dn_q <= 1'b0;
+end
+
+//-----------------------------------------------------------------
+// Reset detection
+//-----------------------------------------------------------------
+reg [6:0] se0_cnt_q;
+
+always @ (posedge clk_i or negedge rstn_i)
+if (!rstn_i)
+ se0_cnt_q <= 7'b0;
+else if (in_se0_w)
+begin
+ if (se0_cnt_q != 7'd127)
+ se0_cnt_q <= se0_cnt_q + 7'd1;
+end
+else
+ se0_cnt_q <= 7'b0;
+
+assign usb_reset_detect_o = (se0_cnt_q == 7'd127);
+
+//-----------------------------------------------------------------
+// Transceiver Interface
+//-----------------------------------------------------------------
+// Tx output enable (active low)
+assign usb_tx_oen_o = rx_en_q;
+
+// Tx +/-
+assign usb_tx_dp_o = out_dp_q;
+assign usb_tx_dn_o = out_dn_q;
+
+// Receive D+/D-
+assign in_dp_w = usb_rx_dp_i;
+assign in_dn_w = usb_rx_dn_i;
+
+// Receive data
+assign in_rx_w = usb_rx_rcv_i;
+
+// USB device pull-up enable
+assign usb_en_o = utmi_termselect_i;
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/phy/usb_transceiver.v b/verilog/rtl/usb1_host/src/phy/usb_transceiver.v
new file mode 100644
index 0000000..45b9912
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/phy/usb_transceiver.v
@@ -0,0 +1,184 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//-----------------------------------------------------------------
+// USB Full Speed (12mbps) Phy
+// V0.2
+// Ultra-Embedded.com
+// Copyright 2015
+//
+// Email: admin@ultra-embedded.com
+//
+// License: LGPL
+//-----------------------------------------------------------------
+//
+// 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, write to the
+// Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+// Boston, MA 02111-1307 USA
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Generated File
+//-----------------------------------------------------------------
+
+module usb_transceiver
+(
+ // Inputs
+ input usb_phy_tx_dp_i,
+ input usb_phy_tx_dn_i,
+ input usb_phy_tx_oen_i,
+ input mode_i,
+
+ output reg out_dp,
+ output reg out_dn,
+ output out_tx_oen,
+
+ // Outputs
+ input in_dp,
+ input in_dn,
+
+ output usb_phy_rx_rcv_o,
+ output usb_phy_rx_dp_o,
+ output usb_phy_rx_dn_o
+);
+
+
+
+//-----------------------------------------------------------------
+// Module: usb_transceiver
+// Emulate standard USB PHY interface and produce a D+/D- outputs.
+// Allows direct connection of USB port to FPGA.
+// Limitations:
+// As no differential amplifier present, no common mode noise
+// rejection occurs.
+// Unlikely to work well with longer connections!
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Wires
+//-----------------------------------------------------------------
+
+//-----------------------------------------------------------------
+// Assignments
+//-----------------------------------------------------------------
+
+// D+/D- Tristate buffers
+//assign usb_dp_io = (usb_phy_tx_oen_i == 1'b0) ? out_dp : 1'bz;
+//assign usb_dn_io = (usb_phy_tx_oen_i == 1'b0) ? out_dn : 1'bz;
+//
+assign out_tx_oen = usb_phy_tx_oen_i;
+
+// Receive D+/D-
+assign usb_phy_rx_dp_o = in_dp;
+assign usb_phy_rx_dn_o = in_dn;
+
+// Receive output
+assign usb_phy_rx_rcv_o = (in_dp == 1'b1 && in_dn == 1'b0) ? 1'b1 : 1'b0;
+
+// PHY Transmit Mode:
+// When phy_tx_mode_i is '0' the outputs are encoded as:
+// vmo_i, vpo_i
+// 0 0 Differential Logic '0'
+// 0 1 Differential Logic '1'
+// 1 0 Single Ended '0'
+// 1 1 Single Ended '0'
+// When phy_tx_mode_i is '1' the outputs are encoded as:
+// vmo_i, vpo_i
+// 0 0 Single Ended '0'
+// 0 1 Differential Logic '1'
+// 1 0 Differential Logic '0'
+// 1 1 Illegal State
+always @ (mode_i or usb_phy_tx_dp_i or usb_phy_tx_dn_i)
+begin : MUX
+ case(mode_i)
+ 1'b0:
+ begin
+ if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // Logic "0"
+ out_dp = 1'b0;
+ out_dn = 1'b1;
+ end
+ else if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // SE0 (both low)
+ out_dp = 1'b0;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // Logic "1"
+ out_dp = 1'b1;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // SE0 (both low)
+ out_dp = 1'b0;
+ out_dn = 1'b0;
+ end
+ end
+ 1'b1 :
+ begin
+ if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // SE0 (both low)
+ out_dp = 1'b0;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b0 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // Logic "0"
+ out_dp = 1'b0;
+ out_dn = 1'b1;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b0)
+ begin
+ // Logic "1"
+ out_dp = 1'b1;
+ out_dn = 1'b0;
+ end
+ else if (usb_phy_tx_dp_i == 1'b1 && usb_phy_tx_dn_i == 1'b1)
+ begin
+ // Illegal
+ out_dp = 1'b1;
+ out_dn = 1'b1;
+ end
+ end
+ endcase
+end
+
+
+endmodule
diff --git a/verilog/rtl/usb1_host/src/top/usb1_host.sv b/verilog/rtl/usb1_host/src/top/usb1_host.sv
new file mode 100644
index 0000000..1de70d4
--- /dev/null
+++ b/verilog/rtl/usb1_host/src/top/usb1_host.sv
@@ -0,0 +1,238 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// USB1.1 HOST Controller + PHY ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// https://github.com/dineshannayya/yifive_r0.git ////
+//// USB1 Core from github.com/ultraembedded/core_usb_host ////
+//// USBB Phy from github.com/ultraembedded/core_usb_fs_phy.git ////
+//// ////
+//// Description ////
+//// Following Modification are Done ////
+//// 1. Integrated the Wishbone Interface ////
+//// 2. WishBone interface made async w.r.t usb clock ////
+//// 3. usb1 core Axi logic is modified to normal Register ////
+//// read/write I/F ////
+//// ////
+//// This module integrate following sub module ////
+//// 1. async_wb : Async wishbone interface does the wishbone ////
+//// to usbclk clock synchronization ////
+//// 2. usb1_core: usb1 core ////
+//// 3. usb1_host : usb phy ////
+//// ////
+//// Assumptiom: usb_clk is 48Mhz ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module usb1_host (
+ input logic usb_clk_i ,
+ input logic usb_rstn_i ,
+
+ // USB D+/D-
+ input in_dp ,
+ input in_dn ,
+
+ input out_dp ,
+ input out_dn ,
+ output out_tx_oen,
+
+ // Master Port
+ input logic wbm_rst_n , // Regular Reset signal
+ input logic wbm_clk_i , // System clock
+ input logic wbm_stb_i , // strobe/request
+ input logic [5:0] wbm_adr_i , // address
+ input logic wbm_we_i , // write
+ input logic [31:0] wbm_dat_i , // data output
+ input logic [3:0] wbm_sel_i , // byte enable
+ output logic [31:0] wbm_dat_o , // data input
+ output logic wbm_ack_o , // acknowlegement
+ output logic wbm_err_o , // error
+
+ // Outputs
+ output usb_intr_o
+
+
+ );
+
+ logic [7:0] utmi_data_in_i;
+ logic utmi_txready_i;
+ logic utmi_rxvalid_i;
+ logic utmi_rxactive_i;
+ logic utmi_rxerror_i;
+ logic [1:0] utmi_linestate_i;
+
+ logic [7:0] utmi_data_out_o;
+ logic utmi_txvalid_o;
+ logic [1:0] utmi_op_mode_o;
+ logic [1:0] utmi_xcvrselect_o;
+ logic utmi_termselect_o;
+ logic utmi_dppulldown_o;
+ logic utmi_dmpulldown_o;
+ logic usb_pads_tx_dp_w;
+ logic usb_pads_tx_oen_w;
+ logic usb_pads_rx_dn_w;
+ logic usb_pads_tx_dn_w;
+ logic usb_pads_rx_rcv_w;
+ logic usb_pads_rx_dp_w;
+ logic usb_xcvr_mode_w = 1'h1;
+
+ // Reg Bus Interface Signal
+ logic reg_cs;
+ logic reg_wr;
+ logic [5:0] reg_addr;
+ logic [31:0] reg_wdata;
+ logic [3:0] reg_be;
+
+ // Outputs
+ logic [31:0] reg_rdata;
+ logic reg_ack;
+
+
+
+async_wb #(.AW (6))
+ u_async_wb(
+
+ // Master Port
+ .wbm_rst_n (wbm_rst_n ), // Regular Reset signal
+ .wbm_clk_i (wbm_clk_i ), // System clock
+ .wbm_cyc_i (wbm_stb_i ), // strobe/request
+ .wbm_stb_i (wbm_stb_i ), // strobe/request
+ .wbm_adr_i (wbm_adr_i ), // address
+ .wbm_we_i (wbm_we_i ), // write
+ .wbm_dat_i (wbm_dat_i ), // data output
+ .wbm_sel_i (wbm_sel_i ), // byte enable
+ .wbm_dat_o (wbm_dat_o ), // data input
+ .wbm_ack_o (wbm_ack_o ), // acknowlegement
+ .wbm_err_o (wbm_err_o ), // error
+
+ // Slave Port
+ .wbs_rst_n (usb_rstn_i ), // Regular Reset signal
+ .wbs_clk_i (usb_clk_i ), // System clock
+ .wbs_cyc_o ( ), // strobe/request
+ .wbs_stb_o (reg_cs ), // strobe/request
+ .wbs_adr_o (reg_addr ), // address
+ .wbs_we_o (reg_wr ), // write
+ .wbs_dat_o (reg_wdata ), // data output
+ .wbs_sel_o (reg_be ), // byte enable
+ .wbs_dat_i (reg_rdata ), // data input
+ .wbs_ack_i (reg_ack ), // acknowlegement
+ .wbs_err_i (1'b0 ) // error
+
+ );
+
+usbh_core u_core (
+ // Inputs
+ .clk_i (usb_clk_i ),
+ .rstn_i (usb_rstn_i ),
+
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_rdata ),
+ .reg_ack (reg_ack ),
+
+ // Outputs
+ .intr_o (usb_intr_o ),
+
+ .utmi_data_in_i (utmi_data_in_i ),
+ .utmi_rxvalid_i (utmi_rxvalid_i ),
+ .utmi_rxactive_i (utmi_rxactive_i ),
+ .utmi_rxerror_i (utmi_rxerror_i ),
+ .utmi_linestate_i (utmi_linestate_i ),
+
+ .utmi_txready_i (utmi_txready_i ),
+ .utmi_data_out_o (utmi_data_out_o ),
+ .utmi_txvalid_o (utmi_txvalid_o ),
+
+ .utmi_op_mode_o (utmi_op_mode_o ),
+ .utmi_xcvrselect_o (utmi_xcvrselect_o ),
+ .utmi_termselect_o (utmi_termselect_o ),
+ .utmi_dppulldown_o (utmi_dppulldown_o ),
+ .utmi_dmpulldown_o (utmi_dmpulldown_o )
+);
+
+
+
+usb_fs_phy u_phy(
+ // Inputs
+ .clk_i (usb_clk_i ),
+ .rstn_i (usb_rstn_i ),
+ .utmi_data_out_i (utmi_data_out_o ),
+ .utmi_txvalid_i (utmi_txvalid_o ),
+ .utmi_op_mode_i (utmi_op_mode_o ),
+ .utmi_xcvrselect_i (utmi_xcvrselect_o ),
+ .utmi_termselect_i (utmi_termselect_o ),
+ .utmi_dppulldown_i (utmi_dppulldown_o ),
+ .utmi_dmpulldown_i (utmi_dmpulldown_o ),
+ .usb_rx_rcv_i (usb_pads_rx_rcv_w ),
+ .usb_rx_dp_i (usb_pads_rx_dp_w ),
+ .usb_rx_dn_i (usb_pads_rx_dn_w ),
+ .usb_reset_assert_i ( 1'b0 ),
+
+ // Outputs
+ .utmi_data_in_o (utmi_data_in_i ),
+ .utmi_txready_o (utmi_txready_i ),
+ .utmi_rxvalid_o (utmi_rxvalid_i ),
+ .utmi_rxactive_o (utmi_rxactive_i ),
+ .utmi_rxerror_o (utmi_rxerror_i ),
+ .utmi_linestate_o (utmi_linestate_i ),
+ .usb_tx_dp_o (usb_pads_tx_dp_w ),
+ .usb_tx_dn_o (usb_pads_tx_dn_w ),
+ .usb_tx_oen_o (usb_pads_tx_oen_w ),
+ .usb_reset_detect_o ( ),
+ .usb_en_o ( )
+ );
+
+
+ usb_transceiver u_usb_xcvr (
+ // Inputs
+ .usb_phy_tx_dp_i (usb_pads_tx_dp_w ),
+ .usb_phy_tx_dn_i (usb_pads_tx_dn_w ),
+ .usb_phy_tx_oen_i (usb_pads_tx_oen_w ),
+ .mode_i (usb_xcvr_mode_w ),
+
+ .out_dp (out_dp ),
+ .out_dn (out_dn ),
+ .out_tx_oen (out_tx_oen ),
+
+ .in_dp (in_dp ),
+ .in_dn (in_dn ),
+
+
+ // Outputs
+ .usb_phy_rx_rcv_o (usb_pads_rx_rcv_w ),
+ .usb_phy_rx_dp_o (usb_pads_rx_dp_w ),
+ .usb_phy_rx_dn_o (usb_pads_rx_dn_w )
+);
+
+
+endmodule
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 80deff9..d32b2ef 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -95,6 +95,10 @@
//// i2cm integrated part of uart_i2cm module, ////
//// due to number of IO pin limitation, ////
//// Only UART OR I2C selected based on config mode ////
+//// 1.1 - 1st Aug 2021, Dinesh A ////
+//// usb1.1 host integrated part of uart_i2cm_usb module,////
+//// due to number of IO pin limitation, ////
+//// Only UART/I2C/USB selected based on config mode ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
@@ -258,10 +262,10 @@
wire wbd_uart_stb_o; // strobe/request
wire [7:0] wbd_uart_adr_o; // address
wire wbd_uart_we_o; // write
-wire [7:0] wbd_uart_dat_o; // data output
+wire [31:0] wbd_uart_dat_o; // data output
wire wbd_uart_sel_o; // byte enable
wire wbd_uart_cyc_o ;
-wire [7:0] wbd_uart_dat_i; // data input
+wire [31:0] wbd_uart_dat_i; // data input
wire wbd_uart_ack_i; // acknowlegement
wire wbd_uart_err_i; // error
@@ -273,10 +277,12 @@
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 usb_rst_n ;// i2c reset
+wire [1:0] uart_i2c_usb_sel ;// 0 - uart, 1 - I2C, 2- USb
wire sdram_clk ;
wire cpu_clk ;
wire rtc_clk ;
+wire usb_clk ;
wire wbd_clk_int ;
//wire wbd_clk_int1 ;
//wire wbd_clk_int2 ;
@@ -372,6 +378,7 @@
.sdram_clk (sdram_clk ),
.cpu_clk (cpu_clk ),
.rtc_clk (rtc_clk ),
+ .usb_clk (usb_clk ),
.wbd_int_rst_n (wbd_int_rst_n ),
.cpu_rst_n (cpu_rst_n ),
@@ -379,7 +386,8 @@
.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
+ .usb_rst_n (usb_rst_n ), // usb reset
+ .uart_i2c_usb_sel (uart_i2c_usb_sel ), // 0 - uart, 1 - I2C, 2- USB
// Master Port
.wbm_rst_i (wb_rst_i ),
@@ -678,21 +686,23 @@
);
-uart_i2c_top u_uart_i2c (
+uart_i2c_usb_top u_uart_i2c_usb (
.uart_rstn (uart_rst_n ), // uart reset
.i2c_rstn (i2c_rst_n ), // i2c reset
- .uart_i2c_sel (uart_i2c_sel ), // 0 - uart, 1 - I2C
+ .usb_rstn (usb_rst_n ), // i2c reset
+ .uart_i2c_usb_sel (uart_i2c_usb_sel ), // 0 - uart, 1 - I2C
.app_clk (wbd_clk_uart ),
+ .usb_clk (usb_clk ),
// Reg Bus Interface Signal
.reg_cs (wbd_uart_stb_o ),
.reg_wr (wbd_uart_we_o ),
.reg_addr (wbd_uart_adr_o[5:2] ),
- .reg_wdata (wbd_uart_dat_o[7:0] ),
+ .reg_wdata (wbd_uart_dat_o ),
.reg_be (wbd_uart_sel_o ),
// Outputs
- .reg_rdata (wbd_uart_dat_i[7:0] ),
+ .reg_rdata (wbd_uart_dat_i ),
.reg_ack (wbd_uart_ack_i ),
// Pad interface
diff --git a/verilog/rtl/wb_host/src/wb_host.sv b/verilog/rtl/wb_host/src/wb_host.sv
index 7605087..2daf54c 100644
--- a/verilog/rtl/wb_host/src/wb_host.sv
+++ b/verilog/rtl/wb_host/src/wb_host.sv
@@ -75,6 +75,7 @@
output logic sdram_clk ,
output logic cpu_clk ,
output logic rtc_clk ,
+ output logic usb_clk ,
// Global Reset control
output logic wbd_int_rst_n ,
output logic cpu_rst_n ,
@@ -82,7 +83,8 @@
output logic sdram_rst_n ,
output logic uart_rst_n ,
output logic i2cm_rst_n ,
- output logic uart_i2c_sel ,
+ output logic usb_rst_n ,
+ output logic [1:0] uart_i2c_usb_sel ,
// Master Port
input logic wbm_rst_i , // Regular Reset signal
@@ -143,13 +145,14 @@
logic [7:0] cfg_bank_sel;
logic [31:0] wbm_adr_int;
logic wbm_stb_int;
-logic [23:0] reg_0; // Software_Reg_0
+logic [31:0] reg_0; // Software_Reg_0
logic [2:0] cfg_wb_clk_ctrl;
-logic [2:0] cfg_sdram_clk_ctrl;
-logic [2:0] cfg_cpu_clk_ctrl;
-logic [2:0] cfg_rtc_clk_ctrl;
-logic [7:0] cfg_glb_ctrl;
+logic [3:0] cfg_sdram_clk_ctrl;
+logic [3:0] cfg_cpu_clk_ctrl;
+logic [7:0] cfg_rtc_clk_ctrl;
+logic [3:0] cfg_usb_clk_ctrl;
+logic [6:0] cfg_glb_ctrl;
assign wbm_rst_n = !wbm_rst_i;
@@ -160,8 +163,9 @@
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));
+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_usb_rst (.A(cfg_glb_ctrl[6]),.X(usb_rst_n));
+
// To reduce the load/Timing Wishbone I/F, Strobe is register to create
// multi-cycle
@@ -226,18 +230,21 @@
//-------------------------------------
// Global + Clock Control
// -------------------------------------
-assign cfg_glb_ctrl = reg_0[7:0];
-assign cfg_wb_clk_ctrl = reg_0[10:8];
-assign cfg_sdram_clk_ctrl = reg_0[15:12];
-assign cfg_cpu_clk_ctrl = reg_0[19:16];
-assign cfg_rtc_clk_ctrl = reg_0[23:20];
+assign cfg_glb_ctrl = reg_0[6:0];
+assign uart_i2c_usb_sel = reg_0[8:7];
+assign cfg_wb_clk_ctrl = reg_0[11:9];
+assign cfg_rtc_clk_ctrl = reg_0[19:12];
+assign cfg_cpu_clk_ctrl = reg_0[23:20];
+assign cfg_sdram_clk_ctrl = reg_0[27:24];
+assign cfg_usb_clk_ctrl = reg_0[31:28];
+
always @( *)
begin
reg_out [31:0] = 8'd0;
case (sw_addr [1:0])
- 2'b00 : reg_out [31:0] = {8'h0, reg_0[23:0]};
+ 2'b00 : reg_out [31:0] = reg_0;
2'b01 : reg_out [31:0] = {24'h0,cfg_bank_sel [7:0]};
2'b10 : reg_out [31:0] = cfg_clk_ctrl1 [31:0];
2'b11 : reg_out [31:0] = cfg_clk_ctrl2 [31:0];
@@ -247,14 +254,14 @@
-generic_register #(24,0 ) u_glb_ctrl (
+generic_register #(32,0 ) u_glb_ctrl (
.we ({24{sw_wr_en_0}} ),
.data_in (wbm_dat_i[23:0] ),
.reset_n (wbm_rst_n ),
.clk (wbm_clk_i ),
//List of Outs
- .data_out (reg_0[23:0])
+ .data_out (reg_0[31:0])
);
generic_register #(8,8'h30 ) u_bank_sel (
@@ -403,27 +410,44 @@
// Generate RTC Clock Generation
//----------------------------------
wire rtc_clk_div;
-wire rtc_ref_clk;
-wire rtc_clk_int;
-wire cfg_rtc_clk_src_sel = cfg_rtc_clk_ctrl[0];
-wire cfg_rtc_clk_div = cfg_rtc_clk_ctrl[1];
-wire [1:0] cfg_rtc_clk_ratio = cfg_rtc_clk_ctrl[3:2];
-
-assign rtc_ref_clk = (cfg_rtc_clk_src_sel) ? user_clock2 : user_clock1;
-assign rtc_clk_int = (cfg_rtc_clk_div) ? rtc_clk_div : rtc_ref_clk;
+wire [7:0] cfg_rtc_clk_ratio = cfg_rtc_clk_ctrl[7:0];
-sky130_fd_sc_hd__clkbuf_16 u_clkbuf_rtc (.A (rtc_clk_int), . X(rtc_clk));
+sky130_fd_sc_hd__clkbuf_16 u_clkbuf_rtc (.A (rtc_clk_div), . X(rtc_clk));
-clk_ctl #(1) u_rtcclk (
+clk_ctl #(7) u_rtcclk (
// Outputs
.clk_o (rtc_clk_div ),
// Inputs
- .mclk (rtc_ref_clk ),
+ .mclk (user_clock2 ),
.reset_n (reset_n ),
.clk_div_ratio (cfg_rtc_clk_ratio)
);
+//----------------------------------
+// Generate USB Clock Generation
+//----------------------------------
+wire usb_clk_div;
+wire usb_ref_clk;
+wire usb_clk_int;
+
+wire cfg_usb_clk_div = cfg_usb_clk_ctrl[0];
+wire [2:0] cfg_usb_clk_ratio = cfg_usb_clk_ctrl[3:1];
+
+assign usb_ref_clk = user_clock2 ;
+assign usb_clk_int = (cfg_usb_clk_div) ? usb_clk_div : usb_ref_clk;
+
+
+sky130_fd_sc_hd__clkbuf_16 u_clkbuf_usb (.A (usb_clk_int), . X(usb_clk));
+
+clk_ctl #(2) u_usbclk (
+ // Outputs
+ .clk_o (usb_clk_div ),
+ // Inputs
+ .mclk (usb_ref_clk ),
+ .reset_n (reset_n ),
+ .clk_div_ratio (cfg_usb_clk_ratio)
+ );
endmodule
diff --git a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
index def88d3..d8b59a5 100644
--- a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
+++ b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
@@ -155,10 +155,10 @@
// Slave 3 Interface
// Uart is 8bit interface
- input logic [7:0] s3_wbd_dat_i,
+ input logic [31:0] s3_wbd_dat_i,
input logic s3_wbd_ack_i,
// input logic s3_wbd_err_i,
- output logic [7:0] s3_wbd_dat_o,
+ output logic [31:0] s3_wbd_dat_o,
output logic [7:0] s3_wbd_adr_o,
output logic s3_wbd_sel_o,
output logic s3_wbd_we_o,
@@ -321,7 +321,7 @@
assign s2_wbd_cyc_o = s2_wb_wr.wbd_cyc ;
assign s2_wbd_stb_o = s2_wb_wr.wbd_stb ;
- assign s3_wbd_dat_o = s3_wb_wr.wbd_dat[7:0] ;
+ assign s3_wbd_dat_o = s3_wb_wr.wbd_dat[31:0] ;
assign s3_wbd_adr_o = s3_wb_wr.wbd_adr[7:0] ; // Global Reg Need 8 bit
assign s3_wbd_sel_o = s3_wb_wr.wbd_sel[0] ;
assign s3_wbd_we_o = s3_wb_wr.wbd_we ;
@@ -340,7 +340,7 @@
assign s2_wb_rd.wbd_ack = s2_wbd_ack_i ;
assign s2_wb_rd.wbd_err = 1'b0; // s2_wbd_err_i ; - unused
- assign s3_wb_rd.wbd_dat = {24'h0,s3_wbd_dat_i} ;
+ assign s3_wb_rd.wbd_dat = s3_wbd_dat_i ;
assign s3_wb_rd.wbd_ack = s3_wbd_ack_i ;
assign s3_wb_rd.wbd_err = 1'b0; // s3_wbd_err_i ; - unused