def visit_ResExpr(self, node): if isinstance(node.val, tuple): res = [] for op in reversed(node.val): res_op = ir.ResExpr(op) if res_op != ir.ResExpr(Unit()) and res_op.dtype != Uint[0]: svexpr = self.visit(res_op) res.append(self.cast_svexpr(svexpr, res_op.dtype, type(op))) if not res: return None return '{' + ', '.join(res) + '}' if getattr(node.val, 'unknown', False): return f"{node.dtype.width}'bx" val = node.val if isinstance(node.val, ir.EmptyType): if node.dtype is None: return f"'x" else: return f"{node.dtype.width}'bx" elif not isinstance(node.val, Integer): val = Integer(code(node.val, int)) sign = '-' if val < 0 else '' return f"{sign}{val.width}'d{abs(int(val))}"
def visit_ConcatExpr(self, node): svexprs = [] for op in reversed(node.operands): if op == ir.ResExpr(Unit()): continue sv = self.visit(op) if sv is None: continue svexprs.append(str(sv)) if svexprs: return '{' + ', '.join(svexprs) + '}' return None
def test_ResExpr(): e1 = ir.ResExpr(Bool(True)) e2 = ir.ResExpr(e1) assert e2 is e1
def test_raw_data_types(): code = ast.parse("Uint[8]").body[0] ctx = Context() ctx.local_namespace['Uint'] = Uint assert visit_ast(code, ctx) == ir.ResExpr(Uint[8])
def _assign_value(self, target, val): if isinstance(target, ir.SubscriptExpr): base_target = target.val elif isinstance(target, ir.Name): base_target = target elif isinstance(target, ir.Component): base_target = target.val elif isinstance(target, ir.ConcatExpr): for i, t in enumerate(target.operands): self._assign_value(t, ir.SubscriptExpr(val, ir.ResExpr(i))) return else: raise Exception if is_reg_id(base_target): if not self.selected(base_target): return name = self.svexpr(target, self.aux_funcs) val = self.svexpr(val, self.aux_funcs) if val is None: return svstmt = f"{name} = {val}" # if this is only partial assignement, the order of assignment then # matters and this cannot be a default if isinstance(target, ir.SubscriptExpr): self.write(svstmt) else: self.handle_defaults(name, svstmt) if name == '_state_next': self.handle_defaults("_state_en", "_state_en = 1") return if target.dtype is OutSig: if self.selected(target): name = target.obj.val.name svval = self.svexpr(val, self.aux_funcs) svstmt = f"{name} = {svval}" self.handle_defaults(name, svstmt) return elif isinstance(target, ir.Component): name = self.svexpr(base_target, self.aux_funcs) if target.field == 'data': if self.selected(base_target): self.handle_defaults(self.attr(name, 'valid'), f"{self.attr(name, 'valid')} = 1") val = self.svexpr(val, self.aux_funcs) if val is not None: svstmt = f"{name}_s = {val}" self.handle_defaults(name, svstmt) elif target.field == 'ready' and self.selected(base_target): self.handle_defaults(self.attr(name, 'ready'), f"{self.attr(name, 'ready')} = 1") return elif is_intf_id(target): if is_intf_id(val) and self.selected(val): name = self.svexpr(base_target, self.aux_funcs) val_name = self.svexpr(val, self.aux_funcs) svstmt = f"{name}_s = {val_name}_s" self.handle_defaults(name, svstmt) self.write(f"{self.attr(name, 'valid')} = {self.attr(val_name, 'valid')}") self.write(f"{self.attr(val_name, 'ready')} = {self.attr(name, 'ready')}") return if not self.selected(base_target): return if val.dtype is None: return target = self.svexpr(target, self.aux_funcs) if target is None: return val = self.svexpr(val, self.aux_funcs) if val is None: return svstmt = f"{target} = {val}" self.handle_defaults(target, svstmt)
def line(self, line=''): if not line: self.lines.append('') else: self.lines.append(f'{" "*self.indent}{line}') def block(self, block): for line in block.split('\n'): self.line(line) def __str__(self): return '\n'.join(self.lines) res_true = ir.ResExpr(Bool(True)) @dataclass class BlockLines: header: List = field(default_factory=list) content: List = field(default_factory=list) footer: List = field(default_factory=list) def is_reg_id(expr): return (isinstance(expr, ir.Name) and isinstance(expr.obj, ir.Variable) and expr.obj.reg) class SVCompiler(HDLVisitor): def __init__(self, ctx, var, writer, selected, lang, aux_funcs=None):
def _assign_value(self, target, val): if isinstance(target, ir.SubscriptExpr): base_target = target.val elif isinstance(target, ir.Name): base_target = target elif isinstance(target, ir.Component): base_target = target.val elif isinstance(target, ir.ConcatExpr): for i, t in enumerate(target.operands): self._assign_value(t, ir.SubscriptExpr(val, ir.ResExpr(i))) return else: raise Exception if is_reg_id(base_target): if not self.selected(base_target): return name = self.svexpr(target, self.aux_funcs) val = self.svexpr(val, self.aux_funcs) if val is None: return svstmt = f"{name} = {val}" self.handle_defaults(name, svstmt) self.write(f"{base_target.name}_en = 1") return if target.dtype is OutSig: if self.selected(target): name = target.obj.val.name svval = self.svexpr(val, self.aux_funcs) svstmt = f"{name} = {svval}" self.handle_defaults(name, svstmt) return elif is_intf_id(target): name = self.svexpr(target, self.aux_funcs) if target.ctx == 'store': if self.selected(target): if is_intf_id(val): val_name = self.svexpr(val, self.aux_funcs) svstmt = f"{name}_s = {val_name}_s" self.handle_defaults(name, svstmt) self.write( f"{self.attr(name, 'valid')} = {self.attr(val_name, 'valid')}" ) elif val == ir.ResExpr(None): self.handle_defaults( self.attr(name, 'valid'), f"{self.attr(name, 'valid')} = 0") else: self.handle_defaults( self.attr(name, 'valid'), f"{self.attr(name, 'valid')} = 1") val = self.svexpr(val, self.aux_funcs) if val is not None: svstmt = f"{name}_s = {val}" self.handle_defaults(name, svstmt) if is_intf_id(val) and self.selected(val): val_name = self.svexpr(val, self.aux_funcs) self.write( f"{self.attr(val_name, 'ready')} = {self.attr(name, 'ready')}" ) elif target.ctx == 'ready': self.handle_defaults(self.attr(name, 'ready'), f"{self.attr(name, 'ready')} = 1") return if not self.selected(base_target): return if val.dtype is None: return target = self.svexpr(target, self.aux_funcs) if target is None: return val = self.svexpr(val, self.aux_funcs) if val is None: return svstmt = f"{target} = {val}" self.handle_defaults(target, svstmt)