#include "dsat_util.h" #include #include #include #include #include #include #include #include #define ERROR -1 #define OK 0 #define maxLineLength 200 //#define RAND_MAX 0xfffffff; #define N 0x80000 //following are some constants and lookup tables #define SAME 2 // in the same segment(22 fibres), if rightmost track is within SAME number of fibres to the leftmost track, consider them the same int dblt_window[8][2] = {17,32,21,40,25,48,29,56,33,64,37,72,41,80,45,88}; int pt_lut[4][8] = {{80,27,16,12},{9,7,6,5},{4,4,3,3},{3,3,2,2,1}}; int xpl_lut[44] = {8,8,9,9,9,10,10,10,11,11,11,12,12,12,13,13,14,14,14,15,15,15,16,16,16,17,17,17,18,18,19,19,19, 20,20,20,21,21,21,22,22,22,23,23}; int xpl_offset[4] = {1,2,3,5}; int match_window[4] = {1,2,2,4}; //end of constants and lookup tables //stores track equations unsigned char eqs[2][N][16]; //stores pointers to eqs in the order of max, high, med and low unsigned int m[2][1761]; //stores u7 link_array to signlet and cps conversion table, last index [0]: layer [1]: fibre [2]: cps char evn_conv[6][196][3]; //stores u9 link_array to signlet and cps conversion table, last index [0]: layer [1]: fibre [2]: cps char odd_conv[6][196][3]; //stores dead doublets char dead_dblt[2][8][90]; //stores singlet hits unsigned char sglt[2][16][90]; //stores doublet hits unsigned char dblt[2][8][90]; //stores cps hits unsigned char cps[2][32]; // int octant[2] = {0}, sector[2] = {0}, turn = 0, tick = 0, wait4sg = 0, wait4fc = 0; //simulation data int scl_data[73]; int link_data[8][511]; //simulation results int mu_trk[73][2][7]; int ctoc[73][2][7]; int l2cft[73][2][27]; int l2cps[73][2][11]; int lvds_out[73][2]; char r2a; int en_new[2],version; int singlet_eq[14]; // command table typedef struct { char *name; int nargs; } a_cmd; // positions in table correspond to switch() constants below! static a_cmd cmds[] = { "help", 0, "quit", 0, "w_csr", 2, "r_csr", 2, "trig", 2, "w_ram", 4, "r_ram",4, "w_dfea",3, "r_dfea",3, "w_cnt",3, "r_cnt",2, "ld_ram",3, "wait",0, "eqs",1, "sim",0, "check",1, "setup",0, "prog",2, "rnd_test",0 }; #define N_CMD (sizeof(cmds)/sizeof(a_cmd)) int parse_command( char *pb, char *tok[], unsigned int tokn[], int maxt); char *rl_gets (); int rd_eqs( char *file_name); int sim(int fd, int event); int w_dfea(int fd, int addr, int data); int r_dfea(int fd, int addr); int programChip(int fd,int chip,char *Filename); int rnd_test(int fd, int cycle_num, int seed); static FILE *fp = NULL; // script input main( argc, argv) int argc; char *argv[]; { int fd = 0; FILE *ifp; int i,j,k,l,n,lnk[6] = {0,2,3,4,5,6}; int start_addr,init_flag,first_data,singlet,bad_version; unsigned addr,buf,data[512]; char line[maxLineLength]; int nt; // number of tokens in input char *pb, *tp; // buffer pointer, token pointer char *tok[16]; // tokens in input commands char *link[8] = {"link1","link2","link3","link4","link5","link6","link7","link8"}; char *slayer[16] = {"ai","ao","bi","bo","ci","co","di","do","ei","eo","fi","fo","gi","go","hi","ho"}; char *dlayer[8] = {"a(","b(","c(","d(","e(","f(","g(","h("}; int dblt_range[8][2] = {3,46,5,56,9,64,14,71,21,76,28,81,38,83,44,89}; unsigned int tokn[16]; // numeric conversion of tokens static char *usage = "usage: dfea_test [script_file] [-p mcs_list]"; if ( (fd = dsat_open((char*)DEVICE, O_RDWR|O_NONBLOCK)) <= 0 ) { perror("DSAT: Cannot open device"); exit(1); } if( argc > 1) { for(i = 1; i < argc; i++) if(!strncasecmp(argv[i],"-p",2)){ if(argc > i+1){ if( (fp = fopen( argv[i+1], "r")) == NULL) { printf("Can't find mcs file %s\n",argv[i+1]); exit(1); } } else{ if( (fp = fopen("mcs_list", "r")) == NULL) { printf("Can't find file mcs_list\n"); exit(1); } } while( fgets(line,maxLineLength-1,fp) != NULL) { nt = parse_command( line, tok, tokn, 15); programChip(fd,tokn[0],tok[1]); } fclose(fp); fp = NULL; argc = i; } } if(argc > 1) if( (fp = fopen( argv[1], "r")) == NULL) { printf( "Can't open script file %s\n",argv[1]); exit(1); } while( (pb = rl_gets()) != NULL) { nt = parse_command( pb, tok, tokn, 15); if (nt) { for (i = 0; i < N_CMD; i++) { if(!strncasecmp( tok[0], cmds[i].name, strlen(tok[0]))) { switch( i) { case 0 : // help printf("help\n"); printf("w_csr [txn | rxn | mun | scl] [data] : write data to CSR\n"); printf("r_csr [txn | rxn | mun | scl] : read CSR\n"); printf("trig : send a global trigger\n"); printf("w_ram [txn | scl] [start_addr] [first data location in a line for lvds_tx data]\n"); printf("r_ram [txn | rxn | mun | scl] [word count] [start_addr]\n"); printf("w_dfea [address] [data] : write data to dfea at address\n"); printf("r_dfea [address] [N(default 1] : read N data words from dfea starting at address\n"); printf("w_cnt [txn | rxn | mun | scl] [data] : write data to word/delay count registers\n"); printf("r_cnt [txn | rxn | mun | scl] : read data from word/delay count registers\n"); printf("ld_ram [txn | scl] [data] : fills ram with data\n"); break; case 1 : //quit return OK; case 2 : // w_csr if(nt < 3){ printf("usage : w_csr [txn | rxn | mun | scl] content of CSR\n"); break; } if(!strncasecmp(tok[1],"tx",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 7) for(j = 0; j < 8; j++) dsat_write_word(fd,(2+j)*16+2,&tokn[2]); else dsat_write_word(fd,(2+j)*16+2,&tokn[2]); } if(!strncasecmp(tok[1],"rx",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 3) for(j = 0; j < 4; j++) dsat_write_word(fd,(10+j)*16+2,&tokn[2]); else dsat_write_word(fd,(10+j)*16+2,&tokn[2]); } if(!strncasecmp(tok[1],"mu",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 1) for(j = 0; j < 2; j++) dsat_write_word(fd,(14+j)*16+2,&tokn[2]); else dsat_write_word(fd,(14+j)*16+2,&tokn[2]); } if(!strcmp(tok[1],"scl")) dsat_write_word(fd,2,&tokn[2]); break; case 3 : // r_csr if(!strncasecmp(tok[1],"tx",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 7) for(j = 0; j < 8; j++){ dsat_read_word(fd,(2+j)*16+2,&buf); buf &= 0xff; printf("read tx%d csr: 0x%02x\n",j, buf); } else{ dsat_read_word(fd,(2+j)*16+2,&buf); buf &= 0xff; printf("read %s csr: 0x%02x\n",tok[1], buf); } } if(!strncasecmp(tok[1],"rx",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 3) for(j = 0; j < 4; j++){ dsat_read_word(fd,(10+j)*16+2,&buf); buf &= 0xff; printf("read rx%d csr: 0x%02x\n",j, buf); } else{ dsat_read_word(fd,(10+j)*16+2,&buf); buf &= 0xff; printf("read %s csr: 0x%02x\n",tok[1], buf); } } if(!strncasecmp(tok[1],"mu",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 1) for(j = 0; j < 2; j++){ dsat_read_word(fd,(14+j)*16+2,&buf); buf &= 0xff; printf("read mu%d csr: 0x%02x\n",j, buf); } else{ dsat_read_word(fd,(14+j)*16+2,&buf); buf &= 0xff; printf("read %s csr: 0x%02x\n",tok[1], buf); } } if(!strcmp(tok[1],"scl")){ dsat_read_word(fd,2,&buf); buf &= 0xff; printf("read %s csr: 0x%02x\n",tok[1], buf); } break; case 4 : // trig buf = 5; if(nt == 2){ j = tokn[1]; //repeat counter if(j & 0xffff00) buf = ((j & 0xffff00) << 8) + 1; //tick trigger if((j & 0xff) <= 0x9e){ j = (j & 0xff) - 4; if(j < 0) j += 0x9f; buf += (j << 8) + 8; } } printf("trigger word = 0x%08x\n",buf); if(version < 0xc) buf += 64; dsat_write_word(fd,2,&buf); break; case 5 : // w_ram if(!strcmp(tok[1],"tx")){ init_flag = 0; if(nt > 2){ start_addr = tokn[2]; init_flag = 255; } first_data = 4; if(nt == 4)first_data = tokn[3]; while((pb = rl_gets()) != NULL){ nt = parse_command( pb, tok, tokn, 16); if(!strncasecmp(tok[0],"end",3)) break; for(j=0;j<8;j++) if(!strncasecmp( tok[0], link[j], 5)) { if(init_flag & (1 << j)){ dsat_write_word(fd,(2+j)*16,&start_addr); init_flag &= 255 - (1 << j); } dsat_write_mem(fd,(2+j)*16+1,nt-first_data+1,&tokn[first_data-1]); } } } if(!strcmp(tok[1],"scl")){ init_flag = 0; if(nt > 2) dsat_write_word(fd,0,&tokn[2]); while((pb = rl_gets()) != NULL){ nt = parse_command( pb, tok, tokn, 16); if(!strncasecmp(tok[0],"end",3)) break; dsat_write_mem(fd,1,nt,&tokn[0]); } } break; case 6 : // r_ram // lvds_tx if(!strncasecmp(tok[1],"tx",2)){ sscanf( tok[1]+2, "%d", &j); if(nt < 3)tokn[2] = 7; //default word count if(tokn[2] > 512)tokn[2] = 512; if(nt < 4) tokn[3] = 0; if(j > 7) for(j = 0; j < 8; j++){ dsat_write_word(fd,(2+j)*16,&tokn[3]); dsat_read_mem(fd,(2+j)*16+1,tokn[2],&data[0]); for(l = 0; 7*l < tokn[2]; l++){ printf("tx%d addr0x%03x",j,tokn[3]+l*7); for(k = 0; k < 7; k++) if((l*7+k) < tokn[2]) printf(" %08x",data[l*7+k]); printf("\n"); } } else{ dsat_write_word(fd,(2+j)*16,&tokn[3]); dsat_read_mem(fd,(2+j)*16+1,tokn[2],&data[0]); printf("read %s data:\n",tok[1]); for(j = 0; 7*j < tokn[2]; j++){ printf(" %02d addr0x%03x",j+1,tokn[3]+j*7); for(k = 0; k < 7; k++) if((j*7+k) < tokn[2]) printf(" %08x",data[j*7+k]); printf("\n"); } } } // lvds_rx if(!strncasecmp(tok[1],"rx",2)){ sscanf( tok[1]+2, "%d", &j); if(nt < 3)tokn[2] = 7; //default word count if(tokn[2] > 512)tokn[2] = 512; if(nt < 4) tokn[3] = 0; dsat_write_word(fd,(10+j)*16,&tokn[3]); dsat_read_mem(fd,(10+j)*16+1,tokn[2],&data[0]); printf("read %s data:\n",tok[1]); for(j = 0; 7*j < tokn[2]; j++){ printf(" %02d addr0x%03x",j+1,tokn[3]+j*7); for(k = 0; k < 7; k++) if((j*7+k) < tokn[2]) printf(" %08x",data[j*7+k]); printf("\n"); } } // sldb if(!strncasecmp(tok[1],"mu",2)){ sscanf( tok[1]+2, "%d", &j); if(nt < 3)tokn[2] = 7; //default word count if(tokn[2] > 512)tokn[2] = 512; if(nt < 4) tokn[3] = 0; dsat_write_word(fd,(14+j)*16,&tokn[3]); dsat_read_mem(fd,(14+j)*16+1,tokn[2],&data[0]); printf("read %s data:\n",tok[1]); for(j = 0; 7*j < tokn[2]; j++){ printf(" %02d addr0x%03x",j+1,tokn[3]+j*7); for(k = 0; k < 7; k++) if((j*7+k) < tokn[2]) printf(" %08x",data[j*7+k]); printf("\n"); } } // scl if(!strcmp(tok[1],"scl")){ if(nt < 3)tokn[2] = 7; //default word count if(tokn[2] > 512)tokn[2] = 512; if(nt < 4) tokn[3] = 0; dsat_write_word(fd,0,&tokn[3]); dsat_read_mem(fd,1,tokn[2],&data[0]); printf("read %s data:\n",tok[1]); for(j = 0; 7*j < tokn[2]; j++){ printf(" %02d addr0x%03x",j+1,tokn[3]+j*7); for(k = 0; k < 7; k++) if((j*7+k) < tokn[2]) printf(" %08x",data[j*7+k]); printf("\n"); } } break; case 7 : // write dfea if(nt == 3) w_dfea(fd,tokn[1],tokn[2]); break; case 8 : // read dfea if(nt >= 2){ j = 1; if(nt == 3)j = tokn[2]; while(j-- > 0){ printf("address 0x%x data 0x%04x\n",tokn[1],r_dfea(fd,tokn[1])); tokn[1]++; } } break; case 9 : // w_cnt if(nt < 3){ printf("usage : w_cnt [txn | rxn | mun | scl] content of CSR\n"); break; } tokn[2] &= 0x2ff; if(!strncasecmp(tok[1],"rx",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 3) for(j = 0; j < 4; j++) dsat_write_word(fd,(10+j)*16+3,&tokn[2]); else dsat_write_word(fd,(10+j)*16+3,&tokn[2]); } if(!strncasecmp(tok[1],"mu",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 1) for(j = 0; j < 2; j++) dsat_write_word(fd,(14+j)*16+3,&tokn[2]); else dsat_write_word(fd,(14+j)*16+3,&tokn[2]); } tokn[2] &= 0x1ff; if(!strncasecmp(tok[1],"tx",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 7) for(j = 0; j < 8; j++) dsat_write_word(fd,(2+j)*16+3,&tokn[2]); else dsat_write_word(fd,(2+j)*16+3,&tokn[2]); } tokn[2] &= 0xff; if(!strcmp(tok[1],"scl")) dsat_write_word(fd,3,&tokn[2]); break; case 10 : // r_cnt if(!strncasecmp(tok[1],"tx",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 7) for(j = 0; j < 8; j++){ dsat_read_word(fd,(2+j)*16+3,&buf); buf &= 0x1ff; printf("read tx%d wcount: 0x%03x\n",j, buf); } else{ dsat_read_word(fd,(2+j)*16+3,&buf); buf &= 0x1ff; printf("read %s wcount: 0x%03x\n",tok[1], buf); } } if(!strncasecmp(tok[1],"rx",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 3) for(j = 0; j < 4; j++){ dsat_read_word(fd,(10+j)*16+3,&buf); buf &= 0x2ff; printf("read rx%d delay: 0x%03x\n",j, buf); } else{ dsat_read_word(fd,(10+j)*16+3,&buf); buf &= 0x2ff; printf("read %s delay: 0x%03x\n",tok[1], buf); } } if(!strncasecmp(tok[1],"mu",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 1) for(j = 0; j < 2; j++){ dsat_read_word(fd,(14+j)*16+3,&buf); buf &= 0x2ff; printf("read mu%d delay: 0x%03x\n",j, buf); } else{ dsat_read_word(fd,(14+j)*16+3,&buf); buf &= 0x2ff; printf("read %s delay: 0x%03x\n",tok[1], buf); } } if(!strcmp(tok[1],"scl")){ dsat_read_word(fd,3,&buf); buf &= 0xff; printf("read %s wcount: 0x%02x\n",tok[1], buf); } break; case 11 : // ld_ram start_addr = 0; if(!strncasecmp(tok[1],"tx",2)){ sscanf( tok[1]+2, "%d", &j); if(j > 7) for(j = 0; j < 8; j++){ dsat_write_word(fd,(2+j)*16,&start_addr); for(k = 0; k < 512 ; k++) dsat_write_word(fd,(2+j)*16+1,&tokn[2]); } else{ dsat_write_word(fd,(2+j)*16,&start_addr); for(k = 0; k < 512 ; k++) dsat_write_word(fd,(2+j)*16+1,&tokn[2]); } } if(!strncasecmp(tok[1],"scl",3)){ dsat_write_word(fd,0,&start_addr); for(k = 0; k < 512 ; k++) dsat_write_word(fd,1,&tokn[2]); } break; case 12 : // wait j = 0; for(i=0;i < 65535;i++) j++; break; case 13 : // eqs read in equations if(nt < 2)tok[1] = "eqs_list\0"; if((ifp = fopen(tok[1],"r")) == NULL){ printf("equation file list %s not found\n",tok[1]); exit(1); } //clear all equation arrays for(j = 0; j < 6; j++) for(k = 0; k < 196; k++) for(l = 0; l < 3; l++){ evn_conv[j][k][l] = 0; odd_conv[j][k][l] = 0; } for(j = 0; j < 8; j++) for(k = 0; k < 90; k++){ dead_dblt[0][j][k] = 0; dead_dblt[1][j][k] = 0; } r2a = 0; while( fgets(line,maxLineLength-1,ifp) != NULL) { if((k = strlen(line)) > 1){ line[k-1] = '\0'; if(!strcmp(line,"r2a")) r2a = 1; else{ printf("file %s\n",line); rd_eqs(line); } } } fclose(ifp); break; case 14 : // sim //read in turn and tick dsat_read_word(fd,3,&buf); tick = ((buf & 0xff00) >> 8); turn = ((buf & 0xffff0000) >> 16); //read sectors for(j = 0; j < 2; j++){ sector[j] = r_dfea(fd,0xb8+j*0x40); octant[j] = sector[j]/10; sector[j] %= 10; } //get tx data to link_data and scl data to scl_data buf = 0; for(j = 0; j < 8; j++){ dsat_write_word(fd,(j+2)*16,&buf); dsat_read_mem(fd,(j+2)*16+1,511,&link_data[j][0]); } dsat_write_word(fd,0,&buf); dsat_read_mem(fd,1,511,&scl_data[0]); if(nt < 2)tokn[1] = 0; if(tokn[1] > 0x48)tokn[1] = 0x48; //reset wait4sg and wait4fc wait4sg = 0; wait4fc = 0; //check if new muon bits are enabled for run2a en_new[0] = (r_dfea(fd,0xB9) & 0x100) >> 8; en_new[1] = (r_dfea(fd,0xF9) & 0x100) >> 8; for(j = 0; j <= tokn[1]; j++) sim(fd,j); break; case 15 : // check //muon tracks if(!strncasecmp(tok[1],"mu",2)){ if(nt < 3) tokn[2] = 0; for(k = 0; k < 2; k++){ printf("muon%d : ",k); for(n = 0; n < 7; n++) printf(" %08x",mu_trk[tokn[2]][k][n]); printf("\n"); } break; } //level 1 data if(!strncasecmp(tok[1],"l1",2)){ if(nt < 3) tokn[2] = 0; for(k = 0; k < 2; k++){ printf("l1_%d : ",k); for(n = 0; n < 7; n++) printf(" %08x",ctoc[tokn[2]][k][n]); printf("\n"); } break; } //level 2 cps if(!strncasecmp(tok[1],"l2cps",5)){ if(nt < 3) tokn[2] = 0; for(k = 0; k < 2; k++){ printf("l2cps%d :\n ",k); for(n = 0; n < 11; n++){ printf(" %08x",l2cps[tokn[2]][k][n]); if(n%7 == 6) printf("\n "); } printf("\n"); } break; } //level 2 cft if(!strncasecmp(tok[1],"l2cft",5)){ if(nt < 3) tokn[2] = 0; for(k = 0; k < 2; k++){ printf("l2cft%d :\n ",k); for(n = 0; n < 27; n++){ printf(" %08x",l2cft[tokn[2]][k][n]); if(n%7 == 6) printf("\n "); } printf("\n"); } break; } //read out even cps table if(!strncasecmp(tok[1],"e_cps",5)){ for(k = 0; k < 6; k++) for(j = 0; j < 196; j++){ if(evn_conv[k][j][2]) printf("link%d(%d) => cps(%d)\n",lnk[k],j,evn_conv[k][j][2]-32 ); } } //read out odd cps table if(!strncasecmp(tok[1],"o_cps",5)){ for(k = 0; k < 6; k++) for(j = 0; j < 196; j++){ if(odd_conv[k][j][2]) printf("link%d(%d) => cps(%d)\n",lnk[k],j,odd_conv[k][j][2]-32 ); } } //read out even singlet table if(!strncasecmp(tok[1],"e_s",3)){ if(nt < 3)tokn[2] = 0; if(tokn[2] > 5)tokn[2] = 5; for(j = 0; j < 196; j++){ if(evn_conv[tokn[2]][j][1]) printf("link%d(%d) => %s(%d)\n",lnk[tokn[2]],j,slayer[evn_conv[tokn[2]][j][0]],evn_conv[tokn[2]][j][1] ); } } //read out odd singlet table if(!strncasecmp(tok[1],"o_s",3)){ if(nt < 3)tokn[2] = 0; if(tokn[2] > 5)tokn[2] = 5; for(j = 0; j < 196; j++){ if(odd_conv[tokn[2]][j][1]) printf("link%d(%d) => %s(%d)\n",lnk[tokn[2]],j,slayer[odd_conv[tokn[2]][j][0]],odd_conv[tokn[2]][j][1] ); } } //read out doublet hits if(!strncasecmp(tok[1],"d_hit",5)){ for(l = 0; l < 2; l++){ if(l==0) printf("even doublet hits\n"); else printf("odd doublet hits\n"); for(k = 0; k < 8; k++){ printf("layer %c:",dlayer[k][0]); for(j = dblt_range[k][0]; j <= dblt_range[k][1]; j++) if(dblt[l][k][j]) printf(" %d,",j); printf("\n"); } } } //read out singlet hits if(!strncasecmp(tok[1],"s_hit",5)){ for(l = 0; l < 2; l++){ if(l==0) printf("even singlet hits\n"); else printf("odd singlet hits\n"); for(k = 0; k < 16; k++){ printf("layer %s:",slayer[k]); for(j = dblt_range[k/2][0]-1+k%2; j <= dblt_range[k/2][1]-1+k%2; j++) if(sglt[l][k][j]) printf(" %d,",j); printf("\n"); } } } //read out cps hits if(!strncasecmp(tok[1],"cps_hit",7)){ for(l = 0; l < 2; l++){ if(l==0) printf("even cps hits:"); else printf("odd cps hits:"); for(k = 0; k < 32; k++) if(cps[l][k]) printf(" %d,",k); printf("\n"); } } //read out even equations if(!strncasecmp(tok[1],"evn_eq",6)){ if(nt == 2){ printf("usage: evn_eq [maxn | highn | medn | lown] where n is equation number\n"); break; } if(!strncasecmp(tok[2],"max",3)){ sscanf( tok[2]+3, "%d", &j); if(j > 351)j = 351; printf("m(%d) =\n",j); singlet = singlet_eq[0]; } if(!strncasecmp(tok[2],"high",4)){ sscanf( tok[2]+4, "%d", &j); if(j > 351)j = 351; printf("m(%d) =\n",j); j += 352; singlet = singlet_eq[1]; } if(!strncasecmp(tok[2],"med",3)){ sscanf( tok[2]+3, "%d", &j); if(j > 351)j = 351; printf("m(%d) =\n",j); j += 704; singlet = singlet_eq[2]; } if(!strncasecmp(tok[2],"low",3)){ sscanf( tok[2]+3, "%d", &j); if(j > 704)j = 703; printf("m(%d) =\n",j); j += 1056; singlet = singlet_eq[3]; } l = m[0][j]; n = m[0][j+1]; for(j = l; j < n; j++){ if(j > l) printf("or\n"); if(!singlet){ for(k = 0; k < 8; k++) if(eqs[0][j][k]) printf(" %s%d)",dlayer[k],eqs[0][j][k]); } else{ for(k = 0; k < 16; k++) if(eqs[0][j][k]) printf("%s%d ",slayer[k],eqs[0][j][k]); } } printf("\n"); } //read out odd equations if(!strncasecmp(tok[1],"odd_eq",6)){ if(nt == 2){ printf("usage: odd_eq [maxn | highn | medn | lown] where n is equation number\n"); break; } if(!strncasecmp(tok[2],"max",3)){ sscanf( tok[2]+3, "%d", &j); if(j > 351)j = 351; printf("m(%d) =\n",j); singlet = singlet_eq[7]; } if(!strncasecmp(tok[2],"high",4)){ sscanf( tok[2]+4, "%d", &j); if(j > 351)j = 351; printf("m(%d) =\n",j); j += 352; singlet = singlet_eq[8]; } if(!strncasecmp(tok[2],"med",3)){ sscanf( tok[2]+3, "%d", &j); if(j > 351)j = 351; printf("m(%d) =\n",j); j += 704; singlet = singlet_eq[9]; } if(!strncasecmp(tok[2],"low",3)){ sscanf( tok[2]+3, "%d", &j); if(j > 704)j = 703; printf("m(%d) =\n",j); j += 1056; singlet = singlet_eq[10]; } l = m[1][j]; n = m[1][j+1]; for(j = l; j < n; j++){ if(j > l) printf("or\n"); if(!singlet){ for(k = 0; k < 8; k++) if(eqs[1][j][k]) printf(" %s%d)",dlayer[k],eqs[1][j][k]); } else{ for(k = 0; k < 16; k++) if(eqs[1][j][k]) printf("%s%d ",slayer[k],eqs[1][j][k]); } } printf("\n"); } break; case 16 : // set up DSAT and DFEA2 registers //test slot number w_dfea(fd,0xf800,0x25); w_dfea(fd,0x940f,0xa5a5); if(r_dfea(fd,0x940f) ^ 0xa5a5) printf("error with slot address\n"); w_dfea(fd,0xf800,0x1a); w_dfea(fd,0x680f,0x5a5a); if(r_dfea(fd,0x680f) ^ 0x5a5a) printf("error with slot address\n"); //set slot number of DSAT to 0 w_dfea(fd,0xf800,0); w_dfea(fd,0xf,0); //read serial number buf = (r_dfea(fd,3) & 0xff00) >> 8; printf("Board serial number is (hex) 0x%x (dec) %d\n",buf,buf); buf = r_dfea(fd,3) & 0xff; if(buf != 0xff){ printf("FPGA not properly configured: status = 0x%x\n",buf); break; } //check pattern //start sending pattern buf = 0x20; dsat_write_word(fd,2,&buf); //reset dfea history w_dfea(fd,0,2); j = (r_dfea(fd,10) >> 8) & 0xff; if(j) printf("pattern check failed, 0x%x\n",j); w_dfea(fd,0x180,0xa5a5); w_dfea(fd,0x1c0,0x5a5a); w_dfea(fd,0xb8,0xa5a5); w_dfea(fd,0xf8,0x5a5a); j = r_dfea(fd,0x180) ^ 0xa5a5; if(j) printf("U7 bus error, 0x%x\n",j); j = r_dfea(fd,0x1c0) ^ 0x5a5a; if(j) printf("U9 bus error, 0x%x\n",j); j = r_dfea(fd,0xb8) ^ 0xa5a5; if(j) printf("U8 bus error, 0x%x\n",j); j = r_dfea(fd,0xf8) ^ 0x5a5a; if(j) printf("U10 bus error, 0x%x\n",j); w_dfea(fd,0x180,0x5a5a); w_dfea(fd,0x1c0,0xa5a5); w_dfea(fd,0xb8,0x5a5a); w_dfea(fd,0xf8,0xa5a5); j = r_dfea(fd,0x180) ^ 0x5a5a; if(j) printf("U7 bus error, 0x%x\n",j); j = r_dfea(fd,0x1c0) ^ 0xa5a5; if(j) printf("U9 bus error, 0x%x\n",j); j = r_dfea(fd,0xb8) ^ 0x5a5a; if(j) printf("U8 bus error, 0x%x\n",j); j = r_dfea(fd,0xf8) ^ 0xa5a5; if(j) printf("U10 bus error, 0x%x\n",j); buf = 0; dsat_write_word(fd,2,&buf); //set DFEA delay register for(j = 0; j < 7; j++){ w_dfea(fd,1,j); w_dfea(fd,0,2); if(!(r_dfea(fd,9) & 0xff00)){ k = j; break; } } for(j = 8+k; j < 0xff; j += 8){ w_dfea(fd,1,j); w_dfea(fd,0,2); if(!(r_dfea(fd,0) & 0xff00)) break; } //L2 pipeline depth is 12 for DSAT w_dfea(fd,0xb,0xc); //reset SLDB receiver ( it takes time for SLDB to function normally after a reset ) buf = 0x20; dsat_write_word(fd,0xe2,&buf); dsat_write_word(fd,0xf2,&buf); //enable SLDB receiver buf = 0x9; dsat_write_word(fd,0xe2,&buf); dsat_write_word(fd,0xf2,&buf); //set SLDB receiver delay as 3 events buf = 0x3; dsat_write_word(fd,0xe3,&buf); dsat_write_word(fd,0xf3,&buf); //enable CTOC receiver buf = 0x9; for(j = 0xa2; j < 0xe2; j += 0x10) dsat_write_word(fd,j,&buf); //set CTOC receiver delay as 5 events buf = 0x5; for(j = 0xa3; j < 0xe3; j += 0x10) dsat_write_word(fd,j,&buf); //enable LINK transmitter buf = 0x9; for(j = 0x22; j < 0xa2; j += 0x10) dsat_write_word(fd,j,&buf); //set default transmit length as full buffer ( 73 events ) buf = 0x1ff; for(j = 0x23; j < 0xa3; j += 0x10) dsat_write_word(fd,j,&buf); //check DFEA2 firmware version to adujust lvds_in, lvds_out timing version = r_dfea(fd,4); bad_version = 0; for(j = 5; j < 8; j++) if(((buf=r_dfea(fd,j)) > 0xa || version > 0xa) && buf != version){ if(buf < version) version = buf; bad_version = 1; } if(bad_version) printf("DFEA2 firmware version inconsistant! u7=0x%x u8=0x%02x u9=0x%02x u10=0x%02x \n",r_dfea(fd,4),r_dfea(fd,5),r_dfea(fd,6),r_dfea(fd,7)); //enable scl and send scl clear to sync tick and turn buf = 3; if(version < 0xc) buf += 64; dsat_write_word(fd,2,&buf); //clear history registers w_dfea(fd,0,2); //set default transmit length as full buffer ( 73 events ) buf = 0x49; dsat_write_word(fd,3,&buf); break; case 17: // program FPGA if(nt == 2){ if(strstr(tok[1],"u7") != NULL) programChip(fd,0,tok[1]); if(strstr(tok[1],"u8") != NULL) programChip(fd,1,tok[1]); if(strstr(tok[1],"u9") != NULL) programChip(fd,2,tok[1]); if(strstr(tok[1],"u10") != NULL) programChip(fd,3,tok[1]); } break; case 18: //random number generate event data and test if(nt < 2) tokn[1] = 0x1000000; if(nt < 3) tokn[2] = -1; else tokn[2] &= 0xfffffff; rnd_test(fd,tokn[1],tokn[2]); break; } } } } } dsat_close(fd); } // int w_dfea(int fd, int addr, int data) { dsat_write_word(fd,0x10,&addr); dsat_write_word(fd,0x11,&data); return OK; } // int r_dfea(int fd, int addr) { int buf; dsat_write_word(fd,0x10,&addr); buf = 2; dsat_write_word(fd,0x12,&buf); dsat_read_word(fd,0x11,&buf); return buf; } // // parse input line into blank-separated tokens // ignore trailing comments (start with "#") // convert obvious numbers // int parse_command( char *pb, char *tok[], unsigned int tokn[], int maxt) { int nt = 0; char *tp, *p, *p2; int ct; // type: 1 = digits 2 = hex 4 = other while( (tp = strsep( &pb, " \t\n")) != NULL) { if( *tp != '\0') { tok[nt] = tp; // see what kind of chars are in there ct = 0; // special case for leading '0x' if( !strncasecmp( "0x", tp, 2)) { ct = 2; p2 = tp+2; } else p2 = tp; for( p=p2; *p && *p != '#'; ++p) { if( isdigit( *p) && ct==0){ ct = 1; if(maxt == 16) ct = 2; } else if( isxdigit( *p) && !isdigit( *p) && (ct!=4)) ct = 2; else if( !isxdigit( *p)) ct = 4; } switch( ct) { case 1: sscanf( p2, "%d", &tokn[nt]); break; case 2: sscanf( p2, "%x", &tokn[nt]); break; default: tokn[nt] = 0; } if( ++nt >= maxt) goto toomany; } } toomany: return nt; } /* A static variable for holding the line. */ static char *line_read = (char *)NULL; static char file_buf[256]; // // read a line from fp if non-null // or terminal using readline // keep a history // char *rl_gets () { int n; static char last_line[2048]; if( fp != NULL) { if( fgets( file_buf, 255, fp) == NULL){ //after file ends, using terminal input fclose(fp); fp = NULL; goto din; } else { if( (n = strlen( file_buf)) > 1) file_buf[n-1] = '\0'; return file_buf; } } din: #ifdef USE_READLINE /* If the buffer has already been allocated, return the memory to the free pool. */ if (line_read) { free (line_read); line_read = (char *)NULL; } /* Get a line from the user. */ line_read = readline ("dfea_tst> "); /* If the line has any text in it, save it on the history. */ if (line_read && *line_read) if (strcasecmp(line_read, last_line)) { strcpy(last_line, line_read); add_history(line_read); } return (line_read); #else printf( "dfea_tst> "); if( fgets( file_buf, 255, stdin) == NULL) return NULL; else { if( (n = strlen( file_buf)) > 1) file_buf[n-1] = '\0'; return file_buf; } #endif } // eq_type : 0x0 evn_max, 0x1 evn_high, 0x2 evn_med, 0x3 evn_low, 0x4 evn_cps, 0x5 evn_singlet, 0x6 evn_doublet // eq_type : 0x7 odd_max, 0x8 odd_high, 0x9 odd_med, 0xa odd_low, 0xb odd_cps, 0xc odd_singlet, 0xd odd_doublet int rd_eqs( char *file_name) { FILE *ifp=NULL; char *layer[16]; char *slayer[16] = {"ai","ao","bi","bo","ci","co","di","do","ei","eo","fi","fo","gi","go","hi","ho"}; char *dlayer[8] = {"a(","b(","c(","d(","e(","f(","g(","h("}; char line[200],*temp,*p,*pp; int i, j, k, l, en, begin_found = 0, m_ptr, m_offset, odd, nlayer,singlet,eq_type; ifp = fopen(file_name,"r"); if (!ifp) { printf("read equation: Can not open file %s\n",file_name); return ERROR; } // strcpy(line,file_name); //convert to lower case for(i = 0; i < strlen(line); i++) if(line[i] > 64 && line[i] < 91) line[i] += 32; if((p = strstr(line,"tsector")) != NULL) odd = strtol(p+7,&pp,10)%2; else{ if((p = strstr(line,"cps_map")) != NULL) odd = strtol(p+8,&pp,10)%2; else{ printf("file name: \"%s\" is not legal\n",line); return ERROR; } } eq_type = -1; if((p = strstr(line,"max")) != NULL) eq_type = odd*7; if((p = strstr(line,"high")) != NULL) eq_type = odd*7+1; if((p = strstr(line,"med")) != NULL) eq_type = odd*7+2; if((p = strstr(line,"low")) != NULL) eq_type = odd*7+3; if((p = strstr(line,"cps")) != NULL) eq_type = odd*7+4; if((p = strstr(line,"singlets")) != NULL) eq_type = odd*7+5; if((p = strstr(line,"doublets")) != NULL) eq_type = odd*7+6; if(eq_type < 0){ printf("file name: \"%s\" is not legal\n",line); return ERROR; } m_ptr = 1; m[odd][0] = 0; m_offset = 352*(eq_type%7); if(eq_type%7 < 4){ if(m_offset == 0) for(i = 0; i < nlayer; i++) eqs[odd][0][i] = 0; en = m[odd][m_offset]; } singlet = 0; while ( fgets(line, 200, ifp) != NULL) { int length,token; //remove comments if((p = strstr(line,"--")) != NULL) *p = '\0'; //find the length of the line length = strlen(line); for(i = 0; i < length; i++){ //convert to lower case if(line[i] > 64 && line[i] < 91) line[i] += 32; //remove space if(line[i] == ' '){ for(j = i; j < length; j++) line[j] = line[j+1]; length--; } } //search for beginning of equations if(begin_found != 1){ if(strstr(line,"ai:in") != NULL) singlet = 1; if(strstr(line,"begin") != NULL){ begin_found = 1; if(singlet){ for(i = 0; i < 16; i++) layer[i] = slayer[i]; nlayer = 16; } else{ for(i = 0; i < 8; i++) layer[i] = dlayer[i]; nlayer = 8; } } singlet_eq[eq_type] = singlet; } else{ if(strstr(line,"end") != NULL) break; //looking for "or" and replace it with ';' while((p = strstr(line,"or")) != NULL){ p[0] = ';'; p[1] = ' '; } switch(eq_type%7){ //processing cps equations case 4: //looking for cps( if((p = strstr(line,"cps(")) != NULL){ i = strtol(p+4,&pp,10); //looking for link if((p = strstr(line,"link")) != NULL){ j = strtol(p+4,&pp,10); if(j > 0)j--; } else{ printf("error in cps(%d)\n",i); return ERROR; } if((p = strstr(line,"array(")) != NULL){ k = strtol(p+6,&pp,10); if(eq_type == 4) evn_conv[j][k][2] = i+32; else odd_conv[j][k][2] = i+32; } else{ printf("error in cps(%d)\n",i); return ERROR; } } break; //processing singlets equations case 5: //looking for layer for(i = 0; i < 16; i++) if((p = strstr(line,slayer[i])) != NULL){ j = strtol(p+3,&pp,10); if((p = strstr(line,"link")) != NULL){ k = strtol(p+4,&pp,10); if(k)k--; l = strtol(p+6,&pp,10); if(eq_type == 5){ evn_conv[k][l][0] = i; evn_conv[k][l][1] = j; } else{ odd_conv[k][l][0] = i; odd_conv[k][l][1] = j; } } else{ printf("error in singlet %s(%d)\n",slayer[i],j); return ERROR; } } break; //processing doublets equations case 6: if((p = strstr(line,"'1'")) != NULL){ for(i = 0; i < 8; i++) if((p = strstr(line,dlayer[i])) != NULL){ j = strtol(p+2,&pp,10); dead_dblt[odd][i][j] = 1; break; } } break; //read track equations default: //looking for m( if((p = strstr(line,"m(")) != NULL){ i = strtol(p+2,&pp,10); //check if there are any missing m terms while(m_ptr <= i){ m[odd][m_ptr+m_offset] = en; m_ptr++; } } //looking for ';' do{ token = 0; if((p = strstr(line,";")) != NULL){ p[0] = '\0'; temp = p+1; token = 1; } for(i = 0; i < nlayer; i++){ if((p = strstr(line,layer[i])) != NULL){ eqs[odd][en][i] = strtol(p+2+singlet,&pp,10); } } strcpy(line,temp); if(token){ j = 0; for(i = 0; i < nlayer; i++) j += eqs[odd][en][i]; //do not include empty line if(j){ en++; //clear next product term for(i = 0; i < nlayer; i++) eqs[odd][en][i] = 0; } } if(en == N){ printf("too many equations found, exit\n"); return ERROR; } }while(token == 1); } } } fclose(ifp); if(eq_type%7 < 4){ do{ m[odd][m_ptr + m_offset] = en; m_ptr++; }while(m_ptr < 353); printf("%d equations found\n",en-m[odd][m_offset]); } return OK; } int sim(int fd, int event) { int i, j, k, l, n, s, addr, l1, cr, lvds_in[2], trk_fnd, nlayer[2] = {8,16}, right, link, link_word; int dblt_cnt[2]; int s1[4] = {0,352,704,1056},s2[4] = {352,704,1056,1760}; int tick_event, turn_event; int curve, pt, ptsub, phi; int cntrd, width, clstr[2][8][2], clstr_cnt[2][2], psc[2], clstr_ram[2][8]; int d, d_min, index, ccw, cw, nccw, ncw, total_trk[2]; int iso[2], iso_byte[2], pt_sum[2]; int data[7], mu_cnt[2], trk_cnt[2][4], track[2][4][7], prj_trk; int dblt_range[8][2] = {3,46,5,56,9,64,14,71,21,76,28,81,38,83,44,89}; int found_trk[2][1760],higher_pt,singlet; //find tick & turn for this event tick_event = tick + event; turn_event = turn; if(tick_event > 0x9e){ tick_event -= 0x9f; turn_event++; turn_event &= 0xffff; } //clear hit arrays for(i=0;i<2;i++){ for(j=0;j<32;j++) cps[i][j] = 0; for(j=0;j<16;j++) for(k=0;k<90;k++) sglt[i][j][k] = 0; for(j=0;j<8;j++) for(k=0;k<90;k++) dblt[i][j][k] = 0; } //read scl word addr = event; dsat_write_word(fd,0,&addr); dsat_read_word(fd,1,&i); lvds_in[0] = (i & 0x4) >> 2; lvds_in[1] = (i & 0x8) >> 3; cr = (i & 0x2) >> 1; l1 = i & 0x1; //scl reset handling if(cr == 1){ wait4sg = 1; wait4fc = 1; } else{ //tick and turn are set at tick == 7 if(wait4fc == 1 && tick_event == 7){ wait4fc = 0; turn_event = 1; turn = 1; tick = tick_event - event; if(tick < 0){ tick += 0x9f; turn--; turn &= 0xffff; } } //muon track is one tick earlier than level 2 packed turn and ticks if(tick_event > 0x94 || tick_event < 0x7) wait4sg = 0; } //fill singlet and cps hits //eight LVDS link for(i = 0; i < 8; i++){ link = i; //swap link3 and link4 data if(i == 2)link = 3; if(i == 3)link = 2; for(j = 0; j < 7; j++){ k = j*28; link_word = link_data[link][7*event+j] & 0xfffffff; while(link_word != 0){ link_word = link_word >> 1; k++; if(link_word & 1){ switch(i){ case 0: case 1: if(l = evn_conv[i][k][1]){ n = evn_conv[i][k][0]; sglt[0][n][l] = 1; } if(l = evn_conv[i][k][2]) cps[0][l-32] = 1; break; case 6: case 7: if(l = odd_conv[i-6][k][1]){ n = odd_conv[i-6][k][0]; sglt[1][n][l] = 1; } if(l = odd_conv[i-6][k][2]) cps[1][l-32] = 1; break; default: if(l = evn_conv[i][k][1]){ n = evn_conv[i][k][0]; sglt[0][n][l] = 1; } if(l = evn_conv[i][k][2]) cps[0][l-32] = 1; if(l = odd_conv[i][k][1]){ n = odd_conv[i][k][0]; sglt[1][n][l] = 1; } if(l=odd_conv[i][k][2]) cps[1][l-32] = 1; } } } } } // fill doublet hits for(k = 0; k < 2; k++) for(i = 0; i < 8; i++){ l = 2*i; for(j = dblt_range[i][0]; j <= dblt_range[i][1]; j++){ if(dead_dblt[k][i][j]){ dblt[k][i][j] = 1; } if(!sglt[k][l][j-1] && sglt[k][l+1][j]) dblt[k][i][j] = 1; if(sglt[k][l][j]) dblt[k][i][j] = 1; } } //count doublets for(k = 0; k < 2; k++){ dblt_cnt[k] = 0; for(i = 0; i < 8; i++) for(j = dblt_window[i][0]; j <= dblt_window[i][1]; j++) dblt_cnt[k] += dblt[k][i][j]; } //track finding //search for all tracks for(i = 0; i < 2; i++){ for(pt = 0; pt < 4; pt++){ if(r2a && (version < 0xb || pt > 1)) singlet = 0; else singlet = 1; for(s = s1[pt]; s < s2[pt]; s++) for(k = m[i][s]; k < m[i][s+1]; k++){ found_trk[i][s] = 1; for(l = 0; l < nlayer[singlet]; l++) if(n = eqs[i][k][l]) if((!dblt[i][l][n] && !singlet) || (!sglt[i][l][n] && singlet)){ found_trk[i][s] = 0; break; } if(found_trk[i][s]) break; } } } //search for even and odd sectors for(i = 0; i < 2; i++){ mu_cnt[i] = 0; for(pt = 0; pt < 4; pt++){ trk_cnt[i][pt] = 0; //search tracks in segments of twenty two for(s = s1[pt]; s < s2[pt]; s += 22){ //search from high phi to low phi for(j = s+21; j >= s; j--){ if((trk_fnd = found_trk[i][j]) && version > 0xa){ //check for ghost tracks (no cross sector veto as of Jan-22-2006) phi = j%44; //if phi is even check neighbouring phi bins if((phi%2 == 0) && ((phi && found_trk[i][j-1]) || found_trk[i][j+1])) trk_fnd = 0; higher_pt = j - 88; if(higher_pt < 0) higher_pt += 44; //not the highest Pt, check ghost track from higher Pt bins if(higher_pt >= r2a*s1[pt] && (found_trk[i][higher_pt] || (phi > 0 && found_trk[i][higher_pt-1]) || (phi < 43 && found_trk[i][higher_pt+1]))) trk_fnd = 0; } if(trk_fnd){ //save muon track if(mu_cnt[i] < 6){ mu_trk[event][i][mu_cnt[i]] = j; mu_cnt[i]++; } //save CTOC track if(trk_cnt[i][pt] < 7){ track[i][pt][trk_cnt[i][pt]] = j - s1[pt]; trk_cnt[i][pt]++; } //if more CTOC tracks are needed, search from right if(trk_cnt[i][pt] < 7){ for(right = s; right < j - SAME; right++){ if((trk_fnd = found_trk[i][right]) && version > 0xa){ //check for ghost tracks (no cross sector veto as of Jan-22-2006) phi = right%44; //if phi is even check neighbouring phi bins if((phi%2 == 0) && ((phi && found_trk[i][right-1]) || found_trk[i][right+1])) trk_fnd = 0; higher_pt = right - 88; if(higher_pt < 0) higher_pt += 44; //not the highest Pt, check ghost track from higher Pt bins if(higher_pt >= r2a*s1[pt] && (found_trk[i][higher_pt] || (phi > 0 && found_trk[i][higher_pt-1]) || (phi < 43 && found_trk[i][higher_pt+1]))) trk_fnd = 0; } if(trk_fnd){ track[i][pt][trk_cnt[i][pt]] = right - s1[pt]; trk_cnt[i][pt]++; break; } } } break; } } if(mu_cnt[i] == 6 && trk_cnt[i][pt] == 7) break; } } } //clusters for(i = 0; i < 2; i++){ psc[i] = 0; for(k = 0; k < 2; k++){ cntrd = 0; width = 0; clstr_cnt[i][k] = 0; for(l = 16; l < 32; l++){ if(k) j = 31 - l; else j = l; if(cps[i][j]){ cntrd += j; width++; } else if(width){ clstr[i][clstr_cnt[i][k]+4*k][0] = cntrd/width; if(width > 7) width = 7; clstr[i][clstr_cnt[i][k]+4*k][1] = width; clstr_cnt[i][k]++; //psc counts only up to three if(psc[i] < 3) psc[i]++; cntrd = 0; width = 0; } if(clstr_cnt[i][k] == 4) break; } //if cps(0) or cps(31) = '1' if(width){ clstr[i][clstr_cnt[i][k]+4*k][0] = cntrd/width; if(width > 7) width = 7; clstr[i][clstr_cnt[i][k]+4*k][1] = width; clstr_cnt[i][k]++; //psc counts only up to three if(psc[i] < 3) psc[i]++; } for(j = clstr_cnt[i][k]; j < 4; j++){ clstr[i][j+4*k][0] = 0; clstr[i][j+4*k][1] = 0; } } } //format CFT tracks for(i = 0; i < 2; i++){ pt_sum[i] = 0; iso_byte[i] = 0; total_trk[i] = 0; for(j = 0; j < 8; j++) if(clstr[i][j][0] < 24 && clstr[i][j][0] > 7) clstr_ram[i][j] = ((clstr[i][j][0] - 8) << 19) + (clstr[i][j][1] << 16) + (sector[i] << 3); else clstr_ram[i][j] = 0; for(j = 0; j < 4; j++){ ccw = 0; cw = 0; nccw = 0; ncw = 0; for(k = 0; k < 7; k++) if(k >= trk_cnt[i][j]) track[i][j][k] = 0; else{ curve = (track[i][j][k]/44 + 1)%2; ptsub = track[i][j][k]/88; pt_sum[i] += pt_lut[j][ptsub]; phi = track[i][j][k]%44; //l2CFT only accept six tracks per pt bin if(k < 6) l2cft[event][i][total_trk[i]+2] = (sector[i] << 16) + (curve << 13) + (j << 11) + (ptsub << 8) + (phi << 1); iso_byte[i] += 0x80 + curve*8 + j*2; if(dblt_cnt[i] < 16) iso_byte[i]++; //cluster matching prj_trk = xpl_lut[phi] + (2*curve - 1)*xpl_offset[j]; d_min = 30; for(n = 0; n < 8; n++) if(clstr[i][n][1]){ d = clstr[i][n][0] - prj_trk; if(d < 0) d = -d; if(d < d_min){ d_min = d; index = n; } } if(d_min <= match_window[j]){ //l2CFT only accept six tracks per pt bin if(k < 6){ l2cft[event][i][total_trk[i]+2] += (((clstr[i][index][0]-8) & 0xf) <<20) + 0x8000; if(clstr[i][index][0] > 23 || clstr[i][index][0] < 8) l2cft[event][i][total_trk[i]+2] += 0x80; else{ if(!(clstr_ram[i][index] & 0x8000)) clstr_ram[i][index] += 0x8000 + (curve <<13) + (j <<11) + (ptsub <<8); } } if(curve) ccw++; else cw++; iso_byte[i] += 16; } else{ if(curve) nccw++; else ncw++; } //l2CFT only accept six tracks per pt bin if(k < 6) total_trk[i]++; } ctoc[event][i][1+j] = (ccw << 13) + (cw << 10) + (nccw << 5) + (ncw << 2); if(j == 2) ctoc[event][i][1+j] += psc[i]; } //in L1 CTOC, only pt_sum(7 downto 2) are kept ctoc[event][i][5] = ((pt_sum[i] & 0xfc) << 16) + (dblt_cnt[i] << 8); } // for(i = 0; i < 2; i++){ iso[i] = 0; ctoc[event][i][0] = 0xe00002f + (octant[i] <<19) + (cr <<18) + (sector[i] << 8); if(tick_event == 0x7) ctoc[event][i][0] += 0x20000; //isolation byte if(lvds_in[i] == 0 && total_trk[i] == 1 && total_trk[1-i] == 0){ ctoc[event][i][5] += iso_byte[i]; //set iso bit l2cft[event][i][2]++; iso[i] = 1; } //ctoc parity ctoc[event][i][6] = 0 ; for(j = 0; j < 6; j++){ n = 0; for(k = 0; k < 24; k++) if(ctoc[event][i][j] & (1 << k)) n = 1 - n; ctoc[event][i][j] |= (n << 24); ctoc[event][i][6] ^= ctoc[event][i][j]; } ctoc[event][i][6] &= 0xffffff; //sort and zero compress l2cps k = 0; for(l = 0; l < 2; l++) for(n = 0; n < 4; n++){ if(l) j = n; else j = 7 - n; if(clstr_ram[i][j]){ l2cps[event][i][k+2] = clstr_ram[i][j]; //l2cps iso bit if(iso[i]) l2cps[event][i][k+2]++; k++; } } l2cps[event][i][0] = (octant[i] <<19) + (((k&7) ^ (k/8)) <<16) + (k <<10) + ((k/8) <<9); switch(k & 7){ case 7: case 4: case 2: case 1: l2cps[event][i][0] += 0x100; default: l2cps[event][i][0] += 0xe0000c0; } if(wait4fc) l2cps[event][i][1] = 0; else l2cps[event][i][1] = tick_event + (turn_event << 8); //zero padding l2cps for(j = k+2; j < 11; j++) l2cps[event][i][j] = 0; //cps parity for(j = 0; j < k+2; j++){ n = 0; for(l = 0; l < 24; l++) if(l2cps[event][i][j] & (1 << l)) n = 1 - n; l2cps[event][i][j] |= (n << 24); l2cps[event][i][k+2] ^= l2cps[event][i][j]; } l2cps[event][i][k+2] &= 0xffffff; //l2cft l2cft[event][i][0] = (octant[i] <<19) + (((total_trk[i] & 7) ^ (total_trk[i]/8)) <<16) + (total_trk[i] <<10); switch(total_trk[i] & 7){ case 7: case 4: case 2: case 1: l2cft[event][i][0] += 0x100; default: l2cft[event][i][0] += 0xe000028; } if(total_trk[i] < 24 && total_trk[i] > 7) l2cft[event][i][0] += 0x200; if(wait4fc) l2cft[event][i][1] = 0; else l2cft[event][i][1] = tick_event + (turn_event << 8); //zero padding l2cft for(j = total_trk[i]+2; j < 27; j++) l2cft[event][i][j] = 0; //cft parity for(j = 0; j < total_trk[i]+2; j++){ n = 0; for(k = 0; k < 24; k++) if(l2cft[event][i][j] & (1 << k)) n = 1 - n; l2cft[event][i][j] |= (n << 24); l2cft[event][i][total_trk[i]+2] ^= l2cft[event][i][j]; } l2cft[event][i][total_trk[i]+2] &= 0xffffff; if(total_trk[i]) lvds_out[event][i] = 1; else lvds_out[event][i] = 0; } //format muon tracks for(i = 0; i < 2; i++){ mu_trk[event][i][6] = 0; for(j = 0; j < 6; j++){ if(mu_cnt[i] <= j) mu_trk[event][i][j] = 0; else{ curve = (mu_trk[event][i][j]/44 + 1)%2; pt = mu_trk[event][i][j]/352; if(pt > 3)pt = 3; ptsub = (mu_trk[event][i][j] - pt*352)/88; phi = mu_trk[event][i][j]%44; mu_trk[event][i][j] = 0x8000 + (curve << 11) + (pt << 9) + (ptsub << 6) + phi; if((!r2a || en_new[i]) && version > 0xa){ //cluster matching prj_trk = xpl_lut[phi] + (2*curve - 1)*xpl_offset[pt]; for(n = 0; n < 8; n++) if(clstr[i][n][1]){ d = clstr[i][n][0] - prj_trk; if(d < 0) d = -d; if(d <= match_window[pt]){ mu_trk[event][i][j] |= 1 << 12; break; } } } } //isolation bit for muon if((!r2a || en_new[i]) && j == 5 && version > 0xb) mu_trk[event][i][j] |= iso[i] << 13; mu_trk[event][i][6] ^= mu_trk[event][i][j]; } //disabled SLDB events //muon track is one tick earlier than level 2 packed turn and ticks if(tick_event > 0x94 || tick_event < 0x7 || wait4sg == 1) mu_trk[event][i][0] |= 0x80000000; } return OK; } // programs chip with MCS file int programChip(int fd,int chip,char *Filename) { FILE *f; int ln = 0; char line[maxLineLength]; char *chip_name[4] = {"U7", "U8", "U9", "U10"}; unsigned buf; // open mcs file f = fopen(Filename,"r"); if (!f) { printf("programChip: Cannot open file %s\n",Filename); return ERROR; } //reprogram the chip w_dfea(fd,3,(1 << chip)); printf("reprogram %s command sent\n",chip_name[chip]); // wait for init go high while(!(r_dfea(fd,3) & (1 << (4+chip)))){ } printf("init goes high\n"); //done signal should be low if(r_dfea(fd,3) & (1 << chip)){ printf("Done is high, something is wrong!\n"); return ERROR; } // program the chip using data from a file // write address buf = chip+4; dsat_write_word(fd,0x10,&buf); // set up for data writing if( ioctl(fd, PPSETMODE, &addr_mode) ) { perror(__func__); return -1; } buf = 0x11; if ( write(fd, &buf, 1) != 1 ) { perror(__func__); return -1; } if( ioctl(fd, PPSETMODE, &data_mode)) { perror(__func__); return -1; } // loop over record in the file and read them in the array "line" while ( fgets(line, maxLineLength, f) != NULL) { char c1[3],c2[5]; unsigned char data[200]; int i,byte_count,address,address_bias,rec_type,total; ln++; if(ln%0x1000 == 0){ printf("\rcurrent line: 0x%x",ln); fflush(stdout); } // check that the record has more than 9 characters if ( strlen(line) < 9 ) { printf("programChip: Error while reading " "line %d: it has less than 9 characters\n",ln); return ERROR; } // number of bytes in the record (first two hex numbers) strncpy(c1,line+1,2); c1[2] = '\0'; sscanf(c1,"%x",&byte_count); // address (hex numbers 3-6) strncpy(c2,line+3,4); c2[4] = '\0'; sscanf(c2,"%x",&address); // record type (hex numbers 7-8) strncpy(c1,line+7,2); c1[2] = '\0'; sscanf(c1,"%x",&rec_type); // calculate checksum total = byte_count+address/256+address%256+rec_type; // loop over the rest of the characters in the record and // convert them to int for (i=0; i<(byte_count+1);i++) { strncpy(c1,line+2*i+9,2); c1[2] = '\0'; data[i] = strtol(c1,NULL,16); total = total + data[i]; } // check the checksum for the record if (total%256 != 0) { printf("programChip: Error while reading line " "%d - a checksum error is found\n",ln); return ERROR; } //byte count must be even if(byte_count%2 == 1)byte_count++; // only data records are written if (rec_type == 0) { // for (i=0; i 0xe000000){ k = i - last_l1; if(k < 0) k += 73; if(k > 6){ last_l1 = i; scl_data[i]++; } } scl_data[i] += (j & 0xc); } dsat_write_word(fd,0,&addr); dsat_write_mem(fd,1,73,&scl_data[0]); //trigger buf = 5; if(version < 0xc) buf += 64; dsat_write_word(fd,2,&buf); //read in turn and tick dsat_read_word(fd,3,&buf); tick = ((buf & 0xff00) >> 8); turn = ((buf & 0xffff0000) >> 16); //reset wait4sg and wait4fc wait4sg = 0; wait4fc = 0; //check if new muon bits are enabled for run2a en_new[0] = (r_dfea(fd,0xB9) & 0x100) >> 8; en_new[1] = (r_dfea(fd,0xF9) & 0x100) >> 8; //call simulation for(i = 0; i < 73; i++) sim(fd,i); for(sec = 0; sec < 2 ;sec++){ //insert level 2 into CTOC stream for(i = 0; i < 60; i++) if(scl_data[i] & 1) for(j = 13+i; (j < 20+i) && (j < 73); j++) for(k = 0; k < 7; k++){ if((j-13-i)*7+k < 27) ctoc[j][sec][k] = l2cft[i][sec][(j-13-i)*7+k]; else{ if(((j-13-i)*7+k > 35) && ((j-13-i)*7+k < 47)) ctoc[j][sec][k] = l2cps[i][sec][(j-13-i)*7+k-36]; else ctoc[j][sec][k] = 0; } } //check results //check ctoc tracks dsat_write_word(fd,(10+sec*2+cycle%2)*16,&addr); dsat_read_mem(fd,(10+sec*2+cycle%2)*16+1,511,&data[0]); for(i = 0; i < 73; i++){ if(((data[i*7+6] & 0x80000000) >> 31) != lvds_out[i][sec]){ printf("\nlvds_out[%d] does not match: event%d\n",sec,i); err_cnt[0][sec]++; } for(j = 0; j < 7; j++) if((data[i*7+j] ^ ctoc[i][sec][j]) & 0xfffffff){ printf("\nctoc%d_%02d real:",sec,i); for(k = 0; k < 7; k++) printf(" x%07x",data[i*7+k] & 0xfffffff); printf("\n"); printf("ctoc%d_%02d sim:",sec,i); for(k = 0; k < 7; k++) printf(" x%07x",ctoc[i][sec][k]); printf("\n"); err_cnt[1][sec]++; break; } } //check muon tracks dsat_write_word(fd,(14+sec)*16,&addr); dsat_read_mem(fd,(14+sec)*16+1,511,&data[0]); for(i = 0; i < 73; i++){ for(j = 0; j < 7; j++){ if(mu_trk[i][sec][0] & 0x80000000){ if(data[i*7+0] & 0x20000){ printf("\nmuon trk%d without xe mismatch at event%d\n",sec,i); err_cnt[2][sec]++; break; } } else{ if((data[i*7+j] ^ mu_trk[i][sec][j]) & 0xffff){ printf("\nmu%d_%02d real:",sec,i); for(k = 0; k < 7; k++) printf(" 0x%04x",data[i*7+k] & 0xffff); printf("\n"); printf("mu%d_%02d sim:",sec,i); for(k = 0; k < 7; k++) printf(" 0x%04x",mu_trk[i][sec][k] & 0xffff); printf("\n"); err_cnt[3][sec]++; break; } } } } } } printf("\ntest done\n"); return OK; }