def __init__(self, left, right): lpoint = left.point if isinstance(left, _FixedBase) else 0 rpoint = right.point if isinstance(right, _FixedBase) else 0 lsigned = vtypes.get_signed(left) rsigned = vtypes.get_signed(right) point = _max_mux(lpoint, rpoint) signed = lsigned and rsigned if not self.overwrite_signed else False lwidth = vtypes.get_width(left) rwidth = vtypes.get_width(right) if lpoint <= rpoint: ldata, rdata = adjust(left, right, lpoint, rpoint, signed) shift_size = point else: ldata = left rdata = right shift_size = point - (lpoint - rpoint) try: lmsb = ldata[lwidth - 1] except: lmsb = (ldata >> (lwidth - 1) & vtypes.Int(1, 1, base=2)) try: rmsb = rdata[rwidth - 1] except: rmsb = (rdata >> (rwidth - 1) & vtypes.Int(1, 1, base=2)) abs_ldata = (ldata if not lsigned else vtypes.Mux( vtypes.Ulnot(lmsb), ldata, vtypes.Unot(ldata) + 1)) abs_rdata = (rdata if not rsigned else vtypes.Mux( vtypes.Ulnot(rmsb), rdata, vtypes.Unot(rdata) + 1)) abs_data = vtypes.Divide(abs_ldata, abs_rdata) data = (abs_data if not signed else vtypes.Mux( vtypes.Eq(lmsb, rmsb), abs_data, vtypes.Unot(abs_data) + 1)) if shift_size > 0: data = vtypes.Sll(data, shift_size) _FixedSkipUnaryOperator.__init__(self, data, point, signed)
def _call_Name_len(self, node): if len(node.args) > 1: raise TypeError('takes %d positional arguments but %d were given' % (1, len(node.args))) value = self.visit(node.args[0]) if not isinstance(value, numerical_types): return len(value) ln = getattr(value, '_len', None) if ln is not None: return ln return vtypes.get_width(value)
def write(dst, value, blk=False, ldelay=None, rdelay=None, method='write'): width = vtypes.get_width(dst) signed = vtypes.get_signed(dst) if signed: max = _pow2(width - 1) - 1 min = _pow2(width - 1) * (-1) else: max = _pow2(width) - 1 min = 0 sat_val = to_saturate(value, width=width, max=max, min=min, signed=signed) return getattr(dst, method)(sat_val, blk=blk, ldelay=ldelay, rdelay=rdelay)
def __init__(self, m, name, clk, addr, values, enable=None, datawidth=None): self.m = m self.name = name self.clk = clk size = int(math.ceil(math.log(len(values), 2))) self.addr = self.m.Wire(name + '_addr', size) self.m.Assign(self.addr(addr)) if datawidth is None: datawidth = 1 for v in values: w = vtypes.get_width(v) if w is not None and w > datawidth: datawidth = w with_enable = enable is not None if enable is not None: self.enable = self.m.Wire(name + '_enable') self.m.Assign(self.enable(enable)) self.rdata = self.m.Wire(name + '_val', datawidth) sync = True if clk is not None else False rom_def = mkROMDefinition(name, values, size, datawidth, sync, with_enable) ports = [] if clk is not None: ports.append(self.clk) ports.append(self.addr) if enable is not None: ports.append(self.enable) ports.append(self.rdata) self.m.Instance(rom_def, name, params=(), ports=ports)
def pack(self, *args): rslts = [self.visit(arg) for arg in args] all_stage_none = reduce(lambda t, x: t and x is None, [rslt[0] for rslt in rslts], True) if all_stage_none: data = [rslt[1] for rslt in rslts] valid = reduce(self.pack_valid, [rslt[2] for rslt in rslts], None) ready = reduce(self.pack_ready, [rslt[3] for rslt in rslts], []) return (None, data, valid, ready) max_stage = reduce( lambda x, y: None if x is None and y is None else x if x is not None and y is None else y if y is not None and x is None else max(x, y), [rslt[0] for rslt in rslts], None) new_args = [] for rslt, arg in zip(rslts, args): stage = rslt[0] if stage is None: new_args.append(arg) continue if stage == max_stage: new_args.append(arg) continue diff = max_stage - stage p = arg for i in range(diff): width = vtypes.get_width(rslt[1]) p = self.df.stage(p, width=width, preg=arg) new_args.append(p) new_rslts = [self.visit(arg) for arg in new_args] data = [rslt[1] for rslt in new_rslts] valid = reduce(self.pack_valid, [rslt[2] for rslt in new_rslts], None) ready = reduce(self.pack_ready, [rslt[3] for rslt in new_rslts], []) return (max_stage, data, valid, ready)
def visit_Cat(self, node): left_values = [] right_values = [] for v in node.vars: val = self.visit(v) width = vtypes.get_width(v) if width is None: width = 1 if val is None: right = vtypes.IntX(width) elif isinstance(val.right, int): right = vtypes.Int(val.right, width) elif isinstance(val.right, vtypes._Constant): right = copy.deepcopy(val.right) right.width = width else: right = v._get_module().TmpLocalparam(val.right, width) left_values.append(v) right_values.append(right) return vtypes.Subst(vtypes.Cat(*left_values), vtypes.Cat(*right_values))
def _add_delayed_subst(self, subst, delay): if not isinstance(subst, vtypes.Subst): return subst left = subst.left right = subst.right if isinstance(right, (bool, int, float, str, vtypes._Constant, vtypes._ParameterVariable)): return subst width = vtypes.get_width(left) signed = vtypes.get_signed(left) prev = right name_prefix = ('_'.join([ '', left.name, str(self.tmp_count) ]) if isinstance(left, vtypes._Variable) else '_'.join( ['', self.name, 'sbst', str(self.tmp_count)])) self.tmp_count += 1 for i in range(delay): tmp_name = '_'.join([name_prefix, str(i + 1)]) tmp = self.m.Reg(tmp_name, width, initval=0, signed=signed) self._add_statement([tmp(prev)], delay=i, no_delay_cond=True) prev = tmp return left(prev)
def __init__(self, m, name, clk, rst, left, right, enable=None, update=None, lwidth=None, rwidth=None, lsigned=True, rsigned=True, depth=6): if lwidth is None: lwidth = vtypes.get_width(left) if lwidth is None: lwidth = 1 if rwidth is None: rwidth = vtypes.get_width(right) if rwidth is None: rwidth = 1 retwidth = lwidth + rwidth with_enable = True if enable is not None else False with_update = True if update is not None else False self.m = m self.name = name self.clk = clk self.rst = rst self.enable = enable self.update = update if with_enable: self.valid = self.m.Wire(name + '_valid') self.left = left self.right = right self.value = self.m.Wire(name + '_value', retwidth) mul_def = mkMultiplier(name, lsigned, rsigned, depth, with_update, with_enable) params = [('lwidth', lwidth), ('rwidth', rwidth)] ports = [] ports.append(self.clk) ports.append(self.rst) if with_update: ports.append(self.update) if with_enable: ports.append(self.enable) ports.append(self.valid) ports.append(self.left) ports.append(self.right) ports.append(self.value) self.m.Instance(mul_def, name, params=params, ports=ports)
def add_dump(self, m, seq, input_vars, output_vars, all_vars): pipeline_depth = self.pipeline_depth() log_pipeline_depth = max( int(math.ceil(math.log(max(pipeline_depth, 10), 10))), 1) seq( self.dump_step(1) ) for i in range(pipeline_depth + 1): seq.If(seq.Prev(self.dump_enable, i))( self.dump_step.inc() ) def get_name(obj): if hasattr(obj, 'name'): return obj.name if isinstance(obj, vtypes._Constant): return obj.__class__.__name__ raise TypeError() longest_name_len = 0 for input_var in sorted(input_vars, key=lambda x: x.object_id): if not (self.dump_mode == 'all' or self.dump_mode == 'stream' or self.dump_mode == 'input' or self.dump_mode == 'inout' or (self.dump_mode == 'selective' and hasattr(input_var, 'dump') and input_var.dump)): continue name = get_name(input_var.sig_data) length = len(name) + 6 longest_name_len = max(longest_name_len, length) for var in sorted(all_vars, key=lambda x: (-1, x.object_id) if x.end_stage is None else (x.end_stage, x.object_id)): if not (self.dump_mode == 'all' or self.dump_mode == 'stream' or (self.dump_mode == 'selective' and hasattr(var, 'dump') and var.dump)): continue name = get_name(var.sig_data) length = len(name) + 6 longest_name_len = max(longest_name_len, length) for output_var in sorted(output_vars, key=lambda x: x.object_id): if not (self.dump_mode == 'all' or self.dump_mode == 'stream' or self.dump_mode == 'output' or self.dump_mode == 'inout' or (self.dump_mode == 'selective' and hasattr(output_var, 'dump') and output_var.dump)): continue name = get_name(output_var.output_sig_data) length = len(name) + 6 longest_name_len = max(longest_name_len, length) longest_var_len = 0 for var in sorted(all_vars, key=lambda x: (-1, x.object_id) if x.start_stage is None else (x.start_stage, x.object_id)): bitwidth = vtypes.get_width(var.sig_data) if bitwidth is None: bitwidth = 1 if bitwidth <= 0: bitwidth = 1 base = (var.dump_base if hasattr(var, 'dump_base') else self.dump_base) total_length = int(math.ceil(bitwidth / math.log(base, 2))) #point_length = int(math.ceil(var.point / math.log(base, 2))) #point_length = max(point_length, 8) #longest_var_len = max(longest_var_len, total_length, point_length) longest_var_len = max(longest_var_len, total_length) for input_var in sorted(input_vars, key=lambda x: x.object_id): base = (input_var.dump_base if hasattr(input_var, 'dump_base') else self.dump_base) base_char = ('b' if base == 2 else 'o' if base == 8 else 'd' if base == 10 and input_var.point <= 0 else # 'f' if base == 10 and input_var.point > 0 else 'g' if base == 10 and input_var.point > 0 else 'x') prefix = ('0b' if base == 2 else '0o' if base == 8 else ' ' if base == 10 else '0x') # if base_char == 'f': # point_length = int(math.ceil(input_var.point / math.log(base, 2))) # point_length = max(point_length, 8) # fmt_list = [prefix, '%', # '%d.%d' % (longest_var_len + 1, point_length), base_char] # if base_char == 'g': # fmt_list = [prefix, '%', base_char] # else: # fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char] fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char] if input_var not in all_vars: fmt_list.append(' (unused)') input_var.dump_fmt = ''.join(fmt_list) for output_var in sorted(output_vars, key=lambda x: x.object_id): base = (output_var.dump_base if hasattr(output_var, 'dump_base') else self.dump_base) base_char = ('b' if base == 2 else 'o' if base == 8 else 'd' if base == 10 and output_var.point <= 0 else # 'f' if base == 10 and output_var.point > 0 else 'g' if base == 10 and output_var.point > 0 else 'x') prefix = ('0b' if base == 2 else '0o' if base == 8 else ' ' if base == 10 else '0x') # if base_char == 'f': # point_length = int(math.ceil(output_var.point / math.log(base, 2))) # point_length = max(point_length, 8) # fmt_list = [prefix, '%', # '%d.%d' % (longest_var_len + 1, point_length), base_char] # if base_char == 'g': # fmt_list = [prefix, '%', base_char] # else: # fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char] fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char] if output_var not in all_vars: fmt_list.append(' (unused)') output_var.dump_fmt = ''.join(fmt_list) for var in sorted(all_vars, key=lambda x: (-1, x.object_id) if x.start_stage is None else (x.start_stage, x.object_id)): base = (var.dump_base if hasattr(var, 'dump_base') else self.dump_base) base_char = ('b' if base == 2 else 'o' if base == 8 else 'd' if base == 10 and var.point <= 0 else # 'f' if base == 10 and var.point > 0 else 'g' if base == 10 and var.point > 0 else 'x') prefix = ('0b' if base == 2 else '0o' if base == 8 else ' ' if base == 10 else '0x') # if base_char == 'f': # point_length = int(math.ceil(var.point / math.log(base, 2))) # point_length = max(point_length, 8) # fmt_list = [prefix, '%', # '%d.%d' % (longest_var_len + 1, point_length), base_char] # if base_char == 'g': # fmt_list = [prefix, '%', base_char] # else: # fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char] fmt_list = [prefix, '%', '%d' % (longest_var_len + 1), base_char] var.dump_fmt = ''.join(fmt_list) enables = [] for input_var in sorted(input_vars, key=lambda x: x.object_id): if not (self.dump_mode == 'all' or self.dump_mode == 'stream' or self.dump_mode == 'input' or self.dump_mode == 'inout' or (self.dump_mode == 'selective' and hasattr(input_var, 'dump') and input_var.dump)): continue vfmt = input_var.dump_fmt name = get_name(input_var.sig_data) name_alignment = ' ' * (longest_name_len - len(name) - len('(in) ')) fmt = ''.join(['<', self.name, ' step:%d, ', 'stage:%', str( log_pipeline_depth), 'd, age:%d> (in) ', name_alignment, name, ' = ', vfmt]) stage = input_var.end_stage if input_var.end_stage is not None else 0 enable = seq.Prev(self.dump_enable, stage) enables.append(enable) age = seq.Prev(self.dump_step, stage) - 1 if input_var.point > 0: sig_data = vtypes.Div(vtypes.SystemTask('itor', input_var.sig_data), 1.0 * (2 ** input_var.point)) elif input_var.point < 0: sig_data = vtypes.Times(input_var.sig_data, 2 ** -input_var.point) else: sig_data = input_var.sig_data seq.If(enable, vtypes.Not(self.dump_mask))( vtypes.Display(fmt, self.dump_step, stage, age, sig_data) ) for var in sorted(all_vars, key=lambda x: (-1, x.object_id) if x.end_stage is None else (x.end_stage, x.object_id)): if not (self.dump_mode == 'all' or self.dump_mode == 'stream' or (self.dump_mode == 'selective' and hasattr(var, 'dump') and var.dump)): continue vfmt = var.dump_fmt name = get_name(var.sig_data) name_alignment = ' ' * (longest_name_len - len(name)) stage = var.end_stage if var.end_stage is not None else 0 fmt = ''.join(['<', self.name, ' step:%d, ', 'stage:%', str(log_pipeline_depth), 'd, age:%d> ', name_alignment, name, ' = ', vfmt]) enable = seq.Prev(self.dump_enable, stage) enables.append(enable) age = seq.Prev(self.dump_step, stage) - 1 if var.point > 0: sig_data = vtypes.Div(vtypes.SystemTask('itor', var.sig_data), 1.0 * (2 ** var.point)) elif var.point < 0: sig_data = vtypes.Times(var.sig_data, 2 ** -var.point) else: sig_data = var.sig_data seq.If(enable, vtypes.Not(self.dump_mask))( vtypes.Display(fmt, self.dump_step, stage, age, sig_data) ) for output_var in sorted(output_vars, key=lambda x: x.object_id): if not (self.dump_mode == 'all' or self.dump_mode == 'stream' or self.dump_mode == 'output' or self.dump_mode == 'inout' or (self.dump_mode == 'selective' and hasattr(output_var, 'dump') and output_var.dump)): continue vfmt = output_var.dump_fmt name = get_name(output_var.output_sig_data) name_alignment = ' ' * (longest_name_len - len(name) - len('(out) ')) fmt = ''.join(['<', self.name, ' step:%d, ', 'stage:%', str( log_pipeline_depth), 'd, age:%d> (out) ', name_alignment, name, ' = ', vfmt]) stage = output_var.end_stage if output_var.end_stage is not None else 0 enable = seq.Prev(self.dump_enable, stage) enables.append(enable) age = seq.Prev(self.dump_step, stage) - 1 if output_var.point > 0: sig_data = vtypes.Div(vtypes.SystemTask('itor', output_var.output_sig_data), 1.0 * (2 ** output_var.point)) elif output_var.point < 0: sig_data = vtypes.Times(output_var.output_sig_data, 2 ** -output_var.point) else: sig_data = output_var.output_sig_data seq.If(enable, vtypes.Not(self.dump_mask))( vtypes.Display(fmt, self.dump_step, stage, age, sig_data) )
def get_width(self): return vtypes.get_width(self.data)
def reinterpret_cast_to_fixed(value, point, signed=True): m = value._get_module() width = vtypes.get_width(value) v = FixedTmpWire(m, width=width, point=point, signed=signed) v.assign_raw(value) return v