|
|
|
@ -6,7 +6,7 @@ from typing import List, Optional
|
|
|
|
|
|
|
|
|
|
from pyhcl.ir.low_node import FirrtlNode
|
|
|
|
|
from pyhcl.ir.low_prim import PrimOp, Bits
|
|
|
|
|
from pyhcl.ir.utils import indent
|
|
|
|
|
from pyhcl.ir.utils import backspace, indent
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Info(FirrtlNode, ABC):
|
|
|
|
@ -16,12 +16,18 @@ class Info(FirrtlNode, ABC):
|
|
|
|
|
"""default implementation"""
|
|
|
|
|
return self.__repr__()
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return self.__repr__()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True, init=False)
|
|
|
|
|
class NoInfo(Info):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return ''
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return ''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class FileInfo(Info):
|
|
|
|
@ -30,6 +36,9 @@ class FileInfo(Info):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f" @[{self.info.serialize()}]"
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f" /*[{self.info.verilog_serialize()}]*/"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class StringLit(FirrtlNode):
|
|
|
|
@ -42,6 +51,9 @@ class StringLit(FirrtlNode):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return self.escape()[1:-1]
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return self.serialize()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Expression(FirrtlNode, ABC):
|
|
|
|
|
"""EXPRESSIONs"""
|
|
|
|
@ -58,6 +70,9 @@ class UnknownType(Type):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return '?'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return self.serialize()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Reference(Expression):
|
|
|
|
@ -67,6 +82,9 @@ class Reference(Expression):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return self.name
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return self.serialize()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class SubField(Expression):
|
|
|
|
@ -77,6 +95,9 @@ class SubField(Expression):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f"{self.expr.serialize()}.{self.name}"
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f"{self.expr.verilog_serialize()}_{self.name}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class SubIndex(Expression):
|
|
|
|
@ -87,6 +108,9 @@ class SubIndex(Expression):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f"{self.expr.serialize()}[{self.value}]"
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f"{self.expr.verilog_serialize()}[{self.value}]"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class SubAccess(Expression):
|
|
|
|
@ -97,6 +121,9 @@ class SubAccess(Expression):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f"{self.expr.serialize()}[{self.index.serialize()}]"
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f"{self.expr.verilog_serialize()}[{self.index.verilog_serialize()}]"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Mux(Expression):
|
|
|
|
@ -108,6 +135,9 @@ class Mux(Expression):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f"mux({self.cond.serialize()}, {self.tval.serialize()}, {self.fval.serialize()})"
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f"{self.cond.serialize()} ? {self.tval.serialize()} : {self.fval.serialize()}"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class DoPrim(Expression):
|
|
|
|
@ -120,6 +150,10 @@ class DoPrim(Expression):
|
|
|
|
|
sl: List[str] = [arg.serialize() for arg in self.args] + [repr(con) for con in self.consts]
|
|
|
|
|
return f'{self.op.serialize()}({", ".join(sl)})'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
sl: List[str] = [arg.serialize() for arg in self.args] + [repr(con) for con in self.consts]
|
|
|
|
|
return f'{self.op.serialize().join(sl)}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Width(FirrtlNode, ABC):
|
|
|
|
@ -133,6 +167,9 @@ class IntWidth(Width):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'<{self.width}>'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'[{self.width-1}:0]' if self.width - 1 else ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True, init=False)
|
|
|
|
|
class UnknownWidth(Width):
|
|
|
|
@ -141,6 +178,9 @@ class UnknownWidth(Width):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True, init=False)
|
|
|
|
|
class UIntLiteral(Expression):
|
|
|
|
@ -159,6 +199,9 @@ class UIntLiteral(Expression):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'UInt{self.width.serialize()}("h{hex(self.value)[2:]}")'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'{self.width}\'h{hex(self.value)}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True, init=False)
|
|
|
|
|
class SIntLiteral(Expression):
|
|
|
|
@ -177,6 +220,9 @@ class SIntLiteral(Expression):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'SInt{self.width.serialize()}("h{hex(self.value)[2:]}")'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'{self.width}\'h{hex(self.value)}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class GroundType(Type, ABC):
|
|
|
|
|
...
|
|
|
|
@ -193,6 +239,9 @@ class UIntType(GroundType):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'UInt{self.width.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'{self.width.verilog_serialize()}'
|
|
|
|
|
|
|
|
|
|
def irWithIndex(self, index):
|
|
|
|
|
if isinstance(index, slice):
|
|
|
|
|
length = index.start - index.stop + 1
|
|
|
|
@ -219,6 +268,9 @@ class SIntType(GroundType):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'SInt{self.width.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'{self.width.serialize()}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Orientation(FirrtlNode, ABC):
|
|
|
|
|
"""# Orientation of [[Field]]"""
|
|
|
|
@ -230,12 +282,18 @@ class Default(Orientation):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return ''
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return ''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True, init=False)
|
|
|
|
|
class Flip(Orientation):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return 'flip '
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return 'flip'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Field(FirrtlNode):
|
|
|
|
@ -247,6 +305,9 @@ class Field(FirrtlNode):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'{self.flip.serialize()}{self.name} : {self.typ.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'{self.flip.verilog_serialize()}{self.typ.verilog_serialize()}\t${self.name}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class BundleType(AggregateType):
|
|
|
|
@ -255,6 +316,16 @@ class BundleType(AggregateType):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return '{' + ', '.join([f.serialize() for f in self.fields]) + '}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> list:
|
|
|
|
|
field_list = []
|
|
|
|
|
for f in self.fields:
|
|
|
|
|
if type(f.typ.verilog_serialize()) is list:
|
|
|
|
|
for t in f.typ.verilog_serialize():
|
|
|
|
|
field_list.append(f'${f.name}{t}')
|
|
|
|
|
else:
|
|
|
|
|
field_list.append(f.verilog_serialize())
|
|
|
|
|
return field_list
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class VectorType(AggregateType):
|
|
|
|
@ -264,6 +335,9 @@ class VectorType(AggregateType):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'{self.typ.serialize()}[{self.size}]'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> list:
|
|
|
|
|
return [f'_{v}' for v in range(self.size)]
|
|
|
|
|
|
|
|
|
|
def irWithIndex(self, index):
|
|
|
|
|
if isinstance(index, int):
|
|
|
|
|
return lambda _: {"ir": SubIndex(_, index, self.typ)}
|
|
|
|
@ -279,6 +353,9 @@ class MemoryType(AggregateType):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'{self.typ.serialize()}[{self.size}]'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return [f'_{v}' for v in range(self.size)]
|
|
|
|
|
|
|
|
|
|
def irWithIndex(self, index):
|
|
|
|
|
return lambda _: {"ir": lambda name, mem, clk, rw: DefMemPort(name, mem, index, clk, rw), "inPort": True}
|
|
|
|
|
|
|
|
|
@ -290,6 +367,32 @@ class ClockType(GroundType):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return 'Clock'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
# Todo
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True, init=False)
|
|
|
|
|
class ResetType(GroundType):
|
|
|
|
|
width: Width = IntWidth(1)
|
|
|
|
|
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return "UInt<1>"
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
# Todo
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True, init=False)
|
|
|
|
|
class AsyncResetType(GroundType):
|
|
|
|
|
width: Width = IntWidth(1)
|
|
|
|
|
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return "AsyncReset"
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
# Todo
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Direction(FirrtlNode, ABC):
|
|
|
|
|
"""[[Port]] Direction"""
|
|
|
|
@ -301,12 +404,22 @@ class Input(Direction):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return 'input'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self, flip = False) -> str:
|
|
|
|
|
if flip is True:
|
|
|
|
|
return 'output'
|
|
|
|
|
return 'input'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True, init=False)
|
|
|
|
|
class Output(Direction):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return 'output'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self, flip = False) -> str:
|
|
|
|
|
if flip is True:
|
|
|
|
|
return 'input'
|
|
|
|
|
return 'output'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# [[DefModule]] Port
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
@ -319,6 +432,22 @@ class Port(FirrtlNode):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'{self.direction.serialize()} {self.name} : {self.typ.serialize()}{self.info.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
if type(self.typ.verilog_serialize()) is str:
|
|
|
|
|
return f'{self.direction.verilog_serialize()}\t{self.typ.verilog_serialize()}\t{self.name},\n'
|
|
|
|
|
else:
|
|
|
|
|
portdeclares = ''
|
|
|
|
|
seq = self.typ.verilog_serialize()
|
|
|
|
|
for s in seq:
|
|
|
|
|
ns = s.replace('$', f'{self.name}_')
|
|
|
|
|
if "flip" in ns:
|
|
|
|
|
ns = ns.replace('flip', "")
|
|
|
|
|
portdeclares += f'{self.direction.verilog_serialize(True)}\t{ns},\n'
|
|
|
|
|
else:
|
|
|
|
|
portdeclares += f'{self.direction.verilog_serialize()}\t{ns},\n'
|
|
|
|
|
return portdeclares
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Statement(FirrtlNode, ABC):
|
|
|
|
|
...
|
|
|
|
@ -329,6 +458,9 @@ class EmptyStmt(Statement):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return 'skip'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return '// skip'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class DefWire(Statement):
|
|
|
|
@ -339,6 +471,8 @@ class DefWire(Statement):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'wire {self.name} : {self.typ.serialize()}{self.info.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'wire\t{self.typ.verilog_serialize()}\t{self.name}{self.info.verilog_serialize()};'
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class DefRegister(Statement):
|
|
|
|
@ -354,16 +488,26 @@ class DefRegister(Statement):
|
|
|
|
|
if self.init is not None else ""
|
|
|
|
|
return f'reg {self.name} : {self.typ.serialize()}, {self.clock.serialize()}{i}{self.info.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'reg {self.typ.verilog_serialize()}\t{self.name}{self.info.verilog_serialize()}'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class DefInstance(Statement):
|
|
|
|
|
name: str
|
|
|
|
|
module: str
|
|
|
|
|
ports: List[Port]
|
|
|
|
|
info: Info = NoInfo()
|
|
|
|
|
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'inst {self.name} of {self.module}{self.info.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
instdeclares = ''
|
|
|
|
|
for p in self.ports:
|
|
|
|
|
instdeclares += f'\n.{p.name}({self.name}_{p.name}),'
|
|
|
|
|
return f'{self.module} {self.name} ({instdeclares}\n);'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# @dataclass(frozen=True)
|
|
|
|
|
# class DefMemory(Statement):
|
|
|
|
@ -399,6 +543,12 @@ class DefMemory(Statement):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'cmem {self.name} : {self.memType.serialize()}{self.info.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
memorydeclares = ''
|
|
|
|
|
memorydeclares += f'{self.memType.verilog_serialize()}\n'
|
|
|
|
|
memorydeclares += f'{self.info.verilog_serialize()}\n'
|
|
|
|
|
return memorydeclares
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class DefNode(Statement):
|
|
|
|
@ -409,6 +559,9 @@ class DefNode(Statement):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'node {self.name} = {self.value.serialize()}{self.info.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'wire {self.name} = {self.value.verilog_serialize()}{self.info.verilog_serialize()};'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class DefMemPort(Statement):
|
|
|
|
@ -424,6 +577,12 @@ class DefMemPort(Statement):
|
|
|
|
|
return f'{rw} mport {self.name} = {self.mem.serialize()}[{self.index.serialize()}], ' \
|
|
|
|
|
f'{self.clk.serialize()}{self.info.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
memportdeclares = ''
|
|
|
|
|
memportdeclares += indent(f'{self.mem.verilog_serialize()}')
|
|
|
|
|
# TODO
|
|
|
|
|
return memportdeclares
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Conditionally(Statement):
|
|
|
|
@ -437,6 +596,9 @@ class Conditionally(Statement):
|
|
|
|
|
('' if self.alt == EmptyStmt() else '\nelse :' + indent(f'\n{self.alt.serialize()}'))
|
|
|
|
|
return f'when {self.pred.serialize()} :{self.info.serialize()}{s}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Block(Statement):
|
|
|
|
@ -445,6 +607,9 @@ class Block(Statement):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return '\n'.join([stmt.serialize() for stmt in self.stmts])
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return '\n'.join([stmt.verilog_serialize() for stmt in self.stmts])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Connect(Statement):
|
|
|
|
@ -455,6 +620,9 @@ class Connect(Statement):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'{self.loc.serialize()} <= {self.expr.serialize()}{self.info.serialize()}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'assign {self.loc.verilog_serialize()} = {self.expr.verilog_serialize()}{self.info.verilog_serialize()};'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Verification
|
|
|
|
|
class Verification(FirrtlNode, ABC):
|
|
|
|
@ -471,6 +639,9 @@ class Assert(Verification):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'assert({self.clk.serialize()}, {self.pred.serialize()}, {self.en.serialize()}, \"{self.msg}\")\n'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Assume(Verification):
|
|
|
|
@ -482,6 +653,9 @@ class Assume(Verification):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'assert({self.clk.serialize()}, {self.pred.serialize()}, {self.en.serialize()},{self.msg})\n'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class Cover(Verification):
|
|
|
|
@ -493,12 +667,19 @@ class Cover(Verification):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return f'assert({self.clk.serialize()}, {self.pred.serialize()}, {self.en.serialize()},{self.msg})\n'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return ""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Base class for modules
|
|
|
|
|
class DefModule(FirrtlNode, ABC):
|
|
|
|
|
def serializeHeader(self, typ: str) -> str:
|
|
|
|
|
ps = indent(''.join([f'\n{p.serialize()}' for p in self.ports]))
|
|
|
|
|
return f'{typ} {self.name} :{self.info.serialize()}{ps}\n'
|
|
|
|
|
moduledeclares = indent(''.join([f'\n{p.serialize()}' for p in self.ports]))
|
|
|
|
|
return f'{typ} {self.name} :{self.info.serialize()}{moduledeclares}\n'
|
|
|
|
|
|
|
|
|
|
def verilog_serializeHeader(self, typ:str) -> str:
|
|
|
|
|
moduledeclares = ''.join([f'{p.verilog_serialize()}' for p in self.ports])
|
|
|
|
|
return f'{typ} {self.name}(\n{moduledeclares});\n'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
@ -512,6 +693,8 @@ class Module(DefModule):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
return self.serializeHeader('module') + indent(f'\n{self.body.serialize()}')
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return self.verilog_serializeHeader('module') + f'\n{self.body.verilog_serialize()}' + '\nendmodule'
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
class ExtModule(DefModule):
|
|
|
|
@ -525,6 +708,9 @@ class ExtModule(DefModule):
|
|
|
|
|
s = indent(f'\ndefname = {self.defname}\n')
|
|
|
|
|
return f'{self.serializeHeader("extmodule")}{s}'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
return f'{self.verilog_serializeHeader("module")}endmodule\n'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
@ -536,3 +722,7 @@ class Circuit(FirrtlNode):
|
|
|
|
|
def serialize(self) -> str:
|
|
|
|
|
ms = '\n'.join([indent(f'\n{m.serialize()}') for m in self.modules])
|
|
|
|
|
return f'circuit {self.main} :{self.info.serialize()}{ms}\n'
|
|
|
|
|
|
|
|
|
|
def verilog_serialize(self) -> str:
|
|
|
|
|
ms = ''.join([f'{m.verilog_serialize()}\n' for m in self.modules])
|
|
|
|
|
return ms
|
|
|
|
|