Allow the formal engine to perform a same-cycle result in the ALU
[soc.git] / src / soc / scoreboard / memfu.py
1 from nmigen.compat.sim import run_simulation
2 from nmigen.cli import verilog, rtlil
3 from nmigen import Module, Signal, Elaboratable
4
5 from soc.scoreboard.fu_fu_matrix import FUFUDepMatrix
6 from soc.scoreboard.mdm import FUMemMatchMatrix
7
8
9 class MemFunctionUnits(Elaboratable):
10
11 def __init__(self, n_ldsts, addrbitwid):
12 self.n_ldsts = n_ldsts
13 self.bitwid = addrbitwid
14
15 self.st_i = Signal(n_ldsts, reset_less=True) # Dest R# in
16 self.ld_i = Signal(n_ldsts, reset_less=True) # oper1 R# in
17
18 self.g_int_ld_pend_o = Signal(n_ldsts, reset_less=True)
19 self.g_int_st_pend_o = Signal(n_ldsts, reset_less=True)
20
21 self.st_rsel_o = Signal(n_ldsts, reset_less=True) # dest reg (bot)
22 self.ld_rsel_o = Signal(n_ldsts, reset_less=True) # src1 reg (bot)
23
24 self.loadable_o = Signal(n_ldsts, reset_less=True)
25 self.storable_o = Signal(n_ldsts, reset_less=True)
26 self.addr_nomatch_o = Signal(n_ldsts, reset_less=True)
27
28 self.go_ld_i = Signal(n_ldsts, reset_less=True)
29 self.go_st_i = Signal(n_ldsts, reset_less=True)
30 self.go_die_i = Signal(n_ldsts, reset_less=True)
31 self.fn_issue_i = Signal(n_ldsts, reset_less=True)
32
33 # address matching
34 self.addrs_i = tuple(Signal(self.bitwid, name="addrs_i%d" % i) \
35 for i in range(n_ldsts))
36 #self.addr_we_i = Signal(n_ldsts) # write-enable for incoming address
37 self.addr_en_i = Signal(n_ldsts) # address latched in
38 self.addr_rs_i = Signal(n_ldsts) # address deactivated
39
40 # Note: FURegs st_pend_o is also outputted from here, for use in WaWGrid
41
42 def elaborate(self, platform):
43 m = Module()
44 comb = m.d.comb
45 sync = m.d.sync
46
47 n_fus = self.n_ldsts
48
49 # Integer FU-FU Dep Matrix
50 intfudeps = FUFUDepMatrix(n_fus, n_fus)
51 m.submodules.intfudeps = intfudeps
52 # Integer FU-Reg Dep Matrix
53 intregdeps = FUMemMatchMatrix(n_fus, self.bitwid)
54 m.submodules.intregdeps = intregdeps
55
56 # ok, because we do not know in advance what the AGEN (address gen)
57 # is, we have to make a transitive dependency set. i.e. the LD
58 # (or ST) being requested now must depend on ALL prior LDs *AND* STs.
59 # these get dropped very rapidly once AGEN is carried out.
60 # XXX TODO
61
62 # connect fureg matrix as a mem system
63 comb += self.g_int_ld_pend_o.eq(intregdeps.v_rd_rsel_o)
64 comb += self.g_int_st_pend_o.eq(intregdeps.v_wr_rsel_o)
65
66 comb += intregdeps.rd_pend_i.eq(intregdeps.v_rd_rsel_o)
67 comb += intregdeps.wr_pend_i.eq(intregdeps.v_wr_rsel_o)
68
69 comb += intfudeps.rd_pend_i.eq(intregdeps.rd_pend_o)
70 comb += intfudeps.wr_pend_i.eq(intregdeps.wr_pend_o)
71 self.st_pend_o = intregdeps.wr_pend_o # also output for use in WaWGrid
72
73 comb += intfudeps.issue_i.eq(self.fn_issue_i)
74 comb += intfudeps.go_rd_i.eq(self.go_ld_i)
75 comb += intfudeps.go_wr_i.eq(self.go_st_i)
76 comb += intfudeps.go_die_i.eq(self.go_die_i)
77 comb += self.loadable_o.eq(intfudeps.readable_o)
78 comb += self.storable_o.eq(intfudeps.writable_o)
79 comb += self.addr_nomatch_o.eq(intregdeps.addr_nomatch_o)
80
81 # Connect function issue / arrays, and dest/src1/src2
82 comb += intregdeps.dest_i.eq(self.st_i)
83 comb += intregdeps.src_i[0].eq(self.ld_i)
84
85 comb += intregdeps.go_rd_i.eq(self.go_ld_i)
86 comb += intregdeps.go_wr_i.eq(self.go_st_i)
87 comb += intregdeps.go_die_i.eq(self.go_die_i)
88 comb += intregdeps.issue_i.eq(self.fn_issue_i)
89
90 comb += self.st_rsel_o.eq(intregdeps.dest_rsel_o)
91 comb += self.ld_rsel_o.eq(intregdeps.src_rsel_o[0])
92
93 # connect address matching: these get connected to the Addr CUs
94 for i in range(self.n_ldsts):
95 comb += intregdeps.addrs_i[i].eq(self.addrs_i[i])
96 #comb += intregdeps.addr_we_i.eq(self.addr_we_i)
97 comb += intregdeps.addr_en_i.eq(self.addr_en_i)
98 comb += intregdeps.addr_rs_i.eq(self.addr_rs_i)
99
100 return m
101
102 def __iter__(self):
103 yield self.ld_i
104 yield self.st_i
105 yield self.g_int_st_pend_o
106 yield self.g_int_ld_pend_o
107 yield self.ld_rsel_o
108 yield self.st_rsel_o
109 yield self.loadable_o
110 yield self.storable_o
111 yield self.go_st_i
112 yield self.go_ld_i
113 yield self.go_die_i
114 yield self.fn_issue_i
115 yield from self.addrs_i
116 #yield self.addr_we_i
117 yield self.addr_en_i
118
119 def ports(self):
120 return list(self)