Пример #1
0
 def visit_Pointer(self, node):
     val = self.visit(node.var)
     if val is None:
         return None
     left = vtypes.Pointer(val.left, node.pos)
     if not isinstance(val.right, (vtypes._Variable, vtypes.Scope)):
         if isinstance(val.right, (int, bool)):
             val_right = vtypes.Int(val.right)
         elif isinstance(val.right, float):
             val_right = vtypes.Float(val.right)
         else:
             raise TypeError("unsupported value type: %s" % str(val.right))
         right = (val_right >> node.pos) & 0x1
     else:
         right = vtypes.Pointer(val.right, node.pos)
     return vtypes.Subst(left, right)
Пример #2
0
 def visit_Pointer(self, node):
     var = self.visit(node.var)
     pos = self.visit(node.ptr)
     return vtypes.Pointer(var, pos)
Пример #3
0
    def make_module(self, reset=(), body=()):
        if self.done:
            #raise ValueError('make_always() has been already called.')
            return

        self.done = True

        m = Module(self.name)

        clk = m.Input('CLK')

        if self.rst is not None:
            rst = m.Input('RST')
        else:
            rst = None

        body = list(body) + list(self.make_code())
        dsts = self.dst_var.values()
        src_visitor = SubstSrcVisitor()

        # collect sources in destination variable definitions
        for dst in dsts:
            if isinstance(dst, (vtypes.Pointer, vtypes.Slice, vtypes.Cat)):
                raise ValueError(
                    'Partial assignment is not supported by as_module mode.')

            if isinstance(dst, vtypes._Variable):
                if dst.width is not None:
                    src_visitor.visit(dst.width)
                if dst.dims is not None:
                    src_visitor.visit(dst.dims)

        # collect sources in statements
        for statement in body:
            src_visitor.visit(statement)

        srcs = src_visitor.srcs.values()

        # collect sources in source variable definitions
        for src in srcs:
            if isinstance(src, vtypes._Variable):
                if src.width is not None:
                    src_visitor.visit(src.width)
                if src.dims is not None:
                    src_visitor.visit(src.dims)

        srcs = src_visitor.srcs.values()

        params = collections.OrderedDict()
        ports = collections.OrderedDict()
        src_rename_dict = collections.OrderedDict()

        # create parameter/localparam definitions
        for src in srcs:
            if isinstance(src, (vtypes.Parameter, vtypes.Localparam)):
                arg_name = src.name
                v = m.Parameter(arg_name, src.value, src.width, src.signed)
                src_rename_dict[src.name] = v
                params[arg_name] = src

        src_rename_visitor = SrcRenameVisitor(src_rename_dict)

        for src in srcs:
            if isinstance(src, (vtypes.Parameter, vtypes.Localparam)):
                continue

            arg_name = 'i_%s' % src.name

            if src.dims is not None:
                # outside FSM-module
                width = src.bit_length()
                dims = src.dims
                length = None
                for dim in dims:
                    if length is None:
                        length = dim
                    else:
                        length *= dim
                pack_width = vtypes.Mul(width, length)
                out_line = self.m.TmpWire(pack_width,
                                          prefix='_%s_%s' %
                                          (self.name, src.name))

                g = self.m
                s = src
                a = None
                for d, dim in enumerate(dims):
                    i = g.TmpGenvar(prefix='i')
                    g = g.GenerateFor(i(0), i < dim, i(i + 1))
                    s = vtypes.Pointer(s, i)
                    b = None
                    for dm in dims[d + 1:]:
                        if b is None:
                            b = dm
                        else:
                            b *= dm
                    if a is None:
                        if b is None:
                            a = i
                        else:
                            a = i * b
                    else:
                        if b is None:
                            a += i
                        else:
                            a += i * b

                v = out_line[a * width:(a + 1) * width]
                p = g.Assign(v(s))

                # inside FSM-module
                rep_width = (src_rename_visitor.visit(src.width)
                             if src.width is not None else None)
                rep_dims = src_rename_visitor.visit(src.dims)
                rep_length = None
                for rep_dim in rep_dims:
                    if rep_length is None:
                        rep_length = rep_dim
                    else:
                        rep_length *= rep_dim
                pack_width = (rep_length if rep_width is None else vtypes.Mul(
                    rep_length, rep_width))
                in_line = m.Input(arg_name + '_line',
                                  pack_width,
                                  signed=src.get_signed())
                in_array = m.Wire(arg_name,
                                  rep_width,
                                  rep_length,
                                  signed=src.get_signed())

                g = m
                ia = in_array
                a = None
                for rep_dim in rep_dims:
                    i = g.TmpGenvar(prefix='i')
                    g = g.GenerateFor(i(0), i < rep_dim, i(i + 1))
                    ia = vtypes.Pointer(ia, i)
                    b = None
                    for rep_dm in rep_dims[d + 1:]:
                        if b is None:
                            b = rep_dm
                        else:
                            b *= rep_dm
                    if a is None:
                        if b is None:
                            a = i
                        else:
                            a = i * b
                    else:
                        if b is None:
                            a += i
                        else:
                            a += i * b

                v = in_line[a * rep_width:(a + 1) * rep_width]
                p = g.Assign(ia(v))

                src_rename_dict[src.name] = in_array
                ports[in_line.name] = out_line

            else:
                rep_width = (src_rename_visitor.visit(src.width)
                             if src.width is not None else None)
                v = m.Input(arg_name, rep_width, signed=src.get_signed())

                src_rename_dict[src.name] = v
                ports[arg_name] = src

        for dst in dsts:
            arg_name = dst.name

            rep_width = (src_rename_visitor.visit(dst.width)
                         if dst.width is not None else None)
            out = m.OutputReg(arg_name, rep_width, signed=dst.get_signed())
            out_wire = self.m.TmpWire(rep_width,
                                      signed=dst.get_signed(),
                                      prefix='_%s_%s' % (self.name, arg_name))
            self.m.Always()(dst(out_wire, blk=True))
            ports[arg_name] = out_wire

        body = [src_rename_visitor.visit(statement) for statement in body]

        reset = list(reset) + list(self.make_reset())

        if not reset and not body:
            pass
        elif not reset or rst is None:
            m.Always(vtypes.Posedge(clk))(body, )
        else:
            m.Always(vtypes.Posedge(clk))(vtypes.If(rst)(reset, )(body, ))

        arg_params = [(name, param) for name, param in params.items()]

        arg_ports = [('CLK', self.clk)]
        if self.rst is not None:
            arg_ports.append(('RST', self.rst))

        arg_ports.extend([(name, port) for name, port in ports.items()])

        sub = Submodule(self.m,
                        m,
                        'inst_' + m.name,
                        '_%s_' % self.name,
                        arg_params=arg_params,
                        arg_ports=arg_ports)
Пример #4
0
                length = None
                for dim in dims:
                    if length is None:
                        length = dim
                    else:
                        length *= dim
                pack_width = vtypes.Mul(width, length)
                out_line = self.m.TmpWire(pack_width, prefix='_%s' % self.name)

                g = self.m
                s = src
                a = None
                for d, dim in enumerate(dims):
                    i = g.TmpGenvar(prefix='i')
                    g = g.GenerateFor(i(0), i < dim, i(i + 1))
                    s = vtypes.Pointer(s, i)
                    b = None
                    for dm in dims[d + 1:]:
                        if b is None:
                            b = dm
                        else:
                            b *= dm
                    if a is None:
                        if b is None:
                            a = i
                        else:
                            a = i * b
                    else:
                        if b is None:
                            a += i
                        else:
Пример #5
0
 def visit_Pointer(self, node):
     val = self.visit(node.var)
     if val is None:
         return None
     return vtypes.Subst(vtypes.Pointer(val.left, node.pos),
                         vtypes.Pointer(val.right, node.pos))