Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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.



46 changes: 9 additions & 37 deletions examples/protocols/pcie/pcie-main.stanza
Original file line number Diff line number Diff line change
Expand Up @@ -24,53 +24,25 @@ 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
; tx.
; Notice that the `reverse-pcie-lane` function handles the null-modem
; swap. We continue to use `tx => tx` and `rx => rx` inside for
; consistency.
require src-IC : pcie(2, PCIe-PRSNT#) from dut1
require dst-IC : pcie(2, PCIe-PRSNT#) from dut2
require src-IC : pcie-with-hotplug(1) from dut1
require dst-IC : pcie-with-hotplug(1) from dut2

; TODO - the routing structure is not applying through the node here.

within [src, dst-straight] = constrain-topology(src-IC, dst-IC, cst):
; Notice that the `reverse-pcie-lane` function handles the null-modem
; swap. We continue to use `tx => tx` and `rx => rx` inside for
; consistency.
val dst = reverse-pcie-lanes(dst-straight)
within [src, dst] = constrain-topology(src-IC, dst-IC, cst):
for i in indices(src.data.lane) do:
; We reverse the Tx/Rx in a null-modem style for active->active connection.
val lane-Rx = dst.data.lane[i].TX
val lane-Tx = dst.data.lane[i].RX

inst tx-coupler : dp-coupler(b-cap)
topo-pair(src.data.lane[i].TX => tx-coupler => dst.data.lane[i].TX)
topo-pair(src.data.lane[i].TX => tx-coupler => lane-Tx)
inst rx-coupler : dp-coupler(b-cap)
topo-pair(src.data.lane[i].RX => rx-coupler => dst.data.lane[i].RX)
topo-pair(src.data.lane[i].RX => rx-coupler => lane-Rx)

topo-net(src.data.refclk => dst.data.refclk)
net (src.control, dst.control)
Expand Down
79 changes: 79 additions & 0 deletions examples/protocols/pcie/pcie-shared-wake.stanza
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#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 conns : jsl/examples/protocols/pcie/pcie-conn/module[2]

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
val pcie-btype = pcie-std(2)
for i in 0 to 2 do:
require dst-ep : pcie-btype from conns[i]
require src-ep : pcie-btype from dut1

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.PERST#, dst.control.PERST#)
net (src.control.CLKREQ#, dst.control.CLKREQ#)

; Notice that this is a direct connection that doesn't use
; the pin assigned bundles. This is how we make a shared
; connection. It must be out of band from the pin assignment solution.
; Note that this will not work for topologies with the `constrain-topology`
; structure unless you make a custom `SI-Constraint` object that is aware
; of the shared topology and then apply constraints from the top level.
net (dut1.shared_wake, dst.control.PEWAKE#)




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)
Loading