Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / src / decoder / power_major_decoder.py
1 from nmigen import Module, Elaboratable, Signal
2 import csv
3 import os
4 from enum import Enum, unique
5
6
7 @unique
8 class Function(Enum):
9 ALU = 0
10 LDST = 1
11
12
13 @unique
14 class InternalOp(Enum):
15 OP_ADD = 0
16 OP_AND = 1
17 OP_B = 2
18 OP_BC = 3
19 OP_CMP = 4
20 OP_LOAD = 5
21 OP_MUL_L64 = 6
22 OP_OR = 7
23 OP_RLC = 8
24 OP_STORE = 9
25 OP_TDI = 10
26 OP_XOR = 11
27
28
29 @unique
30 class In1Sel(Enum):
31 RA = 0
32 RA_OR_ZERO = 1
33 NONE = 2
34 SPR = 3
35
36
37 @unique
38 class In2Sel(Enum):
39 CONST_SI = 0
40 CONST_SI_HI = 1
41 CONST_UI = 2
42 CONST_UI_HI = 3
43 CONST_LI = 4
44 CONST_BD = 5
45 CONST_SH32 = 6
46 RB = 7
47
48
49 @unique
50 class In3Sel(Enum):
51 NONE = 0
52 RS = 1
53
54
55 @unique
56 class OutSel(Enum):
57 RT = 0
58 RA = 1
59 NONE = 2
60 SPR = 3
61
62
63
64 def get_csv(name):
65 file_dir = os.path.dirname(os.path.realpath(__file__))
66 with open(os.path.join(file_dir, name)) as csvfile:
67 reader = csv.DictReader(csvfile)
68 return list(reader)
69
70
71 major_opcodes = get_csv("major.csv")
72
73
74 class PowerMajorDecoder(Elaboratable):
75 def __init__(self):
76 self.opcode_in = Signal(6, reset_less=True)
77
78 self.function_unit = Signal(Function, reset_less=True)
79 self.internal_op = Signal(InternalOp, reset_less=True)
80 self.in1_sel = Signal(In1Sel, reset_less=True)
81 self.in2_sel = Signal(In2Sel, reset_less=True)
82 self.in3_sel = Signal(In3Sel, reset_less=True)
83 self.out_sel = Signal(OutSel, reset_less=True)
84
85 def elaborate(self, platform):
86 m = Module()
87 comb = m.d.comb
88
89 with m.Switch(self.opcode_in):
90 for row in major_opcodes:
91 opcode = int(row['opcode'])
92 with m.Case(opcode):
93 comb += self.function_unit.eq(Function[row['unit']])
94 comb += self.internal_op.eq(InternalOp[row['internal op']])
95 comb += self.in1_sel.eq(In1Sel[row['in1']])
96 comb += self.in2_sel.eq(In2Sel[row['in2']])
97 comb += self.in3_sel.eq(In3Sel[row['in3']])
98 comb += self.out_sel.eq(OutSel[row['out']])
99 return m
100
101 def ports(self):
102 return [self.opcode_in,
103 self.function_unit,
104 self.in1_sel,
105 self.in2_sel,
106 self.in3_sel,
107 self.out_sel,
108 self.internal_op]