1 from functools
import wraps
2 from soc
.decoder
.orderedset
import OrderedSet
3 from soc
.decoder
.selectable_int
import SelectableInt
, selectconcat
6 def create_args(reglist
, extra
=None):
17 def __init__(self
, bytes_per_word
=8):
19 self
.bytes_per_word
= bytes_per_word
20 self
.word_log2
= math
.ceil(math
.log2(bytes_per_word
))
22 def _get_shifter_mask(self
, width
, remainder
):
23 shifter
= ((self
.bytes_per_word
- width
) - remainder
) * \
25 mask
= (1 << (width
* 8)) - 1
28 # TODO: Implement ld/st of lesser width
29 def ld(self
, address
, width
=8):
30 remainder
= address
& (self
.bytes_per_word
- 1)
31 address
= address
>> self
.word_log2
32 assert remainder
& (width
- 1) == 0, "Unaligned access unsupported!"
33 if address
in self
.mem
:
34 val
= self
.mem
[address
]
38 if width
!= self
.bytes_per_word
:
39 shifter
, mask
= self
._get
_shifter
_mask
(width
, remainder
)
40 val
= val
& (mask
<< shifter
)
42 print("Read {:x} from addr {:x}".format(val
, address
))
45 def st(self
, address
, value
, width
=8):
46 remainder
= address
& (self
.bytes_per_word
- 1)
47 address
= address
>> self
.word_log2
48 assert remainder
& (width
- 1) == 0, "Unaligned access unsupported!"
49 print("Writing {:x} to addr {:x}".format(value
, address
))
50 if width
!= self
.bytes_per_word
:
51 if address
in self
.mem
:
52 val
= self
.mem
[address
]
55 shifter
, mask
= self
._get
_shifter
_mask
(width
, remainder
)
56 val
&= ~
(mask
<< shifter
)
57 val |
= value
<< shifter
58 self
.mem
[address
] = val
60 self
.mem
[address
] = value
62 def __call__(self
, addr
, sz
):
63 val
= self
.ld(addr
.value
, sz
)
64 print ("memread", addr
, sz
, val
)
65 return SelectableInt(val
, sz
*8)
67 def memassign(self
, addr
, sz
, val
):
68 print ("memassign", addr
, sz
, val
)
69 self
.st(addr
.value
, val
.value
, sz
)
73 def __init__(self
, decoder
, regfile
):
77 self
[i
] = SelectableInt(regfile
[i
], 64)
79 def __call__(self
, ridx
):
82 def set_form(self
, form
):
86 #rnum = rnum.value # only SelectableInt allowed
87 print("GPR getzero", rnum
)
89 return SelectableInt(0, 64)
92 def _get_regnum(self
, attr
):
93 getform
= self
.sd
.sigforms
[self
.form
]
94 rnum
= getattr(getform
, attr
)
97 def ___getitem__(self
, attr
):
98 print("GPR getitem", attr
)
99 rnum
= self
._get
_regnum
(attr
)
100 return self
.regfile
[rnum
]
103 for i
in range(0, len(self
), 8):
106 s
.append("%08x" % self
[i
+j
].value
)
108 print("reg", "%2d" % i
, s
)
112 # decoder2 - an instance of power_decoder2
113 # regfile - a list of initial values for the registers
114 def __init__(self
, decoder2
, regfile
):
115 self
.gpr
= GPR(decoder2
, regfile
)
117 self
.namespace
= {'GPR': self
.gpr
,
119 'memassign': self
.memassign
121 self
.decoder
= decoder2
123 def memassign(self
, ea
, sz
, val
):
124 self
.mem
.memassign(ea
, sz
, val
)
126 def prep_namespace(self
, formname
, op_fields
):
127 # TODO: get field names from form in decoder*1* (not decoder2)
128 # decoder2 is hand-created, and decoder1.sigform is auto-generated
130 # then "yield" fields only from op_fields rather than hard-coded
132 for name
in ['SI', 'UI', 'D', 'BD']:
133 signal
= getattr(self
.decoder
, name
)
135 self
.namespace
[name
] = SelectableInt(val
, bits
=signal
.width
)
137 def call(self
, name
):
138 function
, read_regs
, uninit_regs
, write_regs
, op_fields
, form \
140 yield from self
.prep_namespace(form
, op_fields
)
142 input_names
= create_args(read_regs | uninit_regs
)
146 for name
in input_names
:
147 regnum
= yield getattr(self
.decoder
, name
)
149 self
.namespace
[regname
] = regnum
150 print('reading reg %d' % regnum
)
151 inputs
.append(self
.gpr(regnum
))
153 results
= function(self
, *inputs
)
157 output_names
= create_args(write_regs
)
158 for name
, output
in zip(output_names
, results
):
159 regnum
= yield getattr(self
.decoder
, name
)
160 print('writing reg %d' % regnum
)
162 output
= SelectableInt(output
.value
, 64)
163 self
.gpr
[regnum
] = output
167 """ Decorator factory. """
168 def variable_injector(func
):
170 def decorator(*args
, **kwargs
):
172 func_globals
= func
.__globals
__ # Python 2.6+
173 except AttributeError:
174 func_globals
= func
.func_globals
# Earlier versions.
176 context
= args
[0].namespace
177 saved_values
= func_globals
.copy() # Shallow copy of dict.
178 func_globals
.update(context
)
180 result
= func(*args
, **kwargs
)
181 #exec (func.__code__, func_globals)
184 # func_globals = saved_values # Undo changes.
190 return variable_injector