Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to the PCIe interface to allow for shared control signals #234

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 155 additions & 0 deletions examples/protocols/pcie/pcie-conn.stanza
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
#use-added-syntax(jitx)
defpackage jsl/examples/protocols/pcie/pcie-conn :
import core
import jitx
import jitx/commands

import jsl

; This is primarily just a placeholder for a
; real PCIe connector.
val SSOP-pkg = SOP(
num-leads = 32,
lead-profile = Lead-Profile(
span = min-max(6.2, 6.6),
pitch = 0.65,
lead = SOP-Lead(
length = min-max(0.5, 0.75),
width = min-max(0.19, 0.3)
)
),
package-body = PackageBody(
width = min-max(4.3, 4.5)
length = min-max(4.9, 5.1)
height = min-max(1.0, 1.2)
),
density-level = DensityLevelC
)



public pcb-component component :
reference-prefix = "J"
mpn = "JITX002"
description = "Dummy PCIe Connector with multiple PCIe supports"

port REFCLK : diff-pair
port LANE : lane-pair[4]

pin-properties :
[pin:Ref | pads:Int ... ]

[REFCLK.N | 1 ]
[REFCLK.P | 2 ]
[GND[0] | 3 ]

[LANE[0].TX.P | 4 ]
[LANE[0].TX.N | 5 ]
[GND[1] | 6 ]
[LANE[0].RX.P | 7 ]
[LANE[0].RX.N | 8 ]
[GND[2] | 9 ]

[LANE[1].TX.P | 10 ]
[LANE[1].TX.N | 11 ]
[GND[3] | 12 ]
[LANE[1].RX.P | 13]
[LANE[1].RX.N | 14 ]
[GND[4] | 15 ]
[PRSNT# | 16 ]

[GND[5] | 17 ]
[LANE[2].TX.P | 18 ]
[LANE[2].TX.N | 19 ]
[GND[6] | 20 ]
[LANE[2].RX.P | 21 ]
[LANE[2].RX.N | 22 ]
[GND[7] | 23 ]

[LANE[3].TX.P | 24 ]
[LANE[3].TX.N | 25 ]
[GND[8] | 26 ]
[LANE[3].RX.P | 27 ]
[LANE[3].RX.N | 28 ]
[GND[9] | 29 ]

[PERST# | 30 ]
[PEWAKE# | 31 ]
[CLKREQ# | 32 ]



val box = BoxSymbol(self)

set-side(Left, self.GND, self.PERST#, self.PEWAKE#, self.CLKREQ#, self.PRSNT#)
set-side(Right, self.LANE, self.REFCLK)

assign-symbol $ create-symbol(box)

val lp = create-landpattern(SSOP-pkg)
assign-landpattern(lp)


for i in 0 to 4 do :
diff-pin-model(self.LANE[i].TX.P, LANE[i].TX.N, delay = typ(10.0e-15) loss = typ(0.1))
diff-pin-model(self.LANE[i].RX.P, LANE[i].RX.N, delay = typ(10.0e-15) loss = typ(0.1))

diff-pin-model(self.REFCLK.P, self.REFCLK.N, delay = typ(10.0e-15) loss = typ(0.1))


doc: \<DOC>
Helper function for creating the necessary PCIe Supports Statements

The user must pass a bundle type, such as `pcie-std(<N>)` and
this will construct a supports statement that will connect
the bundle ports to the predefined `self.sw` instance of the
`compponent` connector.
<DOC>
defn connect_lanes (b:Bundle):
inside pcb-module:
supports b:
for i in indices(b.data.lane) do :
b.data.lane[i].RX.P => self.sw.LANE[i].RX.P
b.data.lane[i].RX.N => self.sw.LANE[i].RX.N
b.data.lane[i].TX.P => self.sw.LANE[i].TX.P
b.data.lane[i].TX.N => self.sw.LANE[i].TX.N
b.data.refclk.P => self.sw.REFCLK.P
b.data.refclk.N => self.sw.REFCLK.N

b.control.PEWAKE# => self.sw.PEWAKE#
b.control.PERST# => self.sw.PERST#
b.control.CLKREQ# => self.sw.CLKREQ#

if has-PRSNT#(b):
b.control.PRSNT# => self.sw.PRSNT#


doc: \<DOC>
PCIe Connector Module with Exposed Pin-Assigned PCIe ports

User must use:

```
inst dut : jsl/examples/protocols/pcie/pcie-conn/module
require pcie-1x:pcie-std(1) from dut
```

To access one of the PCIe interface.
<DOC>
public pcb-module module :

public inst sw : component

val bundle-types = [
pcie-std(4),
pcie-std(2),
pcie-std(1),
pcie-with-hotplug(4),
pcie-with-hotplug(2),
pcie-with-hotplug(1),
]

for btype in bundle-types do:
connect_lanes(btype)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, neat way to reduce typing.



25 changes: 0 additions & 25 deletions examples/protocols/pcie/pcie-main.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -24,31 +24,6 @@ pcb-module pcie-example :

val b-cap = block-cap(220.0e-9)

; Construct a typical passive connector setup
; for a 2 lane configuration. This means a
; straight through `tx => tx` and `rx => rx`
; configuration.

require src-ep : pcie(2) from dut1
require dst-ep : pcie(2) from dut2

within [src, dst] = constrain-topology(src-ep, dst-ep, cst):
; Here we construct the circuit topology for the link
; Note that we don't need to worry about any of the constraint
; application, as that is handled by the `PCIe-Constraint` type.
; You can add other components in the topology as you wish - below
; is a typical basic implementation.
for i in indices(src.data.lane) do:
inst tx-coupler : dp-coupler(b-cap)
topo-pair(src.data.lane[i].TX => tx-coupler => dst.data.lane[i].TX)
; No Blocking Caps on the Receive side.
topo-net(src.data.lane[i].RX => dst.data.lane[i].RX)

topo-net(src.data.refclk => dst.data.refclk)
; The control signals do not demand a topology so
; we just use a straight net connection.
net (src.control, dst.control)

; Setup an example of an active to active connection between
; two ICs (ie not to a connector). In this case, we need
; a null-modem style connection and blocking caps on both rx and
Expand Down
71 changes: 71 additions & 0 deletions examples/protocols/pcie/pcie-shared-wake.stanza
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#use-added-syntax(jitx)
defpackage jsl/examples/protocols/pcie/main:
import core
import collections
import jitx
import jitx/commands


import jsl

import jsl/examples/protocols/common/example-board
import jsl/examples/protocols/common/example-components
import jsl/examples/protocols/pcie/pcie-src


pcb-module pcie-example :

inst dut1 : jsl/examples/protocols/pcie/pcie-src/module
inst dut2 : jsl/examples/protocols/pcie/pcie-conn/module
inst dut3 : jsl/examples/protocols/pcie/pcie-conn/module
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dut3 not used? likely intended to be inst dut2 : jsl/examples/protocols/pcie/pcie-conn/module[2]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch 👍


val version = PCIE-V4
val trace-imped = pcie-get-trace-impedance(version)
val cst = PCIe-Constraint(version, diff(trace-imped))

val b-cap = block-cap(220.0e-9)

; Construct a typical passive connector setup
; for a 2 lane configuration. This means a
; straight through `tx => tx` and `rx => rx`
; configuration.
;
; The two connectors share the one wake pin from the IC source module

require src-ep : pcie-std(2) from dut1
require dst-ep : pcie-std(2)[2] from dut2

for i in 0 to 2 do:
within [src, dst] = constrain-topology(src-ep, dst-ep[i], cst):
; Here we construct the circuit topology for the link
; Note that we don't need to worry about any of the constraint
; application, as that is handled by the `PCIe-Constraint` type.
; You can add other components in the topology as you wish - below
; is a typical basic implementation.
for i in indices(src.data.lane) do:
inst tx-coupler : dp-coupler(b-cap)
topo-pair(src.data.lane[i].TX => tx-coupler => dst.data.lane[i].TX)
; No Blocking Caps on the Receive side.
topo-net(src.data.lane[i].RX => dst.data.lane[i].RX)

topo-net(src.data.refclk => dst.data.refclk)
; The control signals do not demand a topology so
; we just use a straight net connection.
net (src.control, dst.control)




set-current-design("pcie-example-2")
setup-board()
; Set the schematic sheet size
set-paper(ANSI-A)

; Set the top level module (the module to be compile into a schematic and PCB)
set-main-module(pcie-example)

; View the results
view-board()
view-schematic()
view-design-explorer()
; view-bom(BOM-STD)
67 changes: 48 additions & 19 deletions examples/protocols/pcie/pcie-src.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ public pcb-module module :

public inst sw : component

val bd-4x = pcie(4)
val bd-4x = pcie-std(4)
supports bd-4x :
for i in 0 to 4 do :
bd-4x.data.lane[i].RX.P => sw.PRXP[i]
Expand All @@ -153,7 +153,7 @@ public pcb-module module :
bd-4x.control.PERST# => sw.PERST#[0]
bd-4x.control.CLKREQ# => sw.GPIO[1]

val bd-4x-prsnt = pcie(4, PCIe-PRSNT#)
val bd-4x-prsnt = pcie-with-hotplug(4)
supports bd-4x-prsnt :
for i in 0 to 4 do :
bd-4x-prsnt.data.lane[i].RX.P => sw.PRXP[i]
Expand All @@ -168,29 +168,58 @@ public pcb-module module :
bd-4x-prsnt.control.PRSNT# => sw.GPIO[12]
bd-4x-prsnt.control.CLKREQ# => sw.GPIO[1]

; For the PCIe-2X, I'm going to demonstrate
; how to use a shared port WAKE pin across
; the different. This is common situation where
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the different. => the different endpoints.

; if we are not careful, we can run into an unsat
; condition. The key is to just not include the shared
; port in the pin assignment solution and backfill it
; in an external port where the fanout happens.

val pcie-2x-shared-wake = sw.GPIO[7]
val ctls-2x = [
[sw.GPIO[6], sw.GPIO[12], sw.GPIO[1]]
[sw.GPIO[7], sw.GPIO[13], sw.GPIO[2]]
[pcie-2x-shared-wake, sw.GPIO[12], sw.GPIO[1]]
[pcie-2x-shared-wake, sw.GPIO[13], sw.GPIO[2]]
]
val bd-2x = pcie(2)
; The internal bundle contains reset, and clock request
; but does not include the WAKE
val bd-2x-int = pcie(2, PCIe-PERST#, PCIe-CLKREQ#)
for j in 0 to 2 do:
supports bd-2x:
supports bd-2x-int:
val ch-offset = (2 * j)
for i in 0 to 2 do :
bd-2x.data.lane[i].RX.P => sw.PRXP[i + ch-offset]
bd-2x.data.lane[i].RX.N => sw.PRXN[i + ch-offset]
bd-2x.data.lane[i].TX.P => sw.PTXP[i + ch-offset]
bd-2x.data.lane[i].TX.N => sw.PTXN[i + ch-offset]
bd-2x.data.refclk.P => sw.REFCLKP[ch-offset]
bd-2x.data.refclk.N => sw.REFCLKN[ch-offset]
bd-2x-int.data.lane[i].RX.P => sw.PRXP[i + ch-offset]
bd-2x-int.data.lane[i].RX.N => sw.PRXN[i + ch-offset]
bd-2x-int.data.lane[i].TX.P => sw.PTXP[i + ch-offset]
bd-2x-int.data.lane[i].TX.N => sw.PTXN[i + ch-offset]
bd-2x-int.data.refclk.P => sw.REFCLKP[ch-offset]
bd-2x-int.data.refclk.N => sw.REFCLKN[ch-offset]

val [wake, present, clkreq] = ctls-2x[j]
val [_, present, clkreq] = ctls-2x[j]

bd-2x-int.control.PERST# => sw.PERST#[ch-offset]
bd-2x-int.control.CLKREQ# => clkreq

val bd-2x-ext = pcie-std(2)

; The external interface for the PCIe with Shared Wake is different
; from the other interfaces because it has to be implemented as an
; externally facing port instead of a `supports` statement.
; Fortunately, it still takes advantage of pin assignment and hides
; the details of the connection but requires a different connection
; method at the top-level.
port pcie-2x : bd-2x-ext[2]

for pt in indices(pcie-2x) do:
net (pcie-2x[pt].control.PEWAKE#, pcie-2x-shared-wake)

require pt-int : bd-2x-int from self
topo-net(pcie-2x[pt].data => pt-int.data)
net (pcie-2x[pt].control.PERST#, pt-int.control.PERST#)
net (pcie-2x[pt].control.CLKREQ#, pt-int.control.CLKREQ#)

bd-2x.control.PEWAKE# => wake
bd-2x.control.PERST# => sw.PERST#[ch-offset]
bd-2x.control.CLKREQ# => clkreq

val bd-2x-prsnt = pcie(2, PCIe-PRSNT#)
val bd-2x-prsnt = pcie-with-hotplug(2)
for j in 0 to 2 do:
supports bd-2x-prsnt:
val ch-offset = (2 * j)
Expand All @@ -209,7 +238,7 @@ public pcb-module module :
bd-2x-prsnt.control.PRSNT# => present
bd-2x-prsnt.control.CLKREQ# => clkreq

val bd-1x = pcie(1)
val bd-1x = pcie-std(1)
val ctls-1x = [
[sw.GPIO[8], sw.GPIO[12], sw.GPIO[1]],
[sw.GPIO[9], sw.GPIO[14], sw.GPIO[3]],
Expand All @@ -230,7 +259,7 @@ public pcb-module module :
bd-1x.control.PEWAKE# => wake
bd-1x.control.CLKREQ# => clkreq

val bd-1x-prsnt = pcie(1, PCIe-PRSNT#)
val bd-1x-prsnt = pcie-with-hotplug(1)
for j in 0 to 4 do:
supports bd-1x-prsnt:
bd-1x-prsnt.data.lane[0].RX.P => sw.PRXP[j]
Expand Down
Loading
Loading