[usbdev] Fix pinflip logic
Fix implementation of pinflip on both input and output paths;
inverting the signals is not the same as exchanging them
because the two differential signals are not always opposing.
Signed-off-by: Adrian Lees <a.lees@lowrisc.org>
diff --git a/hw/ip/usbdev/rtl/usb_fs_rx.sv b/hw/ip/usbdev/rtl/usb_fs_rx.sv
index 35b095e..10bea5c 100644
--- a/hw/ip/usbdev/rtl/usb_fs_rx.sv
+++ b/hw/ip/usbdev/rtl/usb_fs_rx.sv
@@ -65,8 +65,8 @@
//////////////////////
// Adjust inputs when D+/D- are flipped on the USB side
logic usb_dp_flipped, usb_dn_flipped, usb_d_flipped;
- assign usb_dp_flipped = usb_dp_i ^ cfg_pinflip_i;
- assign usb_dn_flipped = usb_dn_i ^ cfg_pinflip_i;
+ assign usb_dp_flipped = cfg_pinflip_i ? usb_dn_i : usb_dp_i;
+ assign usb_dn_flipped = cfg_pinflip_i ? usb_dp_i : usb_dn_i;
assign usb_d_flipped = usb_d_i ^ cfg_pinflip_i;
///////////////////////////////////////
diff --git a/hw/ip/usbdev/rtl/usb_fs_tx.sv b/hw/ip/usbdev/rtl/usb_fs_tx.sv
index fa28ea1..517b8f8 100644
--- a/hw/ip/usbdev/rtl/usb_fs_tx.sv
+++ b/hw/ip/usbdev/rtl/usb_fs_tx.sv
@@ -453,19 +453,17 @@
// Handle the D+ / D- pin flip on the USB side, and provide both the
// dp/dn and d/se0 interfaces, for compatibility with multiple driver types.
- logic usb_d_flipped, usb_se0_flipped, usb_dp_flipped, usb_dn_flipped;
+ logic usb_se0_flipped, usb_dp_flipped, usb_dn_flipped;
always_comb begin
if (link_reset_i) begin
- usb_d_flipped = 1'b0 ^ cfg_pinflip_i;
usb_se0_flipped = 1'b0;
usb_dp_flipped = 1'b0 ^ cfg_pinflip_i;
usb_dn_flipped = 1'b1 ^ cfg_pinflip_i;
end else begin
- usb_d_flipped = usb_d_d ^ cfg_pinflip_i;
usb_se0_flipped = usb_se0_d;
- usb_dp_flipped = (usb_d_d & ~usb_se0_d) ^ cfg_pinflip_i;
- usb_dn_flipped = (~usb_d_d & ~usb_se0_d) ^ cfg_pinflip_i;
+ usb_dp_flipped = (cfg_pinflip_i ? ~usb_d_d : usb_d_d) & ~usb_se0_d;
+ usb_dn_flipped = (cfg_pinflip_i ? usb_d_d : ~usb_d_d) & ~usb_se0_d;
end
end
@@ -475,7 +473,7 @@
) u_usb_d_o_flop (
.clk_i,
.rst_ni,
- .d_i(usb_d_flipped),
+ .d_i(usb_dp_flipped), // Note: single-ended 'D' output mirrors D+
.q_o(usb_d_o)
);