Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 3 files changed
  • 0 comments
  • 1 contributor
12  examples/basic/two_dividers.py
@@ -2,14 +2,16 @@
2 2
 from migen.fhdl import verilog
3 3
 from migen.genlib import divider
4 4
 
  5
+@DecorateModule(InsertReset)
  6
+@DecorateModule(InsertCE)
5 7
 class Example(Module):
6  
-	def __init__(self):
7  
-		d1 = divider.Divider(16)
8  
-		d2 = divider.Divider(16)
  8
+	def __init__(self, width):
  9
+		d1 = divider.Divider(width)
  10
+		d2 = divider.Divider(width)
9 11
 		self.submodules += d1, d2
10 12
 		self.ios = {
11 13
 			d1.ready_o, d1.quotient_o, d1.remainder_o, d1.start_i, d1.dividend_i, d1.divisor_i,
12 14
 			d2.ready_o, d2.quotient_o, d2.remainder_o, d2.start_i, d2.dividend_i, d2.divisor_i}
13 15
 
14  
-example = Example()
15  
-print(verilog.convert(example, example.ios))
  16
+example = Example(16)
  17
+print(verilog.convert(example, example.ios | {example.ce, example.reset}))
80  migen/fhdl/decorators.py
... ...
@@ -0,0 +1,80 @@
  1
+from migen.fhdl.structure import *
  2
+from migen.fhdl.tools import insert_reset
  3
+
  4
+class ModuleDecorator:
  5
+	def __init__(self, decorated):
  6
+		object.__setattr__(self, "_md_decorated", decorated)
  7
+
  8
+	def __getattr__(self, name):
  9
+		return getattr(self._md_decorated, name)
  10
+
  11
+	def __setattr__(self, name, value):
  12
+		return setattr(self._md_decorated, name, value)
  13
+
  14
+	# overload this in derived classes
  15
+	def transform_fragment(self, f):
  16
+		pass
  17
+
  18
+	def get_fragment(self):
  19
+		f = self._md_decorated.get_fragment()
  20
+		self.transform_fragment(f)
  21
+		return f
  22
+
  23
+class DecorateModule:
  24
+	def __init__(self, decorator, *dec_args, **dec_kwargs):
  25
+		self.decorator = decorator
  26
+		self.dec_args = dec_args
  27
+		self.dec_kwargs = dec_kwargs
  28
+
  29
+	def __call__(self, decorated):
  30
+		def dfinit(dfself, *args, **kwargs):
  31
+			self.decorator.__init__(dfself, decorated(*args, **kwargs),
  32
+				*self.dec_args, **self.dec_kwargs)
  33
+		typename = self.decorator.__name__ + "(" + decorated.__name__ + ")"
  34
+		return type(typename, (self.decorator,), dict(__init__=dfinit))
  35
+
  36
+class InsertControl(ModuleDecorator):
  37
+	def __init__(self, control_name, decorated, clock_domains=None):
  38
+		ModuleDecorator.__init__(self, decorated)
  39
+
  40
+		object.__setattr__(self, "_ic_control_name", control_name)
  41
+		object.__setattr__(self, "_ic_clock_domains", clock_domains)
  42
+		
  43
+		if clock_domains is None:
  44
+			ctl = Signal(name=control_name)
  45
+			assert(not hasattr(decorated, control_name))
  46
+			object.__setattr__(self, control_name, ctl)
  47
+		else:
  48
+			for cd in clock_domains:
  49
+				name = control_name + "_" + cd
  50
+				ctl = Signal(name=name)
  51
+				assert(not hasattr(decorated, name))
  52
+				object.__setattr__(self, name, ctl)
  53
+
  54
+	def transform_fragment(self, f):
  55
+		control_name = self._ic_control_name
  56
+		clock_domains = self._ic_clock_domains
  57
+		if clock_domains is None:
  58
+			if len(f.sync) != 1:
  59
+				raise ValueError("Control signal clock domains must be specified when module has more than one domain")
  60
+			cdn = list(f.sync.keys())[0]
  61
+			to_insert = [(getattr(self, control_name), cdn)]
  62
+		else:
  63
+			to_insert = [(getattr(self, control_name+"_"+cdn), cdn) for cdn in clock_domains]
  64
+		self.transform_fragment_insert(f, to_insert)
  65
+
  66
+class InsertCE(InsertControl):
  67
+	def __init__(self, *args, **kwargs):
  68
+		InsertControl.__init__(self, "ce", *args, **kwargs)
  69
+		
  70
+	def transform_fragment_insert(self, f, to_insert):
  71
+		for ce, cdn in to_insert:
  72
+			f.sync[cdn] = [If(ce, *f.sync[cdn])]
  73
+
  74
+class InsertReset(InsertControl):
  75
+	def __init__(self, *args, **kwargs):
  76
+		InsertControl.__init__(self, "reset", *args, **kwargs)
  77
+
  78
+	def transform_fragment_insert(self, f, to_insert):
  79
+		for reset, cdn in to_insert:
  80
+			f.sync[cdn] = insert_reset(reset, f.sync[cdn])
1  migen/fhdl/std.py
@@ -2,3 +2,4 @@
2 2
 from migen.fhdl.module import Module
3 3
 from migen.fhdl.specials import TSTriple, Instance, Memory
4 4
 from migen.fhdl.size import log2_int, bits_for, flen
  5
+from migen.fhdl.decorators import DecorateModule, InsertCE, InsertReset

No commit comments for this range

Something went wrong with that request. Please try again.