From: Luke Kenneth Casson Leighton Date: Sun, 28 Jun 2020 20:14:52 +0000 (+0100) Subject: read from instruction memory using FetchUnitInterface X-Git-Tag: div_pipeline~214 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=03aa8162cd08de287233c9654744a70182dcd517;p=soc.git read from instruction memory using FetchUnitInterface --- diff --git a/src/soc/bus/test/__init__.py b/src/soc/bus/test/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/soc/experiment/imem.py b/src/soc/experiment/imem.py index 5f0f622c..17c5b1eb 100644 --- a/src/soc/experiment/imem.py +++ b/src/soc/experiment/imem.py @@ -7,6 +7,7 @@ from nmigen.cli import rtlil class TestMemFetchUnit(FetchUnitInterface, Elaboratable): def __init__(self, addr_wid=32, data_wid=32): + print ("testmemfetchunit", addr_wid, data_wid) super().__init__(addr_wid=addr_wid, data_wid=data_wid) # limit TestMemory to 2^6 entries of regwid size self.mem = TestMemory(self.data_wid, 6, readonly=True) @@ -40,6 +41,12 @@ class TestMemFetchUnit(FetchUnitInterface, Elaboratable): return m + def __iter__(self): # TODO + yield self.a_pc_i + yield self.f_instr_o + + def ports(self): + return list(self) if __name__ == '__main__': dut = TestMemFetchUnit(addr_wid=32, data_wid=32) diff --git a/src/soc/experiment/l0_cache.py b/src/soc/experiment/l0_cache.py index f42545d5..cd779c88 100644 --- a/src/soc/experiment/l0_cache.py +++ b/src/soc/experiment/l0_cache.py @@ -266,6 +266,7 @@ class L0CacheBuffer(Elaboratable): class TstL0CacheBuffer(Elaboratable): def __init__(self, n_units=3, regwid=16, addrwid=4, ifacetype='testpi'): pspec = TestMemPspec(ldst_ifacetype=ifacetype, + imem_ifacetype='', addr_wid=addrwid<<1, mask_wid=8, reg_wid=regwid) diff --git a/src/soc/minerva/units/fetch.py b/src/soc/minerva/units/fetch.py index 9aa1ef29..dd691aeb 100644 --- a/src/soc/minerva/units/fetch.py +++ b/src/soc/minerva/units/fetch.py @@ -13,7 +13,7 @@ class FetchUnitInterface: self.addr_wid = addr_wid self.data_wid = data_wid self.adr_lsbs = log2_int(data_wid//8) - self.ibus = Record(make_wb_layout(addr_wid, self.adr_lsbs, data_wid)) + self.ibus = Record(make_wb_layout(addr_wid, data_wid//8, data_wid)) bad_wid = addr_wid - self.adr_lsbs # TODO: is this correct? # inputs: address to fetch PC, and valid/stall signalling diff --git a/src/soc/simple/__init__.py b/src/soc/simple/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index 7dfa9d67..8194b44a 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -18,11 +18,12 @@ improved. from nmigen import Elaboratable, Module, Signal from nmigen.cli import rtlil - from soc.decoder.decode2execute1 import Data from soc.experiment.testmem import TestMemory # test only for instructions from soc.regfile.regfiles import FastRegs from soc.simple.core import NonProductionCore +from soc.config.test.test_loadstore import TestMemPspec +from soc.config.ifetch import ConfigFetchUnit class TestIssuer(Elaboratable): @@ -30,14 +31,18 @@ class TestIssuer(Elaboratable): efficiency and speed is not the main goal here: functional correctness is. """ - def __init__(self, addrwid=6, idepth=6, ifacetype='testpi'): + def __init__(self, addrwid=6, idepth=6, ifacetype='testpi', + imemtype='testmem'): # main instruction core self.core = core = NonProductionCore(addrwid, ifacetype=ifacetype) + pspec = TestMemPspec(ldst_ifacetype=ifacetype, + imem_ifacetype=imemtype, + addr_wid=addrwid<<1, + mask_wid=8, + reg_wid=64) # instruction memory width # Test Instruction memory - self.imemwid = 64 - self.imem = TestMemory(self.imemwid, idepth) - self.i_rd = self.imem.rdport + self.imem = ConfigFetchUnit(pspec).fu # one-row cache of instruction read self.iline = Signal(64) # one instruction line self.iprev_adr = Signal(64) # previous address: if different, do read @@ -106,20 +111,28 @@ class TestIssuer(Elaboratable): # capture the PC and also drop it into Insn Memory # we have joined a pair of combinatorial memory # lookups together. this is Generally Bad. - comb += self.i_rd.addr.eq(pc[3:]) # ignore last 3 bits + comb += self.imem.a_pc_i.eq(pc) + comb += self.imem.a_valid_i.eq(1) + comb += self.imem.f_valid_i.eq(1) sync += current_pc.eq(pc) - m.next = "INSN_READ" # move to "issue" phase + m.next = "INSN_READ" # move to "wait for bus" phase - # got the instruction: start issue + # waiting for instruction bus (stays there until not busy) with m.State("INSN_READ"): - insn = self.i_rd.data.word_select(current_pc[2], 32) # - comb += current_insn.eq(insn) - comb += core_ivalid_i.eq(1) # say instruction is valid - comb += core_issue_i.eq(1) # and issued (ivalid_i redundant) - comb += core_be_i.eq(0) # little-endian mode - comb += core_opcode_i.eq(current_insn) # actual opcode - sync += ilatch.eq(current_insn) - m.next = "INSN_ACTIVE" # move to "wait for completion" phase + with m.If(self.imem.f_busy_o): # zzz... + # busy: stay in wait-read + comb += self.imem.a_valid_i.eq(1) + comb += self.imem.f_valid_i.eq(1) + with m.Else(): + # not busy: instruction fetched + insn = self.imem.f_instr_o.word_select(current_pc[2], 32) + comb += current_insn.eq(insn) + comb += core_ivalid_i.eq(1) # say instruction is valid + comb += core_issue_i.eq(1) # and issued (ivalid redundant) + comb += core_be_i.eq(0) # little-endian mode + comb += core_opcode_i.eq(current_insn) # actual opcode + sync += ilatch.eq(current_insn) + m.next = "INSN_ACTIVE" # move to "wait for completion" phase # instruction started: must wait till it finishes with m.State("INSN_ACTIVE"): diff --git a/src/soc/simple/test/test_issuer.py b/src/soc/simple/test/test_issuer.py index 04a7bd43..48c802ec 100644 --- a/src/soc/simple/test/test_issuer.py +++ b/src/soc/simple/test/test_issuer.py @@ -67,7 +67,7 @@ class TestRunner(FHDLTestCase): pc_i = Signal(32) m.submodules.issuer = issuer = TestIssuer(ifacetype="test_bare_wb") - imem = issuer.imem.mem + imem = issuer.imem.mem.mem core = issuer.core pdecode2 = core.pdecode2 l0 = core.l0