Skip to content

Commit a69f205

Browse files
committed
Update
1 parent 13b0a3f commit a69f205

File tree

88 files changed

+2731
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

88 files changed

+2731
-0
lines changed

.DS_Store

0 Bytes
Binary file not shown.

Paper/.DS_Store

0 Bytes
Binary file not shown.
0 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

PyHCL-Tester/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .dsl import *
143 Bytes
Binary file not shown.
147 Bytes
Binary file not shown.
162 Bytes
Binary file not shown.

PyHCL-Tester/core/__init__.py

Whitespace-only changes.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
443 Bytes
Binary file not shown.
447 Bytes
Binary file not shown.
467 Bytes
Binary file not shown.

PyHCL-Tester/core/_cond.py

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
from __future__ import annotations
2+
from dataclasses import dataclass, field
3+
from typing import List
4+
5+
from pyhcl.core._emit_context import EmitterContext
6+
from pyhcl.core._repr import Declare, Node
7+
from pyhcl.ir import low_ir
8+
9+
10+
@dataclass
11+
class CondBlock(Declare):
12+
when: When = None
13+
elsewhens: List[Elsewhen] = field(init=False, default_factory=list)
14+
otherwise: Otherwise = field(init=False, default=None)
15+
16+
__canAcceptOtherwise: bool = field(init=False, default=True, repr=False)
17+
__canAcceptElsewhen: bool = field(init=False, default=True, repr=False)
18+
19+
def withElsewhen(self, elifBlock):
20+
self.elsewhens.append(elifBlock)
21+
return self
22+
23+
def withOtherwise(self, elseBlock):
24+
self.__canAcceptOtherwise = False
25+
self.__canAcceptElsewhen = False
26+
self.otherwise = elseBlock
27+
return self
28+
29+
def canAcceptElsewhen(self):
30+
return self.__canAcceptElsewhen
31+
32+
def canAcceptOtherwise(self):
33+
return self.__canAcceptOtherwise
34+
35+
def mapToIR(self, ctx: EmitterContext):
36+
def _mapToIRRec(cb: CondBlock):
37+
cond = ctx.getRef(cb.when.cond)
38+
[ctx.getRef(i) for i in cb.when.block]
39+
conseq = low_ir.Block(ctx.getScopeStatements(cb.when.ownScope))
40+
if len(cb.elsewhens) == 0:
41+
if cb.otherwise is None:
42+
alt = low_ir.EmptyStmt()
43+
else:
44+
[ctx.getRef(i) for i in cb.otherwise.block]
45+
alt = low_ir.Block(ctx.getScopeStatements(cb.otherwise.ownScope))
46+
return low_ir.Conditionally(cond, conseq, alt)
47+
else:
48+
elif_ = cb.elsewhens[0]
49+
a = When(elif_.cond, elif_.block)
50+
a.ownScope = elif_.ownScope
51+
ncb = CondBlock(a)
52+
for i in cb.elsewhens[1:]:
53+
ncb.withElsewhen(i)
54+
ncb.withOtherwise(cb.otherwise)
55+
alt = _mapToIRRec(ncb)
56+
return low_ir.Conditionally(cond, conseq, alt)
57+
58+
stmt = _mapToIRRec(self)
59+
ctx.appendFinalStatement(stmt, self.scopeId)
60+
return stmt
61+
62+
63+
@dataclass
64+
class When:
65+
cond: Node
66+
block: List[Node]
67+
ownScope: int = field(init=False, repr=False, default=None)
68+
69+
70+
@dataclass
71+
class Elsewhen:
72+
cond: Node
73+
block: List[Node]
74+
ownScope: int = field(init=False, repr=False, default=None)
75+
76+
77+
@dataclass
78+
class Otherwise:
79+
block: List[Node]
80+
ownScope: int = field(init=False, repr=False, default=None)

PyHCL-Tester/core/_dynamic_ctx.py

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
class DynamicContext:
2+
_lst = []
3+
_scopeId = [object()]
4+
_delScope = []
5+
6+
@staticmethod
7+
def push(stuff):
8+
DynamicContext._lst.append(stuff)
9+
10+
@staticmethod
11+
def pop():
12+
res = DynamicContext._lst.pop()
13+
return res
14+
15+
@staticmethod
16+
def get():
17+
res = DynamicContext._lst
18+
DynamicContext._lst = []
19+
return res
20+
21+
@staticmethod
22+
def currentScope():
23+
return id(DynamicContext._scopeId[-1])
24+
25+
@staticmethod
26+
def createScope():
27+
obj = object()
28+
DynamicContext._scopeId.append(obj)
29+
return id(obj)
30+
31+
@staticmethod
32+
def deleteScope():
33+
DynamicContext._delScope.append(DynamicContext._scopeId[-1])
34+
DynamicContext._scopeId.pop()
35+
36+
@staticmethod
37+
def clearScope():
38+
DynamicContext._scopeId.clear()
39+
DynamicContext._delScope.clear()
40+
DynamicContext._scopeId.append(object())

PyHCL-Tester/core/_emit_context.py

+114
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
from collections import deque
2+
from typing import Optional, Dict, Counter
3+
4+
from pyhcl.core._dynamic_ctx import DynamicContext
5+
from pyhcl.ir import low_ir
6+
7+
8+
class EmitterContext:
9+
def __init__(self, module: "Module",
10+
emittedModules: Dict[int, low_ir.DefModule],
11+
moduleNameCounter: Counter):
12+
13+
# generate the name
14+
modClass = module.__class__
15+
self._modClass = modClass
16+
modName = modClass.__name__
17+
c = moduleNameCounter[modName]
18+
moduleNameCounter[modName] += 1
19+
self.name = modName + (("_" + str(c)) if c > 0 else "")
20+
21+
# bunch of records
22+
self._module = module
23+
self._rawStatements = deque(modClass._statements)
24+
self._rawNameTable = modClass._rawTable
25+
self._emittedModules: Dict[int, low_ir.DefModule] = emittedModules
26+
self._moduleNameCounter = moduleNameCounter
27+
28+
self._innerRef = {}
29+
30+
self._finalStatements = {}
31+
self._finalPorts = []
32+
self._nameIndex = -1
33+
34+
def prependRawStatement(self, statement):
35+
self._rawStatements.appendleft(statement)
36+
37+
def appendFinalStatement(self, statement, scopeId):
38+
if self._finalStatements.get(scopeId) is None:
39+
self._finalStatements[scopeId] = []
40+
41+
self._finalStatements[scopeId].append(statement)
42+
43+
def getScopeStatements(self, scopeId):
44+
res = self._finalStatements[scopeId]
45+
return res
46+
47+
def appendFinalPort(self, port):
48+
self._finalPorts.append(port)
49+
50+
def updateRef(self, obj, ref):
51+
self._innerRef[id(obj)] = ref
52+
53+
def getRef(self, obj) -> Optional:
54+
from pyhcl.core._meta_pub import Pub
55+
if isinstance(obj, Pub):
56+
obj = obj.value
57+
r = self._innerRef.get(id(obj))
58+
if r is not None:
59+
return r
60+
else:
61+
ref = obj.mapToIR(self)
62+
return ref
63+
64+
def emit(self) -> Dict[int, low_ir.DefModule]:
65+
self._dealWithClockAndReset()
66+
scopeId = DynamicContext.currentScope()
67+
68+
while len(self._rawStatements) > 0:
69+
lf = self._rawStatements.popleft()
70+
lf.mapToIR(self)
71+
72+
modBundle = self._mapToBundle(self._finalPorts)
73+
finalMod = low_ir.Module(self.name,
74+
self._finalPorts,
75+
low_ir.Block(self.getScopeStatements(scopeId)),
76+
modBundle)
77+
78+
self._emittedModules[id(self._modClass)] = finalMod
79+
80+
return self._emittedModules
81+
82+
def _dealWithClockAndReset(self):
83+
c = self._modClass.clock.public()
84+
r = self._modClass.reset.public()
85+
c.mapToIR(self)
86+
r.mapToIR(self)
87+
self._finalStatements[c.scopeId] = []
88+
89+
def getName(self, obj):
90+
res = self._rawNameTable.get(id(obj))
91+
if res is not None:
92+
return res
93+
else:
94+
self._nameIndex += 1
95+
return "_T" + (("_" + str(self._nameIndex)) if self._nameIndex > 0 else "")
96+
97+
def extendNewEnv(self, module):
98+
return EmitterContext(module, self._emittedModules, self._moduleNameCounter)
99+
100+
def _mapToBundle(self, finalPorts):
101+
fs = []
102+
for i in finalPorts:
103+
if i.direction == low_ir.Input():
104+
fs.append(low_ir.Field(i.name, low_ir.Flip(), i.typ))
105+
else:
106+
fs.append(low_ir.Field(i.name, low_ir.Default(), i.typ))
107+
108+
return low_ir.BundleType(fs)
109+
110+
def getClock(self):
111+
return low_ir.Reference("clock", low_ir.ClockType())
112+
113+
def getReset(self):
114+
return low_ir.Reference("reset", low_ir.UIntType(low_ir.IntWidth(1)))

PyHCL-Tester/core/_interface.py

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from pyhcl.core._utils import get_attr
2+
3+
4+
class BundleAccessor:
5+
def provideBundle(self):
6+
from pyhcl.dsl.bundle import Bundle
7+
typ = get_attr(self, "typ")
8+
if isinstance(typ, Bundle):
9+
return True, typ
10+
else:
11+
return False, None
12+
13+
def getAttr(self, item):
14+
return get_attr(self, item)
15+
16+
def __getattribute__(self, item):
17+
res = get_attr(self, "getAttr")(item)
18+
if res is not None:
19+
return res
20+
21+
pred, bd = get_attr(self, "provideBundle")()
22+
23+
if pred:
24+
from pyhcl.core._repr import SubField
25+
sf: SubField = getattr(bd, item)
26+
sf.ref = self
27+
return sf
28+
else:
29+
return None
30+
31+
32+
class VecOps:
33+
def provideVector(self):
34+
from pyhcl.dsl.vector import Vec
35+
if isinstance(self.typ, Vec):
36+
return True, self.typ
37+
else:
38+
return False, None
39+
40+
def size(self):
41+
isVec, typ = get_attr(self, "provideVector")()
42+
if isVec:
43+
return typ.size
44+
else:
45+
raise Exception(f"${self} is not vector type")
46+
47+
def length(self):
48+
return self.size()
49+
50+
def reverse(self):
51+
from pyhcl.core._repr import ReverseView
52+
isVec, typ = get_attr(self, "provideVector")()
53+
if isVec:
54+
return ReverseView(self, typ)
55+
else:
56+
raise Exception(f"${self} is not vector type")
57+
58+
def flatten(self):
59+
from pyhcl.dsl.vector import Vec
60+
from pyhcl.core._repr import FlattenView
61+
isVec, typ = get_attr(self, "provideVector")()
62+
if isVec:
63+
l0v = typ
64+
l1v = typ.typ
65+
vt = Vec(l0v.size * l1v.size, l1v.typ)
66+
return FlattenView(self, vt, l0v.size, l1v.size)
67+
else:
68+
raise Exception(f"${self} is not vector type")
69+
70+
def __iter__(self):
71+
isVec, typ = get_attr(self, "provideVector")()
72+
if isVec:
73+
return iter([self[i] for i in range(typ.size)])
74+
75+
raise Exception(f"${self} is not vector type")
76+
77+
def __len__(self):
78+
return self.size()
79+
80+
def __reversed__(self):
81+
return self.reverse()

PyHCL-Tester/core/_meta_pub.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from pyhcl.core._repr import Node
2+
from pyhcl.core._utils import get_attr, has_attr
3+
4+
5+
class Pub(Node):
6+
"""
7+
A Tag Class For Showing The Visibility Of Module's Fields
8+
"""
9+
10+
def __init__(self, value):
11+
self.value = value
12+
self.typ = value.typ
13+
14+
def __repr__(self):
15+
value = get_attr(self, "value")
16+
return "Pub(" + str(value) + ")"
17+
18+
def __getattribute__(self, item):
19+
if has_attr(self, item):
20+
return get_attr(self, item)
21+
else:
22+
return getattr(self.public(), item)
23+
24+
def extractForName(self):
25+
return get_attr(self, "value")
26+
27+
def public(self):
28+
return get_attr(self, "value")
29+
30+
def mapToIR(self, ctx):
31+
return self.value.mapToIR(ctx)
32+
33+
34+
class MetaPub(type):
35+
def __call__(cls, *args, **kwargs):
36+
# unwrap
37+
func = lambda x: get_attr(x, 'value') if isinstance(x, Pub) else x
38+
39+
nArgs = [func(i) for i in args]
40+
nKwargs = {k: func(v) for k, v in kwargs.items()}
41+
obj = type.__call__(cls, *nArgs, **nKwargs)
42+
43+
# rewrap
44+
return Pub(obj)

0 commit comments

Comments
 (0)