• Please review our updated Terms and Rules here

Cloning a PAL/HAL (Part 5)

Chuck(G)

25k Member
Joined
Jan 11, 2007
Messages
44,529
Location
Pacific Northwest, USA
Part 4 of this series can be found here.

Rather than pulling hair and drinking lots of coffee trying to manually figure out how PAL inputs are related to PAL outputs, we can investigate some reduction methods.

If you took computer engineering in school, you probably remember the Quine-McCluskey algorithm. There's plenty of material on the web about it, but it's not particularly efficient, particularly as the number of terms increases. There is also Petrick's Method, which is a bit easier to implement on a computer.

However, the reduction used by most EDA packages derives from the 1980s Espresso package, which uses several heuristics to perform Boolean reduction. In fact, there's a program called Minilog that will do pretty much what we want. It's a 32-bit Windows program that should run on anything from an P1 on up.

All we need is an input file in the format that this program expects. We can do this with the following program that simply takes the output from our reader program and reformats it.
Code:
//  Create a Minilog input file for 10L8 from Palread output.
//  ---------------------------------------------------------
//
//    Read in the PALRead file, and produce a Minilog input file.
//

#include <stdlib.h>
#include <stdio.h>

#define INPUT_BITS 10                   // number of input bits
#define OUTPUT_BITS 8                   // number of output bits
#define PAL_SIZE (1<<INPUT_BITS)        // 2**number of inputs
#define PAL_NAME "PAL10L8"              // What is this thing


typedef struct
{
  unsigned int Index;
  unsigned int Value;
} SAMPLE_ITEM, *PSAMPLE_ITEM;

SAMPLE_ITEM Sample[PAL_SIZE];                    // sample array


//  The following holds information used to determine what inputs
//  affect what outputs.


void BitPrint( FILE *Where, unsigned int What, int Howmany);

void main( int argc, char *argv[])
{

  FILE *in;
  int i, j, k;


//  Get the file open.

  if ( argc < 2)
  {
    fprintf( stderr, "\nERROR - you need the name of a Samplesle file.\n");
    exit(1);
  }
  in = fopen( argv[1],"r");
  if (!in)
  {
    fprintf( stderr, "\nERROR - cannot open %s\n", argv[1]);
    exit(2);
  }

//  Read the Samplesles in.

  for ( i = 0; i < PAL_SIZE; i++)
  {

    unsigned int kt;

    if ( !fscanf( in, "%x", &Sample[i].Value))
      fprintf(stderr, "Input error at line %d\n", i); // read a value

    Sample[i].Index = i;                   // stash the index
  } // for
  fclose(in);                           // okay we're done

//  Generate a Minilog input file.

  printf( "table %s\n", PAL_NAME);

//  Generate some input variable names.

  printf("  INPUT ");
  for( i = INPUT_BITS-1; i >= 0; i--)
    printf( "I%d ",i);
 
//  And some output variable names.

  printf("\n    OUTPUT ");
  for ( i = OUTPUT_BITS-1; i >= 0; i--)
    printf("O%d ",i);
  printf("\n");

//  Generate the truth table.

  for( i = 0; i < PAL_SIZE; i++)
  {
    printf( "  ");
    BitPrint( stdout, i, INPUT_BITS);
    printf(" ");                        // for readability

//  Since this is a negative-logic PAL, we invert the outputs.
//  We'll define the outputs as inverted in the .EQN file.

    BitPrint( stdout, ~Sample[i].Value, OUTPUT_BITS);
    printf("\n");
  } // output the truth table
 
//  Finally, end the table.

  printf("END\n");
}  // end of main


//  Print a binary string.
//  ----------------------
//
//  Input is a file, int, and the number of bits to print.
//

void BitPrint( FILE *Where, unsigned int What, int Howmany)
{

  int i;

  for ( i = Howmany-1; i >= 0; i--)
  {
    fputc( (((1 << i) & What) ? '1' : '0'), Where);
  }
} // BitPrint

On to part 6...
 
Back
Top