1 """PortInterface to LoadStoreUnitInterface adapter
3 PortInterface LoadStoreUnitInterface
4 ------------- ----------------------
9 data_len/4 x_mask/16 (translate using LenExpand)
11 busy_o/1 most likely to be x_busy_o
13 addr.data/48 x_addr_i (x_addr_i[:4] goes into LenExpand)
14 addr.ok/1 probably x_valid_i & ~x_stall_i
16 addr_ok_o/1 no equivalent. *might* work using x_stall_i
17 addr_exc_o/2(?) m_load_err_o and m_store_err_o
19 ld.data/64 m_ld_data_o
20 ld.ok/1 probably implicit, when x_busy drops low
21 st.data/64 x_st_data_i
22 st.ok/1 probably kinda redundant, set to x_st_i
25 from soc
.minerva
.units
.loadstore
import LoadStoreUnitInterface
26 from soc
.experiment
.pimem
import PortInterface
27 from soc
.scoreboard
.addr_match
import LenExpand
29 from nmigen
import Elaboratable
, Module
, Signal
32 class Pi2LSUI(Elaboratable
):
34 def __init__(self
, name
, pi
=None, lsui
=None, regwid
=64, addrwid
=48):
37 pi
= PortInterface(name
="%s_pi", regwid
=regwid
, addrwid
=addrwid
)
40 lsui
= LoadStoreUnitInterface(addrwid
, self
.addrbits
, regwid
)
43 def splitaddr(self
, addr
):
44 """split the address into top and bottom bits of the memory granularity
46 return addr
[:self
.addrbits
], addr
[self
.addrbits
:]
48 def elaborate(self
, platform
):
50 pi
, lsui
, addrbits
= self
.pi
, self
.lsui
, self
.addrbits
51 m
.submodules
.lenexp
= lenexp
= LenExpand(self
.addrbits
, 8)
53 m
.d
.comb
+= lsui
.x_ld_i
.eq(pi
.is_ld_i
)
54 m
.d
.comb
+= lsui
.x_st_i
.eq(pi
.is_st_i
)
56 with m
.If(pi
.addr
.ok
):
57 # expand the LSBs of address plus LD/ST len into 16-bit mask
58 m
.d
.comb
+= lenexp
.len_i
.eq(pi
.data_len
)
59 m
.d
.comb
+= lenexp
.addr_i
.eq(pi
.addr
.data
[addrbits
]) # LSBs of addr
60 m
.d
.comb
+= lsui
.x_mask_i
.eq(lenexp
.lexp_o
)
61 # pass through the address, indicate "valid"
62 m
.d
.comb
+= lsui
.x_addr_i
.eq(pi
.addr
.data
) # full address
63 m
.d
.comb
+= lsui
.x_valid_i
.eq(1)
65 with m
.If(pi
.is_ld_i
):
66 m
.d
.comb
+= pi
.ld
.data
.eq(lsui
.m_ld_data_o
)
67 m
.d
.comb
+= pi
.ld
.ok
.eq(1) # TODO whether this should be one cycle
69 with m
.If(pi
.is_st_i
& pi
.st
.ok
):
70 m
.d
.comb
+= lsui
.x_st_data_i
.eq(pi
.st
.data
)