Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 2 files changed
  • 0 comments
  • 1 contributor
18  migen/fhdl/module.py
@@ -67,11 +67,11 @@ def __iadd__(self, other):
67 67
 
68 68
 class _ModuleSubmodules(_ModuleProxy):
69 69
 	def __setattr__(self, name, value):
70  
-		self._fm._submodules += [(name, e) for e in _flat_list(value)]
  70
+		self._fm._submodules += [(name, e, dict()) for e in _flat_list(value)]
71 71
 		setattr(self._fm, name, value)
72 72
 	
73 73
 	def __iadd__(self, other):
74  
-		self._fm._submodules += [(None, e) for e in _flat_list(other)]
  74
+		self._fm._submodules += [(None, e, dict()) for e in _flat_list(other)]
75 75
 		return self
76 76
 
77 77
 class _ModuleClockDomains(_ModuleProxy, _ModuleForwardAttr):
@@ -130,8 +130,20 @@ def __setattr__(self, name, value):
130 130
 		else:
131 131
 			object.__setattr__(self, name, value)
132 132
 
  133
+	def add_submodule(self, submodule, cd_remapping=dict(), name=None):
  134
+		if isinstance(cd_remapping, str):
  135
+			cd_remapping = {"sys": cd_remapping}
  136
+		if name is not None:
  137
+			setattr(self, name, submodule)
  138
+		self._submodules.append((name, submodule, cd_remapping))
  139
+
133 140
 	def _collect_submodules(self):
134  
-		r = [(name, submodule.get_fragment()) for name, submodule in self._submodules]
  141
+		r = []
  142
+		for name, submodule, cd_remapping in self._submodules:
  143
+			f = submodule.get_fragment()
  144
+			for old, new in cd_remapping.items():
  145
+				rename_clock_domain(f, old, new)
  146
+			r.append((name, f))
135 147
 		self._submodules = []
136 148
 		return r
137 149
 
64  migen/genlib/fifo.py
... ...
@@ -0,0 +1,64 @@
  1
+from migen.fhdl.structure import *
  2
+from migen.fhdl.specials import Memory
  3
+from migen.fhdl.module import Module
  4
+
  5
+def _inc(signal, modulo):
  6
+	if modulo == 2**len(signal):
  7
+		return signal.eq(signal + 1)
  8
+	else:
  9
+		return If(signal == (modulo - 1),
  10
+			signal.eq(0)
  11
+		).Else(
  12
+			signal.eq(signal + 1)
  13
+		)
  14
+
  15
+class SyncFIFO(Module):
  16
+	def __init__(self, width, depth):
  17
+		self.din = Signal(width)
  18
+		self.we = Signal()
  19
+		self.writable = Signal() # not full
  20
+		self.dout = Signal(width)
  21
+		self.re = Signal()
  22
+		self.readable = Signal() # not empty
  23
+
  24
+		###
  25
+
  26
+		do_write = Signal()
  27
+		do_read = Signal()
  28
+		self.comb += [
  29
+			do_write.eq(self.writable & self.we),
  30
+			do_read.eq(self.readable & self.re)
  31
+		]
  32
+
  33
+		level = Signal(max=depth+1)
  34
+		produce = Signal(max=depth)
  35
+		consume = Signal(max=depth)
  36
+		storage = Memory(width, depth)
  37
+		self.specials += storage
  38
+
  39
+		wrport = storage.get_port(write_capable=True)
  40
+		self.comb += [
  41
+			wrport.adr.eq(produce),
  42
+			wrport.dat_w.eq(self.din),
  43
+			wrport.we.eq(do_write)
  44
+		]
  45
+		self.sync += If(do_write, _inc(produce, depth))
  46
+
  47
+		rdport = storage.get_port(async_read=True)
  48
+		self.comb += [
  49
+			rdport.adr.eq(consume),
  50
+			self.dout.eq(rdport.dat_r)
  51
+		]
  52
+		self.sync += If(do_read, _inc(consume, depth))
  53
+
  54
+		self.sync += [
  55
+			If(do_write,
  56
+				If(~do_read, level.eq(level + 1))
  57
+			).Elif(do_read,
  58
+				level.eq(level - 1)
  59
+			)
  60
+		]
  61
+		self.comb += [
  62
+			self.writable.eq(level != depth),
  63
+			self.readable.eq(level != 0)
  64
+		]

No commit comments for this range

Something went wrong with that request. Please try again.