[usbdev] Enable defaulting to NAK for OUT transactions

Add a bit to change the behavior for OUT transactions to default to NAK
without software intervention, for safe communication of responses to
the host.
Before this commit, the device could incorrectly communicate acceptance
of a packet to the host if the firmware did not take action in time.
Defaulting to NAK gives the firmware time, since this is a nonbinding
condition--The device is merely saying, "Please try again later."

Clear the rxenable_out bit in hardware when a packet is received. Update
software code to match.

This change could have deleterious effects on performance in some cases,
but priority is given to safe handling of responses. For interfaces that
may perform transactions when a buffer is available, do not set the
set_nak_out bit for the corresponding endpoints.

Signed-off-by: Alexander Williams <awill@google.com>
diff --git a/hw/ip/usbdev/data/usbdev.hjson b/hw/ip/usbdev/data/usbdev.hjson
index 93229e1..8970fe1 100644
--- a/hw/ip/usbdev/data/usbdev.hjson
+++ b/hw/ip/usbdev/data/usbdev.hjson
@@ -538,16 +538,37 @@
         cname: "Endpoint"
         desc: "Receive OUT transaction enable",
         swaccess: "rw",
-        hwaccess: "hro",
+        hwaccess: "hrw",
+        async: "clk_usb_48mhz_i"
         fields: [
           {
             bits: "0",
             name: "out",
             desc: '''
-                  This bit must be set to enable OUT transactions to be
-                  received on the endpoint. If the bit is clear then an
-                  OUT request will be responded to with a NAK, if the endpoint
-                  is enabled.
+                  This bit must be set to enable OUT transactions to be received on the endpoint.
+                  If the bit is clear then an OUT request will be responded to with a NAK, if the endpoint is enabled.
+                  If set_nak_out for this endpoint is set, hardware will clear this bit whenever an OUT transaction is received on this endpoint.
+                  Software must set this bit again to receive the next OUT transaction.
+                  Until that happens, hardware will continue to NAK any OUT transaction to this endpoint.
+                  '''
+          }
+        ]
+      }
+    }
+    { multireg: {
+        name: "set_nak_out",
+        count: "NEndpoints"
+        cname: "Endpoint"
+        desc: "Set NAK after OUT transactions",
+        swaccess: "rw",
+        hwaccess: "hro",
+        fields: [
+          {
+            bits: "0",
+            name: "enable",
+            desc: '''
+                  When this bit is set, hardware will clear this endpoint's rxenable_out bit whenever an OUT transaction is received on this endpoint.
+                  This bit should not be changed while the endpoint is active.
                   '''
           }
         ]
diff --git a/hw/ip/usbdev/rtl/usbdev.sv b/hw/ip/usbdev/rtl/usbdev.sv
index e2ccc2b..605a8cf 100644
--- a/hw/ip/usbdev/rtl/usbdev.sv
+++ b/hw/ip/usbdev/rtl/usbdev.sv
@@ -216,6 +216,8 @@
   logic [AVFifoWidth - 1:0] usb_av_rdata;
   logic [RXFifoWidth - 1:0] usb_rx_wdata, rx_rdata_raw, rx_rdata;
 
+  logic [NEndpoints-1:0] clear_rxenable_out;
+
   assign event_av_overflow = reg2hw.avbuffer.qe & (~av_fifo_wready);
   assign hw2reg.usbstat.av_full.d = ~av_fifo_wready;
   assign hw2reg.usbstat.rx_empty.d = ~rx_fifo_rvalid;
@@ -287,8 +289,8 @@
   logic [NEndpoints-1:0] clear_rdybit, set_sentbit, update_pend;
   logic                  usb_setup_received, setup_received, usb_set_sent, set_sent;
   logic [NEndpoints-1:0] ep_out_iso, ep_in_iso;
-  logic [NEndpoints-1:0] enable_setup, enable_out, in_ep_stall, out_ep_stall;
-  logic [NEndpoints-1:0] usb_enable_setup, usb_enable_out;
+  logic [NEndpoints-1:0] enable_setup, in_ep_stall, out_ep_stall;
+  logic [NEndpoints-1:0] usb_enable_setup, usb_enable_out, ep_set_nak_on_out;
   logic [NEndpoints-1:0] usb_in_ep_stall, usb_out_ep_stall;
   logic [NEndpoints-1:0] ep_in_enable, ep_out_enable, usb_ep_in_enable, usb_ep_out_enable;
   logic [NEndpoints-1:0] in_rdy_async;
@@ -307,8 +309,8 @@
   // RX enables
   always_comb begin : proc_map_rxenable
     for (int i = 0; i < NEndpoints; i++) begin
-      enable_setup[i] = reg2hw.rxenable_setup[i].q;
-      enable_out[i]   = reg2hw.rxenable_out[i].q;
+      enable_setup[i]   = reg2hw.rxenable_setup[i].q;
+      usb_enable_out[i] = reg2hw.rxenable_out[i].q;
     end
   end
 
@@ -321,12 +323,12 @@
   end
 
   prim_flop_2sync #(
-    .Width(4*NEndpoints)
+    .Width(3*NEndpoints)
   ) usbdev_sync_ep_cfg (
     .clk_i  (clk_usb_48mhz_i),
     .rst_ni (rst_usb_48mhz_ni),
-    .d_i    ({enable_setup, enable_out, in_ep_stall, out_ep_stall}),
-    .q_o    ({usb_enable_setup, usb_enable_out, usb_in_ep_stall, usb_out_ep_stall})
+    .d_i    ({enable_setup, in_ep_stall, out_ep_stall}),
+    .q_o    ({usb_enable_setup, usb_in_ep_stall, usb_out_ep_stall})
   );
 
   prim_flop_2sync #(
@@ -343,6 +345,7 @@
     for (int i = 0; i < NEndpoints; i++) begin
       ep_out_iso[i] = reg2hw.out_iso[i].q;
       ep_in_iso[i] = reg2hw.in_iso[i].q;
+      ep_set_nak_on_out[i] = reg2hw.set_nak_out[i].q;
     end
   end
 
@@ -423,6 +426,25 @@
     end
   end
 
+  // Clear of rxenable_out bit
+  // If so configured, for every received transaction on a given endpoint, clear
+  // the rxenable_out bit. In this configuration, hardware defaults to NAKing
+  // any subsequent transaction, so software has time to decide the next
+  // response.
+  always_comb begin
+    clear_rxenable_out = '0;
+    if (usb_rx_wvalid && usb_out_endpoint_val) begin
+      clear_rxenable_out[usb_out_endpoint] = ep_set_nak_on_out[usb_out_endpoint];
+    end
+  end
+
+  always_comb begin
+    for (int i = 0; i < NEndpoints; i++) begin
+      hw2reg.rxenable_out[i].d = 1'b0;
+      hw2reg.rxenable_out[i].de = clear_rxenable_out[i];
+    end
+  end
+
   // Event (pulse) synchronization
   prim_pulse_sync usbdev_sync_in_err (
     .clk_src_i   (clk_usb_48mhz_i),
diff --git a/hw/ip/usbdev/rtl/usbdev_reg_pkg.sv b/hw/ip/usbdev/rtl/usbdev_reg_pkg.sv
index c0acb39..15ac6cd 100644
--- a/hw/ip/usbdev/rtl/usbdev_reg_pkg.sv
+++ b/hw/ip/usbdev/rtl/usbdev_reg_pkg.sv
@@ -256,6 +256,10 @@
 
   typedef struct packed {
     logic        q;
+  } usbdev_reg2hw_set_nak_out_mreg_t;
+
+  typedef struct packed {
+    logic        q;
   } usbdev_reg2hw_out_stall_mreg_t;
 
   typedef struct packed {
@@ -477,6 +481,11 @@
   typedef struct packed {
     logic        d;
     logic        de;
+  } usbdev_hw2reg_rxenable_out_mreg_t;
+
+  typedef struct packed {
+    logic        d;
+    logic        de;
   } usbdev_hw2reg_in_sent_mreg_t;
 
   typedef struct packed {
@@ -550,17 +559,18 @@
 
   // Register -> HW type
   typedef struct packed {
-    usbdev_reg2hw_intr_state_reg_t intr_state; // [413:397]
-    usbdev_reg2hw_intr_enable_reg_t intr_enable; // [396:380]
-    usbdev_reg2hw_intr_test_reg_t intr_test; // [379:346]
-    usbdev_reg2hw_alert_test_reg_t alert_test; // [345:344]
-    usbdev_reg2hw_usbctrl_reg_t usbctrl; // [343:334]
-    usbdev_reg2hw_ep_out_enable_mreg_t [11:0] ep_out_enable; // [333:322]
-    usbdev_reg2hw_ep_in_enable_mreg_t [11:0] ep_in_enable; // [321:310]
-    usbdev_reg2hw_avbuffer_reg_t avbuffer; // [309:304]
-    usbdev_reg2hw_rxfifo_reg_t rxfifo; // [303:283]
-    usbdev_reg2hw_rxenable_setup_mreg_t [11:0] rxenable_setup; // [282:271]
-    usbdev_reg2hw_rxenable_out_mreg_t [11:0] rxenable_out; // [270:259]
+    usbdev_reg2hw_intr_state_reg_t intr_state; // [425:409]
+    usbdev_reg2hw_intr_enable_reg_t intr_enable; // [408:392]
+    usbdev_reg2hw_intr_test_reg_t intr_test; // [391:358]
+    usbdev_reg2hw_alert_test_reg_t alert_test; // [357:356]
+    usbdev_reg2hw_usbctrl_reg_t usbctrl; // [355:346]
+    usbdev_reg2hw_ep_out_enable_mreg_t [11:0] ep_out_enable; // [345:334]
+    usbdev_reg2hw_ep_in_enable_mreg_t [11:0] ep_in_enable; // [333:322]
+    usbdev_reg2hw_avbuffer_reg_t avbuffer; // [321:316]
+    usbdev_reg2hw_rxfifo_reg_t rxfifo; // [315:295]
+    usbdev_reg2hw_rxenable_setup_mreg_t [11:0] rxenable_setup; // [294:283]
+    usbdev_reg2hw_rxenable_out_mreg_t [11:0] rxenable_out; // [282:271]
+    usbdev_reg2hw_set_nak_out_mreg_t [11:0] set_nak_out; // [270:259]
     usbdev_reg2hw_out_stall_mreg_t [11:0] out_stall; // [258:247]
     usbdev_reg2hw_in_stall_mreg_t [11:0] in_stall; // [246:235]
     usbdev_reg2hw_configin_mreg_t [11:0] configin; // [234:67]
@@ -574,10 +584,11 @@
 
   // HW -> register type
   typedef struct packed {
-    usbdev_hw2reg_intr_state_reg_t intr_state; // [220:187]
-    usbdev_hw2reg_usbctrl_reg_t usbctrl; // [186:179]
-    usbdev_hw2reg_usbstat_reg_t usbstat; // [178:155]
-    usbdev_hw2reg_rxfifo_reg_t rxfifo; // [154:138]
+    usbdev_hw2reg_intr_state_reg_t intr_state; // [244:211]
+    usbdev_hw2reg_usbctrl_reg_t usbctrl; // [210:203]
+    usbdev_hw2reg_usbstat_reg_t usbstat; // [202:179]
+    usbdev_hw2reg_rxfifo_reg_t rxfifo; // [178:162]
+    usbdev_hw2reg_rxenable_out_mreg_t [11:0] rxenable_out; // [161:138]
     usbdev_hw2reg_in_sent_mreg_t [11:0] in_sent; // [137:114]
     usbdev_hw2reg_out_stall_mreg_t [11:0] out_stall; // [113:90]
     usbdev_hw2reg_in_stall_mreg_t [11:0] in_stall; // [89:66]
@@ -599,29 +610,30 @@
   parameter logic [BlockAw-1:0] USBDEV_RXFIFO_OFFSET = 12'h 24;
   parameter logic [BlockAw-1:0] USBDEV_RXENABLE_SETUP_OFFSET = 12'h 28;
   parameter logic [BlockAw-1:0] USBDEV_RXENABLE_OUT_OFFSET = 12'h 2c;
-  parameter logic [BlockAw-1:0] USBDEV_IN_SENT_OFFSET = 12'h 30;
-  parameter logic [BlockAw-1:0] USBDEV_OUT_STALL_OFFSET = 12'h 34;
-  parameter logic [BlockAw-1:0] USBDEV_IN_STALL_OFFSET = 12'h 38;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_0_OFFSET = 12'h 3c;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_1_OFFSET = 12'h 40;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_2_OFFSET = 12'h 44;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_3_OFFSET = 12'h 48;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_4_OFFSET = 12'h 4c;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_5_OFFSET = 12'h 50;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_6_OFFSET = 12'h 54;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_7_OFFSET = 12'h 58;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_8_OFFSET = 12'h 5c;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_9_OFFSET = 12'h 60;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_10_OFFSET = 12'h 64;
-  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_11_OFFSET = 12'h 68;
-  parameter logic [BlockAw-1:0] USBDEV_OUT_ISO_OFFSET = 12'h 6c;
-  parameter logic [BlockAw-1:0] USBDEV_IN_ISO_OFFSET = 12'h 70;
-  parameter logic [BlockAw-1:0] USBDEV_DATA_TOGGLE_CLEAR_OFFSET = 12'h 74;
-  parameter logic [BlockAw-1:0] USBDEV_PHY_PINS_SENSE_OFFSET = 12'h 78;
-  parameter logic [BlockAw-1:0] USBDEV_PHY_PINS_DRIVE_OFFSET = 12'h 7c;
-  parameter logic [BlockAw-1:0] USBDEV_PHY_CONFIG_OFFSET = 12'h 80;
-  parameter logic [BlockAw-1:0] USBDEV_WAKE_CONFIG_OFFSET = 12'h 84;
-  parameter logic [BlockAw-1:0] USBDEV_WAKE_EVENTS_OFFSET = 12'h 88;
+  parameter logic [BlockAw-1:0] USBDEV_SET_NAK_OUT_OFFSET = 12'h 30;
+  parameter logic [BlockAw-1:0] USBDEV_IN_SENT_OFFSET = 12'h 34;
+  parameter logic [BlockAw-1:0] USBDEV_OUT_STALL_OFFSET = 12'h 38;
+  parameter logic [BlockAw-1:0] USBDEV_IN_STALL_OFFSET = 12'h 3c;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_0_OFFSET = 12'h 40;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_1_OFFSET = 12'h 44;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_2_OFFSET = 12'h 48;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_3_OFFSET = 12'h 4c;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_4_OFFSET = 12'h 50;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_5_OFFSET = 12'h 54;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_6_OFFSET = 12'h 58;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_7_OFFSET = 12'h 5c;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_8_OFFSET = 12'h 60;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_9_OFFSET = 12'h 64;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_10_OFFSET = 12'h 68;
+  parameter logic [BlockAw-1:0] USBDEV_CONFIGIN_11_OFFSET = 12'h 6c;
+  parameter logic [BlockAw-1:0] USBDEV_OUT_ISO_OFFSET = 12'h 70;
+  parameter logic [BlockAw-1:0] USBDEV_IN_ISO_OFFSET = 12'h 74;
+  parameter logic [BlockAw-1:0] USBDEV_DATA_TOGGLE_CLEAR_OFFSET = 12'h 78;
+  parameter logic [BlockAw-1:0] USBDEV_PHY_PINS_SENSE_OFFSET = 12'h 7c;
+  parameter logic [BlockAw-1:0] USBDEV_PHY_PINS_DRIVE_OFFSET = 12'h 80;
+  parameter logic [BlockAw-1:0] USBDEV_PHY_CONFIG_OFFSET = 12'h 84;
+  parameter logic [BlockAw-1:0] USBDEV_WAKE_CONFIG_OFFSET = 12'h 88;
+  parameter logic [BlockAw-1:0] USBDEV_WAKE_EVENTS_OFFSET = 12'h 8c;
 
   // Reset values for hwext registers and their fields
   parameter logic [16:0] USBDEV_INTR_TEST_RESVAL = 17'h 0;
@@ -667,6 +679,7 @@
     USBDEV_RXFIFO,
     USBDEV_RXENABLE_SETUP,
     USBDEV_RXENABLE_OUT,
+    USBDEV_SET_NAK_OUT,
     USBDEV_IN_SENT,
     USBDEV_OUT_STALL,
     USBDEV_IN_STALL,
@@ -693,7 +706,7 @@
   } usbdev_id_e;
 
   // Register width information to check illegal writes
-  parameter logic [3:0] USBDEV_PERMIT [35] = '{
+  parameter logic [3:0] USBDEV_PERMIT [36] = '{
     4'b 0111, // index[ 0] USBDEV_INTR_STATE
     4'b 0111, // index[ 1] USBDEV_INTR_ENABLE
     4'b 0111, // index[ 2] USBDEV_INTR_TEST
@@ -706,29 +719,30 @@
     4'b 0111, // index[ 9] USBDEV_RXFIFO
     4'b 0011, // index[10] USBDEV_RXENABLE_SETUP
     4'b 0011, // index[11] USBDEV_RXENABLE_OUT
-    4'b 0011, // index[12] USBDEV_IN_SENT
-    4'b 0011, // index[13] USBDEV_OUT_STALL
-    4'b 0011, // index[14] USBDEV_IN_STALL
-    4'b 1111, // index[15] USBDEV_CONFIGIN_0
-    4'b 1111, // index[16] USBDEV_CONFIGIN_1
-    4'b 1111, // index[17] USBDEV_CONFIGIN_2
-    4'b 1111, // index[18] USBDEV_CONFIGIN_3
-    4'b 1111, // index[19] USBDEV_CONFIGIN_4
-    4'b 1111, // index[20] USBDEV_CONFIGIN_5
-    4'b 1111, // index[21] USBDEV_CONFIGIN_6
-    4'b 1111, // index[22] USBDEV_CONFIGIN_7
-    4'b 1111, // index[23] USBDEV_CONFIGIN_8
-    4'b 1111, // index[24] USBDEV_CONFIGIN_9
-    4'b 1111, // index[25] USBDEV_CONFIGIN_10
-    4'b 1111, // index[26] USBDEV_CONFIGIN_11
-    4'b 0011, // index[27] USBDEV_OUT_ISO
-    4'b 0011, // index[28] USBDEV_IN_ISO
-    4'b 0011, // index[29] USBDEV_DATA_TOGGLE_CLEAR
-    4'b 0111, // index[30] USBDEV_PHY_PINS_SENSE
-    4'b 0111, // index[31] USBDEV_PHY_PINS_DRIVE
-    4'b 0001, // index[32] USBDEV_PHY_CONFIG
-    4'b 0001, // index[33] USBDEV_WAKE_CONFIG
-    4'b 0011  // index[34] USBDEV_WAKE_EVENTS
+    4'b 0011, // index[12] USBDEV_SET_NAK_OUT
+    4'b 0011, // index[13] USBDEV_IN_SENT
+    4'b 0011, // index[14] USBDEV_OUT_STALL
+    4'b 0011, // index[15] USBDEV_IN_STALL
+    4'b 1111, // index[16] USBDEV_CONFIGIN_0
+    4'b 1111, // index[17] USBDEV_CONFIGIN_1
+    4'b 1111, // index[18] USBDEV_CONFIGIN_2
+    4'b 1111, // index[19] USBDEV_CONFIGIN_3
+    4'b 1111, // index[20] USBDEV_CONFIGIN_4
+    4'b 1111, // index[21] USBDEV_CONFIGIN_5
+    4'b 1111, // index[22] USBDEV_CONFIGIN_6
+    4'b 1111, // index[23] USBDEV_CONFIGIN_7
+    4'b 1111, // index[24] USBDEV_CONFIGIN_8
+    4'b 1111, // index[25] USBDEV_CONFIGIN_9
+    4'b 1111, // index[26] USBDEV_CONFIGIN_10
+    4'b 1111, // index[27] USBDEV_CONFIGIN_11
+    4'b 0011, // index[28] USBDEV_OUT_ISO
+    4'b 0011, // index[29] USBDEV_IN_ISO
+    4'b 0011, // index[30] USBDEV_DATA_TOGGLE_CLEAR
+    4'b 0111, // index[31] USBDEV_PHY_PINS_SENSE
+    4'b 0111, // index[32] USBDEV_PHY_PINS_DRIVE
+    4'b 0001, // index[33] USBDEV_PHY_CONFIG
+    4'b 0001, // index[34] USBDEV_WAKE_CONFIG
+    4'b 0011  // index[35] USBDEV_WAKE_EVENTS
   };
 
 endpackage
diff --git a/hw/ip/usbdev/rtl/usbdev_reg_top.sv b/hw/ip/usbdev/rtl/usbdev_reg_top.sv
index 082f810..3b0154a 100644
--- a/hw/ip/usbdev/rtl/usbdev_reg_top.sv
+++ b/hw/ip/usbdev/rtl/usbdev_reg_top.sv
@@ -375,30 +375,33 @@
   logic rxenable_setup_setup_11_qs;
   logic rxenable_setup_setup_11_wd;
   logic rxenable_out_we;
-  logic rxenable_out_out_0_qs;
-  logic rxenable_out_out_0_wd;
-  logic rxenable_out_out_1_qs;
-  logic rxenable_out_out_1_wd;
-  logic rxenable_out_out_2_qs;
-  logic rxenable_out_out_2_wd;
-  logic rxenable_out_out_3_qs;
-  logic rxenable_out_out_3_wd;
-  logic rxenable_out_out_4_qs;
-  logic rxenable_out_out_4_wd;
-  logic rxenable_out_out_5_qs;
-  logic rxenable_out_out_5_wd;
-  logic rxenable_out_out_6_qs;
-  logic rxenable_out_out_6_wd;
-  logic rxenable_out_out_7_qs;
-  logic rxenable_out_out_7_wd;
-  logic rxenable_out_out_8_qs;
-  logic rxenable_out_out_8_wd;
-  logic rxenable_out_out_9_qs;
-  logic rxenable_out_out_9_wd;
-  logic rxenable_out_out_10_qs;
-  logic rxenable_out_out_10_wd;
-  logic rxenable_out_out_11_qs;
-  logic rxenable_out_out_11_wd;
+  logic [11:0] rxenable_out_qs;
+  logic rxenable_out_busy;
+  logic set_nak_out_we;
+  logic set_nak_out_enable_0_qs;
+  logic set_nak_out_enable_0_wd;
+  logic set_nak_out_enable_1_qs;
+  logic set_nak_out_enable_1_wd;
+  logic set_nak_out_enable_2_qs;
+  logic set_nak_out_enable_2_wd;
+  logic set_nak_out_enable_3_qs;
+  logic set_nak_out_enable_3_wd;
+  logic set_nak_out_enable_4_qs;
+  logic set_nak_out_enable_4_wd;
+  logic set_nak_out_enable_5_qs;
+  logic set_nak_out_enable_5_wd;
+  logic set_nak_out_enable_6_qs;
+  logic set_nak_out_enable_6_wd;
+  logic set_nak_out_enable_7_qs;
+  logic set_nak_out_enable_7_wd;
+  logic set_nak_out_enable_8_qs;
+  logic set_nak_out_enable_8_wd;
+  logic set_nak_out_enable_9_qs;
+  logic set_nak_out_enable_9_wd;
+  logic set_nak_out_enable_10_qs;
+  logic set_nak_out_enable_10_wd;
+  logic set_nak_out_enable_11_qs;
+  logic set_nak_out_enable_11_wd;
   logic in_sent_we;
   logic in_sent_sent_0_qs;
   logic in_sent_sent_0_wd;
@@ -736,6 +739,64 @@
   assign unused_usb_48mhz_usbctrl_wdata =
       ^usb_48mhz_usbctrl_wdata;
 
+  logic  usb_48mhz_rxenable_out_out_0_qs_int;
+  logic  usb_48mhz_rxenable_out_out_1_qs_int;
+  logic  usb_48mhz_rxenable_out_out_2_qs_int;
+  logic  usb_48mhz_rxenable_out_out_3_qs_int;
+  logic  usb_48mhz_rxenable_out_out_4_qs_int;
+  logic  usb_48mhz_rxenable_out_out_5_qs_int;
+  logic  usb_48mhz_rxenable_out_out_6_qs_int;
+  logic  usb_48mhz_rxenable_out_out_7_qs_int;
+  logic  usb_48mhz_rxenable_out_out_8_qs_int;
+  logic  usb_48mhz_rxenable_out_out_9_qs_int;
+  logic  usb_48mhz_rxenable_out_out_10_qs_int;
+  logic  usb_48mhz_rxenable_out_out_11_qs_int;
+  logic [11:0] usb_48mhz_rxenable_out_d;
+  logic [11:0] usb_48mhz_rxenable_out_wdata;
+  logic usb_48mhz_rxenable_out_we;
+  logic unused_usb_48mhz_rxenable_out_wdata;
+
+  always_comb begin
+    usb_48mhz_rxenable_out_d = '0;
+    usb_48mhz_rxenable_out_d[0] = usb_48mhz_rxenable_out_out_0_qs_int;
+    usb_48mhz_rxenable_out_d[1] = usb_48mhz_rxenable_out_out_1_qs_int;
+    usb_48mhz_rxenable_out_d[2] = usb_48mhz_rxenable_out_out_2_qs_int;
+    usb_48mhz_rxenable_out_d[3] = usb_48mhz_rxenable_out_out_3_qs_int;
+    usb_48mhz_rxenable_out_d[4] = usb_48mhz_rxenable_out_out_4_qs_int;
+    usb_48mhz_rxenable_out_d[5] = usb_48mhz_rxenable_out_out_5_qs_int;
+    usb_48mhz_rxenable_out_d[6] = usb_48mhz_rxenable_out_out_6_qs_int;
+    usb_48mhz_rxenable_out_d[7] = usb_48mhz_rxenable_out_out_7_qs_int;
+    usb_48mhz_rxenable_out_d[8] = usb_48mhz_rxenable_out_out_8_qs_int;
+    usb_48mhz_rxenable_out_d[9] = usb_48mhz_rxenable_out_out_9_qs_int;
+    usb_48mhz_rxenable_out_d[10] = usb_48mhz_rxenable_out_out_10_qs_int;
+    usb_48mhz_rxenable_out_d[11] = usb_48mhz_rxenable_out_out_11_qs_int;
+  end
+
+  prim_reg_cdc #(
+    .DataWidth(12),
+    .ResetVal(12'h0),
+    .BitMask(12'hfff)
+  ) u_rxenable_out_cdc (
+    .clk_src_i    (clk_i),
+    .rst_src_ni   (rst_ni),
+    .clk_dst_i    (clk_usb_48mhz_i),
+    .rst_dst_ni   (rst_usb_48mhz_ni),
+    .src_update_i (sync_usb_48mhz_update),
+    .src_regwen_i ('0),
+    .src_we_i     (rxenable_out_we),
+    .src_re_i     ('0),
+    .src_wd_i     (reg_wdata[11:0]),
+    .src_busy_o   (rxenable_out_busy),
+    .src_qs_o     (rxenable_out_qs), // for software read back
+    .dst_d_i      (usb_48mhz_rxenable_out_d),
+    .dst_we_o     (usb_48mhz_rxenable_out_we),
+    .dst_re_o     (),
+    .dst_regwen_o (),
+    .dst_wd_o     (usb_48mhz_rxenable_out_wdata)
+  );
+  assign unused_usb_48mhz_rxenable_out_wdata =
+      ^usb_48mhz_rxenable_out_wdata;
+
   logic  aon_wake_config_wake_en_qs_int;
   logic [1:0] aon_wake_config_d;
   logic [1:0] aon_wake_config_wdata;
@@ -3109,23 +3170,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_0 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_0_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[0]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[0].de),
+    .d      (hw2reg.rxenable_out[0].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[0].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_0_qs)
+    .qs     (usb_48mhz_rxenable_out_out_0_qs_int)
   );
 
   //   F[out_1]: 1:1
@@ -3134,23 +3195,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_1 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_1_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[1]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[1].de),
+    .d      (hw2reg.rxenable_out[1].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[1].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_1_qs)
+    .qs     (usb_48mhz_rxenable_out_out_1_qs_int)
   );
 
   //   F[out_2]: 2:2
@@ -3159,23 +3220,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_2 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_2_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[2]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[2].de),
+    .d      (hw2reg.rxenable_out[2].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[2].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_2_qs)
+    .qs     (usb_48mhz_rxenable_out_out_2_qs_int)
   );
 
   //   F[out_3]: 3:3
@@ -3184,23 +3245,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_3 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_3_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[3]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[3].de),
+    .d      (hw2reg.rxenable_out[3].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[3].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_3_qs)
+    .qs     (usb_48mhz_rxenable_out_out_3_qs_int)
   );
 
   //   F[out_4]: 4:4
@@ -3209,23 +3270,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_4 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_4_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[4]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[4].de),
+    .d      (hw2reg.rxenable_out[4].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[4].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_4_qs)
+    .qs     (usb_48mhz_rxenable_out_out_4_qs_int)
   );
 
   //   F[out_5]: 5:5
@@ -3234,23 +3295,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_5 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_5_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[5]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[5].de),
+    .d      (hw2reg.rxenable_out[5].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[5].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_5_qs)
+    .qs     (usb_48mhz_rxenable_out_out_5_qs_int)
   );
 
   //   F[out_6]: 6:6
@@ -3259,23 +3320,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_6 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_6_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[6]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[6].de),
+    .d      (hw2reg.rxenable_out[6].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[6].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_6_qs)
+    .qs     (usb_48mhz_rxenable_out_out_6_qs_int)
   );
 
   //   F[out_7]: 7:7
@@ -3284,23 +3345,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_7 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_7_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[7]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[7].de),
+    .d      (hw2reg.rxenable_out[7].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[7].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_7_qs)
+    .qs     (usb_48mhz_rxenable_out_out_7_qs_int)
   );
 
   //   F[out_8]: 8:8
@@ -3309,23 +3370,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_8 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_8_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[8]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[8].de),
+    .d      (hw2reg.rxenable_out[8].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[8].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_8_qs)
+    .qs     (usb_48mhz_rxenable_out_out_8_qs_int)
   );
 
   //   F[out_9]: 9:9
@@ -3334,23 +3395,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_9 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_9_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[9]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[9].de),
+    .d      (hw2reg.rxenable_out[9].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[9].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_9_qs)
+    .qs     (usb_48mhz_rxenable_out_out_9_qs_int)
   );
 
   //   F[out_10]: 10:10
@@ -3359,23 +3420,23 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_10 (
-    .clk_i   (clk_i),
-    .rst_ni  (rst_ni),
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_10_wd),
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[10]),
 
     // from internal hardware
-    .de     (1'b0),
-    .d      ('0),
+    .de     (hw2reg.rxenable_out[10].de),
+    .d      (hw2reg.rxenable_out[10].d),
 
     // to internal hardware
     .qe     (),
     .q      (reg2hw.rxenable_out[10].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_10_qs)
+    .qs     (usb_48mhz_rxenable_out_out_10_qs_int)
   );
 
   //   F[out_11]: 11:11
@@ -3384,12 +3445,40 @@
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
   ) u_rxenable_out_out_11 (
+    .clk_i   (clk_usb_48mhz_i),
+    .rst_ni  (rst_usb_48mhz_ni),
+
+    // from register interface
+    .we     (usb_48mhz_rxenable_out_we),
+    .wd     (usb_48mhz_rxenable_out_wdata[11]),
+
+    // from internal hardware
+    .de     (hw2reg.rxenable_out[11].de),
+    .d      (hw2reg.rxenable_out[11].d),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.rxenable_out[11].q),
+
+    // to register interface (read)
+    .qs     (usb_48mhz_rxenable_out_out_11_qs_int)
+  );
+
+
+  // Subregister 0 of Multireg set_nak_out
+  // R[set_nak_out]: V(False)
+  //   F[enable_0]: 0:0
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_0 (
     .clk_i   (clk_i),
     .rst_ni  (rst_ni),
 
     // from register interface
-    .we     (rxenable_out_we),
-    .wd     (rxenable_out_out_11_wd),
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_0_wd),
 
     // from internal hardware
     .de     (1'b0),
@@ -3397,10 +3486,285 @@
 
     // to internal hardware
     .qe     (),
-    .q      (reg2hw.rxenable_out[11].q),
+    .q      (reg2hw.set_nak_out[0].q),
 
     // to register interface (read)
-    .qs     (rxenable_out_out_11_qs)
+    .qs     (set_nak_out_enable_0_qs)
+  );
+
+  //   F[enable_1]: 1:1
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_1 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_1_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[1].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_1_qs)
+  );
+
+  //   F[enable_2]: 2:2
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_2 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_2_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[2].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_2_qs)
+  );
+
+  //   F[enable_3]: 3:3
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_3 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_3_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[3].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_3_qs)
+  );
+
+  //   F[enable_4]: 4:4
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_4 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_4_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[4].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_4_qs)
+  );
+
+  //   F[enable_5]: 5:5
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_5 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_5_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[5].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_5_qs)
+  );
+
+  //   F[enable_6]: 6:6
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_6 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_6_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[6].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_6_qs)
+  );
+
+  //   F[enable_7]: 7:7
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_7 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_7_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[7].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_7_qs)
+  );
+
+  //   F[enable_8]: 8:8
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_8 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_8_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[8].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_8_qs)
+  );
+
+  //   F[enable_9]: 9:9
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_9 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_9_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[9].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_9_qs)
+  );
+
+  //   F[enable_10]: 10:10
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_10 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_10_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[10].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_10_qs)
+  );
+
+  //   F[enable_11]: 11:11
+  prim_subreg #(
+    .DW      (1),
+    .SwAccess(prim_subreg_pkg::SwAccessRW),
+    .RESVAL  (1'h0)
+  ) u_set_nak_out_enable_11 (
+    .clk_i   (clk_i),
+    .rst_ni  (rst_ni),
+
+    // from register interface
+    .we     (set_nak_out_we),
+    .wd     (set_nak_out_enable_11_wd),
+
+    // from internal hardware
+    .de     (1'b0),
+    .d      ('0),
+
+    // to internal hardware
+    .qe     (),
+    .q      (reg2hw.set_nak_out[11].q),
+
+    // to register interface (read)
+    .qs     (set_nak_out_enable_11_qs)
   );
 
 
@@ -7134,7 +7498,7 @@
 
 
 
-  logic [34:0] addr_hit;
+  logic [35:0] addr_hit;
   always_comb begin
     addr_hit = '0;
     addr_hit[ 0] = (reg_addr == USBDEV_INTR_STATE_OFFSET);
@@ -7149,29 +7513,30 @@
     addr_hit[ 9] = (reg_addr == USBDEV_RXFIFO_OFFSET);
     addr_hit[10] = (reg_addr == USBDEV_RXENABLE_SETUP_OFFSET);
     addr_hit[11] = (reg_addr == USBDEV_RXENABLE_OUT_OFFSET);
-    addr_hit[12] = (reg_addr == USBDEV_IN_SENT_OFFSET);
-    addr_hit[13] = (reg_addr == USBDEV_OUT_STALL_OFFSET);
-    addr_hit[14] = (reg_addr == USBDEV_IN_STALL_OFFSET);
-    addr_hit[15] = (reg_addr == USBDEV_CONFIGIN_0_OFFSET);
-    addr_hit[16] = (reg_addr == USBDEV_CONFIGIN_1_OFFSET);
-    addr_hit[17] = (reg_addr == USBDEV_CONFIGIN_2_OFFSET);
-    addr_hit[18] = (reg_addr == USBDEV_CONFIGIN_3_OFFSET);
-    addr_hit[19] = (reg_addr == USBDEV_CONFIGIN_4_OFFSET);
-    addr_hit[20] = (reg_addr == USBDEV_CONFIGIN_5_OFFSET);
-    addr_hit[21] = (reg_addr == USBDEV_CONFIGIN_6_OFFSET);
-    addr_hit[22] = (reg_addr == USBDEV_CONFIGIN_7_OFFSET);
-    addr_hit[23] = (reg_addr == USBDEV_CONFIGIN_8_OFFSET);
-    addr_hit[24] = (reg_addr == USBDEV_CONFIGIN_9_OFFSET);
-    addr_hit[25] = (reg_addr == USBDEV_CONFIGIN_10_OFFSET);
-    addr_hit[26] = (reg_addr == USBDEV_CONFIGIN_11_OFFSET);
-    addr_hit[27] = (reg_addr == USBDEV_OUT_ISO_OFFSET);
-    addr_hit[28] = (reg_addr == USBDEV_IN_ISO_OFFSET);
-    addr_hit[29] = (reg_addr == USBDEV_DATA_TOGGLE_CLEAR_OFFSET);
-    addr_hit[30] = (reg_addr == USBDEV_PHY_PINS_SENSE_OFFSET);
-    addr_hit[31] = (reg_addr == USBDEV_PHY_PINS_DRIVE_OFFSET);
-    addr_hit[32] = (reg_addr == USBDEV_PHY_CONFIG_OFFSET);
-    addr_hit[33] = (reg_addr == USBDEV_WAKE_CONFIG_OFFSET);
-    addr_hit[34] = (reg_addr == USBDEV_WAKE_EVENTS_OFFSET);
+    addr_hit[12] = (reg_addr == USBDEV_SET_NAK_OUT_OFFSET);
+    addr_hit[13] = (reg_addr == USBDEV_IN_SENT_OFFSET);
+    addr_hit[14] = (reg_addr == USBDEV_OUT_STALL_OFFSET);
+    addr_hit[15] = (reg_addr == USBDEV_IN_STALL_OFFSET);
+    addr_hit[16] = (reg_addr == USBDEV_CONFIGIN_0_OFFSET);
+    addr_hit[17] = (reg_addr == USBDEV_CONFIGIN_1_OFFSET);
+    addr_hit[18] = (reg_addr == USBDEV_CONFIGIN_2_OFFSET);
+    addr_hit[19] = (reg_addr == USBDEV_CONFIGIN_3_OFFSET);
+    addr_hit[20] = (reg_addr == USBDEV_CONFIGIN_4_OFFSET);
+    addr_hit[21] = (reg_addr == USBDEV_CONFIGIN_5_OFFSET);
+    addr_hit[22] = (reg_addr == USBDEV_CONFIGIN_6_OFFSET);
+    addr_hit[23] = (reg_addr == USBDEV_CONFIGIN_7_OFFSET);
+    addr_hit[24] = (reg_addr == USBDEV_CONFIGIN_8_OFFSET);
+    addr_hit[25] = (reg_addr == USBDEV_CONFIGIN_9_OFFSET);
+    addr_hit[26] = (reg_addr == USBDEV_CONFIGIN_10_OFFSET);
+    addr_hit[27] = (reg_addr == USBDEV_CONFIGIN_11_OFFSET);
+    addr_hit[28] = (reg_addr == USBDEV_OUT_ISO_OFFSET);
+    addr_hit[29] = (reg_addr == USBDEV_IN_ISO_OFFSET);
+    addr_hit[30] = (reg_addr == USBDEV_DATA_TOGGLE_CLEAR_OFFSET);
+    addr_hit[31] = (reg_addr == USBDEV_PHY_PINS_SENSE_OFFSET);
+    addr_hit[32] = (reg_addr == USBDEV_PHY_PINS_DRIVE_OFFSET);
+    addr_hit[33] = (reg_addr == USBDEV_PHY_CONFIG_OFFSET);
+    addr_hit[34] = (reg_addr == USBDEV_WAKE_CONFIG_OFFSET);
+    addr_hit[35] = (reg_addr == USBDEV_WAKE_EVENTS_OFFSET);
   end
 
   assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ;
@@ -7213,7 +7578,8 @@
                (addr_hit[31] & (|(USBDEV_PERMIT[31] & ~reg_be))) |
                (addr_hit[32] & (|(USBDEV_PERMIT[32] & ~reg_be))) |
                (addr_hit[33] & (|(USBDEV_PERMIT[33] & ~reg_be))) |
-               (addr_hit[34] & (|(USBDEV_PERMIT[34] & ~reg_be)))));
+               (addr_hit[34] & (|(USBDEV_PERMIT[34] & ~reg_be))) |
+               (addr_hit[35] & (|(USBDEV_PERMIT[35] & ~reg_be)))));
   end
   assign intr_state_we = addr_hit[0] & reg_we & !reg_error;
 
@@ -7409,30 +7775,43 @@
   assign rxenable_setup_setup_11_wd = reg_wdata[11];
   assign rxenable_out_we = addr_hit[11] & reg_we & !reg_error;
 
-  assign rxenable_out_out_0_wd = reg_wdata[0];
 
-  assign rxenable_out_out_1_wd = reg_wdata[1];
 
-  assign rxenable_out_out_2_wd = reg_wdata[2];
 
-  assign rxenable_out_out_3_wd = reg_wdata[3];
 
-  assign rxenable_out_out_4_wd = reg_wdata[4];
 
-  assign rxenable_out_out_5_wd = reg_wdata[5];
 
-  assign rxenable_out_out_6_wd = reg_wdata[6];
 
-  assign rxenable_out_out_7_wd = reg_wdata[7];
 
-  assign rxenable_out_out_8_wd = reg_wdata[8];
 
-  assign rxenable_out_out_9_wd = reg_wdata[9];
 
-  assign rxenable_out_out_10_wd = reg_wdata[10];
 
-  assign rxenable_out_out_11_wd = reg_wdata[11];
-  assign in_sent_we = addr_hit[12] & reg_we & !reg_error;
+  assign set_nak_out_we = addr_hit[12] & reg_we & !reg_error;
+
+  assign set_nak_out_enable_0_wd = reg_wdata[0];
+
+  assign set_nak_out_enable_1_wd = reg_wdata[1];
+
+  assign set_nak_out_enable_2_wd = reg_wdata[2];
+
+  assign set_nak_out_enable_3_wd = reg_wdata[3];
+
+  assign set_nak_out_enable_4_wd = reg_wdata[4];
+
+  assign set_nak_out_enable_5_wd = reg_wdata[5];
+
+  assign set_nak_out_enable_6_wd = reg_wdata[6];
+
+  assign set_nak_out_enable_7_wd = reg_wdata[7];
+
+  assign set_nak_out_enable_8_wd = reg_wdata[8];
+
+  assign set_nak_out_enable_9_wd = reg_wdata[9];
+
+  assign set_nak_out_enable_10_wd = reg_wdata[10];
+
+  assign set_nak_out_enable_11_wd = reg_wdata[11];
+  assign in_sent_we = addr_hit[13] & reg_we & !reg_error;
 
   assign in_sent_sent_0_wd = reg_wdata[0];
 
@@ -7457,7 +7836,7 @@
   assign in_sent_sent_10_wd = reg_wdata[10];
 
   assign in_sent_sent_11_wd = reg_wdata[11];
-  assign out_stall_we = addr_hit[13] & reg_we & !reg_error;
+  assign out_stall_we = addr_hit[14] & reg_we & !reg_error;
 
   assign out_stall_endpoint_0_wd = reg_wdata[0];
 
@@ -7482,7 +7861,7 @@
   assign out_stall_endpoint_10_wd = reg_wdata[10];
 
   assign out_stall_endpoint_11_wd = reg_wdata[11];
-  assign in_stall_we = addr_hit[14] & reg_we & !reg_error;
+  assign in_stall_we = addr_hit[15] & reg_we & !reg_error;
 
   assign in_stall_endpoint_0_wd = reg_wdata[0];
 
@@ -7507,7 +7886,7 @@
   assign in_stall_endpoint_10_wd = reg_wdata[10];
 
   assign in_stall_endpoint_11_wd = reg_wdata[11];
-  assign configin_0_we = addr_hit[15] & reg_we & !reg_error;
+  assign configin_0_we = addr_hit[16] & reg_we & !reg_error;
 
   assign configin_0_buffer_0_wd = reg_wdata[4:0];
 
@@ -7516,7 +7895,7 @@
   assign configin_0_pend_0_wd = reg_wdata[30];
 
   assign configin_0_rdy_0_wd = reg_wdata[31];
-  assign configin_1_we = addr_hit[16] & reg_we & !reg_error;
+  assign configin_1_we = addr_hit[17] & reg_we & !reg_error;
 
   assign configin_1_buffer_1_wd = reg_wdata[4:0];
 
@@ -7525,7 +7904,7 @@
   assign configin_1_pend_1_wd = reg_wdata[30];
 
   assign configin_1_rdy_1_wd = reg_wdata[31];
-  assign configin_2_we = addr_hit[17] & reg_we & !reg_error;
+  assign configin_2_we = addr_hit[18] & reg_we & !reg_error;
 
   assign configin_2_buffer_2_wd = reg_wdata[4:0];
 
@@ -7534,7 +7913,7 @@
   assign configin_2_pend_2_wd = reg_wdata[30];
 
   assign configin_2_rdy_2_wd = reg_wdata[31];
-  assign configin_3_we = addr_hit[18] & reg_we & !reg_error;
+  assign configin_3_we = addr_hit[19] & reg_we & !reg_error;
 
   assign configin_3_buffer_3_wd = reg_wdata[4:0];
 
@@ -7543,7 +7922,7 @@
   assign configin_3_pend_3_wd = reg_wdata[30];
 
   assign configin_3_rdy_3_wd = reg_wdata[31];
-  assign configin_4_we = addr_hit[19] & reg_we & !reg_error;
+  assign configin_4_we = addr_hit[20] & reg_we & !reg_error;
 
   assign configin_4_buffer_4_wd = reg_wdata[4:0];
 
@@ -7552,7 +7931,7 @@
   assign configin_4_pend_4_wd = reg_wdata[30];
 
   assign configin_4_rdy_4_wd = reg_wdata[31];
-  assign configin_5_we = addr_hit[20] & reg_we & !reg_error;
+  assign configin_5_we = addr_hit[21] & reg_we & !reg_error;
 
   assign configin_5_buffer_5_wd = reg_wdata[4:0];
 
@@ -7561,7 +7940,7 @@
   assign configin_5_pend_5_wd = reg_wdata[30];
 
   assign configin_5_rdy_5_wd = reg_wdata[31];
-  assign configin_6_we = addr_hit[21] & reg_we & !reg_error;
+  assign configin_6_we = addr_hit[22] & reg_we & !reg_error;
 
   assign configin_6_buffer_6_wd = reg_wdata[4:0];
 
@@ -7570,7 +7949,7 @@
   assign configin_6_pend_6_wd = reg_wdata[30];
 
   assign configin_6_rdy_6_wd = reg_wdata[31];
-  assign configin_7_we = addr_hit[22] & reg_we & !reg_error;
+  assign configin_7_we = addr_hit[23] & reg_we & !reg_error;
 
   assign configin_7_buffer_7_wd = reg_wdata[4:0];
 
@@ -7579,7 +7958,7 @@
   assign configin_7_pend_7_wd = reg_wdata[30];
 
   assign configin_7_rdy_7_wd = reg_wdata[31];
-  assign configin_8_we = addr_hit[23] & reg_we & !reg_error;
+  assign configin_8_we = addr_hit[24] & reg_we & !reg_error;
 
   assign configin_8_buffer_8_wd = reg_wdata[4:0];
 
@@ -7588,7 +7967,7 @@
   assign configin_8_pend_8_wd = reg_wdata[30];
 
   assign configin_8_rdy_8_wd = reg_wdata[31];
-  assign configin_9_we = addr_hit[24] & reg_we & !reg_error;
+  assign configin_9_we = addr_hit[25] & reg_we & !reg_error;
 
   assign configin_9_buffer_9_wd = reg_wdata[4:0];
 
@@ -7597,7 +7976,7 @@
   assign configin_9_pend_9_wd = reg_wdata[30];
 
   assign configin_9_rdy_9_wd = reg_wdata[31];
-  assign configin_10_we = addr_hit[25] & reg_we & !reg_error;
+  assign configin_10_we = addr_hit[26] & reg_we & !reg_error;
 
   assign configin_10_buffer_10_wd = reg_wdata[4:0];
 
@@ -7606,7 +7985,7 @@
   assign configin_10_pend_10_wd = reg_wdata[30];
 
   assign configin_10_rdy_10_wd = reg_wdata[31];
-  assign configin_11_we = addr_hit[26] & reg_we & !reg_error;
+  assign configin_11_we = addr_hit[27] & reg_we & !reg_error;
 
   assign configin_11_buffer_11_wd = reg_wdata[4:0];
 
@@ -7615,7 +7994,7 @@
   assign configin_11_pend_11_wd = reg_wdata[30];
 
   assign configin_11_rdy_11_wd = reg_wdata[31];
-  assign out_iso_we = addr_hit[27] & reg_we & !reg_error;
+  assign out_iso_we = addr_hit[28] & reg_we & !reg_error;
 
   assign out_iso_iso_0_wd = reg_wdata[0];
 
@@ -7640,7 +8019,7 @@
   assign out_iso_iso_10_wd = reg_wdata[10];
 
   assign out_iso_iso_11_wd = reg_wdata[11];
-  assign in_iso_we = addr_hit[28] & reg_we & !reg_error;
+  assign in_iso_we = addr_hit[29] & reg_we & !reg_error;
 
   assign in_iso_iso_0_wd = reg_wdata[0];
 
@@ -7665,7 +8044,7 @@
   assign in_iso_iso_10_wd = reg_wdata[10];
 
   assign in_iso_iso_11_wd = reg_wdata[11];
-  assign data_toggle_clear_we = addr_hit[29] & reg_we & !reg_error;
+  assign data_toggle_clear_we = addr_hit[30] & reg_we & !reg_error;
 
   assign data_toggle_clear_clear_0_wd = reg_wdata[0];
 
@@ -7690,8 +8069,8 @@
   assign data_toggle_clear_clear_10_wd = reg_wdata[10];
 
   assign data_toggle_clear_clear_11_wd = reg_wdata[11];
-  assign phy_pins_sense_re = addr_hit[30] & reg_re & !reg_error;
-  assign phy_pins_drive_we = addr_hit[31] & reg_we & !reg_error;
+  assign phy_pins_sense_re = addr_hit[31] & reg_re & !reg_error;
+  assign phy_pins_drive_we = addr_hit[32] & reg_we & !reg_error;
 
   assign phy_pins_drive_dp_o_wd = reg_wdata[0];
 
@@ -7712,7 +8091,7 @@
   assign phy_pins_drive_suspend_o_wd = reg_wdata[8];
 
   assign phy_pins_drive_en_wd = reg_wdata[16];
-  assign phy_config_we = addr_hit[32] & reg_we & !reg_error;
+  assign phy_config_we = addr_hit[33] & reg_we & !reg_error;
 
   assign phy_config_use_diff_rcvr_wd = reg_wdata[0];
 
@@ -7725,7 +8104,7 @@
   assign phy_config_usb_ref_disable_wd = reg_wdata[6];
 
   assign phy_config_tx_osc_test_mode_wd = reg_wdata[7];
-  assign wake_config_we = addr_hit[33] & reg_we & !reg_error;
+  assign wake_config_we = addr_hit[34] & reg_we & !reg_error;
 
 
 
@@ -7868,21 +8247,24 @@
       end
 
       addr_hit[11]: begin
-        reg_rdata_next[0] = rxenable_out_out_0_qs;
-        reg_rdata_next[1] = rxenable_out_out_1_qs;
-        reg_rdata_next[2] = rxenable_out_out_2_qs;
-        reg_rdata_next[3] = rxenable_out_out_3_qs;
-        reg_rdata_next[4] = rxenable_out_out_4_qs;
-        reg_rdata_next[5] = rxenable_out_out_5_qs;
-        reg_rdata_next[6] = rxenable_out_out_6_qs;
-        reg_rdata_next[7] = rxenable_out_out_7_qs;
-        reg_rdata_next[8] = rxenable_out_out_8_qs;
-        reg_rdata_next[9] = rxenable_out_out_9_qs;
-        reg_rdata_next[10] = rxenable_out_out_10_qs;
-        reg_rdata_next[11] = rxenable_out_out_11_qs;
+        reg_rdata_next = DW'(rxenable_out_qs);
+      end
+      addr_hit[12]: begin
+        reg_rdata_next[0] = set_nak_out_enable_0_qs;
+        reg_rdata_next[1] = set_nak_out_enable_1_qs;
+        reg_rdata_next[2] = set_nak_out_enable_2_qs;
+        reg_rdata_next[3] = set_nak_out_enable_3_qs;
+        reg_rdata_next[4] = set_nak_out_enable_4_qs;
+        reg_rdata_next[5] = set_nak_out_enable_5_qs;
+        reg_rdata_next[6] = set_nak_out_enable_6_qs;
+        reg_rdata_next[7] = set_nak_out_enable_7_qs;
+        reg_rdata_next[8] = set_nak_out_enable_8_qs;
+        reg_rdata_next[9] = set_nak_out_enable_9_qs;
+        reg_rdata_next[10] = set_nak_out_enable_10_qs;
+        reg_rdata_next[11] = set_nak_out_enable_11_qs;
       end
 
-      addr_hit[12]: begin
+      addr_hit[13]: begin
         reg_rdata_next[0] = in_sent_sent_0_qs;
         reg_rdata_next[1] = in_sent_sent_1_qs;
         reg_rdata_next[2] = in_sent_sent_2_qs;
@@ -7897,7 +8279,7 @@
         reg_rdata_next[11] = in_sent_sent_11_qs;
       end
 
-      addr_hit[13]: begin
+      addr_hit[14]: begin
         reg_rdata_next[0] = out_stall_endpoint_0_qs;
         reg_rdata_next[1] = out_stall_endpoint_1_qs;
         reg_rdata_next[2] = out_stall_endpoint_2_qs;
@@ -7912,7 +8294,7 @@
         reg_rdata_next[11] = out_stall_endpoint_11_qs;
       end
 
-      addr_hit[14]: begin
+      addr_hit[15]: begin
         reg_rdata_next[0] = in_stall_endpoint_0_qs;
         reg_rdata_next[1] = in_stall_endpoint_1_qs;
         reg_rdata_next[2] = in_stall_endpoint_2_qs;
@@ -7927,91 +8309,91 @@
         reg_rdata_next[11] = in_stall_endpoint_11_qs;
       end
 
-      addr_hit[15]: begin
+      addr_hit[16]: begin
         reg_rdata_next[4:0] = configin_0_buffer_0_qs;
         reg_rdata_next[14:8] = configin_0_size_0_qs;
         reg_rdata_next[30] = configin_0_pend_0_qs;
         reg_rdata_next[31] = configin_0_rdy_0_qs;
       end
 
-      addr_hit[16]: begin
+      addr_hit[17]: begin
         reg_rdata_next[4:0] = configin_1_buffer_1_qs;
         reg_rdata_next[14:8] = configin_1_size_1_qs;
         reg_rdata_next[30] = configin_1_pend_1_qs;
         reg_rdata_next[31] = configin_1_rdy_1_qs;
       end
 
-      addr_hit[17]: begin
+      addr_hit[18]: begin
         reg_rdata_next[4:0] = configin_2_buffer_2_qs;
         reg_rdata_next[14:8] = configin_2_size_2_qs;
         reg_rdata_next[30] = configin_2_pend_2_qs;
         reg_rdata_next[31] = configin_2_rdy_2_qs;
       end
 
-      addr_hit[18]: begin
+      addr_hit[19]: begin
         reg_rdata_next[4:0] = configin_3_buffer_3_qs;
         reg_rdata_next[14:8] = configin_3_size_3_qs;
         reg_rdata_next[30] = configin_3_pend_3_qs;
         reg_rdata_next[31] = configin_3_rdy_3_qs;
       end
 
-      addr_hit[19]: begin
+      addr_hit[20]: begin
         reg_rdata_next[4:0] = configin_4_buffer_4_qs;
         reg_rdata_next[14:8] = configin_4_size_4_qs;
         reg_rdata_next[30] = configin_4_pend_4_qs;
         reg_rdata_next[31] = configin_4_rdy_4_qs;
       end
 
-      addr_hit[20]: begin
+      addr_hit[21]: begin
         reg_rdata_next[4:0] = configin_5_buffer_5_qs;
         reg_rdata_next[14:8] = configin_5_size_5_qs;
         reg_rdata_next[30] = configin_5_pend_5_qs;
         reg_rdata_next[31] = configin_5_rdy_5_qs;
       end
 
-      addr_hit[21]: begin
+      addr_hit[22]: begin
         reg_rdata_next[4:0] = configin_6_buffer_6_qs;
         reg_rdata_next[14:8] = configin_6_size_6_qs;
         reg_rdata_next[30] = configin_6_pend_6_qs;
         reg_rdata_next[31] = configin_6_rdy_6_qs;
       end
 
-      addr_hit[22]: begin
+      addr_hit[23]: begin
         reg_rdata_next[4:0] = configin_7_buffer_7_qs;
         reg_rdata_next[14:8] = configin_7_size_7_qs;
         reg_rdata_next[30] = configin_7_pend_7_qs;
         reg_rdata_next[31] = configin_7_rdy_7_qs;
       end
 
-      addr_hit[23]: begin
+      addr_hit[24]: begin
         reg_rdata_next[4:0] = configin_8_buffer_8_qs;
         reg_rdata_next[14:8] = configin_8_size_8_qs;
         reg_rdata_next[30] = configin_8_pend_8_qs;
         reg_rdata_next[31] = configin_8_rdy_8_qs;
       end
 
-      addr_hit[24]: begin
+      addr_hit[25]: begin
         reg_rdata_next[4:0] = configin_9_buffer_9_qs;
         reg_rdata_next[14:8] = configin_9_size_9_qs;
         reg_rdata_next[30] = configin_9_pend_9_qs;
         reg_rdata_next[31] = configin_9_rdy_9_qs;
       end
 
-      addr_hit[25]: begin
+      addr_hit[26]: begin
         reg_rdata_next[4:0] = configin_10_buffer_10_qs;
         reg_rdata_next[14:8] = configin_10_size_10_qs;
         reg_rdata_next[30] = configin_10_pend_10_qs;
         reg_rdata_next[31] = configin_10_rdy_10_qs;
       end
 
-      addr_hit[26]: begin
+      addr_hit[27]: begin
         reg_rdata_next[4:0] = configin_11_buffer_11_qs;
         reg_rdata_next[14:8] = configin_11_size_11_qs;
         reg_rdata_next[30] = configin_11_pend_11_qs;
         reg_rdata_next[31] = configin_11_rdy_11_qs;
       end
 
-      addr_hit[27]: begin
+      addr_hit[28]: begin
         reg_rdata_next[0] = out_iso_iso_0_qs;
         reg_rdata_next[1] = out_iso_iso_1_qs;
         reg_rdata_next[2] = out_iso_iso_2_qs;
@@ -8026,7 +8408,7 @@
         reg_rdata_next[11] = out_iso_iso_11_qs;
       end
 
-      addr_hit[28]: begin
+      addr_hit[29]: begin
         reg_rdata_next[0] = in_iso_iso_0_qs;
         reg_rdata_next[1] = in_iso_iso_1_qs;
         reg_rdata_next[2] = in_iso_iso_2_qs;
@@ -8041,7 +8423,7 @@
         reg_rdata_next[11] = in_iso_iso_11_qs;
       end
 
-      addr_hit[29]: begin
+      addr_hit[30]: begin
         reg_rdata_next[0] = '0;
         reg_rdata_next[1] = '0;
         reg_rdata_next[2] = '0;
@@ -8056,7 +8438,7 @@
         reg_rdata_next[11] = '0;
       end
 
-      addr_hit[30]: begin
+      addr_hit[31]: begin
         reg_rdata_next[0] = phy_pins_sense_rx_dp_i_qs;
         reg_rdata_next[1] = phy_pins_sense_rx_dn_i_qs;
         reg_rdata_next[2] = phy_pins_sense_rx_d_i_qs;
@@ -8069,7 +8451,7 @@
         reg_rdata_next[16] = phy_pins_sense_pwr_sense_qs;
       end
 
-      addr_hit[31]: begin
+      addr_hit[32]: begin
         reg_rdata_next[0] = phy_pins_drive_dp_o_qs;
         reg_rdata_next[1] = phy_pins_drive_dn_o_qs;
         reg_rdata_next[2] = phy_pins_drive_d_o_qs;
@@ -8082,7 +8464,7 @@
         reg_rdata_next[16] = phy_pins_drive_en_qs;
       end
 
-      addr_hit[32]: begin
+      addr_hit[33]: begin
         reg_rdata_next[0] = phy_config_use_diff_rcvr_qs;
         reg_rdata_next[1] = phy_config_tx_use_d_se0_qs;
         reg_rdata_next[2] = phy_config_eop_single_bit_qs;
@@ -8091,10 +8473,10 @@
         reg_rdata_next[7] = phy_config_tx_osc_test_mode_qs;
       end
 
-      addr_hit[33]: begin
+      addr_hit[34]: begin
         reg_rdata_next = DW'(wake_config_qs);
       end
-      addr_hit[34]: begin
+      addr_hit[35]: begin
         reg_rdata_next = DW'(wake_events_qs);
       end
       default: begin
@@ -8116,10 +8498,13 @@
       addr_hit[4]: begin
         reg_busy_sel = usbctrl_busy;
       end
-      addr_hit[33]: begin
-        reg_busy_sel = wake_config_busy;
+      addr_hit[11]: begin
+        reg_busy_sel = rxenable_out_busy;
       end
       addr_hit[34]: begin
+        reg_busy_sel = wake_config_busy;
+      end
+      addr_hit[35]: begin
         reg_busy_sel = wake_events_busy;
       end
       default: begin
diff --git a/sw/device/lib/dif/dif_usbdev.c b/sw/device/lib/dif/dif_usbdev.c
index 89db6d0..23a1146 100644
--- a/sw/device/lib/dif/dif_usbdev.c
+++ b/sw/device/lib/dif/dif_usbdev.c
@@ -337,6 +337,13 @@
                                        endpoint, new_state);
 }
 
+dif_result_t dif_usbdev_endpoint_set_nak_out_enable(const dif_usbdev_t *usbdev,
+                                                    uint8_t endpoint,
+                                                    dif_toggle_t new_state) {
+  return endpoint_functionality_enable(usbdev, USBDEV_SET_NAK_OUT_REG_OFFSET,
+                                       endpoint, new_state);
+}
+
 dif_result_t dif_usbdev_endpoint_stall_enable(const dif_usbdev_t *usbdev,
                                               dif_usbdev_endpoint_id_t endpoint,
                                               dif_toggle_t new_state) {
diff --git a/sw/device/lib/dif/dif_usbdev.h b/sw/device/lib/dif/dif_usbdev.h
index 4c7a57c..94c6e7a 100644
--- a/sw/device/lib/dif/dif_usbdev.h
+++ b/sw/device/lib/dif/dif_usbdev.h
@@ -212,6 +212,24 @@
                                             dif_toggle_t new_state);
 
 /**
+ * Enable or disable clearing the out_enable bit after completion of an OUT
+ * transaction to an endpoint.
+ *
+ * If set_nak_out is enabled, an OUT endpoint will disable reception of OUT
+ * packets after each successful OUT transaction to that endpoint, requiring a
+ * call to `dif_usbdev_endpoint_out_enable()` to enable reception again.
+ *
+ * @param usbdev A USB device.
+ * @param endpoint An OUT endpoint number.
+ * @param new_state New set_nak_on_out state.
+ * @return The result of the operation.
+ */
+OT_WARN_UNUSED_RESULT
+dif_result_t dif_usbdev_endpoint_set_nak_out_enable(const dif_usbdev_t *usbdev,
+                                                    uint8_t endpoint,
+                                                    dif_toggle_t new_state);
+
+/**
  * Enable or disable STALL for an endpoint.
  *
  * @param usbdev A USB device.
diff --git a/sw/device/lib/usb_controlep.c b/sw/device/lib/usb_controlep.c
index 7ba8fa8..466a6bd 100644
--- a/sw/device/lib/usb_controlep.c
+++ b/sw/device/lib/usb_controlep.c
@@ -187,6 +187,7 @@
 static void ctrl_rx(void *ctctx_v, usbbufid_t buf, int size, int setup) {
   usb_controlep_ctx_t *ctctx = (usb_controlep_ctx_t *)ctctx_v;
   void *ctx = ctctx->ctx;
+  usbdev_clear_out_nak(ctx, 0);
   volatile uint8_t *bp = (volatile uint8_t *)usbdev_buf_idtoaddr(ctx, buf);
   if (size > BUF_LENGTH) {
     size = BUF_LENGTH;
@@ -246,8 +247,8 @@
 void usb_controlep_init(usb_controlep_ctx_t *ctctx, usbdev_ctx_t *ctx, int ep,
                         const uint8_t *cfg_dscr, size_t cfg_dscr_len) {
   ctctx->ctx = ctx;
-  usbdev_endpoint_setup(ctx, ep, 1, ctctx, ctrl_tx_done, ctrl_rx, NULL,
-                        ctrl_reset);
+  usbdev_endpoint_setup(ctx, ep, kUsbdevOutMessage, ctctx, ctrl_tx_done,
+                        ctrl_rx, NULL, ctrl_reset);
   ctctx->ctrlstate = kCtIdle;
   ctctx->cfg_dscr = cfg_dscr;
   ctctx->cfg_dscr_len = cfg_dscr_len;
diff --git a/sw/device/lib/usb_simpleserial.c b/sw/device/lib/usb_simpleserial.c
index b7e874a..03ae9a2 100644
--- a/sw/device/lib/usb_simpleserial.c
+++ b/sw/device/lib/usb_simpleserial.c
@@ -68,7 +68,8 @@
 
 void usb_simpleserial_init(usb_ss_ctx_t *ssctx, usbdev_ctx_t *ctx, int ep,
                            void (*got_byte)(uint8_t)) {
-  usbdev_endpoint_setup(ctx, ep, 1, ssctx, NULL, ss_rx, ss_flush, NULL);
+  usbdev_endpoint_setup(ctx, ep, kUsbdevOutStream, ssctx, NULL, ss_rx, ss_flush,
+                        NULL);
   ssctx->ctx = ctx;
   ssctx->ep = ep;
   ssctx->got_byte = got_byte;
diff --git a/sw/device/lib/usbdev.c b/sw/device/lib/usbdev.c
index 63e1689..be5161b 100644
--- a/sw/device/lib/usbdev.c
+++ b/sw/device/lib/usbdev.c
@@ -267,11 +267,18 @@
   }
 }
 
+void usbdev_clear_out_nak(usbdev_ctx_t *ctx, int ep) {
+  uint32_t rxen = REG32(USBDEV_BASE_ADDR + USBDEV_RXENABLE_OUT_REG_OFFSET);
+  rxen |= (1 << (ep + USBDEV_RXENABLE_OUT_OUT_0_BIT));
+  REG32(USBDEV_BASE_ADDR + USBDEV_RXENABLE_OUT_REG_OFFSET) = rxen;
+}
+
 // TODO got hang with this inline
 int usbdev_can_rem_wake(usbdev_ctx_t *ctx) { return ctx->can_wake; }
 
-void usbdev_endpoint_setup(usbdev_ctx_t *ctx, int ep, int enableout,
-                           void *ep_ctx, void (*tx_done)(void *),
+void usbdev_endpoint_setup(usbdev_ctx_t *ctx, int ep,
+                           usbdev_out_transfer_mode_t out_mode, void *ep_ctx,
+                           void (*tx_done)(void *),
                            void (*rx)(void *, usbbufid_t, int, int),
                            void (*flush)(void *), void (*reset)(void *)) {
   ctx->ep_ctx[ep] = ep_ctx;
@@ -284,7 +291,7 @@
   tx_ep_en |= (1 << (ep + USBDEV_EP_IN_ENABLE_ENABLE_0_BIT));
   REG32(USBDEV_BASE_ADDR + USBDEV_EP_IN_ENABLE_REG_OFFSET) = tx_ep_en;
 
-  if (enableout) {
+  if (out_mode != kUsbdevOutDisabled) {
     uint32_t rxen = REG32(USBDEV_BASE_ADDR + USBDEV_RXENABLE_OUT_REG_OFFSET);
     rxen |= (1 << (ep + USBDEV_RXENABLE_OUT_OUT_0_BIT));
     REG32(USBDEV_BASE_ADDR + USBDEV_RXENABLE_OUT_REG_OFFSET) = rxen;
@@ -292,6 +299,12 @@
     ep_en |= (1 << (ep + USBDEV_EP_OUT_ENABLE_ENABLE_0_BIT));
     REG32(USBDEV_BASE_ADDR + USBDEV_EP_OUT_ENABLE_REG_OFFSET) = ep_en;
   }
+  if (out_mode == kUsbdevOutMessage) {
+    uint32_t set_nak_out =
+        REG32(USBDEV_BASE_ADDR + USBDEV_SET_NAK_OUT_REG_OFFSET);
+    set_nak_out |= (1 << (ep + USBDEV_SET_NAK_OUT_ENABLE_0_BIT));
+    REG32(USBDEV_BASE_ADDR + USBDEV_SET_NAK_OUT_REG_OFFSET) = set_nak_out;
+  }
 }
 
 void usbdev_connect(usbdev_ctx_t *ctx) {
@@ -303,7 +316,8 @@
                  bool tx_use_d_se0) {
   // setup context
   for (int i = 0; i < NUM_ENDPOINTS; i++) {
-    usbdev_endpoint_setup(ctx, i, 0, NULL, NULL, NULL, NULL, NULL);
+    usbdev_endpoint_setup(ctx, i, kUsbdevOutDisabled, NULL, NULL, NULL, NULL,
+                          NULL);
   }
   ctx->halted = 0;
   ctx->can_wake = 0;
diff --git a/sw/device/lib/usbdev.h b/sw/device/lib/usbdev.h
index 54fa3ba..baafdea 100644
--- a/sw/device/lib/usbdev.h
+++ b/sw/device/lib/usbdev.h
@@ -206,12 +206,41 @@
 int usbdev_can_rem_wake(usbdev_ctx_t *ctx);
 
 /**
+ * Re-enable OUT transactions for a given endpoint.
+ *
+ * This function must be called after reception of a packet for a given
+ * endpoint, else the endpoint will NAK the next packet.
+ *
+ * @param ctx usbdev context pointer
+ * @param endpoint endpoint number
+ */
+void usbdev_clear_out_nak(usbdev_ctx_t *ctx, int ep);
+
+typedef enum usbdev_out_transfer_mode {
+  /**
+   * The endpoint does not support OUT transactions.
+   */
+  kUsbdevOutDisabled = 0,
+  /**
+   * Software does NOT need to call usbdev_clear_out_nak() after every received
+   * transaction. If software takes no action, usbdev will allow an endpoint's
+   * transactions to proceed as long as a buffer is available.
+   */
+  kUsbdevOutStream = 1,
+  /**
+   * Software must call usbdev_clear_out_nak() after every received transaction
+   * to re-enable packet reception. This gives software time to respond with the
+   * appropriate handshake when it's ready.
+   */
+  kUsbdevOutMessage = 2,
+} usbdev_out_transfer_mode_t;
+
+/**
  * Call to setup an endpoint
  *
  * @param ctx usbdev context pointer
  * @param ep endpoint number
- * @param enableout boolean, true to enable OUT transactions on the endpoint
- *             (OUT means host->device, ie receive by us)
+ * @param out_mode the transfer mode for OUT transactions
  * @param ep_ctx context pointer for callee
  * @param tx_done(void *ep_ctx) callback once send has been Acked
  * @param rx(void *ep_ctx, usbbufid_t buf, int size, int setup)
@@ -219,8 +248,9 @@
  * @param flush(void *ep_ctx) called every 16ms based USB host timebase
  * @param reset(void *ep_ctx) called when an USB link reset is detected
  */
-void usbdev_endpoint_setup(usbdev_ctx_t *ctx, int ep, int enableout,
-                           void *ep_ctx, void (*tx_done)(void *),
+void usbdev_endpoint_setup(usbdev_ctx_t *ctx, int ep,
+                           usbdev_out_transfer_mode_t out_mode, void *ep_ctx,
+                           void (*tx_done)(void *),
                            void (*rx)(void *, usbbufid_t, int, int),
                            void (*flush)(void *), void (*reset)(void *));