Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

New 'specials' API

  • Loading branch information...
commit 49cfba50fabfed542980e7dca4683bef2fbb4110 1 parent e82ea19
Sébastien Bourdeauducq authored February 22, 2013
80  examples/basic/lm32_inst.py
... ...
@@ -1,50 +1,60 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.specials import Instance
  3
+from migen.bus import wishbone
2 4
 from migen.fhdl import verilog
3 5
 
4 6
 class LM32:
5 7
 	def __init__(self):
6  
-		self.inst = Instance("lm32_top",
  8
+		self.ibus = i = wishbone.Interface()
  9
+		self.dbus = d = wishbone.Interface()
  10
+		self.interrupt = Signal(32)
  11
+		self.ext_break = Signal()
  12
+		self._i_adr_o = Signal(32)
  13
+		self._d_adr_o = Signal(32)
  14
+		self._inst = Instance("lm32_top",
7 15
 			Instance.ClockPort("clk_i"),
8 16
 			Instance.ResetPort("rst_i"),
9  
-		
10  
-			Instance.Input("interrupt", 32),
11  
-			Instance.Input("ext_break", 1),
12  
-		
13  
-			Instance.Output("I_ADR_O", 32),
14  
-			Instance.Output("I_DAT_O", 32),
15  
-			Instance.Output("I_SEL_O", 4),
16  
-			Instance.Output("I_CYC_O", 1),
17  
-			Instance.Output("I_STB_O", 1),
18  
-			Instance.Output("I_WE_O", 1),
19  
-			Instance.Output("I_CTI_O", 3),
20  
-			Instance.Output("I_LOCK_O", 1),
21  
-			Instance.Output("I_BTE_O", 1),
22  
-			Instance.Input("I_DAT_I", 32),
23  
-			Instance.Input("I_ACK_I", 1),
24  
-			Instance.Input("I_ERR_I", 1),
25  
-			Instance.Input("I_RTY_I", 1),
26 17
 			
27  
-			Instance.Output("D_ADR_O", 32),
28  
-			Instance.Output("D_DAT_O", 32),
29  
-			Instance.Output("D_SEL_O", 4),
30  
-			Instance.Output("D_CYC_O", 1),
31  
-			Instance.Output("D_STB_O", 1),
32  
-			Instance.Output("D_WE_O", 1),
33  
-			Instance.Output("D_CTI_O", 3),
34  
-			Instance.Output("D_LOCK_O", 1),
35  
-			Instance.Output("D_BTE_O", 1),
36  
-			Instance.Input("D_DAT_I", 32),
37  
-			Instance.Input("D_ACK_I", 1),
38  
-			Instance.Input("D_ERR_I", 1),
39  
-			Instance.Input("D_RTY_I", 1),
  18
+			Instance.Input("interrupt", self.interrupt),
  19
+			#Instance.Input("ext_break", self.ext_break),
  20
+		
  21
+			Instance.Output("I_ADR_O", self._i_adr_o),
  22
+			Instance.Output("I_DAT_O", i.dat_w),
  23
+			Instance.Output("I_SEL_O", i.sel),
  24
+			Instance.Output("I_CYC_O", i.cyc),
  25
+			Instance.Output("I_STB_O", i.stb),
  26
+			Instance.Output("I_WE_O", i.we),
  27
+			Instance.Output("I_CTI_O", i.cti),
  28
+			Instance.Output("I_LOCK_O"),
  29
+			Instance.Output("I_BTE_O", i.bte),
  30
+			Instance.Input("I_DAT_I", i.dat_r),
  31
+			Instance.Input("I_ACK_I", i.ack),
  32
+			Instance.Input("I_ERR_I", i.err),
  33
+			Instance.Input("I_RTY_I", 0),
40 34
 			
41  
-			name="lm32")
42  
-	
  35
+			Instance.Output("D_ADR_O", self._d_adr_o),
  36
+			Instance.Output("D_DAT_O", d.dat_w),
  37
+			Instance.Output("D_SEL_O", d.sel),
  38
+			Instance.Output("D_CYC_O", d.cyc),
  39
+			Instance.Output("D_STB_O", d.stb),
  40
+			Instance.Output("D_WE_O", d.we),
  41
+			Instance.Output("D_CTI_O", d.cti),
  42
+			Instance.Output("D_LOCK_O"),
  43
+			Instance.Output("D_BTE_O", d.bte),
  44
+			Instance.Input("D_DAT_I", d.dat_r),
  45
+			Instance.Input("D_ACK_I", d.ack),
  46
+			Instance.Input("D_ERR_I", d.err),
  47
+			Instance.Input("D_RTY_I", 0))
  48
+
43 49
 	def get_fragment(self):
44  
-		return Fragment(instances=[self.inst])
  50
+		comb = [
  51
+			self.ibus.adr.eq(self._i_adr_o[2:]),
  52
+			self.dbus.adr.eq(self._d_adr_o[2:])
  53
+		]
  54
+		return Fragment(comb=comb, specials={self._inst})
45 55
 
46 56
 cpus = [LM32() for i in range(4)]
47 57
 frag = Fragment()
48 58
 for cpu in cpus:
49 59
 	frag += cpu.get_fragment()
50  
-print(verilog.convert(frag, set([cpus[0].inst.get_io("interrupt"), cpus[0].inst.get_io("I_WE_O")])))
  60
+print(verilog.convert(frag, {cpus[0].interrupt}))
5  examples/basic/memory.py
... ...
@@ -1,11 +1,12 @@
1  
-from migen.fhdl.structure import *
  1
+from migen.fhdl.structure import Fragment
  2
+from migen.fhdl.specials import Memory
2 3
 from migen.fhdl import verilog
3 4
 
4 5
 mem = Memory(32, 100, init=[5, 18, 32])
5 6
 p1 = mem.get_port(write_capable=True, we_granularity=8)
6 7
 p2 = mem.get_port(has_re=True, clock_domain="rd")
7 8
 
8  
-f = Fragment(memories=[mem])
  9
+f = Fragment(specials={mem})
9 10
 v = verilog.convert(f, ios={p1.adr, p1.dat_r, p1.we, p1.dat_w,
10 11
 	p2.adr, p2.dat_r, p2.re})
11 12
 print(v)
3  examples/basic/tristate.py
... ...
@@ -1,4 +1,5 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.specials import Tristate
2 3
 from migen.fhdl import verilog
3 4
 
4 5
 n = 6
@@ -7,5 +8,5 @@
7 8
 oe = Signal()
8 9
 i = Signal(n)
9 10
 
10  
-f = Fragment(tristates={Tristate(pad, o, oe, i)})
  11
+f = Fragment(specials={Tristate(pad, o, oe, i)})
11 12
 print(verilog.convert(f, ios={pad, o, oe, i}))
1  examples/pytholite/uio.py
@@ -7,6 +7,7 @@
7 7
 from migen.pytholite.transel import Register
8 8
 from migen.pytholite.compiler import make_pytholite
9 9
 from migen.sim.generic import Simulator
  10
+from migen.fhdl.specials import Memory
10 11
 from migen.fhdl import verilog
11 12
 
12 13
 layout = [("r", 32)]
3  examples/sim/memory.py
@@ -2,6 +2,7 @@
2 2
 # License: GPLv3 with additional permissions (see README).
3 3
 
4 4
 from migen.fhdl.structure import *
  5
+from migen.fhdl.specials import Memory
5 6
 from migen.sim.generic import Simulator
6 7
 
7 8
 class Mem:
@@ -24,7 +25,7 @@ def do_simulation(self, s):
24 25
 			s.interrupt = True
25 26
 	
26 27
 	def get_fragment(self):
27  
-		return Fragment(memories=[self.mem], sim=[self.do_simulation])
  28
+		return Fragment(specials={self.mem}, sim=[self.do_simulation])
28 29
 
29 30
 def main():
30 31
 	dut = Mem()
3  migen/actorlib/spi.py
... ...
@@ -1,6 +1,7 @@
1 1
 # Simple Processor Interface
2 2
 
3 3
 from migen.fhdl.structure import *
  4
+from migen.fhdl.specials import Memory
4 5
 from migen.bank.description import *
5 6
 from migen.flow.actor import *
6 7
 
@@ -117,4 +118,4 @@ def get_fragment(self):
117 118
 			self._reg_rd.field.w.eq(rp.dat_r)
118 119
 		]
119 120
 		
120  
-		return Fragment(comb, memories=[mem])
  121
+		return Fragment(comb, specials={mem})
3  migen/bus/csr.py
... ...
@@ -1,4 +1,5 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.specials import Memory
2 3
 from migen.bus.simple import *
3 4
 from migen.bus.transactions import *
4 5
 from migen.sim.generic import PureSimulable
@@ -97,4 +98,4 @@ def get_fragment(self):
97 98
 			pv = self._page.field.r
98 99
 			comb.append(port.adr.eq(Cat(self.bus.adr[:len(port.adr)-len(pv)], pv)))
99 100
 		
100  
-		return Fragment(comb, sync, memories=[self.mem])
  101
+		return Fragment(comb, sync, specials={self.mem})
3  migen/bus/wishbone.py
... ...
@@ -1,4 +1,5 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.specials import Memory
2 3
 from migen.corelogic import roundrobin
3 4
 from migen.corelogic.misc import optree
4 5
 from migen.bus.simple import *
@@ -228,4 +229,4 @@ def get_fragment(self):
228 229
 				self.bus.ack.eq(1)
229 230
 			)
230 231
 		]
231  
-		return Fragment(comb, sync, memories=[self.mem])
  232
+		return Fragment(comb, sync, specials={self.mem})
5  migen/bus/wishbone2asmi.py
... ...
@@ -1,5 +1,6 @@
1  
-from migen.bus import wishbone
2 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.specials import Memory
  3
+from migen.bus import wishbone
3 4
 from migen.corelogic.fsm import FSM
4 5
 from migen.corelogic.misc import split, displacer, chooser
5 6
 from migen.corelogic.record import Record
@@ -136,5 +137,5 @@ def get_fragment(self):
136 137
 			fsm.next_state(fsm.TEST_HIT)
137 138
 		)
138 139
 		
139  
-		return Fragment(comb, sync, memories=[data_mem, tag_mem]) \
  140
+		return Fragment(comb, sync, specials={data_mem, tag_mem}) \
140 141
 			+ fsm.get_fragment()
9  migen/fhdl/namer.py
@@ -131,13 +131,10 @@ def __init__(self, pnd):
131 131
 		self.pnd = pnd
132 132
 	
133 133
 	def get_name(self, sig):
134  
-		if isinstance(sig, Memory):
135  
-			sig_name = "mem"
  134
+		if sig.name_override is not None:
  135
+			sig_name = sig.name_override
136 136
 		else:
137  
-			if sig.name_override is not None:
138  
-				sig_name = sig.name_override
139  
-			else:
140  
-				sig_name = self.pnd[sig]
  137
+			sig_name = self.pnd[sig]
141 138
 		try:
142 139
 			n = self.sigs[sig]
143 140
 		except KeyError:
311  migen/fhdl/specials.py
... ...
@@ -0,0 +1,311 @@
  1
+from migen.fhdl.structure import *
  2
+from migen.fhdl.tools import list_signals, value_bits_sign
  3
+
  4
+from migen.fhdl.verilog import _printexpr as verilog_printexpr
  5
+
  6
+class Special(HUID):
  7
+	def rename_clock_domain(self):
  8
+		pass
  9
+
  10
+	def get_clock_domains(self):
  11
+		return set()
  12
+
  13
+class Tristate(Special):
  14
+	def __init__(self, target, o, oe, i=None):
  15
+		Special.__init__(self)
  16
+		self.target = target
  17
+		self.o = o
  18
+		self.oe = oe
  19
+		self.i = i
  20
+
  21
+	def list_ios(self, ins, outs, inouts):
  22
+		r = set()
  23
+		if inouts:
  24
+			r.update(list_signals(self.target))
  25
+		if ins:
  26
+			r.update(list_signals(self.o))
  27
+			r.update(list_signals(self.oe))
  28
+		if outs:
  29
+			r.update(list_signals(self.i))
  30
+		return r
  31
+
  32
+	@staticmethod
  33
+	def emit_verilog(tristate, ns, clock_domains):
  34
+		def pe(e):
  35
+			return verilog_printexpr(ns, e)[0]
  36
+		w, s = value_bits_sign(tristate.target)
  37
+		r = "assign " + pe(tristate.target) + " = " \
  38
+			+ pe(tristate.oe) + " ? " + pe(tristate.o) \
  39
+			+ " : " + str(w) + "'bz;\n"
  40
+		if tristate.i is not None:
  41
+			r += "assign " + pe(tristate.i) + " = " + pe(tristate.target) + ";\n"
  42
+		r += "\n"
  43
+		return r
  44
+
  45
+class TSTriple:
  46
+	def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0):
  47
+		self.o = Signal(bits_sign, min=min, max=max, reset=reset_o)
  48
+		self.oe = Signal(reset=reset_oe)
  49
+		self.i = Signal(bits_sign, min=min, max=max)
  50
+
  51
+	def get_tristate(self, target):
  52
+		return Tristate(target, self.o, self.oe, self.i)
  53
+
  54
+class Instance(Special):
  55
+	def __init__(self, of, *items, name=""):
  56
+		Special.__init__(self)
  57
+		self.of = of
  58
+		if name:
  59
+			self.name_override = name
  60
+		else:
  61
+			self.name_override = of
  62
+		self.items = items
  63
+	
  64
+	class _IO:
  65
+		def __init__(self, name, expr=None):
  66
+			self.name = name
  67
+			if expr is None:
  68
+				expr = Signal()
  69
+			self.expr = expr
  70
+	class Input(_IO):
  71
+		pass	
  72
+	class Output(_IO):
  73
+		pass
  74
+	class InOut(_IO):
  75
+		pass
  76
+
  77
+	class Parameter:
  78
+		def __init__(self, name, value):
  79
+			self.name = name
  80
+			self.value = value
  81
+	
  82
+	class _CR:
  83
+		def __init__(self, name_inst, domain="sys", invert=False):
  84
+			self.name_inst = name_inst
  85
+			self.domain = domain
  86
+			self.invert = invert
  87
+	class ClockPort(_CR):
  88
+		pass
  89
+	class ResetPort(_CR):
  90
+		pass
  91
+	
  92
+	def get_io(self, name):
  93
+		for item in self.items:
  94
+			if isinstance(item, Instance._IO) and item.name == name:
  95
+				return item.expr
  96
+
  97
+	def rename_clock_domain(self):
  98
+		for cr in filter(lambda x: isinstance(x, Instance._CR), self.items):
  99
+			if cr.domain == old:
  100
+				cr.domain = new
  101
+
  102
+	def get_clock_domains(self):
  103
+		return set(cr.domain 
  104
+			for cr in filter(lambda x: isinstance(x, Instance._CR), self.items))
  105
+
  106
+	def list_ios(self, ins, outs, inouts):
  107
+		subsets = [list_signals(item.expr) for item in filter(lambda x:
  108
+			(ins and isinstance(x, Instance.Input))
  109
+			or (outs and isinstance(x, Instance.Output))
  110
+			or (inouts and isinstance(x, Instance.InOut)),
  111
+			self.items)]
  112
+		if subsets:
  113
+			return set.union(*subsets)
  114
+		else:
  115
+			return set()
  116
+
  117
+	@staticmethod
  118
+	def emit_verilog(instance, ns, clock_domains):
  119
+		r = instance.of + " "
  120
+		parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), instance.items))
  121
+		if parameters:
  122
+			r += "#(\n"
  123
+			firstp = True
  124
+			for p in parameters:
  125
+				if not firstp:
  126
+					r += ",\n"
  127
+				firstp = False
  128
+				r += "\t." + p.name + "("
  129
+				if isinstance(p.value, (int, bool)):
  130
+					r += _printintbool(p.value)[0]
  131
+				elif isinstance(p.value, float):
  132
+					r += str(p.value)
  133
+				elif isinstance(p.value, str):
  134
+					r += "\"" + p.value + "\""
  135
+				else:
  136
+					raise TypeError
  137
+				r += ")"
  138
+			r += "\n) "
  139
+		r += ns.get_name(instance) 
  140
+		if parameters: r += " "
  141
+		r += "(\n"
  142
+		firstp = True
  143
+		for p in instance.items:
  144
+			if isinstance(p, Instance._IO):
  145
+				name_inst = p.name
  146
+				name_design = verilog_printexpr(ns, p.expr)[0]
  147
+			elif isinstance(p, Instance.ClockPort):
  148
+				name_inst = p.name_inst
  149
+				name_design = ns.get_name(clock_domains[p.domain].clk)
  150
+				if p.invert:
  151
+					name_design = "~" + name_design
  152
+			elif isinstance(p, Instance.ResetPort):
  153
+				name_inst = p.name_inst
  154
+				name_design = ns.get_name(clock_domains[p.domain].rst)
  155
+			else:
  156
+				continue
  157
+			if not firstp:
  158
+				r += ",\n"
  159
+			firstp = False
  160
+			r += "\t." + name_inst + "(" + name_design + ")"
  161
+		if not firstp:
  162
+			r += "\n"
  163
+		r += ");\n\n"
  164
+		return r
  165
+
  166
+(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
  167
+
  168
+class _MemoryPort:
  169
+	def __init__(self, adr, dat_r, we=None, dat_w=None,
  170
+	  async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST,
  171
+	  clock_domain="sys"):
  172
+		self.adr = adr
  173
+		self.dat_r = dat_r
  174
+		self.we = we
  175
+		self.dat_w = dat_w
  176
+		self.async_read = async_read
  177
+		self.re = re
  178
+		self.we_granularity = we_granularity
  179
+		self.mode = mode
  180
+		self.clock_domain = clock_domain
  181
+
  182
+class Memory(Special):
  183
+	def __init__(self, width, depth, init=None):
  184
+		Special.__init__(self)
  185
+		self.width = width
  186
+		self.depth = depth
  187
+		self.ports = []
  188
+		self.init = init
  189
+	
  190
+	def get_port(self, write_capable=False, async_read=False,
  191
+	  has_re=False, we_granularity=0, mode=WRITE_FIRST,
  192
+	  clock_domain="sys"):
  193
+		if we_granularity >= self.width:
  194
+			we_granularity = 0
  195
+		adr = Signal(max=self.depth)
  196
+		dat_r = Signal(self.width)
  197
+		if write_capable:
  198
+			if we_granularity:
  199
+				we = Signal(self.width//we_granularity)
  200
+			else:
  201
+				we = Signal()
  202
+			dat_w = Signal(self.width)
  203
+		else:
  204
+			we = None
  205
+			dat_w = None
  206
+		if has_re:
  207
+			re = Signal()
  208
+		else:
  209
+			re = None
  210
+		mp = _MemoryPort(adr, dat_r, we, dat_w,
  211
+		  async_read, re, we_granularity, mode,
  212
+		  clock_domain)
  213
+		self.ports.append(mp)
  214
+		return mp
  215
+
  216
+	def rename_clock_domain(self):
  217
+		for port in self.ports:
  218
+			if port.clock_domain == old:
  219
+				port.clock_domain = new
  220
+
  221
+	def get_clock_domains(self):
  222
+		return set(port.clock_domain for port in self.ports)
  223
+
  224
+	def list_ios(self, ins, outs, inouts):
  225
+		s = set()
  226
+		def add(*sigs):
  227
+			for sig in sigs:
  228
+				if sig is not None:
  229
+					s.add(sig)
  230
+		for p in self.ports:
  231
+			if ins:
  232
+				add(p.adr, p.we, p.dat_w, p.re)
  233
+			if outs:
  234
+				add(p.dat_r)
  235
+		return s
  236
+
  237
+	name_override = "mem"
  238
+
  239
+	@staticmethod
  240
+	def emit_verilog(memory, ns, clock_domains):
  241
+		r = ""
  242
+		gn = ns.get_name # usable instead of verilog_printexpr as ports contain only signals
  243
+		adrbits = bits_for(memory.depth-1)
  244
+		
  245
+		r += "reg [" + str(memory.width-1) + ":0] " \
  246
+			+ gn(memory) \
  247
+			+ "[0:" + str(memory.depth-1) + "];\n"
  248
+
  249
+		adr_regs = {}
  250
+		data_regs = {}
  251
+		for port in memory.ports:
  252
+			if not port.async_read:
  253
+				if port.mode == WRITE_FIRST and port.we is not None:
  254
+					adr_reg = Signal(name_override="memadr")
  255
+					r += "reg [" + str(adrbits-1) + ":0] " \
  256
+						+ gn(adr_reg) + ";\n"
  257
+					adr_regs[id(port)] = adr_reg
  258
+				else:
  259
+					data_reg = Signal(name_override="memdat")
  260
+					r += "reg [" + str(memory.width-1) + ":0] " \
  261
+						+ gn(data_reg) + ";\n"
  262
+					data_regs[id(port)] = data_reg
  263
+
  264
+		for port in memory.ports:
  265
+			r += "always @(posedge " + gn(clock_domains[port.clock_domain].clk) + ") begin\n"
  266
+			if port.we is not None:
  267
+				if port.we_granularity:
  268
+					n = memory.width//port.we_granularity
  269
+					for i in range(n):
  270
+						m = i*port.we_granularity
  271
+						M = (i+1)*port.we_granularity-1
  272
+						sl = "[" + str(M) + ":" + str(m) + "]"
  273
+						r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n"
  274
+						r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n"
  275
+				else:
  276
+					r += "\tif (" + gn(port.we) + ")\n"
  277
+					r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n"
  278
+			if not port.async_read:
  279
+				if port.mode == WRITE_FIRST and port.we is not None:
  280
+					rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n"
  281
+				else:
  282
+					bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n"
  283
+					if port.mode == READ_FIRST or port.we is None:
  284
+						rd = "\t" + bassign
  285
+					elif port.mode == NO_CHANGE:
  286
+						rd = "\tif (!" + gn(port.we) + ")\n" \
  287
+						  + "\t\t" + bassign
  288
+			if port.re is None:
  289
+				r += rd
  290
+			else:
  291
+				r += "\tif (" + gn(port.re) + ")\n"
  292
+				r += "\t" + rd.replace("\n\t", "\n\t\t")
  293
+			r += "end\n\n"
  294
+		
  295
+		for port in memory.ports:
  296
+			if port.async_read:
  297
+				r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n"
  298
+			else:
  299
+				if port.mode == WRITE_FIRST and port.we is not None:
  300
+					r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n"
  301
+				else:
  302
+					r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n"
  303
+		r += "\n"
  304
+		
  305
+		if memory.init is not None:
  306
+			r += "initial begin\n"
  307
+			for i, c in enumerate(memory.init):
  308
+				r += "\t" + gn(memory) + "[" + str(i) + "] <= " + str(memory.width) + "'d" + str(c) + ";\n"
  309
+			r += "end\n\n"
  310
+		
  311
+		return r
147  migen/fhdl/structure.py
@@ -229,126 +229,11 @@ def __getitem__(self, key):
229 229
 		else:
230 230
 			return list.__getitem__(self, key)
231 231
 
232  
-class Tristate:
233  
-	def __init__(self, target, o, oe, i=None):
234  
-		self.target = target
235  
-		self.o = o
236  
-		self.oe = oe
237  
-		self.i = i
238  
-
239  
-class TSTriple:
240  
-	def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0):
241  
-		self.o = Signal(bits_sign, min=min, max=max, reset=reset_o)
242  
-		self.oe = Signal(reset=reset_oe)
243  
-		self.i = Signal(bits_sign, min=min, max=max)
244  
-
245  
-	def get_tristate(self, target):
246  
-		return Tristate(target, self.o, self.oe, self.i)
247  
-
248  
-# extras
249  
-
250  
-class Instance(HUID):
251  
-	def __init__(self, of, *items, name=""):
252  
-		HUID.__init__(self)
253  
-		self.of = of
254  
-		if name:
255  
-			self.name_override = name
256  
-		else:
257  
-			self.name_override = of
258  
-		self.items = items
259  
-	
260  
-	class _IO:
261  
-		def __init__(self, name, expr=None):
262  
-			self.name = name
263  
-			if expr is None:
264  
-				expr = Signal()
265  
-			self.expr = expr
266  
-	class Input(_IO):
267  
-		pass	
268  
-	class Output(_IO):
269  
-		pass
270  
-	class InOut(_IO):
271  
-		pass
272  
-
273  
-	class Parameter:
274  
-		def __init__(self, name, value):
275  
-			self.name = name
276  
-			self.value = value
277  
-	
278  
-	class _CR:
279  
-		def __init__(self, name_inst, domain="sys", invert=False):
280  
-			self.name_inst = name_inst
281  
-			self.domain = domain
282  
-			self.invert = invert
283  
-	class ClockPort(_CR):
284  
-		pass
285  
-	class ResetPort(_CR):
286  
-		pass
287  
-	
288  
-	def get_io(self, name):
289  
-		for item in self.items:
290  
-			if isinstance(item, Instance._IO) and item.name == name:
291  
-				return item.expr
292  
-
293  
-(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
294  
-
295  
-class _MemoryPort:
296  
-	def __init__(self, adr, dat_r, we=None, dat_w=None,
297  
-	  async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST,
298  
-	  clock_domain="sys"):
299  
-		self.adr = adr
300  
-		self.dat_r = dat_r
301  
-		self.we = we
302  
-		self.dat_w = dat_w
303  
-		self.async_read = async_read
304  
-		self.re = re
305  
-		self.we_granularity = we_granularity
306  
-		self.mode = mode
307  
-		self.clock_domain = clock_domain
308  
-
309  
-class Memory(HUID):
310  
-	def __init__(self, width, depth, init=None):
311  
-		HUID.__init__(self)
312  
-		self.width = width
313  
-		self.depth = depth
314  
-		self.ports = []
315  
-		self.init = init
316  
-	
317  
-	def get_port(self, write_capable=False, async_read=False,
318  
-	  has_re=False, we_granularity=0, mode=WRITE_FIRST,
319  
-	  clock_domain="sys"):
320  
-		if we_granularity >= self.width:
321  
-			we_granularity = 0
322  
-		adr = Signal(max=self.depth)
323  
-		dat_r = Signal(self.width)
324  
-		if write_capable:
325  
-			if we_granularity:
326  
-				we = Signal(self.width//we_granularity)
327  
-			else:
328  
-				we = Signal()
329  
-			dat_w = Signal(self.width)
330  
-		else:
331  
-			we = None
332  
-			dat_w = None
333  
-		if has_re:
334  
-			re = Signal()
335  
-		else:
336  
-			re = None
337  
-		mp = _MemoryPort(adr, dat_r, we, dat_w,
338  
-		  async_read, re, we_granularity, mode,
339  
-		  clock_domain)
340  
-		self.ports.append(mp)
341  
-		return mp
342  
-
343  
-#
344  
-
345 232
 class Fragment:
346  
-	def __init__(self, comb=None, sync=None, instances=None, tristates=None, memories=None, sim=None):
  233
+	def __init__(self, comb=None, sync=None, specials=None, sim=None):
347 234
 		if comb is None: comb = []
348 235
 		if sync is None: sync = dict()
349  
-		if instances is None: instances = set()
350  
-		if tristates is None: tristates = set()
351  
-		if memories is None: memories = set()
  236
+		if specials is None: specials = set()
352 237
 		if sim is None: sim = []
353 238
 		
354 239
 		if isinstance(sync, list):
@@ -356,9 +241,7 @@ def __init__(self, comb=None, sync=None, instances=None, tristates=None, memorie
356 241
 		
357 242
 		self.comb = comb
358 243
 		self.sync = sync
359  
-		self.instances = set(instances)
360  
-		self.tristates = set(tristates)
361  
-		self.memories = set(memories)
  244
+		self.specials = set(specials)
362 245
 		self.sim = sim
363 246
 	
364 247
 	def __add__(self, other):
@@ -368,32 +251,14 @@ def __add__(self, other):
368 251
 		for k, v in other.sync.items():
369 252
 			newsync[k].extend(v)
370 253
 		return Fragment(self.comb + other.comb, newsync,
371  
-			self.instances | other.instances,
372  
-			self.tristates | other.tristates,
373  
-			self.memories | other.memories,
  254
+			self.specials | other.specials,
374 255
 			self.sim + other.sim)
375 256
 	
376 257
 	def rename_clock_domain(self, old, new):
377 258
 		self.sync["new"] = self.sync["old"]
378 259
 		del self.sync["old"]
379  
-		for inst in self.instances:
380  
-			for cr in filter(lambda x: isinstance(x, Instance._CR), inst.items):
381  
-				if cr.domain == old:
382  
-					cr.domain = new
383  
-		for mem in self.memories:
384  
-			for port in mem.ports:
385  
-				if port.clock_domain == old:
386  
-					port.clock_domain = new
387  
-
388  
-	def get_clock_domains(self):
389  
-		r = set(self.sync.keys())
390  
-		r |= set(cr.domain 
391  
-			for inst in self.instances
392  
-			for cr in filter(lambda x: isinstance(x, Instance._CR), inst.items))
393  
-		r |= set(port.clock_domain
394  
-			for mem in self.memories
395  
-			for port in mem.ports)
396  
-		return r
  260
+		for special in self.specials:
  261
+			special.rename_clock_domain(old, new)
397 262
 	
398 263
 	def call_sim(self, simulator):
399 264
 		for s in self.sim:
71  migen/fhdl/tools.py
@@ -56,68 +56,17 @@ def group_by_targets(sl):
56 56
 			groups.append((targets, [statement]))
57 57
 	return groups
58 58
 
59  
-def list_inst_ios(i, ins, outs, inouts):
60  
-	if isinstance(i, Fragment):
61  
-		return list_inst_ios(i.instances, ins, outs, inouts)
62  
-	elif isinstance(i, set):
63  
-		if i:
64  
-			return set.union(*(list_inst_ios(e, ins, outs, inouts) for e in i))
65  
-		else:
66  
-			return set()
67  
-	elif isinstance(i, Instance):
68  
-		subsets = [list_signals(item.expr) for item in filter(lambda x:
69  
-			(ins and isinstance(x, Instance.Input))
70  
-			or (outs and isinstance(x, Instance.Output))
71  
-			or (inouts and isinstance(x, Instance.InOut)),
72  
-			i.items)]
73  
-		if subsets:
74  
-			return set.union(*subsets)
75  
-		else:
76  
-			return set()
77  
-	else:
78  
-		return set()
  59
+def list_special_ios(f, ins, outs, inouts):
  60
+	r = set()
  61
+	for special in f.specials:
  62
+		r |= special.list_ios(ins, outs, inouts)
  63
+	return r
79 64
 
80  
-def list_tristate_ios(i, ins, outs, inouts):
81  
-	if isinstance(i, Fragment):
82  
-		return list_tristate_ios(i.tristates, ins, outs, inouts)
83  
-	elif isinstance(i, set):
84  
-		if i:
85  
-			return set.union(*(list_tristate_ios(e, ins, outs, inouts) for e in i))
86  
-		else:
87  
-			return set()
88  
-	elif isinstance(i, Tristate):
89  
-		r = set()
90  
-		if inouts:
91  
-			r.update(list_signals(i.target))
92  
-		if ins:
93  
-			r.update(list_signals(i.o))
94  
-			r.update(list_signals(i.oe))
95  
-		if outs:
96  
-			r.update(list_signals(i.i))
97  
-		return r
98  
-	else:
99  
-		return set()
100  
-
101  
-def list_it_ios(i, ins, outs, inouts):
102  
-	return list_inst_ios(i, ins, outs, inouts) \
103  
-		| list_tristate_ios(i, ins, outs, inouts)
104  
-
105  
-def list_mem_ios(m, ins, outs):
106  
-	if isinstance(m, Fragment):
107  
-		return list_mem_ios(m.memories, ins, outs)
108  
-	else:
109  
-		s = set()
110  
-		def add(*sigs):
111  
-			for sig in sigs:
112  
-				if sig is not None:
113  
-					s.add(sig)
114  
-		for x in m:
115  
-			for p in x.ports:
116  
-				if ins:
117  
-					add(p.adr, p.we, p.dat_w, p.re)
118  
-				if outs:
119  
-					add(p.dat_r)
120  
-		return s
  65
+def list_clock_domains(f):
  66
+	r = set(f.sync.keys())
  67
+	for special in f.specials:
  68
+		r |= special.get_clock_domains()
  69
+	return r
121 70
 
122 71
 def is_variable(node):
123 72
 	if isinstance(node, Signal):
83  migen/fhdl/verilog.py
@@ -5,7 +5,6 @@
5 5
 from migen.fhdl.structure import _Operator, _Slice, _Assign
6 6
 from migen.fhdl.tools import *
7 7
 from migen.fhdl.namer import Namespace, build_namespace
8  
-from migen.fhdl import verilog_behavioral as behavioral
9 8
 
10 9
 def _printsig(ns, s):
11 10
 	if s.signed:
@@ -135,9 +134,9 @@ def _list_comb_wires(f):
135 134
 	return r
136 135
 
137 136
 def _printheader(f, ios, name, ns):
138  
-	sigs = list_signals(f) | list_it_ios(f, True, True, True) | list_mem_ios(f, True, True)
139  
-	it_mem_outs = list_it_ios(f, False, True, False) | list_mem_ios(f, False, True)
140  
-	inouts = list_it_ios(f, False, False, True)
  137
+	sigs = list_signals(f) | list_special_ios(f, True, True, True)
  138
+	it_mem_outs = list_special_ios(f, False, True, False)
  139
+	inouts = list_special_ios(f, False, False, True)
141 140
 	targets = list_targets(f) | it_mem_outs
142 141
 	wires = _list_comb_wires(f) | it_mem_outs
143 142
 	r = "module " + name + "(\n"
@@ -209,66 +208,10 @@ def _printsync(f, ns, clock_domains):
209 208
 		r += "end\n\n"
210 209
 	return r
211 210
 
212  
-def _printinstances(f, ns, clock_domains):
  211
+def _printspecials(f, ns, clock_domains):
213 212
 	r = ""
214  
-	for x in f.instances:
215  
-		parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), x.items))
216  
-		r += x.of + " "
217  
-		if parameters:
218  
-			r += "#(\n"
219  
-			firstp = True
220  
-			for p in parameters:
221  
-				if not firstp:
222  
-					r += ",\n"
223  
-				firstp = False
224  
-				r += "\t." + p.name + "("
225  
-				if isinstance(p.value, (int, bool)):
226  
-					r += _printintbool(p.value)[0]
227  
-				elif isinstance(p.value, float):
228  
-					r += str(p.value)
229  
-				elif isinstance(p.value, str):
230  
-					r += "\"" + p.value + "\""
231  
-				else:
232  
-					raise TypeError
233  
-				r += ")"
234  
-			r += "\n) "
235  
-		r += ns.get_name(x) 
236  
-		if parameters: r += " "
237  
-		r += "(\n"
238  
-		firstp = True
239  
-		for p in x.items:
240  
-			if isinstance(p, Instance._IO):
241  
-				name_inst = p.name
242  
-				name_design = _printexpr(ns, p.expr)[0]
243  
-			elif isinstance(p, Instance.ClockPort):
244  
-				name_inst = p.name_inst
245  
-				name_design = ns.get_name(clock_domains[p.domain].clk)
246  
-				if p.invert:
247  
-					name_design = "~" + name_design
248  
-			elif isinstance(p, Instance.ResetPort):
249  
-				name_inst = p.name_inst
250  
-				name_design = ns.get_name(clock_domains[p.domain].rst)
251  
-			else:
252  
-				continue
253  
-			if not firstp:
254  
-				r += ",\n"
255  
-			firstp = False
256  
-			r += "\t." + name_inst + "(" + name_design + ")"
257  
-		if not firstp:
258  
-			r += "\n"
259  
-		r += ");\n\n"
260  
-	return r
261  
-
262  
-def _printtristates(f, ns, handler):
263  
-	r = ""
264  
-	for tristate in f.tristates:
265  
-		r += handler(tristate, ns)
266  
-	return r
267  
-
268  
-def _printmemories(f, ns, handler, clock_domains):
269  
-	r = ""
270  
-	for memory in f.memories:
271  
-		r += handler(memory, ns, clock_domains)
  213
+	for special in sorted(f.specials, key=lambda x: x.huid):
  214
+		r += special.emit_verilog(special, ns, clock_domains)
272 215
 	return r
273 216
 
274 217
 def _printinit(f, ios, ns):
@@ -276,8 +219,7 @@ def _printinit(f, ios, ns):
276 219
 	signals = list_signals(f) \
277 220
 		- ios \
278 221
 		- list_targets(f) \
279  
-		- list_it_ios(f, False, True, False) \
280  
-		- list_mem_ios(f, False, True)
  222
+		- list_special_ios(f, False, True, False)
281 223
 	if signals:
282 224
 		r += "initial begin\n"
283 225
 		for s in sorted(signals, key=lambda x: x.huid):
@@ -288,14 +230,12 @@ def _printinit(f, ios, ns):
288 230
 def convert(f, ios=None, name="top",
289 231
   clock_domains=None,
290 232
   return_ns=False,
291  
-  memory_handler=behavioral.mem_handler,
292  
-  tristate_handler=behavioral.tristate_handler,
293 233
   display_run=False):
294 234
 	if ios is None:
295 235
 		ios = set()
296 236
 	if clock_domains is None:
297 237
 		clock_domains = dict()
298  
-		for d in f.get_clock_domains():
  238
+		for d in list_clock_domains(f):
299 239
 			cd = ClockDomain(d)
300 240
 			clock_domains[d] = cd
301 241
 			ios.add(cd.clk)
@@ -304,17 +244,14 @@ def convert(f, ios=None, name="top",
304 244
 	f = lower_arrays(f)
305 245
 
306 246
 	ns = build_namespace(list_signals(f) \
307  
-		| list_it_ios(f, True, True, True) \
308  
-		| list_mem_ios(f, True, True) \
  247
+		| list_special_ios(f, True, True, True) \
309 248
 		| ios)
310 249
 
311 250
 	r = "/* Machine-generated using Migen */\n"
312 251
 	r += _printheader(f, ios, name, ns)
313 252
 	r += _printcomb(f, ns, display_run)
314 253
 	r += _printsync(f, ns, clock_domains)
315  
-	r += _printinstances(f, ns, clock_domains)
316  
-	r += _printtristates(f, ns, tristate_handler)
317  
-	r += _printmemories(f, ns, memory_handler, clock_domains)
  254
+	r += _printspecials(f, ns, clock_domains)
318 255
 	r += _printinit(f, ios, ns)
319 256
 	r += "endmodule\n"
320 257
 
86  migen/fhdl/verilog_behavioral.py
... ...
@@ -1,86 +0,0 @@
1  
-from migen.fhdl.structure import *
2  
-from migen.fhdl.tools import *
3  
-
4  
-def mem_handler(memory, ns, clock_domains):
5  
-	r = ""
6  
-	gn = ns.get_name
7  
-	adrbits = bits_for(memory.depth-1)
8  
-	
9  
-	r += "reg [" + str(memory.width-1) + ":0] " \
10  
-		+ gn(memory) \
11  
-		+ "[0:" + str(memory.depth-1) + "];\n"
12  
-
13  
-	adr_regs = {}
14  
-	data_regs = {}
15  
-	for port in memory.ports:
16  
-		if not port.async_read:
17  
-			if port.mode == WRITE_FIRST and port.we is not None:
18  
-				adr_reg = Signal(name_override="memadr")
19  
-				r += "reg [" + str(adrbits-1) + ":0] " \
20  
-					+ gn(adr_reg) + ";\n"
21  
-				adr_regs[id(port)] = adr_reg
22  
-			else:
23  
-				data_reg = Signal(name_override="memdat")
24  
-				r += "reg [" + str(memory.width-1) + ":0] " \
25  
-					+ gn(data_reg) + ";\n"
26  
-				data_regs[id(port)] = data_reg
27  
-
28  
-	for port in memory.ports:
29  
-		r += "always @(posedge " + gn(clock_domains[port.clock_domain].clk) + ") begin\n"
30  
-		if port.we is not None:
31  
-			if port.we_granularity:
32  
-				n = memory.width//port.we_granularity
33  
-				for i in range(n):
34  
-					m = i*port.we_granularity
35  
-					M = (i+1)*port.we_granularity-1
36  
-					sl = "[" + str(M) + ":" + str(m) + "]"
37  
-					r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n"
38  
-					r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n"
39  
-			else:
40  
-				r += "\tif (" + gn(port.we) + ")\n"
41  
-				r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n"
42  
-		if not port.async_read:
43  
-			if port.mode == WRITE_FIRST and port.we is not None:
44  
-				rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n"
45  
-			else:
46  
-				bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n"
47  
-				if port.mode == READ_FIRST or port.we is None:
48  
-					rd = "\t" + bassign
49  
-				elif port.mode == NO_CHANGE:
50  
-					rd = "\tif (!" + gn(port.we) + ")\n" \
51  
-					  + "\t\t" + bassign
52  
-		if port.re is None:
53  
-			r += rd
54  
-		else:
55  
-			r += "\tif (" + gn(port.re) + ")\n"
56  
-			r += "\t" + rd.replace("\n\t", "\n\t\t")
57  
-		r += "end\n\n"
58  
-	
59  
-	for port in memory.ports:
60  
-		if port.async_read:
61  
-			r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n"
62  
-		else:
63  
-			if port.mode == WRITE_FIRST and port.we is not None:
64  
-				r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n"
65  
-			else:
66  
-				r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n"
67  
-	r += "\n"
68  
-	
69  
-	if memory.init is not None:
70  
-		r += "initial begin\n"
71  
-		for i, c in enumerate(memory.init):
72  
-			r += "\t" + gn(memory) + "[" + str(i) + "] <= " + str(memory.width) + "'d" + str(c) + ";\n"
73  
-		r += "end\n\n"
74  
-	
75  
-	return r
76  
-
77  
-def tristate_handler(tristate, ns):
78  
-	gn = ns.get_name
79  
-	w, s = value_bits_sign(tristate.target)
80  
-	r = "assign " + gn(tristate.target) + " = " \
81  
-		+ gn(tristate.oe) + " ? " + gn(tristate.o) \
82  
-		+ " : " + str(w) + "'bz;\n"
83  
-	if tristate.i is not None:
84  
-		r += "assign " + gn(tristate.i) + " = " + gn(tristate.target) + ";\n"
85  
-	r += "\n"
86  
-	return r
1  migen/pytholite/io.py
@@ -2,6 +2,7 @@
2 2
 from itertools import zip_longest
3 3
 
4 4
 from migen.fhdl.structure import *
  5
+from migen.fhdl.specials import Memory
5 6
 from migen.uio.ioo import UnifiedIOObject
6 7
 from migen.flow.actor import Source, Sink
7 8
 from migen.flow.transactions import *
1  migen/sim/generic.py
@@ -2,6 +2,7 @@
2 2
 # License: GPLv3 with additional permissions (see README).
3 3
 
4 4
 from migen.fhdl.structure import *
  5
+from migen.fhdl.specials import Memory
5 6
 from migen.fhdl import verilog
6 7
 from migen.sim.ipc import *
7 8
 from migen.sim import icarus
3  migen/uio/ioo.py
... ...
@@ -1,4 +1,5 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.specials import Memory
2 3
 from migen.flow.actor import *
3 4
 from migen.flow.transactions import *
4 5
 from migen.actorlib.sim import TokenExchanger
@@ -14,7 +15,7 @@ def __init__(self, dataflow=None, buses={}):
14 15
 		self._memories = set(v for v in self.buses.values() if isinstance(v, Memory))
15 16
 	
16 17
 	def get_fragment(self):
17  
-		return Fragment(memories=self._memories)
  18
+		return Fragment(specials={self._memories})
18 19
 
19 20
 (_WAIT_COMPLETE, _WAIT_POLL) = range(2)
20 21
 

0 notes on commit 49cfba5

Please sign in to comment.
Something went wrong with that request. Please try again.