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