Example #1
0
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))
Example #2
0
    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
Example #3
0
    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
Example #4
0
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
Example #5
0
    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