attempt to make carry-in and overflow-enable optional on ALU
[soc.git] / src / soc / decoder / power_regspec_map.py
1 """regspec_decode
2
3 function for the relationship between regspecs and Decode2Execute1Type
4
5 see https://libre-soc.org/3d_gpu/architecture/regfile/ section on regspecs
6 """
7 from nmigen import Const
8 from soc.regfile.regfiles import XERRegs, FastRegs
9
10
11 def regspec_decode(e, regfile, name):
12 """regspec_decode
13
14 this function encodes the understanding (relationship) between
15 Regfiles, Computation Units, and the Power ISA Decoder (PowerDecoder2).
16
17 based on the regspec, which contains the register file name and register
18 name, return a tuple of:
19
20 * how the decoder should determine whether the Function Unit needs
21 a Regport or not
22 * which Regfile port should be read to get that data
23 * when it comes to writing: likewise, which Regfile port should be written
24
25 Note that some of the port numbering encoding is *unary*. in the case
26 of "Full Condition Register", it's a full 8-bit mask of read/write-enables.
27 This actually matches directly with the XFX field in MTCR, and at
28 some point that 8-bit mask from the instruction could actually be passed directly through to full_cr (TODO).
29
30 For the INT and CR numbering, these are expressed in binary in the
31 instruction (note however that XFX in MTCR is unary-masked!)
32
33 XER is implicitly-encoded based on whether the operation has carry or
34 overflow.
35
36 FAST regfile is, again, implicitly encoded, back in PowerDecode2, based
37 on the type of operation (see DecodeB for an example).
38
39 The SPR regfile on the other hand is *binary*-encoded, and, furthermore,
40 has to be "remapped".
41 """
42
43 if regfile == 'INT':
44 # Int register numbering is *unary* encoded
45 if name == 'ra': # RA
46 return e.read_reg1.ok, 1<<e.read_reg1.data, None
47 if name == 'rb': # RB
48 return e.read_reg2.ok, 1<<e.read_reg2.data, None
49 if name == 'rc': # RS
50 return e.read_reg3.ok, 1<<e.read_reg3.data, None
51 if name == 'o': # RT
52 return e.write_reg.ok, None, 1<<e.write_reg.data
53 if name == 'o1': # RA (update mode: LD/ST EA)
54 return e.write_ea.ok, None, 1<<e.write_ea.data
55
56 if regfile == 'CR':
57 # CRRegs register numbering is *unary* encoded
58 if name == 'full_cr': # full CR
59 return e.read_cr_whole, 0b11111111, 0b11111111
60 if name == 'cr_a': # CR A
61 return e.read_cr1.ok, 1<<e.read_cr1.data, 1<<e.write_cr.data
62 if name == 'cr_b': # CR B
63 return e.read_cr2.ok, 1<<e.read_cr2.data, None
64 if name == 'cr_c': # CR C
65 return e.read_cr3.ok, 1<<e.read_cr2.data, None
66
67 if regfile == 'XER':
68 # XERRegs register numbering is *unary* encoded
69 SO = 1<<XERRegs.SO
70 CA = 1<<XERRegs.CA
71 OV = 1<<XERRegs.OV
72 if name == 'xer_so':
73 #return e.oe.oe & e.oe.oe_ok, SO, SO
74 return Const(1), SO, SO # TODO
75 if name == 'xer_ov':
76 return Const(1), OV, OV # TODO
77 return e.oe.oe & e.oe.oe_ok, OV, OV
78 if name == 'xer_ca':
79 return Const(1), CA, CA # TODO
80 #return e.input_carry, CA, CA
81
82 if regfile == 'FAST':
83 # FAST register numbering is *unary* encoded
84 PC = 1<<FastRegs.PC
85 MSR = 1<<FastRegs.MSR
86 CTR = 1<<FastRegs.CTR
87 LR = 1<<FastRegs.LR
88 TAR = 1<<FastRegs.TAR
89 SRR1 = 1<<FastRegs.SRR1
90 SRR2 = 1<<FastRegs.SRR2
91 if name in ['cia', 'nia']:
92 return Const(1), PC, PC # TODO: detect read-conditions
93 if name == 'msr':
94 return Const(1), MSR, MS # TODO: detect read-conditions
95 # TODO: remap the SPR numbers to FAST regs
96 if name == 'spr1':
97 return e.read_fast1.ok, 1<<e.read_fast1.data, 1<<e.write_fast1.data
98 if name == 'spr2':
99 return e.read_fast2.ok, 1<<e.read_fast2.data, 1<<e.write_fast2.data
100
101 if regfile == 'SPR':
102 assert False, "regfile TODO %s %s %d" % (refgile, repr(regspec), idx)
103 assert False, "regspec not found %s %s %d" % (refgile, repr(regspec), idx)