📄 read_netlist.c
字号:
#include <stdio.h>#include <string.h>#include <assert.h>#include "util.h"#include "hash.h"#include "vpr_types.h"#include "vpr_utils.h"#include "ReadLine.h"#include "globals.h"static char *pinlist_str = "pinlist:";enum special_blk{ NORMAL = 0, INPAD, OUTPAD };static t_type_ptr get_type_by_name(IN const char *name, IN int num_types, IN const struct s_type_descriptor block_types[], IN t_type_ptr IO_type, IN const char *net_file, IN int line, OUT enum special_blk *overide);/* Initializes the block_list with info from a netlist */voidread_netlist(IN const char *net_file, IN int num_types, IN const struct s_type_descriptor block_types[], IN t_type_ptr IO_type, IN int io_ipin, IN int io_opin, OUT t_subblock_data * subblock_data_ptr, OUT int *num_blocks, OUT struct s_block *block_list[], OUT int *num_nets, OUT struct s_net *net_list[]){ FILE *infile; int bcount; struct s_block *blist; int ncount; struct s_net *nlist; int i, j, k, l, m; enum { COUNT, LOAD, MAP, STOP } pass; int line, prev_line; enum special_blk overide; char **block_tokens; char **pin_tokens; char **tokens; t_subblock **slist = NULL; int *scount = NULL; t_type_ptr type = NULL; infile = my_fopen(net_file, "r"); bcount = 0; blist = NULL; ncount = 0; nlist = NULL; memset(subblock_data_ptr, 0, sizeof(t_subblock_data)); /* Multi-pass load * COUNT * -> count blocks * -> count nets * * LOAD * -> alloc num_subblocks_per_block list * -> allocate s_block list at start * -> allocate s_net list at start * -> count subblocks per block * -> sets block names * -> sets block types * -> allocs block net lists * -> sets net names * * MAP * -> fills in s_block:nets list * -> fills in subblocks */ for(pass = 0; pass < STOP; ++pass) { rewind(infile); line = 0; i = 0; j = 0; overide = NORMAL; /* Alloc the lists */ if(LOAD == pass) { blist = (struct s_block *)my_malloc(sizeof(struct s_block) * bcount); memset(blist, 0, (sizeof(struct s_block) * bcount)); nlist = (struct s_net *)my_malloc(sizeof(struct s_net) * ncount); memset(nlist, 0, (sizeof(struct s_net) * ncount)); slist = (t_subblock **) my_malloc(sizeof(t_subblock *) * bcount); memset(slist, 0, (sizeof(t_subblock *) * bcount)); scount = (int *)my_malloc(sizeof(int) * bcount); memset(scount, 0, (sizeof(int) * bcount)); } /* Read file line by line */ block_tokens = ReadLineTokens(infile, &line); prev_line = line; while(block_tokens) { /* .global directives have special meaning */ if(0 == strcmp(block_tokens[0], ".global")) { if(MAP == pass) { for(l = 0; l < ncount; ++l) { if(0 == strcmp(nlist[l].name, block_tokens[1])) { nlist[l].is_global = TRUE; break; } } if(l == ncount) { printf(ERRTAG "'%s':%d - '.global' specified an invalid net\n", net_file, prev_line); exit(1); } } /* Don't do any more processing on this */ FreeTokens(&block_tokens); block_tokens = ReadLineTokens(infile, &line); prev_line = line; continue; } pin_tokens = ReadLineTokens(infile, &line); if(CountTokens(block_tokens) != 2) { printf(ERRTAG "'%s':%d - block type line should " "be in form '.type_name block_name'\n", net_file, prev_line); exit(1); } if(NULL == pin_tokens) { printf(ERRTAG "'%s':%d - blocks must be follow by a 'pinlist:' line\n", net_file, line); exit(1); } if(0 != strcmp("pinlist:", pin_tokens[0])) { printf(ERRTAG "'%s':%d - 'pinlist:' line must follow " "block type line\n", net_file, line); exit(1); } type = get_type_by_name(block_tokens[0], num_types, block_types, IO_type, net_file, prev_line, &overide); /* Check if we are overiding the pinlist format for this block */ if(overide) { if(CountTokens(pin_tokens) != 2) { /* 'pinlist:' and name */ printf(ERRTAG "'%s':%d - pinlist for .input and .output should " "only have one item.\n", net_file, line); exit(1); } /* Make a new faked token list with 'pinlist:' and then pin mappings and a null */ tokens = (char **)my_malloc(sizeof(char *) * (type->num_pins + 2)); l = strlen(pinlist_str) + 1; k = strlen(pin_tokens[1]) + 1; tokens[0] = (char *)my_malloc(sizeof(char) * (k + l)); memcpy(tokens[0], pinlist_str, l * sizeof(char)); memcpy(tokens[0] + l, pin_tokens[1], k * sizeof(char)); /* Set all other pins to open */ for(k = 0; k < type->num_pins; ++k) { tokens[1 + k] = "open"; /* free wont be called on this so is safe */ } tokens[1 + k] = NULL; /* End of token list marker */ /* Set the one pin with the value given */ for(k = 0; k < type->num_pins; ++k) { switch (overide) { case INPAD: tokens[1 + io_opin] = (tokens[0] + l); break; case OUTPAD: tokens[1 + io_ipin] = (tokens[0] + l); break; } } FreeTokens(&pin_tokens); pin_tokens = tokens; tokens = NULL; } if(CountTokens(pin_tokens) != (type->num_pins + 1)) { printf(ERRTAG "'%s':%d - 'pinlist:' line has %d pins instead of " "expect %d pins.\n", net_file, line, CountTokens(pin_tokens) - 1, type->num_pins); exit(1); } /* Load block name and type and alloc net list */ if(LOAD == pass) { blist[i].name = my_strdup(block_tokens[1]); blist[i].type = type; blist[i].nets = (int *)my_malloc(sizeof(int) * type->num_pins); for(k = 0; k < type->num_pins; ++k) { blist[i].nets[k] = OPEN; } } /* Examine pin list to determine nets */ for(k = 0; k < type->num_pins; ++k) { if(0 != strcmp("open", pin_tokens[1 + k])) { if(DRIVER == type->class_inf[type->pin_class[k]]. type) { if(LOAD == pass) { nlist[j].name = my_strdup(pin_tokens [1 + k]); } if(MAP == pass) { blist[i].nets[k] = j; /* If we are net source we don't need to search */ } ++j; /* This was an active netlist */ } else { if(MAP == pass) { /* Map sinks by doing a linear search to find the net */ blist[i].nets[k] = OPEN; for(l = 0; l < ncount; ++l) { if(0 == strcmp(nlist [l]. name, pin_tokens [1 + k])) { blist[i]. nets [k] = l; break; } } if(OPEN == blist[i].nets[k]) { printf(ERRTAG "'%s':%d - Net '%s' not found\n", net_file, line, pin_tokens [1 + k]); exit(1); } } } } } /* Allocating subblocks */ if(MAP == pass) { /* All blocks internally have subblocks but I/O subblocks are allocated and loaded elsewhere */ if(scount[i] > 0) { slist[i] = (t_subblock *) my_malloc(sizeof(t_subblock) * scount[i]); for(k = 0; k < scount[i]; ++k) { slist[i][k].name = NULL; slist[i][k].clock = OPEN; slist[i][k].inputs = (int *)my_malloc(sizeof(int) * type-> max_subblock_inputs); for(l = 0; l < type->max_subblock_inputs; ++l) { slist[i][k].inputs[l] = OPEN; } slist[i][k].outputs = (int *)my_malloc(sizeof(int) * type-> max_subblock_outputs); for(l = 0; l < type->max_subblock_outputs; ++l) { slist[i][k].outputs[l] = OPEN; } } } } /* Ignore subblock data */ tokens = ReadLineTokens(infile, &line); prev_line = line; m = 0; while(tokens && (0 == strcmp(tokens[0], "subblock:"))) { if(CountTokens(tokens) != (type->max_subblock_inputs + type->max_subblock_outputs + 1 + /* clocks */ 2)) { /* 'subblock:', name */ printf("subblock wrong pin count, netlist has %d, architecture as %d on line %d \n" , CountTokens(tokens) - 2, (type->max_subblock_inputs + type->max_subblock_outputs + 1), line); exit(1); } /* Count subblocks given */ if(LOAD == pass) { scount[i]++; } /* Load subblock name */ if(MAP == pass) { assert(i < bcount); assert(m < scount[i]); slist[i][m].name = my_strdup(tokens[1]); for(k = 0; k < type->max_subblock_inputs; ++k) { /* Check prefix and load pin num */ l = 2 + k; if(0 == strncmp("ble_", tokens[l], 4)) { slist[i][m].inputs[k] = type->num_pins + my_atoi(tokens[l] + 4); /* Skip the 'ble_' part */ } else if(0 != strcmp("open", tokens[l])) { slist[i][m].inputs[k] = my_atoi(tokens[l]); } } for(k = 0; k < type->max_subblock_outputs; ++k) { l = 2 + type->max_subblock_inputs + k; if(0 != strcmp("open", tokens[l])) { slist[i][m].outputs[k] = my_atoi(tokens[l]); } } l = 2 + type->max_subblock_inputs + type->max_subblock_outputs; if(0 != strcmp("open", tokens[l])) { slist[i][m].clock = my_atoi(tokens[l]); } } ++m; /* Next subblock */ FreeTokens(&tokens); tokens = ReadLineTokens(infile, &line); prev_line = line; } if(pass > COUNT) { /* Check num of subblocks read */ if(scount[i] > type->max_subblocks) { printf("too many subblocks on block [%d] %s\n", i, blist[i].name); exit(1); } } ++i; /* End of this block */ FreeTokens(&block_tokens); FreeTokens(&pin_tokens); block_tokens = tokens; } /* Save counts */ if(COUNT == pass) { bcount = i; ncount = j; } } fclose(infile); /* Builds mappings from each netlist to the blocks contained */ sync_nets_to_blocks(bcount, blist, ncount, nlist); /* Send values back to caller */ *num_blocks = bcount; *block_list = blist; *num_nets = ncount; *net_list = nlist; subblock_data_ptr->subblock_inf = slist; subblock_data_ptr->num_subblocks_per_block = scount;}static t_type_ptrget_type_by_name(IN const char *name, IN int num_types, IN const struct s_type_descriptor block_types[], IN t_type_ptr IO_type, IN const char *net_file, IN int line, OUT enum special_blk *overide){ /* Just does a simple linear search for now */ int i; /* pin_overide is used to specify that the .input and .output * blocks only have one pin specified and should be treated * as if used as a .io with a full pin spec */ *overide = NORMAL; /* .input and .output are special names that map to the basic IO type */ if(0 == strcmp(".input", name)) { *overide = INPAD; return IO_type; } if(0 == strcmp(".output", name)) { *overide = OUTPAD; return IO_type; } /* Linear type search. Don't really expect to have too many * types for it to be a problem */ for(i = 0; i < num_types; ++i) { if(0 == strcmp(block_types[i].name, name)) { return (block_types + i); } } /* No type matched */ printf(ERRTAG "'%s':%d - Invalid block type '%s'\n", net_file, line, name); exit(1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -