[usbdev] Clean up confusing uses of "differential"

Explicitly refer to a receiver wherever "differential" is used with
"rx".

Previously, the term on RX would mean that an *external* differential
receiver would be used, delivering a *single-ended* data signal to the
IP. However, this top-level definition causes too much confusion.

Similarly, for TX, avoid using "differential" altogether, as neither the
driver nor the signals are truly differential. Instead, refer to the two
interfaces by the component signal names.

Signed-off-by: Alexander Williams <awill@google.com>
diff --git a/hw/ip/usb_fs_nb_pe/rtl/usb_fs_nb_pe.sv b/hw/ip/usb_fs_nb_pe/rtl/usb_fs_nb_pe.sv
index add1f3a..a26fa6b 100644
--- a/hw/ip/usb_fs_nb_pe/rtl/usb_fs_nb_pe.sv
+++ b/hw/ip/usb_fs_nb_pe/rtl/usb_fs_nb_pe.sv
@@ -31,7 +31,7 @@
   input  logic [6:0]             dev_addr_i,
 
   input  logic                   cfg_eop_single_bit_i, // 1: detect a single SE0 bit as EOP
-  input  logic                   cfg_rx_differential_i, // 1: use differential rx data on usb_d_i
+  input  logic                   cfg_use_diff_rcvr_i, // 1: use usb_d_i from a differential receiver
   input  logic                   tx_osc_test_mode_i, // Oscillator test mode (constantly output JK)
   input  logic [NumOutEps-1:0]   data_toggle_clear_i, // Clear the data toggles for an EP
 
@@ -233,7 +233,7 @@
     .rst_ni                 (rst_ni),
     .link_reset_i           (link_reset_i),
     .cfg_eop_single_bit_i   (cfg_eop_single_bit_i),
-    .cfg_rx_differential_i  (cfg_rx_differential_i),
+    .cfg_use_diff_rcvr_i    (cfg_use_diff_rcvr_i),
     .usb_d_i                (usb_d_i),
     .usb_dp_i               (usb_dp_i),
     .usb_dn_i               (usb_dn_i),
diff --git a/hw/ip/usb_fs_nb_pe/rtl/usb_fs_rx.sv b/hw/ip/usb_fs_nb_pe/rtl/usb_fs_rx.sv
index 374ff7a..3b38264 100644
--- a/hw/ip/usb_fs_nb_pe/rtl/usb_fs_rx.sv
+++ b/hw/ip/usb_fs_nb_pe/rtl/usb_fs_rx.sv
@@ -12,7 +12,7 @@
 
   // configuration
   input  logic cfg_eop_single_bit_i,
-  input  logic cfg_rx_differential_i,
+  input  logic cfg_use_diff_rcvr_i,
 
   // USB data+ and data- lines (synchronous)
   input  logic usb_d_i,
@@ -68,17 +68,20 @@
   // line state recovery state machine //
   ///////////////////////////////////////
 
-  // If the receive path is set not to use a differential reciever:
-  // There is a chance that one of the differential pairs will appear to have
-  // changed to the new state while the other is still in the old state.  the
+  // If the receive path is set NOT to use an external differential receiver:
+  // This block samples data purely from the usb_dp_i/usb_dn_i pair.
+  // There is a chance that one of the signals in the pair will appear to have
+  // changed to the new state while the other is still in the old state.  The
   // following state machine detects transitions and waits an extra sampling clock
-  // before decoding the state on the differential pair.  this transition period
-  // will only ever last for one clock as long as there is no noise on the line.
-  // if there is enough noise on the line then the data may be corrupted and the
+  // before decoding the state on the dp/dn pair.  This transition period will
+  // only ever last for one clock as long as there is no noise on the line.
+  // If there is enough noise on the line then the data may be corrupted and the
   // packet will fail the data integrity checks.
 
-  // If the receive path uses a differential receiver:
-  // The single ended signals must still be recovered to detect SE0
+  // If the receive path uses an external differential receiver:
+  // This block uses the usb_d_i input to detect K and J symbols.
+  // The individual signals of the differential pair must still be connected
+  // to this block to detect SE0.
   // Note that the spec warns in section 7.1.4.1:
   // Both D+ and D- may temporarily be less than VIH (min) during differential
   // signal transitions. This period can be up to 14 ns (TFST) for full-speed
@@ -87,7 +90,7 @@
   // Since the 48MHz sample clock is 20.833ns period we will either miss this or
   // sample it only once, so it will be covered by line_state=DT and the next
   // sample will not be SE0 unless this was a real SE0 transition
-  // Note: if it is a real SE0 the differential rx could be doing anything
+  // Note: if it is a real SE0 the usb_d_i input could be doing anything.
 
   logic [2:0] line_state_qq, line_state_q, line_state_d;
   logic [2:0] diff_state_q, diff_state_d;
@@ -101,6 +104,12 @@
   // localparam logic [2:0] SE1 = 3'b011; // single-ended 1 - illegal
 
   // Mute the input if we're transmitting
+  // dpair is the usb_dp_i/usb_dn_i pair, used in both modes. With
+  // an external differential receiver, it is only used for detecting SE0 and
+  // transitions. Without an external differential receiver driving the
+  // usb_d_i input, it is used for all symbols.
+  // ddiff is the decoded data input from an external differential receiver,
+  // if available, and it is only for K and J symbols, plus transition detection.
   logic [1:0] dpair, ddiff;
   always_comb begin : proc_dpair_mute
     if (tx_en_i) begin
@@ -167,29 +176,29 @@
   end
 
   // The received line state depends on how the receiver is configured:
-  // Single ended only: it is just the line_state_q that was captured
+  // NOT using a differential receiver: it is just the line_state_q that was captured
   //
-  // Differential: recovered from the differential receiver (diff_state_q)
-  //               unless the single ended indicate SE0 when the differential
-  //               receiver could produce any value
+  // Using a differential receiver: recovered from the differential receiver (diff_state_q)
+  //                                unless the diff pair indicate SE0 when the differential
+  //                                receiver could produce any value
   //
-  // Transition where single ended happens to see SE0 look like (driven by diff DT)
+  // Transition where the dp/dn pair happen to see SE0 will look like (driven by diff DT)
   // line_state    D? DT D?...
   // diff_state    Dx DT Dy         (expect Dy to be inverse of Dx since diff changed)
   //
-  // Transition to SE0 when differential changes will look like:
+  // Transition to SE0 when usb_d_i changes will look like:
   // line_state    DT D? D? D? DT SE0 SE0... (DT is the first sample at SE0)
   // diff_state    DT Dx Dx Dx DT ??  ??...  (diff saw transition as line went SE0)
   //    --> out    DT Dx Dx Dx DT SE0 SE0    (if no transition then DT would be Dx and n=3)
   // bit_phase      n  0  1  2  3  0   1     (n=3 unless there was a clock resync)
   //
-  // Transition to SE0 when differential does not change will look like:
+  // Transition to SE0 when usb_d_i does not change will look like:
   // line_state    DT D? D? D? DT SE0 SE0... (DT is the first sample at SE0)
   // diff_state    DT Dx Dx Dx Dx ??  ??...  (diff no transition as line went SE0)
   //    --> out    DT Dx Dx Dx Dx SE0 SE0    (if no transition then DT would be Dx and n=3)
   // bit_phase      n  0  1  2  3  0   1     (n=3 unless there was a clock resync)
   //
-  // Transition to SE0 when differential does not change and clock resync earlier:
+  // Transition to SE0 when usb_d_i does not change and clock resync earlier:
   // line_state    DT D? D? DT SE0 SE0 SE0... (DT is the first sample at SE0, should resync clock)
   // diff_state    DT Dx Dx Dx Dx  ??  ??...  (diff no transition as line went SE0)
   //    --> out    DT Dx Dx Dx SE0 SE0 SE0    (if no transition then DT would be Dx and n=3)
@@ -203,8 +212,8 @@
   // bit_phase      ?   ?   ?  0  1  2
 
   assign use_se = (line_state_q == SE0) || ((line_state_q == DT) && (line_state_qq == SE0));
-  assign line_state_rx = cfg_rx_differential_i ? (use_se ? line_state_q : diff_state_q) :
-                                                 line_state_q;
+  assign line_state_rx = cfg_use_diff_rcvr_i ? (use_se ? line_state_q : diff_state_q) :
+                                               line_state_q;
 
   ////////////////////
   // clock recovery //
diff --git a/hw/ip/usbdev/data/usbdev.hjson b/hw/ip/usbdev/data/usbdev.hjson
index 0139c43..f73dd48 100644
--- a/hw/ip/usbdev/data/usbdev.hjson
+++ b/hw/ip/usbdev/data/usbdev.hjson
@@ -758,22 +758,22 @@
         {
           bits: "8",
           name: "tx_dp_o",
-          desc: "USB differential D+ output (readback)."
+          desc: "USB transmit D+ output (readback)."
         }
         {
           bits: "9",
           name: "tx_dn_o",
-          desc: "USB differential D- output (readback)."
+          desc: "USB transmit D- output (readback)."
         }
         {
           bits: "10",
           name: "tx_d_o",
-          desc: "USB single-ended output (readback)."
+          desc: "USB transmit data value (readback)."
         }
         {
           bits: "11",
           name: "tx_se0_o",
-          desc: "USB single-ended SE0 output (readback)."
+          desc: "USB single-ended zero output (readback)."
         }
         {
           bits: "12",
@@ -807,22 +807,22 @@
         {
           bits: "0",
           name: "dp_o",
-          desc: "USB differential D+ output."
+          desc: "USB transmit D+ output, used with dn_o."
         }
         {
           bits: "1",
           name: "dn_o",
-          desc: "USB differential D- output."
+          desc: "USB transmit D- output, used with dp_o."
         }
         {
           bits: "2",
           name: "d_o",
-          desc: "USB single-ended output."
+          desc: "USB transmit data output, encoding K and J when se0_o is 0."
         }
         {
           bits: "3",
           name: "se0_o",
-          desc: "USB single-ended SE0 output."
+          desc: "USB single-ended zero output."
         }
         {
           bits: "4",
@@ -869,10 +869,13 @@
         {
           bits: "0",
           resval: "0",
-          name: "rx_differential_mode",
+          name: "use_diff_rcvr",
           desc: '''
-                Use the differential RX signal instead of the single-ended signals.
-                Currently only 0 (single-ended operation) is supported.
+                Detect received K and J symbols from the usb_rx_d signal, which must be driven from an external differential receiver.
+                If 1, make use of the usb_rx_d input.
+                If 0, the usb_rx_d input is ignored and the usb_rx_dp and usb_rx_dn pair are used to detect K and J (useful for some environments, but will be unlikely to pass full USB compliance).
+                Regardless of the state of this field usb_rx_dp and usb_rx_dn are always used to detect SE0.
+                This bit also feeds the rx_enable pin, activating the receiver when the device is not suspended.
                 '''
         }
         {
@@ -883,7 +886,7 @@
                 If 1, select the d and se0 TX interface.
                 If 0, select the dp and dn TX interface.
                 This directly controls the output pin of the same name.
-                It is intended to be used to enable the use of a variety of external transceivers.
+                It is intended to be used to enable the use of a variety of external transceivers, to select an encoding that matches the transceiver.
                 '''
         }
         {
diff --git a/hw/ip/usbdev/doc/_index.md b/hw/ip/usbdev/doc/_index.md
index dcf568c..1f138f5 100644
--- a/hw/ip/usbdev/doc/_index.md
+++ b/hw/ip/usbdev/doc/_index.md
@@ -31,7 +31,7 @@
 
 The USB device module is a simple software-driven generic USB device interface for Full-Speed USB 2.0 operation.
 The IP includes the physical layer interface, the low level USB protocol and a packet buffer interface to the software.
-The physical layer interface features both differential and single-ended transmit and receive paths to allow interfacing with a variety of USB PHYs or regular 3.3V IO pads for FPGA prototyping.
+The physical layer interface features multiple transmit and receive paths to allow interfacing with a variety of USB PHYs or regular 3.3V IO pads for FPGA prototyping.
 
 
 ## Compatibility
@@ -85,12 +85,14 @@
 ## USB Interface Pins
 
 Full-Speed USB uses a bidirectional serial interface as shown in Figure 7-24 of the [USB 2.0 Full-Speed specification](https://www.usb.org/document-library/usb-20-specification).
-For reasons of flexibility, this IP block features both differential and single-ended transmit and receive paths.
+For reasons of flexibility, this IP block features multiple transmit and receive paths for interfacing with various transceivers.
 
 For better receive sensitivity, lower transmit jitter and to be standard compliant, a dedicated, differential USB transceiver such as the [USB1T11A](https://www.mouser.com/datasheet/2/149/fairchild%20semiconductor_usb1t11a-320893.pdf) or the [USB1T20](https://www.onsemi.com/pub/Collateral/USB1T20-D.pdf) must be used (see Section 7.1.4.1 of the [USB 2.0 specification](https://www.usb.org/document-library/usb-20-specification)).
-Depending on the selected USB transceiver, either the differential or the single-ended transmit and receive paths or a combination of the two can be used to interface the IP block with the transceiver.
+Depending on the selected USB transceiver, either the dp/dn or d/se0 transmit paths or can be used to interface the IP block with the transceiver.
+If the selected USB transceiver contains a differential receiver, its output may also be enabled and passed to the D input of the IP block.
 
-When prototyping on FPGAs (here the interface can be implemented with pseudo-differential 3.3V GPIO pins and an oversampling receiver for recovery of the bitstream and clock alignment), the single-ended signal pairs can be used.
+When prototyping on FPGAs the interface can be implemented with pseudo-differential 3.3V GPIO pins for D+ and D-. The receiver will oversample to recover the bitstream and clock alignment even if there is considerable timing skew between the signal paths.
+The full speed transmit always uses LVCMOS output drivers (see USB 2.0 spec Figure 7-1 and Figure 7-3) but there are two possible encodings: Either the D+ and D- values are directly driven from tx_dp and tx_dn, or there is a data value from tx_d and an indicator to force SE0 from tx_se0.
 External to the IP, these should be combined to drive the actual pins when transmit is enabled and receive otherwise.
 Using standard 3.3V IO pads allows use on most FPGAs although the drive strength and series termination resistors may need to be adjusted to meet the USB signal eye.
 On a Xilinx Artix-7 (and less well tested Spartan-7) part, setting the driver to the 8mA, FAST setting seems to work well with a 22R series termination (and with a 0R series termination).
@@ -100,33 +102,37 @@
 
 ### Data Transmit
 
-The IP block supports both differential and single-ended transmission (TX).
-The TX mode can be selected by setting the `tx_differential_mode` bit in {{< regref "phy_config" >}} to either 1 (differential) or 0 (single ended).
+The IP block supports two different encodings, driving out on separate TX interfaces.
+The default encoding looks like the USB bus, with D+ and D- values driven on usb_dp_o and usb_dn_o pins.
+The alternate encoding uses usb_se0_o to indicate a single-ended zero (SE0), and usb_d_o encodes K/J (when usb_se0_o is low).
+The TX mode can be selected by setting the `use_tx_d_se0` bit in {{< regref "phy_config" >}} to either 1 (alternate, using d/se0) or 0 (default, using dp/dn).
 
 The following table summarizes how the different output signals relate to the USB interface pins.
 
 |  External Pins | Internal Signals | Notes |
 |----------------|------------------|-------|
-| D+, D-         | d_o              | Data output for interfacing with a differential USB transceiver. |
-| \"             | se0_o            | Signal Single-Ended Zero (SE0) link state to a differential USB transceiver. |
-| \"             | dp_o, dn_o       | Single-ended data output signals. These can be used to interface to regular IO cells for prototyping on an FPGA, but such an interface will probably not be USB compliant. |
-|   [TX Mode]    | tx_mode_se_o     | Indicates the selected TX mode: single-ended (1) or differential (0) operation. |
+| D+, D-         | dp_o, dn_o       | Data output with an encoding like the USB bus, intended to go directly to pads for supported targets. On an FPGA, the components should be used with a USB transceiver, as the regular bidirectional I/O cells will likely not be USB compliant. |
+| [Alt TX Data]  | se0_o            | Signal Single-Ended Zero (SE0) link state to a USB transceiver. |
+| [Alt TX Data]  | d_o              | Data output used for encoding K and J, for interfacing with a USB transceiver. |
+|   [TX Mode]    | tx_use_d_se0_o   | Indicates the selected TX interface: use dp_o and dn_o (0) or use d_o and se0_o (1). |
 
 Note that according to the [Comportable guideline for peripheral functionality]({{< relref "doc/rm/comportability_specification" >}}), every output signal `name_o` has a dedicated output enable `name_en_o`.
-For TX data, these separate signals `d_en_o`, `dp_en_o` and `dn_en_o` all correspond to the same TX or output enable signal (`OE` in the USB spec).
+For TX data, these separate signals `dp_en_o` and `dn_en_o` all correspond to the same TX or output enable signal (`OE` in the USB spec).
+The other signals listed are of the "intersignal" variety, and they do not go directly to pads or have dedicated output enable signals.
 
 
 ### Data Receive
 
-The IP block supports both differential and single-ended reception (RX).
-The RX mode can be selected by setting the `rx_differential_mode` bit in {{< regref "phy_config" >}} to either 1 (differential) or 0 (single ended).
+The IP block supports recovery of the differential K and J symbols from the output of an external differential receiver or directly from the D+/D- pair.
+The RX mode can be selected to use a differential receiver's output by setting the `use_diff_rcvr` bit in {{< regref "phy_config" >}}.
+The D+/D- pair is always used to detect the single-ended zero (SE0) state.
 
 The following table summarizes how the different input signals relate to the USB interface pins.
 
 |  External Pins | Internal Signals | Notes |
 |----------------|------------------|-------|
-| D+, D-         | d_i              | Data input for interfacing with a differential USB transceiver. Used in differential RX mode only. |
-| \"             | dp_i, dn_i       | Single-ended data input signals. These signals are used to detect the SE0 link state in differential RX mode. They can further be used to interface to regular IO cells for prototyping on an FPGA, but such an interface will probably not be USB compliant. |
+| D+, D-         | dp_i, dn_i       | D+ and D- signals passing into the IP single-ended, intended to go directly to pads for supported targets. These signals are used to detect the SE0 link state, and if a differential receiver is not present, they are also used for K and J symbols. On an FPGA, the components should be used with a USB transceiver, as the bidirectional regular IO cells will likely not be USB compliant. |
+| [Diff Rcvr Out]| d_i              | Data input for interfacing with a differential receiver, which is required for this input. |
 
 
 ### Non-Data Pins
@@ -138,6 +144,7 @@
 | sense (VBUS)   | sense_i                  | The sense pin indicates the presence of VBUS from the USB host. |
 | [pullup]       | dp_pullup_o, dn_pullup_o | When dp_pullup_o or dn_pullup_o asserts a 1.5k pullup resistor should be connected to D+ or D-, respectively. This can be done inside the chip or with an external pin. A permanently connected resistor could be used if the pin flip feature is not needed, but this is not recommended because there is then no way to force the device to appear to unplug. Only one of the pullup signals can be asserted at any time. The selection is based on the `pinflip` bit in {{< regref "phy_config" >}}. Because this is a Full-Speed device the resistor must be on the D+ pin, so when `pinflip` is zero, dp_pullup_o is used. |
 | [suspend]      | suspend_o                | The suspend pin indicates to the USB transceiver that a constant idle has been detected on the link and the device is in the Suspend state (see Section 7.1.7.6 of the [USB 2.0 specification](https://www.usb.org/document-library/usb-20-specification)). |
+| [rx_enable]    | rx_enable_o              | The rx_enable pin turns on/off a differential receiver. It is enabled via a CSR and automatically disabled when the device suspends. |
 
 The USB host will identify itself to the device by enabling the 5V VBUS power.
 It may do a hard reset of a port by removing and reasserting VBUS (the Linux driver will do this when it finds a port in an inconsistent state or a port that generates errors during enumeration).
diff --git a/hw/ip/usbdev/rtl/usbdev.sv b/hw/ip/usbdev/rtl/usbdev.sv
index d037374..dbb7404 100644
--- a/hw/ip/usbdev/rtl/usbdev.sv
+++ b/hw/ip/usbdev/rtl/usbdev.sv
@@ -578,7 +578,7 @@
     .in_ep_iso_i          (ep_in_iso), // cdc ok, quasi-static
     .cfg_eop_single_bit_i (reg2hw.phy_config.eop_single_bit.q), // cdc ok: quasi-static
     .tx_osc_test_mode_i   (reg2hw.phy_config.tx_osc_test_mode.q), // cdc ok: quasi-static
-    .cfg_rx_differential_i (reg2hw.phy_config.rx_differential_mode.q), // cdc ok: quasi-static
+    .cfg_use_diff_rcvr_i  (reg2hw.phy_config.use_diff_rcvr.q), // cdc ok: quasi-static
     .data_toggle_clear_i  (usb_data_toggle_clear),
     .resume_link_active_i (usb_resume_link_active),
 
@@ -1060,7 +1060,7 @@
   // not suspended.
   // TODO(#10901): This can cause undefined behavior if this module stays
   // powered to detect resume (instead of the AON module).
-  assign usb_rx_enable_o = reg2hw.phy_config.rx_differential_mode.q & ~usb_suspend_o;
+  assign usb_rx_enable_o = reg2hw.phy_config.use_diff_rcvr.q & ~usb_suspend_o;
 
   /////////////////////////////////////////
   // SOF Reference for Clock Calibration //
diff --git a/hw/ip/usbdev/rtl/usbdev_iomux.sv b/hw/ip/usbdev/rtl/usbdev_iomux.sv
index 45c76e4..3e8c1a6 100644
--- a/hw/ip/usbdev/rtl/usbdev_iomux.sv
+++ b/hw/ip/usbdev/rtl/usbdev_iomux.sv
@@ -59,14 +59,14 @@
   logic usb_rx_dp, usb_rx_dn, usb_rx_d;
   logic pinflip;
   logic unused_eop_single_bit;
-  logic unused_rx_differential_mode;
+  logic unused_use_diff_rcvr;
   logic unused_usb_ref_disable;
   logic unused_tx_osc_test_mode;
 
   assign unused_eop_single_bit       = sys_reg2hw_config_i.eop_single_bit.q;
   assign unused_usb_ref_disable      = sys_reg2hw_config_i.usb_ref_disable.q;
   assign unused_tx_osc_test_mode     = sys_reg2hw_config_i.tx_osc_test_mode.q;
-  assign unused_rx_differential_mode = sys_reg2hw_config_i.rx_differential_mode.q;
+  assign unused_use_diff_rcvr        = sys_reg2hw_config_i.use_diff_rcvr.q;
 
   //////////
   // CDCs //
diff --git a/hw/ip/usbdev/rtl/usbdev_reg_pkg.sv b/hw/ip/usbdev/rtl/usbdev_reg_pkg.sv
index aed1517..2f26e70 100644
--- a/hw/ip/usbdev/rtl/usbdev_reg_pkg.sv
+++ b/hw/ip/usbdev/rtl/usbdev_reg_pkg.sv
@@ -326,7 +326,7 @@
   typedef struct packed {
     struct packed {
       logic        q;
-    } rx_differential_mode;
+    } use_diff_rcvr;
     struct packed {
       logic        q;
     } tx_use_d_se0;
diff --git a/hw/ip/usbdev/rtl/usbdev_reg_top.sv b/hw/ip/usbdev/rtl/usbdev_reg_top.sv
index 08ff85f..d091a62 100644
--- a/hw/ip/usbdev/rtl/usbdev_reg_top.sv
+++ b/hw/ip/usbdev/rtl/usbdev_reg_top.sv
@@ -678,8 +678,8 @@
   logic phy_pins_drive_en_qs;
   logic phy_pins_drive_en_wd;
   logic phy_config_we;
-  logic phy_config_rx_differential_mode_qs;
-  logic phy_config_rx_differential_mode_wd;
+  logic phy_config_use_diff_rcvr_qs;
+  logic phy_config_use_diff_rcvr_wd;
   logic phy_config_tx_use_d_se0_qs;
   logic phy_config_tx_use_d_se0_wd;
   logic phy_config_eop_single_bit_qs;
@@ -6853,18 +6853,18 @@
 
 
   // R[phy_config]: V(False)
-  //   F[rx_differential_mode]: 0:0
+  //   F[use_diff_rcvr]: 0:0
   prim_subreg #(
     .DW      (1),
     .SwAccess(prim_subreg_pkg::SwAccessRW),
     .RESVAL  (1'h0)
-  ) u_phy_config_rx_differential_mode (
+  ) u_phy_config_use_diff_rcvr (
     .clk_i   (clk_i),
     .rst_ni  (rst_ni),
 
     // from register interface
     .we     (phy_config_we),
-    .wd     (phy_config_rx_differential_mode_wd),
+    .wd     (phy_config_use_diff_rcvr_wd),
 
     // from internal hardware
     .de     (1'b0),
@@ -6872,10 +6872,10 @@
 
     // to internal hardware
     .qe     (),
-    .q      (reg2hw.phy_config.rx_differential_mode.q),
+    .q      (reg2hw.phy_config.use_diff_rcvr.q),
 
     // to register interface (read)
-    .qs     (phy_config_rx_differential_mode_qs)
+    .qs     (phy_config_use_diff_rcvr_qs)
   );
 
   //   F[tx_use_d_se0]: 1:1
@@ -7714,7 +7714,7 @@
   assign phy_pins_drive_en_wd = reg_wdata[16];
   assign phy_config_we = addr_hit[32] & reg_we & !reg_error;
 
-  assign phy_config_rx_differential_mode_wd = reg_wdata[0];
+  assign phy_config_use_diff_rcvr_wd = reg_wdata[0];
 
   assign phy_config_tx_use_d_se0_wd = reg_wdata[1];
 
@@ -8083,7 +8083,7 @@
       end
 
       addr_hit[32]: begin
-        reg_rdata_next[0] = phy_config_rx_differential_mode_qs;
+        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;
         reg_rdata_next[5] = phy_config_pinflip_qs;
diff --git a/hw/ip/usbdev/rtl/usbdev_usbif.sv b/hw/ip/usbdev/rtl/usbdev_usbif.sv
index 2dbe67d..e1eca63 100644
--- a/hw/ip/usbdev/rtl/usbdev_usbif.sv
+++ b/hw/ip/usbdev/rtl/usbdev_usbif.sv
@@ -76,7 +76,7 @@
   input  logic [NEndpoints-1:0]    out_ep_iso_i,
   input  logic [NEndpoints-1:0]    in_ep_iso_i,
   input  logic                     cfg_eop_single_bit_i, // 1: detect a single SE0 bit as EOP
-  input  logic                     cfg_rx_differential_i, // 1: use differential rx data on usb_d_i
+  input  logic                     cfg_use_diff_rcvr_i, // 1: use single-ended rx data on usb_d_i
   input  logic                     tx_osc_test_mode_i, // Oscillator test mode: constant JK output
   input  logic [NEndpoints-1:0]    data_toggle_clear_i, // Clear the data toggles for an EP
   input  logic                     resume_link_active_i, // Jump from LinkPowered to LinkResuming
@@ -277,7 +277,7 @@
     .link_active_i         (link_active_o),
 
     .cfg_eop_single_bit_i  (cfg_eop_single_bit_i),
-    .cfg_rx_differential_i (cfg_rx_differential_i),
+    .cfg_use_diff_rcvr_i   (cfg_use_diff_rcvr_i),
     .tx_osc_test_mode_i    (tx_osc_test_mode_i),
     .data_toggle_clear_i   (data_toggle_clear_i),
 
diff --git a/sw/device/lib/dif/dif_usbdev.c b/sw/device/lib/dif/dif_usbdev.c
index 1de79a4..89db6d0 100644
--- a/sw/device/lib/dif/dif_usbdev.c
+++ b/sw/device/lib/dif/dif_usbdev.c
@@ -233,7 +233,7 @@
   }
 
   // Check enum fields.
-  if (!is_valid_toggle(config.differential_rx) ||
+  if (!is_valid_toggle(config.have_differential_receiver) ||
       !is_valid_toggle(config.use_tx_d_se0) ||
       !is_valid_toggle(config.single_bit_eop) ||
       !is_valid_toggle(config.pin_flip) ||
@@ -244,14 +244,14 @@
   // Determine the value of the PHY_CONFIG register.
   uint32_t phy_config_val = 0;
 
-  if (config.differential_rx == kDifToggleEnabled) {
-    phy_config_val = bitfield_field32_write(
-        phy_config_val,
-        (bitfield_field32_t){
-            .mask = 1,
-            .index = USBDEV_PHY_CONFIG_RX_DIFFERENTIAL_MODE_BIT,
-        },
-        1);
+  if (config.have_differential_receiver == kDifToggleEnabled) {
+    phy_config_val =
+        bitfield_field32_write(phy_config_val,
+                               (bitfield_field32_t){
+                                   .mask = 1,
+                                   .index = USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT,
+                               },
+                               1);
   }
 
   if (config.use_tx_d_se0 == kDifToggleEnabled) {
diff --git a/sw/device/lib/dif/dif_usbdev.h b/sw/device/lib/dif/dif_usbdev.h
index 46b7240..4c7a57c 100644
--- a/sw/device/lib/dif/dif_usbdev.h
+++ b/sw/device/lib/dif/dif_usbdev.h
@@ -123,9 +123,10 @@
  */
 typedef struct dif_usbdev_config {
   /**
-   * Use the differential rx signal instead of the single-ended signals.
+   * Activate the single-ended D signal for detecting K and J symbols, for use
+   * with a differential receiver.
    */
-  dif_toggle_t differential_rx;
+  dif_toggle_t have_differential_receiver;
   /**
    * Use the TX interface with D and SE0 signals instead of Dp/Dn, for use with
    * certain transceivers.
diff --git a/sw/device/lib/usbdev.c b/sw/device/lib/usbdev.c
index 9de3848..63e1689 100644
--- a/sw/device/lib/usbdev.c
+++ b/sw/device/lib/usbdev.c
@@ -299,7 +299,7 @@
       (1 << USBDEV_USBCTRL_ENABLE_BIT);
 }
 
-void usbdev_init(usbdev_ctx_t *ctx, bool pinflip, bool diff_rx,
+void usbdev_init(usbdev_ctx_t *ctx, bool pinflip, bool en_diff_rcvr,
                  bool tx_use_d_se0) {
   // setup context
   for (int i = 0; i < NUM_ENDPOINTS; i++) {
@@ -326,11 +326,10 @@
   REG32(USBDEV_BASE_ADDR + USBDEV_IN_STALL_REG_OFFSET) = 0;
   REG32(USBDEV_BASE_ADDR + USBDEV_OUT_STALL_REG_OFFSET) = 0;
 
-  uint32_t phy_config =
-      (pinflip << USBDEV_PHY_CONFIG_PINFLIP_BIT) |
-      (diff_rx << USBDEV_PHY_CONFIG_RX_DIFFERENTIAL_MODE_BIT) |
-      (tx_use_d_se0 << USBDEV_PHY_CONFIG_TX_USE_D_SE0_BIT) |
-      (1 << USBDEV_PHY_CONFIG_EOP_SINGLE_BIT_BIT);
+  uint32_t phy_config = (pinflip << USBDEV_PHY_CONFIG_PINFLIP_BIT) |
+                        (en_diff_rcvr << USBDEV_PHY_CONFIG_USE_DIFF_RCVR_BIT) |
+                        (tx_use_d_se0 << USBDEV_PHY_CONFIG_TX_USE_D_SE0_BIT) |
+                        (1 << USBDEV_PHY_CONFIG_EOP_SINGLE_BIT_BIT);
   REG32(USBDEV_BASE_ADDR + USBDEV_PHY_CONFIG_REG_OFFSET) = phy_config;
 }
 
diff --git a/sw/device/lib/usbdev.h b/sw/device/lib/usbdev.h
index b8f356e..54fa3ba 100644
--- a/sw/device/lib/usbdev.h
+++ b/sw/device/lib/usbdev.h
@@ -239,11 +239,13 @@
  *
  * @param ctx uninitialized usbdev context pointer
  * @param pinflip boolean to indicate if PHY should be configured for D+/D- flip
- * @param diff_rx boolean to indicate if PHY uses differential RX
+ * @param en_diff_rcvr boolean to indicate if PHY should enable an external
+ *                     differential receiver, activating the single-ended D
+ *                     input
  * @param tx_use_d_se0 boolean to indicate if PHY uses D/SE0 for TX instead of
  *                     Dp/Dn
  */
-void usbdev_init(usbdev_ctx_t *ctx, bool pinflip, bool diff_rx,
+void usbdev_init(usbdev_ctx_t *ctx, bool pinflip, bool en_diff_rcvr,
                  bool tx_use_d_se0);
 
 /**
diff --git a/sw/device/tests/usbdev_test.c b/sw/device/tests/usbdev_test.c
index 4d48502..2102034 100644
--- a/sw/device/tests/usbdev_test.c
+++ b/sw/device/tests/usbdev_test.c
@@ -108,7 +108,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.
-  usbdev_init(&usbdev, /* pinflip= */ false, /* rx_diff= */ false,
+  usbdev_init(&usbdev, /* pinflip= */ false, /* en_diff_rcvr= */ false,
               /* tx_use_d_se0= */ false);
   usb_controlep_init(&usbdev_control, &usbdev, 0, config_descriptors,
                      sizeof(config_descriptors));