Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 2 commits
  • 10 files changed
  • 0 comments
  • 1 contributor
11  examples/basic/simple_gpio.py
@@ -3,12 +3,11 @@
3 3
 from migen.fhdl import verilog
4 4
 from migen.genlib.cdc import MultiReg
5 5
 from migen.bank import description, csrgen
6  
-from migen.bank.description import READ_ONLY, WRITE_ONLY
7 6
 
8 7
 class Example(Module):
9 8
 	def __init__(self, ninputs=32, noutputs=32):
10  
-		r_o = description.RegisterField(noutputs, atomic_write=True)
11  
-		r_i = description.RegisterField(ninputs, READ_ONLY, WRITE_ONLY)
  9
+		r_o = description.CSRStorage(noutputs, atomic_write=True)
  10
+		r_i = description.CSRStatus(ninputs)
12 11
 
13 12
 		self.submodules.bank = csrgen.Bank([r_o, r_i])
14 13
 		self.gpio_in = Signal(ninputs)
@@ -17,10 +16,10 @@ def __init__(self, ninputs=32, noutputs=32):
17 16
 		###
18 17
 
19 18
 		gpio_in_s = Signal(ninputs)
20  
-		self.specials += MultiReg(self.gpio_in, gpio_in_s, "sys")
  19
+		self.specials += MultiReg(self.gpio_in, gpio_in_s)
21 20
 		self.comb += [
22  
-			r_i.field.w.eq(gpio_in_s),
23  
-			self.gpio_out.eq(r_o.field.r)
  21
+			self.gpio_out.eq(r_o.storage),
  22
+			r_i.status.eq(gpio_in_s)
24 23
 		]
25 24
 
26 25
 example = Example()
61  migen/actorlib/spi.py
@@ -18,16 +18,16 @@ def _convert_layout(layout):
18 18
 			r.append((element[0], element[1]))
19 19
 	return r
20 20
 
21  
-def _create_registers_assign(layout, target, atomic, prefix=""):
22  
-	registers = []
  21
+def _create_csrs_assign(layout, target, atomic, prefix=""):
  22
+	csrs = []
23 23
 	assigns = []
24 24
 	for element in layout:
25 25
 		if isinstance(element[1], list):
26  
-			r_registers, r_assigns = _create_registers_assign(element[1],
  26
+			r_csrs, r_assigns = _create_csrs_assign(element[1],
27 27
 				atomic,
28 28
 				getattr(target, element[0]),
29 29
 				element[0] + "_")
30  
-			registers += r_registers
  30
+			csrs += r_csrs
31 31
 			assigns += r_assigns
32 32
 		else:
33 33
 			name = element[0]
@@ -40,10 +40,10 @@ def _create_registers_assign(layout, target, atomic, prefix=""):
40 40
 				alignment = element[3]
41 41
 			else:
42 42
 				alignment = 0
43  
-			reg = RegisterField(nbits + alignment, reset=reset, atomic_write=atomic, name=prefix + name)
44  
-			registers.append(reg)
45  
-			assigns.append(getattr(target, name).eq(reg.field.r[alignment:]))
46  
-	return registers, assigns
  43
+			reg = CSRStorage(nbits + alignment, reset=reset, atomic_write=atomic, name=prefix + name)
  44
+			csrs.append(reg)
  45
+			assigns.append(getattr(target, name).eq(reg.storage[alignment:]))
  46
+	return csrs, assigns
47 47
 
48 48
 (MODE_EXTERNAL, MODE_SINGLE_SHOT, MODE_CONTINUOUS) = range(3)
49 49
 
@@ -51,23 +51,23 @@ class SingleGenerator(Actor):
51 51
 	def __init__(self, layout, mode):
52 52
 		self._mode = mode
53 53
 		Actor.__init__(self, ("source", Source, _convert_layout(layout)))
54  
-		self._registers, self._assigns = _create_registers_assign(layout,
  54
+		self._csrs, self._assigns = _create_csrs_assign(layout,
55 55
 			self.token("source"), self._mode != MODE_SINGLE_SHOT)
56 56
 		if mode == MODE_EXTERNAL:
57 57
 			self.trigger = Signal()
58 58
 		elif mode == MODE_SINGLE_SHOT:
59  
-			shoot = RegisterRaw()
60  
-			self._registers.insert(0, shoot)
  59
+			shoot = CSR()
  60
+			self._csrs.insert(0, shoot)
61 61
 			self.trigger = shoot.re
62 62
 		elif mode == MODE_CONTINUOUS:
63  
-			enable = RegisterField()
64  
-			self._registers.insert(0, enable)
65  
-			self.trigger = enable.field.r
  63
+			enable = CSRStorage()
  64
+			self._csrs.insert(0, enable)
  65
+			self.trigger = enable.storage
66 66
 		else:
67 67
 			raise ValueError
68 68
 	
69  
-	def get_registers(self):
70  
-		return self._registers
  69
+	def get_csrs(self):
  70
+		return self._csrs
71 71
 	
72 72
 	def get_fragment(self):
73 73
 		stb = self.endpoints["source"].stb
@@ -79,19 +79,16 @@ def get_fragment(self):
79 79
 		sync = [If(ack | ~stb, *stmts)]
80 80
 		return Fragment(comb, sync)
81 81
 
82  
-class Collector(Actor):
  82
+class Collector(Actor, AutoCSR):
83 83
 	def __init__(self, layout, depth=1024):
84 84
 		Actor.__init__(self, ("sink", Sink, layout))
85 85
 		self._depth = depth
86 86
 		self._dw = sum(len(s) for s in self.token("sink").flatten())
87 87
 		
88  
-		self._r_wa = RegisterField(bits_for(self._depth-1), READ_WRITE, READ_WRITE)
89  
-		self._r_wc = RegisterField(bits_for(self._depth), READ_WRITE, READ_WRITE, atomic_write=True)
90  
-		self._r_ra = RegisterField(bits_for(self._depth-1), READ_WRITE, READ_ONLY)
91  
-		self._r_rd = RegisterField(self._dw, READ_ONLY, WRITE_ONLY)
92  
-	
93  
-	def get_registers(self):
94  
-		return [self._r_wa, self._r_wc, self._r_ra, self._r_rd]
  88
+		self._r_wa = CSRStorage(bits_for(self._depth-1), write_from_dev=True)
  89
+		self._r_wc = CSRStorage(bits_for(self._depth), write_from_dev=True, atomic_write=True)
  90
+		self._r_ra = CSRStorage(bits_for(self._depth-1))
  91
+		self._r_rd = CSRStatus(self._dw)
95 92
 	
96 93
 	def get_fragment(self):
97 94
 		mem = Memory(self._dw, self._depth)
@@ -99,22 +96,22 @@ def get_fragment(self):
99 96
 		rp = mem.get_port()
100 97
 		
101 98
 		comb = [
102  
-			If(self._r_wc.field.r != 0,
  99
+			If(self._r_wc.r != 0,
103 100
 				self.endpoints["sink"].ack.eq(1),
104 101
 				If(self.endpoints["sink"].stb,
105  
-					self._r_wa.field.we.eq(1),
106  
-					self._r_wc.field.we.eq(1),
  102
+					self._r_wa.we.eq(1),
  103
+					self._r_wc.we.eq(1),
107 104
 					wp.we.eq(1)
108 105
 				)
109 106
 			),
110  
-			self._r_wa.field.w.eq(self._r_wa.field.r + 1),
111  
-			self._r_wc.field.w.eq(self._r_wc.field.r - 1),
  107
+			self._r_wa.dat_w.eq(self._r_wa.storage + 1),
  108
+			self._r_wc.dat_w.eq(self._r_wc.storage - 1),
112 109
 			
113  
-			wp.adr.eq(self._r_wa.field.r),
  110
+			wp.adr.eq(self._r_wa.storage),
114 111
 			wp.dat_w.eq(Cat(*self.token("sink").flatten())),
115 112
 			
116  
-			rp.adr.eq(self._r_ra.field.r),
117  
-			self._r_rd.field.w.eq(rp.dat_r)
  113
+			rp.adr.eq(self._r_ra.storage),
  114
+			self._r_rd.status.eq(rp.dat_r)
118 115
 		]
119 116
 		
120 117
 		return Fragment(comb, specials={mem})
129  migen/bank/csrgen.py
... ...
@@ -1,91 +1,51 @@
1 1
 from operator import itemgetter
2 2
 
3 3
 from migen.fhdl.structure import *
  4
+from migen.fhdl.module import Module
4 5
 from migen.bus import csr
5 6
 from migen.bank.description import *
6 7
 
7  
-class Bank:
  8
+class Bank(Module):
8 9
 	def __init__(self, description, address=0, bus=None):
9  
-		self.description = description
10  
-		self.address = address
11 10
 		if bus is None:
12 11
 			bus = csr.Interface()
13 12
 		self.bus = bus
14  
-	
15  
-	def get_fragment(self):
16  
-		comb = []
17  
-		sync = []
18 13
 		
19  
-		sel = Signal()
20  
-		comb.append(sel.eq(self.bus.adr[9:] == self.address))
  14
+		###
  15
+
  16
+		if not description:
  17
+			return
21 18
 		
22  
-		desc_exp = expand_description(self.description, csr.data_width)
23  
-		nbits = bits_for(len(desc_exp)-1)
  19
+		# Turn description into simple CSRs and claim ownership of compound CSR modules
  20
+		simple_csrs = []
  21
+		for c in description:
  22
+			if isinstance(c, CSR):
  23
+				simple_csrs.append(c)
  24
+			else:
  25
+				c.finalize(csr.data_width)
  26
+				simple_csrs += c.get_simple_csrs()
  27
+				self.submodules += c
  28
+		nbits = bits_for(len(simple_csrs)-1)
  29
+
  30
+		# Decode selection
  31
+		sel = Signal()
  32
+		self.comb += sel.eq(self.bus.adr[9:] == address)
24 33
 		
25 34
 		# Bus writes
26  
-		bwcases = {}
27  
-		for i, reg in enumerate(desc_exp):
28  
-			if isinstance(reg, RegisterRaw):
29  
-				comb.append(reg.r.eq(self.bus.dat_w[:reg.size]))
30  
-				comb.append(reg.re.eq(sel & \
  35
+		for i, c in enumerate(simple_csrs):
  36
+			self.comb += [
  37
+				c.r.eq(self.bus.dat_w[:c.size]),
  38
+				c.re.eq(sel & \
31 39
 					self.bus.we & \
32  
-					(self.bus.adr[:nbits] == i)))
33  
-			elif isinstance(reg, RegisterFields):
34  
-				bwra = []
35  
-				offset = 0
36  
-				for field in reg.fields:
37  
-					if field.access_bus == WRITE_ONLY or field.access_bus == READ_WRITE:
38  
-						bwra.append(field.storage.eq(self.bus.dat_w[offset:offset+field.size]))
39  
-					offset += field.size
40  
-				if bwra:
41  
-					bwcases[i] = bwra
42  
-				# commit atomic writes
43  
-				for field in reg.fields:
44  
-					if isinstance(field, FieldAlias) and field.commit_list:
45  
-						commit_instr = [hf.commit_to.eq(hf.storage) for hf in field.commit_list]
46  
-						sync.append(If(sel & self.bus.we & self.bus.adr[:nbits] == i, *commit_instr))
47  
-			else:
48  
-				raise TypeError
49  
-		if bwcases:
50  
-			sync.append(If(sel & self.bus.we, Case(self.bus.adr[:nbits], bwcases)))
  40
+					(self.bus.adr[:nbits] == i))
  41
+			]
51 42
 		
52 43
 		# Bus reads
53  
-		brcases = {}
54  
-		for i, reg in enumerate(desc_exp):
55  
-			if isinstance(reg, RegisterRaw):
56  
-				brcases[i] = [self.bus.dat_r.eq(reg.w)]
57  
-			elif isinstance(reg, RegisterFields):
58  
-				brs = []
59  
-				reg_readable = False
60  
-				for field in reg.fields:
61  
-					if field.access_bus == READ_ONLY or field.access_bus == READ_WRITE:
62  
-						brs.append(field.storage)
63  
-						reg_readable = True
64  
-					else:
65  
-						brs.append(Replicate(0, field.size))
66  
-				if reg_readable:
67  
-					brcases[i] = [self.bus.dat_r.eq(Cat(*brs))]
68  
-			else:
69  
-				raise TypeError
70  
-		if brcases:
71  
-			sync.append(self.bus.dat_r.eq(0))
72  
-			sync.append(If(sel, Case(self.bus.adr[:nbits], brcases)))
73  
-		else:
74  
-			comb.append(self.bus.dat_r.eq(0))
75  
-		
76  
-		# Device access
77  
-		for reg in self.description:
78  
-			if isinstance(reg, RegisterFields):
79  
-				for field in reg.fields:
80  
-					if field.access_bus == READ_ONLY and field.access_dev == WRITE_ONLY:
81  
-						comb.append(field.storage.eq(field.w))
82  
-					else:
83  
-						if field.access_dev == READ_ONLY or field.access_dev == READ_WRITE:
84  
-							comb.append(field.r.eq(field.storage))
85  
-						if field.access_dev == WRITE_ONLY or field.access_dev == READ_WRITE:
86  
-							sync.append(If(field.we, field.storage.eq(field.w)))
87  
-		
88  
-		return Fragment(comb, sync)
  44
+		brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(simple_csrs))
  45
+		self.sync += [
  46
+			self.bus.dat_r.eq(0),
  47
+			If(sel, Case(self.bus.adr[:nbits], brcases))
  48
+		]
89 49
 
90 50
 # address_map(name, memory) returns the CSR offset at which to map
91 51
 # the CSR object (register bank or memory).
@@ -93,7 +53,7 @@ def get_fragment(self):
93 53
 # Otherwise, it is a memory object belonging to source.name.
94 54
 # address_map is called exactly once for each object at each call to
95 55
 # scan(), so it can have side effects.
96  
-class BankArray:
  56
+class BankArray(Module):
97 57
 	def __init__(self, source, address_map):
98 58
 		self.source = source
99 59
 		self.address_map = address_map
@@ -103,30 +63,29 @@ def scan(self):
103 63
 		self.banks = []
104 64
 		self.srams = []
105 65
 		for name, obj in sorted(self.source.__dict__.items(), key=itemgetter(0)):
106  
-			if hasattr(obj, "get_registers"):
107  
-				registers = obj.get_registers()
  66
+			if hasattr(obj, "get_csrs"):
  67
+				csrs = obj.get_csrs()
108 68
 			else:
109  
-				registers = []
  69
+				csrs = []
110 70
 			if hasattr(obj, "get_memories"):
111 71
 				memories = obj.get_memories()
112 72
 				for memory in memories:
113 73
 					mapaddr = self.address_map(name, memory)
114 74
 					mmap = csr.SRAM(memory, mapaddr)
115  
-					registers += mmap.get_registers()
116  
-					self.srams.append((name, memory, mmap))
117  
-			if registers:
  75
+					self.submodules += mmap
  76
+					csrs += mmap.get_csrs()
  77
+					self.srams.append((name, memory, mapaddr, mmap))
  78
+			if csrs:
118 79
 				mapaddr = self.address_map(name, None)
119  
-				rmap = Bank(registers, mapaddr)
120  
-				self.banks.append((name, rmap))
  80
+				rmap = Bank(csrs, mapaddr)
  81
+				self.submodules += rmap
  82
+				self.banks.append((name, csrs, mapaddr, rmap))
121 83
 
122 84
 	def get_rmaps(self):
123  
-		return [rmap for name, rmap in self.banks]
  85
+		return [rmap for name, csrs, mapaddr, rmap in self.banks]
124 86
 
125 87
 	def get_mmaps(self):
126  
-		return [mmap for name, memory, mmap in self.srams]
  88
+		return [mmap for name, memory, mapaddr, mmap in self.srams]
127 89
 
128 90
 	def get_buses(self):
129 91
 		return [i.bus for i in self.get_rmaps() + self.get_mmaps()]
130  
-
131  
-	def get_fragment(self):
132  
-		return sum([i.get_fragment() for i in self.get_rmaps() + self.get_mmaps()], Fragment())
195  migen/bank/description.py
... ...
@@ -1,70 +1,92 @@
1 1
 from migen.fhdl.structure import *
2 2
 from migen.fhdl.specials import Memory
  3
+from migen.fhdl.module import *
3 4
 from migen.fhdl.tracer import get_obj_var_name
4 5
 
5  
-class _Register(HUID):
6  
-	def __init__(self, name):
  6
+class _CSRBase(HUID):
  7
+	def __init__(self, size, name):
7 8
 		HUID.__init__(self)
8 9
 		self.name = get_obj_var_name(name)
9 10
 		if self.name is None:
10  
-			raise ValueError("Cannot extract register name from code, need to specify.")
  11
+			raise ValueError("Cannot extract CSR name from code, need to specify.")
11 12
 		if len(self.name) > 2 and self.name[:2] == "r_":
12 13
 			self.name = self.name[2:]
  14
+		self.size = size
13 15
 
14  
-class RegisterRaw(_Register):
  16
+class CSR(_CSRBase):
15 17
 	def __init__(self, size=1, name=None):
16  
-		_Register.__init__(self, name)
17  
-		self.size = size
18  
-		self.re = Signal()
19  
-		self.r = Signal(self.size)
20  
-		self.w = Signal(self.size)
  18
+		_CSRBase.__init__(self, size, name)
  19
+		self.re = Signal(name=self.name + "_re")
  20
+		self.r = Signal(self.size, name=self.name + "_r")
  21
+		self.w = Signal(self.size, name=self.name + "_w")
21 22
 
22  
-	def get_size(self):
23  
-		return self.size
  23
+class _CompoundCSR(_CSRBase, Module):
  24
+	def __init__(self, size, name):
  25
+		_CSRBase.__init__(self, size, name)
  26
+		self.simple_csrs = []
24 27
 
25  
-(READ_ONLY, WRITE_ONLY, READ_WRITE) = range(3)
  28
+	def get_simple_csrs(self):
  29
+		if not self.finalized:
  30
+			raise FinalizeError
  31
+		return self.simple_csrs
26 32
 
27  
-class Field:
28  
-	def __init__(self, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False, name=None):
29  
-		self.name = get_obj_var_name(name)
30  
-		if self.name is None:
31  
-			raise ValueError("Cannot extract field name from code, need to specify.")
32  
-		self.size = size
33  
-		self.access_bus = access_bus
34  
-		self.access_dev = access_dev
  33
+	def do_finalize(self, busword):
  34
+		raise NotImplementedError
  35
+
  36
+class CSRStatus(_CompoundCSR):
  37
+	def __init__(self, size=1, name=None):
  38
+		_CompoundCSR.__init__(self, size, name)
  39
+		self.status = Signal(self.size)
  40
+
  41
+	def do_finalize(self, busword):
  42
+		nwords = (self.size + busword - 1)//busword
  43
+		for i in reversed(range(nwords)):
  44
+			nbits = min(self.size - i*busword, busword)
  45
+			sc = CSR(nbits, self.name + str(i) if nwords > 1 else self.name)
  46
+			self.comb += sc.w.eq(self.status[i*busword:i*busword+nbits])
  47
+			self.simple_csrs.append(sc)
  48
+
  49
+class CSRStorage(_CompoundCSR):
  50
+	def __init__(self, size=1, reset=0, atomic_write=False, write_from_dev=False, name=None):
  51
+		_CompoundCSR.__init__(self, size, name)
35 52
 		self.storage = Signal(self.size, reset=reset)
36 53
 		self.atomic_write = atomic_write
37  
-		if self.access_bus == READ_ONLY and self.access_dev == WRITE_ONLY:
38  
-			self.w = Signal(self.size)
39  
-		else:
40  
-			if self.access_dev == READ_ONLY or self.access_dev == READ_WRITE:
41  
-				self.r = Signal(self.size, reset=reset)
42  
-			if self.access_dev == WRITE_ONLY or self.access_dev == READ_WRITE:
43  
-				self.w = Signal(self.size)
44  
-				self.we = Signal()
45  
-
46  
-class RegisterFields(_Register):
47  
-	def __init__(self, *fields, name=None):
48  
-		_Register.__init__(self, name)
49  
-		self.fields = fields
  54
+		if write_from_dev:
  55
+			self.we = Signal()
  56
+			self.dat_w = Signal(self.size)
  57
+			self.sync += If(self.we, self.storage.eq(self.dat_w))
50 58
 
51  
-	def get_size(self):
52  
-		return sum(field.size for field in self.fields)
  59
+	def do_finalize(self, busword):
  60
+		nwords = (self.size + busword - 1)//busword
  61
+		if nwords > 1 and self.atomic_write:
  62
+			backstore = Signal(self.size - busword, name=self.name + "_backstore")
  63
+		for i in reversed(range(nwords)):
  64
+			nbits = min(self.size - i*busword, busword)
  65
+			sc = CSR(nbits, self.name + str(i) if nwords else self.name)
  66
+			lo = i*busword
  67
+			hi = lo+nbits
  68
+			# read
  69
+			self.comb += sc.w.eq(self.storage[lo:hi])
  70
+			# write
  71
+			if nwords > 1 and self.atomic_write:
  72
+				if i:
  73
+					self.sync += If(sc.re, backstore[lo-busword:hi-busword].eq(sc.r))
  74
+				else:
  75
+					self.sync += If(sc.re, self.storage.eq(Cat(sc.r, backstore)))
  76
+			else:
  77
+				self.sync += If(sc.re, self.storage[lo:hi].eq(sc.r))
53 78
 
54  
-class RegisterField(RegisterFields):
55  
-	def __init__(self, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False, name=None):
56  
-		self.field = Field(size, access_bus, access_dev, reset, atomic_write, name="")
57  
-		RegisterFields.__init__(self, self.field, name=name)
  79
+			self.simple_csrs.append(sc)
58 80
 
59  
-def regprefix(prefix, registers):
60  
-	for register in registers:
61  
-		register.name = prefix + register.name
  81
+def csrprefix(prefix, csrs):
  82
+	for csr in csrs:
  83
+		csr.name = prefix + csr.name
62 84
 
63 85
 def memprefix(prefix, memories):
64 86
 	for memory in memories:
65 87
 		memory.name_override = prefix + memory.name_override
66 88
 
67  
-class AutoReg:
  89
+class AutoCSR:
68 90
 	def get_memories(self):
69 91
 		r = []
70 92
 		for k, v in self.__dict__.items():
@@ -76,88 +98,13 @@ def get_memories(self):
76 98
 				r += memories
77 99
 		return sorted(r, key=lambda x: x.huid)
78 100
 
79  
-	def get_registers(self):
  101
+	def get_csrs(self):
80 102
 		r = []
81 103
 		for k, v in self.__dict__.items():
82  
-			if isinstance(v, _Register):
  104
+			if isinstance(v, _CSRBase):
83 105
 				r.append(v)
84  
-			elif hasattr(v, "get_registers") and callable(v.get_registers):
85  
-				registers = v.get_registers()
86  
-				regprefix(k + "_", registers)
87  
-				r += registers
  106
+			elif hasattr(v, "get_csrs") and callable(v.get_csrs):
  107
+				csrs = v.get_csrs()
  108
+				csrprefix(k + "_", csrs)
  109
+				r += csrs
88 110
 		return sorted(r, key=lambda x: x.huid)
89  
-
90  
-(ALIAS_NON_ATOMIC, ALIAS_ATOMIC_HOLD, ALIAS_ATOMIC_COMMIT) = range(3)
91  
-
92  
-class FieldAlias:
93  
-	def __init__(self, mode, f, start, end, commit_list):
94  
-		self.mode = mode
95  
-		self.size = end - start
96  
-		self.access_bus = f.access_bus
97  
-		self.access_dev = f.access_dev
98  
-		if mode == ALIAS_ATOMIC_HOLD:
99  
-			self.storage = Signal(end-start, name="atomic_hold")
100  
-			self.commit_to = f.storage[start:end]
101  
-		else:
102  
-			self.storage = f.storage[start:end]
103  
-		if mode == ALIAS_ATOMIC_COMMIT:
104  
-			self.commit_list = commit_list
105  
-		else:
106  
-			self.commit_list = []
107  
-		# device access is through the original field
108  
-
109  
-def expand_description(description, busword):
110  
-	d = []
111  
-	for reg in description:
112  
-		if isinstance(reg, RegisterRaw):
113  
-			if reg.size > busword:
114  
-				raise ValueError("Raw register larger than a bus word")
115  
-			d.append(reg)
116  
-		elif isinstance(reg, RegisterFields):
117  
-			f = []
118  
-			offset = 0
119  
-			totalsize = 0
120  
-			for field in reg.fields:
121  
-				offset += field.size
122  
-				totalsize += field.size
123  
-				if offset > busword:
124  
-					# add padding
125  
-					padding = busword - (totalsize % busword)
126  
-					if padding != busword:
127  
-						totalsize += padding
128  
-						offset += padding
129  
-					
130  
-					top = field.size
131  
-					commit_list = []
132  
-					while offset > busword:
133  
-						if field.atomic_write:
134  
-							if offset - busword > busword:
135  
-								mode = ALIAS_ATOMIC_HOLD
136  
-							else:
137  
-								# last iteration
138  
-								mode = ALIAS_ATOMIC_COMMIT
139  
-						else:
140  
-							mode = ALIAS_NON_ATOMIC
141  
-						
142  
-						slice1 = busword - offset + top
143  
-						slice2 = min(offset - busword, busword)
144  
-						if slice1:
145  
-							alias = FieldAlias(mode, field, top - slice1, top, commit_list)
146  
-							f.append(alias)
147  
-							if mode == ALIAS_ATOMIC_HOLD:
148  
-								commit_list.append(alias)
149  
-							top -= slice1
150  
-						d.append(RegisterFields(*f, name=reg.name))
151  
-						alias = FieldAlias(mode, field, top - slice2, top, commit_list)
152  
-						f = [alias]
153  
-						if mode == ALIAS_ATOMIC_HOLD:
154  
-							commit_list.append(alias)
155  
-						top -= slice2
156  
-						offset -= busword
157  
-				else:
158  
-					f.append(field)
159  
-			if f:
160  
-				d.append(RegisterFields(*f, name=reg.name))
161  
-		else:
162  
-			raise TypeError
163  
-	return d
10  migen/bank/eventmanager.py
@@ -15,7 +15,7 @@ class EventSourcePulse(_EventSource):
15 15
 class EventSourceLevel(_EventSource):
16 16
 	pass
17 17
 
18  
-class EventManager(Module, AutoReg):
  18
+class EventManager(Module, AutoCSR):
19 19
 	def __init__(self):
20 20
 		self.irq = Signal()
21 21
 	
@@ -23,9 +23,9 @@ def do_finalize(self):
23 23
 		sources_u = [v for v in self.__dict__.values() if isinstance(v, _EventSource)]
24 24
 		sources = sorted(sources_u, key=lambda x: x.huid)
25 25
 		n = len(sources)
26  
-		self.status = RegisterRaw(n)
27  
-		self.pending = RegisterRaw(n)
28  
-		self.enable = RegisterFields(*(Field(1, READ_WRITE, READ_ONLY, name="e" + str(i)) for i in range(n)))
  26
+		self.status = CSR(n)
  27
+		self.pending = CSR(n)
  28
+		self.enable = CSRStorage(n)
29 29
 
30 30
 		# status
31 31
 		for i, source in enumerate(sources):
@@ -55,7 +55,7 @@ def do_finalize(self):
55 55
 			self.comb += self.pending.w[i].eq(source.pending)
56 56
 		
57 57
 		# IRQ
58  
-		irqs = [self.pending.w[i] & field.r for i, field in enumerate(self.enable.fields)]
  58
+		irqs = [self.pending.w[i] & self.enable.storage[i] for i in range(n)]
59 59
 		self.comb += self.irq.eq(optree("|", irqs))
60 60
 
61 61
 	def __setattr__(self, name, value):
8  migen/bus/csr.py
@@ -3,7 +3,7 @@
3 3
 from migen.fhdl.module import Module
4 4
 from migen.bus.simple import *
5 5
 from migen.bus.transactions import *
6  
-from migen.bank.description import RegisterField
  6
+from migen.bank.description import CSRStorage
7 7
 from migen.genlib.misc import chooser
8 8
 
9 9
 data_width = 8
@@ -68,7 +68,7 @@ def __init__(self, mem_or_size, address, read_only=None, bus=None):
68 68
 			self.word_bits = 0
69 69
 		page_bits = _compute_page_bits(self.mem.depth + self.word_bits)
70 70
 		if page_bits:
71  
-			self._page = RegisterField(page_bits, name=self.mem.name_override + "_page")
  71
+			self._page = CSRStorage(page_bits, name=self.mem.name_override + "_page")
72 72
 		else:
73 73
 			self._page = None
74 74
 		if read_only is None:
@@ -81,7 +81,7 @@ def __init__(self, mem_or_size, address, read_only=None, bus=None):
81 81
 			bus = Interface()
82 82
 		self.bus = bus
83 83
 	
84  
-	def get_registers(self):
  84
+	def get_csrs(self):
85 85
 		if self._page is None:
86 86
 			return []
87 87
 		else:
@@ -126,7 +126,7 @@ def get_fragment(self):
126 126
 		if self._page is None:
127 127
 			comb.append(port.adr.eq(self.bus.adr[self.word_bits:len(port.adr)]))
128 128
 		else:
129  
-			pv = self._page.field.r
  129
+			pv = self._page.storage
130 130
 			comb.append(port.adr.eq(Cat(self.bus.adr[self.word_bits:len(port.adr)-len(pv)], pv)))
131 131
 		
132 132
 		return Fragment(comb, sync, specials={self.mem})
4  migen/fhdl/module.py
@@ -147,12 +147,12 @@ def _collect_submodules(self):
147 147
 		self._submodules = []
148 148
 		return r
149 149
 
150  
-	def finalize(self):
  150
+	def finalize(self, *args, **kwargs):
151 151
 		if not self.finalized:
152 152
 			self.finalized = True
153 153
 			# finalize existing submodules before finalizing us
154 154
 			subfragments = self._collect_submodules()
155  
-			self.do_finalize()
  155
+			self.do_finalize(*args, **kwargs)
156 156
 			# finalize submodules created by do_finalize
157 157
 			subfragments += self._collect_submodules()
158 158
 			# resolve clock domain name conflicts
21  migen/flow/hooks.py
... ...
@@ -1,3 +1,5 @@
  1
+from collections import defaultdict
  2
+
1 3
 from migen.fhdl.structure import *
2 4
 from migen.fhdl.module import Module
3 5
 from migen.flow.actor import *
@@ -24,23 +26,18 @@ def do_simulation(self, s):
24 26
 		else:
25 27
 			self.on_inactive()
26 28
 
27  
-class DFGHook:
  29
+class DFGHook(Module):
28 30
 	def __init__(self, dfg, create):
29 31
 		assert(not dfg.is_abstract())
30  
-		self.nodepair_to_ep = dict()
31  
-		for u, v, data in dfg.edges_iter(data=True):
32  
-			if (u, v) in self.nodepair_to_ep:
33  
-				ep_to_hook = self.nodepair_to_ep[(u, v)]
34  
-			else:
35  
-				ep_to_hook = dict()
36  
-				self.nodepair_to_ep[(u, v)] = ep_to_hook
  32
+		self.nodepair_to_ep = defaultdict(dict)
  33
+		for hookn, (u, v, data) in dfg.edges_iter(data=True):
  34
+			ep_to_hook = self.nodepair_to_ep[(u, v)]
37 35
 			ep = data["source"]
38  
-			ep_to_hook[ep] = create(u, ep, v)
  36
+			h = create(u, ep, v)
  37
+			ep_to_hook[ep] = h
  38
+			setattr(self.submodules, "hook"+str(hookn), h)
39 39
 	
40 40
 	def hooks_iter(self):
41 41
 		for v1 in self.nodepair_to_ep.values():
42 42
 			for v2 in v1.values():
43 43
 				yield v2
44  
-	
45  
-	def get_fragment(self):
46  
-		return sum([h.get_fragment() for h in self.hooks_iter()], Fragment())
90  migen/flow/isd.py
... ...
@@ -1,38 +1,30 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.module import Module
2 3
 from migen.bank.description import *
3 4
 from migen.flow.hooks import DFGHook
4 5
 
5 6
 ISD_MAGIC = 0x6ab4
6 7
 
7  
-class EndpointReporter:
  8
+class EndpointReporter(Module, AutoCSR):
8 9
 	def __init__(self, endpoint, nbits):
9  
-		self.endpoint = endpoint
10  
-		self.nbits = nbits
11 10
 		self.reset = Signal()
12 11
 		self.freeze = Signal()
13 12
 		
14  
-		self._ack_count = RegisterField(self.nbits, READ_ONLY, WRITE_ONLY)
15  
-		self._nack_count = RegisterField(self.nbits, READ_ONLY, WRITE_ONLY)
16  
-		self._cur_stb = Field(1, READ_ONLY, WRITE_ONLY)
17  
-		self._cur_ack = Field(1, READ_ONLY, WRITE_ONLY)
18  
-		self._cur_status = RegisterFields(self._cur_stb, self._cur_ack)
  13
+		self._ack_count = CSRStatus(nbits)
  14
+		self._nack_count = CSRStatus(nbits)
  15
+		self._cur_status = CSRStatus(2)
19 16
 	
20  
-	def get_registers(self):
21  
-		return [self._ack_count, self._nack_count, self._cur_status]
22  
-	
23  
-	def get_fragment(self):
  17
+		###
  18
+
24 19
 		stb = Signal()
25 20
 		ack = Signal()
26  
-		ack_count = Signal(self.nbits)
27  
-		nack_count = Signal(self.nbits)
28  
-		comb = [
29  
-			self._cur_stb.w.eq(stb),
30  
-			self._cur_ack.w.eq(ack)
31  
-		]
32  
-		sync = [
  21
+		self.comb += self._cur_status.status.eq(Cat(stb, ack))
  22
+		ack_count = Signal(nbits)
  23
+		nack_count = Signal(nbits)
  24
+		self.sync += [
33 25
 			# register monitored signals
34  
-			stb.eq(self.endpoint.stb),
35  
-			ack.eq(self.endpoint.ack),
  26
+			stb.eq(endpoint.stb),
  27
+			ack.eq(endpoint.ack),
36 28
 			# count operations
37 29
 			If(self.reset,
38 30
 				ack_count.eq(0),
@@ -47,49 +39,31 @@ def get_fragment(self):
47 39
 				)
48 40
 			),
49 41
 			If(~self.freeze,
50  
-				self._ack_count.field.w.eq(ack_count),
51  
-				self._nack_count.field.w.eq(nack_count)
  42
+				self._ack_count.status.eq(ack_count),
  43
+				self._nack_count.status.eq(nack_count)
52 44
 			)
53 45
 		]
54  
-		return Fragment(comb, sync)
55 46
 
56  
-class DFGReporter(DFGHook):
  47
+class DFGReporter(DFGHook, AutoCSR):
57 48
 	def __init__(self, dfg, nbits):
58  
-		self._nbits = nbits
  49
+		self._r_magic = CSRStatus(16)
  50
+		self._r_neps = CSRStatus(8)
  51
+		self._r_nbits = CSRStatus(8)
  52
+		self._r_freeze = CSRStorage()
  53
+		self._r_reset = CSR()
59 54
 		
60  
-		self._r_magic = RegisterField(16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
61  
-		self._r_neps = RegisterField(8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
62  
-		self._r_nbits = RegisterField(8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
63  
-		self._r_freeze = RegisterField()
64  
-		self._r_reset = RegisterRaw()
65  
-		
66  
-		self.order = []
67  
-		DFGHook.__init__(self, dfg, self._create)
68  
-	
69  
-	def _create(self, u, ep, v):
70  
-		self.order.append((u, ep, v))
71  
-		return EndpointReporter(u.actor.endpoints[ep], self._nbits)
72  
-	
73  
-	def print_map(self):
74  
-		for n, (u, ep, v) in enumerate(self.order):
75  
-			print("#" + str(n) + ": " + str(u) + ":" + ep + "  ->  " + str(v))
76  
-	
77  
-	def get_registers(self):
78  
-		registers = [self._r_magic, self._r_neps, self._r_nbits,
79  
-			self._r_freeze, self._r_reset]
80  
-		for u, ep, v in self.order:
81  
-			registers += self.nodepair_to_ep[(u, v)][ep].get_registers()
82  
-		return registers
83  
-	
84  
-	def get_fragment(self):
85  
-		comb = [
86  
-			self._r_magic.field.w.eq(ISD_MAGIC),
87  
-			self._r_neps.field.w.eq(len(self.order)),
88  
-			self._r_nbits.field.w.eq(self._nbits)
  55
+		###
  56
+
  57
+		DFGHook.__init__(self, dfg,
  58
+			lambda u, ep, v: EndpointReporter(u.endpoints[ep], nbits))
  59
+
  60
+		self.comb += [
  61
+			self._r_magic.status.eq(ISD_MAGIC),
  62
+			self._r_neps.status.eq(len(self.hooks_iter())),
  63
+			self._r_nbits.status.eq(nbits)
89 64
 		]
90 65
 		for h in self.hooks_iter():
91  
-			comb += [
92  
-				h.freeze.eq(self._r_freeze.field.r),
  66
+			self.comb += [
  67
+				h.freeze.eq(self._r_freeze.storage),
93 68
 				h.reset.eq(self._r_reset.re)
94 69
 			]
95  
-		return Fragment(comb) + DFGHook.get_fragment(self)
4  migen/flow/network.py
@@ -211,9 +211,9 @@ def __init__(self, dfg, debugger=False, debugger_nbits=48):
211 211
 			self.debugger = DFGReporter(self.dfg, debugger_nbits)
212 212
 		Actor.__init__(self)
213 213
 	
214  
-	def get_registers(self):
  214
+	def get_csrs(self):
215 215
 		if hasattr(self, "debugger"):
216  
-			return self.debugger.get_registers()
  216
+			return self.debugger.get_csrs()
217 217
 		else:
218 218
 			return []
219 219
 	

No commit comments for this range

Something went wrong with that request. Please try again.