📄 e_table.c
字号:
/*------------------------------------------------------------------------** Copyright 1998 by Paul Leventis, Jonathan Rose and the University of ** Toronto. Use is permitted, provided that this attribution is retained ** and no part of the code is re-distributed or included in any commercial ** product except by written agreement with the above parties. ** ** For more information, contact us directly: ** Paul Leventis (leventi@eecg.utoronto.ca) ** Jonathan Rose (jayar@eecg.toronto.edu) ** Department of Electrical and Computer Engineering ** University of Toronto, 10 King's College Rd., ** Toronto, Ontario, CANADA M5S 1A4 ** Phone: (416) 978-6992 Fax: (416) 971-2286 **------------------------------------------------------------------------*//* * e_table.c * * Translation Table Parsing Routines * * P. Leventis, May 1998*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "e_table.h"#include "e_shared.h"#define verbose (!opt.tab_verbose) ? 1 : printf#define warn (!opt.tab_warn) ? 1 : printf#define info (!opt.tab_info) ? 1 : printf#define error printf/* * Strips leading and trailing whitespace from supplied string and returns * a pointer to location in the string where this non-blank stuff starts. * Note: Affects passed string.*/static char* _strip_space(char *str){ char *p; while(*str && isspace(*str)) *str++; p = strdup(str); for(str = p; *str && !isspace(*str); str++); *str=0; return p;}/* * Sets all elements in TT that correspond to truth-table line buff. * n input truth table, currently at position i of n in the buff * Returns 0 on success, -1 otherwise*/static int _fill_TT(char *buff, int n, char *TT, int i, int byte){ int bit; my_assert(n<=32); for(; i<n; i++) { if(buff[i]=='1') { byte+=1<<(n-i-1); } else if(buff[i]=='0') { } else if(buff[i]=='-') { if(_fill_TT(buff, n, TT, i+1, byte)) return -1; return _fill_TT(buff, n, TT, i+1, byte+(1<<(n-i-1))); } else { return -1; } } TT[byte/8] |= 1<<(byte%8); return 0;}/* * Adds pCell to the pLib. * Note: if duplicate cell exists, it is overwritten. Literally.*/static int _add_cell(CELL *pCell, LIBRARY *pLib){ CELL *pTemp = hash_get(pLib->pCellHT, pCell->name); int i; if(pTemp) { warn("Warning: Cell %s is already defined. Overwriting.\n", pCell->name); free(pTemp->name); if(pTemp->pViewLL) { free(pTemp->pViewLL->name); for(i=0; i<pTemp->pViewLL->nPorts; i++) free(pTemp->pViewLL->ports[i].name); free(pTemp->pViewLL->ports); free(pTemp->pViewLL->TT); free(pTemp->pViewLL); } *pTemp = *pCell; } else if(!hash_add(pLib->pCellHT, pCell->name, pCell)) { error("Error adding cell '%s' to default library.\n", pCell->name); return -1; } return 0;}/* * Prints the data on a cell */static void _print_cell(CELL *pCell){ int i; int nIn; my_assert(pCell); nIn = pCell->pViewLL->nIn; verbose("CELL %s (nIn = %d, nOut = %d)\n", pCell->name, nIn, pCell->pViewLL->nOutPorts); if(pCell->pViewLL->ports && pCell->pViewLL->tag==logic) { verbose("\tInputs:"); for(i=pCell->pViewLL->nOutPorts; i<pCell->pViewLL->nPorts; i++) verbose(" %s%s", ((pCell->pViewLL->ports[i].ignore) ? "!" : "" ) , pCell->pViewLL->ports[i].name); verbose("\n\tOutputs:"); for(i=0; i<pCell->pViewLL->nOutPorts; i++) verbose(" %s%s", ((pCell->pViewLL->ports[i].ignore) ? "!" : "" ) , pCell->pViewLL->ports[i].name); verbose("\n"); verbose("\tTruth table: \n"); for(i=0; i<(1<<nIn); i++) { if(i%64==0) verbose("\t "); if(pCell->pViewLL->TT[i/8] & (1<<(i%8))) verbose("1"); else verbose("0"); if((i+1)%64==0) verbose("\n"); } if(i%64) verbose("\n"); } else if(pCell->pViewLL->ports && pCell->pViewLL->tag==latch) { int i; verbose("\tLatch input: %s\n", pCell->pViewLL->ports[pCell->pViewLL->input_pin].name); verbose("\tLatch output: %s\n", pCell->pViewLL->ports[pCell->pViewLL->output_pin].name); verbose("\tLatch clock: %s\n", ((pCell->pViewLL->clock_pin==-1)?"None":pCell->pViewLL->ports[pCell->pViewLL->clock_pin].name)); verbose("\tIgnored inputs:"); for(i=pCell->pViewLL->nOutPorts; i<pCell->pViewLL->nPorts; i++) if(i!=pCell->pViewLL->input_pin && i!=pCell->pViewLL->clock_pin) verbose(" %s", pCell->pViewLL->ports[i].name); verbose("\n\tIgnored outputs:"); for(i=0; i<pCell->pViewLL->nOutPorts; i++) if(i!=pCell->pViewLL->output_pin) verbose(" %s", pCell->pViewLL->ports[i].name); verbose("\n"); } else { verbose("\tPort names undefined (alias)\n"); verbose("\tTruth table: \n"); for(i=0; i<(1<<nIn); i++) { if(i%64==0) verbose("\t "); if(pCell->pViewLL->TT[i/8] & (1<<(i%8))) verbose("1"); else verbose("0"); if((i+1)%64==0) verbose("\n"); } if(i%64) verbose("\n"); } }/* * Reads a cell skeleton in the form NAME(in1,in2,...,;out*/static int _read_cell(FILE *fp, CELL **targetCell){ char buffer[4100]; CELL *pCell; char *instr, *outstr, *p, *buff2; int nIn, nOut, charFlag; int i; fgets(buffer, 4096, fp); p = buffer; while(*p && *p!='(') p++; if(!*p) { error("Error: no '(' in define.\n"); return -1; } *p=0; buff2 = ++p; pCell = (CELL *) malloc(sizeof(CELL)); mem_assert(pCell); pCell->name = _strip_space(buffer); pCell->pViewLL = (NETLISTVIEW *) malloc(sizeof(NETLISTVIEW)); mem_assert(pCell->pViewLL); memset(pCell->pViewLL, 0, sizeof(NETLISTVIEW)); pCell->pViewLL->tag = logic; /* Count the number of inputs */ charFlag = 0; nIn = 0; while(*p) { if(*p==',') { if(charFlag) { nIn++; charFlag=0; } else { error("Error: unexpected comma for define '%s'\n", pCell->name); return -1; } } else if(*p==';') { nIn += charFlag; charFlag = 0; p++; break; } else if(*p==')') { error("Error: no outputs specified for define '%s'\n", pCell->name); return -1; } else if(!isspace(*p)) { charFlag = 1; } p++; } if(!*p) { error("Error: unexpected end-of-line processing define '%s'\n", pCell->name); return -1; } /* Count the number of outputs */ charFlag = 0; nOut = 0; while(*p) { if(*p==',') { if(charFlag) { nOut++; charFlag=0; } else { error("Error: unexpected comma processing define '%s'\n", pCell->name); return -1; } } else if(*p==';') { nOut += charFlag; charFlag = 0; break; } else if(*p==')') { nOut += charFlag; break; } else if(!isspace(*p)) { charFlag = 1; } p++; } if(!*p) { error("Error: no ')' in define '%s'\n", pCell->name); return -1; } pCell->pViewLL->ports = (PORT *) malloc((nIn + nOut) * sizeof(PORT)); mem_assert(pCell->pViewLL->ports); memset(pCell->pViewLL->ports, 0, (nIn + nOut) * sizeof(PORT)); /* Special case since strtok sucks */ if(buff2[0] == ';') { outstr = buff2+1; } else { instr = strtok(buff2, ";"); outstr = &buff2[strlen(instr)+1]; } /* Read output names */ if(!nOut) { error("Error: No output ports on define '%s'\n", pCell->name); return -1; } pCell->pViewLL->ports[0].name = _strip_space(strtok(outstr, ",)")); pCell->pViewLL->ports[0].direction = out; if(pCell->pViewLL->ports[0].name[0] == '!') { error("Error: Can't ignore outputs (yet) on port %s of cell %s\n", pCell->pViewLL->ports[0].name, pCell->name); return -1; } else { pCell->pViewLL->ports[0].ignore = 0; } pCell->pViewLL->ports[0].pNet = NULL; for(i=1; i<nOut; i++) { pCell->pViewLL->ports[i].name = _strip_space(strtok(NULL, ",)")); pCell->pViewLL->ports[i].direction = out; if(pCell->pViewLL->ports[i].name[0] == '!') { error("Error: Can't ignore outputs (yet) on port %s of cell %s\n", pCell->pViewLL->ports[i].name, pCell->name); return -1; } else { pCell->pViewLL->ports[i].ignore = 0; } pCell->pViewLL->ports[i].pNet = NULL; } /* Read input names */ pCell->pViewLL->nIn = 0; if(nIn) { pCell->pViewLL->ports[i].name = _strip_space(strtok(instr, ",")); pCell->pViewLL->ports[i].direction = in; if(pCell->pViewLL->ports[i].name[0]=='!') { strcpy(pCell->pViewLL->ports[i].name, pCell->pViewLL->ports[i].name+1); pCell->pViewLL->ports[i].ignore = 1; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -