add pi.busy_o connection, increase to 64 bit
[soc.git] / src / soc / experiment / pi2ls.py
1 """PortInterface to LoadStoreUnitInterface adapter
2
3 PortInterface LoadStoreUnitInterface
4 ------------- ----------------------
5
6 is_ld_i/1 x_ld_i
7 is_st_i/1 x_st_i
8
9 data_len/4 x_mask/16 (translate using LenExpand)
10
11 busy_o/1 most likely to be x_busy_o
12 go_die_i/1 rst?
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
15
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
18
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
23 """
24
25 from soc.minerva.units.loadstore import LoadStoreUnitInterface
26 from soc.experiment.pimem import PortInterface
27 from soc.scoreboard.addr_match import LenExpand
28
29 from nmigen import Elaboratable, Module, Signal
30
31
32 class Pi2LSUI(Elaboratable):
33
34 def __init__(self, name, pi=None, lsui=None,
35 regwid=64, mask_wid=8, addrwid=48):
36 self.addrbits = mask_wid
37 if pi is None:
38 pi = PortInterface(name="%s_pi", regwid=regwid, addrwid=addrwid)
39 self.pi = pi
40 if lsui is None:
41 lsui = LoadStoreUnitInterface(addrwid, self.addrbits, regwid)
42 self.lsui = lsui
43
44 def splitaddr(self, addr):
45 """split the address into top and bottom bits of the memory granularity
46 """
47 return addr[:self.addrbits], addr[self.addrbits:]
48
49 def elaborate(self, platform):
50 m = Module()
51 pi, lsui, addrbits = self.pi, self.lsui, self.addrbits
52 m.submodules.lenexp = lenexp = LenExpand(self.addrbits, 8)
53
54 m.d.comb += lsui.x_ld_i.eq(pi.is_ld_i)
55 m.d.comb += lsui.x_st_i.eq(pi.is_st_i)
56 m.d.comb += pi.busy_o.eq(lsui.x_busy_o)
57
58 with m.If(pi.addr.ok):
59 # expand the LSBs of address plus LD/ST len into 16-bit mask
60 m.d.comb += lenexp.len_i.eq(pi.data_len)
61 m.d.comb += lenexp.addr_i.eq(pi.addr.data[addrbits]) # LSBs of addr
62 m.d.comb += lsui.x_mask_i.eq(lenexp.lexp_o)
63 # pass through the address, indicate "valid"
64 m.d.comb += lsui.x_addr_i.eq(pi.addr.data) # full address
65 m.d.comb += lsui.x_valid_i.eq(1)
66
67 with m.If(pi.is_ld_i):
68 m.d.comb += pi.ld.data.eq(lsui.m_ld_data_o)
69 m.d.comb += pi.ld.ok.eq(1) # TODO whether this should be one cycle
70
71 with m.If(pi.is_st_i & pi.st.ok):
72 m.d.comb += lsui.x_st_data_i.eq(pi.st.data)
73
74 return m
75