def adjust(left, right, lpoint, rpoint, signed=True): diff_lpoint = vtypes.Mux(rpoint < lpoint, 0, rpoint - lpoint) diff_rpoint = vtypes.Mux(lpoint < rpoint, 0, lpoint - rpoint) ldata = vtypes.Mux(diff_lpoint == 0, left, shift_left(left, diff_lpoint, signed)) rdata = vtypes.Mux(diff_rpoint == 0, right, shift_left(right, diff_rpoint, signed)) _ldata = vtypes.Mux(signed, vtypes.SystemTask('signed', ldata), ldata) _rdata = vtypes.Mux(signed, vtypes.SystemTask('signed', rdata), rdata) return _ldata, _rdata
def fixed_to_real(value, point): if point < 0: return vtypes.SystemTask('itor', fixed_to_int(value, point)) if point == 0: return vtypes.SystemTask('itor', value) if isinstance(value, float): raise TypeError("value is already float.") if isinstance(value, (int, bool)) and isinstance(point, int): mag = 2 ** point return float(value) / mag signed = vtypes.get_signed(value) width = value.bit_length() msb = (value[width - 1] if isinstance(value, vtypes._Variable) else (value >> (width - 1)) & 0x1) v0 = (vtypes.SystemTask('itor', fixed_to_int(value, point)) + vtypes.SystemTask('itor', fixed_to_int_low(value, point)) / vtypes.SystemTask('itor', vtypes.Int(2) ** point)) nv = vtypes.Unot(value) + 1 v1 = ((vtypes.SystemTask('itor', fixed_to_int(nv, point)) + vtypes.SystemTask('itor', fixed_to_int_low(nv, point)) / vtypes.SystemTask('itor', vtypes.Int(2) ** point))) * vtypes.SystemTask('itor', -1) return vtypes.Mux(signed and msb == 0, v0, v1)
def mkMultiplierCore(name, lsigned=True, rsigned=True, depth=6, with_update=True): m = module.Module(name + '_core') lwidth = m.Parameter('lwidth', 32) rwidth = m.Parameter('rwidth', 32) retwidth = lwidth + rwidth clk = m.Input('CLK') if with_update: update = m.Input('update') a = m.Input('a', lwidth) b = m.Input('b', rwidth) c = m.Output('c', retwidth) _a = m.Reg('_a', lwidth, signed=lsigned) _b = m.Reg('_b', rwidth, signed=rsigned) _mul = m.Wire('_mul', retwidth, signed=True) _pipe_mul = [ m.Reg('_pipe_mul%d' % i, retwidth, signed=True) for i in range(depth - 1) ] __a = _a __b = _b if not lsigned: __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _a)) if not rsigned: __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _b)) m.Assign(_mul(__a * __b)) m.Assign(c(_pipe_mul[depth - 2])) body = (_a(a), _b(b), _pipe_mul[0](_mul), [_pipe_mul[i](_pipe_mul[i - 1]) for i in range(1, depth - 1)]) if with_update: body = vtypes.If(update)(body) m.Always(vtypes.Posedge(clk))(body) return m
def mkMaddCore(index, awidth=32, bwidth=32, cwidth=32, asigned=True, bsigned=True, csigned=True, depth=6): retwidth = max(awidth + bwidth, cwidth) m = module.Module('madd_core_%d' % index) clk = m.Input('CLK') update = m.Input('update') a = m.Input('a', awidth) b = m.Input('b', bwidth) c = m.Input('c', cwidth) d = m.Output('d', retwidth) _a = m.Reg('_a', awidth, signed=asigned) _b = m.Reg('_b', bwidth, signed=bsigned) _c = m.Reg('_c', cwidth, signed=csigned) _mul = m.Wire('_mul', retwidth, signed=True) _madd = m.Wire('_madd', retwidth, signed=True) _pipe_madd = [m.Reg('_pipe_madd%d' % i, retwidth, signed=True) for i in range(depth - 1)] __a = _a __b = _b __c = _c if not asigned: __a = vtypes.SystemTask( 'signed', vtypes.Cat(vtypes.Int(0, width=1), _a)) if not bsigned: __b = vtypes.SystemTask( 'signed', vtypes.Cat(vtypes.Int(0, width=1), _b)) if not csigned: __c = vtypes.SystemTask( 'signed', vtypes.Cat(vtypes.Int(0, width=1), _c)) m.Assign(_mul(__a * __b)) m.Assign(_madd(_mul + __c)) m.Assign(d(_pipe_madd[depth - 2])) m.Always(vtypes.Posedge(clk))( vtypes.If(update)( _a(a), _b(b), _c(c), _pipe_madd[0](_madd), [_pipe_madd[i](_pipe_madd[i - 1]) for i in range(1, depth - 1)] )) return m
def mkMultiplierCore(index, lwidth=32, rwidth=32, lsigned=True, rsigned=True, depth=6): if lwidth <= 0: raise ValueError("data width must be greater than 0.") if rwidth <= 0: raise ValueError("data width must be greater than 0.") if depth < 2: raise ValueError("depth must be greater than 1.") retwidth = lwidth + rwidth m = module.Module('multiplier_core_%d' % index) clk = m.Input('CLK') update = m.Input('update') a = m.Input('a', lwidth) b = m.Input('b', rwidth) c = m.Output('c', retwidth) _a = m.Reg('_a', lwidth, signed=lsigned) _b = m.Reg('_b', rwidth, signed=rsigned) _mul = m.Wire('_mul', retwidth, signed=True) _pipe_mul = [ m.Reg('_pipe_mul%d' % i, retwidth, signed=True) for i in range(depth - 1) ] __a = _a __b = _b if not lsigned: __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _a)) if not rsigned: __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _b)) m.Assign(_mul(__a * __b)) m.Assign(c(_pipe_mul[depth - 2])) m.Always(vtypes.Posedge(clk))(vtypes.If(update)( _a(a), _b(b), _pipe_mul[0](_mul), [_pipe_mul[i](_pipe_mul[i - 1]) for i in range(1, depth - 1)])) return m
def to_signed(value): if isinstance(value, int): return vtypes.Int(value, signed=True) if isinstance(value, vtypes.Int): return vtypes.Int(value.value, signed=True) if vtypes.get_signed(value): return value data = vtypes.SystemTask('signed', value) point = value.point if hasattr(value, 'point') else 0 return _FixedSkipUnaryOperator(data, point, True)
def mkMultiplierCore(index, lwidth=32, rwidth=32, lsigned=True, rsigned=True, depth=6): retwidth = lwidth + rwidth m = module.Module('multiplier_core_%d' % index) clk = m.Input('CLK') update = m.Input('update') a = m.Input('a', lwidth) b = m.Input('b', rwidth) c = m.Output('c', retwidth) _a = m.Reg('_a', lwidth, signed=lsigned) _b = m.Reg('_b', rwidth, signed=rsigned) tmpval = [ m.Reg('_tmpval%d' % i, retwidth, signed=True) for i in range(depth - 1) ] rslt = m.Wire('rslt', retwidth, signed=True) __a = _a __b = _b if not lsigned: __a = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _a)) if not rsigned: __b = vtypes.SystemTask('signed', vtypes.Cat(vtypes.Int(0, width=1), _b)) m.Assign(rslt(__a * __b)) m.Assign(c(tmpval[depth - 2])) m.Always(vtypes.Posedge(clk))(vtypes.If(update)( _a(a), _b(b), tmpval[0](rslt), [tmpval[i](tmpval[i - 1]) for i in range(1, depth - 1)])) return m
def _binary_op_mul(self, op, r): lvalue = self.value lpoint = self.point lsigned = self.signed if not isinstance(r, Fixed): rvalue = r rsigned = vtypes.get_signed(r) rpoint = 0 else: rvalue = r.value rsigned = r.signed rpoint = r.point point = _max_mux(lpoint, rpoint) signed = lsigned and rsigned ldata = vtypes.SystemTask('signed', lvalue) rdata = vtypes.SystemTask('signed', rvalue) shift_size = _min_mux(lpoint, rpoint) data = op(ldata, rdata) data = shift_right(data, shift_size, signed=signed) return Fixed(data, point, signed)
def visit_Print(self, node): # for Python 2.x # prepare the argument values argvalues = [] formatstring_list = [] for arg in node.values: if (isinstance(arg, ast.BinOp) and isinstance(arg.op, ast.Mod) and isinstance(arg.left, ast.Str)): # format string in print statement values, form = self._print_binop_mod(arg) argvalues.extend(values) formatstring_list.append(form) formatstring_list.append(" ") elif isinstance(arg, ast.Tuple): for e in arg.elts: value = self.visit(e) if isinstance(value, vtypes.Str): formatstring_list.append(value.value) formatstring_list.append(" ") else: argvalues.append(value) formatstring_list.append("%d") formatstring_list.append(" ") else: value = self.visit(arg) if isinstance(value, vtypes.Str): formatstring_list.append(value.value) formatstring_list.append(" ") else: argvalues.append(value) formatstring_list.append("%d") formatstring_list.append(" ") formatstring_list = formatstring_list[:-1] args = [] args.append(vtypes.Str(''.join(formatstring_list))) args.extend(argvalues) left = None right = vtypes.SystemTask('display', *args) self.setBind(left, right) self.setFsm() self.incFsmCount() return right
def makeASTTree(node): if isinstance(node, DFBranch): return Cond(makeASTTree(node.condnode), makeASTTree(node.truenode), makeASTTree(node.falsenode)) if isinstance(node, DFIntConst): return vtypes.Int(int(node.value)) if isinstance(node, DFFloatConst): return vtypes.Float(float(node.value)) if isinstance(node, DFStringConst): return vtypes.Str(node.value) if isinstance(node, DFEvalValue): if isinstance(node.value, int): return vtypes.Int(node.value) if isinstance(node.value, float): return vtypes.Float(node.value) if isinstance(node.value, DFStringConst): return vtypes.Str(node.value) raise TypeError('Unknown constant') if isinstance(node, DFTerminal): return node.original if isinstance(node, DFUndefined): return vtypes.IntX() if isinstance(node, DFHighImpedance): return vtypes.IntZ() if isinstance(node, DFOperator): if len(node.nextnodes) == 1: return getOp(node.operator)(makeASTTree(node.nextnodes[0])) return getOp(node.operator)(makeASTTree(node.nextnodes[0]), makeASTTree(node.nextnodes[1])) if isinstance(node, DFSyscall): return vtypes.SystemTask( node.syscall, tuple([makeASTTree(n) for n in node.nextnodes])) raise TypeError("Unsupported DFNode %s" % type(node))
def visit_SystemCall(self, node): cmd = node.syscall args = tuple([self.visit(arg) for arg in node.args]) systask = vtypes.SystemTask(cmd, *args) return systask
def _call_Name_print(self, node): # prepare the argument values argvalues = [] formatstring_list = [] for arg in node.args: if (isinstance(arg, ast.BinOp) and isinstance(arg.op, ast.Mod) and isinstance(arg.left, ast.Str)): # format string in print statement values, form = self._print_binop_mod(arg) for value in values: if isinstance(value, fxd._FixedBase): if value.point >= 0: argvalues.append( vtypes.Div(vtypes.SystemTask('itor', value), 1.0 * (2**value.point))) else: argvalues.append( vtypes.Times(value, 2**-value.point)) else: argvalues.append(value) formatstring_list.append(form) formatstring_list.append(" ") elif isinstance(arg, ast.Tuple): for e in arg.elts: value = self.visit(e) if isinstance(value, vtypes.Str): formatstring_list.append(value.value) formatstring_list.append(" ") elif isinstance(value, fxd._FixedBase): if value.point >= 0: argvalues.append( vtypes.Div(vtypes.SystemTask('itor', value), 1.0 * (2**value.point))) else: argvalues.append( vtypes.Times(value, 2**value.point)) formatstring_list.append("%f") formatstring_list.append(" ") else: argvalues.append(value) formatstring_list.append("%d") formatstring_list.append(" ") else: value = self.visit(arg) if isinstance(value, vtypes.Str): formatstring_list.append(value.value) formatstring_list.append(" ") elif isinstance(value, fxd._FixedBase): if value.point >= 0: argvalues.append( vtypes.Div(vtypes.SystemTask('itor', value), 1.0 * (2**value.point))) else: argvalues.append(vtypes.Times(value, 2**value.point)) formatstring_list.append("%f") formatstring_list.append(" ") else: argvalues.append(value) formatstring_list.append("%d") formatstring_list.append(" ") formatstring_list = formatstring_list[:-1] args = [] args.append(vtypes.Str(''.join(formatstring_list))) args.extend(argvalues) left = None right = vtypes.SystemTask('display', *args) self.setBind(left, right) self.setFsm() self.incFsmCount() return right
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 visit_SystemTask(self, node): args = [self.visit(arg) for arg in node.args] return vtypes.SystemTask(node.cmd, *args)