add testcase for dcbz
[soc.git] / src / soc / experiment / test / test_compldst_multi_mmu.py
1 # test case for LOAD / STORE Computation Unit using MMU
2
3 from nmigen.compat.sim import run_simulation
4 from nmigen.cli import verilog, rtlil
5 from nmigen import Module, Signal, Mux, Cat, Elaboratable, Array, Repl
6 from nmigen.hdl.rec import Record, Layout
7
8 from nmutil.latch import SRLatch, latchregister
9 from nmutil.byterev import byte_reverse
10 from nmutil.extend import exts
11 from soc.fu.regspec import RegSpecAPI
12
13 from openpower.decoder.power_enums import MicrOp, Function, LDSTMode
14 from soc.fu.ldst.ldst_input_record import CompLDSTOpSubset
15 from openpower.decoder.power_decoder2 import Data
16 from openpower.consts import MSR
17
18 from soc.experiment.compalu_multi import go_record, CompUnitRecord
19 from soc.experiment.l0_cache import PortInterface
20 from soc.experiment.pimem import LDSTException
21 from soc.experiment.compldst_multi import LDSTCompUnit
22 from soc.config.test.test_loadstore import TestMemPspec
23
24 from soc.experiment.mmu import MMU
25
26 ########################################
27 # copied from compldst_multi.py
28 # for debugging -- remove once done
29 def load_part(dut, src1, src2, imm, imm_ok=True, update=False, zero_a=False,
30 byterev=True):
31 print("LD_part", src1, src2, imm, imm_ok, update)
32 yield dut.oper_i.insn_type.eq(MicrOp.OP_LOAD)
33 yield dut.oper_i.data_len.eq(2) # half-word
34 yield dut.oper_i.byte_reverse.eq(byterev)
35 yield dut.src1_i.eq(src1)
36 yield dut.src2_i.eq(src2)
37 yield dut.oper_i.zero_a.eq(zero_a)
38 yield dut.oper_i.imm_data.imm.eq(imm)
39 yield dut.oper_i.imm_data.ok.eq(imm_ok)
40 yield dut.issue_i.eq(1)
41 yield
42 yield dut.issue_i.eq(0)
43 yield
44
45 # set up read-operand flags
46 rd = 0b00
47 if not imm_ok: # no immediate means RB register needs to be read
48 rd |= 0b10
49 if not zero_a: # no zero-a means RA needs to be read
50 rd |= 0b01
51
52 # wait for the operands (RA, RB, or both)
53 if rd:
54 yield dut.rd.go.eq(rd)
55 yield from wait_for(dut.rd.rel_o)
56 yield dut.rd.go.eq(0)
57
58 # if RA = 0 then b <- 0 RA needs to be read if RA = 0
59 # else b <-(RA)
60 # EA <- b + (RB) RB needs to be read
61 # verify that EA is correct first
62 def dcbz(dut, ra, ra_needed, rb):
63 print("LD_part", ra, ra_needed, rb)
64 yield dut.oper_i.insn_type.eq(MicrOp.OP_DCBZ)
65 #yield dut.oper_i.data_len.eq(2) # half-word
66 #yield dut.oper_i.byte_reverse.eq(byterev)
67 yield dut.src1_i.eq(ra)
68 yield dut.src2_i.eq(rb)
69 #???yield dut.oper_i.zero_a.eq(zero_a)
70 #yield dut.oper_i.imm_data.imm.eq(imm)
71 #yield dut.oper_i.imm_data.ok.eq(imm_ok)
72 yield dut.issue_i.eq(1)
73 yield
74 yield dut.issue_i.eq(0)
75 yield
76
77
78 def ldst_sim(dut):
79 yield from dcbz(dut, 4, True, 3) # EA=7
80 #yield from load_part(dut, 4, 0, 2)
81 yield
82
83 ########################################
84
85
86 class TestLDSTCompUnitMMU(LDSTCompUnit):
87
88 def __init__(self, rwid, pspec):
89 from soc.experiment.l0_cache import TstL0CacheBuffer
90 self.l0 = l0 = TstL0CacheBuffer(pspec)
91 pi = l0.l0.dports[0]
92 LDSTCompUnit.__init__(self, pi, rwid, 4)
93
94 def elaborate(self, platform):
95 m = LDSTCompUnit.elaborate(self, platform)
96 m.submodules.l0 = self.l0
97 # link addr-go direct to rel
98 m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
99 return m
100
101
102 def test_scoreboard_mmu():
103
104 units = {}
105 pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
106 imem_ifacetype='bare_wb',
107 addr_wid=48,
108 mask_wid=8,
109 reg_wid=64,
110 units=units)
111
112 dut = TestLDSTCompUnitMMU(16,pspec)
113 vl = rtlil.convert(dut, ports=dut.ports())
114 with open("test_ldst_comp_mmu1.il", "w") as f:
115 f.write(vl)
116
117 run_simulation(dut, ldst_sim(dut), vcd_name='test_ldst_comp.vcd')
118
119 ########################################
120 class TestLDSTCompUnitRegSpecMMU(LDSTCompUnit):
121
122 def __init__(self, pspec):
123 from soc.experiment.l0_cache import TstL0CacheBuffer
124 from soc.fu.ldst.pipe_data import LDSTPipeSpec
125 regspec = LDSTPipeSpec.regspec
126 self.l0 = l0 = TstL0CacheBuffer(pspec)
127 self.mmu = MMU()
128 pi = l0.l0.dports[0]
129 LDSTCompUnit.__init__(self, pi, regspec, 4)
130
131 def elaborate(self, platform):
132 m = LDSTCompUnit.elaborate(self, platform)
133 m.submodules.l0 = self.l0
134 m.submodules.mmu = self.mmu
135 # link addr-go direct to rel
136 m.d.comb += self.ad.go_i.eq(self.ad.rel_o)
137
138 # link mmu and dcache together
139 dcache = self.l0.pimem.dcache
140 mmu = self.mmu
141 m.d.comb += dcache.m_in.eq(mmu.d_out) # MMUToDCacheType
142 m.d.comb += mmu.d_in.eq(dcache.m_out) # DCacheToMMUType
143
144
145 return m
146
147
148 def test_scoreboard_regspec_mmu():
149
150 units = {}
151 pspec = TestMemPspec(ldst_ifacetype='mmu_cache_wb',
152 imem_ifacetype='bare_wb',
153 addr_wid=48,
154 mask_wid=8,
155 reg_wid=64,
156 units=units)
157
158 dut = TestLDSTCompUnitRegSpecMMU(pspec)
159
160 # TODO: setup pagetables for MMU
161
162 vl = rtlil.convert(dut, ports=dut.ports())
163 with open("test_ldst_comp_mmu2.il", "w") as f:
164 f.write(vl)
165
166 run_simulation(dut, ldst_sim(dut), vcd_name='test_ldst_regspec.vcd')
167
168
169 if __name__ == '__main__':
170 test_scoreboard_regspec_mmu()
171 #only one test for now -- test_scoreboard_mmu()