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)
def visit_Pointer(self, node): var = self.visit(node.var) pos = self.visit(node.ptr) return vtypes.Pointer(var, pos)
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)
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:
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))