USB fixups

- Build rules for usbdev tests.
- Fixups for the usbdev libraries and tests to execute on matcha.
- Tweak to the verilator setup, such that VBUS sense is bound to the
  correct MIO.

Change-Id: Ieee258399986e106529131c49e11b88f12436ca7
diff --git a/hw/top_matcha/rtl/chip_matcha_verilator.sv b/hw/top_matcha/rtl/chip_matcha_verilator.sv
index d0d5606..279cc22 100644
--- a/hw/top_matcha/rtl/chip_matcha_verilator.sv
+++ b/hw/top_matcha/rtl/chip_matcha_verilator.sv
@@ -123,7 +123,7 @@
     mio_in[MioPadIob8:MioPadIoa0] = cio_gpio_p2d_i[17:0];
     mio_in[MioPadIob12:MioPadIob10] = cio_gpio_p2d_i[20:18];
     mio_in[MioPadIoc6] = cio_gpio_p2d_i[21];
-    mio_in[MioPadIoc7] = cio_gpio_p2d_i[25];
+    mio_in[MioPadIoc7] = cio_usbdev_sense_p2d_i;
     mio_in[MioPadIoc9] = cio_gpio_p2d_i[26];
     mio_in[MioPadIor7:MioPadIor6] = cio_gpio_p2d_i[29:28];
     mio_in[MioPadIor10] = cio_gpio_p2d_i[31];
@@ -403,8 +403,6 @@
   logic unused_pwr_clamp;
   assign unused_pwr_clamp = base_ast_pwr.pwr_clamp;
 
-  logic unused_cio_usbdev_sense_p2d_i;
-  assign unused_cio_usbdev_sense_p2d_i = cio_usbdev_sense_p2d_i;
 
   prim_mubi_pkg::mubi4_t ast_init_done;
   ast #(
diff --git a/sw/device/lib/dif/BUILD b/sw/device/lib/dif/BUILD
index c907a26..e926379 100644
--- a/sw/device/lib/dif/BUILD
+++ b/sw/device/lib/dif/BUILD
@@ -273,4 +273,25 @@
     ],
 )
 
+cc_library(
+    name = "usbdev",
+    srcs = [
+        "autogen/dif_usbdev_autogen.c",
+        "autogen/dif_usbdev_autogen.h",
+        "dif_usbdev.c",
+    ],
+    hdrs = [
+        "dif_usbdev.h",
+    ],
+    deps = [
+        "@lowrisc_opentitan//sw/device/lib/dif:base",
+        "@lowrisc_opentitan//hw/ip/usbdev/data:usbdev_regs",
+        "@lowrisc_opentitan//sw/device/lib/base:bitfield",
+        "@lowrisc_opentitan//sw/device/lib/base:macros",
+        "@lowrisc_opentitan//sw/device/lib/base:memory",
+        "@lowrisc_opentitan//sw/device/lib/base:mmio",
+        "@lowrisc_opentitan//sw/device/lib/base:multibits",
+    ],
+)
+
 #TODO(b/249392661): Add unit test for each dif component.
diff --git a/sw/device/lib/testing/BUILD b/sw/device/lib/testing/BUILD
index 5f8fd9f..dc8bfdb 100644
--- a/sw/device/lib/testing/BUILD
+++ b/sw/device/lib/testing/BUILD
@@ -96,3 +96,34 @@
         "@lowrisc_opentitan//sw/device/lib/testing/test_framework:check",
     ],
 )
+
+cc_library(
+    name = "usb_testutils",
+    srcs = [
+        "usb_testutils.c",
+        "usb_testutils_controlep.c",
+    ],
+    hdrs = [
+        "usb_testutils.h",
+        "usb_testutils_controlep.h",
+        "usb_testutils_diags.h",
+    ],
+    target_compatible_with = [OPENTITAN_CPU],
+    deps = [
+        "//hw/top_matcha/sw/autogen:top_matcha",
+        "//sw/device/lib/dif:usbdev",
+        "@lowrisc_opentitan//sw/device/lib/testing/test_framework:check",
+    ],
+)
+
+cc_library(
+    name = "usb_testutils_simpleserial",
+    srcs = ["usb_testutils_simpleserial.c"],
+    hdrs = ["usb_testutils_simpleserial.h"],
+    target_compatible_with = [OPENTITAN_CPU],
+    deps = [
+        ":usb_testutils",
+        "@lowrisc_opentitan//sw/device/lib/testing/test_framework:check",
+    ],
+)
+
diff --git a/sw/device/lib/testing/usb_testutils.c b/sw/device/lib/testing/usb_testutils.c
index bacc95b..d1e79c0 100644
--- a/sw/device/lib/testing/usb_testutils.c
+++ b/sw/device/lib/testing/usb_testutils.c
@@ -7,9 +7,9 @@
 #include "sw/device/lib/dif/dif_usbdev.h"
 #include "sw/device/lib/testing/test_framework/check.h"
 
-#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"
+#include "hw/top_matcha/sw/autogen/top_matcha.h"
 
-#define USBDEV_BASE_ADDR TOP_EARLGREY_USBDEV_BASE_ADDR
+#define USBDEV_BASE_ADDR TOP_MATCHA_USBDEV_BASE_ADDR
 
 static dif_usbdev_t usbdev;
 static dif_usbdev_buffer_pool_t buffer_pool;
diff --git a/sw/device/tests/BUILD b/sw/device/tests/BUILD
index cf00c08..69afec9 100644
--- a/sw/device/tests/BUILD
+++ b/sw/device/tests/BUILD
@@ -511,6 +511,44 @@
     ],
 )
 
+sec_flash_binary(
+    name = "usbdev_test",
+    srcs = [
+        "usbdev_test.c",
+    ],
+    copts = [
+        "-nostdlib",
+        "-ffreestanding",
+    ],
+    deps = [
+        ":test_lib",
+        "//sw/device/lib/testing/test_framework:ottf_main",
+        "//sw/device/lib/dif:usbdev",
+        "//sw/device/lib/testing:usb_testutils",
+        "//sw/device/lib/testing:usb_testutils_simpleserial",
+        "@lowrisc_opentitan//hw/ip/usbdev/data:usbdev_regs",
+    ],
+)
+
+sec_flash_binary(
+    name = "usbdev_stream_test",
+    srcs = [
+        "usbdev_stream_test.c",
+    ],
+    copts = [
+        "-nostdlib",
+        "-ffreestanding",
+    ],
+    deps = [
+        ":test_lib",
+        "//sw/device/lib/testing/test_framework:ottf_main",
+        "//sw/device/lib/dif:usbdev",
+        "//sw/device/lib/testing:usb_testutils",
+        "//sw/device/lib/testing:usb_testutils_simpleserial",
+        "@lowrisc_opentitan//hw/ip/usbdev/data:usbdev_regs",
+    ],
+)
+
 cc_library(
     name = "test_lib",
     target_compatible_with = [OPENTITAN_CPU],
@@ -611,6 +649,18 @@
 # To test the following targets:
 # bazel test --test_output=streamed --test_tag_filters=verilator,-broken //sw/device/tests/...
 matcha_verilator_test(
+    name = "verilator_usbdev_test",
+    timeout = "long",
+    sec_flash_binary = ":usbdev_test",
+)
+
+matcha_verilator_test(
+    name = "verilator_usbdev_stream_test",
+    timeout = "long",
+    sec_flash_binary = ":usbdev_stream_test",
+)
+
+matcha_verilator_test(
     name = "verilator_tlul_mailbox_test",
     timeout = "long",
     sec_flash_binary = ":tlul_mailbox_test",
diff --git a/sw/device/tests/usbdev_stream_test.c b/sw/device/tests/usbdev_stream_test.c
index a119324..0d19c6d 100644
--- a/sw/device/tests/usbdev_stream_test.c
+++ b/sw/device/tests/usbdev_stream_test.c
@@ -26,7 +26,7 @@
 #include "sw/device/lib/testing/usb_testutils.h"
 #include "sw/device/lib/testing/usb_testutils_controlep.h"
 
-#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"  // Generated.
+#include "hw/top_matcha/sw/autogen/top_matcha.h"  // Generated.
 
 // Maximum number of concurrent streams
 #ifdef USBDEV_NUM_ENDPOINTS
@@ -36,13 +36,6 @@
 #define STREAMS_MAX 11U
 #endif
 
-// TODO - currently we are unable to send the configuration descriptor
-// if we try to describe more than two bidirectional endpoints
-#if STREAMS_MAX > 2U
-#undef STREAMS_MAX
-#define STREAMS_MAX 2U
-#endif
-
 // Number of streams to be tested
 #ifndef NUM_STREAMS
 #define NUM_STREAMS STREAMS_MAX
@@ -216,15 +209,14 @@
 
 /**
  * Configuration values for USB.
- * TODO - dynamically construct a config descriptor appropriate to the test;
- *        this would avoid creating unusable ports on the host and also provide
- *        a little more testing
  */
 static const uint8_t config_descriptors[] = {
     USB_CFG_DSCR_HEAD(USB_CFG_DSCR_LEN + STREAMS_MAX * (USB_INTERFACE_DSCR_LEN +
                                                         2 * USB_EP_DSCR_LEN),
                       STREAMS_MAX),
 
+    // Up to 11 interfaces and STREAMS_MAX in the descriptor head specifies how
+    // many of the interfaces will be declared to the host
     VEND_INTERFACE_DSCR(0, 2, 0x50, 1),
     USB_BULK_EP_DSCR(0, 1U, USBDEV_MAX_PACKET_SIZE, 0),
     USB_BULK_EP_DSCR(1, 1U, USBDEV_MAX_PACKET_SIZE, 0),
@@ -232,6 +224,42 @@
     VEND_INTERFACE_DSCR(1, 2, 0x50, 1),
     USB_BULK_EP_DSCR(0, 2U, USBDEV_MAX_PACKET_SIZE, 0),
     USB_BULK_EP_DSCR(1, 2U, USBDEV_MAX_PACKET_SIZE, 0),
+
+    VEND_INTERFACE_DSCR(2, 2, 0x50, 1),
+    USB_BULK_EP_DSCR(0, 3U, USBDEV_MAX_PACKET_SIZE, 0),
+    USB_BULK_EP_DSCR(1, 3U, USBDEV_MAX_PACKET_SIZE, 0),
+
+    VEND_INTERFACE_DSCR(3, 2, 0x50, 1),
+    USB_BULK_EP_DSCR(0, 4U, USBDEV_MAX_PACKET_SIZE, 0),
+    USB_BULK_EP_DSCR(1, 4U, USBDEV_MAX_PACKET_SIZE, 0),
+
+    VEND_INTERFACE_DSCR(4, 2, 0x50, 1),
+    USB_BULK_EP_DSCR(0, 5U, USBDEV_MAX_PACKET_SIZE, 0),
+    USB_BULK_EP_DSCR(1, 5U, USBDEV_MAX_PACKET_SIZE, 0),
+
+    VEND_INTERFACE_DSCR(5, 2, 0x50, 1),
+    USB_BULK_EP_DSCR(0, 6U, USBDEV_MAX_PACKET_SIZE, 0),
+    USB_BULK_EP_DSCR(1, 6U, USBDEV_MAX_PACKET_SIZE, 0),
+
+    VEND_INTERFACE_DSCR(6, 2, 0x50, 1),
+    USB_BULK_EP_DSCR(0, 7U, USBDEV_MAX_PACKET_SIZE, 0),
+    USB_BULK_EP_DSCR(1, 7U, USBDEV_MAX_PACKET_SIZE, 0),
+
+    VEND_INTERFACE_DSCR(7, 2, 0x50, 1),
+    USB_BULK_EP_DSCR(0, 8U, USBDEV_MAX_PACKET_SIZE, 0),
+    USB_BULK_EP_DSCR(1, 8U, USBDEV_MAX_PACKET_SIZE, 0),
+
+    VEND_INTERFACE_DSCR(8, 2, 0x50, 1),
+    USB_BULK_EP_DSCR(0, 9U, USBDEV_MAX_PACKET_SIZE, 0),
+    USB_BULK_EP_DSCR(1, 9U, USBDEV_MAX_PACKET_SIZE, 0),
+
+    VEND_INTERFACE_DSCR(9, 2, 0x50, 1),
+    USB_BULK_EP_DSCR(0, 10U, USBDEV_MAX_PACKET_SIZE, 0),
+    USB_BULK_EP_DSCR(1, 10U, USBDEV_MAX_PACKET_SIZE, 0),
+
+    VEND_INTERFACE_DSCR(10, 2, 0x50, 1),
+    USB_BULK_EP_DSCR(0, 11U, USBDEV_MAX_PACKET_SIZE, 0),
+    USB_BULK_EP_DSCR(1, 11U, USBDEV_MAX_PACKET_SIZE, 0),
 };
 
 /**
@@ -414,7 +442,7 @@
 }
 
 // Callback for successful buffer transmission
-static void strm_tx_done(void *stream_v) {
+static void strm_tx_done(void *stream_v, usb_testutils_xfr_result_t result) {
   usbdev_stream_t *s = (usbdev_stream_t *)stream_v;
   usbdev_stream_test_ctx_t *ctx = s->ctx;
   usb_testutils_ctx_t *usbdev = ctx->usbdev;
@@ -457,7 +485,6 @@
                     dif_usbdev_buffer_t buf) {
   usbdev_stream_t *s = (usbdev_stream_t *)stream_v;
   usbdev_stream_test_ctx_t *ctx = s->ctx;
-  usb_testutils_ctx_t *usbdev = ctx->usbdev;
 
   CHECK(packet_info.endpoint == s->rx_ep);
 
@@ -627,9 +654,9 @@
   // Context state for streaming test
   usbdev_stream_test_ctx_t *ctx = &stream_test;
 
-  CHECK(kDeviceType == kDeviceSimVerilator || kDeviceType == kDeviceFpgaCw310,
+  CHECK(kDeviceType == kDeviceSimVerilator || kDeviceType == kDeviceFpgaNexus,
         "This test is not expected to run on platforms other than the "
-        "Verilator simulation or CW310 FPGA. It needs logic on the host side "
+        "Verilator simulation or Nexus FPGA. It needs logic on the host side "
         "to retrieve, scramble and return the generated byte stream");
 
   LOG_INFO("Running USBDEV Stream Test");
@@ -646,11 +673,17 @@
   LOG_INFO(" - %u stream(s), 0x%x bytes each", nstreams, transfer_bytes);
 
   CHECK_DIF_OK(dif_pinmux_init(
-      mmio_region_from_addr(TOP_EARLGREY_PINMUX_AON_BASE_ADDR), &pinmux));
+      mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
   pinmux_testutils_init(&pinmux);
   CHECK_DIF_OK(dif_pinmux_input_select(
-      &pinmux, kTopEarlgreyPinmuxPeripheralInUsbdevSense,
-      kTopEarlgreyPinmuxInselIoc7));
+      &pinmux, kTopMatchaPinmuxPeripheralInUsbdevSense,
+      kTopMatchaPinmuxInselIoc7));
+  if (kDeviceType == kDeviceFpgaNexus) {
+      dif_pinmux_pad_attr_t attrs;
+      CHECK_DIF_OK(dif_pinmux_pad_get_attrs(&pinmux, kTopMatchaMuxedPadsIoc7, kDifPinmuxPadKindMio, &attrs));
+      attrs.flags |= kDifPinmuxPadAttrInvertLevel;
+      CHECK_DIF_OK(dif_pinmux_pad_write_attrs(&pinmux, kTopMatchaMuxedPadsIoc7, kDifPinmuxPadKindMio, attrs, &attrs));
+  }
 
   // Remember context state for usb_testutils context
   ctx->usbdev = &usbdev;
@@ -658,7 +691,7 @@
   // Call `usbdev_init` here so that DPI will not start until the
   // simulation has finished all of the printing, which takes a while
   // if `--trace` was passed in.
-  usb_testutils_init(ctx->usbdev, /*pinflip=*/false, /*en_diff_rcvr=*/false,
+  usb_testutils_init(&usbdev, /*pinflip=*/false, /*en_diff_rcvr=*/kDeviceType == kDeviceSimVerilator ? false : true,
                      /*tx_use_d_se0=*/false);
   usb_testutils_controlep_init(&usbdev_control, ctx->usbdev, 0,
                                config_descriptors, sizeof(config_descriptors),
diff --git a/sw/device/tests/usbdev_test.c b/sw/device/tests/usbdev_test.c
index af52cf5..482c207 100644
--- a/sw/device/tests/usbdev_test.c
+++ b/sw/device/tests/usbdev_test.c
@@ -27,7 +27,7 @@
 #include "sw/device/lib/testing/usb_testutils_controlep.h"
 #include "sw/device/lib/testing/usb_testutils_simpleserial.h"
 
-#include "hw/top_earlgrey/sw/autogen/top_earlgrey.h"  // Generated.
+#include "hw/top_matcha/sw/autogen/top_matcha.h"  // Generated.
 
 /**
  * Configuration values for USB.
@@ -97,24 +97,30 @@
 OTTF_DEFINE_TEST_CONFIG();
 
 bool test_main(void) {
-  CHECK(kDeviceType == kDeviceSimVerilator || kDeviceType == kDeviceFpgaCw310,
+  CHECK(kDeviceType == kDeviceSimVerilator || kDeviceType == kDeviceFpgaNexus,
         "This test is not expected to run on platforms other than the "
-        "Verilator simulation or CW310 FPGA. It needs the USB DPI model "
+        "Verilator simulation or Nexus FPGA. It needs the USB DPI model "
         "or host application.");
 
   LOG_INFO("Running USBDEV test");
 
   CHECK_DIF_OK(dif_pinmux_init(
-      mmio_region_from_addr(TOP_EARLGREY_PINMUX_AON_BASE_ADDR), &pinmux));
+      mmio_region_from_addr(TOP_MATCHA_PINMUX_AON_BASE_ADDR), &pinmux));
   pinmux_testutils_init(&pinmux);
   CHECK_DIF_OK(dif_pinmux_input_select(
-      &pinmux, kTopEarlgreyPinmuxPeripheralInUsbdevSense,
-      kTopEarlgreyPinmuxInselIoc7));
+      &pinmux, kTopMatchaPinmuxPeripheralInUsbdevSense,
+      kTopMatchaPinmuxInselIoc7));
+  if (kDeviceType == kDeviceFpgaNexus) {
+      dif_pinmux_pad_attr_t attrs;
+      CHECK_DIF_OK(dif_pinmux_pad_get_attrs(&pinmux, kTopMatchaMuxedPadsIoc7, kDifPinmuxPadKindMio, &attrs));
+      attrs.flags |= kDifPinmuxPadAttrInvertLevel;
+      CHECK_DIF_OK(dif_pinmux_pad_write_attrs(&pinmux, kTopMatchaMuxedPadsIoc7, kDifPinmuxPadKindMio, attrs, &attrs));
+  }
 
   // Call `usbdev_init` here so that DPI will not start until the
   // simulation has finished all of the printing, which takes a while
   // if `--trace` was passed in.
-  usb_testutils_init(&usbdev, /*pinflip=*/false, /*en_diff_rcvr=*/false,
+  usb_testutils_init(&usbdev, /*pinflip=*/false, /*en_diff_rcvr=*/kDeviceType == kDeviceSimVerilator ? false : true,
                      /*tx_use_d_se0=*/false);
   usb_testutils_controlep_init(&usbdev_control, &usbdev, 0, config_descriptors,
                                sizeof(config_descriptors), test_descriptor,