Ejemplo n.º 1
0
void FricXactor::_sendPacket(FrSimReg &type, FrSimReg &port, FrSimReg &addr, FrSimReg &data) {
  *(_intf->out) = type;
  *(_intf->out) = *(_intf->out) << 4;
  *(_intf->out) |= port;
  _sif->wait(posedge((_intf->clk)));
  *(_intf->out) = addr;
  _sif->wait(posedge((_intf->clk)));
  if(type==2 || type==5) {
    *(_intf->out) = data;
    _sif->wait(posedge((_intf->clk)));
    *(_intf->out) = data>>8;
    _sif->wait(posedge((_intf->clk)));
  }
Ejemplo n.º 2
0
void best_tracks::operator()
(
	signal_& phi__io,
	signal_& theta__io,
	signal_& cpattern__io,
	signal_& delta_ph__io,
	signal_& delta_th__io,
	signal_& sign_ph__io,
	signal_& sign_th__io,
	signal_& rank__io,
	signal_& vi__io,
	signal_& hi__io,
	signal_& ci__io,
	signal_& si__io,
	signal_& bt_phi__io,
	signal_& bt_theta__io,
	signal_& bt_cpattern__io,
	signal_& bt_delta_ph__io,
	signal_& bt_delta_th__io,
	signal_& bt_sign_ph__io,
	signal_& bt_sign_th__io,
	signal_& bt_rank__io,
	signal_& bt_vi__io,
	signal_& bt_hi__io,
	signal_& bt_ci__io,
	signal_& bt_si__io,
	signal_& clk__io
)
{
	if (!built)
	{
		seg_ch = 2;
		bw_ph = 8;
		bw_th = 7;
		bw_fph = 12;
		bw_fth = 8;
		bw_wg = 7;
		bw_ds = 7;
		bw_hs = 8;
		pat_w_st3 = 3;
		pat_w_st1 = pat_w_st3 + 1;
		full_pat_w_st3 = (1 << (pat_w_st3+1)) - 1;
		full_pat_w_st1 = (1 << (pat_w_st1+1)) - 1;
		padding_w_st1 = full_pat_w_st1 / 2;
		padding_w_st3 = full_pat_w_st3 / 2;
		red_pat_w_st3 = pat_w_st3 * 2 + 1;
		red_pat_w_st1 = pat_w_st1 * 2 + 1;
		fold = 4;
		th_ch11 = seg_ch*seg_ch;
		bw_q = 4;
		bw_addr = 7;
		ph_raw_w = (1 << pat_w_st3) * 15 + 2;
		th_raw_w = (1 << bw_th);
		max_drift = 3;
		bw_phi = 12;
		bw_eta = 7;
		ph_hit_w = 40+4;
		ph_hit_w20 = ph_hit_w;
		ph_hit_w10 = 20+4;
		th_hit_w = 56 + 8;
		endcap = 1;
		n_strips = (station <= 1 && cscid <= 2) ? 64 :
						 (station <= 1 && cscid >= 6) ? 64 : 80;
		n_wg = (station <= 1 && cscid <= 3) ? 48  :
					 (station <= 1 && cscid >= 6) ? 32  :
					 (station == 2 && cscid <= 3) ? 112 :
					 (station >= 3 && cscid <= 3) ? 96  : 64;
		th_coverage = (station <= 1 && cscid <= 2) ? 45  :
						 (station <= 1 && cscid >= 6) ? 27  :
						 (station <= 1 && cscid >= 3) ? 39  :
						 (station == 2 && cscid <= 2) ? 43  :
						 (station == 2 && cscid >= 3) ? 56  :
						 (station == 3 && cscid <= 2) ? 34  :
						 (station == 3 && cscid >= 3) ? 52  :
						 (station == 4 && cscid <= 2) ? 28  :
						 (station == 4 && cscid >= 3) ? 50  : 0;
		ph_coverage = (station <= 1 && cscid >= 6) ? 15 : //30 :
						   (station >= 2 && cscid <= 2) ? 40 : 20;
		th_ch = (station <= 1 && cscid <= 2) ? (seg_ch*seg_ch) : seg_ch;
		ph_reverse = (endcap == 1 && station >= 3) ? 1 : 
			   			   (endcap == 2 && station <  3) ? 1 : 0;
		th_mem_sz = (1 << bw_addr);
		th_corr_mem_sz = (1 << bw_addr);
		mult_bw = bw_fph + 11;
		ph_zone_bnd1 = (station <= 1 && cscid <= 2) ? 41 :
							(station == 2 && cscid <= 2) ? 41 :
							(station == 2 && cscid >  2) ? 87 :
							(station == 3 && cscid >  2) ? 49 :
							(station == 4 && cscid >  2) ? 49 : 127;
		ph_zone_bnd2 = (station == 3 && cscid >  2) ? 87 : 127;
		zone_overlap = 2;
		bwr = 6;
		bpow = 6;
		cnr = (1 << bpow);
		cnrex = ph_raw_w;
		build();
		// precise phi and theta of candidates
// [zone][pattern_num]
		phi.attach(phi__io);
		theta.attach(theta__io);
		cpattern.attach(cpattern__io);
		// ph and th deltas from best stations
// [zone][pattern_num], last index: [0] - best pair of stations, [1] - second best pair
		delta_ph.attach(delta_ph__io);
		delta_th.attach(delta_th__io);
		sign_ph.attach(sign_ph__io);
		sign_th.attach(sign_th__io);
		// updated ranks [zone][pattern_num]
		rank.attach(rank__io);
		//[zone][pattern_num][station 0-3]
		vi.attach(vi__io);
		hi.attach(hi__io);
		ci.attach(ci__io);
		si.attach(si__io);
		clk.attach(clk__io);
		// precise phi and theta of best tracks
// [best_track_num]
		bt_phi.attach(bt_phi__io);
		bt_theta.attach(bt_theta__io);
		bt_cpattern.attach(bt_cpattern__io);
		// ph and th deltas from best stations
// [best_track_num], last index: [0] - best pair of stations, [1] - second best pair
		bt_delta_ph.attach(bt_delta_ph__io);
		bt_delta_th.attach(bt_delta_th__io);
		bt_sign_ph.attach(bt_sign_ph__io);
		bt_sign_th.attach(bt_sign_th__io);
		// ranks [best_track_num]
		bt_rank.attach(bt_rank__io);
		//[best_track_num][station 0-3]
		bt_vi.attach(bt_vi__io);
		bt_hi.attach(bt_hi__io);
		bt_ci.attach(bt_ci__io);
		bt_si.attach(bt_si__io);
	}


	beginalways();
	
	if (posedge (clk))
	{

		// zero segment numbers
		for (z = 0; z < 4; z = z+1) // zone loop
		{
			for (n = 0; n < 3; n = n+1) // pattern number
			{
				for (s = 0; s < 5; s = s+1) // station
				{
					cn_vi[z][n][s] = 0;
					cn_hi[z][n][s] = 0;
					cn_si[z][n][s] = 0;
					cn_ci[z][n][s] = 0;
				}
			}
		}
		// input segment numbers are in terms of chambers in zone
		// convert them back into chamber ids in sector
		for (z = 0; z < 4; z = z+1) // zone loop
		{
			for (n = 0; n < 3; n = n+1) // pattern number
			{
				for (s = 0; s < 4; s = s+1) // station
				{
					// calculate real station and chamber numbers
					cham = ci[z][n][s];
					if (s == 0)
					{
						real_st = (cham < 3) ? 0 : 1;
						real_ch = cham % 3; // will this synthesize OK?
						if (z == 2) real_ch = real_ch + const_(3, 3UL);
						if (z == 3) real_ch = real_ch + const_(3, 6UL);
					}
					else
					if (s == 1)
					{
						real_st = s + 1;
						real_ch = cham;
						if (z > 1) real_ch = real_ch + const_(3, 3UL);
					}
					else
					{
						real_st = s + 1;
						real_ch = cham;
						if (z > 0) real_ch = real_ch + const_(3, 3UL);
					}
					
					cn_vi[z][n][real_st] = vi[z][n][s];
					cn_hi[z][n][real_st] = hi[z][n][s];
					cn_si[z][n][real_st] = si[z][n][s];
					cn_ci[z][n][real_st] = real_ch;
				}
			}
		}
	
		// zero outputs initially
		for (n = 0; n < 3; n = n+1)
		{
			winner[n] = 0;
			bt_rank [n] = 0;
			bt_phi[n] = 0;
			bt_theta[n] = 0;
			bt_cpattern[n] = 0;
			for (s = 0; s < 2; s = s+1) // delta loop
			{
				bt_delta_ph [n][s] = 0;
				bt_sign_ph  [n][s] = 0; 
				bt_delta_th [n][s] = 0; 
				bt_sign_th  [n][s] = 0; 
			}
			
			for (s = 0; s < 5; s = s+1) // station loop
			{
				bt_vi[n][s] = 0;
				bt_hi[n][s] = 0;
				bt_si[n][s] = 0;
				bt_ci[n][s] = 0;
			}
		}
	
		// simultaneously compare each rank with each
		for (i = 0; i < 12; i = i+1)
		{
			larger[i] = 0;
			larger[i][i] = 1; // result of comparison with itself
			ri = rank[i%4][i/4]; // first index loops zone, second loops candidate. Zone loops faster, so we give equal priority to zones
			for (j = 0; j < 12; j = j+1)
			{
				// ilgj bits show which rank is larger
				// the comparison scheme below avoids problems
				// when there are two | more tracks with the same rank
				rj = rank[j%4][j/4];
				gt = ri > rj;
				eq = ri == rj;
				if ((i < j && (gt || eq)) || (i > j && gt)) larger[i][j] = 1; 				
			}
			// "larger" array shows the result of comparison for each rank

			// track exists if quality != 0 
			exists[i] = (ri != 0);
		}

		// ghost cancellation, only in the current BX so far
		kill1 = 0;
		
		for (i = 0; i < 12; i = i+1) // candidate loop
		{
			for (j = i+1; j < 12; j = j+1) // comparison candidate loop
			{
				sh_segs = 0;
				// count shared segments
				for (s = 0; s < 5; s = s+1) // station loop
				{
					if (cn_vi[i%4][i/4][s] && cn_vi[j%4][j/4][s] && // both segments valid
						cn_ci[i%4][i/4][s] == cn_ci[j%4][j/4][s] && // from same chamber
						cn_si[i%4][i/4][s] == cn_si[j%4][j/4][s]) // same segment
						sh_segs = sh_segs + const_(3, 0x1UL); // increment shared segment counter
				}

				if (sh_segs > 0) // a single shared segment means const_s(it, ) ghost
				{
					// kill candidate that has lower rank
					if (larger[i][j]) kill1[j] = 1;
					else kill1[i] = 1;
				}
			}
		}

		// remove ghosts according to kill mask
		exists = exists & (~kill1);
		
		for (i = 0; i < 12; i = i+1)
		{
			if  (exists[i]) larger[i] = larger[i] | (~exists); // if this track exists make it larger than all non-existing tracks
			else  larger[i] = 0; // else make it smaller than anything

			// count zeros in the comparison results. The best track will have none, the next will have one, the third will have two.
			// skip the bits corresponding to the comparison of the track with itself
			sum = 0;
			for (j = 0; j < 12; j = j+1) if (larger[i][j] == 0) sum = sum + 1; 
			
			if (sum < 3) winner[sum][i] = 1; //  positional winner codes
		}
	
		// multiplex best tracks to outputs according to winner signals
		for (n = 0; n < 3; n = n+1) // output loop
		{
			for (i = 0; i < 12; i = i+1) // winner bit loop
			{
				if (winner[n][i])
				{
					bt_rank [n] = bt_rank [n] | rank [i%4][i/4];
					bt_phi[n] = bt_phi[n] | phi[i%4][i/4];
					bt_theta[n] = bt_theta[n] | theta[i%4][i/4];
					bt_cpattern[n] = bt_cpattern[n] | cpattern[i%4][i/4];
					
					for (s = 0; s < 2; s = s+1) // delta loop
					{
						bt_delta_ph [n][s] = bt_delta_ph [n][s] | delta_ph [i%4][i/4][s];
						bt_sign_ph  [n][s] = bt_sign_ph  [n][s] | sign_ph  [i%4][i/4][s];
						bt_delta_th [n][s] = bt_delta_th [n][s] | delta_th [i%4][i/4][s];
						bt_sign_th  [n][s] = bt_sign_th  [n][s] | sign_th  [i%4][i/4][s];
					}
					
					for (s = 0; s < 5; s = s+1) // station loop
					{
						bt_vi[n][s] = bt_vi[n][s] | cn_vi[i%4][i/4][s];
						bt_hi[n][s] = bt_hi[n][s] | cn_hi[i%4][i/4][s];
						bt_ci[n][s] = bt_ci[n][s] | cn_ci[i%4][i/4][s];
						bt_si[n][s] = bt_si[n][s] | cn_si[i%4][i/4][s];
					}              
				}
			}
		}
	}
	endalways();
}
Ejemplo n.º 3
0
void deltas::operator()
(
	signal_& vi__io,
	signal_& hi__io,
	signal_& ci__io,
	signal_& si__io,
	signal_& ph_match__io,
	signal_& th_match__io,
	signal_& th_match11__io,
	signal_& cpat_match__io,
	signal_& ph_q__io,
	signal_& th_window__io,
	signal_& phi__io,
	signal_& theta__io,
	signal_& cpattern__io,
	signal_& delta_ph__io,
	signal_& delta_th__io,
	signal_& sign_ph__io,
	signal_& sign_th__io,
	signal_& rank__io,
	signal_& vir__io,
	signal_& hir__io,
	signal_& cir__io,
	signal_& sir__io,
	signal_& clk__io
)
{
	if (!built)
	{
		seg_ch = 2;
		bw_ph = 8;
		bw_th = 7;
		bw_fph = 12;
		bw_fth = 8;
		bw_wg = 7;
		bw_ds = 7;
		bw_hs = 8;
		pat_w_st3 = 3;
		pat_w_st1 = pat_w_st3 + 1;
		full_pat_w_st3 = (1 << (pat_w_st3+1)) - 1;
		full_pat_w_st1 = (1 << (pat_w_st1+1)) - 1;
		padding_w_st1 = full_pat_w_st1 / 2;
		padding_w_st3 = full_pat_w_st3 / 2;
		red_pat_w_st3 = pat_w_st3 * 2 + 1;
		red_pat_w_st1 = pat_w_st1 * 2 + 1;
		fold = 4;
		th_ch11 = seg_ch*seg_ch;
		bw_q = 4;
		bw_addr = 7;
		ph_raw_w = (1 << pat_w_st3) * 15;
		th_raw_w = (1 << bw_th);
		max_drift = 3;
		bw_phi = 12;
		bw_eta = 7;
		ph_hit_w = 40+4;
		ph_hit_w20 = ph_hit_w;
		ph_hit_w10 = 20+4;
		th_hit_w = 56 + 8;
		endcap = 1;
		n_strips = (station <= 1 && cscid <= 2) ? 64 :
						 (station <= 1 && cscid >= 6) ? 64 : 80;
		n_wg = (station <= 1 && cscid <= 3) ? 48  :
					 (station <= 1 && cscid >= 6) ? 32  :
					 (station == 2 && cscid <= 3) ? 112 :
					 (station >= 3 && cscid <= 3) ? 96  : 64;
		th_coverage = (station <= 1 && cscid <= 2) ? 45  :
						 (station <= 1 && cscid >= 6) ? 27  :
						 (station <= 1 && cscid >= 3) ? 39  :
						 (station == 2 && cscid <= 2) ? 43  :
						 (station == 2 && cscid >= 3) ? 56  :
						 (station == 3 && cscid <= 2) ? 34  :
						 (station == 3 && cscid >= 3) ? 52  :
						 (station == 4 && cscid <= 2) ? 28  :
						 (station == 4 && cscid >= 3) ? 50  : 0;
		ph_coverage = (station <= 1 && cscid >= 6) ? 15 : //30 :
						   (station >= 2 && cscid <= 2) ? 40 : 20;
		th_ch = (station <= 1 && cscid <= 2) ? (seg_ch*seg_ch) : seg_ch;
		ph_reverse = (endcap == 1 && station >= 3) ? 1 : 
			   			   (endcap == 2 && station <  3) ? 1 : 0;
		th_mem_sz = (1 << bw_addr);
		th_corr_mem_sz = (1 << bw_addr);
		mult_bw = bw_fph + 11;
		ph_zone_bnd1 = (station <= 1 && cscid <= 2) ? 41 :
							(station == 2 && cscid <= 2) ? 41 :
							(station == 2 && cscid >  2) ? 87 :
							(station == 3 && cscid >  2) ? 49 :
							(station == 4 && cscid >  2) ? 49 : 127;
		ph_zone_bnd2 = (station == 3 && cscid >  2) ? 87 : 127;
		zone_overlap = 2;
		bwr = 6;
		bpow = 6;
		cnr = (1 << bpow);
		cnrex = ph_raw_w;
		seg1 = me11 ? th_ch11 : seg_ch;
		bw_nm1 = me11 ? 3 : 2;
		bw_nm2 = 2;
		build();
		// input parameters [station]
		vi.attach(vi__io);
		hi.attach(hi__io);
		ci.attach(ci__io);
		si.attach(si__io);
		ph_match.attach(ph_match__io);
		// theta coordinates [station][segment]
		th_match.attach(th_match__io);
		// ME11 duplicated thetas [segment]
		th_match11.attach(th_match11__io);
		cpat_match.attach(cpat_match__io);
		ph_q.attach(ph_q__io);
		th_window.attach(th_window__io);
		clk.attach(clk__io);
		// precise phi and theta
		phi.attach(phi__io);
		theta.attach(theta__io);
		cpattern.attach(cpattern__io);
		// ph and th deltas from best stations [0] - best pair of stations, [1] - second best pair
		delta_ph.attach(delta_ph__io);
		delta_th.attach(delta_th__io);
		sign_ph.attach(sign_ph__io);
		sign_th.attach(sign_th__io);
		rank.attach(rank__io);
		vir.attach(vir__io);
		hir.attach(hir__io);
		cir.attach(cir__io);
		sir.attach(sir__io);
	}
	dvalid = dvl12 != 0 || dvl13 != 0 || dvl14 != 0 || dvl23 != 0 || dvl24 != 0 || dvl34 != 0;


	// difference sorters
	 bd12.nseg = seg1*seg_ch;
	 bd13.nseg = seg1*seg_ch;
	 bd14.nseg = seg1*seg_ch;
	 bd23.nseg = seg_ch*seg_ch;
	 bd24.nseg = seg_ch*seg_ch;
	 bd34.nseg = seg_ch*seg_ch;
	
	if (true)
	{

		for (i1 = 0; i1 < 3; i1 = i1+1) // station 1 loop
		{
			for (i2 = i1+1; i2 < 4; i2 = i2+1) // station 2 loop
			{
				
				// calculate theta deltas
				for (j = 0; j < ((i1==0) ? seg1 : seg_ch); j = j+1) // segment st A loop
				{
					for (k = 0; k < seg_ch; k = k+1) // segment st B loop
					{
						
						if (me11)
							thA = (i1 == 0) ? th_match11[j] : th_match[i1][j];
						else
							thA = th_match[i1][j];
						
						thB = th_match[i2][k];
						dth = (thA > thB) ? thA - thB : thB - thA;
						sth = (thA > thB); // sign
						// if one of the segments not valid, delta not valid
						dvl = vi[i1][j%seg_ch] & vi[i2][k];
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x1UL))) {  { dth12[j*seg_ch + k] = dth; dvl12[j*seg_ch + k] = dvl; sth12[j*seg_ch + k] = sth; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x2UL))) {  { dth13[j*seg_ch + k] = dth; dvl13[j*seg_ch + k] = dvl; sth13[j*seg_ch + k] = sth; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x3UL))) {  { dth14[j*seg_ch + k] = dth; dvl14[j*seg_ch + k] = dvl; sth14[j*seg_ch + k] = sth; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x6UL))) {  { dth23[j*seg_ch + k] = dth; dvl23[j*seg_ch + k] = dvl; sth23[j*seg_ch + k] = sth; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x7UL))) {  { dth24[j*seg_ch + k] = dth; dvl24[j*seg_ch + k] = dvl; sth24[j*seg_ch + k] = sth; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0xbUL))) {  { dth34[j*seg_ch + k] = dth; dvl34[j*seg_ch + k] = dvl; sth34[j*seg_ch + k] = sth; } } 
					}
				} // for (j = 0; j < ((i1==0) ? seg1 : seg_ch); j = j+1)

				// calculate phi deltas
				phA = ph_match[i1];
				phB = ph_match[i2];
				dph = (phA > phB) ? phA - phB : phB - phA;
				sph = (phA > phB);
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x1UL))) {  { dph12 = dph; sph12 = sph; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x2UL))) {  { dph13 = dph; sph13 = sph; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x3UL))) {  { dph14 = dph; sph14 = sph; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x6UL))) {  { dph23 = dph; sph23 = sph; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0x7UL))) {  { dph24 = dph; sph24 = sph; } } else 
 if (( ((i1(1,0), i2(1,0))) == const_(4, 0xbUL))) {  { dph34 = dph; sph34 = sph; } } 
				
				
			}
		} // for (i = 0; i < 3; i = i+1)
	}

	beginalways();
		
	if (posedge (clk))
	{
		// find valid segments
		vmask1 = const_(4, 0x0UL);
		vmask2 = const_(4, 0x0UL);
		vmask3 = const_(4, 0x0UL);
		
		//std::cout<<"\n";
		//for(int t=0;t<4;t++){
		//	std::cout<<"PhiMatch["<<t<<"] = "<<ph_match[t]<<std::endl;
		//}

		// vmask contains valid station mask = (ME4,ME3,ME2,ME1)
		if (bth12 <= th_window && bvl12) vmask1 = vmask1 | const_(4, 0x3UL);
		if (bth13 <= th_window && bvl13) vmask1 = vmask1 | const_(4, 0x5UL);
		if (bth14 <= th_window && bvl14) vmask1 = vmask1 | const_(4, 0x9UL);
		if (bth23 <= th_window && bvl23) vmask2 = vmask2 | const_(4, 0x6UL);
		if (bth24 <= th_window && bvl24) vmask2 = vmask2 | const_(4, 0xaUL);
		if (bth34 <= th_window && bvl34) vmask3 = vmask3 | const_(4, 0xcUL);
		
		
		if(vmask1){std::cout<<"vmask1 = "<<vmask1<<std::endl;}
		if(vmask2){std::cout<<"vmask2 = "<<vmask2<<std::endl;}
		if(vmask3){std::cout<<"vmask3 = "<<vmask3<<std::endl;}
		

		// merge station masks only if they share bits
		// could try here to find two tracks with identical ph
		// for example vmask1 = 1001 and vmask2 = 0110
		// not done so far, just select one with better station combination
		vstat = vmask1;
		
		if(vstat){std::cout<<"vstat = "<<vstat<<std::endl;}
		
		if ((vstat & vmask2) != const_(4, 0x0UL) || vstat == const_(4, 0x0UL)) vstat = vstat | vmask2;
		
		if(vstat){std::cout<<"vstat = "<<vstat<<std::endl;}
		
		if ((vstat & vmask3) != const_(4, 0x0UL) || vstat == const_(4, 0x0UL)) vstat = vstat | vmask3;
		
		if(vstat){std::cout<<"vstat = "<<vstat<<std::endl;}
		
		if (( (vstat) == const_(4, 0xcUL))) {  { delta_ph[0] = dph34; delta_ph[1] = dph34; delta_th[0] = bth34; delta_th[1] = bth34; } } else 
		if (( (vstat) == const_(4, 0xaUL))) {  { delta_ph[0] = dph24; delta_ph[1] = dph24; delta_th[0] = bth24; delta_th[1] = bth24; } } else 
		if (( (vstat) == const_(4, 0x6UL))) {  { delta_ph[0] = dph23; delta_ph[1] = dph23; delta_th[0] = bth23; delta_th[1] = bth23; } } else 
		if (( (vstat) == const_(4, 0xeUL))) {  { delta_ph[0] = dph23; delta_ph[1] = dph34; delta_th[0] = bth23; delta_th[1] = bth34; } } else 
		if (( (vstat) == const_(4, 0x9UL))) {  { delta_ph[0] = dph14; delta_ph[1] = dph14; delta_th[0] = bth14; delta_th[1] = bth14; } } else 
		if (( (vstat) == const_(4, 0x5UL))) {  { delta_ph[0] = dph13; delta_ph[1] = dph13; delta_th[0] = bth13; delta_th[1] = bth13; } } else 
		if (( (vstat) == const_(4, 0xdUL))) {  { delta_ph[0] = dph13; delta_ph[1] = dph34; delta_th[0] = bth13; delta_th[1] = bth34; } } else 
		if (( (vstat) == const_(4, 0x3UL))) {  { delta_ph[0] = dph12; delta_ph[1] = dph12; delta_th[0] = bth12; delta_th[1] = bth12; } } else 
		if (( (vstat) == const_(4, 0xbUL))) {  { delta_ph[0] = dph12; delta_ph[1] = dph24; delta_th[0] = bth12; delta_th[1] = bth24; } } else 
		if (( (vstat) == const_(4, 0x7UL))) {  { delta_ph[0] = dph12; delta_ph[1] = dph23; delta_th[0] = bth12; delta_th[1] = bth23; } } else 
		if (( (vstat) == const_(4, 0xfUL))) {  { delta_ph[0] = dph12; delta_ph[1] = dph23; delta_th[0] = bth12; delta_th[1] = bth23; } }
 		if (( (vstat) == const_(4, 0xcUL))) {  { sign_ph[0] = sph34; sign_ph[1] = sph34; sign_th[0] = bsg34; sign_th[1] = bsg34; } } else 
 		if (( (vstat) == const_(4, 0xaUL))) {  { sign_ph[0] = sph24; sign_ph[1] = sph24; sign_th[0] = bsg24; sign_th[1] = bsg24; } } else 
 		if (( (vstat) == const_(4, 0x6UL))) {  { sign_ph[0] = sph23; sign_ph[1] = sph23; sign_th[0] = bsg23; sign_th[1] = bsg23; } } else 
 		if (( (vstat) == const_(4, 0xeUL))) {  { sign_ph[0] = sph23; sign_ph[1] = sph34; sign_th[0] = bsg23; sign_th[1] = bsg34; } } else 
 		if (( (vstat) == const_(4, 0x9UL))) {  { sign_ph[0] = sph14; sign_ph[1] = sph14; sign_th[0] = bsg14; sign_th[1] = bsg14; } } else 
 		if (( (vstat) == const_(4, 0x5UL))) {  { sign_ph[0] = sph13; sign_ph[1] = sph13; sign_th[0] = bsg13; sign_th[1] = bsg13; } } else 
 		if (( (vstat) == const_(4, 0xdUL))) {  { sign_ph[0] = sph13; sign_ph[1] = sph34; sign_th[0] = bsg13; sign_th[1] = bsg34; } } else 
 		if (( (vstat) == const_(4, 0x3UL))) {  { sign_ph[0] = sph12; sign_ph[1] = sph12; sign_th[0] = bsg12; sign_th[1] = bsg12; } } else 
 		if (( (vstat) == const_(4, 0xbUL))) {  { sign_ph[0] = sph12; sign_ph[1] = sph24; sign_th[0] = bsg12; sign_th[1] = bsg24; } } else 
 		if (( (vstat) == const_(4, 0x7UL))) {  { sign_ph[0] = sph12; sign_ph[1] = sph23; sign_th[0] = bsg12; sign_th[1] = bsg23; } } else 
 		if (( (vstat) == const_(4, 0xfUL))) {  { sign_ph[0] = sph12; sign_ph[1] = sph23; sign_th[0] = bsg12; sign_th[1] = bsg23; } } 


		// segment ids
		vir = vi;
		hir = hi;
		cir = ci;
		sir = si;

		// remove some valid flags if th did not line up
		for (j = 0; j < 4; j = j+1)
			if (vstat[j] == const_(1, 0x0UL)) vir[j] = 0;

		//  precise phi and theta
		phi = 0;
		theta = 0;
		if      (vstat[1] == const_(1, 0x1UL)) // ME2 present
		{
			// phi is simple, we have it
			phi = ph_match[1];

			// for theta, select delta to best station, use winner number as index
			if      (bvl12) theta = th_match[1][bnm12[0]];
			else if (bvl23) theta = th_match[1][bnm23[1]];
			else if (bvl24) theta = th_match[1][bnm24[1]];
		} 
		else if (vstat[2] == const_(1, 0x1UL)) // ME3 present
		{ 
			phi = ph_match[2]; 
			if      (bvl13) theta = th_match[2][bnm13[0]];
			else if (bvl34) theta = th_match[2][bnm34[1]];
		} 
		else if (vstat[3] == const_(1, 0x1UL)) // ME4 present
		{ 
			phi = ph_match[3]; 
			if      (bvl14) theta = th_match[3][bnm14[0]];
		} 

		// update rank taking into account available stations after th deltas
		// keep straightness as it was
		rank = (ph_q, const_s(1, 0x0UL)); // output rank is one bit longer than input, to accommodate ME4 separately
		
		if(rank){std::cout<<"ph_q = "<<ph_q<<" and rank = "<<rank<<" and vstat = "<<vstat<<std::endl;}
		
		rank[0] = vstat[3]; // ME4
		rank[1] = vstat[2]; // ME3
		rank[3] = vstat[1]; // ME2
		rank[5] = vstat[0]; // ME1
		
		if(rank){std::cout<<"ph_q = "<<ph_q<<" and rank = "<<rank<<std::endl;}

		// if less than 2 segments, kill rank
		if (vstat == const_(4, 0x1UL) || vstat == const_(4, 0x2UL) || vstat == const_(4, 0x4UL) || vstat == const_(4, 0x8UL) || vstat == const_(4, 0x0UL))
			rank = 0;

		cpattern = cpat_match[0]; // pattern taken from station 1 only at this time

	}
	endalways();	bd12
	(
		dth12,
		sth12,
		dvl12,
		bth12,
		bsg12,
		bvl12,
		bnm12
	);
	bd13
	(
		dth13,
		sth13,
		dvl13,
		bth13,
		bsg13,
		bvl13,
		bnm13
	);
	bd14
	(
		dth14,
		sth14,
		dvl14,
		bth14,
		bsg14,
		bvl14,
		bnm14
	);
	bd23
	(
		dth23,
		sth23,
		dvl23,
		bth23,
		bsg23,
		bvl23,
		bnm23
	);
	bd24
	(
		dth24,
		sth24,
		dvl24,
		bth24,
		bsg24,
		bvl24,
		bnm24
	);
	bd34
	(
		dth34,
		sth34,
		dvl34,
		bth34,
		bsg34,
		bvl34,
		bnm34
	);

}
Ejemplo n.º 4
0
void find_segment::operator()
(
	signal_& ph_pat_p__io,
	signal_& ph_pat_q_p__io,
	signal_& ph_seg_p__io,
	signal_& ph_seg_v_p__io,
	signal_& th_seg_p__io,
	signal_& cpat_seg_p__io,
	signal_& vid__io,
	signal_& hid__io,
	signal_& cid__io,
	signal_& sid__io,
	signal_& ph_match__io,
	signal_& th_match__io,
	signal_& cpat_match__io,
	signal_& clk__io
)
{
	if (!built)
	{
		seg_ch = 2;
		bw_ph = 8;
		bw_th = 7;
		bw_fph = 12;
		bw_fth = 8;
		bw_wg = 7;
		bw_ds = 7;
		bw_hs = 8;
		pat_w_st3 = 3;
		pat_w_st1 = pat_w_st3 + 1;
		full_pat_w_st3 = (1 << (pat_w_st3+1)) - 1;
		full_pat_w_st1 = (1 << (pat_w_st1+1)) - 1;
		padding_w_st1 = full_pat_w_st1 / 2;
		padding_w_st3 = full_pat_w_st3 / 2;
		red_pat_w_st3 = pat_w_st3 * 2 + 1;
		red_pat_w_st1 = pat_w_st1 * 2 + 1;
		fold = 4;
		th_ch11 = seg_ch*seg_ch;
		bw_q = 4;
		bw_addr = 7;
		ph_raw_w = (1 << pat_w_st3) * 15;
		th_raw_w = (1 << bw_th);
		max_drift = 3;
		bw_phi = 12;
		bw_eta = 7;
		ph_hit_w = 40+4;
		ph_hit_w20 = ph_hit_w;
		ph_hit_w10 = 20+4;
		th_hit_w = 56 + 8;
		endcap = 1;
		n_strips = (station <= 1 && cscid <= 2) ? 64 :
						 (station <= 1 && cscid >= 6) ? 64 : 80;
		n_wg = (station <= 1 && cscid <= 3) ? 48  :
					 (station <= 1 && cscid >= 6) ? 32  :
					 (station == 2 && cscid <= 3) ? 112 :
					 (station >= 3 && cscid <= 3) ? 96  : 64;
		th_coverage = (station <= 1 && cscid <= 2) ? 45  :
						 (station <= 1 && cscid >= 6) ? 27  :
						 (station <= 1 && cscid >= 3) ? 39  :
						 (station == 2 && cscid <= 2) ? 43  :
						 (station == 2 && cscid >= 3) ? 56  :
						 (station == 3 && cscid <= 2) ? 34  :
						 (station == 3 && cscid >= 3) ? 52  :
						 (station == 4 && cscid <= 2) ? 28  :
						 (station == 4 && cscid >= 3) ? 50  : 0;
		ph_coverage = (station <= 1 && cscid >= 6) ? 15 : //30 :
						   (station >= 2 && cscid <= 2) ? 40 : 20;
		th_ch = (station <= 1 && cscid <= 2) ? (seg_ch*seg_ch) : seg_ch;
		ph_reverse = (endcap == 1 && station >= 3) ? 1 : 
			   			   (endcap == 2 && station <  3) ? 1 : 0;
		th_mem_sz = (1 << bw_addr);
		th_corr_mem_sz = (1 << bw_addr);
		mult_bw = bw_fph + 11;
		ph_zone_bnd1 = (station <= 1 && cscid <= 2) ? 41 :
							(station == 2 && cscid <= 2) ? 41 :
							(station == 2 && cscid >  2) ? 87 :
							(station == 3 && cscid >  2) ? 49 :
							(station == 4 && cscid >  2) ? 49 : 127;
		ph_zone_bnd2 = (station == 3 && cscid >  2) ? 87 : 127;
		zone_overlap = 2;
		bwr = 6;
		bpow = 6;
		cnr = (1 << bpow);
		cnrex = ph_raw_w;
		tot_diff = max_drift*zone_cham*seg_ch;
		nodiff = ((1 << (bpow+1)) - 1);
		build();
		ph_pat_p.attach(ph_pat_p__io);
		ph_pat_q_p.attach(ph_pat_q_p__io);
		// ph from segments [bx_history][chamber][segment]
// segments are coming from chambers in the interesting zone only
// for example, in zone 0 ME1 segments should come from chambers
// subsector1: 1,2,3, subsector2: 1,2,3
		ph_seg_p.attach(ph_seg_p__io);
		// valid flags for segments
		ph_seg_v_p.attach(ph_seg_v_p__io);
		th_seg_p.attach(th_seg_p__io);
		cpat_seg_p.attach(cpat_seg_p__io);
		clk.attach(clk__io);
		// indexes of best match
		vid.attach(vid__io);
		hid.attach(hid__io);
		cid.attach(cid__io);
		sid.attach(sid__io);
		ph_match.attach(ph_match__io);
		// all th's from matching chamber, we don't know which one will fit best
		th_match.attach(th_match__io);
		cpat_match.attach(cpat_match__io);
	}


	beginalways();
	
	if (posedge (clk))
	{
		ph_pat = ph_pat_p;
		ph_pat_v = ph_pat_q_p != 0; // non-zero quality means valid pattern
		ph_seg = ph_seg_p;
		ph_seg_v = ph_seg_v_p;
		th_seg = th_seg_p;
		cpat_seg = cpat_seg_p;
	
		
		
		// calculate abs differences
		di = 0;
		for (i = 0; i < max_drift; i = i+1) // history loop
		{
			for (j = 0; j < zone_cham; j = j+1) // chamber loop
			{
				for (k = 0; k < seg_ch; k = k+1) // segment loop
				{
					// remove unused low bits from segment ph
					ph_segr = ph_seg[i][j][k](bw_fph-1 , bw_fph-bpow-1);

					// get abs difference
					if (ph_seg_v[i][j][k]){
						ph_diff[i*zone_cham*seg_ch + j*seg_ch + k] = (ph_pat > ph_segr) ? ph_pat - ph_segr : ph_segr - ph_pat;
						if(ph_pat != 127){std::cout<<"\nph_pat = "<<ph_pat<<" and ph_segr = "<<ph_segr<<std::endl;
						std::cout<<"ph_diff["<<i*zone_cham*seg_ch + j*seg_ch + k<<"] = "<<ph_diff[i*zone_cham*seg_ch + j*seg_ch + k]<<std::endl;}
					}
					else{
						ph_diff[i*zone_cham*seg_ch + j*seg_ch + k] = nodiff; // if segment invalid put max value into diff
						//std::cout<<"\nph_pat = "<<ph_pat<<" and ph_segr = "<<ph_segr<<std::endl;
					}

					ri = i;
					rj = j;
					rk = k;
					// diffi variables carry track indexes
					diffi0[i*zone_cham*seg_ch + j*seg_ch + k] = (ri, rj, rk);
				}
			}
		} // for (i = 0; i < max_drift; i = i+1)

		// sort differences
		// first stage
		for (i = 0; i < tot_diff/3; i = i+1)
		{
			// compare 3 values
			rcomp = comp3(ph_diff[i*3], ph_diff[i*3+1], ph_diff[i*3+2]);
			if (( (rcomp) == 0)) {  { cmp1[i] = ph_diff[i*3+0]; diffi1[i] = diffi0[i*3+0]; } } else 
			if (( (rcomp) == 1)) {  { cmp1[i] = ph_diff[i*3+1]; diffi1[i] = diffi0[i*3+1]; } } else 
			if (( (rcomp) == 2)) {  { cmp1[i] = ph_diff[i*3+2]; diffi1[i] = diffi0[i*3+2]; } } 
		}

		// second stage
		for (i = 0; i < tot_diff/9; i = i+1)
		{
			// compare 3 values
			rcomp = comp3(cmp1[i*3], cmp1[i*3+1], cmp1[i*3+2]);
			if (( (rcomp) == 0)) {  { cmp2[i] = cmp1[i*3+0]; diffi2[i] = diffi1[i*3+0]; } } else 
			if (( (rcomp) == 1)) {  { cmp2[i] = cmp1[i*3+1]; diffi2[i] = diffi1[i*3+1]; } } else 
			if (( (rcomp) == 2)) {  { cmp2[i] = cmp1[i*3+2]; diffi2[i] = diffi1[i*3+2]; } } 
		}

		// third stage
		for (i = 0; i < tot_diff/18; i = i+1)
		{
			// compare 2 values
			rcomp[0] = cmp2[i*2] >= cmp2[i*2+1];
			if (( (rcomp[0]) == 0)) {  { cmp3[i] = cmp2[i*2+0]; diffi3[i] = diffi2[i*2+0]; } } else 
			if (( (rcomp[0]) == 1)) {  { cmp3[i] = cmp2[i*2+1]; diffi3[i] = diffi2[i*2+1]; } } 
		}

		// last stage depends on number of input segments
		if (tot_diff == 36)
		{
			// compare 2 values
			rcomp[0] = cmp3[0] >= cmp3[1];
			if (( (rcomp[0]) == 0)) {  { cmp4 = cmp3[0]; diffi4 = diffi3[0]; } } else 
			if (( (rcomp[0]) == 1)) {  { cmp4 = cmp3[1]; diffi4 = diffi3[1]; } } 
		}
		else
		{
			cmp4 = cmp3[0]; 
			diffi4 = diffi3[0];
		}

		(hid, cid, sid) = diffi4;
		vid = ph_seg_v[hid][cid][sid];
		// if pattern invalid remove valid flags 
		if (!ph_pat_v) vid = 0;
		
		ph_match = ph_seg[hid][cid][sid]; // route best matching phi to output
		//if(ph_match)
			//std::cout<<"ph_match = "<<ph_match<<std::endl;
		th_match = th_seg[hid][cid]; // route all th coords from matching chamber to output
		cpat_match = cpat_seg[hid][cid][sid]; // route pattern to output
	}
	endalways();
}
Ejemplo n.º 5
0
void prim_conv11::operator()
  (
   signal_& quality__io,
   signal_& wiregroup__io,
   signal_& hstrip__io,
   signal_& clctpat__io,
   signal_& ph__io,
   signal_& th__io,
   signal_& vl__io,
   signal_& phzvl__io,
   signal_& me11a__io,
   signal_& clctpat_r__io,
   signal_& ph_hit__io,
   signal_& th_hit__io,
   signal_& sel__io,
   signal_& addr__io,
   signal_& r_in__io,
   signal_& r_out__io,
   signal_& we__io,
   signal_& clk__io,
   signal_& control_clk__io
   )
{
  if (!built)
    {
      seg_ch = 2;
      bw_ph = 8;
      bw_th = 7;
      bw_fph = 12;
      bw_fth = 8;
      bw_wg = 7;
      bw_ds = 7;
      bw_hs = 8;
      pat_w_st3 = 3;
      pat_w_st1 = pat_w_st3 + 1;
      full_pat_w_st3 = (1 << (pat_w_st3+1)) - 1;
      full_pat_w_st1 = (1 << (pat_w_st1+1)) - 1;
      padding_w_st1 = full_pat_w_st1 / 2;
      padding_w_st3 = full_pat_w_st3 / 2;
      red_pat_w_st3 = pat_w_st3 * 2 + 1;
      red_pat_w_st1 = pat_w_st1 * 2 + 1;
      fold = 4;
      th_ch11 = seg_ch*seg_ch;
      bw_q = 4;
      bw_addr = 7;
      ph_raw_w = (1 << pat_w_st3) * 15;
      th_raw_w = (1 << bw_th);
      max_drift = 3;
      bw_phi = 12;
      bw_eta = 7;
      ph_hit_w = 40+4;
      ph_hit_w20 = ph_hit_w;
      ph_hit_w10 = 20+4;
      th_hit_w = 56 + 8;
      endcap = 1;
      n_strips = (station <= 1 && cscid <= 2) ? 64 :
	(station <= 1 && cscid >= 6) ? 64 : 80;
      n_wg = (station <= 1 && cscid <= 3) ? 48  :
	(station <= 1 && cscid >= 6) ? 32  :
	(station == 2 && cscid <= 3) ? 112 :
	(station >= 3 && cscid <= 3) ? 96  : 64;
      th_coverage = (station <= 1 && cscid <= 2) ? 45  :
	(station <= 1 && cscid >= 6) ? 27  :
	(station <= 1 && cscid >= 3) ? 39  :
	(station == 2 && cscid <= 2) ? 43  :
	(station == 2 && cscid >= 3) ? 56  :
	(station == 3 && cscid <= 2) ? 34  :
	(station == 3 && cscid >= 3) ? 52  :
	(station == 4 && cscid <= 2) ? 28  :
	(station == 4 && cscid >= 3) ? 50  : 0;
      ph_coverage = (station <= 1 && cscid >= 6) ? 15 : //30 :
	(station >= 2 && cscid <= 2) ? 40 : 20;
      th_ch = (station <= 1 && cscid <= 2) ? (seg_ch*seg_ch) : seg_ch;
      ph_reverse = (endcap == 1 && station >= 3) ? 1 : 
	(endcap == 2 && station <  3) ? 1 : 0;
      th_mem_sz = (1 << bw_addr);
      th_corr_mem_sz = (1 << bw_addr);
      mult_bw = bw_fph + 11;
      ph_zone_bnd1 = (station <= 1 && cscid <= 2) ? 41 :
	(station == 2 && cscid <= 2) ? 41 :
	(station == 2 && cscid >  2) ? 87 :
	(station == 3 && cscid >  2) ? 49 :
	(station == 4 && cscid >  2) ? 49 : 127;
      ph_zone_bnd2 = (station == 3 && cscid >  2) ? 87 : 127;
      zone_overlap = 2;
      bwr = 6;
      bpow = 6;
      cnr = (1 << bpow);
      cnrex = ph_raw_w;
      build();
      // input parameters from MPC
      quality.attach(quality__io);
      wiregroup.attach(wiregroup__io);
      hstrip.attach(hstrip__io);
      clctpat.attach(clctpat__io);
      sel.attach(sel__io);
      addr.attach(addr__io);
      r_in.attach(r_in__io);
      we.attach(we__io);
      clk.attach(clk__io);
      control_clk.attach(control_clk__io);
      // outputs
      // low-precision ph, only for detection
      // high-precision ph with displacement correction will be calculated when 
      // 3 best tracks are found.
      ph.attach(ph__io);
      // full precision th, but without displacement correction, takes th duplication into account
      th.attach(th__io);
      // one-bit valid flags
      vl.attach(vl__io);
      phzvl.attach(phzvl__io);
      me11a.attach(me11a__io);
      clctpat_r.attach(clctpat_r__io);
      // ph and th raw hits
      ph_hit.attach(ph_hit__io);
      th_hit.attach(th_hit__io);
      r_out.attach(r_out__io);
    }

	
  pc_id(3,0) = cscid;
  pc_id(7,4) = station;
	
  r_out = (sel == const_(2, 0x0UL)) ? params[addr] : 
    (sel == const_(2, 0x1UL)) ? th_mem[addr] : 
    (sel == const_(2, 0x2UL)) ? th_corr_mem[addr] : pc_id;

  beginalways();	

  if (posedge (control_clk))
    {
      if (( (sel) == 0)) {  { if (we) params     [addr] = r_in; } } else 
	if (( (sel) == 1)) {  { if (we) th_mem     [addr] = r_in; } } else 
	  if (( (sel) == 2)) {  { if (we) th_corr_mem[addr] = r_in(3,0); } } 
    }
  endalways();

  beginalways();
	
  if (posedge (clk))
    {

      // zero outputs
      vl = 0;
      phzvl = 0;
      for (i = 0; i < seg_ch; i = i+1) { fph[i] = 0; clctpat_r[i] = 0; }
      for (i = 0; i < th_ch;  i = i+1) th[i] = 0;
      ph_hit = 0;
      th_hit = 0;

      for (i = 0; i < seg_ch; i = i+1)
	{

	  factor[i] = (station <= 1 && cscid <= 2 && hstrip[i] > 127) ? 1707 : // ME1/1a
	    1301; // ME1/1b
				 
	  //if(factor[i])
	  //	std::cout<<"factor 11 = "<<factor[i]<<std::endl;

	  me11a_w[i] = (station <= 1 && cscid <= 2 && hstrip[i] > 127);
	  if (( (clctpat[i]) == 0)) {  { clct_pat_corr = const_(3, 0x0UL); clct_pat_sign = 0; } } else 
	    if (( (clctpat[i]) == 1)) {  { clct_pat_corr = const_(3, 0x0UL); clct_pat_sign = 0; } } else 
	      if (( (clctpat[i]) == 2)) {  { clct_pat_corr = const_(3, 0x5UL); clct_pat_sign = 1; } } else 
		if (( (clctpat[i]) == 3)) {  { clct_pat_corr = const_(3, 0x5UL); clct_pat_sign = 0; } } else 
		  if (( (clctpat[i]) == 4)) {  { clct_pat_corr = const_(3, 0x5UL); clct_pat_sign = 1; } } else 
		    if (( (clctpat[i]) == 5)) {  { clct_pat_corr = const_(3, 0x5UL); clct_pat_sign = 0; } } else 
		      if (( (clctpat[i]) == 6)) {  { clct_pat_corr = const_(3, 0x2UL); clct_pat_sign = 1; } } else 
			if (( (clctpat[i]) == 7)) {  { clct_pat_corr = const_(3, 0x2UL); clct_pat_sign = 0; } } else 
			  if (( (clctpat[i]) == 8)) {  { clct_pat_corr = const_(3, 0x2UL); clct_pat_sign = 1; } } else 
			    if (( (clctpat[i]) == 9)) {  { clct_pat_corr = const_(3, 0x2UL); clct_pat_sign = 0; } } else 
			      if (( (clctpat[i]) == 10)) {  { clct_pat_corr = const_(3, 0x0UL); clct_pat_sign = 0; } } else  {  { clct_pat_corr = const_(3, 0x0UL); clct_pat_sign = 0; } } 

	  // reverse clct pattern correction if chamber is reversed
	  //			if (ph_reverse) clct_pat_sign = ~clct_pat_sign;

	  // convert into 1/8 strips and remove ME1/1a offset (512=128*4)
	  eight_str[i]  = (const_s(2, 0x0UL), hstrip [i], const_s(2, 0x0UL)) - (me11a_w[i] ? 512 : 0);
			
	  // clct pattern correction
	  if (clct_pat_sign == 0) eight_str[i] = eight_str[i] + clct_pat_corr(2,1);
	  else eight_str[i] = eight_str[i] - clct_pat_corr(2,1);

	  if (quality[i])
	    {
	      vl[i] = 1;
	      // ph conversion
	      // for factors 1024 and 2048 the multiplier should be replaced with shifts by synthesizer
	      mult = eight_str[i] * factor[i];
	      ph_tmp = mult(mult_bw-1 , 10);
	      //std::cout<<"ph_tmp = "<<ph_tmp<<std::endl;
	      ph_init_ix =  me11a_w[i] ? const_(3, 2UL) : const_(3, 0UL); // index of ph_init parameter to apply (different for ME11a and b)
	      //std::cout<<"ph_init_ix = "<<ph_init_ix<<std::endl;
	      if (ph_reverse)
		{
		  fph[i] = params[ph_init_ix] - ph_tmp;
		  // set ph raw hits
		  ph_hit[ph_coverage - ph_tmp(bw_fph-1,5) + params[ph_init_ix + const_(3, 1UL)](7,1)] = 1;
		}
	      else
		{            
		  fph[i] = params[ph_init_ix] + ph_tmp;
		  // set ph raw hits
		  ph_hit[ph_tmp(bw_fph-1,5) + params[ph_init_ix + const_(3, 1UL)](7,1)] = 1;
		  /* -----\/----- EXCLUDED -----\/-----
		  // add hits to take ME11a strip ganging into account
		  // offsets of 14 and 28 is what I observe from MC. Calculations show 11.6 and 23.2 (???)
		  if (me11a_w[i])
		  {
		  ph_hit[ph_tmp(bw_fph-1,5) + params[2] + 14] = 1;
		  ph_hit[ph_tmp(bw_fph-1,5) + params[2] + 28] = 1;
		  }
		  -----/\----- EXCLUDED -----/\----- */
		}
				
	      //std::cout<<"estr = "<<eight_str[i]<<", factor = "<<factor[i]<<", ph_rev = "<<ph_reverse<<", ph_tmp = "<<ph_tmp<<std::endl;
	      //std::cout<<"ph_hit = "<<ph_tmp(bw_fph-1,5) + params[ph_init_ix + const_(3, 1UL)](7,1)<<std::endl;
	      //std::cout<<"strip = "<<hstrip[i]<<", Id = "<<cscid + 1<<",phinit = "<<(params[ph_init_ix])<<"ph_cov = "<<ph_coverage<<", and phshift = "<<(ph_tmp(bw_fph-1,5))<<", and phdisp = "<<(params[ph_init_ix + const_(3, 1UL)](7,1))<<"\n\n\n";
				
				
	      wg = wiregroup[i];
	      // th conversion
	      // call appropriate LUT, it returns th[i] relative to wg0 of that chamber
	      th_orig = th_mem[wg];
	      //std::cout<<"wire = "<<wg<<", th_mem[wg] = "<<th_orig<<std::endl;


	      // need th duplication here
	      for (j = 0; j < seg_ch; j = j+1)
		{
		  if (quality[j])
		    {
		      // calculate correction for each strip number
		      // index is: (wiregroup(2 MS bits), dblstrip(5-bit for these chambers))
		      index = (wg(5,4), eight_str[j](8,4));
		      th_corr = th_corr_mem[index];
		      //std::cout<<"eightstrip = "<<eight_str[j]<<", eightstrip(8,4) = "<<eight_str[j](8,4)<<", index = "<<index<<", th_corr = "<<th_corr<<std::endl;

		      //std::cout<<"th_corr = "<<th_corr<<" and th_orig = "<<th_orig<<std::endl;
		      // apply correction to the corresponding output
		      if (ph_reverse) th_tmp = (th_orig - th_corr) & const_(6, 0x3fUL);
		      else            th_tmp = (th_orig + th_corr) & const_(6, 0x3fUL);
		      //std::cout<<"ph_reverse = "<<ph_reverse<<" ";
		      //if(th_tmp)std::cout<<"th_tmp = "<<th_tmp<<" and thcoverage = "<<th_coverage<<std::endl;
		      // check that correction did not make invalid value outside chamber coverage
		      // this will actually take care of both positive and negative illegal values
		      if (th_tmp < th_coverage) 
			{
			  // apply initial th value for that chamber
			  th[i*seg_ch+j] = th_tmp + params[4];
			  //std::cout<<"params[4] = "<<params[4]<<"\n";
							
			  // th hits
			  th_hit[th_tmp + params[5]] = 1;
							
							
			  // check which zones ph hits should be applied to
			  if (th[i*seg_ch+j] <= (ph_zone_bnd1 + zone_overlap)) phzvl[0] = 1;
			  if (th[i*seg_ch+j] >  (ph_zone_bnd2 - zone_overlap)) phzvl[2] = 1;
			  if (
			      (th[i*seg_ch+j] >  (ph_zone_bnd1 - zone_overlap)) &&
			      (th[i*seg_ch+j] <= (ph_zone_bnd2 + zone_overlap))
			      ) phzvl[1] = 1;
			  //std::cout<<"ph_zone_bnd1 = "<<ph_zone_bnd1<<std::endl;
			  //std::cout<<"phzvl = "<<phzvl<<std::endl;
			}
		    }
		}
	      clctpat_r[i] = clctpat[i]; // just propagate pattern downstream
	    } // if (quality[i])
			
	  ph[i] = fph[i];
	  //if(fph[i]) std::cout<<"fph["<<i<<"] = "<<fph[i]<<" and vl[i] = "<<vl[i]<<std::endl;
			
	} // for (i = 0; i < seg_ch; i = i+1)
      me11a = me11a_w;
    }
  endalways();
}
Ejemplo n.º 6
0
void prim_conv::operator()
(
	signal_& quality__io,
	signal_& wiregroup__io,
	signal_& hstrip__io,
	signal_& clctpat__io,
	signal_& ph__io,
	signal_& th__io,
	signal_& vl__io,
	signal_& phzvl__io,
	signal_& me11a__io,
	signal_& clctpat_r__io,
	signal_& ph_hit__io,
	signal_& th_hit__io,
	signal_& sel__io,
	signal_& addr__io,
	signal_& r_in__io,
	signal_& r_out__io,
	signal_& we__io,
	signal_& clk__io,
	signal_& control_clk__io
)
{
	if (!built)
	{
		seg_ch = 2;
		bw_ph = 8;
		bw_th = 7;
		bw_fph = 12;
		bw_fth = 8;
		bw_wg = 7;
		bw_ds = 7;
		bw_hs = 8;
		pat_w_st3 = 3;
		pat_w_st1 = pat_w_st3 + 1;
		full_pat_w_st3 = (1 << (pat_w_st3+1)) - 1;
		full_pat_w_st1 = (1 << (pat_w_st1+1)) - 1;
		padding_w_st1 = full_pat_w_st1 / 2;
		padding_w_st3 = full_pat_w_st3 / 2;
		red_pat_w_st3 = pat_w_st3 * 2 + 1;
		red_pat_w_st1 = pat_w_st1 * 2 + 1;
		fold = 4;
		th_ch11 = seg_ch*seg_ch;
		bw_q = 4;
		bw_addr = 7;
		ph_raw_w = (1 << pat_w_st3) * 15;
		th_raw_w = (1 << bw_th);
		max_drift = 3;
		bw_phi = 12;
		bw_eta = 7;
		ph_hit_w = 40+4;
		ph_hit_w20 = ph_hit_w;
		ph_hit_w10 = 20+4;
		th_hit_w = 56 + 8;
		endcap = 1;
		n_strips = (station <= 1 && cscid <= 2) ? 64 :
						 (station <= 1 && cscid >= 6) ? 64 : 80;
		n_wg = (station <= 1 && cscid <= 3) ? 48  :
					 (station <= 1 && cscid >= 6) ? 32  :
					 (station == 2 && cscid <= 3) ? 112 :
					 (station >= 3 && cscid <= 3) ? 96  : 64;
		th_coverage = (station <= 1 && cscid <= 2) ? 45  :
						 (station <= 1 && cscid >= 6) ? 27  :
						 (station <= 1 && cscid >= 3) ? 39  :
						 (station == 2 && cscid <= 2) ? 43  :
						 (station == 2 && cscid >= 3) ? 56  :
						 (station == 3 && cscid <= 2) ? 34  :
						 (station == 3 && cscid >= 3) ? 52  :
						 (station == 4 && cscid <= 2) ? 28  :
						 (station == 4 && cscid >= 3) ? 50  : 0;
		ph_coverage = (station <= 1 && cscid >= 6) ? 15 : //30 :
						   (station >= 2 && cscid <= 2) ? 40 : 20;
		th_ch = (station <= 1 && cscid <= 2) ? (seg_ch*seg_ch) : seg_ch;
		ph_reverse = (endcap == 1 && station >= 3) ? 1 : 
			   			   (endcap == 2 && station <  3) ? 1 : 0;
		th_mem_sz = (1 << bw_addr);
		th_corr_mem_sz = (1 << bw_addr);
		mult_bw = bw_fph + 11;
		ph_zone_bnd1 = (station <= 1 && cscid <= 2) ? 41 :
							(station == 2 && cscid <= 2) ? 41 :
							(station == 2 && cscid >  2) ? 87 :
							(station == 3 && cscid >  2) ? 49 :
							(station == 4 && cscid >  2) ? 49 : 127;
		ph_zone_bnd2 = (station == 3 && cscid >  2) ? 87 : 127;
		zone_overlap = 2;
		bwr = 6;
		bpow = 6;
		cnr = (1 << bpow);
		cnrex = ph_raw_w;
		build();
		// input parameters from MPC
		quality.attach(quality__io);
		wiregroup.attach(wiregroup__io);
		hstrip.attach(hstrip__io);
		clctpat.attach(clctpat__io);
		sel.attach(sel__io);
		addr.attach(addr__io);
		r_in.attach(r_in__io);
		we.attach(we__io);
		clk.attach(clk__io);
		control_clk.attach(control_clk__io);
		// outputs
// phi
		ph.attach(ph__io);
		// full precision th, but without displacement correction
		th.attach(th__io);
		// one-bit valid flags
		vl.attach(vl__io);
		phzvl.attach(phzvl__io);
		me11a.attach(me11a__io);
		clctpat_r.attach(clctpat_r__io);
		// ph and th raw hits
		ph_hit.attach(ph_hit__io);
		th_hit.attach(th_hit__io);
		r_out.attach(r_out__io);
	}


	 pc_id(3,0) = cscid;
	 pc_id(7,4) = station;
	


	// ME11 special case
	// all other stations
	 r_out = (sel == const_(2, 0x0UL)) ? params[addr] : 
				   (sel == const_(2, 0x1UL)) ? th_mem[addr] : pc_id;

	beginalways();	

	if (posedge (control_clk))
	{
		if (( (sel) == 0)) {  { if (we) params [addr] = r_in; } } else 
		if (( (sel) == 1)) {  { if (we) th_mem [addr] = r_in; } }  // case (sel)
	}
	endalways();

	beginalways();

	
	if (posedge (clk))
	{

		// zero outputs
		vl = 0;
		phzvl = 0;
		for (i = 0; i < seg_ch; i = i+1) { fph[i] = 0; th[i] = 0; clctpat_r[i] = 0; }
		ph_hit = 0;
		th_hit = 0;
		

		// strip width factor relative to ME234/2 
		// 1024 == 1
		factor = (station <= 1 && cscid >= 6) ? 947 : // ME1/3
				 1024; // all other chambers
				 
		//if(factor)
		//	std::cout<<"factor else = "<<factor<<std::endl;

		for (i = 0; i < seg_ch; i = i+1)
		{

			me11a_w[i] = 0;
			if (( (clctpat[i]) == 0)) {  { clct_pat_corr = const_(3, 0x0UL); clct_pat_sign = 0; } } else 
			if (( (clctpat[i]) == 1)) {  { clct_pat_corr = const_(3, 0x0UL); clct_pat_sign = 0; } } else 
			if (( (clctpat[i]) == 2)) {  { clct_pat_corr = const_(3, 0x5UL); clct_pat_sign = 1; } } else 
			if (( (clctpat[i]) == 3)) {  { clct_pat_corr = const_(3, 0x5UL); clct_pat_sign = 0; } } else 
			if (( (clctpat[i]) == 4)) {  { clct_pat_corr = const_(3, 0x5UL); clct_pat_sign = 1; } } else 
			if (( (clctpat[i]) == 5)) {  { clct_pat_corr = const_(3, 0x5UL); clct_pat_sign = 0; } } else 
			if (( (clctpat[i]) == 6)) {  { clct_pat_corr = const_(3, 0x2UL); clct_pat_sign = 1; } } else 
			if (( (clctpat[i]) == 7)) {  { clct_pat_corr = const_(3, 0x2UL); clct_pat_sign = 0; } } else 
			if (( (clctpat[i]) == 8)) {  { clct_pat_corr = const_(3, 0x2UL); clct_pat_sign = 1; } } else 
			if (( (clctpat[i]) == 9)) {  { clct_pat_corr = const_(3, 0x2UL); clct_pat_sign = 0; } } else 
			if (( (clctpat[i]) == 10)) {  { clct_pat_corr = const_(3, 0x0UL); clct_pat_sign = 0; } } else  {  { clct_pat_corr = const_(3, 0x0UL); clct_pat_sign = 0; } } 

			// reverse clct pattern correction if chamber is reversed
//			if (ph_reverse) clct_pat_sign = ~clct_pat_sign;
			
			// 10 deg chambers		
			if (station < 2 || cscid > 2)
			{
				eight_str[i]  = (const_s(2, 0x0UL), hstrip [i], const_s(2, 0x0UL)); // full precision, uses only 2 bits of clct pattern correction
				if (clct_pat_sign == 0) eight_str[i] = eight_str[i] + clct_pat_corr(2,1);
				else eight_str[i] = eight_str[i] - clct_pat_corr(2,1);
			}
			else
			{
				// 20 deg chambers
				eight_str[i]  = (const_s(1, 0x0UL), hstrip [i], const_s(3, 0x0UL)); // multiply by 2, uses all 3 bits of pattern correction
				if (clct_pat_sign == 0) eight_str[i] = eight_str[i] + clct_pat_corr;
				else eight_str[i] = eight_str[i] - clct_pat_corr;
			}
			
			
			if (quality[i])
			{
				vl[i] = 1;
				// ph conversion
				// for factors 1024 and 2048 the multiplier should be replaced with shifts by synthesizer
				mult = eight_str[i] * factor;
				ph_tmp = mult(mult_bw-1 , 10);
				if (ph_reverse)
				{
					fph[i] = params[0] - ph_tmp;
					// set ph raw hits
					ph_hit[ph_coverage - ph_tmp(bw_fph-1,5) + params[2](7,1)] = 1;
				}
				else
				{            
					fph[i] = params[0] + ph_tmp;
					// set ph raw hits
					ph_hit[ph_tmp(bw_fph-1,5) + params[2](7,1)] = 1;
				}
				
				if(fph[i])
					std::cout<<"fph["<<i<<"] = "<<fph[i]<<" and vl[i] = "<<vl[i]<<std::endl;
				//std::cout<<"estr = "<<eight_str[i]<<", factor = "<<factor<<", ph_rev = "<<ph_reverse<<", ph_tmp = "<<ph_tmp<<std::endl;
				//std::cout<<"strip = "<<hstrip[i]<<", Id = "<<cscid + 1<<",phinit = "<<params[0]<<"ph_cov = "<<ph_coverage<<", and phshift = "<<ph_tmp(bw_fph-1,5)<<", and params[2] = "<<params[2](7,1)<<"\n\n\n";
				wg = wiregroup[i];
				// th conversion
				th_tmp = th_mem[wg];
				th[i] = th_tmp + params[1];

				th_hit[th_tmp + params[3]] = 1;

				// check which zones ph hits should be applied to
				if (th[i] <= (ph_zone_bnd1 + zone_overlap)) phzvl[0] = 1;
				if (th[i] >  (ph_zone_bnd2 - zone_overlap)) phzvl[2] = 1;
				if (
					(th[i] >  (ph_zone_bnd1 - zone_overlap)) &&
					(th[i] <= (ph_zone_bnd2 + zone_overlap))
					) phzvl[1] = 1;

				clctpat_r[i] = clctpat[i]; // just propagate pattern downstream
				std::cout<<"phzvl = "<<phzvl<<std::endl;
			} // if (quality[i])

			ph[i] = fph[i];
		}
		me11a = 0;
	}
	endalways();
}