3 not in any way intended for production use. connects up FunctionUnits to
4 Register Files in a brain-dead fashion that only permits one and only one
5 Function Unit to be operational.
7 from nmigen
import Elaboratable
, Module
, Signal
8 from nmigen
.cli
import rtlil
10 from nmutil
.picker
import PriorityPicker
12 from soc
.fu
.compunits
.compunits
import AllFunctionUnits
13 from soc
.regfile
.regfiles
import RegFiles
14 from soc
.decoder
.power_decoder
import create_pdecode
15 from soc
.decoder
.power_decoder2
import PowerDecode2
18 class NonProductionCore(Elaboratable
):
20 self
.fus
= AllFunctionUnits()
21 self
.regs
= RegFiles()
22 self
.pdecode
= pdecode
= create_pdecode()
23 self
.pdecode2
= PowerDecode2(pdecode
) # instruction decoder
24 self
.ivalid_i
= self
.pdecode2
.e
.valid
# instruction is valid
26 def elaborate(self
, platform
):
30 m
.submodules
.pdecode2
= dec2
= self
.pdecode2
31 m
.submodules
.fus
= self
.fus
32 self
.regs
.elaborate_into(m
, platform
)
36 # enable-signals for each FU, get one bit for each FU (by name)
37 fu_enable
= Signal(len(fus
), reset_less
=True)
39 for i
, funame
in enumerate(fus
.keys()):
40 fu_bitdict
[funame
] = fu_enable
[i
]
42 # dictionary of lists of regfile read ports
44 byregfiles_rdspec
= {}
45 for (funame
, fu
) in fus
.items():
46 print ("read ports for %s" % funame
)
47 for idx
in range(fu
.n_src
):
48 (regfile
, regname
, wid
) = fu
.get_in_spec(idx
)
49 print (" %s %s %s" % (regfile
, regname
, str(wid
)))
50 rdflag
, read
, _
= dec2
.regspecmap(regfile
, regname
)
51 if regfile
not in byregfiles_rd
:
52 byregfiles_rd
[regfile
] = {}
53 byregfiles_rdspec
[regfile
] = (regname
, rdflag
, read
, wid
)
54 # here we start to create "lanes"
55 if idx
not in byregfiles_rd
[regfile
]:
56 byregfiles_rd
[regfile
][idx
] = []
58 byregfiles_rd
[regfile
][idx
].append(fuspec
)
60 # ok just print that out, for convenience
61 for regfile
, spec
in byregfiles_rd
.items():
62 print ("regfile read ports:", regfile
)
63 for idx
, fuspec
in spec
.items():
64 print (" regfile read port %s lane: %d" % (regfile
, idx
))
65 (regname
, rdflag
, read
, wid
) = byregfiles_rdspec
[regfile
]
66 print (" %s" % regname
, wid
, read
, rdflag
)
67 for (funame
, fu
) in fuspec
:
68 print (" ", funame
, fu
, fu
.src_i
[idx
])
71 # okaay, now we need a PriorityPicker per regfile per regfile port
72 # loootta pickers... peter piper picked a pack of pickled peppers...
74 for regfile
, spec
in byregfiles_rd
.items():
75 rdpickers
[regfile
] = {}
76 for idx
, fuspec
in spec
.items():
77 rdpickers
[regfile
][idx
] = rdpick
= PriorityPicker(len(fuspec
))
78 setattr(m
.submodules
, "rdpick_%s_%d" % (regfile
, idx
), rdpick
)
79 for pi
, (funame
, fu
) in enumerate(fuspec
):
80 # connect request-read to picker input, and output to go-rd
81 fu_active
= fu_bitdict
[funame
]
82 comb
+= rdpick
.i
[pi
].eq(fu
.rd_rel_o
[idx
] & fu_active
)
83 comb
+= fu
.go_rd_i
[idx
].eq(rdpick
.o
[pi
])
88 yield from self
.fus
.ports()
89 yield from self
.pdecode2
.ports()
96 if __name__
== '__main__':
97 dut
= NonProductionCore()
98 vl
= rtlil
.convert(dut
, ports
=dut
.ports())
99 with
open("non_production_core.il", "w") as f
: