def sub_circuit(name, **kwargs): data = kwargs.pop('config', None) _root_builder.circuit_builder.circuit.children.append( ir.ASTSubCircuit(name, {k: _unwrap(v) for k, v in kwargs.items()}, {k: _unwrap(v) for k, v in kwargs.items()}, data=data))
def transform(self): for bk, bv in self.binddict.items(): print('bk:', bk) for bvi in bv: print('bvi:') # print(bvi.tocode()) print(self._lower(bvi)) for instance in self.instances: module_def = self.other_modules[instance.module] module_ports = module_def.portlist.ports bound_entries = instance.portlist mapping = {} for port, arg in zip(module_ports, bound_entries): mapping[port.first.name] = self.circuit.get_port( arg.argname.name) self.circuit.children.append( ir.ASTSubCircuit(module_def.name, mapping, mapping)) pass
def _emit_expr_intrinsic(self, v_name, children, bits=None): if v_name == 'Plus': assert type(bits) == int assert len(children) == 2 assert all(c.get_bitsize() == bits for c in children) result_sig = self.circuit.generate_internal_signal(bits) result_port = self.circuit.get_port(result_sig) self.required_intrinsics.add(('add', bits)) self.circuit.children.append( ir.ASTSubCircuit( '_add' + str(bits), { 'A': children[0], 'B': children[1], 'Cin': ir.ASTPort('__const1_off', 1), }, { 'X': result_port, })) return result_port raise ValueError
def generate_intrinsic(info): name = '[unknown]' circuit = None other_intrinsics = set([]) if info == ('add', 1): name = '_add1' circuit = ir.ASTCircuit( [ir.ASTPort('A', 1), ir.ASTPort('B', 1), ir.ASTPort('Cin', 1)], [ir.ASTPort('X', 1), ir.ASTPort('Cout', 1)]) circuit.internal_signals['AxorB'] = 1 circuit.children.append( ir.ASTAssign( circuit.get_port('AxorB'), ir.ASTLogicGate('xor', [circuit.get_port('A'), circuit.get_port('B')]))) circuit.children.append( ir.ASTAssign( circuit.get_port('X'), ir.ASTLogicGate( 'xor', [circuit.get_port('AxorB'), circuit.get_port('Cin')]))) circuit.children.append( ir.ASTAssign( circuit.get_port('Cout'), ir.ASTLogicGate('or', [ ir.ASTLogicGate( 'and', [circuit.get_port('A'), circuit.get_port('B')]), ir.ASTLogicGate( 'and', [circuit.get_port('AxorB'), circuit.get_port('Cin')]) ]))) elif info[0] == 'add': size = info[1] other_intrinsics.add(('add', 1)) name = '_add' + str(size) circuit = ir.ASTCircuit([ ir.ASTPort('A', size), ir.ASTPort('B', size), ir.ASTPort('Cin', 1) ], [ir.ASTPort('X', size), ir.ASTPort('Cout', 1)]) in_cin = 'Cin' for i in range(size): carry = 'c' + str(i) circuit.internal_signals[carry] = 1 circuit.children.append( ir.ASTSubCircuit( '_add1', { 'A': circuit.get_port('A')[i], 'B': circuit.get_port('B')[i], 'Cin': circuit.get_port(in_cin), }, { 'X': circuit.get_port('X')[i], 'Cout': circuit.get_port(carry), })) in_cin = carry circuit.children.append( ir.ASTAssign(circuit.get_port('Cout'), circuit.get_port(in_cin))) # (circuit, new intrinsics that are needed) return name, circuit, other_intrinsics
def _lower_expr(self, expr, ident=None, bits=None): # if isinstance(expr, ) if isinstance(expr, df.DFPartselect): return self.circuit.get_port(expr.var.name[1])[int(expr.lsb.value), int(expr.msb.value)] elif isinstance(expr, df.DFBranch): spec_mux = self._speculative_mux_folding(expr, ident=ident, bits=bits) if spec_mux: return spec_mux false_node = self._lower_expr( expr.falsenode, ident=ident, bits=bits) if expr.falsenode else ident true_node = self._lower_expr(expr.truenode, ident=ident, bits=bits) if expr.truenode else ident if isinstance(expr.condnode, df.DFIntConst): if expr.condnode.eval(): return true_node else: return false_node return ir.ASTMultiplexer(self._lower_expr(expr.condnode, bits=1), { 0: false_node, 1: true_node, }) elif isinstance(expr, df.DFTerminal): return self.circuit.get_port(str(expr.name[1])) elif isinstance(expr, df.DFOperator): assert len(expr.nextnodes) == 2 or (len(expr.nextnodes) == 1 and expr.operator in ['Unot']) if expr.operator == 'Eq' and isinstance(expr.nextnodes[1], df.DFIntConst): lhs = self._lower_expr(expr.nextnodes[0]) bitsize = lhs.get_bitsize() lhs_name = self.circuit.generate_internal_signal(bitsize) lhs_port = self.circuit.get_port(lhs_name) self.circuit.children.append(ir.ASTAssign(lhs_port, lhs)) const_str = expr.nextnodes[1].value if "'" in const_str: _, _, const_str = const_str.partition("'b") const_value = int(const_str) previous = None for i in range(bitsize): my_bit = lhs_port[i] if ((const_value >> i) % 2) == 0: my_bit = ir.ASTLogicGate('not', children=[my_bit]) if previous: previous = ir.ASTLogicGate('and', children=[previous, my_bit]) else: previous = my_bit return previous lookup = { 'Lor': 'or', 'Or': 'or', 'And': 'and', 'Xor': 'xor', 'Unot': 'not' } if expr.operator in ['Plus']: return self._emit_expr_intrinsic( expr.operator, [self._lower_expr(x, bits=bits) for x in expr.nextnodes], bits=bits) return ir.ASTLogicGate( lookup[expr.operator], children=[self._lower_expr(x) for x in expr.nextnodes]) elif isinstance(expr, df.DFIntConst): return self.resolve_const(expr.eval(), bits=bits) elif isinstance(expr, df.DFPointer): mem_name = str(expr.var.name[1]) mem_init = '' if mem_name in self.mem_initial: mem_init = self.mem_initial[mem_name] reg_array = self.mem_definitions[mem_name] def p(x): return df.DFIntConst(x.value).eval() assert p(reg_array.width.lsb) == 0 assert p(reg_array.length.msb) == 0 address_bits = math.ceil( math.log2( p(reg_array.length.lsb) - p(reg_array.length.msb) + 1)) data_bits = p(reg_array.width.msb) - p(reg_array.width.lsb) + 1 address = self._lower_expr(expr.ptr, bits=address_bits) data_name = self.circuit.generate_internal_signal(data_bits) data_port = ir.ASTPort(data_name, data_bits) self.circuit.children.append( ir.ASTSubCircuit('rom', {'Address': address}, {'Data': data_port}, data={ 'address_bits': address_bits, 'data_bits': data_bits, 'contents': mem_init, })) return data_port elif isinstance(expr, df.DFConcat): pieces = [self._lower_expr(node) for node in expr.nextnodes] total_bits = sum(x.get_bitsize() for x in pieces) out_name = self.circuit.generate_internal_signal(total_bits) out_port = ir.ASTPort(out_name, total_bits) high_bit = total_bits - 1 for piece in pieces: low = high_bit - piece.get_bitsize() + 1 self.circuit.children.append( ir.ASTAssign(ir.ASTSubPort(out_name, low, high_bit), piece)) high_bit = low - 1 return out_port else: raise ValueError