Add code to download csv files from wiki if they don't exist
[soc.git] / src / decoder / power_major_decoder.py
1 from nmigen import Module, Elaboratable, Signal
2 from power_enums import (Function, InternalOp, In1Sel, In2Sel, In3Sel,
3 OutSel, RC, LdstLen, CryIn, get_csv)
4
5
6 # names of the fields in major.csv that don't correspond to an enum
7 single_bit_flags = ['CR in', 'CR out', 'inv A', 'inv out',
8 'cry out', 'BR', 'sgn ext', 'upd', 'rsrv', '32b',
9 'sgn', 'lk', 'sgl pipe']
10
11
12 def get_signal_name(name):
13 return name.lower().replace(' ', '_')
14
15
16
17
18 major_opcodes = get_csv("major.csv")
19
20
21 class PowerMajorDecoder(Elaboratable):
22 def __init__(self):
23 self.opcode_in = Signal(6, reset_less=True)
24
25 self.function_unit = Signal(Function, reset_less=True)
26 self.internal_op = Signal(InternalOp, reset_less=True)
27 self.in1_sel = Signal(In1Sel, reset_less=True)
28 self.in2_sel = Signal(In2Sel, reset_less=True)
29 self.in3_sel = Signal(In3Sel, reset_less=True)
30 self.out_sel = Signal(OutSel, reset_less=True)
31 self.ldst_len = Signal(LdstLen, reset_less=True)
32 self.rc_sel = Signal(RC, reset_less=True)
33 self.cry_in = Signal(CryIn, reset_less=True)
34 for bit in single_bit_flags:
35 name = get_signal_name(bit)
36 setattr(self, name,
37 Signal(reset_less=True, name=name))
38
39 def elaborate(self, platform):
40 m = Module()
41 comb = m.d.comb
42
43 with m.Switch(self.opcode_in):
44 for row in major_opcodes:
45 opcode = int(row['opcode'])
46 with m.Case(opcode):
47 comb += self.function_unit.eq(Function[row['unit']])
48 comb += self.internal_op.eq(InternalOp[row['internal op']])
49 comb += self.in1_sel.eq(In1Sel[row['in1']])
50 comb += self.in2_sel.eq(In2Sel[row['in2']])
51 comb += self.in3_sel.eq(In3Sel[row['in3']])
52 comb += self.out_sel.eq(OutSel[row['out']])
53 comb += self.ldst_len.eq(LdstLen[row['ldst len']])
54 comb += self.rc_sel.eq(RC[row['rc']])
55 comb += self.cry_in.eq(CryIn[row['cry in']])
56 for bit in single_bit_flags:
57 sig = getattr(self, get_signal_name(bit))
58 comb += sig.eq(int(row[bit]))
59 return m
60
61 def ports(self):
62 regular =[self.opcode_in,
63 self.function_unit,
64 self.in1_sel,
65 self.in2_sel,
66 self.in3_sel,
67 self.out_sel,
68 self.ldst_len,
69 self.rc_sel,
70 self.internal_op]
71 single_bit_ports = [getattr(self, get_signal_name(x))
72 for x in single_bit_flags]
73 return regular + single_bit_ports