LDMX Software
trackproducer_hw.cxx
1#include <stdio.h>
2
3#include <iostream>
4
5#include "TrigScint/Firmware/objdef.h"
6#include "TrigScint/Firmware/trackproducer.h"
7
8void trackproducer_hw(Cluster Pad1[NTRK], Cluster Pad2[NCLUS],
9 Cluster Pad3[NCLUS], Track outTrk[NTRK],
10 ap_int<12> lookup[NCENT][COMBO][2]) {
11#ifdef TS_NOT_EMULATION
12#pragma HLS ARRAY_PARTITION variable = Pad1 dim = 0 complete
13#pragma HLS ARRAY_PARTITION variable = Pad2 dim = 0 complete
14#pragma HLS ARRAY_PARTITION variable = Pad3 dim = 0 complete
15#pragma HLS ARRAY_PARTITION variable = outTrk dim = 0 complete
16#pragma HLS ARRAY_PARTITION variable = lookup dim = 0 complete
17#pragma HLS PIPELINE II = 10
18#endif
19 Track test;
20#ifdef TS_NOT_EMULATION
21#pragma HLS ARRAY_PARTITION variable = test complete
22#endif
23
24 // This firmware module loops over first the Pad1 seeds (NTRK) and then the
25 // patterns (COMBO) For each seed it check 9 combinations of tracks. These
26 // combinations, which depend on alignment essentially consist of the clusters
27 // that have channels immediattely above or below the Pad1 cluster in the
28 // first layer, which you may observe from the LUT if you printed it. I would
29 // only need to check the pattern without all these continue statements, but
30 // the continue statements further reduce the pattern collection size by only
31 // applying certain patterns iff a secondary hit is there Thats why this looks
32 // complicated at all: the continues just include logic on whether a pattern
33 // should have a secondary hit. It also checks the track residual, only
34 // keeping one pattern for each pad1 cluster.
35 for (int i = 0; i < NTRK; i++) {
36 if (2 * Pad1[i].Seed.bID > 2 * NCHAN) {
37 continue;
38 }
39 for (int I = 0; I < COMBO; I++) {
40 clearTrack(test);
41 if (not(Pad1[i].Seed.Amp > 0)) {
42 continue;
43 } // Continue if Seed not Satisfied
44 ap_int<12> centroid = 2 * Pad1[i].Seed.bID;
45 if (Pad1[i].Sec.Amp > 0) {
46 centroid += 1;
47 }
48 cpyCluster(test.Pad1, Pad1[i]);
49 if ((lookup[centroid][I][0] == -1) or (lookup[centroid][I][1] == -1)) {
50 continue;
51 } // Pattern Empty
52 if (not(Pad2[lookup[centroid][I][0] / 4].Seed.Amp > 0)) {
53 continue;
54 } // Continue if Seed not Satisfied
55 if ((lookup[centroid][I][0] % 4 == 0) and
56 ((Pad2[lookup[centroid][I][0] / 4].Sec.bID >= 0) or
57 (Pad2[lookup[centroid][I][0] / 4].Seed.bID % 2 == 1))) {
58 continue;
59 } // Continue if Sec is not Expected, and not Empty
60 if ((lookup[centroid][I][0] % 4 == 1) and
61 ((Pad2[lookup[centroid][I][0] / 4].Sec.bID < 0) or
62 (Pad2[lookup[centroid][I][0] / 4].Seed.bID % 2 == 1))) {
63 continue;
64 } // Continue if Sec is Expected, and Empty
65 if ((lookup[centroid][I][0] % 4 == 2) and
66 ((Pad2[lookup[centroid][I][0] / 4].Sec.bID >= 0) or
67 (Pad2[lookup[centroid][I][0] / 4].Seed.bID % 2 == 0))) {
68 continue;
69 } // Continue if Sec is not Expected, and not Empty
70 if ((lookup[centroid][I][0] % 4 == 3) and
71 ((Pad2[lookup[centroid][I][0] / 4].Sec.bID < 0) or
72 (Pad2[lookup[centroid][I][0] / 4].Seed.bID % 2 == 0))) {
73 continue;
74 } // Continue if Sec is Expected, and Empty
75 if (not(Pad3[lookup[centroid][I][1] / 4].Seed.Amp > 0)) {
76 continue;
77 } // Continue if Seed not Satisfied
78 if ((lookup[centroid][I][1] % 4 == 0) and
79 ((Pad3[lookup[centroid][I][1] / 4].Sec.bID >= 0) or
80 (Pad3[lookup[centroid][I][1] / 4].Seed.bID % 2 == 1))) {
81 continue;
82 } // Continue if Sec is not Expected, and not Empty
83 if ((lookup[centroid][I][1] % 4 == 1) and
84 ((Pad3[lookup[centroid][I][1] / 4].Sec.bID < 0) or
85 (Pad3[lookup[centroid][I][1] / 4].Seed.bID % 2 == 1))) {
86 continue;
87 } // Continue if Sec is Expected, and Empty
88 if ((lookup[centroid][I][1] % 4 == 2) and
89 ((Pad3[lookup[centroid][I][1] / 4].Sec.bID >= 0) or
90 (Pad3[lookup[centroid][I][1] / 4].Seed.bID % 2 == 0))) {
91 continue;
92 } // Continue if Sec is not Expected, and not Empty
93 if ((lookup[centroid][I][1] % 4 == 3) and
94 ((Pad3[lookup[centroid][I][1] / 4].Sec.bID < 0) or
95 (Pad3[lookup[centroid][I][1] / 4].Seed.bID % 2 == 0))) {
96 continue;
97 } // Continue if Sec is Expected, and Empty
98 cpyCluster(test.Pad2, Pad2[lookup[centroid][I][0] / 4]);
99 cpyCluster(test.Pad3, Pad3[lookup[centroid][I][1] / 4]);
100 calcResid(test);
101 if (test.resid < outTrk[i].resid) {
102 cpyTrack(outTrk[i], test);
103 }
104 }
105 }
106 // While we ultimately envision having the firmware do duplicate track removal
107 // in the other two layers in a separate firmware module, they are done here
108 // so as to not have track over counting and to validate the processor. Thats
109 // what occurs here below.
110 for (int i = 1; i < NTRK - 1; i++) {
111 if ((outTrk[i - 1].Pad2.Seed.bID == outTrk[i].Pad2.Seed.bID) and
112 (outTrk[i].Pad2.Seed.bID >= 0)) {
113 if (outTrk[i - 1].resid <= outTrk[i].resid) {
114 clearTrack(outTrk[i]);
115 } else {
116 clearTrack(outTrk[i - 1]);
117 }
118 }
119 if ((outTrk[i].Pad2.Seed.bID == outTrk[i + 1].Pad2.Seed.bID) and
120 (outTrk[i + 1].Pad2.Seed.bID >= 0)) {
121 if (outTrk[i + 1].resid <= outTrk[i].resid) {
122 clearTrack(outTrk[i]);
123 } else {
124 clearTrack(outTrk[i + 1]);
125 }
126 }
127 if ((outTrk[i - 1].Pad2.Seed.bID == outTrk[i + 1].Pad2.Seed.bID) and
128 (outTrk[i + 1].Pad2.Seed.bID >= 0)) {
129 if (outTrk[i - 1].resid <= outTrk[i + 1].resid) {
130 clearTrack(outTrk[i + 1]);
131 } else {
132 clearTrack(outTrk[i - 1]);
133 }
134 }
135 }
136 for (int i = 1; i < NTRK - 1; i++) {
137 if ((outTrk[i - 1].Pad3.Seed.bID == outTrk[i].Pad3.Seed.bID) and
138 (outTrk[i].Pad3.Seed.bID >= 0)) {
139 if (outTrk[i - 1].resid <= outTrk[i].resid) {
140 clearTrack(outTrk[i]);
141 } else {
142 clearTrack(outTrk[i - 1]);
143 }
144 }
145 if ((outTrk[i].Pad3.Seed.bID == outTrk[i + 1].Pad3.Seed.bID) and
146 (outTrk[i + 1].Pad3.Seed.bID >= 0)) {
147 if (outTrk[i + 1].resid <= outTrk[i].resid) {
148 clearTrack(outTrk[i]);
149 } else {
150 clearTrack(outTrk[i + 1]);
151 }
152 }
153 if ((outTrk[i - 1].Pad3.Seed.bID == outTrk[i + 1].Pad3.Seed.bID) and
154 (outTrk[i + 1].Pad3.Seed.bID >= 0)) {
155 if (outTrk[i - 1].resid <= outTrk[i + 1].resid) {
156 clearTrack(outTrk[i + 1]);
157 } else {
158 clearTrack(outTrk[i - 1]);
159 }
160 }
161 }
162 return;
163}
Sign Arbitrary Precision Type.
Definition ap_int.h:28