diff options
author | hap <happppp@users.noreply.github.com> | 2014-11-16 05:01:08 +0100 |
---|---|---|
committer | hap <happppp@users.noreply.github.com> | 2014-11-16 05:01:08 +0100 |
commit | 301af68a068d069e153b6c494585296c94e9cada (patch) | |
tree | c7479b6b68e39ad11de1d6bab5c23b212966e503 | |
parent | 02fc842fe94008da4d821f84a70507fa46ed8f25 (diff) |
made plaparse less strict about whitespace and ordering, and added .phase keyword
-rw-r--r-- | src/lib/util/plaparse.c | 298 |
1 files changed, 194 insertions, 104 deletions
diff --git a/src/lib/util/plaparse.c b/src/lib/util/plaparse.c index 65c84b04f09..03eaed0017b 100644 --- a/src/lib/util/plaparse.c +++ b/src/lib/util/plaparse.c @@ -4,7 +4,9 @@ plaparse.h - Parser for Berkeley standard PLA files into raw fusemaps. + Simple parser for Berkeley standard PLA files into raw fusemaps. + It supports no more than one output matrix, and is limited to + keywords: i, o, p, phase, e ***************************************************************************/ @@ -31,9 +33,11 @@ struct parse_info { - UINT32 inputs; - UINT32 outputs; - UINT32 terms; + UINT32 inputs; /* number of input columns */ + UINT32 outputs; /* number of output columns */ + UINT32 terms; /* number of terms */ + UINT32 xorval[JED_MAX_FUSES/64]; /* output polarity */ + UINT32 xorptr; }; @@ -57,20 +61,22 @@ static int iscrlf(char c) character stream -------------------------------------------------*/ -static UINT32 suck_number(const UINT8 **psrc) +static UINT32 suck_number(const UINT8 **cursrc, const UINT8 *srcend) { - const UINT8 *src = *psrc; UINT32 value = 0; + (*cursrc)++; + + // find first digit + while (*cursrc < srcend && !iscrlf(**cursrc) && !isdigit(**cursrc)) + (*cursrc)++; // loop over and accumulate digits - while (isdigit(*src)) + while (isdigit(**cursrc)) { - value = value * 10 + *src - '0'; - src++; + value = value * 10 + (**cursrc) - '0'; + (*cursrc)++; } - // return a pointer to the string afterwards - *psrc = src; return value; } @@ -81,113 +87,178 @@ static UINT32 suck_number(const UINT8 **psrc) ***************************************************************************/ /*------------------------------------------------- - process_field - process a single field + process_terms - process input/output matrix -------------------------------------------------*/ -static void process_field(jed_data *data, const UINT8 *cursrc, const UINT8 *srcend, parse_info *pinfo) +static bool process_terms(jed_data *data, const UINT8 **cursrc, const UINT8 *srcend, parse_info *pinfo) { - cursrc++; + UINT32 curinput = 0; + UINT32 curoutput = 0; + bool outputs = false; - // switch off of the field type - switch (*cursrc) + while (*cursrc < srcend && **cursrc != '.' && **cursrc != '#') { - // number of inputs - case 'i': - cursrc += 2; - pinfo->inputs = suck_number(&cursrc); - if (LOG_PARSE) printf("Inputs: %u\n", pinfo->inputs); - break; - - // number of outputs - case 'o': - cursrc += 2; - pinfo->outputs = suck_number(&cursrc); - if (LOG_PARSE) printf("Outputs: %u\n", pinfo->outputs); - break; - - // number of product terms - case 'p': + switch (**cursrc) { - cursrc += 2; - pinfo->terms = suck_number(&cursrc); - if (LOG_PARSE) printf("Terms: %u\n", pinfo->terms); + case '-': + if (!outputs) + { + curinput++; + jed_set_fuse(data, data->numfuses++, 1); + jed_set_fuse(data, data->numfuses++, 1); - UINT32 curfuse = 0; - bool outputs = false; + if (LOG_PARSE) printf("11"); + } + break; - cursrc++; - while (cursrc < srcend && *cursrc != '.') - { - switch (*cursrc) + case '~': + if (!outputs) { - case '-': - if (!outputs) - { - jed_set_fuse(data, curfuse++, 1); - jed_set_fuse(data, curfuse++, 1); + curinput++; + // this product term is inhibited + jed_set_fuse(data, data->numfuses++, 0); + jed_set_fuse(data, data->numfuses++, 0); - if (LOG_PARSE) printf("11"); - } - break; + if (LOG_PARSE) printf("00"); + } + break; - case '1': - if (outputs) - { - jed_set_fuse(data, curfuse++, 0); + case '1': + if (outputs) + { + curoutput++; + jed_set_fuse(data, data->numfuses++, 0); - if (LOG_PARSE) printf("0"); - } - else - { - jed_set_fuse(data, curfuse++, 1); - jed_set_fuse(data, curfuse++, 0); + if (LOG_PARSE) printf("0"); + } + else + { + curinput++; + jed_set_fuse(data, data->numfuses++, 1); + jed_set_fuse(data, data->numfuses++, 0); - if (LOG_PARSE) printf("10"); - } - break; + if (LOG_PARSE) printf("10"); + } + break; - case '0': - if (outputs) - { - jed_set_fuse(data, curfuse++, 1); + case '0': + if (outputs) + { + curoutput++; + jed_set_fuse(data, data->numfuses++, 1); - if (LOG_PARSE) printf("1"); - } - else - { - jed_set_fuse(data, curfuse++, 0); - jed_set_fuse(data, curfuse++, 1); + if (LOG_PARSE) printf("1"); + } + else + { + curinput++; + jed_set_fuse(data, data->numfuses++, 0); + jed_set_fuse(data, data->numfuses++, 1); - if (LOG_PARSE) printf("01"); - } - break; + if (LOG_PARSE) printf("01"); + } + break; - case ' ': + case ' ': case '\t': + if (curinput > 0) + { outputs = true; if (LOG_PARSE) printf(" "); - break; } + break; + + default: + break; + } + + if (iscrlf(**cursrc) && outputs) + { + outputs = false; + if (LOG_PARSE) printf("\n"); + + if (curinput != pinfo->inputs || curoutput != pinfo->outputs) + return false; + + curinput = 0; + curoutput = 0; + } - if (iscrlf(*cursrc) && outputs) + (*cursrc)++; + } + + return true; +} + + + +/*------------------------------------------------- + process_field - process a single field +-------------------------------------------------*/ + +static bool process_field(jed_data *data, const UINT8 **cursrc, const UINT8 *srcend, parse_info *pinfo) +{ + (*cursrc)++; + + switch (**cursrc) + { + // number of inputs + case 'i': + pinfo->inputs = suck_number(cursrc, srcend); + if (pinfo->inputs == 0 || pinfo->inputs >= (JED_MAX_FUSES/2)) + return false; + + if (LOG_PARSE) printf("Inputs: %u\n", pinfo->inputs); + break; + + // number of outputs + case 'o': + pinfo->outputs = suck_number(cursrc, srcend); + if (pinfo->outputs == 0 || pinfo->outputs >= (JED_MAX_FUSES/2)) + return false; + + if (LOG_PARSE) printf("Outputs: %u\n", pinfo->outputs); + break; + + case 'p': + // output polarity (optional) + if ((*cursrc)[1] == 'h' && (*cursrc)[2] == 'a' && (*cursrc)[3] == 's' && (*cursrc)[4] == 'e') + { + if (LOG_PARSE) printf("Phase...\n"); + while (*cursrc < srcend && !iscrlf(**cursrc) && pinfo->xorptr < (JED_MAX_FUSES/2)) { - outputs = false; - if (LOG_PARSE) printf("\n"); + if (**cursrc == '0' || **cursrc == '1') + { + // 0 is negative + if (**cursrc == '0') + pinfo->xorval[pinfo->xorptr/32] |= 1 << (pinfo->xorptr & 31); + pinfo->xorptr++; + } + + (*cursrc)++; } - - cursrc++; } + + // or number of product terms (optional) + else + { + pinfo->terms = suck_number(cursrc, srcend); + if (pinfo->terms == 0 || pinfo->terms >= (JED_MAX_FUSES/2)) + return false; - data->numfuses = curfuse; + if (LOG_PARSE) printf("Terms: %u\n", pinfo->terms); + } break; - } - // end of file + // end of file (optional) case 'e': if (LOG_PARSE) printf("End of file\n"); break; + + default: + return false; } - - cursrc++; + + return true; } @@ -201,34 +272,53 @@ int pla_parse(const void *data, size_t length, jed_data *result) { const UINT8 *cursrc = (const UINT8 *)data; const UINT8 *srcend = cursrc + length; - const UINT8 *scan; + parse_info pinfo; + memset(&pinfo, 0, sizeof(pinfo)); result->numfuses = 0; - memset(result->fusemap, 0x00, sizeof(result->fusemap)); + memset(result->fusemap, 0, sizeof(result->fusemap)); while (cursrc < srcend) { - if (*cursrc == '#') + switch (*cursrc) { - cursrc++; - while (cursrc < srcend && !iscrlf(*cursrc)) + // comment line + case '#': + while (cursrc < srcend && !iscrlf(*cursrc)) + cursrc++; + break; + + // keyword + case '.': + if (!process_field(result, &cursrc, srcend, &pinfo)) + return JEDERR_INVALID_DATA; + break; + + // terms + case '0': case '1': case '-': case '~': + if (!process_terms(result, &cursrc, srcend, &pinfo)) + return JEDERR_INVALID_DATA; + break; + + default: cursrc++; + break; } - else if (*cursrc == '.') + } + + // write output polarity + if (pinfo.xorptr > 0) + { + if (LOG_PARSE) printf("Polarity: "); + + for (int i = 0; i < pinfo.outputs; i++) { - scan = cursrc; - while (scan < srcend && !iscrlf(*scan)) - scan++; - if (scan >= srcend) - return JEDERR_INVALID_DATA; - - process_field(result, cursrc, srcend, &pinfo); - - cursrc = scan + 1; + int bit = pinfo.xorval[i/32] >> (i & 31) & 1; + jed_set_fuse(result, result->numfuses++, bit); + if (LOG_PARSE) printf("%d", bit); } - - cursrc++; + if (LOG_PARSE) printf("\n"); } return JEDERR_NONE; |