⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 e_table.c

📁 对于研究FPGA结构的人来说
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------** 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 + -