📄 e_blif.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_blif.c * BLIF output routines * * This module includes routines to take an EDIF graph and spit out the * corresponding BLIF. If opt.func is not set, the functions will default * to AND * * P. Leventis, May 98 */#include <stdio.h>#include <string.h>#include <assert.h>#include <stdlib.h>#include "e_graph.h"#include "e_shared.h"#define info (!opt.blif_info) ? 1 : printf #define verbose (!opt.blif_verbose) ? 1 : printf#define warn (!opt.blif_warn) ? 1 : printf#define error printf/* EXPORTS */int blif_write(char *filename, CELL *pCell);/* INTERNALS */static int _output(FILE *fp, CELL *pCell);static int _output_guts(FILE *fp, CELL *pCell, char *prefix);/* -------------------------------------------------------------------------*//* ----------------------- Exported Routines -------------------------------*//* -------------------------------------------------------------------------*//* * */intblif_write(char *filename, CELL *pCell){ FILE *fp; fp = fopen(filename, "wt"); if (!fp) { error("Error opening %s for blif output.\n", filename); return -1; } info("\n** Beginning BLIF output to '%s' **\n", filename); if(_output(fp, pCell)) { fclose(fp); return -1; } fclose(fp); return 0;}static void_print_TT(FILE *fp, char *TT, int nIn){#if 1 int i; for(i=0; i<1<<nIn; i++) { int j; if((TT[i/8]>>(i%8))%2) { for(j=0; j<nIn; j++) fprintf(fp, "%c", '0' + (i>>(nIn-j-1))%2); fprintf(fp, " 1\n"); } }#else int i; int *dontcare; dontcare = (int *) malloc(nIn * sizeof(int)); assert(dontcare); memset(dontcare, 0, sizeof(int) * nIn); for(i=0; i<nIn; i++) { for#endif}static int _output(FILE *fp, CELL *pCell){ int i; INSTANCE *pInst; NET *pNet; assert(pCell && pCell->pViewLL); /* Start the cell */ fprintf(fp, ".model %s\n", pCell->name); /* Inputs */ fprintf(fp, ".inputs"); for(i=pCell->pViewLL->nOutPorts; i<pCell->pViewLL->nPorts; i++) if(!pCell->pViewLL->ports[i].ignore) fprintf(fp, " %s", pCell->pViewLL->ports[i].name); /* Outputs */ fprintf(fp, "\n.outputs"); for(i=0; i<pCell->pViewLL->nOutPorts; i++) fprintf(fp, " %s", pCell->pViewLL->ports[i].name); fprintf(fp, "\n"); if(_output_guts(fp, pCell, "")) return -1; fprintf(fp, ".end\n"); return 0;} static int_output_guts(FILE *fp, CELL *pCell, char *prefix){ int i; INSTANCE *pInst; NET *pNet; my_assert(fp && pCell && prefix); if(strlen(prefix) > 64) { warn("Prefix is getting very long. Try flattening the EDIF file if you run into problems.\n"); } for(pInst=pCell->pViewLL->pFirstInstance; pInst; pInst = pInst->pNextInstance) { assert(pInst->pCellRef && pInst->pCellRef->pViewLL); if(pInst->pCellRef->pViewLL->pFirstInstance || pInst->pCellRef->pViewLL->pFirstNet) { char buffer[1024]; /* It's a hierarchical EDIF file * Steps: * 1. Make input stubs to connect "real" input driver to "new" pin * 2. Recurse with _output_guts */ for(i=pInst->pCellRef->pViewLL->nOutPorts; i<pInst->pCellRef->pViewLL->nPorts; i++) { fprintf(fp, ".names "); if(pInst->pCellRef->pViewLL->ports[i].ignore) continue; if(pInst->ports[i]->ports[0].pInstance) { fprintf(fp, "%s%s", prefix, pInst->ports[i]->ports[0].pInstance->name); if(pInst->ports[i]->ports[0].pInstance->pCellRef->pViewLL->pFirstNet) fprintf(fp, "_%s", pInst->ports[i]->ports[0].pInstance->pCellRef->pViewLL->ports[pInst->ports[i]->ports[0].portNum].name); } else fprintf(fp, "%s%s", prefix, pCell->pViewLL->ports[pInst->ports[i]->ports[0].portNum].name); fprintf(fp, " %s%s_%s\n1 1\n", prefix, pInst->name, pInst->pCellRef->pViewLL->ports[i].name); } sprintf(buffer, "%s%s_", prefix, pInst->name); if(_output_guts(fp, pInst->pCellRef, buffer)) return -1; } else if(pInst->pCellRef->pViewLL->tag == logic) { fprintf(fp, ".names"); assert(pInst->pCellRef->pViewLL->nOutPorts==1); for(i=pInst->pCellRef->pViewLL->nOutPorts; i<pInst->pCellRef->pViewLL->nPorts; i++) { if(pInst->pCellRef->pViewLL->ports[i].ignore) continue; pNet = pInst->ports[i]; assert(pNet); if(pNet->ports[0].pInstance) { fprintf(fp, " %s%s", prefix, pNet->ports[0].pInstance->name); if(pNet->ports[0].pInstance->pCellRef->pViewLL->pFirstNet) fprintf(fp, "_%s", pNet->ports[0].pInstance->pCellRef->pViewLL->ports[pNet->ports[0].portNum].name); } else { fprintf(fp, " %s%s", prefix, pCell->pViewLL->ports[pNet->ports[0].portNum].name); } } fprintf(fp, " %s%s\n", prefix, pInst->name); /* Print the Truth Table (if it exists) */ if(!opt.func) { for(i=0; i<pInst->pCellRef->pViewLL->nIn; i++) fprintf(fp, "1"); fprintf(fp, " 1\n"); } else if(pInst->pCellRef->pViewLL->TT) { _print_TT(fp, pInst->pCellRef->pViewLL->TT, pInst->pCellRef->pViewLL->nIn); } } else { int i, input_pin=-1; fprintf(fp, ".latch"); /* Print the input pin */ for(i=pInst->pCellRef->pViewLL->nOutPorts; i<pInst->pCellRef->pViewLL->nPorts; i++) { if(pInst->pCellRef->pViewLL->ports[i].ignore) continue; if(pInst->ports[i]->ports[0].pInstance) { fprintf(fp, " %s%s", prefix, pInst->ports[i]->ports[0].pInstance->name); if(pInst->ports[i]->ports[0].pInstance->pCellRef->pViewLL->pFirstNet) fprintf(fp, "_%s", pInst->ports[i]->ports[0].pInstance->pCellRef->pViewLL->ports[pInst->ports[i]->ports[0].portNum].name); } else { fprintf(fp, " %s%s", prefix, pCell->pViewLL->ports[pInst->ports[i]->ports[0].portNum].name); } input_pin = i; break; } if(input_pin==-1) { error("Error: No non-ignored input pin on instance '%s' of cell '%s'.\n", pInst->name, pInst->pCellRef->name); return -1; } /* Print the output name */ fprintf(fp, " %s%s", prefix, pInst->name); /* Print the clock */ for(i=pInst->pCellRef->pViewLL->nPorts-1; i>input_pin; i--) { if(pInst->pCellRef->pViewLL->ports[i].ignore) continue; if(pInst->ports[i]->ports[0].pInstance) { fprintf(fp, " re %s%s", prefix, pInst->ports[i]->ports[0].pInstance->name); if(pInst->ports[i]->ports[0].pInstance->pCellRef->pViewLL->pFirstNet) fprintf(fp, "_%s", pInst->ports[i]->ports[0].pInstance->pCellRef->pViewLL->ports[pInst->ports[i]->ports[0].portNum].name); fprintf(fp, " 2\n"); } else { fprintf(fp, " re %s%s 2\n", prefix, pCell->pViewLL->ports[pInst->ports[i]->ports[0].portNum].name); } break; } } } /* Figure out the output stubs */ for(pNet = pCell->pViewLL->pFirstNet; pNet; pNet = pNet->pNextNet) { for(i=1; i<pNet->nPorts; i++) { if(!pNet->ports[i].pInstance) { if(pNet->ports[0].pInstance) { fprintf(fp, ".names %s%s", prefix, pNet->ports[0].pInstance->name); if(pNet->ports[0].pInstance->pCellRef->pViewLL->pFirstNet) fprintf(fp, "_%s", pNet->ports[0].pInstance->pCellRef->pViewLL->ports[pNet->ports[0].portNum].name); } else { fprintf(fp, ".names %s%s", prefix, pCell->pViewLL->ports[pNet->ports[0].portNum].name); } fprintf(fp, " %s%s\n1 1\n", prefix, pCell->pViewLL->ports[pNet->ports[i].portNum].name); } } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -