PageRenderTime 58ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 1ms

/alliance-5.0/genlib/src/dpgen_ROM_code.y

#
Happy | 740 lines | 655 code | 85 blank | 0 comment | 0 complexity | 7c4d501b1c4e2b94e1316a1e3a5551c3 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0
  1. /*
  2. * This file has been stolen from the old full custom ROM generator : Grog...
  3. * Courtesy of Mr Fred Petrot.
  4. *
  5. */
  6. %{
  7. #include <stdio.h>
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include <ctype.h>
  11. #include <mut.h>
  12. typedef struct vhdl_constant {
  13. struct vhdl_constant *NEXT;
  14. char *string;
  15. char *value;
  16. } dptr;
  17. static char oct2bin[8][4] = {
  18. "000",
  19. "001",
  20. "010",
  21. "011",
  22. "100",
  23. "101",
  24. "110",
  25. "111"
  26. };
  27. static char hex2bin[16][5] = {
  28. "0000",
  29. "0001",
  30. "0010",
  31. "0011",
  32. "0100",
  33. "0101",
  34. "0110",
  35. "0111",
  36. "1000",
  37. "1001",
  38. "1010",
  39. "1011",
  40. "1100",
  41. "1101",
  42. "1110",
  43. "1111"
  44. };
  45. static char *vhdl_line;
  46. static dptr *asc = NULL;
  47. static int line = 0;
  48. static int notempty = 0;
  49. static char datbuf[65];
  50. static char adrbuf[33];
  51. static long nwords, nbits, rf, ibmbull;
  52. static long *ydata;
  53. static long used[8912];
  54. static char aorder; /* vector order for addresses */
  55. static char forder; /* vector order for data out */
  56. static void readvhdlfile();
  57. static int yylex();
  58. static int yyerror();
  59. /* danger :
  60. These three functions use an internal buffer when called, so
  61. avoid calling them twice in the same function call. */
  62. static char *octbin(s)
  63. char *s;
  64. {
  65. static char b[256];
  66. char t[2];
  67. b[0] = t[1] = '\0';
  68. while (*s) {
  69. *t = *s;
  70. strcat(b, oct2bin[strtol(t, (char **)NULL, 8)]);
  71. s++;
  72. }
  73. return b;
  74. }
  75. static char *hexbin(s)
  76. char *s;
  77. {
  78. static char b[256];
  79. char t[2];
  80. b[0] = t[1] = '\0';
  81. while (*s) {
  82. *t = *s;
  83. strcat(b, hex2bin[strtol(t, (char **)NULL, 16)]);
  84. s++;
  85. }
  86. return b;
  87. }
  88. static char *binvert(s)
  89. char *s;
  90. {
  91. static char b[256];
  92. int l = strlen(s) - 1, i = 0;
  93. while (l >= 0)
  94. b[i++] = s[l--];
  95. b[i] = '\0';
  96. return b;
  97. }
  98. static dptr *adddptr(h, s, v)
  99. dptr *h;
  100. char *s, *v;
  101. {
  102. dptr *p;
  103. p = (dptr *)mbkalloc(sizeof(dptr));
  104. p->string = (char *)mbkalloc(strlen(s) + 1);
  105. (void)strcpy(p->string, s);
  106. p->value = (char *)mbkalloc(strlen(v) + 1);
  107. (void)strcpy(p->value, v);
  108. p->NEXT = h;
  109. return p;
  110. }
  111. static char *getdptr(h, s)
  112. dptr *h;
  113. char *s;
  114. {
  115. while (h != NULL) {
  116. if (!strcmp(h->string, s))
  117. return h->value;
  118. h = h->NEXT;
  119. }
  120. return NULL;
  121. }
  122. %}
  123. %union {
  124. int integer;
  125. char string[256];
  126. }
  127. %token CONSTANT OTHERS WHEN SELECT WITH
  128. %token <string> STRING BSTRING OSTRING XSTRING
  129. %type <string> value dvalues avalues
  130. /* needed only to avoid bison `type clash', as I do not care about it */
  131. %type <string> line constant
  132. %%
  133. line : constant
  134. | STRING /* forget it */
  135. | WITH STRING '(' STRING STRING STRING ')' SELECT
  136. {
  137. if (atoi($4) != 0 && atoi($6) != 0)
  138. yyerror("illegal vector boundaries for GRoG");
  139. /* address order choice :
  140. depends upon the bit ordering convention, and what is read
  141. from the file. */
  142. if ((!ibmbull && !strcmp($5, "TO"))
  143. || (ibmbull && !strcmp($5, "DOWNTO")))
  144. aorder = -1;
  145. else
  146. aorder = 1;
  147. }
  148. | STRING '(' STRING STRING STRING ')' '<' '=' dvalues WHEN avalues ','
  149. {
  150. int i;
  151. #ifdef PARSEOUT
  152. fprintf(stdout, "\n%s when %s\n", datbuf, adrbuf);
  153. #endif
  154. if (atoi($3) != 0 && atoi($5) != 0)
  155. yyerror("illegal vector boundaries for GRoG");
  156. /* output ordering :
  157. internally, the data is seen in the ibmbull convention, since
  158. the generator was designed with this convention I hate
  159. demanded. */
  160. if ((rf && !strcmp($4, "TO")) || (!rf && !strcmp($4, "DOWNTO")))
  161. forder = -1;
  162. else
  163. forder = 1;
  164. notempty = 1;
  165. if (strlen(datbuf) > nbits)
  166. yyerror("data too wide for the number of bits");
  167. if (strlen(adrbuf) > nwords)
  168. yyerror("address too high for the number of words");
  169. if (aorder == -1)
  170. strcpy(adrbuf, binvert(adrbuf));
  171. if (forder == -1)
  172. strcpy(datbuf, binvert(datbuf));
  173. if (nbits < 32) {
  174. i = strtol(adrbuf, 0, 2);
  175. ydata[(i << 1) ] = strtol(datbuf, 0, 2);
  176. ydata[(i << 1) + 1] = 0;
  177. } else {
  178. i = strtol(adrbuf, 0, 2);
  179. ydata[(i << 1) ] = strtol(&datbuf[nbits - 32], 0, 2);
  180. datbuf[nbits - 32] = '\0';
  181. ydata[(i << 1) + 1] = strtol(datbuf, 0, 2);
  182. }
  183. if (!used[i])
  184. used[i] = 1;
  185. else
  186. yyerror("same address used twice");
  187. }
  188. | dvalues WHEN avalues ','
  189. {
  190. int i;
  191. #ifdef PARSEOUT
  192. fprintf(stdout, "\n%s when %s\n", datbuf, adrbuf);
  193. #endif
  194. if (strlen(datbuf) > nbits)
  195. yyerror("data too wide for the number of bits");
  196. if (strlen(adrbuf) > nwords)
  197. yyerror("address too high for the number of words");
  198. if (aorder == -1)
  199. strcpy(adrbuf, binvert(adrbuf));
  200. if (forder == -1)
  201. strcpy(datbuf, binvert(datbuf));
  202. if (nbits < 32) {
  203. i = strtol(adrbuf, 0, 2);
  204. ydata[(i << 1) ] = strtol(datbuf, 0, 2);
  205. ydata[(i << 1) + 1] = 0;
  206. } else {
  207. i = strtol(adrbuf, 0, 2);
  208. ydata[(i << 1) ] = strtol(&datbuf[nbits - 32], 0, 2);
  209. datbuf[nbits - 32] = '\0';
  210. ydata[(i << 1) + 1] = strtol(datbuf, 0, 2);
  211. }
  212. if (!used[i])
  213. used[i] = 1;
  214. else
  215. yyerror("same address used twice");
  216. }
  217. | dvalues WHEN avalues ';'
  218. {
  219. int i;
  220. #ifdef PARSEOUT
  221. fprintf(stdout, "\n%s when %s\n", datbuf, adrbuf);
  222. #endif
  223. if (strlen(datbuf) > nbits)
  224. yyerror("data too wide for the number of bits");
  225. if (strlen(adrbuf) > nwords)
  226. yyerror("address too high for the number of words");
  227. if (aorder == -1)
  228. strcpy(adrbuf, binvert(adrbuf));
  229. if (forder == -1)
  230. strcpy(datbuf, binvert(datbuf));
  231. if (nbits < 32) {
  232. i = strtol(adrbuf, 0, 2);
  233. ydata[(i << 1) ] = strtol(datbuf, 0, 2);
  234. ydata[(i << 1) + 1] = 0;
  235. } else {
  236. i = strtol(adrbuf, 0, 2);
  237. ydata[(i << 1) ] = strtol(&datbuf[nbits - 32], 0, 2);
  238. datbuf[nbits - 32] = '\0';
  239. ydata[(i << 1) + 1] = strtol(datbuf, 0, 2);
  240. }
  241. if (!used[i])
  242. used[i] = 1;
  243. else
  244. yyerror("same address used twice");
  245. }
  246. | dvalues WHEN OTHERS ';'
  247. {
  248. int i;
  249. long j[2];
  250. #ifdef PARSEOUT
  251. fprintf(stdout, "\n%s when others\n", datbuf);
  252. #endif
  253. if (strlen(datbuf) > nbits)
  254. yyerror("data too wide for the number of bits");
  255. if (strlen(adrbuf) > nwords)
  256. yyerror("address too high for the number of words");
  257. if (forder == -1)
  258. strcpy(datbuf, binvert(datbuf));
  259. if (nbits < 32) {
  260. j[0] = strtol(datbuf, 0, 2);
  261. j[1] = 0;
  262. } else {
  263. j[0] = strtol(&datbuf[nbits - 32], 0, 2);
  264. datbuf[nbits - 32] = '\0';
  265. j[1] = strtol(datbuf, 0, 2);
  266. }
  267. for (i = 0; i < nwords; i++)
  268. if (!used[i])
  269. ydata[(i << 1) ] = j[0],
  270. ydata[(i << 1) + 1] = j[1];
  271. }
  272. | {strcpy($$, "Just to have bison shut up");}
  273. ;
  274. constant : CONSTANT STRING '=' value ';'
  275. {
  276. asc = adddptr(asc, $2, $4);
  277. }
  278. ;
  279. value : BSTRING {strcpy($$, $1);}
  280. | OSTRING {strcpy($$, octbin($1));}
  281. | XSTRING {strcpy($$, hexbin($1));}
  282. ;
  283. dvalues : value {strcat(datbuf, $1);}
  284. | value {strcat(datbuf, $1);} '&' dvalues
  285. | STRING
  286. {
  287. char *p = getdptr(asc, $1);
  288. if (p == NULL) {
  289. sprintf(datbuf, "unknown constant %s", $1);
  290. yyerror(datbuf);
  291. }
  292. strcat(datbuf, p);
  293. }
  294. | STRING {
  295. char *p = getdptr(asc, $1);
  296. if (p == NULL) {
  297. sprintf(datbuf, "unknown constant %s", $1);
  298. yyerror(datbuf);
  299. }
  300. strcat(datbuf, p);
  301. } '&' dvalues
  302. ;
  303. avalues : value {strcat(adrbuf, $1);}
  304. | value {strcat(adrbuf, $1);} '&' avalues
  305. | STRING
  306. {
  307. char *p = getdptr(asc, $1);
  308. if (p == NULL) {
  309. sprintf(adrbuf, "unknown constant %s", $1);
  310. yyerror(adrbuf);
  311. }
  312. strcat(adrbuf, p);
  313. }
  314. | STRING {
  315. char *p = getdptr(asc, $1);
  316. if (p == NULL) {
  317. sprintf(adrbuf, "unknown constant %s", $1);
  318. yyerror(adrbuf);
  319. }
  320. strcat(adrbuf, p);
  321. } '&' avalues
  322. ;
  323. %%
  324. void dpgen_ROM_code(s, nb, nw, r, msb, data)
  325. char *s;
  326. long nb, nw, r, msb;
  327. long *data;
  328. {
  329. FILE *f;
  330. if ((f = mbkfopen(s, "vbe", "r")) == NULL) {
  331. fprintf(stderr, "DPGEN_ROM error : cannot open file %s.vbe\n", s);
  332. EXIT(1);
  333. }
  334. readvhdlfile(f, s, nb, nw, r, msb, data);
  335. if (!notempty) {
  336. (void)fflush(stdout);
  337. (void)fprintf(stdout, "DPGEN_ROM : the file was empty of usable data\n");
  338. (void)fprintf(stdout, " the generated ROM will contain zeros\n");
  339. }
  340. fclose(f);
  341. }
  342. static FILE *vhdlfile;
  343. static void nextvhdlline(f, str)
  344. FILE *f;
  345. char *str;
  346. {
  347. char *s, *t;
  348. int space;
  349. if (fgets(str, 512, f) == (char *)NULL)
  350. return;
  351. s = t = str;
  352. space = isspace(*t) ? 0 : 1;
  353. while (*t)
  354. if (!isspace(*t) || space) {
  355. space = isspace(*t) || *t == ':' ? 0 : 1;
  356. if (islower(*t))
  357. *t = toupper(*t);
  358. *s++ = *t++;
  359. } else {
  360. t++;
  361. space = 0;
  362. }
  363. *s = '\0';
  364. }
  365. static char *nextline()
  366. {
  367. static char str[256];
  368. nextvhdlline(vhdlfile, str);
  369. return str;
  370. }
  371. static void readvhdlfile(f, s, nb, nw, r, msb, data)
  372. FILE *f;
  373. char *s;
  374. long nb, nw, r, msb;
  375. long *data;
  376. {
  377. char str[256];
  378. char *t;
  379. int space, i;
  380. /* globalize variables for yacc */
  381. nwords = nw;
  382. nbits = nb;
  383. rf = r;
  384. ibmbull = msb;
  385. ydata = data;
  386. vhdlfile = f;
  387. /* initialize stuff for OTHERS */
  388. for (i = 0; i < 8912; i++)
  389. used[i] = 0;
  390. while (!feof(f)) {
  391. line++;
  392. nextvhdlline(f, str);
  393. vhdl_line = str;
  394. datbuf[0] = adrbuf[0] = '\0';
  395. yyparse();
  396. }
  397. }
  398. /* lexical analyser */
  399. static int yylex()
  400. {
  401. static int c;
  402. int i = 0;
  403. char *s = vhdl_line; /* remember where to start from */
  404. while (*s && isspace(*s))
  405. s++;
  406. switch (*s) {
  407. case '\0':
  408. #ifdef PARSEOUT
  409. printf("\n");
  410. #endif
  411. return -1; /* expected by yacc as end of entries */
  412. case ';':
  413. c = '\0'; /* reset to nul state */
  414. case '<':
  415. case '=':
  416. case ',':
  417. case '&':
  418. case '(':
  419. case ')':
  420. #ifdef PARSEOUT
  421. printf("(%c)", *s);
  422. #endif
  423. if (*s == '<' && c == SELECT)
  424. c = WITH;
  425. vhdl_line = s;
  426. return *vhdl_line++;
  427. case ':':
  428. s++;
  429. while (*s && *s != '=')
  430. s++;
  431. #ifdef PARSEOUT
  432. printf("(%c)", *s);
  433. #endif
  434. vhdl_line = ++s;
  435. return '=';
  436. case '-':
  437. if (*++s == '-') {
  438. #ifdef PARSEOUT
  439. printf("COMMENT\n");
  440. #endif
  441. return -1;
  442. }
  443. return *vhdl_line++;
  444. case 'C':
  445. while (*s && (isalnum(*s) || *s == '_'))
  446. yylval.string[i++] = *s++;
  447. yylval.string[i] = '\0';
  448. vhdl_line = s;
  449. if (!strcmp(yylval.string, "CONSTANT")) {
  450. #ifdef PARSEOUT
  451. printf("TOKEN[%s]", yylval.string);
  452. #endif
  453. return c = CONSTANT;
  454. }
  455. #ifdef PARSEOUT
  456. printf("STRING{%s}", yylval.string);
  457. #endif
  458. if (c != SELECT && c != WITH && c != CONSTANT)
  459. *vhdl_line = '\0';
  460. return STRING;
  461. case 'G':
  462. while (*s && (isalnum(*s) || *s == '_'))
  463. yylval.string[i++] = *s++;
  464. yylval.string[i] = '\0';
  465. vhdl_line = s;
  466. if (!strcmp(yylval.string, "GENERIC")) {
  467. while (1) {
  468. if (!*s)
  469. s = nextline();
  470. if (*s++ == '(') {
  471. s--;
  472. i = 0;
  473. break;
  474. }
  475. }
  476. while (1) {
  477. if (!*s)
  478. s = nextline();
  479. switch (*s++) {
  480. case '(':
  481. i++;
  482. break;
  483. case ')':
  484. i--;
  485. break;
  486. case '\n':
  487. line++;
  488. }
  489. if (i == 0)
  490. break;
  491. }
  492. *vhdl_line = '\0';
  493. return STRING;
  494. }
  495. #ifdef PARSEOUT
  496. printf("STRING{%s}", yylval.string);
  497. #endif
  498. if (c != SELECT && c != WITH && c != CONSTANT)
  499. *vhdl_line = '\0';
  500. return STRING;
  501. case 'W':
  502. while (*s && (isalnum(*s) || *s == '_'))
  503. yylval.string[i++] = *s++;
  504. yylval.string[i] = '\0';
  505. vhdl_line = s;
  506. if (!strcmp(yylval.string, "WHEN")) {
  507. #ifdef PARSEOUT
  508. printf("TOKEN[%s]", yylval.string);
  509. #endif
  510. return WHEN;
  511. } else if (!strcmp(yylval.string, "WITH")) {
  512. #ifdef PARSEOUT
  513. printf("TOKEN[%s]", yylval.string);
  514. #endif
  515. c = SELECT;
  516. return WITH;
  517. } else {
  518. #ifdef PARSEOUT
  519. printf("STRING{%s}", yylval.string);
  520. #endif
  521. if (c != SELECT && c != WITH && c != CONSTANT)
  522. *vhdl_line = '\0';
  523. return STRING;
  524. }
  525. case 'S':
  526. while (*s && (isalnum(*s) || *s == '_'))
  527. yylval.string[i++] = *s++;
  528. yylval.string[i] = '\0';
  529. vhdl_line = s;
  530. if (!strcmp(yylval.string, "SELECT")) {
  531. #ifdef PARSEOUT
  532. printf("TOKEN[%s]", yylval.string);
  533. #endif
  534. *vhdl_line = '\0';
  535. return SELECT;
  536. } else {
  537. #ifdef PARSEOUT
  538. printf("STRING{%s}", yylval.string);
  539. #endif
  540. if (c != SELECT && c != WITH && c != CONSTANT)
  541. *vhdl_line = '\0';
  542. return STRING;
  543. }
  544. case 'B':
  545. if (c != SELECT && c != WITH && c != CONSTANT) {
  546. *vhdl_line = '\0';
  547. return STRING;
  548. }
  549. if (*(s + 1) == '"') {
  550. s += 2;
  551. while (*s && *s != '"')
  552. if (*s != '0' && *s != '1')
  553. yyerror("bad binary number");
  554. else
  555. yylval.string[i++] = *s++;
  556. yylval.string[i] = '\0';
  557. vhdl_line = ++s;
  558. #ifdef PARSEOUT
  559. printf("BSTRING{%s}", yylval.string);
  560. #endif
  561. return BSTRING;
  562. }
  563. while (*s && (isalnum(*s) || *s == '_'))
  564. yylval.string[i++] = *s++;
  565. yylval.string[i] = '\0';
  566. vhdl_line = s;
  567. #ifdef PARSEOUT
  568. printf("STRING{%s}", yylval.string);
  569. #endif
  570. return STRING;
  571. case 'O':
  572. if (c != SELECT && c != WITH && c != CONSTANT) {
  573. *vhdl_line = '\0';
  574. return STRING;
  575. }
  576. if (*(s + 1) == '"') {
  577. s += 2;
  578. while (*s && *s != '"')
  579. if (!isdigit(*s) && *s != '8' && *s != '9')
  580. yyerror("bad octal number");
  581. else
  582. yylval.string[i++] = *s++;
  583. yylval.string[i] = '\0';
  584. vhdl_line = ++s;
  585. #ifdef PARSEOUT
  586. printf("OSTRING{%s}", yylval.string);
  587. #endif
  588. return OSTRING;
  589. }
  590. while (*s && (isalnum(*s) || *s == '_'))
  591. yylval.string[i++] = *s++;
  592. yylval.string[i] = '\0';
  593. vhdl_line = s;
  594. if (!strcmp(yylval.string, "OTHERS")) {
  595. #ifdef PARSEOUT
  596. printf("TOKEN[%s]", yylval.string);
  597. #endif
  598. return OTHERS;
  599. }
  600. #ifdef PARSEOUT
  601. printf("STRING{%s}", yylval.string);
  602. #endif
  603. return STRING;
  604. case 'X':
  605. if (c != SELECT && c != WITH && c != CONSTANT) {
  606. *vhdl_line = '\0';
  607. return STRING;
  608. }
  609. if (*(s + 1) == '"') {
  610. s += 2;
  611. while (*s && *s != '"')
  612. if (!isxdigit(*s))
  613. yyerror("bad hexadecimal number");
  614. else
  615. yylval.string[i++] = *s++;
  616. yylval.string[i] = '\0';
  617. vhdl_line = ++s;
  618. #ifdef PARSEOUT
  619. printf("XSTRING{%s}", yylval.string);
  620. #endif
  621. return XSTRING;
  622. }
  623. while (*s && (isalnum(*s) || *s == '_'))
  624. yylval.string[i++] = *s++;
  625. yylval.string[i] = '\0';
  626. vhdl_line = s;
  627. #ifdef PARSEOUT
  628. printf("STRING{%s}", yylval.string);
  629. #endif
  630. return STRING;
  631. default:
  632. if (c == SELECT)
  633. while (*s && !isspace(*s) && *s != '(' && *s != ')')
  634. yylval.string[i++] = *s++;
  635. else
  636. while (*s && !isspace(*s))
  637. yylval.string[i++] = *s++;
  638. yylval.string[i] = '\0';
  639. vhdl_line = s;
  640. if (c != SELECT && c != WITH && c != CONSTANT)
  641. *vhdl_line = '\0';
  642. #ifdef PARSEOUT
  643. printf("STRING{%s}", yylval.string);
  644. #endif
  645. return STRING;
  646. }
  647. }
  648. static int yyerror(s)
  649. char *s;
  650. {
  651. fflush(stdout);
  652. fprintf(stderr, "DPGEN_ROM : %s on line %d (%s), '%c'\n",
  653. s, line, vhdl_line, yychar);
  654. exit(1);
  655. }