1 from nmigen
import Elaboratable
, Module
, Signal
, Shape
, unsigned
, Cat
, Mux
2 from soc
.fu
.mmu
.pipe_data
import MMUInputData
, MMUOutputData
, MMUPipeSpec
3 from nmutil
.singlepipe
import ControlBase
5 from soc
.experiment
.mmu
import MMU
6 from soc
.experiment
.dcache
import DCache
9 class FSMMMUStage(ControlBase
):
10 def __init__(self
, pspec
):
14 self
.p
.data_i
= MMUInputData(pspec
)
15 self
.n
.data_o
= MMUOutputData(pspec
)
17 # this Function Unit is extremely unusual in that it actually stores a
18 # "thing" rather than "processes inputs and produces outputs". hence
19 # why it has to be a FSM. linking up LD/ST however is going to have
20 # to be done back in Issuer (or Core)
23 self
.dcache
= DCache()
26 def elaborate(self
, platform
):
27 m
= super().elaborate(platform
)
29 # link mmu and dcache together
30 m
.submodules
.dcache
= dcache
= self
.dcache
31 m
.submodules
.mmu
= mmu
= self
.mmu
32 m
.d
.comb
+= dcache
.m_in
.eq(mmu
.d_out
)
33 m
.d
.comb
+= mmu
.d_in
.eq(dcache
.m_out
)
35 data_i
= self
.p
.data_i
36 data_o
= self
.n
.data_o
38 m
.d
.comb
+= self
.n
.valid_o
.eq(~self
.empty
& self
.div_state_next
.o
.done
)
39 m
.d
.comb
+= self
.p
.ready_o
.eq(self
.empty
)
40 m
.d
.sync
+= self
.saved_state
.eq(self
.div_state_next
.o
)
42 with m
.If(self
.empty
):
43 with m
.If(self
.p
.valid_i
):
44 m
.d
.sync
+= self
.empty
.eq(0)
45 m
.d
.sync
+= self
.saved_input_data
.eq(data_i
)
48 with m
.If(self
.n
.ready_i
& self
.n
.valid_o
):
49 m
.d
.sync
+= self
.empty
.eq(1)