From e7a76a5f882d36ecc392e14e236e1c45e773ff02 Mon Sep 17 00:00:00 2001 From: Aranganathan Rathinavelu Date: Sun, 29 Sep 2024 01:53:59 +0200 Subject: [PATCH] code refactor --- README.md | 8 +- src/blocks/BackgroundGrid.tsx | 2 +- src/blocks/Labels.tsx | 2 +- src/blocks/ParameterInputs.tsx | 4 +- src/blocks/ResultsDisplay.tsx | 2 +- src/blocks/ShiftInputs.tsx | 2 +- src/blocks/SingleInput.tsx | 2 +- src/blocks/WaferDiameterSelect.tsx | 10 +- src/blocks/WaferMap.tsx | 104 ++++++++++--------- src/blocks/WaferOutline.tsx | 2 +- src/blocks/YieldControls.tsx | 66 ++++++++++++ src/contexts/useDieYield.tsx | 19 ++-- src/lib/calculateDiePositionAndDimensions.ts | 58 +++++------ src/lib/countDies.ts | 10 +- src/lib/createDies.ts | 90 ++++++++-------- src/lib/getDieColor.ts | 24 ++--- src/lib/{isInWafer.tsx => getDieStatus.ts} | 2 +- src/pages/DieYield/constants.ts | 2 +- src/pages/DieYield/index.tsx | 64 +----------- src/types/index.tsx | 9 ++ 20 files changed, 263 insertions(+), 219 deletions(-) create mode 100644 src/blocks/YieldControls.tsx rename src/lib/{isInWafer.tsx => getDieStatus.ts} (97%) diff --git a/README.md b/README.md index cf07140..77488c8 100644 --- a/README.md +++ b/README.md @@ -22,21 +22,25 @@ The Die Wise is a sophisticated tool designed for semiconductor manufacturing pr ## Installation 1. Clone the repository: + ```bash git clone https://github.com/arangates/die-wise.git ``` 2. Navigate to the project directory: + ```bash cd die-wise ``` 3. Install dependencies: + ```bash npm install ``` 4. Start the development server: + ```bash npm run dev ``` @@ -62,7 +66,6 @@ The Die Wise is a sophisticated tool designed for semiconductor manufacturing pr - **Excluded Dies**: Dies in the edge exclusion zone. - **Yield Estimation**: Based on defect density and die area. - ## License This project is licensed under the MIT License. @@ -70,7 +73,8 @@ This project is licensed under the MIT License. ## Acknowledgments - Inspired by the needs of semiconductor manufacturing professionals --Wafer Map Estimation using Murphy’s Model of Die Yield + -Wafer Map Estimation using Murphy’s Model of Die Yield + ## Contact For questions, suggestions, or support, please open an issue in the GitHub repository diff --git a/src/blocks/BackgroundGrid.tsx b/src/blocks/BackgroundGrid.tsx index 768a840..85e0960 100644 --- a/src/blocks/BackgroundGrid.tsx +++ b/src/blocks/BackgroundGrid.tsx @@ -25,4 +25,4 @@ export const BackgroundGrid: React.FC<{ size: number }> = ({ size }) => ( /> ))} -) \ No newline at end of file +) diff --git a/src/blocks/Labels.tsx b/src/blocks/Labels.tsx index d363a81..6db746f 100644 --- a/src/blocks/Labels.tsx +++ b/src/blocks/Labels.tsx @@ -15,4 +15,4 @@ export const Labels: React.FC<{ size: number }> = ({ size }) => ( Exclusion Edge -) \ No newline at end of file +) diff --git a/src/blocks/ParameterInputs.tsx b/src/blocks/ParameterInputs.tsx index 5716db3..a35d838 100644 --- a/src/blocks/ParameterInputs.tsx +++ b/src/blocks/ParameterInputs.tsx @@ -13,7 +13,6 @@ export const ParameterInputs: React.FC<{ value={parameters.dieSize.horizontal} onChange={onChange} step="0.1" - className="border-red-500" /> -) \ No newline at end of file +) diff --git a/src/blocks/ResultsDisplay.tsx b/src/blocks/ResultsDisplay.tsx index e452af4..de0d426 100644 --- a/src/blocks/ResultsDisplay.tsx +++ b/src/blocks/ResultsDisplay.tsx @@ -24,4 +24,4 @@ export const ResultsDisplay: React.FC<{ Max Dies Per Wafer (without defect) #{results.goodDevices}

-) \ No newline at end of file +) diff --git a/src/blocks/ShiftInputs.tsx b/src/blocks/ShiftInputs.tsx index e0d1a5a..516c3ba 100644 --- a/src/blocks/ShiftInputs.tsx +++ b/src/blocks/ShiftInputs.tsx @@ -20,4 +20,4 @@ export const ShiftInputs: React.FC<{ onChange={onChange} /> -) \ No newline at end of file +) diff --git a/src/blocks/SingleInput.tsx b/src/blocks/SingleInput.tsx index 5fee931..202f4a9 100644 --- a/src/blocks/SingleInput.tsx +++ b/src/blocks/SingleInput.tsx @@ -22,4 +22,4 @@ export const SingleInput: React.FC<{ className={className} /> -) \ No newline at end of file +) diff --git a/src/blocks/WaferDiameterSelect.tsx b/src/blocks/WaferDiameterSelect.tsx index 983d52c..4f67d67 100644 --- a/src/blocks/WaferDiameterSelect.tsx +++ b/src/blocks/WaferDiameterSelect.tsx @@ -1,5 +1,11 @@ import React from "react" -import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select" +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from "@/components/ui/select" import { Label } from "@/components/ui/label" export const WaferDiameterSelect: React.FC<{ @@ -20,4 +26,4 @@ export const WaferDiameterSelect: React.FC<{ -) \ No newline at end of file +) diff --git a/src/blocks/WaferMap.tsx b/src/blocks/WaferMap.tsx index 42ce0c5..cdfe74a 100644 --- a/src/blocks/WaferMap.tsx +++ b/src/blocks/WaferMap.tsx @@ -1,56 +1,66 @@ -import { DieCalculationParameters } from "@/types" -import { createDies } from "../lib/createDies" +import type { DieCalculationParameters } from "@/types" +import { createDies } from "@/lib/createDies" import { BackgroundGrid } from "@/blocks/BackgroundGrid" import { WaferOutline } from "@/blocks/WaferOutline" import { Labels } from "@/blocks/Labels" -export const WaferMap = ({parameters}: {parameters: DieCalculationParameters}) => { - const size = 900 - const centerX = size / 2 - const centerY = size / 2 - const radius = size / 2 - 10 - const exclusionRadius = radius * (1 - parameters.edgeLoss / parameters.waferDiameter) +export const WaferMap = ({ + parameters, +}: { + parameters: DieCalculationParameters +}) => { + const size = 900 + const centerX = size / 2 + const centerY = size / 2 + const radius = size / 2 + const exclusionRadius = + radius * (1 - parameters.edgeLoss / parameters.waferDiameter) - const reticle = { - horizontal: parameters.dieSize.horizontal + parameters.dieSpacing.horizontal, - vertical: parameters.dieSize.vertical + parameters.dieSpacing.vertical, - } + const reticle = { + horizontal: + parameters.dieSize.horizontal + parameters.dieSpacing.horizontal, + vertical: parameters.dieSize.vertical + parameters.dieSpacing.vertical, + } - const dieCountHorizontal = Math.round(parameters.waferDiameter / reticle.horizontal) - const dieCountVertical = Math.round(parameters.waferDiameter / reticle.vertical) - const scale = size / parameters.waferDiameter + const dieCountHorizontal = Math.round( + parameters.waferDiameter / reticle.horizontal + ) + const dieCountVertical = Math.round( + parameters.waferDiameter / reticle.vertical + ) + const scale = size / parameters.waferDiameter - const dies = createDies( - dieCountHorizontal, - dieCountVertical, - reticle, - scale, - centerX, - centerY, - radius, - parameters - ) + const dies = createDies( + dieCountHorizontal, + dieCountVertical, + reticle, + scale, + centerX, + centerY, + radius, + parameters + ) - return ( - - - + + + {dies.map((die) => ( + - {dies.map((die) => ( - - ))} - - - ) - } \ No newline at end of file + ))} + + + ) +} diff --git a/src/blocks/WaferOutline.tsx b/src/blocks/WaferOutline.tsx index c05013a..9093a8f 100644 --- a/src/blocks/WaferOutline.tsx +++ b/src/blocks/WaferOutline.tsx @@ -24,4 +24,4 @@ export const WaferOutline: React.FC<{ fill="none" /> -) \ No newline at end of file +) diff --git a/src/blocks/YieldControls.tsx b/src/blocks/YieldControls.tsx new file mode 100644 index 0000000..0e38932 --- /dev/null +++ b/src/blocks/YieldControls.tsx @@ -0,0 +1,66 @@ +import { Button } from "@/components/ui/button" +import { SingleInput } from "@/blocks/SingleInput" +import { ShiftInputs } from "@/blocks/ShiftInputs" +import { ParameterInputs } from "@/blocks/ParameterInputs" +import { WaferDiameterSelect } from "@/blocks/WaferDiameterSelect" +import { useDieYield } from "@/contexts/useDieYield" + +const YieldControls: React.FC = () => { + const { parameters, setParameters, resetParameters } = useDieYield() + + const handleInputChange = (event: React.ChangeEvent) => { + const { name, value } = event.target + setParameters((prev) => { + const newParameters: any = { ...prev } + if (name.includes(".")) { + const [parent, child] = name.split(".") + newParameters[parent] = { + ...newParameters[parent], + [child]: parseFloat(value), + } + } else { + newParameters[name] = parseFloat(value) + } + return newParameters + }) + } + + return ( + <> + + setParameters((prev) => ({ + ...prev, + waferDiameter: parseInt(value), + })) + } + /> + + + + + + + + ) +} + +export { YieldControls} diff --git a/src/contexts/useDieYield.tsx b/src/contexts/useDieYield.tsx index a006804..fdff8e6 100644 --- a/src/contexts/useDieYield.tsx +++ b/src/contexts/useDieYield.tsx @@ -12,10 +12,15 @@ interface DieYieldContextProps { resetParameters: () => void } -const DieYieldContext = createContext(undefined) - -export const DieYieldProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { - const [parameters, setParameters] = useState(INITIAL_PARAMETERS) +const DieYieldContext = createContext( + undefined +) + +export const DieYieldProvider: React.FC<{ children: React.ReactNode }> = ({ + children, +}) => { + const [parameters, setParameters] = + useState(INITIAL_PARAMETERS) const [results, setResults] = useState(INITIAL_RESULTS) useEffect(() => { @@ -35,7 +40,9 @@ export const DieYieldProvider: React.FC<{ children: React.ReactNode }> = ({ chil } return ( - + {children} ) @@ -47,4 +54,4 @@ export const useDieYield = () => { throw new Error("useDieYield must be used within a DieYieldProvider") } return context -} \ No newline at end of file +} diff --git a/src/lib/calculateDiePositionAndDimensions.ts b/src/lib/calculateDiePositionAndDimensions.ts index 029ca83..fe3cd7d 100644 --- a/src/lib/calculateDiePositionAndDimensions.ts +++ b/src/lib/calculateDiePositionAndDimensions.ts @@ -1,33 +1,33 @@ import type { DieCalculationParameters } from "@/types" - export const calculateDiePositionAndDimensions = ( - x: number, - y: number, - reticle: any, - scale: number, - centerX: number, - centerY: number, - parameters: DieCalculationParameters - ) => { - const offsetX = - parameters.dieSpacing.horizontal * 0.5 + parameters.horizontalShift - const offsetY = - parameters.dieSpacing.vertical * 0.5 + parameters.verticalShift +export const calculateDiePositionAndDimensions = ( + x: number, + y: number, + reticle: any, + scale: number, + centerX: number, + centerY: number, + parameters: DieCalculationParameters +) => { + const offsetX = + parameters.dieSpacing.horizontal * 0.5 + parameters.horizontalShift + const offsetY = + parameters.dieSpacing.vertical * 0.5 + parameters.verticalShift - const diePositionX = - centerX + - (x - 0.5 * Math.round(parameters.waferDiameter / reticle.horizontal)) * - reticle.horizontal * - scale + - offsetX * scale - const diePositionY = - centerY + - (y - 0.5 * Math.round(parameters.waferDiameter / reticle.vertical)) * - reticle.vertical * - scale + - offsetY * scale - const dieDimensionX = parameters.dieSize.horizontal * scale - const dieDimensionY = parameters.dieSize.vertical * scale + const diePositionX = + centerX + + (x - 0.5 * Math.round(parameters.waferDiameter / reticle.horizontal)) * + reticle.horizontal * + scale + + offsetX * scale + const diePositionY = + centerY + + (y - 0.5 * Math.round(parameters.waferDiameter / reticle.vertical)) * + reticle.vertical * + scale + + offsetY * scale + const dieDimensionX = parameters.dieSize.horizontal * scale + const dieDimensionY = parameters.dieSize.vertical * scale - return { diePositionX, diePositionY, dieDimensionX, dieDimensionY } - } \ No newline at end of file + return { diePositionX, diePositionY, dieDimensionX, dieDimensionY } +} diff --git a/src/lib/countDies.ts b/src/lib/countDies.ts index 3da3ad7..24db727 100644 --- a/src/lib/countDies.ts +++ b/src/lib/countDies.ts @@ -1,5 +1,5 @@ import type { DieCalculationParameters, DieCalculationResults } from "@/types" -import { isInWafer } from "./isInWafer" +import { getDieStatus } from "./getDieStatus" export const countDies = ( parameters: DieCalculationParameters, @@ -47,7 +47,7 @@ export const countDies = ( const dieDimensionX = parameters.dieSize.horizontal const dieDimensionY = parameters.dieSize.vertical - const dieInWafer = isInWafer( + const diePositionInWafer = getDieStatus( diePositionX, diePositionY, dieDimensionX, @@ -57,9 +57,9 @@ export const countDies = ( ) // Increment counters based on die position - if (dieInWafer === 4) results.partialDevices++ - if (dieInWafer === 2) results.excludedDevices++ - if (dieInWafer === 1) results.goodDevices++ + if (diePositionInWafer === 4) results.partialDevices++ + if (diePositionInWafer === 2) results.excludedDevices++ + if (diePositionInWafer === 1) results.goodDevices++ } } diff --git a/src/lib/createDies.ts b/src/lib/createDies.ts index a5f31f3..2884ad1 100644 --- a/src/lib/createDies.ts +++ b/src/lib/createDies.ts @@ -1,52 +1,52 @@ -import type { DieCalculationParameters } from "@/types" +import type { Die, DieCalculationParameters, Point } from "@/types" import { calculateDiePositionAndDimensions } from "./calculateDiePositionAndDimensions" import { getDieColor } from "./getDieColor" -import { isInWafer } from "./isInWafer" +import { getDieStatus } from "./getDieStatus" - export const createDies = ( - dieCountHorizontal: number, - dieCountVertical: number, - reticle: any, - scale: number, - centerX: number, - centerY: number, - radius: number, - parameters: DieCalculationParameters - ) => { - const dies = [] - for (let x = 0; x < dieCountHorizontal; x++) { - for (let y = 0; y < dieCountVertical; y++) { - const { diePositionX, diePositionY, dieDimensionX, dieDimensionY } = - calculateDiePositionAndDimensions( - x, - y, - reticle, - scale, - centerX, - centerY, - parameters - ) - const dieInWafer = isInWafer( - diePositionX, - diePositionY, - dieDimensionX, - dieDimensionY, - radius * 2, - radius * 2 - parameters.edgeLoss * 2 * scale +export const createDies = ( + dieCountHorizontal: number, + dieCountVertical: number, + reticle: Point, + scale: number, + centerX: number, + centerY: number, + radius: number, + parameters: DieCalculationParameters +) => { + const dies: Die[] = [] + for (let x = 0; x < dieCountHorizontal; x++) { + for (let y = 0; y < dieCountVertical; y++) { + const { diePositionX, diePositionY, dieDimensionX, dieDimensionY } = + calculateDiePositionAndDimensions( + x, + y, + reticle, + scale, + centerX, + centerY, + parameters ) + const dieInWafer = getDieStatus( + diePositionX, + diePositionY, + dieDimensionX, + dieDimensionY, + radius * 2, + radius * 2 - parameters.edgeLoss * 2 * scale + ) - const dieColor = getDieColor(dieInWafer) - if (dieColor) { - dies.push({ - key: `die-${x}-${y}`, - x: diePositionX, - y: diePositionY, - width: dieDimensionX, - height: dieDimensionY, - fill: dieColor - }) - } + const dieColor = getDieColor(dieInWafer) + if (dieColor) { + dies.push({ + key: `die-${x}-${y}`, + x: diePositionX, + y: diePositionY, + width: dieDimensionX, + height: dieDimensionY, + fill: dieColor, + }) } } - return dies - } \ No newline at end of file + } + return dies +} diff --git a/src/lib/getDieColor.ts b/src/lib/getDieColor.ts index dcc6ee0..7373fdd 100644 --- a/src/lib/getDieColor.ts +++ b/src/lib/getDieColor.ts @@ -1,12 +1,12 @@ - export const getDieColor = (dieInWafer: number) => { - switch (dieInWafer) { - case 1: - return "rgba(70,200,70,0.8)" // Good dies - case 2: - return "rgba(240,70,70,0.8)" // Wasted dies - case 4: - return "rgba(220,210,0,0.8)" // Partial dies - default: - return null // Skip dies outside the wafer - } - } \ No newline at end of file +export const getDieColor = (dieInWafer: number) => { + switch (dieInWafer) { + case 1: + return "rgba(70,200,70,0.8)" // Good dies + case 2: + return "rgba(240,70,70,0.8)" // Wasted dies + case 4: + return "rgba(220,210,0,0.8)" // Partial dies + default: + return null // Skip dies outside the wafer + } +} diff --git a/src/lib/isInWafer.tsx b/src/lib/getDieStatus.ts similarity index 97% rename from src/lib/isInWafer.tsx rename to src/lib/getDieStatus.ts index cae5463..6a8a386 100644 --- a/src/lib/isInWafer.tsx +++ b/src/lib/getDieStatus.ts @@ -1,4 +1,4 @@ -export const isInWafer = ( +export const getDieStatus = ( diePositionX: number, diePositionY: number, dieDimensionX: number, diff --git a/src/pages/DieYield/constants.ts b/src/pages/DieYield/constants.ts index ea7f838..85d2f0d 100644 --- a/src/pages/DieYield/constants.ts +++ b/src/pages/DieYield/constants.ts @@ -23,4 +23,4 @@ export const INITIAL_RESULTS: DieCalculationResults = { partialDevices: 0, excludedDevices: 0, yield: 0, -} \ No newline at end of file +} diff --git a/src/pages/DieYield/index.tsx b/src/pages/DieYield/index.tsx index a25ef1e..99aa172 100644 --- a/src/pages/DieYield/index.tsx +++ b/src/pages/DieYield/index.tsx @@ -2,77 +2,21 @@ import { useDieYield } from "@/contexts/useDieYield" -import { Button } from "@/components/ui/button" import { Card, CardContent } from "@/components/ui/card" -import { ParameterInputs } from "@/blocks/ParameterInputs" import { ResultsDisplay } from "@/blocks/ResultsDisplay" -import { ShiftInputs } from "@/blocks/ShiftInputs" -import { SingleInput } from "@/blocks/SingleInput" -import { WaferDiameterSelect } from "@/blocks/WaferDiameterSelect" import { WaferMap } from "@/blocks/WaferMap" +import { YieldControls } from "@/blocks/YieldControls" const DieYield: React.FC = () => { - const { parameters, results, setParameters, resetParameters } = useDieYield() - - - const handleInputChange = (event: React.ChangeEvent) => { - const { name, value } = event.target - setParameters((prev) => { - const newParameters: any = { ...prev } - if (name.includes(".")) { - const [parent, child] = name.split(".") - newParameters[parent] = { - ...newParameters[parent], - [child]: parseFloat(value), - } - } else { - newParameters[name] = parseFloat(value) - } - return newParameters - }) - } + const { parameters, results } = useDieYield() return (
-
- - - setParameters((prev) => ({ - ...prev, - waferDiameter: parseInt(value), - })) - } - /> - - - - +
@@ -89,4 +33,4 @@ const DieYield: React.FC = () => { ) } -export default DieYield \ No newline at end of file +export default DieYield diff --git a/src/types/index.tsx b/src/types/index.tsx index b5597e0..e982527 100644 --- a/src/types/index.tsx +++ b/src/types/index.tsx @@ -22,3 +22,12 @@ export type DieCalculationResults = { excludedDevices: number yield: number } + +export type Die = { + key: string + x: number + y: number + width: number + height: number + fill: string +}