bd9469888754ac2883d378e38eac273f323db3e6
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
):
127 si
= yield self
.decoder
.SI
128 self
.namespace
['SI'] = SelectableInt(si
, bits
=16)
130 def call(self
, name
):
131 yield from self
.prep_namespace()
133 function
, read_regs
, uninit_regs
, write_regs
= self
.instrs
[name
]
134 input_names
= create_args(read_regs | uninit_regs
)
138 for name
in input_names
:
139 regnum
= yield getattr(self
.decoder
, name
)
140 print('reading reg %d' % regnum
)
141 inputs
.append(self
.gpr(regnum
))
143 results
= function(self
, *inputs
)
146 output_names
= create_args(write_regs
)
147 for name
, output
in zip(output_names
, results
):
148 regnum
= yield getattr(self
.decoder
, name
)
149 print('writing reg %d' % regnum
)
150 self
.gpr
[regnum
] = output
.narrow(64)
154 """ Decorator factory. """
155 def variable_injector(func
):
157 def decorator(*args
, **kwargs
):
159 func_globals
= func
.__globals
__ # Python 2.6+
160 except AttributeError:
161 func_globals
= func
.func_globals
# Earlier versions.
163 context
= args
[0].namespace
164 saved_values
= func_globals
.copy() # Shallow copy of dict.
165 func_globals
.update(context
)
167 result
= func(*args
, **kwargs
)
168 #exec (func.__code__, func_globals)
171 # func_globals = saved_values # Undo changes.
177 return variable_injector