3 function for the relationship between regspecs and Decode2Execute1Type
5 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
7 from nmigen
import Const
8 from soc
.regfile
.regfiles
import XERRegs
, FastRegs
9 from soc
.decoder
.power_enums
import CryIn
12 def regspec_decode(e
, regfile
, name
):
15 this function encodes the understanding (relationship) between
16 Regfiles, Computation Units, and the Power ISA Decoder (PowerDecoder2).
18 based on the regspec, which contains the register file name and register
19 name, return a tuple of:
21 * how the decoder should determine whether the Function Unit needs
23 * which Regfile port should be read to get that data
24 * when it comes to writing: likewise, which Regfile port should be written
26 Note that some of the port numbering encoding is *unary*. in the case
27 of "Full Condition Register", it's a full 8-bit mask of read/write-enables.
28 This actually matches directly with the XFX field in MTCR, and at
29 some point that 8-bit mask from the instruction could actually be passed directly through to full_cr (TODO).
31 For the INT and CR numbering, these are expressed in binary in the
32 instruction (note however that XFX in MTCR is unary-masked!)
34 XER is implicitly-encoded based on whether the operation has carry or
37 FAST regfile is, again, implicitly encoded, back in PowerDecode2, based
38 on the type of operation (see DecodeB for an example).
40 The SPR regfile on the other hand is *binary*-encoded, and, furthermore,
45 # Int register numbering is *unary* encoded
47 return e
.read_reg1
.ok
, 1<<e
.read_reg1
.data
, None
49 return e
.read_reg2
.ok
, 1<<e
.read_reg2
.data
, None
51 return e
.read_reg3
.ok
, 1<<e
.read_reg3
.data
, None
53 return e
.write_reg
.ok
, None, 1<<e
.write_reg
.data
54 if name
== 'o1': # RA (update mode: LD/ST EA)
55 return e
.write_ea
.ok
, None, 1<<e
.write_ea
.data
58 # CRRegs register numbering is *unary* encoded
59 if name
== 'full_cr': # full CR
60 return e
.read_cr_whole
, 0b11111111, 0b11111111
61 if name
== 'cr_a': # CR A
62 return e
.read_cr1
.ok
, 1<<e
.read_cr1
.data
, 1<<e
.write_cr
.data
63 if name
== 'cr_b': # CR B
64 return e
.read_cr2
.ok
, 1<<e
.read_cr2
.data
, None
65 if name
== 'cr_c': # CR C
66 return e
.read_cr3
.ok
, 1<<e
.read_cr2
.data
, None
69 # XERRegs register numbering is *unary* encoded
74 return e
.oe
.oe
[0] & e
.oe
.oe_ok
, SO
, SO
76 return e
.oe
.oe
[0] & e
.oe
.oe_ok
, OV
, OV
78 return (e
.input_carry
== CryIn
.CA
.value
), CA
, CA
81 # FAST register numbering is *unary* encoded
87 SRR1
= 1<<FastRegs
.SRR1
88 SRR2
= 1<<FastRegs
.SRR2
89 if name
in ['cia', 'nia']:
90 return Const(1), PC
, PC
# TODO: detect read-conditions
92 return Const(1), MSR
, MS
# TODO: detect read-conditions
93 # TODO: remap the SPR numbers to FAST regs
95 return e
.read_fast1
.ok
, 1<<e
.read_fast1
.data
, 1<<e
.write_fast1
.data
97 return e
.read_fast2
.ok
, 1<<e
.read_fast2
.data
, 1<<e
.write_fast2
.data
100 assert False, "regfile TODO %s %s %d" % (refgile
, repr(regspec
), idx
)
101 assert False, "regspec not found %s %s %d" % (refgile
, repr(regspec
), idx
)