Skip to content

Commit

Permalink
Merge pull request #123 from enjoy-digital/xilinx_us_cleanup
Browse files Browse the repository at this point in the history
Cleanup Xilinx US/USP PHY integration.
  • Loading branch information
enjoy-digital authored Nov 10, 2023
2 parents 5e3383c + 9e0a01e commit 76c7381
Show file tree
Hide file tree
Showing 38 changed files with 3,167 additions and 11,920 deletions.
6 changes: 4 additions & 2 deletions bench/fk33.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ def __init__(self, platform, sys_clk_freq):
class LitePCIeSoC(SoCMini):
configs = {
# Gen3 data_width, sys_clk_freq
"gen3:x4": (128, int(200e6)),
"gen3:x4" : (128, int(200e6)),
"gen3:x8" : (256, int(200e6)),
"gen3:x16": (512, int(200e6)),
}
def __init__(self, platform, speed="gen3", nlanes=4):
data_width, sys_clk_freq = self.configs[speed + f":x{nlanes}"]
Expand Down Expand Up @@ -112,7 +114,7 @@ def main():
parser.add_argument("--driver", action="store_true", help="Generate LitePCIe driver")
parser.add_argument("--load", action="store_true", help="Load bitstream (to SRAM)")
parser.add_argument("--speed", default="gen3", help="PCIe speed: gen3")
parser.add_argument("--nlanes", default=4, help="PCIe lanes: 4 (default) or 8")
parser.add_argument("--nlanes", default=4, help="PCIe lanes: 4 (default), 8 or 16")
args = parser.parse_args()

platform = sqrl_fk33.Platform()
Expand Down
2 changes: 1 addition & 1 deletion bench/xcu1525.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def main():
parser.add_argument("--driver", action="store_true", help="Generate LitePCIe driver")
parser.add_argument("--load", action="store_true", help="Load bitstream (to SRAM)")
parser.add_argument("--speed", default="gen3", help="PCIe speed: gen3")
parser.add_argument("--nlanes", default=4, help="PCIe lanes: 4 (default) or 8")
parser.add_argument("--nlanes", default=4, help="PCIe lanes: 4 (default), 8 or 16")
args = parser.parse_args()

platform = sqrl_xcu1525.Platform()
Expand Down
63 changes: 55 additions & 8 deletions litepcie/phy/uspciephy.py
Original file line number Diff line number Diff line change
Expand Up @@ -377,9 +377,60 @@ def add_ltssm_tracer(self):
self.ltssm_tracer = LTSSMTracer(self._link_status.fields.ltssm)

# Hard IP sources ------------------------------------------------------------------------------
def add_sources(self, platform, phy_path, phy_filename):
platform.add_ip(os.path.join(phy_path, phy_filename))
platform.add_source(os.path.join(phy_path, "pcie_us_support.v"))
def add_sources(self, platform, phy_path=None, phy_filename=None):
if phy_filename is not None:
platform.add_ip(os.path.join(phy_path, phy_filename))
else:
# FIXME: Add missing parameters?
config = {
# Generic Config.
# ---------------
"Component_Name" : "pcie_us",
"PL_LINK_CAP_MAX_LINK_WIDTH" : f"X{self.nlanes}",
"PL_LINK_CAP_MAX_LINK_SPEED" : "8.0_GT/s", # CHECKME.
"axisten_if_width" : f"{self.pcie_data_width}_bit",
"AXISTEN_IF_RC_STRADDLE" : True,
"PF0_DEVICE_ID" : 8030 + self.nlanes,
"axisten_freq" : 250, # CHECKME.
"axisten_if_enable_client_tag" : True,
"aspm_support" : "No_ASPM",
"coreclk_freq" : 500, # CHECKME.
"plltype" : "QPLL1",

# BAR0 Config.
# ------------
"pf0_bar0_scale" : "Megabytes", # FIXME.
"pf0_bar0_size" : max(self.bar0_size/MB, 1), # FIXME.

# Interrupt Config.
# -----------------
"PF0_INTERRUPT_PIN" : "NONE",
}
ip_tcl = []
ip_tcl.append("create_ip -vendor xilinx.com -name pcie3_ultrascale -module_name pcie_us")
ip_tcl.append("set obj [get_ips pcie_us]")
ip_tcl.append("set_property -dict [list \\")
for config, value in config.items():
ip_tcl.append("CONFIG.{} {} \\".format(config, '{{' + str(value) + '}}'))
ip_tcl.append(f"] $obj")
ip_tcl.append("synth_ip $obj")
platform.toolchain.pre_synthesis_commands += ip_tcl

verilog_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "xilinx_us")
platform.add_source(os.path.join(verilog_path, "axis_iff.v"))
if self.nlanes == 4:
platform.add_source(os.path.join(verilog_path, "s_axis_rq_adapt_x4.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_rc_adapt_x4.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_cq_adapt_x4.v"))
platform.add_source(os.path.join(verilog_path, "s_axis_cc_adapt_x4.v"))

if self.nlanes == 8:
platform.add_source(os.path.join(verilog_path, "s_axis_rq_adapt_x8.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_rc_adapt_x8.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_cq_adapt_x8.v"))
platform.add_source(os.path.join(verilog_path, "s_axis_cc_adapt_x8.v"))

platform.add_source(os.path.join(verilog_path, "pcie_us_support.v"))

# External Hard IP -----------------------------------------------------------------------------
def use_external_hard_ip(self, hard_ip_path, hard_ip_filename):
Expand All @@ -389,9 +440,5 @@ def use_external_hard_ip(self, hard_ip_path, hard_ip_filename):
# Finalize -------------------------------------------------------------------------------------
def do_finalize(self):
if not self.external_hard_ip:
phy_path = "xilinx_us_{}_x{}".format(self.speed, self.nlanes)
self.add_sources(self.platform,
phy_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), phy_path),
phy_filename = "pcie_us.xci"
)
self.add_sources(self.platform)
self.specials += Instance("pcie_support", **self.pcie_phy_params)
74 changes: 62 additions & 12 deletions litepcie/phy/usppciephy.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@

from migen import *

from litex.gen import *

from litex.soc.interconnect.csr import *

from litepcie.common import *
Expand Down Expand Up @@ -376,9 +378,65 @@ def add_ltssm_tracer(self):
self.ltssm_tracer = LTSSMTracer(self._link_status.fields.ltssm)

# Hard IP sources ------------------------------------------------------------------------------
def add_sources(self, platform, phy_path, phy_filename):
platform.add_ip(os.path.join(phy_path, phy_filename))
platform.add_source(os.path.join(phy_path, "pcie_usp_support.v"))
def add_sources(self, platform, phy_path=None, phy_filename=None, hbm=False):
if phy_filename is not None:
platform.add_ip(os.path.join(phy_path, phy_filename))
else:
# FIXME: Add missing parameters?
config = {
# Generic Config.
# ---------------
"Component_Name" : "pcie_usp",
"PL_LINK_CAP_MAX_LINK_WIDTH" : f"X{self.nlanes}",
"PL_LINK_CAP_MAX_LINK_SPEED" : "8.0_GT/s", # CHECKME.
"axisten_if_width" : f"{self.pcie_data_width}_bit",
"AXISTEN_IF_RC_STRADDLE" : True,
"PF0_DEVICE_ID" : 9030 + self.nlanes,
"axisten_freq" : 250, # CHECKME.
"axisten_if_enable_client_tag" : True,
"aspm_support" : "No_ASPM",
"coreclk_freq" : 500, # CHECKME.
"plltype" : "QPLL1",

# BAR0 Config.
# ------------
"pf0_bar0_scale" : "Megabytes", # FIXME.
"pf0_bar0_size" : max(self.bar0_size/MB, 1), # FIXME.

# Interrupt Config.
# -----------------
"PF0_INTERRUPT_PIN" : "NONE",
}
ip_tcl = []
ip_name = {False: "pcie4_uscale_plus", True: "pcie4c_uscale_plus"}[hbm]
ip_tcl.append(f"create_ip -vendor xilinx.com -name {ip_name} -module_name pcie_usp")
ip_tcl.append("set obj [get_ips pcie_usp]")
ip_tcl.append("set_property -dict [list \\")
for config, value in config.items():
ip_tcl.append("CONFIG.{} {} \\".format(config, '{{' + str(value) + '}}'))
ip_tcl.append(f"] $obj")
ip_tcl.append("synth_ip $obj")
platform.toolchain.pre_synthesis_commands += ip_tcl

verilog_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), "xilinx_usp")
platform.add_source(os.path.join(verilog_path, "axis_iff.v"))
if self.nlanes == 4:
platform.add_source(os.path.join(verilog_path, "s_axis_rq_adapt_x4.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_rc_adapt_x4.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_cq_adapt_x4.v"))
platform.add_source(os.path.join(verilog_path, "s_axis_cc_adapt_x4.v"))
if self.nlanes == 8:
platform.add_source(os.path.join(verilog_path, "s_axis_rq_adapt_x8.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_rc_adapt_x8.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_cq_adapt_x8.v"))
platform.add_source(os.path.join(verilog_path, "s_axis_cc_adapt_x8.v"))
if self.nlanes == 16:
platform.add_source(os.path.join(verilog_path, "s_axis_rq_adapt_x16.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_rc_adapt_x16.v"))
platform.add_source(os.path.join(verilog_path, "m_axis_cq_adapt_x16.v"))
platform.add_source(os.path.join(verilog_path, "s_axis_cc_adapt_x16.v"))

platform.add_source(os.path.join(verilog_path, "pcie_usp_support.v"))

# External Hard IP -----------------------------------------------------------------------------
def use_external_hard_ip(self, hard_ip_path, hard_ip_filename):
Expand All @@ -388,15 +446,7 @@ def use_external_hard_ip(self, hard_ip_path, hard_ip_filename):
# Finalize -------------------------------------------------------------------------------------
def do_finalize(self):
if not self.external_hard_ip:
phy_path = "xilinx_usp{}_{}_x{}".format(
"_hbm" if isinstance(self, USPHBMPCIEPHY) else "",
self.speed,
self.nlanes
)
self.add_sources(self.platform,
phy_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), phy_path),
phy_filename = "pcie_usp.xci"
)
self.add_sources(self.platform, hbm=isinstance(self, USPHBMPCIEPHY))
self.specials += Instance("pcie_support", **self.pcie_phy_params)

# USPHBMPCIEPHY ------------------------------------------------------------------------------------
Expand Down
111 changes: 111 additions & 0 deletions litepcie/phy/xilinx_us/axis_iff.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
// This file is part of LitePCIe.
//
// Copyright (c) 2020-2023 Enjoy-Digital <enjoy-digital.fr>
// SPDX-License-Identifier: BSD-2-Clause

module axis_iff
#(
parameter DAT_B = 32
)
(
input clk,
input rst,

input i_vld,
output o_rdy,
input i_sop,
input i_eop,
input [DAT_B-1:0] i_dat,


output o_vld,
input i_rdy,
output o_sop,
output o_eop,
output [DAT_B-1:0] o_dat
);

///////////////////////////////////////////////////////////////////////////
//FIFO instance
localparam FF_B = 8;
localparam FF_L = 256;

wire ff_empt, ff_full;
reg [FF_B:0] ff_len;

wire ff_wr, ff_rd;

reg [FF_B-1:0] wrcnt;
always @(posedge clk)
if (rst) wrcnt <= {FF_B{1'b0}};
else if (ff_wr) wrcnt <= wrcnt + 1;

always @(posedge clk)
if (rst) ff_len <= {FF_B+1{1'b0}};
else
case ({ff_wr, ff_rd})
2'b10: ff_len <= ff_len + 1;
2'b01: ff_len <= ff_len - 1;
default: ff_len <= ff_len;
endcase

wire [FF_B-1:0] rdcnt;
assign rdcnt = wrcnt - ff_len[FF_B-1:0];

wire [FF_B-1:0] rda, wra;
assign rda = ff_rd ? (rdcnt + 1) : rdcnt;
assign wra = wrcnt;

wire [DAT_B+1:0] ff_wdat;
wire [DAT_B+1:0] ff_rdat;
assign ff_wdat = {i_sop, i_eop, i_dat};
assign {o_sop, o_eop, o_dat} = ff_rdat;
assign o_rdy = !(ff_len[FF_B] | pktcnt[3]);
assign o_vld = (pktcnt > 0);

reg [3:0] pktcnt;
assign ff_wr = i_vld & (!(ff_len[FF_B] | pktcnt[3]));
assign ff_rd = i_rdy & (pktcnt > 0);

///////////////////////////////////////////////////////////////////////////
//Single dual port RAM 1-clock

(* ram_style="block" *)
reg [DAT_B+1:0] ram [FF_L-1:0];

always @(posedge clk)
if (ff_wr) ram[wra] <= ff_wdat;

reg [DAT_B+1:0] ff_rdat_m;
always @(posedge clk)
ff_rdat_m <= ram[rda];

///////////////////////////////////////////////////////////////////////////
//same read/write

wire readsame = ff_wr & (wra == rda);
reg readsame1;
always @(posedge clk)
if (rst) readsame1 <= 1'b0;
else readsame1 <= readsame;

reg [DAT_B+1:0] ff_wdat1;
always @(posedge clk)
ff_wdat1 <= ff_wdat;

assign ff_rdat = readsame1 ? ff_wdat1 : ff_rdat_m;

///////////////////////////////////////////////////////////////////////////
//Store max 8 packet

always @(posedge clk)
if (rst) pktcnt <= 4'd0;
else begin
case ({(ff_wr & i_eop), (ff_rd & o_eop)})
2'b10: pktcnt <= pktcnt + 1;
2'b01: pktcnt <= pktcnt - 1;
default: pktcnt <= pktcnt;
endcase
end

endmodule
Loading

0 comments on commit 76c7381

Please sign in to comment.