kenanlian
3/8/2019 - 7:57 AM

[site_begin function in functional code] What is done in site_begin, the beginning of the test flow #Magnum2

[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);
}