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 elaborate(self
, platform
):
11 regwid
, addrwid
= self
.data_wid
, self
.addr_wid
12 adr_lsb
= self
.adr_lsbs
14 # limit TestMemory to 2^6 entries of regwid size
15 m
.submodules
.mem
= mem
= TestMemory(regwid
, 6, readonly
=True)
17 do_fetch
= Signal() # set when fetch while valid and not stalled
18 m
.d
.comb
+= do_fetch
.eq(self
.a_valid_i
& ~self
.a_stall_i
)
20 # bit of a messy FSM that progresses from idle to in progress
22 op_actioned
= Signal(reset
=0)
23 op_in_progress
= Signal(reset
=0)
24 with m
.If(~op_actioned
& do_fetch
): # idle
25 m
.d
.sync
+= op_actioned
.eq(1)
26 m
.d
.sync
+= op_in_progress
.eq(1)
27 with m
.Elif(op_in_progress
): # in progress
28 m
.d
.sync
+= op_actioned
.eq(0)
29 with m
.If(~do_fetch
): # done
30 m
.d
.sync
+= op_in_progress
.eq(0)
32 m
.d
.comb
+= self
.a_busy_o
.eq(op_actioned
& self
.a_valid_i
)
34 m
.d
.comb
+= mem
.rdport
.addr
.eq(self
.a_pc_i
[adr_lsb
:])
35 m
.d
.comb
+= self
.f_instr_o
.eq(mem
.rdport
.data
)
40 if __name__
== '__main__':
41 dut
= TestMemFetchUnit(addr_wid
=32, data_wid
=32)
42 vl
= rtlil
.convert(dut
, ports
=[]) # TODOdut.ports())
43 with
open("test_imem.il", "w") as f
: