📄 spec2vhdl.py
字号:
#!/usr/bin/python2.4# Copyright 2007 John Kasunich## This program is free software; you can redistribute it and/or modify# it under the terms of the GNU General Public License as published by# the Free Software Foundation; either version 2 of the License, or# (at your option) any later version.## This program is distributed in the hope that it will be useful,# but WITHOUT ANY WARRANTY; without even the implied warranty of# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the# GNU General Public License for more details.## You should have received a copy of the GNU General Public License# along with this program; if not, write to the Free Software# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USAimport sysimport osimport globimport ConfigParserimport stringimport reimport datetimeimport getopt# this is a hack until I find out how we're really supposed to do itsys.path.append("../../../../../lib/python")import bitfiledef section2dict(section, cfgfile) : if not cfgfile.has_section(section) : print "ERROR: section '"+section+"' not found" sys.exit(1) tmp = {} for option in cfgfile.options(section) : tmp[option] = cfgfile.get(section, option) return tmpclass KeyValueError (Exception): def __str__ (self): return "KeyValueError"class SymbolSpec : def __init__ (self, defstr) : #print "SymbolSpec.__init__("+defstr+")" definition = eval(defstr) try: types = definition["type"].split("_") self.vartype = types[0] if len(types) == 1: self.tweakable = 0 elif len(types) == 2: if types[1] == "preroute": self.tweakable = 0 elif types[1] == "postroute": self.tweakable = 1 else: raise KeyValueError, ("type", definition["type"]) else: raise KeyValueError, ("type", definition["type"]) if self.vartype == "constant": self.default = definition["value"] elif self.vartype == "pin": self.default = 0 self.description = definition["description"] elif self.vartype == "enum": self.default = definition["default"] self.choices = definition["options"] self.question = definition["question"] elif self.vartype == "bool": self.default = definition["default"] self.question = definition["question"] else: print "ERROR: symbol spec '"+defstr+"' has illegal type '"+var_type+"'" sys.exit(1) except KeyError, key: print "ERROR: symbol spec '"+defstr+"' is missing item '"+str(key)+"'" sys.exit(1) except KeyValueError, (key, value): print "ERROR: symbol spec '"+defstr+"' has bad value '"+value+"' for item '"+str(key)+"'" sys.exit(1) def to_list (self): rep = [ self.vartype, self.tweakable, self.default ] if self.vartype == "constant": return rep if self.vartype == "pin": rep.append(self.description) return rep if self.vartype == "enum": rep.append(self.choices) rep.append(self.question) return rep if self.vartype == "bool": rep.append(self.question) return rep def __repr__ (self): return repr(self.to_list())class ModuleSpec : def __init__ (self, name) : global lib global packages #print "ModuleSpec.__init__("+name+")" # save basic stuff self.name = name # extract symbol data from module spec library section = name+".symbols" if not lib.has_section(section): print "ERROR: module spec '"+name+"' has no 'symbols' section" sys.exit(1) self.symspecs = {} for key in lib.options(section): self.symspecs[key] = SymbolSpec(lib.get(section, key)) # check for required symbols required_symbols = [ 'num_regs', 'id_code', 'vhdl_package' ] for s in required_symbols : if not s in self.symspecs : print "ERROR: modspec '"+self.name+"' needs symbol '"+s+"'" sys.exit(1) # extract template data from module spec library section = name+".templates" if not lib.has_section(section): print "WARNING: module spec '"+name+"' has no 'templates' section" self.templates = {} required_templates = [ 'sigs', 'vhdl', 'ram' ] for key in required_templates: if lib.has_option(section, key): s = lib.get(section, key) # strip '!' hackery (used to preserve indenting), and # turn it into a Template object for later substitution self.templates[key] = string.Template(re.sub("(?m)^!","", s)) else: # load default template self.templates[key] = string.Template("") # do we already have the neccessary package? p = self.symspecs["vhdl_package"].default if not p in packages : packages.append(p) # turn strings into integers self.num_regs = int(self.symspecs["num_regs"].default) self.id_code = int(self.symspecs["id_code"].default) # compute power of two size of register block self.blk_size = 1 while self.blk_size < self.num_regs : self.blk_size <<= 1 def to_list (self) : rep = [ self.name, self.id_code, self.num_regs, self.blk_size, self.symspecs] templates = {} for key, template in self.templates.iteritems(): templates[key] = template.template rep.extend([templates]) return rep def __repr__ (self) : return repr(self.to_list()) def symbol_table (self) : rv = {} for name,value in self.symspecs.iteritems() : name = self.name+"__"+name rv[name] = value return rvclass ModuleInstance : def __init__ (self, name) : global src global modspecs #print "ModuleInstance.__init__("+name+")" # save some basic stuff self.name = name self.modname = name.split('.')[0] self.instance = name.split('.')[1] # do we already have a matching module spec? if not self.modname in modspecs : # no, add the module spec modspecs[self.modname] = ModuleSpec(self.modname) self.module = modspecs[self.modname] # get default and/or constant symbol values from module spec self.symbols = {} for key,symspec in self.module.symspecs.iteritems(): self.symbols[key] = symspec.default # get variable/value pairs from the spec file (replace defaults) for key in src.options(name) : if key in self.symbols.keys(): self.symbols[key] = src.get(name, key) else: print "WARNING: module '"+name+"' has unneeded variable '"+key+"'" # add a couple special values self.symbols["instnum"] = self.instance self.byteaddr = -1 def to_list (self) : rep = [ self.name, self.modname, self.instance, self.symbols] return rep def __repr__ (self) : return repr(self.to_list()) def get_name (self) : return self.name def get_num_regs (self) : return self.module.num_regs def get_id_code_and_instance (self) : return (self.module.id_code << 8 ) | int(self.instance) def get_blk_size (self) : return self.module.blk_size def assign_address (self, addr) : self.wordaddr = upper_limit self.byteaddr = upper_limit * 4 self.symbols['baseaddr'] = repr(self.byteaddr) mask = 0x3FFF & ~(self.module.blk_size-1) self.select = ChipSelect(self.wordaddr, mask) self.symbols['cs'] = self.select.name chip_selects.append(self.select) def vhdl (self) : try: vhdl = self.module.templates["vhdl"].substitute(self.symbols) except KeyError : print "ERROR: no value for '"+str(sys.exc_value)+"' in '"+self.name+"'" sys.exit(1) return vhdl def ram_template (self) : # use "__" to separate module, instance, and variable names prefix = "${"+self.modname+"__"+self.instance+"__" rv = self.module.templates["ram"].template rv = re.sub("\${",prefix, rv) return rv def symbol_table (self) : rv = {} for name,value in self.symbols.iteritems() : name = self.modname+"__"+self.instance+"__"+name rv[name] = value return rvdef binstr(value) : name = "" for n in reversed(range(14)) : if (value & (1<<n)) : name += '1' else : name += '0' return namedef count_ones(value) : ones = 0 for n in reversed(range(14)) : if (value & (1<<n)) : ones += 1 return onesdef trim_ones_lsb(value, bits) : for n in range(14) : if (value & (1<<n)) : value &= ~(1<<n) bits -= 1 if bits == 0 : break return valueclass ChipSelect : def __init__ (self, addr, mask) : #print "ChipSelect.__init__("+binstr(addr)+", "+binstr(mask)+")" self.addr = addr self.mask = mask self.name = "cs" for n in reversed(range(14)) : if (mask & (1<<n)) :
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -