From: lkcl Date: Wed, 26 Apr 2023 06:55:01 +0000 (+0100) Subject: (no commit message) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=bbb35dd4882235a18d2a1efc80eeda0e75d7ae7d;p=libreriscv.git --- diff --git a/openpower/sv/vector_ops/discussion.mdwn b/openpower/sv/vector_ops/discussion.mdwn index 6ff8b9f79..04763fc18 100644 --- a/openpower/sv/vector_ops/discussion.mdwn +++ b/openpower/sv/vector_ops/discussion.mdwn @@ -259,3 +259,60 @@ mask-out effect of resetting the count back to zero. However close examination shows that the above may actually be `sv.addi/mr/sm=EQ/dz r0.v, r0.v, 1` +# cprop + +* +* +* +* +* + `((P|G)+G)^P` +* + +From QLSKY.png: + +``` + x0 = nand(CIn, P0) + C0 = nand(x0, ~G0) + + x1 = nand(CIn, P0, P1) + y1 = nand(G0, P1) + C1 = nand(x1, y1, ~G1) + + x2 = nand(CIn, P0, P1, P2) + y2 = nand(G0, P1, P2) + z2 = nand(G1, P2) + C1 = nand(x2, y2, z2, ~G2) + + # Gen* + x3 = nand(G0, P1, P2, P3) + y3 = nand(G1, P2, P3) + z3 = nand(G2, P3) + G* = nand(x3, y3, z3, ~G3) +``` + +``` + P = (A | B) & Ci + G = (A & B) +``` + +Stackoverflow algorithm `((P|G)+G)^P` works on the cumulated bits of P and G from associated vector units (P and G are integers here). The result of the algorithm is the new carry-in which already includes ripple, one bit of carry per element. + +``` + At each id, compute C[id] = A[id]+B[id]+0 + Get G[id] = C[id] > radix -1 + Get P[id] = C[id] == radix-1 + Join all P[id] together, likewise G[id] + Compute newC = ((P|G)+G)^P + result[id] = (C[id] + newC[id]) % radix +``` + +two versions: scalar int version and CR based version. + +scalar int version acts as a scalar carry-propagate, reading XER.CA as input, P and G as regs, and taking a radix argument. the end bits go into XER.CA and CR0.ge + +vector version takes CR0.so as carry in, stores in CR0.so and CR.ge end bits. + +if zero (no propagation) then CR0.eq is zero + +CR based version, TODO.