[site_begin function in functional code] What is done in site_begin, the beginning of the test flow #Magnum2
SITE_BEGIN_BLOCK( site_begin_example )
{
output("\nMemory Characterization Unified Flow");
output("Compiled for: %s\n", DEVICE_NAME);
// setting the device size.
numx( 24 ); // Number of X addresses used -- EV2 only
numy( 15 ); // 15 Number of Y addresses used, 这里不是16位,是因为最高位用不到
// Data Generator
data_reg_width( 36 ); // Device is only 8 bits, so we can use either 36 or 18 mode
yindexmask ( 0xFF ); // For diagonal generation (Char program example)
x_fast_axis( FALSE ); // 对于addr register,低位是Y bits,在这里是低15位
tri_state(pl_RB);
cs_active_high(t_cs7); // 默认是active low
// select pinlists used by timing tool
remote_set("ui_TimingToolPinLists","pl_IO,pl_CE,pl_WE,pl_ALE,pl_CLE,pl_RE,pl_REn,pl_DQS,pl_DQSn,pl_RB,pl_VREF",-1);
measure(TRUE); // switch the global DC test mode between Go/NoGo test mode and measurement mode.
DBM_Setup();
ECR_Setup_16K();
iFSetup_Good_Blk();
data_strobe(0xFFFF); //enable IO0~IO15 strobe
}
void DBM_Setup()
{
int x = 11; //11 0x7FF
int y = 15; //15 0x7FFF
dbm_ddr_mux_config_set( t_dbm_ddr_mode ); // Configure to DDR mode to avoid wasted space, not very clear?
dbm_ddr_mux_mode_set( TRUE ); // not very clear?
// Orginally 5ns but should be kept at '4.6 NS', width is typically set to match the DUT’s data width
// t_dbm_random_access is not very clear?
dbm_config_set( x, y, 8, t_dbm_random_access, 4.6 NS );
dbm_ymax = pow(2,y)-1;
dbm_xmax = pow(2,x)-1;
// We set this so on program load, we will by default load the entire DBM
// dbm_xstop = dbm_xmax;
}
void ECR_Setup_16K()
{
int x = ECR_X_NUM; //11 0x0 - 0x3FF
int y = 15; //7FFF
ecr_xmax = pow(2,x)-1;
ecr_ymax = pow(2,y)-1;
// specify which pins will use DDR
fail_signal_mux( pl_IO_DQS_DQSb, t_double);
// DDR address differentiator
ecr_ddr_mux_config_set ( t_ecr_ddr_mode, t_y0,t_tf_na );
ecr_config_set(x, y, pl_IO_DQS_DQSb, ecr_xmax, ecr_ymax);
ecr_rcm_config_set(ecr_xmax, 0);
ecr_tec_save_config_set(num_saves, t_bit_duplicates, t_tec_save_no_compare, 0, -1, TEC_SAVE_BEFORE_DONE);
MaskBit = 0x3FF;
}
int iFSetup_Good_Blk()
{
FILE *read_file;
char buffer[32];
char buf1[2];
int index;
int total_good_blk;
char blk_file_1[32];
char blk_file_2[32];
char blk_file_3[32];
char blk_file_4[32];
char final_blk_file[32];
int total_2_good_blk_group;
int total_5_good_blk_group;
int good_blk_step = 0;
for (index = 0; index < DEV_BLKS_PER_DIE; index++)
gi_Good_Blk[index] = 0;
for (index = 0; index < MAX_2_GOOD_BLK_GROUP; index++)
gi_Good_2_Blk_Group[index] = 0;
for (index = 0; index < MAX_5_GOOD_BLK_GROUP; index++)
gi_Good_5_Blk_Group[index] = 0;
sprintf(blk_file_1, "blk_files\\blk_%d_%d_%d.txt", giVar_Z2_Lot_Number, giVar_Z3_Wafer_Number, giVar_Z6_Dut1_unit_num);
sprintf(blk_file_2, "blk_files\\blk_%d_%d_%d.txt", giVar_Z2_Lot_Number, giVar_Z3_Wafer_Number, giVar_Z8_Dut2_unit_num);
sprintf(blk_file_3, "blk_files\\blk_%d_%d_%d.txt", giVar_Z2_Lot_Number, giVar_Z3_Wafer_Number, giVar_Z10_Dut3_unit_num);
sprintf(blk_file_4, "blk_files\\blk_%d_%d_%d.txt", giVar_Z2_Lot_Number, giVar_Z3_Wafer_Number, giVar_Z12_Dut4_unit_num);
//check the second dut and combine good blks of dut1 and dut2 together
if (giVar_Z4_4_Duts_Paralell)
{
//dut 1
if (giVar_Z5_Use_Dut1_unit != TRUE)
{
return (0);
}
sprintf(final_blk_file, "..\\%s", blk_file_1);
if ((read_file = fopen(final_blk_file, "rt")) == NULL)
{
output("\n<b><color=red>***********************************************************</color></b>");
output("<b><color=red>*** WARNING WARNING WARNING ***</color></b>");
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>*** %s fopen FAIL </color></b>", final_blk_file);
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>***********************************************************</color></b>\n");
return (0);
}
total_good_blk = 0;
for (index = 0; index < DEV_BLKS_PER_DIE; index++)
{
if (fgets(buffer, sizeof(buffer), read_file) != NULL)
{
sprintf(buf1, "%c%c", buffer[0], buffer[1]);
if (strcmp(buf1, "OK") == 0)
{
gi_Good_Blk[index] = 1;
total_good_blk++;
}
}
}
fclose(read_file);
//dut 2
if (giVar_Z7_Use_Dut2_unit != TRUE)
{
return (0);
}
sprintf(final_blk_file, "..\\%s", blk_file_2);
if ((read_file = fopen(final_blk_file, "rt")) == NULL)
{
output("\n<b><color=red>***********************************************************</color></b>");
output("<b><color=red>*** WARNING WARNING WARNING ***</color></b>");
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>*** %s fopen FAIL </color></b>", final_blk_file);
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>***********************************************************</color></b>\n");
return (0);
}
total_good_blk = 0;
for (index = 0; index < DEV_BLKS_PER_DIE; index++)
{
if (fgets(buffer, sizeof(buffer), read_file) != NULL)
{
sprintf(buf1, "%c%c", buffer[0], buffer[1]);
if (strcmp(buf1, "OK") == 0) //dut2 = good
{
if (gi_Good_Blk[index] == 1) //dut1 = good
{
gi_Good_Blk[index] = 1;
total_good_blk++;
}
else
gi_Good_Blk[index] = 0; //dut2=good, dut1=bad,
}
else
gi_Good_Blk[index] = 0; //dut2=bad, dut1=dont care
}
}
fclose(read_file);
if (giVar_Z9_Use_Dut3_unit != TRUE)
{
return (0);
}
sprintf(final_blk_file, "..\\%s", blk_file_3);
if ((read_file = fopen(final_blk_file, "rt")) == NULL)
{
output("\n<b><color=red>***********************************************************</color></b>");
output("<b><color=red>*** WARNING WARNING WARNING ***</color></b>");
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>*** %s fopen FAIL </color></b>", final_blk_file);
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>***********************************************************</color></b>\n");
return (0);
}
total_good_blk = 0;
for (index = 0; index < DEV_BLKS_PER_DIE; index++)
{
if (fgets(buffer, sizeof(buffer), read_file) != NULL)
{
sprintf(buf1, "%c%c", buffer[0], buffer[1]);
if (strcmp(buf1, "OK") == 0) //dut3 = good
{
if (gi_Good_Blk[index] == 1) //dut1 & dut2 = good
{
gi_Good_Blk[index] = 1;
total_good_blk++;
}
else
gi_Good_Blk[index] = 0; //dut3=good, dut1 or dut2=bad,
}
else
gi_Good_Blk[index] = 0; //dut3=bad, dut1=dont care
}
}
fclose(read_file);
if (giVar_Z11_Use_Dut4_unit != TRUE)
{
return (0);
}
sprintf(final_blk_file, "..\\%s", blk_file_4);
if ((read_file = fopen(final_blk_file, "rt")) == NULL)
{
output("\n<b><color=red>***********************************************************</color></b>");
output("<b><color=red>*** WARNING WARNING WARNING ***</color></b>");
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>*** %s fopen FAIL </color></b>", final_blk_file);
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>***********************************************************</color></b>\n");
return (0);
}
total_good_blk = 0;
for (index = 0; index < DEV_BLKS_PER_DIE; index++)
{
if (fgets(buffer, sizeof(buffer), read_file) != NULL)
{
sprintf(buf1, "%c%c", buffer[0], buffer[1]);
if (strcmp(buf1, "OK") == 0) //dut4 = good
{
if (gi_Good_Blk[index] == 1) //dut1 & dut2 & dut3 = good
{
gi_Good_Blk[index] = 1;
total_good_blk++;
}
else
gi_Good_Blk[index] = 0; //dut4=good, dut1 or dut2 or dut3=bad,
}
else
gi_Good_Blk[index] = 0; //dut4=bad, dut1=dont care
}
}
fclose(read_file);
}
else if (giVar_Z4_2_Duts_Paralell)
{
//dut 1
if (giVar_Z5_Use_Dut1_unit != TRUE)
{
return (0);
}
sprintf(final_blk_file, "..\\%s", blk_file_1);
if ((read_file = fopen(final_blk_file, "rt")) == NULL)
{
output("\n<b><color=red>***********************************************************</color></b>");
output("<b><color=red>*** WARNING WARNING WARNING ***</color></b>");
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>*** %s fopen FAIL </color></b>", final_blk_file);
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>***********************************************************</color></b>\n");
return (0);
}
total_good_blk = 0;
for (index = 0; index < DEV_BLKS_PER_DIE; index++)
{
if (fgets(buffer, sizeof(buffer), read_file) != NULL)
{
sprintf(buf1, "%c%c", buffer[0], buffer[1]);
if (strcmp(buf1, "OK") == 0)
{
gi_Good_Blk[index] = 1;
total_good_blk++;
}
}
}
fclose(read_file);
//dut 2
if (giVar_Z7_Use_Dut2_unit != TRUE)
{
return (0);
}
sprintf(final_blk_file, "..\\%s", blk_file_2);
if ((read_file = fopen(final_blk_file, "rt")) == NULL)
{
output("\n<b><color=red>***********************************************************</color></b>");
output("<b><color=red>*** WARNING WARNING WARNING ***</color></b>");
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>*** %s fopen FAIL </color></b>", final_blk_file);
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>***********************************************************</color></b>\n");
return (0);
}
total_good_blk = 0;
for (index = 0; index < DEV_BLKS_PER_DIE; index++)
{
if (fgets(buffer, sizeof(buffer), read_file) != NULL)
{
sprintf(buf1, "%c%c", buffer[0], buffer[1]);
if (strcmp(buf1, "OK") == 0) //dut2 = good
{
if (gi_Good_Blk[index] == 1) //dut1 = good
{
gi_Good_Blk[index] = 1;
total_good_blk++;
}
else
gi_Good_Blk[index] = 0; //dut2=good, dut1=bad,
}
else
gi_Good_Blk[index] = 0; //dut2=bad, dut1=dont care
}
}
fclose(read_file);
}
else //not testing all duts in paralell
{
if (giVar_Z5_Use_Dut1_unit)
sprintf(final_blk_file, "..\\%s", blk_file_1);
else if (giVar_Z7_Use_Dut2_unit)
sprintf(final_blk_file, "..\\%s", blk_file_2);
else
return (0);
if ((read_file = fopen(final_blk_file, "rt")) == NULL)
{
output("\n<b><color=red>***********************************************************</color></b>");
output("<b><color=red>*** WARNING WARNING WARNING ***</color></b>");
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>*** %s fopen FAIL </color></b>", final_blk_file);
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>***********************************************************</color></b>\n");
return (0);
}
total_good_blk = 0;
for (index = 0; index < DEV_BLKS_PER_DIE; index++)
{
if (fgets(buffer, sizeof(buffer), read_file) != NULL)
{
sprintf(buf1, "%c%c", buffer[0], buffer[1]);
if (strcmp(buf1, "OK") == 0)
{
gi_Good_Blk[index] = 1;
total_good_blk++;
}
}
}
fclose(read_file);
}
total_2_good_blk_group = 0;
for (index = 0; index < DEV_BLKS_PER_DIE; index += 2) //always even blk
{
if (gi_Good_Blk[index] == 1)
{
if (gi_Good_Blk[index + 1] == 1)
{
gi_Good_2_Blk_Group[total_2_good_blk_group] = index;
total_2_good_blk_group++;
}
}
if (total_2_good_blk_group >= MAX_2_GOOD_BLK_GROUP)
break;
}
total_5_good_blk_group = 0;
for (index = 0; index < (DEV_BLKS_PER_DIE - 9); index += 2) //always even blk
{
if (gi_Good_Blk[index] == 1)
{
if ((gi_Good_Blk[index + 1] == 1) && (gi_Good_Blk[index + 2] == 1) && (gi_Good_Blk[index + 3] == 1) && (gi_Good_Blk[index + 4] == 1) && (gi_Good_Blk[index + 5] == 1) && (gi_Good_Blk[index + 6] == 1) && (gi_Good_Blk[index + 7] == 1) && (gi_Good_Blk[index + 8] == 1) && (gi_Good_Blk[index + 9] == 1)
)
{
gi_Good_5_Blk_Group[total_5_good_blk_group] = index;
total_5_good_blk_group++;
}
}
if (total_5_good_blk_group >= MAX_5_GOOD_BLK_GROUP)
break;
}
output("\n<b><color=red>***********************************************************</color></b>");
output("<b><color=red>*** WARNING WARNING WARNING ***</color></b>");
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>*** MASK REVISION = 0x%x </color></b>", giVar_Z1_Mask_Rev);
if (giVar_Z4_4_Duts_Paralell)
{
output("<b><color=red>*** GOOD BLK FILE 1 USED = %s </color></b>", blk_file_1);
output("<b><color=red>*** GOOD BLK FILE 2 USED = %s </color></b>", blk_file_2);
output("<b><color=red>*** GOOD BLK FILE 3 USED = %s </color></b>", blk_file_3);
output("<b><color=red>*** GOOD BLK FILE 4 USED = %s </color></b>", blk_file_4);
}
else if (giVar_Z4_2_Duts_Paralell)
{
output("<b><color=red>*** GOOD BLK FILE 1 USED = %s </color></b>", blk_file_1);
output("<b><color=red>*** GOOD BLK FILE 2 USED = %s </color></b>", blk_file_2);
}
else
{
if (giVar_Z5_Use_Dut1_unit)
output("<b><color=red>*** GOOD BLK FILE 1 USED = %s </color></b>", blk_file_1);
else if (giVar_Z7_Use_Dut2_unit)
output("<b><color=red>*** GOOD BLK FILE 2 USED = %s </color></b>", blk_file_2);
else
output("<b><color=red>*** NO BLK FILE is selected </color></b>");
}
output("<b><color=red>*** TOTAL GOOD BLOCKS = %d </color></b>", total_good_blk);
output("<b><color=red>*** TOTAL 2 GOOD BLK GROUP = %d </color></b>", total_2_good_blk_group);
output("<b><color=red>*** TOTAL 5 GOOD BLK GROUP = %d </color></b>", total_5_good_blk_group);
output("<b><color=red>*** ***</color></b>");
output("<b><color=red>*** MAKE SURE the right BLK FILE is used for test DUT ***</color></b>");
output("<b><color=red>***********************************************************</color></b>\n");
return (1);
}