diff options
Diffstat (limited to 'host/lib/ic_reg_maps/common.py')
-rw-r--r-- | host/lib/ic_reg_maps/common.py | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/host/lib/ic_reg_maps/common.py b/host/lib/ic_reg_maps/common.py new file mode 100644 index 000000000..4aa1ef35e --- /dev/null +++ b/host/lib/ic_reg_maps/common.py @@ -0,0 +1,118 @@ +# +# Copyright 2010 Ettus Research LLC +# +# 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 3 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, see <http://www.gnu.org/licenses/>. +# + +import re +import sys +import math +from Cheetah.Template import Template + +COMMON_TMPL = """\ +#import time +/*********************************************************************** + * This file was generated by $file on $time.strftime("%c") + **********************************************************************/ + +\#ifndef INCLUDED_$(name.upper())_HPP +\#define INCLUDED_$(name.upper())_HPP + +\#include <boost/cstdint.hpp> + +struct $(name)_t{ + + #for $reg in $regs + #if $reg.get_enums() + enum $reg.get_type(){ + #for $i, $enum in enumerate($reg.get_enums()) + #set $end_comma = ',' if $i < len($reg.get_enums())-1 else '' + $(reg.get_name().upper())_$(enum[0].upper()) = $enum[1]$end_comma + #end for + }; + #end if + $reg.get_type() $reg.get_name(); + #end for + + $(name)_t(void){ + #for $reg in $regs + $reg.get_name() = $reg.get_default(); + #end for + } + +$body + +}; + +\#endif /* INCLUDED_$(name.upper())_HPP */ +""" + +def parse_tmpl(_tmpl_text, **kwargs): + return str(Template(_tmpl_text, kwargs)) + +def to_num(arg): return eval(arg) + +class reg: + def __init__(self, reg_des): + try: self.parse(reg_des) + except Exception, e: + raise Exception, 'Error parsing register description: "%s"\nWhat: %s'%(reg_des, e) + + def parse(self, reg_des): + x = re.match('^(\w*)\s*(\w*)\[(.*)\]\s*(\w*)\s*(.*)$', reg_des) + name, addr, bit_range, default, enums = x.groups() + + #store variables + self._name = name + self._addr = to_num(addr) + if ':' in bit_range: self._addr_spec = sorted(map(int, bit_range.split(':'))) + else: self._addr_spec = int(bit_range), int(bit_range) + self._default = to_num(default) + + #extract enum + self._enums = list() + if enums: + enum_val = 0 + for enum_str in map(str.strip, enums.split(',')): + if '=' in enum_str: + enum_name, enum_val = enum_str.split('=') + enum_val = to_num(enum_val) + else: enum_name = enum_str + self._enums.append((enum_name, enum_val)) + enum_val += 1 + + def get_addr(self): return self._addr + def get_enums(self): return self._enums + def get_name(self): return self._name + def get_default(self): + for key, val in self.get_enums(): + if val == self._default: return str.upper('%s_%s'%(self.get_name(), key)) + return self._default + def get_type(self): + if self.get_enums(): return '%s_t'%self.get_name() + return 'boost::uint%d_t'%max(2**math.ceil(math.log(self.get_bit_width(), 2)), 8) + def get_shift(self): return self._addr_spec[0] + def get_mask(self): return hex(int('1'*self.get_bit_width(), 2)) + def get_bit_width(self): return self._addr_spec[1] - self._addr_spec[0] + 1 + +def generate(name, regs_tmpl, body_tmpl='', file=__file__): + regs = map(reg, parse_tmpl(regs_tmpl).splitlines()) + body = parse_tmpl(body_tmpl, regs=regs).replace('\n', '\n ').strip() + code = parse_tmpl(COMMON_TMPL, + name=name, + regs=regs, + body=body, + file=file, + ) + open(sys.argv[1], 'w').write(code) |