5f0f622c6b26d70467cc3fe27e3db7102886d21a
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
, addr_wid
=32, data_wid
=32):
10 super().__init
__(addr_wid
=addr_wid
, data_wid
=data_wid
)
11 # limit TestMemory to 2^6 entries of regwid size
12 self
.mem
= TestMemory(self
.data_wid
, 6, readonly
=True)
14 def elaborate(self
, platform
):
16 regwid
, addrwid
= self
.data_wid
, self
.addr_wid
17 adr_lsb
= self
.adr_lsbs
19 m
.submodules
.mem
= mem
= self
.mem
21 do_fetch
= Signal() # set when fetch while valid and not stalled
22 m
.d
.comb
+= do_fetch
.eq(self
.a_valid_i
& ~self
.a_stall_i
)
24 # bit of a messy FSM that progresses from idle to in progress
26 op_actioned
= Signal(reset
=0)
27 op_in_progress
= Signal(reset
=0)
28 with m
.If(~op_actioned
& do_fetch
): # idle
29 m
.d
.sync
+= op_actioned
.eq(1)
30 m
.d
.sync
+= op_in_progress
.eq(1)
31 with m
.Elif(op_in_progress
): # in progress
32 m
.d
.sync
+= op_actioned
.eq(0)
33 with m
.If(~do_fetch
): # done
34 m
.d
.sync
+= op_in_progress
.eq(0)
36 m
.d
.comb
+= self
.a_busy_o
.eq(op_actioned
& self
.a_valid_i
)
38 m
.d
.comb
+= mem
.rdport
.addr
.eq(self
.a_pc_i
[adr_lsb
:])
39 m
.d
.comb
+= self
.f_instr_o
.eq(mem
.rdport
.data
)
44 if __name__
== '__main__':
45 dut
= TestMemFetchUnit(addr_wid
=32, data_wid
=32)
46 vl
= rtlil
.convert(dut
, ports
=[]) # TODOdut.ports())
47 with
open("test_imem.il", "w") as f
: