1 from soc
.minerva
.units
.fetch
import FetchUnitInterface
2 from nmigen
import Signal
, Module
, Elaboratable
, Mux
3 from soc
.experiment
.testmem
import TestMemory
4 from nmigen
.cli
import rtlil
7 class TestMemFetchUnit(FetchUnitInterface
, Elaboratable
):
9 def __init__(self
, pspec
):
10 print("testmemfetchunit", pspec
.addr_wid
, pspec
.reg_wid
)
11 super().__init
__(pspec
)
12 # limit TestMemory to 2^6 entries of regwid size
13 self
.mem
= TestMemory(self
.data_wid
, 6, readonly
=True)
15 def _get_memory(self
):
18 def elaborate(self
, platform
):
20 regwid
, addrwid
= self
.data_wid
, self
.addr_wid
21 adr_lsb
= self
.adr_lsbs
23 m
.submodules
.mem
= mem
= self
.mem
25 do_fetch
= Signal() # set when fetch while valid and not stalled
26 m
.d
.comb
+= do_fetch
.eq(self
.a_valid_i
& ~self
.a_stall_i
)
28 # bit of a messy FSM that progresses from idle to in progress
30 op_actioned
= Signal(reset
=0)
31 op_in_progress
= Signal(reset
=0)
32 with m
.If(~op_actioned
& do_fetch
): # idle
33 m
.d
.sync
+= op_actioned
.eq(1)
34 m
.d
.sync
+= op_in_progress
.eq(1)
35 with m
.Elif(op_in_progress
): # in progress
36 m
.d
.sync
+= op_actioned
.eq(0)
37 with m
.If(~do_fetch
): # done
38 m
.d
.sync
+= op_in_progress
.eq(0)
40 m
.d
.comb
+= self
.a_busy_o
.eq(op_actioned
& self
.a_valid_i
)
42 m
.d
.comb
+= mem
.rdport
.addr
.eq(self
.a_pc_i
[adr_lsb
:])
43 m
.d
.comb
+= self
.f_instr_o
.eq(mem
.rdport
.data
)
47 def __iter__(self
): # TODO
55 if __name__
== '__main__':
56 dut
= TestMemFetchUnit(addr_wid
=32, data_wid
=32)
57 vl
= rtlil
.convert(dut
, ports
=[]) # TODOdut.ports())
58 with
open("test_imem.il", "w") as f
: