1 """ Example 5: Making use of PyRTL and Introspection. """
3 from nmigen
import Signal
4 from nmigen
.compat
.fhdl
.bitcontainer
import value_bits_sign
6 # The following example shows how pyrtl can be used to make some interesting
7 # hardware structures using python introspection. In particular, this example
8 # makes a N-stage pipeline structure. Any specific pipeline is then a derived
9 # class of SimplePipeline where methods with names starting with "stage" are
10 # stages, and new members with names not starting with "_" are to be registered
13 from singlepipe
import eq
15 class SimplePipeline(object):
16 """ Pipeline builder with auto generation of pipeline registers.
19 def __init__(self
, pipe
):
21 self
._pipeline
_register
_map
= {}
22 self
._current
_stage
_num
= 0
26 for method
in dir(self
):
27 if method
.startswith('stage'):
28 stage_list
.append(method
)
29 for stage
in sorted(stage_list
):
30 stage_method
= getattr(self
, stage
)
32 self
._current
_stage
_num
+= 1
34 def __getattr__(self
, name
):
36 return self
._pipeline
_register
_map
[self
._current
_stage
_num
][name
]
39 'error, no pipeline register "%s" defined for stage %d'
40 % (name
, self
._current
_stage
_num
))
42 def __setattr__(self
, name
, value
):
43 if name
.startswith('_'):
44 # do not do anything tricky with variables starting with '_'
45 object.__setattr
__(self
, name
, value
)
47 next_stage
= self
._current
_stage
_num
+ 1
48 pipereg_id
= str(self
._current
_stage
_num
) + 'to' + str(next_stage
)
49 rname
= 'pipereg_' + pipereg_id
+ '_' + name
50 #new_pipereg = Signal(value_bits_sign(value), name=rname,
52 new_pipereg
= Signal
.like(value
, name
=rname
, reset_less
= True)
53 if next_stage
not in self
._pipeline
_register
_map
:
54 self
._pipeline
_register
_map
[next_stage
] = {}
55 self
._pipeline
_register
_map
[next_stage
][name
] = new_pipereg
56 self
._pipe
.sync
+= eq(new_pipereg
, value
)