1 from soc
.minerva
.units
.loadstore
import LoadStoreUnitInterface
2 from nmigen
import Signal
, Module
, Elaboratable
, Mux
3 from soc
.experiment
.testmem
import TestMemory
# TODO: replace with TMLSUI
6 from nmigen
.back
.pysim
import Simulator
, Settle
9 class TestMemLoadStoreUnit(LoadStoreUnitInterface
, Elaboratable
):
10 def __init__(self
, regwid
, addrwid
):
13 self
.addrwid
= addrwid
14 def elaborate(self
, platform
):
18 m
.submodules
.mem
= mem
= TestMemory(
19 self
.regwid
, self
.addrwid
, granularity
=8)
21 do_load
= Signal() # set when doing a load while valid and not stalled
22 do_store
= Signal() # set when doing a store while valid and not stalled
25 do_load
.eq(self
.x_ld_i
& (self
.x_valid_i
& ~self
.x_stall_i
)),
26 do_store
.eq(self
.x_st_i
& (self
.x_valid_i
& ~self
.x_stall_i
)),
29 mem
.rdport
.addr
.eq(self
.x_addr_i
[2:]),
30 self
.m_ld_data_o
.eq(mem
.rdport
.data
),
32 mem
.wrport
.addr
.eq(self
.x_addr_i
[2:]),
33 mem
.wrport
.en
.eq(Mux(do_store
, self
.x_mask_i
, 0)),
34 mem
.wrport
.data
.eq(self
.x_st_data_i
)
40 def write_to_addr(dut
, addr
, value
):
41 yield dut
.x_addr_i
.eq(addr
)
42 yield dut
.x_st_data_i
.eq(value
)
43 yield dut
.x_st_i
.eq(1)
44 yield dut
.x_mask_i
.eq(-1)
45 yield dut
.x_valid_i
.eq(1)
46 yield dut
.x_stall_i
.eq(1)
50 yield dut
.x_stall_i
.eq(0)
52 yield dut
.x_st_i
.eq(0)
53 while (yield dut
.x_stall_i
):
57 def read_from_addr(dut
, addr
):
58 yield dut
.x_addr_i
.eq(addr
)
59 yield dut
.x_ld_i
.eq(1)
60 yield dut
.x_valid_i
.eq(1)
61 yield dut
.x_stall_i
.eq(1)
63 yield dut
.x_stall_i
.eq(0)
65 yield dut
.x_ld_i
.eq(0)
67 while (yield dut
.x_stall_i
):
69 assert (yield dut
.x_valid_i
)
70 return (yield dut
.m_ld_data_o
)
73 def write_byte(dut
, addr
, val
):
75 yield dut
.x_addr_i
.eq(addr
)
76 yield dut
.x_st_i
.eq(1)
77 yield dut
.x_st_data_i
.eq(val
<< (offset
* 8))
78 yield dut
.x_mask_i
.eq(1 << offset
)
79 yield dut
.x_valid_i
.eq(1)
82 yield dut
.x_st_i
.eq(0)
83 while (yield dut
.x_stall_i
):
87 def read_byte(dut
, addr
):
89 yield dut
.x_addr_i
.eq(addr
)
90 yield dut
.x_ld_i
.eq(1)
91 yield dut
.x_valid_i
.eq(1)
93 yield dut
.x_ld_i
.eq(0)
95 while (yield dut
.x_stall_i
):
97 assert (yield dut
.x_valid_i
)
98 val
= (yield dut
.m_ld_data_o
)
99 return (val
>> (offset
* 8)) & 0xff
102 if __name__
== '__main__':
104 dut
= TestMemLoadStoreUnit(regwid
=32, addrwid
=4)
105 m
.submodules
.dut
= dut
112 values
= [random
.randint(0, (1<<32)-1) for x
in range(16)]
114 for addr
, val
in enumerate(values
):
115 yield from write_to_addr(dut
, addr
<< 2, val
)
116 for addr
, val
in enumerate(values
):
117 x
= yield from read_from_addr(dut
, addr
<< 2)
120 values
= [random
.randint(0, 255) for x
in range(16*4)]
121 for addr
, val
in enumerate(values
):
122 yield from write_byte(dut
, addr
, val
)
123 for addr
, val
in enumerate(values
):
124 x
= yield from read_byte(dut
, addr
)
127 sim
.add_sync_process(process
)
128 with sim
.write_vcd("lsmem.vcd", "lsmem.gtkw", traces
=[]):