39d99d5e4fbe4d6fec12999e48e0514e6835bdfe
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 fields
= self
.decoder
.sigforms
[formname
]
133 for name
in fields
._fields
:
134 if name
not in ["RA", "RB", "RT"]:
135 sig
= getattr(fields
, name
)
137 self
.namespace
[name
] = SelectableInt(val
, sig
.width
)
139 def call(self
, name
):
140 # TODO, asmregs is from the spec, e.g. add RT,RA,RB
141 # see http://bugs.libre-riscv.org/show_bug.cgi?id=282
142 fn
, read_regs
, uninit_regs
, write_regs
, op_fields
, form
, asmregs \
144 yield from self
.prep_namespace(form
, op_fields
)
146 input_names
= create_args(read_regs | uninit_regs
)
150 for name
in input_names
:
151 regnum
= yield getattr(self
.decoder
, name
)
153 self
.namespace
[regname
] = regnum
154 print('reading reg %d' % regnum
)
155 inputs
.append(self
.gpr(regnum
))
157 results
= fn(self
, *inputs
)
161 output_names
= create_args(write_regs
)
162 for name
, output
in zip(output_names
, results
):
163 regnum
= yield getattr(self
.decoder
, name
)
164 print('writing reg %d' % regnum
)
166 output
= SelectableInt(output
.value
, 64)
167 self
.gpr
[regnum
] = output
171 """ Decorator factory. """
172 def variable_injector(func
):
174 def decorator(*args
, **kwargs
):
176 func_globals
= func
.__globals
__ # Python 2.6+
177 except AttributeError:
178 func_globals
= func
.func_globals
# Earlier versions.
180 context
= args
[0].namespace
181 saved_values
= func_globals
.copy() # Shallow copy of dict.
182 func_globals
.update(context
)
184 result
= func(*args
, **kwargs
)
185 #exec (func.__code__, func_globals)
188 # func_globals = saved_values # Undo changes.
194 return variable_injector