From 6e7befa376b5dec2e57fe447499b7bfaf20fd47c Mon Sep 17 00:00:00 2001 From: Bhusan Gupta Date: Wed, 25 Sep 2024 14:30:54 -0700 Subject: [PATCH 1/8] initial file creation --- src/protocols/memory/ddr4.stanza | 266 +++++++++++++++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 src/protocols/memory/ddr4.stanza diff --git a/src/protocols/memory/ddr4.stanza b/src/protocols/memory/ddr4.stanza new file mode 100644 index 00000000..58c27b9b --- /dev/null +++ b/src/protocols/memory/ddr4.stanza @@ -0,0 +1,266 @@ +doc: \ +@brief DDR 4 + +DDR4 is a high speed memory protocol +@see https://en.wikipedia.org/wiki/DDR4_SDRAM + +This functions and definitions in this file support defining DDR4 +connections between microprocessors and memories in a board design. + + +#use-added-syntax(jitx) +defpackage jsl/protocols/memory/ddr4: + import core + import jitx + import jitx/commands + + import jsl/bundles + import jsl/errors + import jsl/ensure + import jsl/si + import jsl/pin-assignment + +doc: \ +@brief DDR4 Width enums +This is a fixed list of possible lane widths for DDR4 memory channels + +public pcb-enum jsl/protocols/memory/DDR4Width: + DDR4-x4 + DDR4-x8 + DDR4-x16 + +public defn DDR4-enum-to-int (en:jsl/protocols/memory/DDR4Width) -> Int: + switch(en) : + DDR4-x4 : 4 + DDR4-x8 : 8 + DDR4-x16 : 16 + +doc: \ +@brief DDR4 Bundle +One DDR4 bundle consists of the connections between an integrated memory controller and +one DDR4 memory chip. The overall memory connections consists of 4 separate channels. +@member control Control channel for DDR4 +@member data Four data channels for DDR4 + + +public defn ddr4 (width:jsl/protocols/memory/DDR4Width) : + val r-width = DDR4-enum-to-int(width) + ddr4-b(r-width) + +public pcb-bundle ddr4-b (width:Int) : + name = "DDR4" + description = "Double Data Rate 4 Dynamic Random-Access Memory protocol" + port data : ddr4-data-channel(width) ; + port control : ddr4-control-channel ; covers all A,B,C,D + +public pcb-bundle ddr4-data-channel (width:Int): + port DQ : pin[width]; + port DQS : diff-pair ; + +public pcb-bundle ddr4-control-channel : + port CK : diff-pair + port CKE : pin + port A : pin[[0 1 2 3 4 5 6 7 8 9 10 11 12 13 17]] + port ACT_n : pin + port BG : pin[2] + port BA : pin[2] + port CS_n : pin + port RAS_n : pin ; aka A[16] + port CAS_n : pin ; aka A[15] + port WE_n : pin ; aka A[14] + port RESET_n : pin + port ODT : pin + port PAR : pin + + +doc: \ +@brief Curated values for skew and loss of DDR4 channel +This is a helper function that returns the bounds on the intra-pair +skew timing and maximum loss as expected by the particular standard targeted by +the user. The values returned are a toleranced value with upper/lower limits for the +intra-pair skew and the maximum loss as a double representing dB. Some defaults in the +table are derived from the references listed below. + +1. Skew match between A[17] A[13:0] and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD +2. Skew match between RAS_n, CAS_n, WE_n, and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD +3. Skew match between BA[1:0], BG[1:0] and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD +4. Skew match between ACT_n, CKE, CS_n, ODT, PAR and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD +5. Skew match between CMD/ADDR/CTRL within a channel is 0.0 +/- 20e-12 (20 ps) Intel +6. Skew match of CK is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD +7. Skew match of DQS is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD +8. Skew match between DQ and DQS.P is 0.0 +/- 3.5e-12 (3.5 ps) Intel or 0.0 +/- 100.0e-12 (100 ps) AMD +9. Skew match between CK.P and DQS.P is -85 ps to 935 ps Intel or -149 ps to +1796 ps AMD + +Intel derived from https://www.intel.com/content/www/us/en/docs/programmable/683216/23-2-2-7-1/skew-matching-guidelines-for-ddr4-discrete.html +AMD derived from https://docs.amd.com/r/en-US/ug863-versal-pcb-design/Timing-Constraint-Rules-for-DDR4-Signals +for the DDR4 component table + +Calculating the distance to time correspondence depends on the board material. +Example: + tpd 147 ps/in 170 ps/in -> 147 fs/mil to 170 fs/mil + @ 5 mils spec'ed that is a intra-pair skew of 750 fs to 850 fs + @ 10 mils spec'ed that is a intra-pair skew of 1.50 ps to 1.70 ps + + + +doc: \ +@brief Differential impedance specified by the DDR4 standard +This is a helper function that returns the expected differential +trace impedance for the standard. + +@return Upper/lower limits for the impedance. + +public defn ddr4-get-trace-impedance () -> [Toleranced, Toleranced] : + [100.0 +/- (5 %) 50.0 +/- (5 %)] + + +doc: \ +DDR4 SI Constraint Type + +This derives from the whole data lane constraint +as most of the controlled signals are single-ended but referenced to the +read and write clock lane pairs (tx/rx). All of these constraints +will be applied to the full lane. + 0.0 +/- 10.0e-15, ; Skew match for RCK_P RCK_N is 0.0 +/- 10.0e-15 (10 fs) + 0.0 +/- 10.0e-15, ; Skew match for WCK_P WCK_N is 0.0 +/- 10.0e-15 (10 fs) + 0.0 +/- 20.0e-12, ; Skew match between RCK and WCK is 0.0 +/- 20.0e-12 (20 ps) + 0.0 +/- 20.0e-12, ; Skew match between WCK and CA (per channel A,B,C,D) is 0.0 +/- 20.0e-12 (20 ps) + 0.0 +/- 20.0e-12, ; Skew match between RCK and DQ and DQE (per channel A,B,C,D) is 0.0 +/- 20.0e-12 (20 p + 0.0 +/- 20.0e-12, ; Skew match between WCK and DQ and DQE (per channel A,B,C,D) is 0.0 +/- 20.0e-12 (20 p + 0.0 +/- 5.0e-12, ; Skew match between DQ and DQE (per channel A,B,C,D) is 0.0 +/- 5.0e-12 (5 ps) + 0.0 +/- 100.0e-12,; Skew match between Reset and CA (per channel A,B,C,D) is 0.0 +/- 100.0e-12 (100ps) + 0.0 +/- 100.0e-12,; Skew match between ERR and WCK (per channel A,B,C,D) is 0.0 +/- 100.0e-12 (100 ps) + 0.0 +/- 5.0e-12, ; Skew match between CA (per channel A,B,C,D) is 0.0 +/- 5.0e-12 (5ps) + +The `constrain` function for this type expects two compatible `ddr4-b` types. + +public defstruct DDR4-Constraint <: SI-Constraint : + doc: \ + RCK Intra-pair Timing Skew Constraint in Seconds + + skew-rck:Toleranced with : + default => 0.0 +/- 10.0e-15 + doc: \ + WCK Intra-pair Timing Skew Constraint in Seconds + + skew-wck:Toleranced with : + default => 0.0 +/- 10.0e-15 + doc: \ + RCK to WCK Inter-pair Timing Skew Constraint in Seconds + + skew-rck-wck:Toleranced with : + default => 0.0 +/- 20.0e-12 + doc: \ + WCK to CA Inter-signal Timing Skew Constraint in Seconds + + skew-wck-ca:Toleranced with : + default => 0.0 +/- 20.0e-12 + doc: \ + RCK to DQ/DQE Inter-pair Timing Skew Constraint in Seconds + + skew-rck-dq:Toleranced with : + default => 0.0 +/- 20.0e-12 + doc: \ + WCK to DQ/DQE Inter-pair Timing Skew Constraint in Seconds + + skew-wck-dq:Toleranced with: + default => 0.0 +/- 20.0e-12 + doc: \ + DQ and DQE Inter-pair Timing Skew Constraint in Seconds + + skew-dq:Toleranced with: + default => 0.0 +/- 5.0e-12 + doc: \ + Reset to CA Inter-pair Timing Skew Constraint in Seconds + + skew-rst-ca:Toleranced with: + default => 0.0 +/- 100.0e-12 + doc: \ + ERR and WCK Inter-pair Timing Skew Constraint in Seconds + + skew-err-wck:Toleranced with: + default => 0.0 +/- 100.0e-12 + doc: \ + CA Inter-pair Timing Skew Constraint in Seconds + + skew-ca:Toleranced with: + default => 0.0 +/- 5.0e-12 + doc: \ + Diff-Pair Max Loss Limit Constraint in dB + + loss:Double with: + ensure => ensure-positive!, + default => 5.0 + doc: \ + Differential Routing Structure for each Diff-Pair + + diff-route-struct:DifferentialRoutingStructure + doc: \ + Single-Ended Routing Structure for each SE signal + + se-route-struct:RoutingStructure +with: + keyword-constructor => true + constructor => #DDR4-Constraint + +doc: \ +Constructor for the DDR4 Link Constraint + +@param rs Differential Routing Structure constraints for all +data lane signals, command/address, and the differential write and read clocks. +This is not applied to the control signals. + +public defn DDR4-Constraint (diff-rs:DifferentialRoutingStructure rs:RoutingStructure) -> DDR4-Constraint: + DDR4-Constraint( + diff-route-struct = diff-rs + se-route-struct = rs + ) + +doc: \ +Constrain a DDR4 Link + +@param cst Constraint Object +@param src Source End Point - must be of `ddr4-b` type +@param dst Destination End Point - must be of `ddr4-b` type and match +the parameterization of `src`, including lane counts. + +public defmethod constrain (cst:DDR4-Constraint, src:JITXObject, dst:JITXObject) -> False : + inside pcb-module: + val cst-rck = DiffPair-Constraint(skew = skew-rck(cst) loss = loss(cst) route-struct = diff-route-struct(cst)) + val cst-wck = DiffPair-Constraint(skew = skew-wck(cst) loss = loss(cst) route-struct = diff-route-struct(cst)) + val guide-rck = src.data[0].RCK.P => dst.data[0].RCK.P + val guide-reset = src.control.RESET_n => dst.control.RESET_n + structure(guide-reset) = se-route-struct(cst) + + for i in 0 to 4 do : + diffpair-constrain(cst-rck, src.data[i].RCK dst.data[i].RCK) + diffpair-constrain(cst-wck, src.data[i].WCK dst.data[i].WCK) + timing-window(skew-rck-wck(cst) guide-rck src.data[i].RCK.P => dst.data[i].RCK.P) + timing-window(skew-rck-wck(cst) guide-rck src.data[i].WCK.P => dst.data[i].WCK.P) + val guide-rck-chan = src.data[i].RCK.P => dst.data[i].RCK.P + val guide-wck-chan = src.data[i].WCK.P => dst.data[i].WCK.P + val guide-dq = src.data[i].DQ[0] => dst.data[i].DQ[0] + val dq-bus = to-tuple $ cat{_, [src.data[i].DQE => dst.data[i].DQE]} $ for j in 0 to 10 seq : src.data[i].DQ[j] => dst.data[i].DQ[j] + timing-window(skew-rck-dq(cst) guide-rck-chan topos = dq-bus) + timing-window(skew-wck-dq(cst) guide-wck-chan topos = dq-bus) + timing-window(skew-dq(cst) guide-dq topos = dq-bus) + timing-window(skew-err-wck(cst), guide-wck-chan src.data[i].ERR => dst.data[i].ERR) + val ca-bus = to-tuple $ for j in 0 to 5 seq : src.data[i].CA[j] => dst.data[i].CA[j] + val guide-ca = src.data[i].CA[0] => dst.data[i].CA[0] + timing-window(skew-wck-ca(cst), guide-wck-chan topos = ca-bus) + timing-window(skew-rst-ca(cst), guide-reset topos = ca-bus) + timing-window(skew-ca(cst), guide-ca topos = ca-bus) + + structure(src.data[i].DQ, dst.data[i].DQ) = se-route-struct(cst) + structure(src.data[i].DQE, dst.data[i].DQE) = se-route-struct(cst) + structure(src.data[i].CA, dst.data[i].CA) = se-route-struct(cst) + structure(src.data[i].ERR, dst.data[i].ERR) = se-route-struct(cst) + max-loss(loss(cst), src.data[i].DQ => dst.data[i].DQ) + max-loss(loss(cst), src.data[i].DQE => dst.data[i].DQE) + max-loss(loss(cst), src.data[i].CA => dst.data[i].CA) + max-loss(loss(cst), src.data[i].ERR => dst.data[i].ERR) + +public defn connect-DDR4 (src:JITXObject dst:JITXObject diff-rs:DifferentialRoutingStructure rs:RoutingStructure) : + inside pcb-module : + val ddr4-cst = DDR4-Constraint(diff-rs, rs) + constrain-topology(src, dst, ddr4-cst) From f95231c28957b3c0de44ccef75d290265413757c Mon Sep 17 00:00:00 2001 From: Bhusan Gupta Date: Thu, 3 Oct 2024 06:07:20 -0700 Subject: [PATCH 2/8] simple check point --- src/protocols/memory/ddr4.stanza | 288 ++++++++++++++++++++++--------- 1 file changed, 209 insertions(+), 79 deletions(-) diff --git a/src/protocols/memory/ddr4.stanza b/src/protocols/memory/ddr4.stanza index 58c27b9b..79b7a1a2 100644 --- a/src/protocols/memory/ddr4.stanza +++ b/src/protocols/memory/ddr4.stanza @@ -21,46 +21,90 @@ defpackage jsl/protocols/memory/ddr4: import jsl/pin-assignment doc: \ -@brief DDR4 Width enums -This is a fixed list of possible lane widths for DDR4 memory channels +@brief ddr4 width enums +This is a fixed list of possible lane widths for ddr4 memory channels -public pcb-enum jsl/protocols/memory/DDR4Width: +public pcb-enum jsl/protocols/memory/ddr4-width: DDR4-x4 DDR4-x8 DDR4-x16 -public defn DDR4-enum-to-int (en:jsl/protocols/memory/DDR4Width) -> Int: +doc: \ +@brief ddr4 Width enum conversion to integers +This converts possible lane widths for ddr4 memory channels into the corresponding integer + +public defn ddr4-width-enum-to-int (en:jsl/protocols/memory/ddr4-width) -> Int: switch(en) : DDR4-x4 : 4 DDR4-x8 : 8 DDR4-x16 : 16 doc: \ -@brief DDR4 Bundle -One DDR4 bundle consists of the connections between an integrated memory controller and -one DDR4 memory chip. The overall memory connections consists of 4 separate channels. -@member control Control channel for DDR4 -@member data Four data channels for DDR4 +@brief ddr4 topology +This is a fixed list of possible topologies for ddr4 memories + +public pcb-enum jsl/protocols/memory/ddr4-topology: + FlyBy + ClamShell + +doc: \ +@brief ddr4 rank Options +This is a fixed list of possible rank options for ddr4 implementations +public pcb-enum jsl/protocols/memory/ddr4-rank: + SingleRank + DualRank + QuadRank -public defn ddr4 (width:jsl/protocols/memory/DDR4Width) : - val r-width = DDR4-enum-to-int(width) - ddr4-b(r-width) +doc: \ +@brief ddr4 rank enum conversion to integers +This converts possible rank options for ddr4 memory channels into the corresponding integer + +public defn ddr4-rank-enum-to-int (en:jsl/protocols/memory/ddr4-rank) -> Int: + switch(en) : + SingleRank : 1 + DualRank : 2 + QuadRank : 4 -public pcb-bundle ddr4-b (width:Int) : +doc: \ +@brief ddr4 Bundle +One ddr4 bundle consists of the connections between an integrated memory controller and +one or more ddr4 memory chips/DIMMs. +@member control Control channel for ddr4 +@member data Data channels for ddr4 depending on the width +@member topology Topology of the DDR4 connection (FlyBy or ClamShell) +@member rank Rank configuration of the DDR4 memory (SingleRank, DualRank, or QuadRank) + + +public defn ddr4 (width:jsl/protocols/memory/ddr4-width -- topology:jsl/protocols/memory/ddr4-topology = FlyBy rank:jsl/protocols/memory/ddr4-rank = SingleRank) : + ; Ensure the width is valid + ensure-enum-value(width, [DDR4-x4, DDR4-x8, DDR4-x16]) + ; Ensure the topology is valid + ensure-enum-value(topology, [FlyBy, ClamShell]) + ; Ensure the rank is valid + ensure-enum-value(rank, [SingleRank, DualRank, QuadRank]) + ; Ensure the width matches the rank + if width == DDR4-x4 and rank != SingleRank: + fatal("DDR4-x4 is only supported in SingleRank configuration") + if width == DDR4-x16 and rank == QuadRank: + fatal("DDR4-x16 is not supported in QuadRank configuration") + ddr4-b(ddr4-width-enum-to-int(width), topology, ddr4-rank-enum-to-int(rank)) + + +public pcb-bundle ddr4-b (width:Int topology:jsl/protocols/memory/ddr4-topology, rank:Int) : name = "DDR4" description = "Double Data Rate 4 Dynamic Random-Access Memory protocol" - port data : ddr4-data-channel(width) ; - port control : ddr4-control-channel ; covers all A,B,C,D + port data : ddr4-data-channel(width) ; + port control : ddr4-control-channel(rank) ; covers all CMD/CTRL/ADDR public pcb-bundle ddr4-data-channel (width:Int): - port DQ : pin[width]; - port DQS : diff-pair ; + port DQ : pin[width]; + port DQS : diff-pair ; -public pcb-bundle ddr4-control-channel : +public pcb-bundle ddr4-control-channel (rank:Int): port CK : diff-pair port CKE : pin - port A : pin[[0 1 2 3 4 5 6 7 8 9 10 11 12 13 17]] + port A : pin[[0 to 14, 17]] port ACT_n : pin port BG : pin[2] port BA : pin[2] @@ -88,19 +132,91 @@ table are derived from the references listed below. 5. Skew match between CMD/ADDR/CTRL within a channel is 0.0 +/- 20e-12 (20 ps) Intel 6. Skew match of CK is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD 7. Skew match of DQS is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD -8. Skew match between DQ and DQS.P is 0.0 +/- 3.5e-12 (3.5 ps) Intel or 0.0 +/- 100.0e-12 (100 ps) AMD +8. Skew match between DQ and DQS.P within a byte lane is 0.0 +/- 3.5e-12 (3.5 ps) Intel or 0.0 +/- 100.0e-12 (100 ps) AMD 9. Skew match between CK.P and DQS.P is -85 ps to 935 ps Intel or -149 ps to +1796 ps AMD -Intel derived from https://www.intel.com/content/www/us/en/docs/programmable/683216/23-2-2-7-1/skew-matching-guidelines-for-ddr4-discrete.html -AMD derived from https://docs.amd.com/r/en-US/ug863-versal-pcb-design/Timing-Constraint-Rules-for-DDR4-Signals -for the DDR4 component table +Intel specs derived from: +https://www.intel.com/content/www/us/en/docs/programmable/683216/23-2-2-7-1/skew-matching-guidelines-for-ddr4-discrete.html +AMD specs derived from: +https://docs.amd.com/r/en-US/ug863-versal-pcb-design/Timing-Constraint-Rules-for-DDR4-Signals +for the DDR4 component table Calculating the distance to time correspondence depends on the board material. Example: tpd 147 ps/in 170 ps/in -> 147 fs/mil to 170 fs/mil - @ 5 mils spec'ed that is a intra-pair skew of 750 fs to 850 fs - @ 10 mils spec'ed that is a intra-pair skew of 1.50 ps to 1.70 ps + @ 5 mils spec'ed that is a intra-pair skew of 735 fs to 850 fs depending on the material characteristics + @ 10 mils spec'ed that is a intra-pair skew of 1.47 ps to 1.70 ps depending on the material characteristics + + +doc: \ +@brief Returns address mapping depending on the topology for each address pin that can be permuted +Memory Controller Pin | DRAM Pin (Non-Mirrored) | DRAM Pin (Mirrored) +A3 | A3 | A4 +A4 | A4 | A3 +A5 | A5 | A6 +A6 | A6 | A5 +A7 | A7 | A8 +A8 | A8 | A7 +A11 | A11 | A13 +A13 | A13 | A11 +BA0 | BA0 | BA1 +BA1 | BA1 | BA0 ; this is optional depending on the memory size/rank +BG0 | BG0 | BG1 +BG1 | BG1 | BG0 ; this is optional depending on the memory size/rank +public defn DDR4-Topology-address-map (a:JITXObject topo:jsl/protocols/memory/DDR4-Topology) -> JITXObject: + switch(a) : + A[3] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + A[4] + else : + A[3] + A[4] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + A[3] + else : + A[4] + A[5] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + A[6] + else : + A[5] + A[6] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + A[5] + else : + A[6] + A[7] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + A[8] + else : + A[7] + A[8] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + A[7] + else : + A[8] + A[11] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + A[13] + else : + A[11] + A[13] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + A[11] + else : + A[13] + BA[0] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + BA[1] + else : + BA[0] + BA[1] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + BA[0] + else : + BA[1] + BG[0] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + BG[1] + else : + BG[0] + BG[1] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : + BG[0] + else : + BG[1] + else : + println("Attempting to use unknown address (%_) for mapping" % [a]) + false doc: \ @@ -110,81 +226,80 @@ trace impedance for the standard. @return Upper/lower limits for the impedance. -public defn ddr4-get-trace-impedance () -> [Toleranced, Toleranced] : - [100.0 +/- (5 %) 50.0 +/- (5 %)] +public defn ddr4-get-trace-impedance () -> [Toleranced, Toleranced, Toleranced, Toleranced] : + [ 90.0 +/- (5 %) ; CLK + 100.0 +/- (5 %) ; DQS + 50.0 +/- (5 %) ; DQ + 45.0 +/- (5 %)]; CMD/CTRL/ALERT doc: \ DDR4 SI Constraint Type -This derives from the whole data lane constraint -as most of the controlled signals are single-ended but referenced to the -read and write clock lane pairs (tx/rx). All of these constraints -will be applied to the full lane. - 0.0 +/- 10.0e-15, ; Skew match for RCK_P RCK_N is 0.0 +/- 10.0e-15 (10 fs) - 0.0 +/- 10.0e-15, ; Skew match for WCK_P WCK_N is 0.0 +/- 10.0e-15 (10 fs) - 0.0 +/- 20.0e-12, ; Skew match between RCK and WCK is 0.0 +/- 20.0e-12 (20 ps) - 0.0 +/- 20.0e-12, ; Skew match between WCK and CA (per channel A,B,C,D) is 0.0 +/- 20.0e-12 (20 ps) - 0.0 +/- 20.0e-12, ; Skew match between RCK and DQ and DQE (per channel A,B,C,D) is 0.0 +/- 20.0e-12 (20 p - 0.0 +/- 20.0e-12, ; Skew match between WCK and DQ and DQE (per channel A,B,C,D) is 0.0 +/- 20.0e-12 (20 p - 0.0 +/- 5.0e-12, ; Skew match between DQ and DQE (per channel A,B,C,D) is 0.0 +/- 5.0e-12 (5 ps) - 0.0 +/- 100.0e-12,; Skew match between Reset and CA (per channel A,B,C,D) is 0.0 +/- 100.0e-12 (100ps) - 0.0 +/- 100.0e-12,; Skew match between ERR and WCK (per channel A,B,C,D) is 0.0 +/- 100.0e-12 (100 ps) - 0.0 +/- 5.0e-12, ; Skew match between CA (per channel A,B,C,D) is 0.0 +/- 5.0e-12 (5ps) +This derives from the whole data lane constraint as most of the dq signals +are single-ended but referenced to the dqs pairs. The remainder of the signals are +constrained to the CK pair. The constraints are: + + 0.0 +/- 1.0e-12 ; Intrapair skew match of CK is +/- 1 ps + 0.0 +/- 1.0e-12 ; Intrapair skew match of DQS is +/- 1 ps + -85.0e-12 +935.0e-12 ; Skew match between CK.P and DQS.P -85 ps to 935 ps + 0.0 +/- 3.5e-12 ; Skew match between DQ and DQS.P within a byte lane is +/- 3.5 ps + 0.0 +/- 20.0e-12 ; Skew match between A[17] A[13:0] and CK.P +/- 20 ps + 0.0 +/- 20.0e-12 ; Skew match between RAS_n, CAS_n, WE_n, and CK.P is +/- 20 ps + 0.0 +/- 20.0e-12 ; Skew match between BA[1:0], BG[1:0] and CK.P is +/- 20 ps + 0.0 +/- 20.0e-12 ; Skew match between CMD/ADDR/CTRL within a channel is +/- 20 ps + 0.0 +/- 20.0e-12 ; Skew match between ACT_n, CKE, CS_n, ODT, PAR and CK.P is +/- 20 ps + The `constrain` function for this type expects two compatible `ddr4-b` types. public defstruct DDR4-Constraint <: SI-Constraint : doc: \ - RCK Intra-pair Timing Skew Constraint in Seconds + CK Intra-pair Timing Skew Constraint in Seconds - skew-rck:Toleranced with : - default => 0.0 +/- 10.0e-15 + skew-ck:Toleranced with : + default => 0.0 +/- 1.00e-12 doc: \ - WCK Intra-pair Timing Skew Constraint in Seconds + DQS Intra-pair Timing Skew Constraint in Seconds - skew-wck:Toleranced with : - default => 0.0 +/- 10.0e-15 + skew-dqs:Toleranced with : + default => 0.0 +/- 1.00e-12 doc: \ - RCK to WCK Inter-pair Timing Skew Constraint in Seconds + CK.P to DQS.P Inter-signal Timing Skew Constraint in Seconds - skew-rck-wck:Toleranced with : - default => 0.0 +/- 20.0e-12 + skew-ck-dqs:Toleranced with : + default => min-max(-85.0e-12 935.0e-12) doc: \ - WCK to CA Inter-signal Timing Skew Constraint in Seconds + DQ to DQS Inter-pair Timing Skew Constraint in Seconds - skew-wck-ca:Toleranced with : - default => 0.0 +/- 20.0e-12 + skew-dq-dqs:Toleranced with : + default => 0.0 +/- 3.50e-12 doc: \ - RCK to DQ/DQE Inter-pair Timing Skew Constraint in Seconds + ADDR to CK Inter-pair Timing Skew Constraint in Seconds - skew-rck-dq:Toleranced with : + skew-addr-ck:Toleranced with : default => 0.0 +/- 20.0e-12 doc: \ - WCK to DQ/DQE Inter-pair Timing Skew Constraint in Seconds + RAS_n, CAS_n, WE_n to CK.P Inter-pair Timing Skew Constraint in Seconds - skew-wck-dq:Toleranced with: + skew-ras-cas-we-ck:Toleranced with: default => 0.0 +/- 20.0e-12 doc: \ - DQ and DQE Inter-pair Timing Skew Constraint in Seconds + BA[1:0], BG[1:0] to CK.P Inter-pair Timing Skew Constraint in Seconds - skew-dq:Toleranced with: - default => 0.0 +/- 5.0e-12 + skew-ba-bg-ck:Toleranced with: + default => 0.0 +/- 20.0e-12 doc: \ - Reset to CA Inter-pair Timing Skew Constraint in Seconds + ACT_n, CKE, CS_n, ODT, PAR to CK.P Inter-pair Timing Skew Constraint in Seconds - skew-rst-ca:Toleranced with: - default => 0.0 +/- 100.0e-12 + skew-misc-ck:Toleranced with: + default => 0.0 +/- 20.0e-12 doc: \ - ERR and WCK Inter-pair Timing Skew Constraint in Seconds + CMD, ADDR, CTRL Inter-pair Timing Skew Constraint in Seconds - skew-err-wck:Toleranced with: + skew-cmd-addr-ctrl:Toleranced with: default => 0.0 +/- 100.0e-12 doc: \ - CA Inter-pair Timing Skew Constraint in Seconds - - skew-ca:Toleranced with: - default => 0.0 +/- 5.0e-12 doc: \ Diff-Pair Max Loss Limit Constraint in dB @@ -192,32 +307,47 @@ public defstruct DDR4-Constraint <: SI-Constraint : ensure => ensure-positive!, default => 5.0 doc: \ - Differential Routing Structure for each Diff-Pair + Differential Routing Structure for CK [90.0 +/- (5 %)] + + diff-ck-route-struct:DifferentialRoutingStructure + doc: \ + Differential Routing Structure for DQS [100.0 +/- (5 %)] - diff-route-struct:DifferentialRoutingStructure + diff-dqs-route-struct:DifferentialRoutingStructure doc: \ - Single-Ended Routing Structure for each SE signal + Single-Ended Routing Structure for each DQ signal [50.0 +/- (5 %)] + + se-dq-route-struct:RoutingStructure + doc: \ + Single-Ended Routing Structure for all other SE signal [45.0 +/- (5 %)] se-route-struct:RoutingStructure with: keyword-constructor => true constructor => #DDR4-Constraint + doc: \ Constructor for the DDR4 Link Constraint - -@param rs Differential Routing Structure constraints for all -data lane signals, command/address, and the differential write and read clocks. -This is not applied to the control signals. +@param diff-ck-rs Differential Routing Structure constraints for CK signals +@param diff-dqs-rs Differential Routing Structure constraints for DQS signals +@param dq-rs Routing Structure constraints for DQ signals +@param rs Routing Structure constraints for remaining signals (CMD/CTRL/ADDR) -public defn DDR4-Constraint (diff-rs:DifferentialRoutingStructure rs:RoutingStructure) -> DDR4-Constraint: +public defn DDR4-Constraint ( + diff-ck-rs:DifferentialRoutingStructure + diff-dqs-rs:DifferentialRoutingStructure + dq-rs:RoutingStructure + rs:RoutingStructure ) -> DDR4-Constraint: DDR4-Constraint( - diff-route-struct = diff-rs + diff-ck-route-struct = diff-ck-rs + diff-dqs-route-struct = diff-dqs-rs + se-dq-route-struct = dq-rs se-route-struct = rs ) doc: \ -Constrain a DDR4 Link +Constrain a DDR4 Link assuming that it is a discrete link (not DIMM) @param cst Constraint Object @param src Source End Point - must be of `ddr4-b` type From 659c005601964403485f0dfab70d71b0811bff8d Mon Sep 17 00:00:00 2001 From: Bhusan Gupta Date: Fri, 11 Oct 2024 14:30:52 -0700 Subject: [PATCH 3/8] check pount for ddr4 constraints --- src/protocols/memory/ddr4.stanza | 59 +++++++++++++++++--------------- 1 file changed, 31 insertions(+), 28 deletions(-) diff --git a/src/protocols/memory/ddr4.stanza b/src/protocols/memory/ddr4.stanza index 79b7a1a2..63d1d52f 100644 --- a/src/protocols/memory/ddr4.stanza +++ b/src/protocols/memory/ddr4.stanza @@ -102,6 +102,7 @@ public pcb-bundle ddr4-data-channel (width:Int): port DQS : diff-pair ; public pcb-bundle ddr4-control-channel (rank:Int): + ; how do I use rank here? Needs some work... port CK : diff-pair port CKE : pin port A : pin[[0 to 14, 17]] @@ -240,15 +241,15 @@ This derives from the whole data lane constraint as most of the dq signals are single-ended but referenced to the dqs pairs. The remainder of the signals are constrained to the CK pair. The constraints are: - 0.0 +/- 1.0e-12 ; Intrapair skew match of CK is +/- 1 ps - 0.0 +/- 1.0e-12 ; Intrapair skew match of DQS is +/- 1 ps - -85.0e-12 +935.0e-12 ; Skew match between CK.P and DQS.P -85 ps to 935 ps - 0.0 +/- 3.5e-12 ; Skew match between DQ and DQS.P within a byte lane is +/- 3.5 ps - 0.0 +/- 20.0e-12 ; Skew match between A[17] A[13:0] and CK.P +/- 20 ps - 0.0 +/- 20.0e-12 ; Skew match between RAS_n, CAS_n, WE_n, and CK.P is +/- 20 ps - 0.0 +/- 20.0e-12 ; Skew match between BA[1:0], BG[1:0] and CK.P is +/- 20 ps - 0.0 +/- 20.0e-12 ; Skew match between CMD/ADDR/CTRL within a channel is +/- 20 ps - 0.0 +/- 20.0e-12 ; Skew match between ACT_n, CKE, CS_n, ODT, PAR and CK.P is +/- 20 ps + 0.0 +/- 1.0e-12 ; Intrapair skew match of CK is +/- 1 ps + 0.0 +/- 1.0e-12 ; Intrapair skew match of DQS is +/- 1 ps + -85.0e-12 +935.0e-12 ; Skew match between CK.P and DQS.P -85 ps to 935 ps + 0.0 +/- 3.5e-12 ; Skew match between DQ and DQS.P within a byte lane is +/- 3.5 ps + 0.0 +/- 20.0e-12 ; Skew match between A[17] A[13:0] and CK.P +/- 20 ps + 0.0 +/- 20.0e-12 ; Skew match between RAS_n, CAS_n, WE_n, and CK.P is +/- 20 ps + 0.0 +/- 20.0e-12 ; Skew match between BA[1:0], BG[1:0] and CK.P is +/- 20 ps + 0.0 +/- 20.0e-12 ; Skew match between CMD/ADDR/CTRL within a channel is +/- 20 ps + 0.0 +/- 20.0e-12 ; Skew match between ACT_n, CKE, CS_n, ODT, PAR and CK.P is +/- 20 ps The `constrain` function for this type expects two compatible `ddr4-b` types. @@ -300,7 +301,6 @@ public defstruct DDR4-Constraint <: SI-Constraint : skew-cmd-addr-ctrl:Toleranced with: default => 0.0 +/- 100.0e-12 doc: \ - doc: \ Diff-Pair Max Loss Limit Constraint in dB loss:Double with: @@ -309,19 +309,19 @@ public defstruct DDR4-Constraint <: SI-Constraint : doc: \ Differential Routing Structure for CK [90.0 +/- (5 %)] - diff-ck-route-struct:DifferentialRoutingStructure + diff-ck-rs:DifferentialRoutingStructure doc: \ Differential Routing Structure for DQS [100.0 +/- (5 %)] - diff-dqs-route-struct:DifferentialRoutingStructure + diff-dqs-rs:DifferentialRoutingStructure doc: \ Single-Ended Routing Structure for each DQ signal [50.0 +/- (5 %)] - se-dq-route-struct:RoutingStructure + se-dq-rs:RoutingStructure doc: \ Single-Ended Routing Structure for all other SE signal [45.0 +/- (5 %)] - se-route-struct:RoutingStructure + se-rs:RoutingStructure with: keyword-constructor => true constructor => #DDR4-Constraint @@ -329,21 +329,21 @@ with: doc: \ Constructor for the DDR4 Link Constraint -@param diff-ck-rs Differential Routing Structure constraints for CK signals -@param diff-dqs-rs Differential Routing Structure constraints for DQS signals +@param ck-rs Differential Routing Structure constraints for CK signals +@param dqs-rs Differential Routing Structure constraints for DQS signals @param dq-rs Routing Structure constraints for DQ signals @param rs Routing Structure constraints for remaining signals (CMD/CTRL/ADDR) public defn DDR4-Constraint ( - diff-ck-rs:DifferentialRoutingStructure - diff-dqs-rs:DifferentialRoutingStructure + ck-rs:DifferentialRoutingStructure + dqs-rs:DifferentialRoutingStructure dq-rs:RoutingStructure rs:RoutingStructure ) -> DDR4-Constraint: DDR4-Constraint( - diff-ck-route-struct = diff-ck-rs - diff-dqs-route-struct = diff-dqs-rs - se-dq-route-struct = dq-rs - se-route-struct = rs + diff-ck-rs = ck-rs + diff-dqs-rs = dqs-rs + se-dq-rs = dq-rs + se-rs = rs ) doc: \ @@ -352,15 +352,18 @@ Constrain a DDR4 Link assuming that it is a discrete link (not DIMM) @param cst Constraint Object @param src Source End Point - must be of `ddr4-b` type @param dst Destination End Point - must be of `ddr4-b` type and match -the parameterization of `src`, including lane counts. +the parameterization of `src`, including width. public defmethod constrain (cst:DDR4-Constraint, src:JITXObject, dst:JITXObject) -> False : inside pcb-module: - val cst-rck = DiffPair-Constraint(skew = skew-rck(cst) loss = loss(cst) route-struct = diff-route-struct(cst)) - val cst-wck = DiffPair-Constraint(skew = skew-wck(cst) loss = loss(cst) route-struct = diff-route-struct(cst)) - val guide-rck = src.data[0].RCK.P => dst.data[0].RCK.P - val guide-reset = src.control.RESET_n => dst.control.RESET_n - structure(guide-reset) = se-route-struct(cst) + val cst-ck = DiffPair-Constraint(skew = skew-ck(cst) loss = loss(cst) route-struct = diff-ck-rs(cst)) + val cst-dqs = DiffPair-Constraint(skew = skew-dqs(cst) loss = loss(cst) route-struct = diff-dqs-rs(cst)) + + val guide-ck = src.control.CK.P => dst.control.CK.P + val guide-dqs = src.data.DQS.P => dst.data.DQS.P + + ; val guide-reset = src.control.RESET_n => dst.control.RESET_n + ; structure(guide-reset) = se-route-struct(cst) for i in 0 to 4 do : diffpair-constrain(cst-rck, src.data[i].RCK dst.data[i].RCK) From 3a344687c3ed670e267cdab3f230739314abc1b7 Mon Sep 17 00:00:00 2001 From: Bhusan Gupta Date: Thu, 17 Oct 2024 09:25:03 -0700 Subject: [PATCH 4/8] WIP for DDR4 --- .../protocols/memory/ddr4/ddr4-src.stanza | 204 ++++++++++++++++++ src/protocols/memory.stanza | 2 + 2 files changed, 206 insertions(+) create mode 100644 examples/protocols/memory/ddr4/ddr4-src.stanza diff --git a/examples/protocols/memory/ddr4/ddr4-src.stanza b/examples/protocols/memory/ddr4/ddr4-src.stanza new file mode 100644 index 00000000..47f5c814 --- /dev/null +++ b/examples/protocols/memory/ddr4/ddr4-src.stanza @@ -0,0 +1,204 @@ +doc: \ +@brief GDDR 7 + +GDDR7 is a high speed memory protocol +@see https://en.wikipedia.org/wiki/GDDR7_SDRAM + +This functions and definitions in this example support defining GDDR7 +interfaces on controllers and memories. + +#use-added-syntax(jitx) +defpackage jsl/examples/protocols/memory/gddr7-src : + import core + import jitx + import jitx/commands + + import jsl/symbols + import jsl/landpatterns + + import jsl/design/settings + import jsl/si + import jsl/pin-assignment + import jsl/bundles + import jsl/protocols/memory/ddr4 + +public pcb-component ddr4-mem-ic : + reference-prefix = "U" + mpn = "memory-JITX-DDR4" + description = "Dummy DDR4 memory following JEDEC spec" + + port ddr4 : ddr4() + port vddq : power + port vdd : power + + pin-properties : + [pin:Ref | pads:Ref ... ] + [ VDDQ[0] | A[1] ] + [ VSSQ[0] | A[2] ] + [ DQ[8] | A[3] ] + [ UDQS_c | A[7] ] + [ VSSQ[1] | A[8] ] + [ VDDQ[1] | A[9] ] + [ VPP[0] | B[1] ] + [ VSS[0] | B[2] ] + [ VDD[0] | B[3] ] + [ UDQS_t | B[7] ] + [ DQ[9] | B[8] ] + [ VDD[1] | B[9] ] + [ VDDQ[2] | C[1] ] + [ DQ[12] | C[2] ] + [ DQ[10] | C[3] ] + [ DQ[11] | C[7] ] + [ DQ[13] | C[8] ] + [ VSSQ[2] | C[9] ] + [ VDD[2] | D[1] ] + [ VSS[1] | D[2] ] + [ DQ[14] | D[3] ] + [ DQ[15] | D[7] ] + [ VSS[2] | D[8] ] + [ VDDQ[3] | D[9] ] + [ VSS[3] | E[1] ] + [ VSS[4] | E[9] ] + [ VSSQ[3] | F[1] ] + [ VDDQ[4] | F[2] ] + [ LDQS_c | F[3] ] + [ DQ[1] | F[7] ] + [ VDDQ[5] | F[8] ] + [ ZQ | F[9] ] + [ VDDQ[6] | G[1] ] + [ DQ[0] | G[2] ] + [ LDQS_t | G[3] ] + [ VDD[3] | G[7] ] + [ VSS[5] | G[8] ] + [ VDDQ[7] | G[9] ] + [ VSSQ[4] | H[1] ] + [ DQ[4] | H[2] ] + [ DQ[2] | H[3] ] + [ DQ[3] | H[7] ] + [ DQ[5] | H[8] ] + [ VSSQ[5] | H[9] ] + [ VDD[4] | J[1] ] + [ VDDQ[8] | J[2] ] + [ DQ[6] | J[3] ] + [ DQ[7] | J[7] ] + [ VDDQ[9] | J[8] ] + [ VDD[5] | J[9] ] + [ VSS[6] | K[1] ] + [ CKE | K[2] ] + [ ODT | K[3] ] + [ CK_t | K[7] ] + [ CK_c | K[8] ] + [ VSS[7] | K[9] ] + [ VDD[6] | L[1] ] + [ WE_n | L[2] ] ; aka A[14] + [ ACT_n | L[3] ] + [ CS_n | L[7] ] + [ RAS_n | L[8] ] ; aka A[16] + [ VDD[7] | L[9] ] + [ VREFCA | M[1] ] + [ BG[0] | M[2] ] + [ A[10] | M[3] ] ; /AP + [ A[12] | M[7] ] ; /BC_n + [ CAS_n | M[8] ] ; aka A[15] + [ VSS[8] | M[9] ] + [ VSS[9] | N[1] ] + [ BA[0] | N[2] ] + [ A[4] | N[3] ] + [ A[3] | N[7] ] + [ BA[1] | N[8] ] + [ TEN | N[9] ] + [ RESET_n | P[1] ] + [ A[6] | P[2] ] + [ A[0] | P[3] ] + [ A[1] | P[7] ] + [ A[5] | P[8] ] + [ ALERT_n | P[9] ] + [ VDD[8] | R[1] ] + [ A[8] | R[2] ] + [ A[2] | R[3] ] + [ A[9] | R[7] ] + [ A[7] | R[8] ] + [ VPP[1] | R[9] ] + [ VSS[10] | T[1] ] + [ A[11] | T[2] ] + [ PAR | T[3] ] + [ NC | T[7] ] + [ A[13] | T[8] ] + [ VDD[9] | T[9] ] + + val channel-A = Ref("chA") + val channel-B = Ref("chB") + val channel-C = Ref("chC") + val channel-D = Ref("chD") + val ctl-r = Ref("ctl") + val pwr = Ref("pwr") + + val box-params = BoxSymbolParams( + show-grid = false + ) + + val box = BoxSymbol(self, params = box-params) + + for (c in [channel-A channel-B channel-C channel-D], i in 0 to false) do : + for j in 0 to 10 do : + set-bank(c, DQp[j][i]) + set-side(Left, DQp[j][i]) + set-bank(c, RCK_c[i]) + set-bank(c, RCK_t[i]) + set-bank(c, WCK_c[i]) + set-bank(c, WCK_t[i]) + set-side(Right, RCK_c[i] RCK_t[i] WCK_c[i] WCK_t[i]) + for j in 0 to 5 do : + set-bank(c, CA[j][i]) + set-side(Right, CA[j][i]) + set-bank(c, DQE[i]) + set-side(Right, DQE[i]) + set-bank(c, ERR[i]) + set-side(Right, ERR[i]) + + set-bank(ctl-r, self.ZQ_AB self.ZQ_CD, self.RESET_n) + set-side(Left, self.ZQ_AB self.ZQ_CD, self.RESET_n) + set-bank(pwr, self.VSS self.VDD self.VDDQ self.VPP) + set-side(Down, self.VSS) + set-side(Up, self.VDD self.VDDQ self.VPP) + + + assign-symbols( + ctl-r => box, + pwr => box, + channel-A => box, + channel-B => box, + channel-C => box, + channel-D => box, + ) + + val pkg = BGA( + num-leads = 96, + lead-diam = 0.47, + lead-numbering = Grid-Numbering(16, 9), + package-body = PackageBody( + width = 10.0 +/- 0.1 + length = 13.5 +/- 0.1 + height = 1.1 +/- 0.1 + ), + pad-planner = Perimeter-Matrix-Planner( + rows = 16, + columns = 9, + pitch = Dims(0.8, 0.8), + inactive = [PadIsland(1 to 16, 4 to 7)] + ) + ) + assign-landpattern(pkg) + + for i in 0 to 4 do : + diff-pin-model(self.RCK_c[i], self.RCK_t[i], delay = typ(1.0e-15) loss = typ(0.1)) + diff-pin-model(self.WCK_c[i], self.WCK_t[i], delay = typ(1.0e-15) loss = typ(0.1)) + + for i in 0 to 4 do : + for j in 0 to 10 do : + pin-model(self.DQp[j][i]) = PinModel(typ(1.0e-15), typ(0.1)) + for j in 0 to 5 do : + pin-model(self.CA[j][i]) = PinModel(typ(1.0e-15), typ(0.1)) + pin-model(self.DQE[i]) = PinModel(typ(1.0e-15), typ(0.1)) + pin-model(self.ERR[i]) = PinModel(typ(1.0e-15), typ(0.1)) + pin-model(self.RESET_n) = PinModel(typ(1.0e-15), typ(0.1)) diff --git a/src/protocols/memory.stanza b/src/protocols/memory.stanza index b516f644..717e02aa 100644 --- a/src/protocols/memory.stanza +++ b/src/protocols/memory.stanza @@ -1,2 +1,4 @@ defpackage jsl/protocols/memory: forward jsl/protocols/memory/lpddr4 + forward jsl/protocols/memory/ddr4 + forward jsl/protocols/memory/gddr7 From 86536c68d67bb471a22b58234d7a72aa200025b1 Mon Sep 17 00:00:00 2001 From: Bhusan Gupta Date: Wed, 30 Oct 2024 14:06:58 -0700 Subject: [PATCH 5/8] interim check in --- .../protocols/memory/ddr4/ddr4-src.stanza | 147 +++++---- src/protocols/memory/ddr4.stanza | 282 ++++++++++-------- 2 files changed, 242 insertions(+), 187 deletions(-) diff --git a/examples/protocols/memory/ddr4/ddr4-src.stanza b/examples/protocols/memory/ddr4/ddr4-src.stanza index 47f5c814..a2422f8a 100644 --- a/examples/protocols/memory/ddr4/ddr4-src.stanza +++ b/examples/protocols/memory/ddr4/ddr4-src.stanza @@ -1,14 +1,9 @@ doc: \ -@brief GDDR 7 +@brief DDR4 -GDDR7 is a high speed memory protocol -@see https://en.wikipedia.org/wiki/GDDR7_SDRAM - -This functions and definitions in this example support defining GDDR7 -interfaces on controllers and memories. #use-added-syntax(jitx) -defpackage jsl/examples/protocols/memory/gddr7-src : +defpackage jsl/examples/protocols/memory/ddr4-src : import core import jitx import jitx/commands @@ -16,7 +11,6 @@ defpackage jsl/examples/protocols/memory/gddr7-src : import jsl/symbols import jsl/landpatterns - import jsl/design/settings import jsl/si import jsl/pin-assignment import jsl/bundles @@ -27,22 +21,42 @@ public pcb-component ddr4-mem-ic : mpn = "memory-JITX-DDR4" description = "Dummy DDR4 memory following JEDEC spec" - port ddr4 : ddr4() - port vddq : power - port vdd : power + port ACT_n : pin + port ALERT_n : pin + port A : pin[14] ; also could be written as pin[18] + port BA : pin[2] + port BG : pin[2] + port CAS_n : pin ; aka A[15] + port CKE : pin + port CK : diff-pair + port CS_n : pin + port DQ : pin[16] + port LDQS : diff-pair + port ODT : pin + port PAR : pin + port RAS_n : pin ; aka A[16] + port TEN : pin + port UDQS : diff-pair + port VDDQ : pin[10] + port VDD : pin[10] + port VREFCA : pin + port VSSQ : pin[6] + port VSS : pin[11] + port WE_n : pin ; aka A[14] + port ZQ : pin pin-properties : [pin:Ref | pads:Ref ... ] [ VDDQ[0] | A[1] ] [ VSSQ[0] | A[2] ] [ DQ[8] | A[3] ] - [ UDQS_c | A[7] ] + [ UDQS.N | A[7] ] [ VSSQ[1] | A[8] ] [ VDDQ[1] | A[9] ] [ VPP[0] | B[1] ] [ VSS[0] | B[2] ] [ VDD[0] | B[3] ] - [ UDQS_t | B[7] ] + [ UDQS.P | B[7] ] [ DQ[9] | B[8] ] [ VDD[1] | B[9] ] [ VDDQ[2] | C[1] ] @@ -61,13 +75,13 @@ public pcb-component ddr4-mem-ic : [ VSS[4] | E[9] ] [ VSSQ[3] | F[1] ] [ VDDQ[4] | F[2] ] - [ LDQS_c | F[3] ] + [ LDQS.N | F[3] ] [ DQ[1] | F[7] ] [ VDDQ[5] | F[8] ] [ ZQ | F[9] ] [ VDDQ[6] | G[1] ] [ DQ[0] | G[2] ] - [ LDQS_t | G[3] ] + [ LDQS.P | G[3] ] [ VDD[3] | G[7] ] [ VSS[5] | G[8] ] [ VDDQ[7] | G[9] ] @@ -86,8 +100,8 @@ public pcb-component ddr4-mem-ic : [ VSS[6] | K[1] ] [ CKE | K[2] ] [ ODT | K[3] ] - [ CK_t | K[7] ] - [ CK_c | K[8] ] + [ CK.P | K[7] ] + [ CK.N | K[8] ] [ VSS[7] | K[9] ] [ VDD[6] | L[1] ] [ WE_n | L[2] ] ; aka A[14] @@ -126,12 +140,11 @@ public pcb-component ddr4-mem-ic : [ A[13] | T[8] ] [ VDD[9] | T[9] ] - val channel-A = Ref("chA") - val channel-B = Ref("chB") - val channel-C = Ref("chC") - val channel-D = Ref("chD") - val ctl-r = Ref("ctl") - val pwr = Ref("pwr") + val channel-A = Ref("UB") + val channel-B = Ref("LB") + val ctl-A = Ref("CTL-A") + val ctl-B = Ref("CTL-B") + val pwr = Ref("PWR") val box-params = BoxSymbolParams( show-grid = false @@ -139,37 +152,49 @@ public pcb-component ddr4-mem-ic : val box = BoxSymbol(self, params = box-params) - for (c in [channel-A channel-B channel-C channel-D], i in 0 to false) do : - for j in 0 to 10 do : - set-bank(c, DQp[j][i]) - set-side(Left, DQp[j][i]) - set-bank(c, RCK_c[i]) - set-bank(c, RCK_t[i]) - set-bank(c, WCK_c[i]) - set-bank(c, WCK_t[i]) - set-side(Right, RCK_c[i] RCK_t[i] WCK_c[i] WCK_t[i]) - for j in 0 to 5 do : - set-bank(c, CA[j][i]) - set-side(Right, CA[j][i]) - set-bank(c, DQE[i]) - set-side(Right, DQE[i]) - set-bank(c, ERR[i]) - set-side(Right, ERR[i]) - - set-bank(ctl-r, self.ZQ_AB self.ZQ_CD, self.RESET_n) - set-side(Left, self.ZQ_AB self.ZQ_CD, self.RESET_n) - set-bank(pwr, self.VSS self.VDD self.VDDQ self.VPP) - set-side(Down, self.VSS) - set-side(Up, self.VDD self.VDDQ self.VPP) + for (c in [channel-A channel-B], i in 0 to false) do : + for j in 0 to 8 do : + set-bank(c, DQ[i * 8 + j]) + set-side(Left, DQ[i * 8 + j]) + + for sig in pins(LDQS) do : + set-bank(channel-A, sig) + set-side(Right, sig) + for sig in pins(UDQS) do : + set-bank(channel-B, sig) + set-side(Right, sig) + + for i in pins(A) do : + set-bank(ctl-A, i) + set-side(Left, i) + for a in pins(BA) do : + set-bank(ctl-A, a) + for a in pins(BG) do : + set-bank(ctl-A, a) + for a in pins(CK) do : + set-bank(ctl-A, CK) + set-side(Right, BA) + set-side(Right, BG) + set-side(Right, CK) + + set-bank(ctl-A, CAS_n, CKE, RAS_n, WE_n) + set-side(Right, CAS_n, CKE, RAS_n, WE_n) + set-bank(ctl-B, ACT_n, ALERT_n, CS_n, ODT, PAR, TEN, ZQ) + set-side(Left, ACT_n, ALERT_n, CS_n, ODT, PAR, TEN, ZQ) + + + set-bank(pwr, VDDQ, VDD, VREFCA, VSSQ, VSS) + set-side(Up, VDDQ, VDD) + set-side(Down, VSSQ, VSS) + set-side(Left, VREFCA) assign-symbols( - ctl-r => box, + ctl-A => box, + ctl-B => box, pwr => box, channel-A => box, channel-B => box, - channel-C => box, - channel-D => box, ) val pkg = BGA( @@ -190,15 +215,17 @@ public pcb-component ddr4-mem-ic : ) assign-landpattern(pkg) - for i in 0 to 4 do : - diff-pin-model(self.RCK_c[i], self.RCK_t[i], delay = typ(1.0e-15) loss = typ(0.1)) - diff-pin-model(self.WCK_c[i], self.WCK_t[i], delay = typ(1.0e-15) loss = typ(0.1)) - - for i in 0 to 4 do : - for j in 0 to 10 do : - pin-model(self.DQp[j][i]) = PinModel(typ(1.0e-15), typ(0.1)) - for j in 0 to 5 do : - pin-model(self.CA[j][i]) = PinModel(typ(1.0e-15), typ(0.1)) - pin-model(self.DQE[i]) = PinModel(typ(1.0e-15), typ(0.1)) - pin-model(self.ERR[i]) = PinModel(typ(1.0e-15), typ(0.1)) - pin-model(self.RESET_n) = PinModel(typ(1.0e-15), typ(0.1)) +; for i in 0 to 4 do : +; diff-pin-model(self.RCK_c[i], self.RCK_t[i], delay = typ(1.0e-15) loss = typ(0.1)) +; diff-pin-model(self.WCK_c[i], self.WCK_t[i], delay = typ(1.0e-15) loss = typ(0.1)) + +; for i in 0 to 4 do : +; for j in 0 to 10 do : +; pin-model(self.DQp[j][i]) = PinModel(typ(1.0e-15), typ(0.1)) +; for j in 0 to 5 do : +; pin-model(self.CA[j][i]) = PinModel(typ(1.0e-15), typ(0.1)) +; pin-model(self.DQE[i]) = PinModel(typ(1.0e-15), typ(0.1)) +; pin-model(self.ERR[i]) = PinModel(typ(1.0e-15), typ(0.1)) +; pin-model(self.RESET_n) = PinModel(typ(1.0e-15), typ(0.1)) + +view(ddr4-mem-ic) \ No newline at end of file diff --git a/src/protocols/memory/ddr4.stanza b/src/protocols/memory/ddr4.stanza index 63d1d52f..aca73b77 100644 --- a/src/protocols/memory/ddr4.stanza +++ b/src/protocols/memory/ddr4.stanza @@ -1,13 +1,43 @@ doc: \ -@brief DDR 4 +@brief Double Data Rate 4 Memory Standard (DDR4) -DDR4 is a high speed memory protocol +DDR4 is a high speed memory protocol @see https://en.wikipedia.org/wiki/DDR4_SDRAM This functions and definitions in this file support defining DDR4 connections between microprocessors and memories in a board design. +This file contains curated values for skew and loss of DDR4 channel +It specifies the bounds on the intra-pair +skew timing and maximum loss as expected by this particular standard. The values +returned are a toleranced value with upper/lower limits for the +intra-pair skew and the maximum loss as a double representing dB. Some defaults in the +table are derived from the references listed below. + +1. Skew match between A[17] A[13:0] and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD +2. Skew match between RAS_n, CAS_n, WE_n, and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD +3. Skew match between BA[1:0], BG[1:0] and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD +4. Skew match between ACT_n, CKE, CS_n, ODT, PAR and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD +5. Skew match between CMD/ADDR/CTRL within a channel is 0.0 +/- 20e-12 (20 ps) Intel +6. Skew match of CK is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD +7. Skew match of DQS is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD +8. Skew match between DQ and DQS.P within a byte lane is 0.0 +/- 3.5e-12 (3.5 ps) Intel or 0.0 +/- 100.0e-12 (100 ps) AMD +9. Skew match between CK.P and DQS.P is -85 ps to 935 ps Intel or -149 ps to +1796 ps AMD + +Intel specs derived from: +https://www.intel.com/content/www/us/en/docs/programmable/683216/23-2-2-7-1/skew-matching-guidelines-for-ddr4-discrete.html +AMD specs derived from: +https://docs.amd.com/r/en-US/ug863-versal-pcb-design/Timing-Constraint-Rules-for-DDR4-Signals +for the DDR4 component table + +Calculating the distance to time correspondence depends on the board material. +Example: + tpd 147 ps/in 170 ps/in -> 147 fs/mil to 170 fs/mil + @ 5 mils spec'ed that is a intra-pair skew of 735 fs to 850 fs depending on the material characteristics + @ 10 mils spec'ed that is a intra-pair skew of 1.47 ps to 1.70 ps depending on the material characteristics + + #use-added-syntax(jitx) defpackage jsl/protocols/memory/ddr4: import core @@ -21,46 +51,67 @@ defpackage jsl/protocols/memory/ddr4: import jsl/pin-assignment doc: \ -@brief ddr4 width enums -This is a fixed list of possible lane widths for ddr4 memory channels +@brief DDR4 width enums +This is a fixed list of possible lane widths for DDR4 memory channels +@member DDR4-x4 4 bit width +@member DDR4-x8 8 bit width +@member DDR4-x16 16 bit width -public pcb-enum jsl/protocols/memory/ddr4-width: +public pcb-enum jsl/protocols/memory/ddr4/DDR4-width: DDR4-x4 DDR4-x8 DDR4-x16 doc: \ -@brief ddr4 Width enum conversion to integers +@brief DDR4 Width enum conversion to integers This converts possible lane widths for ddr4 memory channels into the corresponding integer -public defn ddr4-width-enum-to-int (en:jsl/protocols/memory/ddr4-width) -> Int: +public defn width-to-int (en:DDR4-width) -> Int: switch(en) : DDR4-x4 : 4 DDR4-x8 : 8 DDR4-x16 : 16 +doc: \ +@brief DDR4 Width enum conversion to lane count +This converts possible lane widths for ddr4 memory channels +into the corresponding integer number of 8-bit lanes which +determines the number of DQS pairs required. + +public defn width-to-lane (en:DDR4-width) -> Int: + switch(en) : + DDR4-x4 : 1 ; degenerate case + DDR4-x8 : 1 + DDR4-x16 : 2 + doc: \ @brief ddr4 topology This is a fixed list of possible topologies for ddr4 memories +@member FlyBy +@member ClamShell -public pcb-enum jsl/protocols/memory/ddr4-topology: +public pcb-enum jsl/protocols/memory/ddr4/DDR4-topology: FlyBy ClamShell doc: \ -@brief ddr4 rank Options +@brief DDR4 rank Options This is a fixed list of possible rank options for ddr4 implementations +@member SingleRank +@member DualRank +@member QuadRank -public pcb-enum jsl/protocols/memory/ddr4-rank: +public pcb-enum jsl/protocols/memory/ddr4/DDR4-rank: SingleRank DualRank QuadRank doc: \ -@brief ddr4 rank enum conversion to integers -This converts possible rank options for ddr4 memory channels into the corresponding integer +@brief DDR4 rank enum conversion to integers +This converts possible rank options for ddr4 memory channels into a corresponding integer +which determines the number of CS_n signals needed to control the memories -public defn ddr4-rank-enum-to-int (en:jsl/protocols/memory/ddr4-rank) -> Int: +public defn rank-to-int (en:DDR4-rank) -> Int: switch(en) : SingleRank : 1 DualRank : 2 @@ -70,46 +121,38 @@ doc: \ @brief ddr4 Bundle One ddr4 bundle consists of the connections between an integrated memory controller and one or more ddr4 memory chips/DIMMs. -@member control Control channel for ddr4 -@member data Data channels for ddr4 depending on the width -@member topology Topology of the DDR4 connection (FlyBy or ClamShell) +@member data Data channel(s) for ddr4 depending on the width +@member ctl Control channel for ddr4 @member rank Rank configuration of the DDR4 memory (SingleRank, DualRank, or QuadRank) +@member topology Topology of the DDR4 connection (FlyBy or ClamShell) -public defn ddr4 (width:jsl/protocols/memory/ddr4-width -- topology:jsl/protocols/memory/ddr4-topology = FlyBy rank:jsl/protocols/memory/ddr4-rank = SingleRank) : - ; Ensure the width is valid - ensure-enum-value(width, [DDR4-x4, DDR4-x8, DDR4-x16]) - ; Ensure the topology is valid - ensure-enum-value(topology, [FlyBy, ClamShell]) - ; Ensure the rank is valid - ensure-enum-value(rank, [SingleRank, DualRank, QuadRank]) - ; Ensure the width matches the rank +public defn ddr4 (width:DDR4-width -- rank:DDR4-rank = SingleRank topology:DDR4-topology = FlyBy) : if width == DDR4-x4 and rank != SingleRank: fatal("DDR4-x4 is only supported in SingleRank configuration") if width == DDR4-x16 and rank == QuadRank: fatal("DDR4-x16 is not supported in QuadRank configuration") - ddr4-b(ddr4-width-enum-to-int(width), topology, ddr4-rank-enum-to-int(rank)) + ddr4-b(width, rank, topology) - -public pcb-bundle ddr4-b (width:Int topology:jsl/protocols/memory/ddr4-topology, rank:Int) : +public pcb-bundle ddr4-b (width:DDR4-width rank:DDR4-rank topology:DDR4-topology) : name = "DDR4" - description = "Double Data Rate 4 Dynamic Random-Access Memory protocol" + description = "DDR4 Dynamic Random-Access Memory protocol" port data : ddr4-data-channel(width) ; - port control : ddr4-control-channel(rank) ; covers all CMD/CTRL/ADDR + port ctl : ddr4-ctl-channel(rank) ; covers all CMD/CTRL/ADDR -public pcb-bundle ddr4-data-channel (width:Int): - port DQ : pin[width]; - port DQS : diff-pair ; +public pcb-bundle ddr4-data-channel (width:DDR4-width): + port DQ : pin[width-to-int(width)] ; will vary from 3:0 to 7:0 to 15:0 as appropriate + port DQS : pin[width-to-lane(width)] ; will either be 0 or 1:0 -public pcb-bundle ddr4-control-channel (rank:Int): +public pcb-bundle ddr4-ctl-channel (rank:DDR4-rank): ; how do I use rank here? Needs some work... port CK : diff-pair port CKE : pin port A : pin[[0 to 14, 17]] port ACT_n : pin - port BG : pin[2] - port BA : pin[2] - port CS_n : pin + port BG : pin[2] ; not fully present? + port BA : pin[2] ; not fully present? + port CS_n : pin[rank-to-int(rank)] port RAS_n : pin ; aka A[16] port CAS_n : pin ; aka A[15] port WE_n : pin ; aka A[14] @@ -119,34 +162,6 @@ public pcb-bundle ddr4-control-channel (rank:Int): doc: \ -@brief Curated values for skew and loss of DDR4 channel -This is a helper function that returns the bounds on the intra-pair -skew timing and maximum loss as expected by the particular standard targeted by -the user. The values returned are a toleranced value with upper/lower limits for the -intra-pair skew and the maximum loss as a double representing dB. Some defaults in the -table are derived from the references listed below. - -1. Skew match between A[17] A[13:0] and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD -2. Skew match between RAS_n, CAS_n, WE_n, and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD -3. Skew match between BA[1:0], BG[1:0] and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD -4. Skew match between ACT_n, CKE, CS_n, ODT, PAR and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD -5. Skew match between CMD/ADDR/CTRL within a channel is 0.0 +/- 20e-12 (20 ps) Intel -6. Skew match of CK is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD -7. Skew match of DQS is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD -8. Skew match between DQ and DQS.P within a byte lane is 0.0 +/- 3.5e-12 (3.5 ps) Intel or 0.0 +/- 100.0e-12 (100 ps) AMD -9. Skew match between CK.P and DQS.P is -85 ps to 935 ps Intel or -149 ps to +1796 ps AMD - -Intel specs derived from: -https://www.intel.com/content/www/us/en/docs/programmable/683216/23-2-2-7-1/skew-matching-guidelines-for-ddr4-discrete.html -AMD specs derived from: -https://docs.amd.com/r/en-US/ug863-versal-pcb-design/Timing-Constraint-Rules-for-DDR4-Signals -for the DDR4 component table - -Calculating the distance to time correspondence depends on the board material. -Example: - tpd 147 ps/in 170 ps/in -> 147 fs/mil to 170 fs/mil - @ 5 mils spec'ed that is a intra-pair skew of 735 fs to 850 fs depending on the material characteristics - @ 10 mils spec'ed that is a intra-pair skew of 1.47 ps to 1.70 ps depending on the material characteristics doc: \ @@ -165,59 +180,23 @@ BA1 | BA1 | BA0 ; this is optional depending on the memory size/rank BG0 | BG0 | BG1 BG1 | BG1 | BG0 ; this is optional depending on the memory size/rank -public defn DDR4-Topology-address-map (a:JITXObject topo:jsl/protocols/memory/DDR4-Topology) -> JITXObject: - switch(a) : - A[3] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - A[4] - else : - A[3] - A[4] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - A[3] - else : - A[4] - A[5] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - A[6] - else : - A[5] - A[6] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - A[5] - else : - A[6] - A[7] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - A[8] - else : - A[7] - A[8] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - A[7] - else : - A[8] - A[11] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - A[13] - else : - A[11] - A[13] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - A[11] - else : - A[13] - BA[0] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - BA[1] - else : - BA[0] - BA[1] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - BA[0] - else : - BA[1] - BG[0] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - BG[1] - else : - BG[0] - BG[1] : if topo == jsl/protocols/memory/DDR4-Topology:Mirrored : - BG[0] - else : - BG[1] - else : - println("Attempting to use unknown address (%_) for mapping" % [a]) - false +; public defn DDR4-Topology-address-map (a:JITXObject topo:DDR4-topology) -> JITXObject: +; switch(a) : +; A[3] : if topo == ClamShell : A[4] else : A[3] +; A[4] : if topo == ClamShell : A[3] else : A[4] +; A[5] : if topo == ClamShell : A[6] else : A[5] +; A[6] : if topo == ClamShell : A[5] else : A[6] +; A[7] : if topo == ClamShell : A[8] else : A[7] +; A[8] : if topo == ClamShell : A[7] else : A[8] +; A[11] : if topo == ClamShell : A[13] else : A[11] +; A[13] : if topo == ClamShell : A[11] else : A[13] +; BA[0] : if topo == ClamShell : BA[1] else : BA[0] +; BA[1] : if topo == ClamShell : BA[0] else : BA[1] +; BG[0] : if topo == ClamShell : BG[1] else : BG[0] +; BG[1] : if topo == ClamShell : BG[0] else : BG[1] +; else : +; println("Attempting to use unknown address (%_) for mapping" % [a]) +; false doc: \ @@ -241,8 +220,8 @@ This derives from the whole data lane constraint as most of the dq signals are single-ended but referenced to the dqs pairs. The remainder of the signals are constrained to the CK pair. The constraints are: - 0.0 +/- 1.0e-12 ; Intrapair skew match of CK is +/- 1 ps - 0.0 +/- 1.0e-12 ; Intrapair skew match of DQS is +/- 1 ps + 0.0 +/- 1.0e-12 ; Intra-pair skew match of CK is +/- 1 ps + 0.0 +/- 1.0e-12 ; Intra-pair skew match of DQS is +/- 1 ps -85.0e-12 +935.0e-12 ; Skew match between CK.P and DQS.P -85 ps to 935 ps 0.0 +/- 3.5e-12 ; Skew match between DQ and DQS.P within a byte lane is +/- 3.5 ps 0.0 +/- 20.0e-12 ; Skew match between A[17] A[13:0] and CK.P +/- 20 ps @@ -251,77 +230,105 @@ constrained to the CK pair. The constraints are: 0.0 +/- 20.0e-12 ; Skew match between CMD/ADDR/CTRL within a channel is +/- 20 ps 0.0 +/- 20.0e-12 ; Skew match between ACT_n, CKE, CS_n, ODT, PAR and CK.P is +/- 20 ps - The `constrain` function for this type expects two compatible `ddr4-b` types. public defstruct DDR4-Constraint <: SI-Constraint : + doc: \ + Channel Bit Width + + width:DDR4-width + + doc: \ + Channel Rank + + + rank:DDR4-rank + doc: \ + Topology of memory channel + + topology:DDR4-topology + doc: \ CK Intra-pair Timing Skew Constraint in Seconds skew-ck:Toleranced with : default => 0.0 +/- 1.00e-12 + doc: \ DQS Intra-pair Timing Skew Constraint in Seconds skew-dqs:Toleranced with : default => 0.0 +/- 1.00e-12 + doc: \ CK.P to DQS.P Inter-signal Timing Skew Constraint in Seconds skew-ck-dqs:Toleranced with : default => min-max(-85.0e-12 935.0e-12) + doc: \ DQ to DQS Inter-pair Timing Skew Constraint in Seconds skew-dq-dqs:Toleranced with : default => 0.0 +/- 3.50e-12 + doc: \ ADDR to CK Inter-pair Timing Skew Constraint in Seconds skew-addr-ck:Toleranced with : default => 0.0 +/- 20.0e-12 + doc: \ RAS_n, CAS_n, WE_n to CK.P Inter-pair Timing Skew Constraint in Seconds skew-ras-cas-we-ck:Toleranced with: default => 0.0 +/- 20.0e-12 + doc: \ BA[1:0], BG[1:0] to CK.P Inter-pair Timing Skew Constraint in Seconds skew-ba-bg-ck:Toleranced with: default => 0.0 +/- 20.0e-12 + doc: \ ACT_n, CKE, CS_n, ODT, PAR to CK.P Inter-pair Timing Skew Constraint in Seconds skew-misc-ck:Toleranced with: default => 0.0 +/- 20.0e-12 + doc: \ CMD, ADDR, CTRL Inter-pair Timing Skew Constraint in Seconds skew-cmd-addr-ctrl:Toleranced with: default => 0.0 +/- 100.0e-12 + doc: \ Diff-Pair Max Loss Limit Constraint in dB loss:Double with: ensure => ensure-positive!, default => 5.0 + doc: \ Differential Routing Structure for CK [90.0 +/- (5 %)] diff-ck-rs:DifferentialRoutingStructure + doc: \ Differential Routing Structure for DQS [100.0 +/- (5 %)] diff-dqs-rs:DifferentialRoutingStructure + doc: \ Single-Ended Routing Structure for each DQ signal [50.0 +/- (5 %)] se-dq-rs:RoutingStructure + doc: \ Single-Ended Routing Structure for all other SE signal [45.0 +/- (5 %)] se-rs:RoutingStructure + with: keyword-constructor => true constructor => #DDR4-Constraint @@ -335,11 +342,17 @@ Constructor for the DDR4 Link Constraint @param rs Routing Structure constraints for remaining signals (CMD/CTRL/ADDR) public defn DDR4-Constraint ( + width:DDR4-width + topology:DDR4-topology + rank:DDR4-topology ck-rs:DifferentialRoutingStructure dqs-rs:DifferentialRoutingStructure dq-rs:RoutingStructure rs:RoutingStructure ) -> DDR4-Constraint: DDR4-Constraint( + width = width + topology = topology + rank = rank diff-ck-rs = ck-rs diff-dqs-rs = dqs-rs se-dq-rs = dq-rs @@ -356,17 +369,30 @@ the parameterization of `src`, including width. public defmethod constrain (cst:DDR4-Constraint, src:JITXObject, dst:JITXObject) -> False : inside pcb-module: - val cst-ck = DiffPair-Constraint(skew = skew-ck(cst) loss = loss(cst) route-struct = diff-ck-rs(cst)) + val width = width-to-int(width(cs)) + val lane = width-to-lane(width(cs)) + val rank = rank-to-int(rank(cst)) + val topo = topology(cst) ; not sure how to use this atm + + val cst-ck = DiffPair-Constraint(skew = skew-ck(cst) loss = loss(cst) route-struct = diff-ck-rs(cst)) val cst-dqs = DiffPair-Constraint(skew = skew-dqs(cst) loss = loss(cst) route-struct = diff-dqs-rs(cst)) - val guide-ck = src.control.CK.P => dst.control.CK.P - val guide-dqs = src.data.DQS.P => dst.data.DQS.P + val guide-ck = src.ctl.CK.P => dst.ctl.CK.P + diffpair-constrain(cst-ck, src.ctl.CK dst.ctl.CK) + + var guide-dqs[lane] + for i in 0 to lane do : + guide-dqs[i] = src.data.DQS[i].P => dst.data.DQS[i].P + diffpair-constrain(cst-dqs, src.data.DQS[i] dst.data.DQS[i]) + + + timing-window(skew-ck-dqs(cst), guide-ck, src.ctl.CK.P src.data[i].DQS.P) + + for i in 0 to lane do : + val dq-bus = to-tuple $ for j in 0 to width seq : src.data.DQ[j] => dst.data.DQ[j] + - ; val guide-reset = src.control.RESET_n => dst.control.RESET_n - ; structure(guide-reset) = se-route-struct(cst) - for i in 0 to 4 do : - diffpair-constrain(cst-rck, src.data[i].RCK dst.data[i].RCK) diffpair-constrain(cst-wck, src.data[i].WCK dst.data[i].WCK) timing-window(skew-rck-wck(cst) guide-rck src.data[i].RCK.P => dst.data[i].RCK.P) timing-window(skew-rck-wck(cst) guide-rck src.data[i].WCK.P => dst.data[i].WCK.P) @@ -388,6 +414,8 @@ public defmethod constrain (cst:DDR4-Constraint, src:JITXObject, dst:JITXObject) structure(src.data[i].DQE, dst.data[i].DQE) = se-route-struct(cst) structure(src.data[i].CA, dst.data[i].CA) = se-route-struct(cst) structure(src.data[i].ERR, dst.data[i].ERR) = se-route-struct(cst) + + max-loss(loss(cst), src.data[i].DQ => dst.data[i].DQ) max-loss(loss(cst), src.data[i].DQE => dst.data[i].DQE) max-loss(loss(cst), src.data[i].CA => dst.data[i].CA) From a61b01c7eb925f1d9e0846fecc44283c4318f3a1 Mon Sep 17 00:00:00 2001 From: Bhusan Gupta Date: Tue, 12 Nov 2024 15:54:58 -0800 Subject: [PATCH 6/8] fixed backdrill arguments --- examples/protocols/memory/gddr7/gddr7-board.stanza | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/protocols/memory/gddr7/gddr7-board.stanza b/examples/protocols/memory/gddr7/gddr7-board.stanza index 6746d2d4..27dd403e 100644 --- a/examples/protocols/memory/gddr7/gddr7-board.stanza +++ b/examples/protocols/memory/gddr7/gddr7-board.stanza @@ -89,8 +89,6 @@ consult: https://docs.jitx.com/reference/statements/viastmt/heading.html defn bd (via-stop) : Backdrill( - Top, ; Side - Top / Bottom - via-stop, ; Stop Layer 0.3 ; drill diameter, mm 0.6 ; starting pad diameter, mm 0.5 ; Soldermask Opening diameter, mm From b64e3b71088e44af80feff86506b031d40c132bf Mon Sep 17 00:00:00 2001 From: Bhusan Gupta Date: Tue, 12 Nov 2024 16:21:54 -0800 Subject: [PATCH 7/8] removed ddr4 --- .../protocols/memory/ddr4/ddr4-src.stanza | 231 ---------- src/protocols/memory/ddr4.stanza | 427 ------------------ 2 files changed, 658 deletions(-) delete mode 100644 examples/protocols/memory/ddr4/ddr4-src.stanza delete mode 100644 src/protocols/memory/ddr4.stanza diff --git a/examples/protocols/memory/ddr4/ddr4-src.stanza b/examples/protocols/memory/ddr4/ddr4-src.stanza deleted file mode 100644 index a2422f8a..00000000 --- a/examples/protocols/memory/ddr4/ddr4-src.stanza +++ /dev/null @@ -1,231 +0,0 @@ -doc: \ -@brief DDR4 - - -#use-added-syntax(jitx) -defpackage jsl/examples/protocols/memory/ddr4-src : - import core - import jitx - import jitx/commands - - import jsl/symbols - import jsl/landpatterns - - import jsl/si - import jsl/pin-assignment - import jsl/bundles - import jsl/protocols/memory/ddr4 - -public pcb-component ddr4-mem-ic : - reference-prefix = "U" - mpn = "memory-JITX-DDR4" - description = "Dummy DDR4 memory following JEDEC spec" - - port ACT_n : pin - port ALERT_n : pin - port A : pin[14] ; also could be written as pin[18] - port BA : pin[2] - port BG : pin[2] - port CAS_n : pin ; aka A[15] - port CKE : pin - port CK : diff-pair - port CS_n : pin - port DQ : pin[16] - port LDQS : diff-pair - port ODT : pin - port PAR : pin - port RAS_n : pin ; aka A[16] - port TEN : pin - port UDQS : diff-pair - port VDDQ : pin[10] - port VDD : pin[10] - port VREFCA : pin - port VSSQ : pin[6] - port VSS : pin[11] - port WE_n : pin ; aka A[14] - port ZQ : pin - - pin-properties : - [pin:Ref | pads:Ref ... ] - [ VDDQ[0] | A[1] ] - [ VSSQ[0] | A[2] ] - [ DQ[8] | A[3] ] - [ UDQS.N | A[7] ] - [ VSSQ[1] | A[8] ] - [ VDDQ[1] | A[9] ] - [ VPP[0] | B[1] ] - [ VSS[0] | B[2] ] - [ VDD[0] | B[3] ] - [ UDQS.P | B[7] ] - [ DQ[9] | B[8] ] - [ VDD[1] | B[9] ] - [ VDDQ[2] | C[1] ] - [ DQ[12] | C[2] ] - [ DQ[10] | C[3] ] - [ DQ[11] | C[7] ] - [ DQ[13] | C[8] ] - [ VSSQ[2] | C[9] ] - [ VDD[2] | D[1] ] - [ VSS[1] | D[2] ] - [ DQ[14] | D[3] ] - [ DQ[15] | D[7] ] - [ VSS[2] | D[8] ] - [ VDDQ[3] | D[9] ] - [ VSS[3] | E[1] ] - [ VSS[4] | E[9] ] - [ VSSQ[3] | F[1] ] - [ VDDQ[4] | F[2] ] - [ LDQS.N | F[3] ] - [ DQ[1] | F[7] ] - [ VDDQ[5] | F[8] ] - [ ZQ | F[9] ] - [ VDDQ[6] | G[1] ] - [ DQ[0] | G[2] ] - [ LDQS.P | G[3] ] - [ VDD[3] | G[7] ] - [ VSS[5] | G[8] ] - [ VDDQ[7] | G[9] ] - [ VSSQ[4] | H[1] ] - [ DQ[4] | H[2] ] - [ DQ[2] | H[3] ] - [ DQ[3] | H[7] ] - [ DQ[5] | H[8] ] - [ VSSQ[5] | H[9] ] - [ VDD[4] | J[1] ] - [ VDDQ[8] | J[2] ] - [ DQ[6] | J[3] ] - [ DQ[7] | J[7] ] - [ VDDQ[9] | J[8] ] - [ VDD[5] | J[9] ] - [ VSS[6] | K[1] ] - [ CKE | K[2] ] - [ ODT | K[3] ] - [ CK.P | K[7] ] - [ CK.N | K[8] ] - [ VSS[7] | K[9] ] - [ VDD[6] | L[1] ] - [ WE_n | L[2] ] ; aka A[14] - [ ACT_n | L[3] ] - [ CS_n | L[7] ] - [ RAS_n | L[8] ] ; aka A[16] - [ VDD[7] | L[9] ] - [ VREFCA | M[1] ] - [ BG[0] | M[2] ] - [ A[10] | M[3] ] ; /AP - [ A[12] | M[7] ] ; /BC_n - [ CAS_n | M[8] ] ; aka A[15] - [ VSS[8] | M[9] ] - [ VSS[9] | N[1] ] - [ BA[0] | N[2] ] - [ A[4] | N[3] ] - [ A[3] | N[7] ] - [ BA[1] | N[8] ] - [ TEN | N[9] ] - [ RESET_n | P[1] ] - [ A[6] | P[2] ] - [ A[0] | P[3] ] - [ A[1] | P[7] ] - [ A[5] | P[8] ] - [ ALERT_n | P[9] ] - [ VDD[8] | R[1] ] - [ A[8] | R[2] ] - [ A[2] | R[3] ] - [ A[9] | R[7] ] - [ A[7] | R[8] ] - [ VPP[1] | R[9] ] - [ VSS[10] | T[1] ] - [ A[11] | T[2] ] - [ PAR | T[3] ] - [ NC | T[7] ] - [ A[13] | T[8] ] - [ VDD[9] | T[9] ] - - val channel-A = Ref("UB") - val channel-B = Ref("LB") - val ctl-A = Ref("CTL-A") - val ctl-B = Ref("CTL-B") - val pwr = Ref("PWR") - - val box-params = BoxSymbolParams( - show-grid = false - ) - - val box = BoxSymbol(self, params = box-params) - - for (c in [channel-A channel-B], i in 0 to false) do : - for j in 0 to 8 do : - set-bank(c, DQ[i * 8 + j]) - set-side(Left, DQ[i * 8 + j]) - - for sig in pins(LDQS) do : - set-bank(channel-A, sig) - set-side(Right, sig) - for sig in pins(UDQS) do : - set-bank(channel-B, sig) - set-side(Right, sig) - - for i in pins(A) do : - set-bank(ctl-A, i) - set-side(Left, i) - for a in pins(BA) do : - set-bank(ctl-A, a) - for a in pins(BG) do : - set-bank(ctl-A, a) - for a in pins(CK) do : - set-bank(ctl-A, CK) - set-side(Right, BA) - set-side(Right, BG) - set-side(Right, CK) - - set-bank(ctl-A, CAS_n, CKE, RAS_n, WE_n) - set-side(Right, CAS_n, CKE, RAS_n, WE_n) - set-bank(ctl-B, ACT_n, ALERT_n, CS_n, ODT, PAR, TEN, ZQ) - set-side(Left, ACT_n, ALERT_n, CS_n, ODT, PAR, TEN, ZQ) - - - set-bank(pwr, VDDQ, VDD, VREFCA, VSSQ, VSS) - set-side(Up, VDDQ, VDD) - set-side(Down, VSSQ, VSS) - set-side(Left, VREFCA) - - - assign-symbols( - ctl-A => box, - ctl-B => box, - pwr => box, - channel-A => box, - channel-B => box, - ) - - val pkg = BGA( - num-leads = 96, - lead-diam = 0.47, - lead-numbering = Grid-Numbering(16, 9), - package-body = PackageBody( - width = 10.0 +/- 0.1 - length = 13.5 +/- 0.1 - height = 1.1 +/- 0.1 - ), - pad-planner = Perimeter-Matrix-Planner( - rows = 16, - columns = 9, - pitch = Dims(0.8, 0.8), - inactive = [PadIsland(1 to 16, 4 to 7)] - ) - ) - assign-landpattern(pkg) - -; for i in 0 to 4 do : -; diff-pin-model(self.RCK_c[i], self.RCK_t[i], delay = typ(1.0e-15) loss = typ(0.1)) -; diff-pin-model(self.WCK_c[i], self.WCK_t[i], delay = typ(1.0e-15) loss = typ(0.1)) - -; for i in 0 to 4 do : -; for j in 0 to 10 do : -; pin-model(self.DQp[j][i]) = PinModel(typ(1.0e-15), typ(0.1)) -; for j in 0 to 5 do : -; pin-model(self.CA[j][i]) = PinModel(typ(1.0e-15), typ(0.1)) -; pin-model(self.DQE[i]) = PinModel(typ(1.0e-15), typ(0.1)) -; pin-model(self.ERR[i]) = PinModel(typ(1.0e-15), typ(0.1)) -; pin-model(self.RESET_n) = PinModel(typ(1.0e-15), typ(0.1)) - -view(ddr4-mem-ic) \ No newline at end of file diff --git a/src/protocols/memory/ddr4.stanza b/src/protocols/memory/ddr4.stanza deleted file mode 100644 index aca73b77..00000000 --- a/src/protocols/memory/ddr4.stanza +++ /dev/null @@ -1,427 +0,0 @@ -doc: \ -@brief Double Data Rate 4 Memory Standard (DDR4) - -DDR4 is a high speed memory protocol -@see https://en.wikipedia.org/wiki/DDR4_SDRAM - -This functions and definitions in this file support defining DDR4 -connections between microprocessors and memories in a board design. - -This file contains curated values for skew and loss of DDR4 channel -It specifies the bounds on the intra-pair -skew timing and maximum loss as expected by this particular standard. The values -returned are a toleranced value with upper/lower limits for the -intra-pair skew and the maximum loss as a double representing dB. Some defaults in the -table are derived from the references listed below. - -1. Skew match between A[17] A[13:0] and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD -2. Skew match between RAS_n, CAS_n, WE_n, and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD -3. Skew match between BA[1:0], BG[1:0] and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD -4. Skew match between ACT_n, CKE, CS_n, ODT, PAR and CK.P is 0.0 +/- 20e-12 (20 ps) Intel or -50ps, -34ps AMD -5. Skew match between CMD/ADDR/CTRL within a channel is 0.0 +/- 20e-12 (20 ps) Intel -6. Skew match of CK is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD -7. Skew match of DQS is 0.0 +/- 1.0e-12 (1 ps) Intel or 0.0 +/- 2.0e-12 (2 ps) AMD -8. Skew match between DQ and DQS.P within a byte lane is 0.0 +/- 3.5e-12 (3.5 ps) Intel or 0.0 +/- 100.0e-12 (100 ps) AMD -9. Skew match between CK.P and DQS.P is -85 ps to 935 ps Intel or -149 ps to +1796 ps AMD - -Intel specs derived from: -https://www.intel.com/content/www/us/en/docs/programmable/683216/23-2-2-7-1/skew-matching-guidelines-for-ddr4-discrete.html -AMD specs derived from: -https://docs.amd.com/r/en-US/ug863-versal-pcb-design/Timing-Constraint-Rules-for-DDR4-Signals -for the DDR4 component table - -Calculating the distance to time correspondence depends on the board material. -Example: - tpd 147 ps/in 170 ps/in -> 147 fs/mil to 170 fs/mil - @ 5 mils spec'ed that is a intra-pair skew of 735 fs to 850 fs depending on the material characteristics - @ 10 mils spec'ed that is a intra-pair skew of 1.47 ps to 1.70 ps depending on the material characteristics - - - -#use-added-syntax(jitx) -defpackage jsl/protocols/memory/ddr4: - import core - import jitx - import jitx/commands - - import jsl/bundles - import jsl/errors - import jsl/ensure - import jsl/si - import jsl/pin-assignment - -doc: \ -@brief DDR4 width enums -This is a fixed list of possible lane widths for DDR4 memory channels -@member DDR4-x4 4 bit width -@member DDR4-x8 8 bit width -@member DDR4-x16 16 bit width - -public pcb-enum jsl/protocols/memory/ddr4/DDR4-width: - DDR4-x4 - DDR4-x8 - DDR4-x16 - -doc: \ -@brief DDR4 Width enum conversion to integers -This converts possible lane widths for ddr4 memory channels into the corresponding integer - -public defn width-to-int (en:DDR4-width) -> Int: - switch(en) : - DDR4-x4 : 4 - DDR4-x8 : 8 - DDR4-x16 : 16 - -doc: \ -@brief DDR4 Width enum conversion to lane count -This converts possible lane widths for ddr4 memory channels -into the corresponding integer number of 8-bit lanes which -determines the number of DQS pairs required. - -public defn width-to-lane (en:DDR4-width) -> Int: - switch(en) : - DDR4-x4 : 1 ; degenerate case - DDR4-x8 : 1 - DDR4-x16 : 2 - -doc: \ -@brief ddr4 topology -This is a fixed list of possible topologies for ddr4 memories -@member FlyBy -@member ClamShell - -public pcb-enum jsl/protocols/memory/ddr4/DDR4-topology: - FlyBy - ClamShell - -doc: \ -@brief DDR4 rank Options -This is a fixed list of possible rank options for ddr4 implementations -@member SingleRank -@member DualRank -@member QuadRank - -public pcb-enum jsl/protocols/memory/ddr4/DDR4-rank: - SingleRank - DualRank - QuadRank - -doc: \ -@brief DDR4 rank enum conversion to integers -This converts possible rank options for ddr4 memory channels into a corresponding integer -which determines the number of CS_n signals needed to control the memories - -public defn rank-to-int (en:DDR4-rank) -> Int: - switch(en) : - SingleRank : 1 - DualRank : 2 - QuadRank : 4 - -doc: \ -@brief ddr4 Bundle -One ddr4 bundle consists of the connections between an integrated memory controller and -one or more ddr4 memory chips/DIMMs. -@member data Data channel(s) for ddr4 depending on the width -@member ctl Control channel for ddr4 -@member rank Rank configuration of the DDR4 memory (SingleRank, DualRank, or QuadRank) -@member topology Topology of the DDR4 connection (FlyBy or ClamShell) - - -public defn ddr4 (width:DDR4-width -- rank:DDR4-rank = SingleRank topology:DDR4-topology = FlyBy) : - if width == DDR4-x4 and rank != SingleRank: - fatal("DDR4-x4 is only supported in SingleRank configuration") - if width == DDR4-x16 and rank == QuadRank: - fatal("DDR4-x16 is not supported in QuadRank configuration") - ddr4-b(width, rank, topology) - -public pcb-bundle ddr4-b (width:DDR4-width rank:DDR4-rank topology:DDR4-topology) : - name = "DDR4" - description = "DDR4 Dynamic Random-Access Memory protocol" - port data : ddr4-data-channel(width) ; - port ctl : ddr4-ctl-channel(rank) ; covers all CMD/CTRL/ADDR - -public pcb-bundle ddr4-data-channel (width:DDR4-width): - port DQ : pin[width-to-int(width)] ; will vary from 3:0 to 7:0 to 15:0 as appropriate - port DQS : pin[width-to-lane(width)] ; will either be 0 or 1:0 - -public pcb-bundle ddr4-ctl-channel (rank:DDR4-rank): - ; how do I use rank here? Needs some work... - port CK : diff-pair - port CKE : pin - port A : pin[[0 to 14, 17]] - port ACT_n : pin - port BG : pin[2] ; not fully present? - port BA : pin[2] ; not fully present? - port CS_n : pin[rank-to-int(rank)] - port RAS_n : pin ; aka A[16] - port CAS_n : pin ; aka A[15] - port WE_n : pin ; aka A[14] - port RESET_n : pin - port ODT : pin - port PAR : pin - - -doc: \ - - -doc: \ -@brief Returns address mapping depending on the topology for each address pin that can be permuted -Memory Controller Pin | DRAM Pin (Non-Mirrored) | DRAM Pin (Mirrored) -A3 | A3 | A4 -A4 | A4 | A3 -A5 | A5 | A6 -A6 | A6 | A5 -A7 | A7 | A8 -A8 | A8 | A7 -A11 | A11 | A13 -A13 | A13 | A11 -BA0 | BA0 | BA1 -BA1 | BA1 | BA0 ; this is optional depending on the memory size/rank -BG0 | BG0 | BG1 -BG1 | BG1 | BG0 ; this is optional depending on the memory size/rank - -; public defn DDR4-Topology-address-map (a:JITXObject topo:DDR4-topology) -> JITXObject: -; switch(a) : -; A[3] : if topo == ClamShell : A[4] else : A[3] -; A[4] : if topo == ClamShell : A[3] else : A[4] -; A[5] : if topo == ClamShell : A[6] else : A[5] -; A[6] : if topo == ClamShell : A[5] else : A[6] -; A[7] : if topo == ClamShell : A[8] else : A[7] -; A[8] : if topo == ClamShell : A[7] else : A[8] -; A[11] : if topo == ClamShell : A[13] else : A[11] -; A[13] : if topo == ClamShell : A[11] else : A[13] -; BA[0] : if topo == ClamShell : BA[1] else : BA[0] -; BA[1] : if topo == ClamShell : BA[0] else : BA[1] -; BG[0] : if topo == ClamShell : BG[1] else : BG[0] -; BG[1] : if topo == ClamShell : BG[0] else : BG[1] -; else : -; println("Attempting to use unknown address (%_) for mapping" % [a]) -; false - - -doc: \ -@brief Differential impedance specified by the DDR4 standard -This is a helper function that returns the expected differential -trace impedance for the standard. - -@return Upper/lower limits for the impedance. - -public defn ddr4-get-trace-impedance () -> [Toleranced, Toleranced, Toleranced, Toleranced] : - [ 90.0 +/- (5 %) ; CLK - 100.0 +/- (5 %) ; DQS - 50.0 +/- (5 %) ; DQ - 45.0 +/- (5 %)]; CMD/CTRL/ALERT - - -doc: \ -DDR4 SI Constraint Type - -This derives from the whole data lane constraint as most of the dq signals -are single-ended but referenced to the dqs pairs. The remainder of the signals are -constrained to the CK pair. The constraints are: - - 0.0 +/- 1.0e-12 ; Intra-pair skew match of CK is +/- 1 ps - 0.0 +/- 1.0e-12 ; Intra-pair skew match of DQS is +/- 1 ps - -85.0e-12 +935.0e-12 ; Skew match between CK.P and DQS.P -85 ps to 935 ps - 0.0 +/- 3.5e-12 ; Skew match between DQ and DQS.P within a byte lane is +/- 3.5 ps - 0.0 +/- 20.0e-12 ; Skew match between A[17] A[13:0] and CK.P +/- 20 ps - 0.0 +/- 20.0e-12 ; Skew match between RAS_n, CAS_n, WE_n, and CK.P is +/- 20 ps - 0.0 +/- 20.0e-12 ; Skew match between BA[1:0], BG[1:0] and CK.P is +/- 20 ps - 0.0 +/- 20.0e-12 ; Skew match between CMD/ADDR/CTRL within a channel is +/- 20 ps - 0.0 +/- 20.0e-12 ; Skew match between ACT_n, CKE, CS_n, ODT, PAR and CK.P is +/- 20 ps - -The `constrain` function for this type expects two compatible `ddr4-b` types. - -public defstruct DDR4-Constraint <: SI-Constraint : - doc: \ - Channel Bit Width - - width:DDR4-width - - doc: \ - Channel Rank - - - rank:DDR4-rank - doc: \ - Topology of memory channel - - topology:DDR4-topology - - doc: \ - CK Intra-pair Timing Skew Constraint in Seconds - - skew-ck:Toleranced with : - default => 0.0 +/- 1.00e-12 - - doc: \ - DQS Intra-pair Timing Skew Constraint in Seconds - - skew-dqs:Toleranced with : - default => 0.0 +/- 1.00e-12 - - doc: \ - CK.P to DQS.P Inter-signal Timing Skew Constraint in Seconds - - skew-ck-dqs:Toleranced with : - default => min-max(-85.0e-12 935.0e-12) - - doc: \ - DQ to DQS Inter-pair Timing Skew Constraint in Seconds - - skew-dq-dqs:Toleranced with : - default => 0.0 +/- 3.50e-12 - - doc: \ - ADDR to CK Inter-pair Timing Skew Constraint in Seconds - - skew-addr-ck:Toleranced with : - default => 0.0 +/- 20.0e-12 - - doc: \ - RAS_n, CAS_n, WE_n to CK.P Inter-pair Timing Skew Constraint in Seconds - - skew-ras-cas-we-ck:Toleranced with: - default => 0.0 +/- 20.0e-12 - - doc: \ - BA[1:0], BG[1:0] to CK.P Inter-pair Timing Skew Constraint in Seconds - - skew-ba-bg-ck:Toleranced with: - default => 0.0 +/- 20.0e-12 - - doc: \ - ACT_n, CKE, CS_n, ODT, PAR to CK.P Inter-pair Timing Skew Constraint in Seconds - - skew-misc-ck:Toleranced with: - default => 0.0 +/- 20.0e-12 - - doc: \ - CMD, ADDR, CTRL Inter-pair Timing Skew Constraint in Seconds - - skew-cmd-addr-ctrl:Toleranced with: - default => 0.0 +/- 100.0e-12 - - doc: \ - Diff-Pair Max Loss Limit Constraint in dB - - loss:Double with: - ensure => ensure-positive!, - default => 5.0 - - doc: \ - Differential Routing Structure for CK [90.0 +/- (5 %)] - - diff-ck-rs:DifferentialRoutingStructure - - doc: \ - Differential Routing Structure for DQS [100.0 +/- (5 %)] - - diff-dqs-rs:DifferentialRoutingStructure - - doc: \ - Single-Ended Routing Structure for each DQ signal [50.0 +/- (5 %)] - - se-dq-rs:RoutingStructure - - doc: \ - Single-Ended Routing Structure for all other SE signal [45.0 +/- (5 %)] - - se-rs:RoutingStructure - -with: - keyword-constructor => true - constructor => #DDR4-Constraint - - -doc: \ -Constructor for the DDR4 Link Constraint -@param ck-rs Differential Routing Structure constraints for CK signals -@param dqs-rs Differential Routing Structure constraints for DQS signals -@param dq-rs Routing Structure constraints for DQ signals -@param rs Routing Structure constraints for remaining signals (CMD/CTRL/ADDR) - -public defn DDR4-Constraint ( - width:DDR4-width - topology:DDR4-topology - rank:DDR4-topology - ck-rs:DifferentialRoutingStructure - dqs-rs:DifferentialRoutingStructure - dq-rs:RoutingStructure - rs:RoutingStructure ) -> DDR4-Constraint: - DDR4-Constraint( - width = width - topology = topology - rank = rank - diff-ck-rs = ck-rs - diff-dqs-rs = dqs-rs - se-dq-rs = dq-rs - se-rs = rs - ) - -doc: \ -Constrain a DDR4 Link assuming that it is a discrete link (not DIMM) - -@param cst Constraint Object -@param src Source End Point - must be of `ddr4-b` type -@param dst Destination End Point - must be of `ddr4-b` type and match -the parameterization of `src`, including width. - -public defmethod constrain (cst:DDR4-Constraint, src:JITXObject, dst:JITXObject) -> False : - inside pcb-module: - val width = width-to-int(width(cs)) - val lane = width-to-lane(width(cs)) - val rank = rank-to-int(rank(cst)) - val topo = topology(cst) ; not sure how to use this atm - - val cst-ck = DiffPair-Constraint(skew = skew-ck(cst) loss = loss(cst) route-struct = diff-ck-rs(cst)) - val cst-dqs = DiffPair-Constraint(skew = skew-dqs(cst) loss = loss(cst) route-struct = diff-dqs-rs(cst)) - - val guide-ck = src.ctl.CK.P => dst.ctl.CK.P - diffpair-constrain(cst-ck, src.ctl.CK dst.ctl.CK) - - var guide-dqs[lane] - for i in 0 to lane do : - guide-dqs[i] = src.data.DQS[i].P => dst.data.DQS[i].P - diffpair-constrain(cst-dqs, src.data.DQS[i] dst.data.DQS[i]) - - - timing-window(skew-ck-dqs(cst), guide-ck, src.ctl.CK.P src.data[i].DQS.P) - - for i in 0 to lane do : - val dq-bus = to-tuple $ for j in 0 to width seq : src.data.DQ[j] => dst.data.DQ[j] - - - - diffpair-constrain(cst-wck, src.data[i].WCK dst.data[i].WCK) - timing-window(skew-rck-wck(cst) guide-rck src.data[i].RCK.P => dst.data[i].RCK.P) - timing-window(skew-rck-wck(cst) guide-rck src.data[i].WCK.P => dst.data[i].WCK.P) - val guide-rck-chan = src.data[i].RCK.P => dst.data[i].RCK.P - val guide-wck-chan = src.data[i].WCK.P => dst.data[i].WCK.P - val guide-dq = src.data[i].DQ[0] => dst.data[i].DQ[0] - val dq-bus = to-tuple $ cat{_, [src.data[i].DQE => dst.data[i].DQE]} $ for j in 0 to 10 seq : src.data[i].DQ[j] => dst.data[i].DQ[j] - timing-window(skew-rck-dq(cst) guide-rck-chan topos = dq-bus) - timing-window(skew-wck-dq(cst) guide-wck-chan topos = dq-bus) - timing-window(skew-dq(cst) guide-dq topos = dq-bus) - timing-window(skew-err-wck(cst), guide-wck-chan src.data[i].ERR => dst.data[i].ERR) - val ca-bus = to-tuple $ for j in 0 to 5 seq : src.data[i].CA[j] => dst.data[i].CA[j] - val guide-ca = src.data[i].CA[0] => dst.data[i].CA[0] - timing-window(skew-wck-ca(cst), guide-wck-chan topos = ca-bus) - timing-window(skew-rst-ca(cst), guide-reset topos = ca-bus) - timing-window(skew-ca(cst), guide-ca topos = ca-bus) - - structure(src.data[i].DQ, dst.data[i].DQ) = se-route-struct(cst) - structure(src.data[i].DQE, dst.data[i].DQE) = se-route-struct(cst) - structure(src.data[i].CA, dst.data[i].CA) = se-route-struct(cst) - structure(src.data[i].ERR, dst.data[i].ERR) = se-route-struct(cst) - - - max-loss(loss(cst), src.data[i].DQ => dst.data[i].DQ) - max-loss(loss(cst), src.data[i].DQE => dst.data[i].DQE) - max-loss(loss(cst), src.data[i].CA => dst.data[i].CA) - max-loss(loss(cst), src.data[i].ERR => dst.data[i].ERR) - -public defn connect-DDR4 (src:JITXObject dst:JITXObject diff-rs:DifferentialRoutingStructure rs:RoutingStructure) : - inside pcb-module : - val ddr4-cst = DDR4-Constraint(diff-rs, rs) - constrain-topology(src, dst, ddr4-cst) From 94a18ea19659297880ba940061711ddfec80a61a Mon Sep 17 00:00:00 2001 From: Bhusan Gupta Date: Tue, 12 Nov 2024 16:23:20 -0800 Subject: [PATCH 8/8] removed ddr4 --- src/protocols/memory.stanza | 1 - 1 file changed, 1 deletion(-) diff --git a/src/protocols/memory.stanza b/src/protocols/memory.stanza index 717e02aa..ae2e65b1 100644 --- a/src/protocols/memory.stanza +++ b/src/protocols/memory.stanza @@ -1,4 +1,3 @@ defpackage jsl/protocols/memory: forward jsl/protocols/memory/lpddr4 - forward jsl/protocols/memory/ddr4 forward jsl/protocols/memory/gddr7