mirror of
https://github.com/RTimothyEdwards/magic.git
synced 2026-08-29 17:39:28 +02:00
and forcing it to be passed as an argument to all the callback functions for the search routines that require it. Magic now compiles and runs with the new code, but there are a number of known issues that need to be fixed up. Committing now so that I can rebase on the last update to the master branch.
320 lines
8.3 KiB
C
320 lines
8.3 KiB
C
/*
|
|
* PlowRandom.c --
|
|
*
|
|
* Plowing.
|
|
* Random testing: generate a whole bunch of random plows
|
|
* and make sure each one produces a design-rule-correct
|
|
* result that has the same extracted circuit (minus the
|
|
* parasitics) as the initial cell.
|
|
*
|
|
* *********************************************************************
|
|
* * Copyright (C) 1985, 1990 Regents of the University of California. *
|
|
* * Permission to use, copy, modify, and distribute this *
|
|
* * software and its documentation for any purpose and without *
|
|
* * fee is hereby granted, provided that the above copyright *
|
|
* * notice appear in all copies. The University of California *
|
|
* * makes no representations about the suitability of this *
|
|
* * software for any purpose. It is provided "as is" without *
|
|
* * express or implied warranty. Export of this software outside *
|
|
* * of the United States of America may require an export license. *
|
|
* *********************************************************************
|
|
*/
|
|
|
|
#ifndef lint
|
|
static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/plow/PlowRandom.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
|
|
#endif /* not lint */
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
#include <sys/file.h>
|
|
#include <sys/stat.h>
|
|
#include <unistd.h>
|
|
#if defined(SYSV) || defined(EMSCRIPTEN)
|
|
#include <fcntl.h>
|
|
#endif
|
|
|
|
#include "utils/magic.h"
|
|
#include "utils/geometry.h"
|
|
#include "tiles/tile.h"
|
|
#include "utils/hash.h"
|
|
#include "database/database.h"
|
|
#include "plow/plowInt.h"
|
|
#include "textio/textio.h"
|
|
#include "utils/undo.h"
|
|
#include "utils/signals.h"
|
|
#include "extract/extract.h"
|
|
|
|
/* C99 compat */
|
|
#include "drc/drc.h"
|
|
|
|
/* Imports from PlowMain.c */
|
|
extern CellDef *plowYankDef;
|
|
|
|
/* Forward declarations */
|
|
int plowFindFirstError();
|
|
void plowGenRect();
|
|
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* PlowRandomTest --
|
|
*
|
|
* Random testing: generate a whole bunch of random plows
|
|
* and make sure each one produces a design-rule-correct
|
|
* result that has the same extracted circuit (minus the
|
|
* parasitics) as the initial cell.
|
|
*
|
|
* Output the coordinates and direction of each plow as
|
|
* we go, flagging it as one producing a DRC violation
|
|
* or a connectivity violation as we go.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* Writes a whole bunch of information via TxPrintf(),
|
|
* as described above.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
PlowRandomTest(def)
|
|
CellDef *def;
|
|
{
|
|
#ifdef notdef
|
|
static char *tempgood = "/tmp/PlowGoodaXXXXX";
|
|
static char *temptemp = "/tmp/PlowTempaXXXXX";
|
|
char goodName[64], tempName[64], goodExt[64], tempExt[64];
|
|
char command[256];
|
|
#endif /* notdef */
|
|
static int dirs[] = { GEO_NORTH, GEO_SOUTH, GEO_EAST, GEO_WEST };
|
|
static char *dirnames[] = { "up", "down", "right", "left" };
|
|
Rect plowRect;
|
|
int dir, plowDir;
|
|
Plane *savePlane;
|
|
|
|
#ifdef notdef
|
|
strcpy(goodName, tempgood);
|
|
strcpy(tempName, temptemp);
|
|
mkstemp(goodName);
|
|
mkstemp(tempName);
|
|
sprintf(goodExt, "%s.ext", goodName);
|
|
sprintf(tempExt, "%s.ext", tempName);
|
|
|
|
/* Generate "good" extracted file */
|
|
savePlane = ExtCell(def, goodName, FALSE);
|
|
ExtRevertSubstrate(def, savePlane);
|
|
(void) sprintf(command, "sedplow %s", goodExt);
|
|
system(command);
|
|
#endif /* notdef */
|
|
|
|
/* Repeatedly try to break plowing */
|
|
while (!SigInterruptPending)
|
|
{
|
|
/* Generate a random plow direction and rectangle */
|
|
dir = plowGenRandom(0, 3);
|
|
plowDir = dirs[dir];
|
|
plowGenRect(&def->cd_bbox, &plowRect);
|
|
(void) Plow(def, &plowRect, &DBAllTypeBits, plowDir);
|
|
TxPrintf("%s %d %d %d %d\n", dirnames[dir],
|
|
plowRect.r_xbot, plowRect.r_ybot,
|
|
plowRect.r_xtop, plowRect.r_ytop);
|
|
TxFlush();
|
|
|
|
/* Finish the design-rule check and count any errors */
|
|
DRCCatchUp();
|
|
if (DBSrPaintArea((Tile *) NULL, def->cd_planes[PL_DRC_ERROR],
|
|
&def->cd_bbox, &DBAllButSpaceBits,
|
|
plowFindFirstError, (ClientData) NULL))
|
|
{
|
|
TxPrintf("%s %d %d %d %d: DRC error\n", dirnames[dir],
|
|
plowRect.r_xbot, plowRect.r_ybot,
|
|
plowRect.r_xtop, plowRect.r_ytop);
|
|
TxFlush();
|
|
}
|
|
|
|
/* Turn off the modified bit so we get the same timestamp */
|
|
def->cd_flags &= ~CDMODIFIED;
|
|
|
|
#ifdef notdef
|
|
/* Extract to the temp file */
|
|
savePlane = ExtCell(def, tempName, FALSE);
|
|
ExtRevertSubstrate(def, savePlane);
|
|
(void) sprintf(command, "sedplow %s", tempExt);
|
|
system(command);
|
|
|
|
/* Check for any differences */
|
|
if (plowFileDiff(goodExt, tempExt))
|
|
{
|
|
TxPrintf("%s %d %d %d %d: EXT error\n", dirnames[dir],
|
|
plowRect.r_xbot, plowRect.r_ybot,
|
|
plowRect.r_xtop, plowRect.r_ytop);
|
|
TxFlush();
|
|
}
|
|
#endif /* notdef */
|
|
|
|
/* Make sure there's always something to undo */
|
|
DBPutLabel(def, &def->cd_bbox, -1, "dummylabel", TT_SPACE, 0, 0);
|
|
|
|
/* Undo */
|
|
UndoBackward(1);
|
|
}
|
|
|
|
#ifdef notdef
|
|
(void) unlink(goodExt);
|
|
(void) unlink(tempExt);
|
|
#endif /* notdef */
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* plowFindFirstError --
|
|
*
|
|
* Filter procedure called via DBSrPaintArea by PlowRandomTest()
|
|
* above, on the PL_DRC_ERROR plane, looking for non-space tiles.
|
|
*
|
|
* Results:
|
|
* Returns 1 always, to force DBSrPaintArea to abort and
|
|
* return 1.
|
|
*
|
|
* Side effects:
|
|
* None.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
int
|
|
plowFindFirstError(Tile *tile, TileType dinfo, ClientData clientdata)
|
|
{
|
|
return (1);
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* plowGenRect --
|
|
*
|
|
* Generate a random plow rectangle.
|
|
* This rectangle is guaranteed to lie within the bounding box of
|
|
* the cell. The four coordinates are chosen randomly from a uniform
|
|
* distribution, and then the rectangle is flipped to insure that its
|
|
* upper-right is above and to the right of its lower-left.
|
|
*
|
|
* Results:
|
|
* None.
|
|
*
|
|
* Side effects:
|
|
* Fills in the rectangle pointed to by 'r'.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
void
|
|
plowGenRect(bbox, r)
|
|
Rect *bbox; /* Bounding box of the cell being plowed */
|
|
Rect *r; /* Fill in this rectangle */
|
|
{
|
|
int temp;
|
|
|
|
r->r_xbot = plowGenRandom(bbox->r_xbot, bbox->r_xtop);
|
|
r->r_xtop = plowGenRandom(bbox->r_xbot, bbox->r_xtop);
|
|
r->r_ybot = plowGenRandom(bbox->r_ybot, bbox->r_ytop);
|
|
r->r_ytop = plowGenRandom(bbox->r_ybot, bbox->r_ytop);
|
|
if (r->r_xbot == r->r_xtop) r->r_xtop = r->r_xbot + 1;
|
|
if (r->r_ybot == r->r_ytop) r->r_ytop = r->r_ybot + 1;
|
|
if (r->r_xbot > r->r_xtop)
|
|
{
|
|
temp = r->r_xtop;
|
|
r->r_xtop = r->r_xbot;
|
|
r->r_xbot = temp;
|
|
}
|
|
if (r->r_ybot > r->r_ytop)
|
|
{
|
|
temp = r->r_ytop;
|
|
r->r_ytop = r->r_ybot;
|
|
r->r_ybot = temp;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* plowGenRandom --
|
|
*
|
|
* Generate a random integer chosen from the integers lo, lo+1, ..., hi,
|
|
* with each integer having equal probability.
|
|
*
|
|
* Results:
|
|
* Returns the integer described above.
|
|
*
|
|
* Side effects:
|
|
* None.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
int
|
|
plowGenRandom(lo, hi)
|
|
int lo, hi; /* Inclusive bounds for the integer we'll generate */
|
|
{
|
|
int range = hi - lo + 1;
|
|
#if defined(SYSV) || defined(EMSCRIPTEN)
|
|
int r = rand();
|
|
#else
|
|
int r = random();
|
|
#endif /* SYSV */
|
|
|
|
return ((r % range) + lo);
|
|
}
|
|
|
|
/*
|
|
* ----------------------------------------------------------------------------
|
|
*
|
|
* plowFileDiff --
|
|
*
|
|
* Compare two files for equality.
|
|
*
|
|
* Results:
|
|
* Returns TRUE if they are identical and the same length,
|
|
* FALSE if they differ.
|
|
*
|
|
* Side effects:
|
|
* None.
|
|
*
|
|
* ----------------------------------------------------------------------------
|
|
*/
|
|
|
|
bool
|
|
plowFileDiff(file1, file2)
|
|
char *file1;
|
|
char *file2;
|
|
{
|
|
char b1[BUFSIZ], b2[BUFSIZ];
|
|
int f1 = -1, f2 = -1;
|
|
int n1, n2;
|
|
bool ret = FALSE;
|
|
|
|
if ((f1 = open(file1, O_RDONLY, 0)) < 0) goto done;
|
|
if ((f2 = open(file2, O_RDONLY, 0)) < 0) goto done;
|
|
|
|
while ((n1 = read(f1, b1, BUFSIZ)) > 0)
|
|
{
|
|
n2 = read(f2, b2, BUFSIZ);
|
|
if (n1 != n2 || bcmp(b1, b2, n1) != 0)
|
|
goto done;
|
|
}
|
|
ret = TRUE;
|
|
|
|
done:
|
|
if (f1 >= 0)
|
|
(void) close(f1);
|
|
if (f2 >= 0)
|
|
(void) close(f2);
|
|
return (ret);
|
|
}
|