def mapToIR(self, ctx: EmitterContext): def _mapToIRRec(cb: CondBlock): cond = ctx.getRef(cb.when.cond) [ctx.getRef(i) for i in cb.when.block] conseq = low_ir.Block(ctx.getScopeStatements(cb.when.ownScope)) if len(cb.elsewhens) == 0: if cb.otherwise is None: alt = low_ir.EmptyStmt() else: [ctx.getRef(i) for i in cb.otherwise.block] alt = low_ir.Block( ctx.getScopeStatements(cb.otherwise.ownScope)) return low_ir.Conditionally(cond, conseq, alt) else: elif_ = cb.elsewhens[0] a = When(elif_.cond, elif_.block) a.ownScope = elif_.ownScope ncb = CondBlock(a) for i in cb.elsewhens[1:]: ncb.withElsewhen(i) ncb.withOtherwise(cb.otherwise) alt = _mapToIRRec(ncb) return low_ir.Conditionally(cond, conseq, alt) stmt = _mapToIRRec(self) ctx.appendFinalStatement(stmt, self.scopeId) return stmt
def mapToIR(self, ctx: EmitterContext): name = ctx.getName(self) mtyp = self.typ.mapToIR(ctx) defm = low_ir.DefMemory(name, mtyp) ctx.appendFinalStatement(defm, self.scopeId) ref = low_ir.Reference(name, mtyp) ctx.updateRef(self, ref) return ref
def mapToIR(self, ctx: EmitterContext): ref = get_attr(self, "ref") name = get_attr(self, "name") n = ctx.getRef(ref) typ = next(f.typ for f in n.typ.fields if f.name == name) f = low_ir.SubField(n, name, typ) ctx.updateRef(self, f) return f
def mapToIR(self, ctx: EmitterContext): name = ctx.getName(self) fs = [] for k, v in self._ios.items(): f = v.mapToIOFieldIR(k, ctx) fs.append(f) typ = low_ir.BundleType(fs) port = low_ir.Port(name, low_ir.Output(), low_ir.BundleType(fs)) ref = low_ir.Reference(name, typ) ctx.updateRef(self, ref) ctx.appendFinalPort(port) return ref
def mapToIR(self, ctx: EmitterContext): from pyhcl.dsl.vector import Vec if has_attr(self.lhs, "typ") and has_attr(self.rhs, "typ") \ and (isinstance(self.lhs.typ, Vec) or isinstance(self.rhs.typ, Vec)): lhs = OneDimensionalization(self.lhs) rhs = OneDimensionalization(self.rhs) if len(lhs) != len(rhs): raise Exception("vector size does not match") for l, r in zip(lhs, rhs): Connect._doConnect(ctx, l.mapToIR(ctx), r.mapToIR(ctx), self.scopeId) else: Connect._doConnect(ctx, ctx.getRef(self.lhs), ctx.getRef(self.rhs), self.scopeId)
def mapToIR(self, ctx: EmitterContext): val = ctx.getRef(self.initValue) name = ctx.getName(self) w = low_ir.DefRegister(name, val.typ, ctx.getClock(), ctx.getReset(), val) ctx.appendFinalStatement(w, self.scopeId) ref = low_ir.Reference(name, val.typ) ctx.updateRef(self, ref) return ref
def mapToIR(self, ctx: EmitterContext): name = ctx.getName(self) cond = ctx.getRef(self.cond) conseq = ctx.getRef(self.conseq) alt = ctx.getRef(self.alt) m = low_ir.Mux(cond, conseq, alt, conseq.typ) n = low_ir.DefNode(name, m) ctx.appendFinalStatement(n, self.scopeId) ref = low_ir.Reference(name, conseq.typ) ctx.updateRef(self, ref) return ref
def mapToIR(self, ctx: EmitterContext): from pyhcl.dsl.vector import Vec from pyhcl import IO if has_attr(self.lhs, "typ") and has_attr(self.rhs, "typ") \ and (isinstance(self.lhs.typ, Vec) or isinstance(self.rhs.typ, Vec)): lhs = OneDimensionalization(self.lhs) rhs = OneDimensionalization(self.rhs) if len(lhs) != len(rhs): raise Exception("vector size does not match") for l, r in zip(lhs, rhs): Connect._doConnect(ctx, l.mapToIR(ctx), r.mapToIR(ctx), self.scopeId) # A trick to do inheriting connect elif has_attr(self.lhs, "value") and has_attr(self.rhs, "value") \ and (isinstance(self.lhs.value, IO) or isinstance(self.rhs.value, IO)): for (key_left, value_left) in self.lhs.value._ios.items(): for (key_right, value_right) in self.rhs.value._ios.items(): from pyhcl import Input, Output assert type(value_left) == Input or type( value_left) == Output assert type(value_right) == Input or type( value_right) == Output if key_left == key_right and type(value_left) == type( value_right): lhs = getattr(self.lhs, key_left) rhs = getattr(self.rhs, key_right) if type(value_left) == Output: Connect(lhs, rhs).mapToIR(ctx) else: Connect(rhs, lhs).mapToIR(ctx) else: Connect._doConnect(ctx, ctx.getRef(self.lhs), ctx.getRef(self.rhs), self.scopeId)
def mapToIR(self, ctx: EmitterContext): typ = self.typ.mapToIR(ctx) name = ctx.getName(self) w = low_ir.DefRegister(name, typ, ctx.getClock()) ctx.appendFinalStatement(w, self.scopeId) ref = low_ir.Reference(name, typ) ctx.updateRef(self, ref) return ref
def mapToIR(self, ctx: EmitterContext): typ = ctx.getRef(self.typ) name = ctx.getName(self) w = low_ir.DefWire(name, typ) ctx.appendFinalStatement(w, self.scopeId) ref = low_ir.Reference(name, typ) ctx.updateRef(self, ref) return ref
def mapToIR(self, ctx: EmitterContext): # Define Wire name = ctx.getName(self) typ = self.typ.mapToIR(ctx) wire = low_ir.DefWire(name, typ) ctx.appendFinalStatement(wire, self.scopeId) ref = low_ir.Reference(name, typ) ctx.updateRef(self, ref) # Connect Elements for i, node in enumerate(self.lst): for idx, elem in self.subIdxs(low_ir.SubIndex(ref, i, typ.typ), node, ctx): con = low_ir.Connect(idx, elem) ctx.appendFinalStatement(con, self.scopeId) return ref
def _primMap(ctx: EmitterContext, obj, op, args, consts, tranFormFunc): if consts is None: consts = [] # get items' reference and do checking ars = [ctx.getRef(a) for a in args] newArgs, typ = tranFormFunc(*ars) e = low_ir.DoPrim(op, newArgs, consts, typ) name = ctx.getName(obj) node = low_ir.DefNode(name, e) ctx.appendFinalStatement(node, obj.scopeId) ref = low_ir.Reference(name, typ) ctx.updateRef(obj, ref) return ref
def elaborate(m: Module) -> low_ir.Circuit: ec: EmitterContext = EmitterContext(m, {}, Counter()) modIRs: Dict[int, low_ir.DefModule] = ec.emit() circuit = low_ir.Circuit(list(modIRs.values()), ec.name) DynamicContext.clearScope() return circuit