1 from migen
.fhdl
.structure
import *
2 from migen
.fhdl
.module
import Module
3 from migen
.fhdl
.tools
import insert_reset
, rename_clock_domain
6 __all__
= ["CEInserter", "ResetInserter", "ClockDomainsRenamer",
10 class ModuleTransformer
:
11 # overload this in derived classes
12 def transform_instance(self
, i
):
15 # overload this in derived classes
16 def transform_fragment(self
, i
, f
):
19 def wrap_class(self
, victim
):
20 class Wrapped(victim
):
21 def __init__(i
, *args
, **kwargs
):
22 victim
.__init
__(i
, *args
, **kwargs
)
23 self
.transform_instance(i
)
26 f
= victim
.get_fragment(i
)
27 self
.transform_fragment(i
, f
)
30 Wrapped
.__name
__ = victim
.__name
__
31 # "{}_{}".format(self.__class__.__name__, victim.__name__)
34 def wrap_instance(self
, victim
):
35 self
.transform_instance(victim
)
36 orig_get_fragment
= victim
.get_fragment
39 f
= orig_get_fragment()
40 self
.transform_fragment(victim
, f
)
43 victim
.get_fragment
= get_fragment
46 def __call__(self
, victim
):
47 if isinstance(victim
, Module
):
48 return self
.wrap_instance(victim
)
50 return self
.wrap_class(victim
)
53 class ControlInserter(ModuleTransformer
):
54 control_name
= None # override this
56 def __init__(self
, clock_domains
=None):
57 self
.clock_domains
= clock_domains
59 def transform_instance(self
, i
):
60 if self
.clock_domains
is None:
61 ctl
= Signal(name
=self
.control_name
)
62 assert not hasattr(i
, self
.control_name
)
63 setattr(i
, self
.control_name
, ctl
)
65 for cd
in self
.clock_domains
:
66 name
= self
.control_name
+ "_" + cd
67 ctl
= Signal(name
=name
)
68 assert not hasattr(i
, name
)
71 def transform_fragment(self
, i
, f
):
72 if self
.clock_domains
is None:
74 raise ValueError("Control signal clock domains must be specified when module has more than one domain")
75 cdn
= list(f
.sync
.keys())[0]
76 to_insert
= [(getattr(i
, self
.control_name
), cdn
)]
78 to_insert
= [(getattr(i
, self
.control_name
+ "_" + cdn
), cdn
)
79 for cdn
in self
.clock_domains
]
80 self
.transform_fragment_insert(i
, f
, to_insert
)
83 class CEInserter(ControlInserter
):
86 def transform_fragment_insert(self
, i
, f
, to_insert
):
87 for ce
, cdn
in to_insert
:
88 f
.sync
[cdn
] = [If(ce
, *f
.sync
[cdn
])]
91 class ResetInserter(ControlInserter
):
92 control_name
= "reset"
94 def transform_fragment_insert(self
, i
, f
, to_insert
):
95 for reset
, cdn
in to_insert
:
96 f
.sync
[cdn
] = insert_reset(reset
, f
.sync
[cdn
])
99 class ClockDomainsRenamer(ModuleTransformer
):
100 def __init__(self
, cd_remapping
):
101 if isinstance(cd_remapping
, str):
102 cd_remapping
= {"sys": cd_remapping
}
103 self
.cd_remapping
= cd_remapping
105 def transform_fragment(self
, i
, f
):
106 for old
, new
in self
.cd_remapping
.items():
107 rename_clock_domain(f
, old
, new
)