usb3_core: first usb3_top simplifications to use USB3PIPE

This commit is contained in:
Florent Kermarrec 2019-11-22 09:51:17 +01:00
parent f926443335
commit 4d2adbd4bf
2 changed files with 45 additions and 315 deletions

View File

@ -9,6 +9,7 @@ from litex.soc.interconnect.csr import *
class USB3Core(Module, AutoCSR):
def __init__(self, platform):
self.reset = Signal()
self.sink = sink = stream.Endpoint([("data", 32), ("ctrl", 4)])
self.source = source = stream.Endpoint([("data", 32), ("ctrl", 4)])
@ -54,51 +55,18 @@ class USB3Core(Module, AutoCSR):
self.submodules.usb3_control = USB3Control()
phy_rx_status = Signal(6)
phy_phy_status = Signal(2)
dbg_pipe_state = Signal(6)
dbg_ltssm_state = Signal(5)
usb_pipe_status_phy_status = Signal()
self.specials += Tristate(usb_pipe_status.phy_status, 0, ~usb3_reset_n, usb_pipe_status_phy_status)
self.comb += usb3_reset_n.eq(self.usb3_control.phy_enable)
self.specials += Instance("usb3_top",
i_ext_clk = ClockSignal(),
i_reset_n = self.usb3_control.core_enable,
i_clk = ClockSignal(),
i_reset_n = ~self.reset,
i_phy_pipe_half_clk = 0, # FIXME
i_phy_pipe_half_clk_phase = 0, # FIXME,
i_phy_pipe_quarter_clk = 0, # FIXME,
i_in_data = sink.data,
i_in_datak = sink.ctrl,
i_in_active = sink.valid,
i_phy_pipe_rx_data = sink.data,
i_phy_pipe_rx_datak = sink.ctrl,
i_phy_pipe_rx_valid = sink.valid,
o_phy_pipe_tx_data = source.data, # FIXME use source.ready
o_phy_pipe_tx_datak = source.ctrl, # FIXME use source.ready
# FIXME: remove since USB3PIPE is handling this internally
#o_phy_reset_n = ,
#o_phy_out_enable = ,
#o_phy_phy_reset_n = ,
#o_phy_tx_detrx_lpbk = ,
#o_phy_tx_elecidle = ,
#io_phy_rx_elecidle = ,
#i_phy_rx_status = ,
#o_phy_power_down = ,
#i_phy_phy_status_i = ,
#o_phy_phy_status_o = ,
#i_phy_pwrpresent = ,
#o_phy_tx_oneszeros = ,
#o_phy_tx_deemph = ,
#o_phy_tx_margin = ,
#o_phy_tx_swing = ,
#o_phy_rx_polarity = ,
#o_phy_rx_termination = ,
#o_phy_rate = ,
#o_phy_elas_buf_mode = ,
o_out_data = source.data,
o_out_datak = source.datak,
o_out_active = source.valid,
i_out_stall = ~source.ready,
i_buf_in_addr = self.usb3_control.buf_in_addr,
i_buf_in_data = self.usb3_control.buf_in_data,
@ -109,19 +77,16 @@ class USB3Core(Module, AutoCSR):
i_buf_in_commit_len = self.usb3_control.buf_in_commit_len,
o_buf_in_commit_ack = self.usb3_control.buf_in_commit_ack,
i_buf_out_addr = self.usb3_control.buf_out_addr,
o_buf_out_q = self.usb3_control.buf_out_q,
o_buf_out_len = self.usb3_control.buf_out_len,
o_buf_out_hasdata = self.usb3_control.buf_out_hasdata,
i_buf_out_arm = self.usb3_control.buf_out_arm,
o_buf_out_arm_ack = self.usb3_control.buf_out_arm_ack,
i_buf_out_addr = self.usb3_control.buf_out_addr,
o_buf_out_q = self.usb3_control.buf_out_q,
o_buf_out_len = self.usb3_control.buf_out_len,
o_buf_out_hasdata = self.usb3_control.buf_out_hasdata,
i_buf_out_arm = self.usb3_control.buf_out_arm,
o_buf_out_arm_ack = self.usb3_control.buf_out_arm_ack,
#o_vend_req_act =,
#o_vend_req_request =,
#o_vend_req_val =,
#o_dbg_pipe_state = ,
#o_dbg_ltssm_state = ,
#o_vend_req_val =
)
daisho_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "daisho")
platform.add_verilog_include_path(os.path.join(daisho_path, "core"))

View File

@ -11,38 +11,17 @@
module usb3_top_usb3_pipe (
input wire ext_clk,
input wire clk,
input wire reset_n,
input wire phy_pipe_half_clk, // 125MHz: 1/2 PCLK
input wire phy_pipe_half_clk_phase, // 125MHz: 1/2 PCLK, phase shift 90
input wire phy_pipe_quarter_clk, // 62.5MHz: 1/4 PCLK
input wire [31:0] phy_pipe_rx_data,
input wire [3:0] phy_pipe_rx_datak,
input wire [1:0] phy_pipe_rx_valid,
output wire [31:0] phy_pipe_tx_data,
output wire [3:0] phy_pipe_tx_datak,
input wire [31:0] in_data,
input wire [3:0] in_datak,
input wire in_active,
output wire phy_reset_n,
output wire phy_out_enable,
output wire phy_phy_reset_n,
output wire phy_tx_detrx_lpbk,
output wire phy_tx_elecidle,
inout wire phy_rx_elecidle,
input wire [5:0] phy_rx_status,
output wire [1:0] phy_power_down,
input wire [1:0] phy_phy_status_i,
output wire phy_phy_status_o,
input wire phy_pwrpresent,
output wire phy_tx_oneszeros,
output wire [1:0] phy_tx_deemph,
output wire [2:0] phy_tx_margin,
output wire phy_tx_swing,
output wire phy_rx_polarity,
output wire phy_rx_termination,
output wire phy_rate,
output wire phy_elas_buf_mode,
output wire [31:0] out_data,
output wire [3:0] out_datak,
output wire out_active,
output wire out_stall,
input wire [8:0] buf_in_addr,
input wire [31:0] buf_in_data,
@ -62,246 +41,33 @@ output wire buf_out_arm_ack,
output wire vend_req_act,
output wire [7:0] vend_req_request,
output wire [15:0] vend_req_val,
output wire [5:0] dbg_pipe_state,
output wire [4:0] dbg_ltssm_state
output wire [15:0] vend_req_val
);
reg reset_1, reset_2; // local reset
wire local_reset = reset_n & phy_pwrpresent;
always @(posedge phy_pipe_half_clk ) begin
// synchronize external reset to local domain
{reset_2, reset_1} <= {reset_1, local_reset};
end
assign phy_reset_n = reset_n; // TUSB1310A has minimum 1uS pulse width for RESET
// responsibility of the toplevel module to supply this reset
// NOTE: reset entire phy will cause loss of PLL lock
assign phy_phy_reset_n = reset_n & phy_pwrpresent;
// reset the PHY along with all our core code if cable unplugged
assign phy_out_enable = 1'b1;
wire [1:0] mux_tx_margin;
parameter XTAL_SEL = 1'b0; // crystal input
parameter OSC_SEL = 1'b1; // clock input
parameter [2:0] SSC_DIS = 2'b11; // spread spectrum clock disable
parameter [2:0] SSC_EN = 2'b00; // spread spectrum clock enable
parameter PIPE_16BIT = 1'b0; // sdr 16bit pipe interface
// strap pins
assign phy_rx_elecidle = reset_2 ? 1'bZ : XTAL_SEL;
assign phy_tx_margin = reset_2 ? mux_tx_margin : SSC_DIS;
assign phy_phy_status_o = reset_2 ? 1'bZ : PIPE_16BIT;
////////////////////////////////////////////////////////////
//
// USB 3.0 PIPE3 interface
//
////////////////////////////////////////////////////////////
wire ltssm_reset_n;
usb3_pipe iu3p (
.slow_clk ( phy_pipe_quarter_clk ),
.local_clk ( phy_pipe_half_clk ),
.local_clk_capture ( phy_pipe_half_clk_phase ),
.reset_n ( reset_2 ),
.ltssm_reset_n ( ltssm_reset_n ),
.phy_pipe_rx_data ( phy_pipe_rx_data ),
.phy_pipe_rx_datak ( phy_pipe_rx_datak ),
.phy_pipe_rx_valid ( phy_pipe_rx_valid ),
.phy_pipe_tx_data ( phy_pipe_tx_data ),
.phy_pipe_tx_datak ( phy_pipe_tx_datak ),
.phy_tx_detrx_lpbk ( phy_tx_detrx_lpbk ),
.phy_tx_elecidle ( phy_tx_elecidle ),
.phy_rx_elecidle ( phy_rx_elecidle ),
.phy_rx_status ( phy_rx_status ),
.phy_power_down ( phy_power_down ),
.phy_phy_status ( phy_phy_status_i ),
.phy_pwrpresent ( phy_pwrpresent ),
.phy_tx_oneszeros ( phy_tx_oneszeros ),
.phy_tx_deemph ( phy_tx_deemph ),
.phy_tx_margin ( mux_tx_margin ),
.phy_tx_swing ( phy_tx_swing ),
.phy_rx_polarity ( phy_rx_polarity ),
.phy_rx_termination ( phy_rx_termination ),
.phy_rate ( phy_rate ),
.phy_elas_buf_mode ( phy_elas_buf_mode ),
.link_in_data ( link_in_data ),
.link_in_datak ( link_in_datak ),
.link_in_active ( link_in_active ),
.link_out_data ( link_out_data ),
.link_out_datak ( link_out_datak ),
.link_out_active ( link_out_active ),
.link_out_stall ( link_out_stall ),
.partner_detect ( partner_detect ),
.partner_looking ( partner_looking ),
.partner_detected ( partner_detected ),
.ltssm_tx_detrx_lpbk ( port_tx_detrx_lpbk ),
.ltssm_tx_elecidle ( port_tx_elecidle ),
.ltssm_power_down ( port_power_down ),
.ltssm_power_go ( port_power_go ),
.ltssm_power_ack ( port_power_ack ),
.ltssm_hot_reset ( ltssm_hot_reset ),
.ltssm_state ( ltssm_state ),
.ltssm_training ( ltssm_training ),
.ltssm_train_rxeq ( ltssm_train_rxeq ),
.ltssm_train_rxeq_pass ( ltssm_train_rxeq_pass ),
.ltssm_train_active ( ltssm_train_active ),
.ltssm_train_ts1 ( ltssm_train_ts1 ),
.ltssm_train_ts2 ( ltssm_train_ts2 ),
.ltssm_train_config ( ltssm_train_config ),
.ltssm_train_idle ( ltssm_train_idle ),
.ltssm_train_idle_pass ( ltssm_train_idle_pass ),
.lfps_recv_active ( lfps_recv_active ),
.lfps_recv_poll_u1 ( lfps_recv_poll_u1 ),
.lfps_recv_ping ( lfps_recv_ping ),
.lfps_recv_reset ( lfps_recv_reset ),
.lfps_recv_u2lb ( lfps_recv_u2lb ),
.lfps_recv_u3 ( lfps_recv_u3 ),
.dbg_state ( dbg_pipe_state )
);
////////////////////////////////////////////////////////////
//
// USB 3.0 LTSSM, LFPS
//
////////////////////////////////////////////////////////////
wire [4:0] ltssm_state;
wire port_rx_term;
wire port_tx_detrx_lpbk;
wire port_tx_elecidle;
wire [1:0] port_power_down;
wire port_power_go;
wire port_power_ack;
wire port_power_err;
wire ltssm_hot_reset;
wire ltssm_training;
wire ltssm_train_rxeq;
wire ltssm_train_rxeq_pass;
wire ltssm_train_active;
wire ltssm_train_ts1;
wire ltssm_train_ts2;
wire ltssm_train_config;
wire ltssm_train_idle;
wire ltssm_train_idle_pass;
wire partner_detect;
wire partner_looking;
wire partner_detected;
wire lfps_recv_active;
wire lfps_recv_poll_u1;
wire lfps_recv_ping;
wire lfps_recv_reset;
wire lfps_recv_u2lb;
wire lfps_recv_u3;
wire ltssm_warm_reset;
usb3_ltssm iu3lt (
.slow_clk ( phy_pipe_quarter_clk ),
.local_clk ( phy_pipe_half_clk ),
.reset_n ( ltssm_reset_n ),
// inputs
.vbus_present ( phy_pwrpresent ),
.port_rx_valid ( phy_pipe_rx_valid ), // these signals are in the 250mhz source
.port_rx_elecidle ( phy_rx_elecidle ), // domain, but no problem for lfps in 62.5mhz
.partner_looking ( partner_looking ),
.partner_detected ( partner_detected ),
.port_power_state ( phy_power_down ), // reflect actual value driven by PIPE pd_fsm
.port_power_ack ( port_power_ack ),
.port_power_err ( port_power_err ),
.train_rxeq_pass ( ltssm_train_rxeq_pass ),
.train_idle_pass ( ltssm_train_idle_pass ),
.train_ts1 ( ltssm_train_ts1 ),
.train_ts2 ( ltssm_train_ts2 ),
.go_disabled ( ltssm_go_disabled ),
.go_recovery ( ltssm_go_recovery ),
.go_u ( ltssm_go_u ),
.hot_reset ( ltssm_hot_reset ),
// outputs
.ltssm_state ( ltssm_state ),
.port_rx_term ( port_rx_term ),
.port_tx_detrx_lpbk ( port_tx_detrx_lpbk ),
.port_tx_elecidle ( port_tx_elecidle ),
.port_power_down ( port_power_down ),
.port_power_go ( port_power_go ),
.partner_detect ( partner_detect ),
.training ( ltssm_training ),
.train_rxeq ( ltssm_train_rxeq ),
.train_active ( ltssm_train_active ),
.train_config ( ltssm_train_config ),
.train_idle ( ltssm_train_idle ),
.lfps_recv_active ( lfps_recv_active ),
.lfps_recv_poll_u1 ( lfps_recv_poll_u1 ),
.lfps_recv_ping ( lfps_recv_ping ),
.lfps_recv_reset ( lfps_recv_reset ),
.lfps_recv_u2lb ( lfps_recv_u2lb ),
.lfps_recv_u3 ( lfps_recv_u3 ),
.warm_reset ( ltssm_warm_reset ),
.dbg_state ( dbg_ltssm_state )
);
////////////////////////////////////////////////////////////
//
// USB 3.0 Link layer interface
//
////////////////////////////////////////////////////////////
wire [31:0] link_in_data;
wire [3:0] link_in_datak;
wire link_in_active;
wire [31:0] link_out_data;
wire [3:0] link_out_datak;
wire link_out_active;
wire link_out_stall;
wire ltssm_go_disabled;
wire ltssm_go_recovery;
wire [2:0] ltssm_go_u;
usb3_link iu3l (
.local_clk ( phy_pipe_half_clk ),
.reset_n ( reset_2 ),
.local_clk ( clk ),
.reset_n ( reset_n ),
.ltssm_state ( ltssm_state ),
.ltssm_hot_reset ( ltssm_hot_reset ),
.ltssm_go_disabled ( ltssm_go_disabled ),
.ltssm_go_recovery ( ltssm_go_recovery ),
.ltssm_go_u ( ltssm_go_u),
.in_data ( link_in_data ),
.in_datak ( link_in_datak ),
.in_active ( link_in_active ),
.ltssm_state ( ), // FIXME
.ltssm_hot_reset ( ), // FIXME
.ltssm_go_disabled ( ),
.ltssm_go_recovery ( ),
.ltssm_go_u ( ),
.in_data ( in_data ),
.in_datak ( in_datak ),
.in_active ( in_active ),
.outp_data ( link_out_data ),
.outp_datak ( link_out_datak ),
.outp_active ( link_out_active ),
.out_stall ( link_out_stall ),
.outp_data ( out_data ),
.outp_datak ( out_datak ),
.outp_active ( out_active ),
.out_stall ( out_stall ),
.endp_mode_rx ( prot_endp_mode_rx ),
.endp_mode_tx ( prot_endp_mode_tx ),
@ -386,7 +152,6 @@ usb3_link iu3l (
);
////////////////////////////////////////////////////////////
//
// USB 3.0 Protocol layer interface
@ -482,12 +247,12 @@ usb3_link iu3l (
usb3_protocol iu3r (
.local_clk ( phy_pipe_half_clk ),
.slow_clk ( phy_pipe_quarter_clk ),
.ext_clk ( ext_clk ),
.local_clk ( clk ), // FIXME ?
.slow_clk ( clk ), // FIXME ?
.ext_clk ( clk ), // FIXME ?
.reset_n ( reset_2 | ~ltssm_warm_reset),
.ltssm_state ( ltssm_state ),
.reset_n ( reset_n),
.ltssm_state ( ), // FIXME
// muxed endpoint signals
.endp_mode_rx ( prot_endp_mode_rx ),