remove unneeded minerva code
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 6 May 2020 12:34:28 +0000 (13:34 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Wed, 6 May 2020 12:34:28 +0000 (13:34 +0100)
15 files changed:
src/soc/minerva/core.py [deleted file]
src/soc/minerva/csr.py [deleted file]
src/soc/minerva/isa.py [deleted file]
src/soc/minerva/stage.py [deleted file]
src/soc/minerva/test/test_units_divider.py [deleted file]
src/soc/minerva/test/test_units_multiplier.py [deleted file]
src/soc/minerva/units/adder.py [deleted file]
src/soc/minerva/units/compare.py [deleted file]
src/soc/minerva/units/decoder.py [deleted file]
src/soc/minerva/units/divider.py [deleted file]
src/soc/minerva/units/exception.py [deleted file]
src/soc/minerva/units/logic.py [deleted file]
src/soc/minerva/units/multiplier.py [deleted file]
src/soc/minerva/units/shifter.py [deleted file]
src/soc/minerva/units/trigger.py [deleted file]

diff --git a/src/soc/minerva/core.py b/src/soc/minerva/core.py
deleted file mode 100644 (file)
index c270f3b..0000000
+++ /dev/null
@@ -1,833 +0,0 @@
-from functools import reduce
-from operator import or_
-from itertools import tee
-
-from nmigen import Elaboratable, Module, Record, Mux, Const, Signal, Memory
-from nmigen.lib.coding import PriorityEncoder
-
-from soc.minerva.stage import Stage
-from soc.minerva.csr import CSRFile
-from soc.minerva.units.adder import Adder
-from soc.minerva.units.compare import CompareUnit
-from soc.minerva.units.debug import DebugUnit
-from soc.minerva.units.decoder import InstructionDecoder
-from soc.minerva.units.divider import Divider, DummyDivider
-from soc.minerva.units.exception import ExceptionUnit
-from soc.minerva.units.fetch import BareFetchUnit, CachedFetchUnit, PCSelector
-from soc.minerva.units.rvficon import RVFIController, rvfi_layout
-from soc.minerva.units.loadstore import (BareLoadStoreUnit, CachedLoadStoreUnit,
-                                         DataSelector)
-from soc.minerva.units.logic import LogicUnit
-from soc.minerva.units.multiplier import DummyMultiplier, Multiplier
-from soc.minerva.units.predict import BranchPredictor
-from soc.minerva.units.shifter import Shifter
-from soc.minerva.units.trigger import TriggerUnit
-
-from soc.minerva.units.debug.jtag import jtag_layout
-from soc.minerva.wishbone import wishbone_layout
-
-
-__all__ = ["Minerva"]
-
-
-_af_layout = [
-    ("pc",      (33, True)),
-]
-
-
-_fd_layout = [
-    ("pc",               32),
-    ("instruction",      32),
-    ("fetch_error",       1),
-    ("fetch_badaddr",    30)
-]
-
-
-_dx_layout = [
-    ("pc",                  32),
-    ("instruction",         32),
-    ("fetch_error",          1),
-    ("fetch_badaddr",       30),
-    ("illegal",              1),
-    ("rd",                   5),
-    ("rs1",                  5),
-    ("rd_we",                1),
-    ("rs1_re",               1),
-    ("src1",                32),
-    ("src2",                32),
-    ("immediate",           32),
-    ("bypass_x",             1),
-    ("bypass_m",             1),
-    ("funct3",               3),
-    ("load",                 1),
-    ("store",                1),
-    ("adder",                1),
-    ("adder_sub",            1),
-    ("logic",                1),
-    ("multiply",             1),
-    ("divide",               1),
-    ("shift",                1),
-    ("direction",            1),
-    ("sext",                 1),
-    ("jump",                 1),
-    ("compare",              1),
-    ("branch",               1),
-    ("branch_target",       32),
-    ("branch_predict_taken", 1),
-    ("fence_i",              1),
-    ("csr",                  1),
-    ("csr_adr",             12),
-    ("csr_we",               1),
-    ("ecall",                1),
-    ("ebreak",               1),
-    ("mret",                 1),
-]
-
-
-_xm_layout = [
-    ("pc",                  32),
-    ("instruction",         32),
-    ("fetch_error",          1),
-    ("fetch_badaddr",       30),
-    ("illegal",              1),
-    ("loadstore_misaligned", 1),
-    ("ecall",                1),
-    ("ebreak",               1),
-    ("rd",                   5),
-    ("rd_we",                1),
-    ("bypass_m",             1),
-    ("funct3",               3),
-    ("result",              32),
-    ("shift",                1),
-    ("load",                 1),
-    ("store",                1),
-    ("store_data",          32),
-    ("compare",              1),
-    ("multiply",             1),
-    ("divide",               1),
-    ("condition_met",        1),
-    ("branch_target",       32),
-    ("branch_taken",         1),
-    ("branch_predict_taken", 1),
-    ("csr",                  1),
-    ("csr_adr",             12),
-    ("csr_we",               1),
-    ("csr_result",          32),
-    ("mret",                 1),
-    ("exception",            1)
-]
-
-
-_mw_layout = [
-    ("pc",                32),
-    ("rd",                 5),
-    ("rd_we",              1),
-    ("funct3",             3),
-    ("result",            32),
-    ("load",               1),
-    ("load_data",         32),
-    ("multiply",           1),
-    ("exception",          1)
-]
-
-
-class Minerva(Elaboratable):
-    def __init__(self, reset_address=0x00000000,
-                 with_icache=False,
-                 icache_nways=1, icache_nlines=256, icache_nwords=8, icache_base=0, icache_limit=2**31,
-                 with_dcache=False,
-                 dcache_nways=1, dcache_nlines=256, dcache_nwords=8, dcache_base=0, dcache_limit=2**31,
-                 with_muldiv=False,
-                 with_debug=False,
-                 with_trigger=False, nb_triggers=8,
-                 with_rvfi=False):
-        self.external_interrupt = Signal(32)
-        self.timer_interrupt = Signal()
-        self.software_interrupt = Signal()
-        self.ibus = Record(wishbone_layout)
-        self.dbus = Record(wishbone_layout)
-
-        if with_debug:
-            self.jtag = Record(jtag_layout)
-
-        if with_rvfi:
-            self.rvfi = Record(rvfi_layout)
-
-        self.reset_address = reset_address
-        self.with_icache = with_icache
-        self.icache_args = icache_nways, icache_nlines, icache_nwords, icache_base, icache_limit
-        self.with_dcache = with_dcache
-        self.dcache_args = dcache_nways, dcache_nlines, dcache_nwords, dcache_base, dcache_limit
-        self.with_muldiv = with_muldiv
-        self.with_debug = with_debug
-        self.with_trigger = with_trigger
-        self.nb_triggers = nb_triggers
-        self.with_rvfi = with_rvfi
-
-    def elaborate(self, platform):
-        cpu = Module()
-
-        # pipeline stages
-
-        a = cpu.submodules.a = Stage(None, _af_layout)
-        f = cpu.submodules.f = Stage(_af_layout, _fd_layout)
-        d = cpu.submodules.d = Stage(_fd_layout, _dx_layout)
-        x = cpu.submodules.x = Stage(_dx_layout, _xm_layout)
-        m = cpu.submodules.m = Stage(_xm_layout, _mw_layout)
-        w = cpu.submodules.w = Stage(_mw_layout, None)
-        stages = a, f, d, x, m, w
-
-        sources, sinks = tee(stages)
-        next(sinks)
-        for s1, s2 in zip(sources, sinks):
-            cpu.d.comb += s1.source.connect(s2.sink)
-
-        a.source.pc.reset = self.reset_address - 4
-        cpu.d.comb += a.valid.eq(Const(1))
-
-        # units
-
-        pc_sel = cpu.submodules.pc_sel = PCSelector()
-        data_sel = cpu.submodules.data_sel = DataSelector()
-        adder = cpu.submodules.adder = Adder()
-        compare = cpu.submodules.compare = CompareUnit()
-        decoder = cpu.submodules.decoder = InstructionDecoder(self.with_muldiv)
-        exception = cpu.submodules.exception = ExceptionUnit()
-        logic = cpu.submodules.logic = LogicUnit()
-        predict = cpu.submodules.predict = BranchPredictor()
-        shifter = cpu.submodules.shifter = Shifter()
-
-        if self.with_icache:
-            fetch = cpu.submodules.fetch = CachedFetchUnit(*self.icache_args)
-        else:
-            fetch = cpu.submodules.fetch = BareFetchUnit()
-
-        if self.with_dcache:
-            loadstore = cpu.submodules.loadstore = CachedLoadStoreUnit(
-                *self.dcache_args)
-        else:
-            loadstore = cpu.submodules.loadstore = BareLoadStoreUnit()
-
-        if self.with_muldiv:
-            multiplier = Multiplier() if not self.with_rvfi else DummyMultiplier()
-            divider = Divider() if not self.with_rvfi else DummyDivider()
-            cpu.submodules.multiplier = multiplier
-            cpu.submodules.divider = divider
-
-        if self.with_debug:
-            debug = cpu.submodules.debug = DebugUnit()
-
-        if self.with_trigger:
-            trigger = cpu.submodules.trigger = TriggerUnit(self.nb_triggers)
-
-        if self.with_rvfi:
-            rvficon = cpu.submodules.rvficon = RVFIController()
-
-        # register files
-
-        gprf = Memory(width=32, depth=32)
-        gprf_rp1 = gprf.read_port()
-        gprf_rp2 = gprf.read_port()
-        gprf_wp = gprf.write_port()
-        cpu.submodules += gprf_rp1, gprf_rp2, gprf_wp
-
-        csrf = cpu.submodules.csrf = CSRFile()
-        csrf_rp = csrf.read_port()
-        csrf_wp = csrf.write_port()
-
-        csrf.add_csrs(exception.iter_csrs())
-        if self.with_debug:
-            csrf.add_csrs(debug.iter_csrs())
-        if self.with_trigger:
-            csrf.add_csrs(trigger.iter_csrs())
-
-        # pipeline logic
-
-        cpu.d.comb += [
-            pc_sel.f_pc.eq(f.sink.pc),
-            pc_sel.d_pc.eq(d.sink.pc),
-            pc_sel.d_branch_predict_taken.eq(
-                predict.d_branch_taken & ~predict.d_fetch_misaligned),
-            pc_sel.d_branch_target.eq(predict.d_branch_target),
-            pc_sel.d_valid.eq(d.valid),
-            pc_sel.x_pc.eq(x.sink.pc),
-            pc_sel.x_fence_i.eq(x.sink.fence_i),
-            pc_sel.x_valid.eq(x.valid),
-            pc_sel.m_branch_predict_taken.eq(m.sink.branch_predict_taken),
-            pc_sel.m_branch_taken.eq(m.sink.branch_taken),
-            pc_sel.m_branch_target.eq(m.sink.branch_target),
-            pc_sel.m_exception.eq(exception.m_raise),
-            pc_sel.m_mret.eq(m.sink.mret),
-            pc_sel.m_valid.eq(m.valid),
-            pc_sel.mtvec_r_base.eq(exception.mtvec.r.base),
-            pc_sel.mepc_r_base.eq(exception.mepc.r.base)
-        ]
-
-        cpu.d.comb += [
-            fetch.a_pc.eq(pc_sel.a_pc),
-            fetch.a_stall.eq(a.stall),
-            fetch.a_valid.eq(a.valid),
-            fetch.f_stall.eq(f.stall),
-            fetch.f_valid.eq(f.valid),
-            fetch.ibus.connect(self.ibus)
-        ]
-
-        m.stall_on(fetch.a_busy & a.valid)
-        m.stall_on(fetch.f_busy & f.valid)
-
-        if self.with_icache:
-            flush_icache = x.sink.fence_i & x.valid & ~x.stall
-            if self.with_debug:
-                flush_icache |= debug.resumereq
-
-            cpu.d.comb += [
-                fetch.a_flush.eq(flush_icache),
-                fetch.f_pc.eq(f.sink.pc)
-            ]
-
-        cpu.d.comb += [
-            decoder.instruction.eq(d.sink.instruction)
-        ]
-
-        if self.with_debug:
-            with cpu.If(debug.halt & debug.halted):
-                cpu.d.comb += gprf_rp1.addr.eq(debug.gprf_addr)
-            with cpu.Elif(~d.stall):
-                cpu.d.comb += gprf_rp1.addr.eq(fetch.f_instruction[15:20])
-            with cpu.Else():
-                cpu.d.comb += gprf_rp1.addr.eq(decoder.rs1)
-
-            cpu.d.comb += debug.gprf_dat_r.eq(gprf_rp1.data)
-        else:
-            with cpu.If(~d.stall):
-                cpu.d.comb += gprf_rp1.addr.eq(fetch.f_instruction[15:20])
-            with cpu.Else():
-                cpu.d.comb += gprf_rp1.addr.eq(decoder.rs1)
-
-        with cpu.If(~d.stall):
-            cpu.d.comb += gprf_rp2.addr.eq(fetch.f_instruction[20:25])
-        with cpu.Else():
-            cpu.d.comb += gprf_rp2.addr.eq(decoder.rs2)
-
-        with cpu.If(~f.stall):
-            cpu.d.sync += csrf_rp.addr.eq(fetch.f_instruction[20:32])
-        cpu.d.comb += csrf_rp.en.eq(decoder.csr & d.valid)
-
-        # CSR set/clear instructions are translated to logic operations.
-        x_csr_set_clear = x.sink.funct3[1]
-        x_csr_clear = x_csr_set_clear & x.sink.funct3[0]
-        x_csr_fmt_i = x.sink.funct3[2]
-        x_csr_src1 = Mux(x_csr_fmt_i, x.sink.rs1, x.sink.src1)
-        x_csr_src1 = Mux(x_csr_clear, ~x_csr_src1, x_csr_src1)
-        x_csr_logic_op = x.sink.funct3 | 0b100
-
-        cpu.d.comb += [
-            logic.op.eq(Mux(x.sink.csr, x_csr_logic_op, x.sink.funct3)),
-            logic.src1.eq(Mux(x.sink.csr, x_csr_src1, x.sink.src1)),
-            logic.src2.eq(x.sink.src2)
-        ]
-
-        cpu.d.comb += [
-            adder.sub.eq(x.sink.adder & x.sink.adder_sub |
-                         x.sink.compare | x.sink.branch),
-            adder.src1.eq(x.sink.src1),
-            adder.src2.eq(Mux(x.sink.store, x.sink.immediate, x.sink.src2))
-        ]
-
-        if self.with_muldiv:
-            cpu.d.comb += [
-                multiplier.x_op.eq(x.sink.funct3),
-                multiplier.x_src1.eq(x.sink.src1),
-                multiplier.x_src2.eq(x.sink.src2),
-                multiplier.x_stall.eq(x.stall),
-                multiplier.m_stall.eq(m.stall)
-            ]
-
-            cpu.d.comb += [
-                divider.x_op.eq(x.sink.funct3),
-                divider.x_src1.eq(x.sink.src1),
-                divider.x_src2.eq(x.sink.src2),
-                divider.x_valid.eq(x.sink.valid),
-                divider.x_stall.eq(x.stall)
-            ]
-
-            m.stall_on(divider.m_busy)
-
-        cpu.d.comb += [
-            shifter.x_direction.eq(x.sink.direction),
-            shifter.x_sext.eq(x.sink.sext),
-            shifter.x_shamt.eq(x.sink.src2),
-            shifter.x_src1.eq(x.sink.src1),
-            shifter.x_stall.eq(x.stall)
-        ]
-
-        cpu.d.comb += [
-            # compare.op is shared by compare and branch instructions.
-            compare.op.eq(
-                Mux(x.sink.compare, x.sink.funct3 << 1, x.sink.funct3)),
-            compare.zero.eq(x.sink.src1 == x.sink.src2),
-            compare.negative.eq(adder.result[-1]),
-            compare.overflow.eq(adder.overflow),
-            compare.carry.eq(adder.carry)
-        ]
-
-        cpu.d.comb += [
-            exception.external_interrupt.eq(self.external_interrupt),
-            exception.timer_interrupt.eq(self.timer_interrupt),
-            exception.software_interrupt.eq(self.software_interrupt),
-            exception.m_fetch_misaligned.eq(
-                m.sink.branch_taken & m.sink.branch_target[:2].bool()),
-            exception.m_fetch_error.eq(m.sink.fetch_error),
-            exception.m_fetch_badaddr.eq(m.sink.fetch_badaddr),
-            exception.m_load_misaligned.eq(
-                m.sink.load & m.sink.loadstore_misaligned),
-            exception.m_load_error.eq(loadstore.m_load_error),
-            exception.m_store_misaligned.eq(
-                m.sink.store & m.sink.loadstore_misaligned),
-            exception.m_store_error.eq(loadstore.m_store_error),
-            exception.m_loadstore_badaddr.eq(loadstore.m_badaddr),
-            exception.m_branch_target.eq(m.sink.branch_target),
-            exception.m_illegal.eq(m.sink.illegal),
-            exception.m_ecall.eq(m.sink.ecall),
-            exception.m_pc.eq(m.sink.pc),
-            exception.m_instruction.eq(m.sink.instruction),
-            exception.m_result.eq(m.sink.result),
-            exception.m_mret.eq(m.sink.mret),
-            exception.m_stall.eq(m.sink.stall),
-            exception.m_valid.eq(m.valid)
-        ]
-
-        m_ebreak = m.sink.ebreak
-        if self.with_debug:
-            # If dcsr.ebreakm is set, EBREAK instructions enter Debug Mode.
-            # We do not want to raise an exception in this case because Debug Mode
-            # should be invisible to software execution.
-            m_ebreak &= ~debug.dcsr_ebreakm
-        if self.with_trigger:
-            m_ebreak |= trigger.trap
-        cpu.d.comb += exception.m_ebreak.eq(m_ebreak)
-
-        m.kill_on(m.source.exception & m.source.valid)
-
-        cpu.d.comb += [
-            data_sel.x_offset.eq(adder.result[:2]),
-            data_sel.x_funct3.eq(x.sink.funct3),
-            data_sel.x_store_operand.eq(x.sink.src2),
-            data_sel.w_offset.eq(w.sink.result[:2]),
-            data_sel.w_funct3.eq(w.sink.funct3),
-            data_sel.w_load_data.eq(w.sink.load_data)
-        ]
-
-        cpu.d.comb += [
-            loadstore.x_addr.eq(adder.result),
-            loadstore.x_mask.eq(data_sel.x_mask),
-            loadstore.x_load.eq(x.sink.load),
-            loadstore.x_store.eq(x.sink.store),
-            loadstore.x_store_data.eq(data_sel.x_store_data),
-            loadstore.x_stall.eq(x.stall),
-            loadstore.x_valid.eq(x.valid),
-            loadstore.m_stall.eq(m.stall),
-            loadstore.m_valid.eq(m.valid)
-        ]
-
-        m.stall_on(loadstore.x_busy & x.valid)
-        m.stall_on(loadstore.m_busy & m.valid)
-
-        if self.with_dcache:
-            if self.with_debug:
-                cpu.d.comb += loadstore.x_flush.eq(debug.resumereq)
-
-            cpu.d.comb += [
-                loadstore.x_fence_i.eq(x.sink.fence_i),
-                loadstore.m_addr.eq(m.sink.result),
-                loadstore.m_load.eq(m.sink.load),
-                loadstore.m_store.eq(m.sink.store),
-            ]
-
-            x.stall_on(loadstore.x_busy & x.valid)
-
-        for s in a, f:
-            s.kill_on(x.sink.fence_i & x.valid)
-
-        if self.with_debug:
-            with cpu.If(debug.halt & debug.halted):
-                cpu.d.comb += debug.dbus.connect(self.dbus)
-            with cpu.Else():
-                cpu.d.comb += loadstore.dbus.connect(self.dbus)
-        else:
-            cpu.d.comb += loadstore.dbus.connect(self.dbus)
-
-        # RAW hazard management
-
-        x_raw_rs1 = Signal()
-        m_raw_rs1 = Signal()
-        w_raw_rs1 = Signal()
-        x_raw_rs2 = Signal()
-        m_raw_rs2 = Signal()
-        w_raw_rs2 = Signal()
-
-        x_raw_csr = Signal()
-        m_raw_csr = Signal()
-
-        x_lock = Signal()
-        m_lock = Signal()
-
-        cpu.d.comb += [
-            x_raw_rs1.eq((x.sink.rd != 0) & (
-                x.sink.rd == decoder.rs1) & x.sink.rd_we),
-            m_raw_rs1.eq((m.sink.rd != 0) & (
-                m.sink.rd == decoder.rs1) & m.sink.rd_we),
-            w_raw_rs1.eq((w.sink.rd != 0) & (
-                w.sink.rd == decoder.rs1) & w.sink.rd_we),
-
-            x_raw_rs2.eq((x.sink.rd != 0) & (
-                x.sink.rd == decoder.rs2) & x.sink.rd_we),
-            m_raw_rs2.eq((m.sink.rd != 0) & (
-                m.sink.rd == decoder.rs2) & m.sink.rd_we),
-            w_raw_rs2.eq((w.sink.rd != 0) & (
-                w.sink.rd == decoder.rs2) & w.sink.rd_we),
-
-            x_raw_csr.eq((x.sink.csr_adr == decoder.immediate)
-                         & x.sink.csr_we),
-            m_raw_csr.eq((m.sink.csr_adr == decoder.immediate)
-                         & m.sink.csr_we),
-
-            x_lock.eq(~x.sink.bypass_x & (decoder.rs1_re & x_raw_rs1 |
-                                          decoder.rs2_re & x_raw_rs2) | decoder.csr & x_raw_csr),
-            m_lock.eq(~m.sink.bypass_m & (decoder.rs1_re & m_raw_rs1 |
-                                          decoder.rs2_re & m_raw_rs2) | decoder.csr & m_raw_csr)
-        ]
-
-        if self.with_debug:
-            d.stall_on((x_lock & x.valid | m_lock & m.valid)
-                       & d.valid & ~debug.dcsr_step)
-        else:
-            d.stall_on((x_lock & x.valid | m_lock & m.valid) & d.valid)
-
-        # result selection
-
-        x_result = Signal(32)
-        m_result = Signal(32)
-        w_result = Signal(32)
-        x_csr_result = Signal(32)
-
-        with cpu.If(x.sink.jump):
-            cpu.d.comb += x_result.eq(x.sink.pc + 4)
-        with cpu.Elif(x.sink.logic):
-            cpu.d.comb += x_result.eq(logic.result)
-        with cpu.Elif(x.sink.csr):
-            cpu.d.comb += x_result.eq(x.sink.src2)
-        with cpu.Else():
-            cpu.d.comb += x_result.eq(adder.result)
-
-        with cpu.If(m.sink.compare):
-            cpu.d.comb += m_result.eq(m.sink.condition_met)
-        if self.with_muldiv:
-            with cpu.Elif(m.sink.divide):
-                cpu.d.comb += m_result.eq(divider.m_result)
-        with cpu.Elif(m.sink.shift):
-            cpu.d.comb += m_result.eq(shifter.m_result)
-        with cpu.Else():
-            cpu.d.comb += m_result.eq(m.sink.result)
-
-        with cpu.If(w.sink.load):
-            cpu.d.comb += w_result.eq(data_sel.w_load_result)
-        if self.with_muldiv:
-            with cpu.Elif(w.sink.multiply):
-                cpu.d.comb += w_result.eq(multiplier.w_result)
-        with cpu.Else():
-            cpu.d.comb += w_result.eq(w.sink.result)
-
-        with cpu.If(x_csr_set_clear):
-            cpu.d.comb += x_csr_result.eq(logic.result)
-        with cpu.Else():
-            cpu.d.comb += x_csr_result.eq(x_csr_src1)
-
-        cpu.d.comb += [
-            csrf_wp.en.eq(m.sink.csr & m.sink.csr_we & m.valid &
-                          ~exception.m_raise & ~m.stall),
-            csrf_wp.addr.eq(m.sink.csr_adr),
-            csrf_wp.data.eq(m.sink.csr_result)
-        ]
-
-        if self.with_debug:
-            with cpu.If(debug.halt & debug.halted):
-                cpu.d.comb += [
-                    gprf_wp.addr.eq(debug.gprf_addr),
-                    gprf_wp.en.eq(debug.gprf_we),
-                    gprf_wp.data.eq(debug.gprf_dat_w)
-                ]
-            with cpu.Else():
-                cpu.d.comb += [
-                    gprf_wp.en.eq((w.sink.rd != 0) & w.sink.rd_we &
-                                  w.valid & ~w.sink.exception),
-                    gprf_wp.addr.eq(w.sink.rd),
-                    gprf_wp.data.eq(w_result)
-                ]
-        else:
-            cpu.d.comb += [
-                gprf_wp.en.eq((w.sink.rd != 0) & w.sink.rd_we & w.valid),
-                gprf_wp.addr.eq(w.sink.rd),
-                gprf_wp.data.eq(w_result)
-            ]
-
-        # D stage operand selection
-
-        d_src1 = Signal(32)
-        d_src2 = Signal(32)
-
-        with cpu.If(decoder.lui):
-            cpu.d.comb += d_src1.eq(0)
-        with cpu.Elif(decoder.auipc):
-            cpu.d.comb += d_src1.eq(d.sink.pc)
-        with cpu.Elif(decoder.rs1_re & (decoder.rs1 == 0)):
-            cpu.d.comb += d_src1.eq(0)
-        with cpu.Elif(x_raw_rs1 & x.valid):
-            cpu.d.comb += d_src1.eq(x_result)
-        with cpu.Elif(m_raw_rs1 & m.valid):
-            cpu.d.comb += d_src1.eq(m_result)
-        with cpu.Elif(w_raw_rs1 & w.valid):
-            cpu.d.comb += d_src1.eq(w_result)
-        with cpu.Else():
-            cpu.d.comb += d_src1.eq(gprf_rp1.data)
-
-        with cpu.If(decoder.csr):
-            cpu.d.comb += d_src2.eq(csrf_rp.data)
-        with cpu.Elif(~decoder.rs2_re):
-            cpu.d.comb += d_src2.eq(decoder.immediate)
-        with cpu.Elif(decoder.rs2 == 0):
-            cpu.d.comb += d_src2.eq(0)
-        with cpu.Elif(x_raw_rs2 & x.valid):
-            cpu.d.comb += d_src2.eq(x_result)
-        with cpu.Elif(m_raw_rs2 & m.valid):
-            cpu.d.comb += d_src2.eq(m_result)
-        with cpu.Elif(w_raw_rs2 & w.valid):
-            cpu.d.comb += d_src2.eq(w_result)
-        with cpu.Else():
-            cpu.d.comb += d_src2.eq(gprf_rp2.data)
-
-        # branch prediction
-
-        cpu.d.comb += [
-            predict.d_branch.eq(decoder.branch),
-            predict.d_jump.eq(decoder.jump),
-            predict.d_offset.eq(decoder.immediate),
-            predict.d_pc.eq(d.sink.pc),
-            predict.d_rs1_re.eq(decoder.rs1_re)
-        ]
-
-        a.kill_on(predict.d_branch_taken & ~
-                  predict.d_fetch_misaligned & d.valid)
-        for s in a, f:
-            s.kill_on(m.sink.branch_predict_taken & ~
-                      m.sink.branch_taken & m.valid)
-        for s in a, f, d:
-            s.kill_on(~m.sink.branch_predict_taken &
-                      m.sink.branch_taken & m.valid)
-            s.kill_on((exception.m_raise | m.sink.mret) & m.valid)
-
-        # debug unit
-
-        if self.with_debug:
-            cpu.d.comb += [
-                debug.jtag.connect(self.jtag),
-                debug.x_pc.eq(x.sink.pc),
-                debug.x_ebreak.eq(x.sink.ebreak),
-                debug.x_stall.eq(x.stall),
-                debug.m_branch_taken.eq(m.sink.branch_taken),
-                debug.m_branch_target.eq(m.sink.branch_target),
-                debug.m_mret.eq(m.sink.mret),
-                debug.m_exception.eq(exception.m_raise),
-                debug.m_pc.eq(m.sink.pc),
-                debug.m_valid.eq(m.valid),
-                debug.mepc_r_base.eq(exception.mepc.r.base),
-                debug.mtvec_r_base.eq(exception.mtvec.r.base)
-            ]
-
-            if self.with_trigger:
-                cpu.d.comb += debug.trigger_haltreq.eq(trigger.haltreq)
-            else:
-                cpu.d.comb += debug.trigger_haltreq.eq(Const(0))
-
-            csrf_debug_rp = csrf.read_port()
-            csrf_debug_wp = csrf.write_port()
-            cpu.d.comb += [
-                csrf_debug_rp.addr.eq(debug.csrf_addr),
-                csrf_debug_rp.en.eq(debug.csrf_re),
-                debug.csrf_dat_r.eq(csrf_debug_rp.data),
-                csrf_debug_wp.addr.eq(debug.csrf_addr),
-                csrf_debug_wp.en.eq(debug.csrf_we),
-                csrf_debug_wp.data.eq(debug.csrf_dat_w)
-            ]
-
-            x.stall_on(debug.halt)
-            m.stall_on(debug.dcsr_step & m.valid & ~debug.halt)
-            for s in a, f, d, x:
-                s.kill_on(debug.killall)
-
-            halted = x.stall & ~reduce(or_, (s.valid for s in (m, w)))
-            cpu.d.sync += debug.halted.eq(halted)
-
-            with cpu.If(debug.resumereq):
-                with cpu.If(~debug.dbus_busy):
-                    cpu.d.comb += debug.resumeack.eq(1)
-                    cpu.d.sync += a.source.pc.eq(debug.dpc_value - 4)
-
-        if self.with_trigger:
-            cpu.d.comb += [
-                trigger.x_pc.eq(x.sink.pc),
-                trigger.x_valid.eq(x.valid),
-            ]
-
-        if self.with_rvfi:
-            cpu.d.comb += [
-                rvficon.d_insn.eq(decoder.instruction),
-                rvficon.d_rs1_addr.eq(Mux(decoder.rs1_re, decoder.rs1, 0)),
-                rvficon.d_rs2_addr.eq(Mux(decoder.rs2_re, decoder.rs2, 0)),
-                rvficon.d_rs1_rdata.eq(Mux(decoder.rs1_re, d_src1, 0)),
-                rvficon.d_rs2_rdata.eq(Mux(decoder.rs2_re, d_src2, 0)),
-                rvficon.d_stall.eq(d.stall),
-                rvficon.x_mem_addr.eq(loadstore.x_addr[2:] << 2),
-                rvficon.x_mem_wmask.eq(
-                    Mux(loadstore.x_store, loadstore.x_mask, 0)),
-                rvficon.x_mem_rmask.eq(
-                    Mux(loadstore.x_load, loadstore.x_mask, 0)),
-                rvficon.x_mem_wdata.eq(loadstore.x_store_data),
-                rvficon.x_stall.eq(x.stall),
-                rvficon.m_mem_rdata.eq(loadstore.m_load_data),
-                rvficon.m_fetch_misaligned.eq(exception.m_fetch_misaligned),
-                rvficon.m_illegal_insn.eq(m.sink.illegal),
-                rvficon.m_load_misaligned.eq(exception.m_load_misaligned),
-                rvficon.m_store_misaligned.eq(exception.m_store_misaligned),
-                rvficon.m_exception.eq(exception.m_raise),
-                rvficon.m_mret.eq(m.sink.mret),
-                rvficon.m_branch_taken.eq(m.sink.branch_taken),
-                rvficon.m_branch_target.eq(m.sink.branch_target),
-                rvficon.m_pc_rdata.eq(m.sink.pc),
-                rvficon.m_stall.eq(m.stall),
-                rvficon.m_valid.eq(m.valid),
-                rvficon.w_rd_addr.eq(Mux(gprf_wp.en, gprf_wp.addr, 0)),
-                rvficon.w_rd_wdata.eq(Mux(gprf_wp.en, gprf_wp.data, 0)),
-                rvficon.mtvec_r_base.eq(exception.mtvec.r.base),
-                rvficon.mepc_r_value.eq(exception.mepc.r),
-                rvficon.rvfi.connect(self.rvfi)
-            ]
-
-        # pipeline registers
-
-        # A/F
-        with cpu.If(~a.stall):
-            cpu.d.sync += a.source.pc.eq(fetch.a_pc)
-
-        # F/D
-        with cpu.If(~f.stall):
-            cpu.d.sync += [
-                f.source.pc.eq(f.sink.pc),
-                f.source.instruction.eq(fetch.f_instruction),
-                f.source.fetch_error.eq(fetch.f_fetch_error),
-                f.source.fetch_badaddr.eq(fetch.f_badaddr)
-            ]
-
-        # D/X
-        with cpu.If(~d.stall):
-            cpu.d.sync += [
-                d.source.pc.eq(d.sink.pc),
-                d.source.instruction.eq(d.sink.instruction),
-                d.source.fetch_error.eq(d.sink.fetch_error),
-                d.source.fetch_badaddr.eq(d.sink.fetch_badaddr),
-                d.source.illegal.eq(decoder.illegal),
-                d.source.rd.eq(decoder.rd),
-                d.source.rs1.eq(decoder.rs1),
-                d.source.rd_we.eq(decoder.rd_we),
-                d.source.rs1_re.eq(decoder.rs1_re),
-                d.source.immediate.eq(decoder.immediate),
-                d.source.bypass_x.eq(decoder.bypass_x),
-                d.source.bypass_m.eq(decoder.bypass_m),
-                d.source.funct3.eq(decoder.funct3),
-                d.source.load.eq(decoder.load),
-                d.source.store.eq(decoder.store),
-                d.source.adder.eq(decoder.adder),
-                d.source.adder_sub.eq(decoder.adder_sub),
-                d.source.compare.eq(decoder.compare),
-                d.source.logic.eq(decoder.logic),
-                d.source.shift.eq(decoder.shift),
-                d.source.direction.eq(decoder.direction),
-                d.source.sext.eq(decoder.sext),
-                d.source.jump.eq(decoder.jump),
-                d.source.branch.eq(decoder.branch),
-                d.source.fence_i.eq(decoder.fence_i),
-                d.source.csr.eq(decoder.csr),
-                d.source.csr_adr.eq(decoder.immediate),
-                d.source.csr_we.eq(decoder.csr_we),
-                d.source.ecall.eq(decoder.ecall),
-                d.source.ebreak.eq(decoder.ebreak),
-                d.source.mret.eq(decoder.mret),
-                d.source.src1.eq(d_src1),
-                d.source.src2.eq(d_src2),
-                d.source.branch_predict_taken.eq(
-                    predict.d_branch_taken & ~predict.d_fetch_misaligned),
-                d.source.branch_target.eq(predict.d_branch_target)
-            ]
-            if self.with_muldiv:
-                cpu.d.sync += [
-                    d.source.multiply.eq(decoder.multiply),
-                    d.source.divide.eq(decoder.divide)
-                ]
-
-        # X/M
-        with cpu.If(~x.stall):
-            cpu.d.sync += [
-                x.source.pc.eq(x.sink.pc),
-                x.source.instruction.eq(x.sink.instruction),
-                x.source.fetch_error.eq(x.sink.fetch_error),
-                x.source.fetch_badaddr.eq(x.sink.fetch_badaddr),
-                x.source.illegal.eq(x.sink.illegal),
-                x.source.loadstore_misaligned.eq(data_sel.x_misaligned),
-                x.source.ecall.eq(x.sink.ecall),
-                x.source.ebreak.eq(x.sink.ebreak),
-                x.source.rd.eq(x.sink.rd),
-                x.source.rd_we.eq(x.sink.rd_we),
-                x.source.bypass_m.eq(x.sink.bypass_m | x.sink.bypass_x),
-                x.source.funct3.eq(x.sink.funct3),
-                x.source.load.eq(x.sink.load),
-                x.source.store.eq(x.sink.store),
-                x.source.store_data.eq(loadstore.x_store_data),
-                x.source.compare.eq(x.sink.compare),
-                x.source.shift.eq(x.sink.shift),
-                x.source.mret.eq(x.sink.mret),
-                x.source.condition_met.eq(compare.condition_met),
-                x.source.branch_taken.eq(
-                    x.sink.jump | x.sink.branch & compare.condition_met),
-                x.source.branch_target.eq(
-                    Mux(x.sink.jump & x.sink.rs1_re, adder.result[1:] << 1, x.sink.branch_target)),
-                x.source.branch_predict_taken.eq(x.sink.branch_predict_taken),
-                x.source.csr.eq(x.sink.csr),
-                x.source.csr_adr.eq(x.sink.csr_adr),
-                x.source.csr_we.eq(x.sink.csr_we),
-                x.source.csr_result.eq(x_csr_result),
-                x.source.result.eq(x_result)
-            ]
-            if self.with_muldiv:
-                cpu.d.sync += [
-                    x.source.multiply.eq(x.sink.multiply),
-                    x.source.divide.eq(x.sink.divide)
-                ]
-
-        # M/W
-        with cpu.If(~m.stall):
-            cpu.d.sync += [
-                m.source.pc.eq(m.sink.pc),
-                m.source.rd.eq(m.sink.rd),
-                m.source.load.eq(m.sink.load),
-                m.source.funct3.eq(m.sink.funct3),
-                m.source.load_data.eq(loadstore.m_load_data),
-                m.source.rd_we.eq(m.sink.rd_we),
-                m.source.result.eq(m_result),
-                m.source.exception.eq(exception.m_raise)
-            ]
-            if self.with_muldiv:
-                cpu.d.sync += [
-                    m.source.multiply.eq(m.sink.multiply)
-                ]
-
-        return cpu
diff --git a/src/soc/minerva/csr.py b/src/soc/minerva/csr.py
deleted file mode 100644 (file)
index 120f426..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-from enum import Enum
-from collections import OrderedDict
-
-from nmigen import (Const, Elaboratable, Module, Mux,
-                    Record, Signal,)
-from nmigen.utils import bits_for
-
-
-__all__ = ["CSRAccess", "CSR", "AutoCSR", "CSRFile"]
-
-
-CSRAccess = Enum("CSRAccess", ("WIRI", "WPRI", "WLRL", "WARL"))
-
-
-class CSR():
-    def __init__(self, addr, description, name):
-        fields = []
-        mask = 0
-        offset = 0
-        for name, shape, access in description:
-            if isinstance(shape, int):
-                shape = shape, False
-            nbits, signed = shape
-            fields.append((name, shape))
-            if access in {CSRAccess.WLRL, CSRAccess.WARL}:
-                mask |= ((1 << nbits) - 1) << offset
-            offset += nbits
-
-        self.addr = addr
-        self.rmask = self.wmask = Const(mask)
-        self.r = Record(fields)
-        self.w = Record(fields)
-        self.re = Signal()
-        self.we = Signal()
-
-
-class AutoCSR():
-    def iter_csrs(self):
-        for v in vars(self).values():
-            if isinstance(v, CSR):
-                yield v
-            elif hasattr(v, "iter_csrs"):
-                yield from v.iter_csrs()
-
-
-class CSRFile(Elaboratable):
-    def __init__(self, width=32, depth=2**12):
-        self.width = width
-        self.depth = depth
-        self._csr_map = OrderedDict()
-        self._read_ports = []
-        self._write_ports = []
-
-    def add_csrs(self, csrs):
-        for csr in csrs:
-            if not isinstance(csr, CSR):
-                raise TypeError("Object {!r} is not a CSR".format(csr))
-            if csr.addr in self._csr_map:
-                raise ValueError("CSR address 0x{:x} has already been allocated"
-                                 .format(csr.addr))
-            self._csr_map[csr.addr] = csr
-
-    def read_port(self):
-        port = Record([("addr", bits_for(self.depth)), ("en", 1), ("data", self.width)])
-        self._read_ports.append(port)
-        return port
-
-    def write_port(self):
-        port = Record([("addr", bits_for(self.depth)), ("en", 1), ("data", self.width)])
-        self._write_ports.append(port)
-        return port
-
-    def elaborate(self, platform):
-        m = Module()
-
-        for rp in self._read_ports:
-            with m.Switch(rp.addr):
-                for addr, csr in self._csr_map.items():
-                    with m.Case(addr):
-                        m.d.comb += [
-                            csr.re.eq(rp.en),
-                            rp.data.eq(csr.r & csr.rmask)
-                        ]
-
-        for wp in self._write_ports:
-            with m.Switch(wp.addr):
-                for addr, csr in self._csr_map.items():
-                    with m.Case(addr):
-                        m.d.comb += [
-                            csr.we.eq(wp.en),
-                            csr.w.eq(wp.data & csr.wmask)
-                        ]
-
-        return m
diff --git a/src/soc/minerva/isa.py b/src/soc/minerva/isa.py
deleted file mode 100644 (file)
index 625a4e1..0000000
+++ /dev/null
@@ -1,221 +0,0 @@
-from soc.minerva.csr import CSRAccess
-
-
-__all__ = [
-    "Opcode", "Funct3", "Funct7", "Funct12", "CSRIndex", "Cause",
-    "flat_layout", "misa_layout", "mstatus_layout", "mtvec_layout", "mepc_layout",
-    "mip_layout", "mie_layout", "mcause_layout", "dcsr_layout", "tdata1_layout"
-]
-
-class Opcode:
-    LUI       = 0b01101
-    AUIPC     = 0b00101
-    JAL       = 0b11011
-    JALR      = 0b11001
-    BRANCH    = 0b11000
-    LOAD      = 0b00000
-    STORE     = 0b01000
-    OP_IMM_32 = 0b00100
-    OP_32     = 0b01100
-    MISC_MEM  = 0b00011
-    SYSTEM    = 0b11100
-
-
-class Funct3:
-    BEQ  = B  = ADD  = FENCE  = PRIV   = MUL    = 0b000
-    BNE  = H  = SLL  = FENCEI = CSRRW  = MULH   = 0b001
-    _    = W  = SLT  = _      = CSRRS  = MULHSU = 0b010
-    _    = _  = SLTU = _      = CSRRC  = MULHU  = 0b011
-    BLT  = BU = XOR  = _      = _      = DIV    = 0b100
-    BGE  = HU = SR   = _      = CSRRWI = DIVU   = 0b101
-    BLTU = _  = OR   = _      = CSRRSI = REM    = 0b110
-    BGEU = _  = AND  = _      = CSRRCI = REMU   = 0b111
-
-
-class Funct7:
-    SRL = ADD = 0b0000000
-    MULDIV    = 0b0000001
-    SRA = SUB = 0b0100000
-
-
-class Funct12:
-    ECALL  = 0b000000000000
-    EBREAK = 0b000000000001
-    MRET   = 0b001100000010
-    WFI    = 0b000100000101
-
-
-class CSRIndex:
-    MVENDORID   = 0xF11
-    MARCHID     = 0xF12
-    MIMPID      = 0xF13
-    MHARTID     = 0xF14
-    MSTATUS     = 0x300
-    MISA        = 0x301
-    MEDELEG     = 0x302
-    MIDELEG     = 0x303
-    MIE         = 0x304
-    MTVEC       = 0x305
-    MCOUTEREN   = 0x306
-    MSCRATCH    = 0x340
-    MEPC        = 0x341
-    MCAUSE      = 0x342
-    MTVAL       = 0x343
-    MIP         = 0x344
-    # µarch specific
-    IRQ_MASK    = 0x330
-    IRQ_PENDING = 0x360
-    # trigger module
-    TSELECT     = 0x7a0
-    TDATA1      = 0x7a1
-    TDATA2      = 0x7a2
-    TDATA3      = 0x7a3
-    TINFO       = 0x7a4
-    MCONTEXT    = 0x7a8
-    # debug module
-    DCSR        = 0x7b0
-    DPC         = 0x7b1
-
-
-class Cause:
-    FETCH_MISALIGNED     = 0
-    FETCH_ACCESS_FAULT   = 1
-    ILLEGAL_INSTRUCTION  = 2
-    BREAKPOINT           = 3
-    LOAD_MISALIGNED      = 4
-    LOAD_ACCESS_FAULT    = 5
-    STORE_MISALIGNED     = 6
-    STORE_ACCESS_FAULT   = 7
-    ECALL_FROM_U         = 8
-    ECALL_FROM_S         = 9
-    ECALL_FROM_M         = 11
-    FETCH_PAGE_FAULT     = 12
-    LOAD_PAGE_FAULT      = 13
-    STORE_PAGE_FAULT     = 15
-    # interrupts
-    U_SOFTWARE_INTERRUPT = 0
-    S_SOFTWARE_INTERRUPT = 1
-    M_SOFTWARE_INTERRUPT = 3
-    U_TIMER_INTERRUPT    = 4
-    S_TIMER_INTERRUPT    = 5
-    M_TIMER_INTERRUPT    = 7
-    U_EXTERNAL_INTERRUPT = 8
-    S_EXTERNAL_INTERRUPT = 9
-    M_EXTERNAL_INTERRUPT = 11
-
-
-# CSR layouts
-
-flat_layout = [
-    ("value", 32, CSRAccess.WARL)
-]
-
-
-misa_layout = [
-    ("extensions", 26, CSRAccess.WARL),
-    ("wiri0",       4, CSRAccess.WIRI),
-    ("mxl",         2, CSRAccess.WARL)
-]
-
-
-mstatus_layout = [
-    ("uie",   1, CSRAccess.WARL), # User Interrupt Enable
-    ("sie",   1, CSRAccess.WARL), # Supervisor Interrupt Enable
-    ("wpri0", 1, CSRAccess.WPRI),
-    ("mie",   1, CSRAccess.WARL), # Machine Interrupt Enable
-    ("upie",  1, CSRAccess.WARL), # User Previous Interrupt Enable
-    ("spie",  1, CSRAccess.WARL), # Supervisor Previous Interrupt Enable
-    ("wpri1", 1, CSRAccess.WPRI),
-    ("mpie",  1, CSRAccess.WARL), # Machine Previous Interrupt Enable
-    ("spp",   1, CSRAccess.WARL), # Supervisor Previous Privilege
-    ("wpri2", 2, CSRAccess.WPRI),
-    ("mpp",   2, CSRAccess.WARL), # Machine Previous Privilege
-    ("fs",    2, CSRAccess.WARL), # FPU Status
-    ("xs",    2, CSRAccess.WARL), # user-mode eXtensions Status
-    ("mprv",  1, CSRAccess.WARL), # Modify PRiVilege
-    ("sum",   1, CSRAccess.WARL), # Supervisor User Memory access
-    ("mxr",   1, CSRAccess.WARL), # Make eXecutable Readable
-    ("tvm",   1, CSRAccess.WARL), # Trap Virtual Memory
-    ("tw",    1, CSRAccess.WARL), # Timeout Wait
-    ("tsr",   1, CSRAccess.WARL), # Trap SRET
-    ("wpri3", 8, CSRAccess.WPRI),
-    ("sd",    1, CSRAccess.WARL)  # State Dirty (set if XS or FS are set to dirty)
-]
-
-
-mtvec_layout = [
-    ("mode",  2, CSRAccess.WARL),
-    ("base", 30, CSRAccess.WARL)
-]
-
-
-mepc_layout = [
-    ("zero",  2, CSRAccess.WIRI),  # 16-bit instructions are not supported
-    ("base", 30, CSRAccess.WARL)
-]
-
-
-mip_layout = [
-    ("usip",   1, CSRAccess.WARL),
-    ("ssip",   1, CSRAccess.WARL),
-    ("wiri0",  1, CSRAccess.WIRI),
-    ("msip",   1, CSRAccess.WARL),
-    ("utip",   1, CSRAccess.WARL),
-    ("stip",   1, CSRAccess.WARL),
-    ("wiri1",  1, CSRAccess.WIRI),
-    ("mtip",   1, CSRAccess.WARL),
-    ("ueip",   1, CSRAccess.WARL),
-    ("seip",   1, CSRAccess.WARL),
-    ("wiri2",  1, CSRAccess.WIRI),
-    ("meip",   1, CSRAccess.WARL),
-    ("wiri3", 20, CSRAccess.WIRI)
-]
-
-
-mie_layout = [
-    ("usie",   1, CSRAccess.WARL),
-    ("ssie",   1, CSRAccess.WARL),
-    ("wpri0",  1, CSRAccess.WPRI),
-    ("msie",   1, CSRAccess.WARL),
-    ("utie",   1, CSRAccess.WARL),
-    ("stie",   1, CSRAccess.WARL),
-    ("wpri1",  1, CSRAccess.WPRI),
-    ("mtie",   1, CSRAccess.WARL),
-    ("ueie",   1, CSRAccess.WARL),
-    ("seie",   1, CSRAccess.WARL),
-    ("wpri2",  1, CSRAccess.WPRI),
-    ("meie",   1, CSRAccess.WARL),
-    ("wpri3", 20, CSRAccess.WPRI)
-]
-
-
-mcause_layout = [
-    ("ecode",    31, CSRAccess.WARL),
-    ("interrupt", 1, CSRAccess.WARL)
-]
-
-
-dcsr_layout = [
-    ("prv",        2, CSRAccess.WARL), # Privilege level before Debug Mode was entered
-    ("step",       1, CSRAccess.WARL), # Execute a single instruction and re-enter Debug Mode
-    ("nmip",       1, CSRAccess.WLRL), # A non-maskable interrupt is pending
-    ("mprven",     1, CSRAccess.WARL), # Use mstatus.mprv in Debug Mode
-    ("zero0",      1, CSRAccess.WPRI),
-    ("cause",      3, CSRAccess.WLRL), # Explains why Debug Mode was entered
-    ("stoptime",   1, CSRAccess.WARL), # Stop timer increment during Debug Mode
-    ("stopcount",  1, CSRAccess.WARL), # Stop counter increment during Debug Mode
-    ("stepie",     1, CSRAccess.WARL), # Enable interrupts during single stepping
-    ("ebreaku",    1, CSRAccess.WARL), # EBREAKs in U-mode enter Debug Mode
-    ("ebreaks",    1, CSRAccess.WARL), # EBREAKs in S-mode enter Debug Mode
-    ("zero1",      1, CSRAccess.WPRI),
-    ("ebreakm",    1, CSRAccess.WARL), # EBREAKs in M-mode enter Debug Mode
-    ("zero2",     12, CSRAccess.WPRI),
-    ("xdebugver",  4, CSRAccess.WLRL)  # External Debug specification version
-]
-
-
-tdata1_layout = [
-    ("data",  27, CSRAccess.WARL),
-    ("dmode",  1, CSRAccess.WARL),
-    ("type",   4, CSRAccess.WARL)
-]
diff --git a/src/soc/minerva/stage.py b/src/soc/minerva/stage.py
deleted file mode 100644 (file)
index 3b108d7..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-from functools import reduce
-from operator import or_
-
-from nmigen import Elaboratable, Module, Mux, Record, Signal
-from nmigen.hdl.rec import DIR_FANIN, DIR_FANOUT, DIR_NONE
-
-
-__all__ = ["Stage"]
-
-
-def _make_m2s(layout):
-    r = []
-    for f in layout:
-        if isinstance(f[1], (int, tuple)):
-            r.append((f[0], f[1], DIR_FANOUT))
-        else:
-            r.append((f[0], _make_m2s(f[1])))
-    return r
-
-
-class _EndpointDescription:
-    def __init__(self, payload_layout):
-        self.payload_layout = payload_layout
-
-    def get_full_layout(self):
-        reserved = {"valid", "stall", "kill"}
-        attributed = set()
-        for f in self.payload_layout:
-            if f[0] in attributed:
-                raise ValueError(f[0] + " already attributed in payload layout")
-            if f[0] in reserved:
-                raise ValueError(f[0] + " cannot be used in endpoint layout")
-            attributed.add(f[0])
-
-        full_layout = [
-            ("valid", 1, DIR_FANOUT),
-            ("stall", 1, DIR_FANIN),
-            ("kill",  1, DIR_FANOUT),
-            ("payload", _make_m2s(self.payload_layout))
-        ]
-        return full_layout
-
-
-class _Endpoint(Record):
-    def __init__(self, layout):
-        self.description = _EndpointDescription(layout)
-        super().__init__(self.description.get_full_layout())
-
-    def __getattr__(self, name):
-        try:
-            return super().__getattr__(name)
-        except AttributeError:
-            return self.fields["payload"][name]
-
-
-class Stage(Elaboratable):
-    def __init__(self, sink_layout, source_layout):
-        self.kill = Signal()
-        self.stall = Signal()
-        self.valid = Signal()
-
-        if sink_layout is None and source_layout is None:
-            raise ValueError
-        if sink_layout is not None:
-            self.sink = _Endpoint(sink_layout)
-        if source_layout is not None:
-            self.source = _Endpoint(source_layout)
-
-        self._kill_sources = []
-        self._stall_sources = []
-
-    def kill_on(self, cond):
-        self._kill_sources.append(cond)
-
-    def stall_on(self, cond):
-        self._stall_sources.append(cond)
-
-    def elaborate(self, platform):
-        m = Module()
-
-        if hasattr(self, "sink"):
-            m.d.comb += [
-                self.valid.eq(self.sink.valid & ~self.sink.kill),
-                self.sink.stall.eq(self.stall)
-            ]
-
-        if hasattr(self, "source"):
-            with m.If(~self.stall):
-                m.d.sync += self.source.valid.eq(self.valid)
-            with m.Elif(~self.source.stall | self.kill):
-                m.d.sync += self.source.valid.eq(0)
-            self.stall_on(self.source.stall)
-            m.d.comb += [
-                self.source.kill.eq(self.kill),
-                self.kill.eq(reduce(or_, self._kill_sources, 0))
-            ]
-
-        m.d.comb += self.stall.eq(reduce(or_, self._stall_sources, 0))
-
-        return m
diff --git a/src/soc/minerva/test/test_units_divider.py b/src/soc/minerva/test/test_units_divider.py
deleted file mode 100644 (file)
index 1dec373..0000000
+++ /dev/null
@@ -1,243 +0,0 @@
-from nmigen import *
-from nmigen.back.pysim import *
-from nmigen.test.utils import *
-
-from ..units.divider import *
-from ..isa import Funct3
-
-
-def tst_op(funct3, src1, src2, result):
-    def test(self):
-        with Simulator(self.dut) as sim:
-            def process():
-                yield self.dut.x_op.eq(funct3)
-                yield self.dut.x_src1.eq(src1)
-                yield self.dut.x_src2.eq(src2)
-                yield self.dut.x_valid.eq(1)
-                yield self.dut.x_stall.eq(0)
-                yield Tick()
-                yield self.dut.x_valid.eq(0)
-                yield Tick()
-                while (yield self.dut.m_busy):
-                    yield Tick()
-                self.assertEqual((yield self.dut.m_result), result)
-            sim.add_clock(1e-6)
-            sim.add_sync_process(process)
-            sim.run()
-    return test
-
-
-class DividerTestCase(FHDLTestCase):
-    def setUp(self):
-        self.dut = Divider()
-
-    # Test cases are taken from the riscv-compliance testbench:
-    # https://github.com/riscv/riscv-compliance/tree/master/riscv-test-suite/rv32im
-
-    # DIV ------------------------------------------------------------------------
-
-    test_div_0 = tst_op(Funct3.DIV,  0x00000000, 0x00000000, result=0xffffffff)
-    test_div_1 = tst_op(Funct3.DIV,  0x00000000, 0x00000001, result=0x00000000)
-    test_div_2 = tst_op(Funct3.DIV,  0x00000000, 0xffffffff, result=0x00000000)
-    test_div_3 = tst_op(Funct3.DIV,  0x00000000, 0x7fffffff, result=0x00000000)
-    test_div_4 = tst_op(Funct3.DIV,  0x00000000, 0x80000000, result=0x00000000)
-
-    test_div_5 = tst_op(Funct3.DIV,  0x00000001, 0x00000000, result=0xffffffff)
-    test_div_6 = tst_op(Funct3.DIV,  0x00000001, 0x00000001, result=0x00000001)
-    test_div_7 = tst_op(Funct3.DIV,  0x00000001, 0xffffffff, result=0xffffffff)
-    test_div_8 = tst_op(Funct3.DIV,  0x00000001, 0x7fffffff, result=0x00000000)
-    test_div_9 = tst_op(Funct3.DIV,  0x00000001, 0x80000000, result=0x00000000)
-
-    test_div_10 = tst_op(Funct3.DIV,  0xffffffff,
-                         0x00000000, result=0xffffffff)
-    test_div_11 = tst_op(Funct3.DIV,  0xffffffff,
-                         0x00000001, result=0xffffffff)
-    test_div_12 = tst_op(Funct3.DIV,  0xffffffff,
-                         0xffffffff, result=0x00000001)
-    test_div_13 = tst_op(Funct3.DIV,  0xffffffff,
-                         0x7fffffff, result=0x00000000)
-    test_div_14 = tst_op(Funct3.DIV,  0xffffffff,
-                         0x80000000, result=0x00000000)
-
-    test_div_15 = tst_op(Funct3.DIV,  0x7fffffff,
-                         0x00000000, result=0xffffffff)
-    test_div_16 = tst_op(Funct3.DIV,  0x7fffffff,
-                         0x00000001, result=0x7fffffff)
-    test_div_17 = tst_op(Funct3.DIV,  0x7fffffff,
-                         0xffffffff, result=0x80000001)
-    test_div_18 = tst_op(Funct3.DIV,  0x7fffffff,
-                         0x7fffffff, result=0x00000001)
-    test_div_19 = tst_op(Funct3.DIV,  0x7fffffff,
-                         0x80000000, result=0x00000000)
-
-    test_div_20 = tst_op(Funct3.DIV,  0x80000000,
-                         0x00000000, result=0xffffffff)
-    test_div_21 = tst_op(Funct3.DIV,  0x80000000,
-                         0x00000001, result=0x80000000)
-    test_div_22 = tst_op(Funct3.DIV,  0x80000000,
-                         0xffffffff, result=0x80000000)
-    test_div_23 = tst_op(Funct3.DIV,  0x80000000,
-                         0x7fffffff, result=0xffffffff)
-    test_div_24 = tst_op(Funct3.DIV,  0x80000000,
-                         0x80000000, result=0x00000001)
-
-    # DIVU -----------------------------------------------------------------------
-
-    test_divu_0 = tst_op(Funct3.DIVU, 0x00000000,
-                         0x00000000, result=0xffffffff)
-    test_divu_1 = tst_op(Funct3.DIVU, 0x00000000,
-                         0x00000001, result=0x00000000)
-    test_divu_2 = tst_op(Funct3.DIVU, 0x00000000,
-                         0xffffffff, result=0x00000000)
-    test_divu_3 = tst_op(Funct3.DIVU, 0x00000000,
-                         0x7fffffff, result=0x00000000)
-    test_divu_4 = tst_op(Funct3.DIVU, 0x00000000,
-                         0x80000000, result=0x00000000)
-
-    test_divu_5 = tst_op(Funct3.DIVU, 0x00000001,
-                         0x00000000, result=0xffffffff)
-    test_divu_6 = tst_op(Funct3.DIVU, 0x00000001,
-                         0x00000001, result=0x00000001)
-    test_divu_7 = tst_op(Funct3.DIVU, 0x00000001,
-                         0xffffffff, result=0x00000000)
-    test_divu_8 = tst_op(Funct3.DIVU, 0x00000001,
-                         0x7fffffff, result=0x00000000)
-    test_divu_9 = tst_op(Funct3.DIVU, 0x00000001,
-                         0x80000000, result=0x00000000)
-
-    test_divu_10 = tst_op(Funct3.DIVU, 0xffffffff,
-                          0x00000000, result=0xffffffff)
-    test_divu_11 = tst_op(Funct3.DIVU, 0xffffffff,
-                          0x00000001, result=0xffffffff)
-    test_divu_12 = tst_op(Funct3.DIVU, 0xffffffff,
-                          0xffffffff, result=0x00000001)
-    test_divu_13 = tst_op(Funct3.DIVU, 0xffffffff,
-                          0x7fffffff, result=0x00000002)
-    test_divu_14 = tst_op(Funct3.DIVU, 0xffffffff,
-                          0x80000000, result=0x00000001)
-
-    test_divu_15 = tst_op(Funct3.DIVU, 0x7fffffff,
-                          0x00000000, result=0xffffffff)
-    test_divu_16 = tst_op(Funct3.DIVU, 0x7fffffff,
-                          0x00000001, result=0x7fffffff)
-    test_divu_17 = tst_op(Funct3.DIVU, 0x7fffffff,
-                          0xffffffff, result=0x00000000)
-    test_divu_18 = tst_op(Funct3.DIVU, 0x7fffffff,
-                          0x7fffffff, result=0x00000001)
-    test_divu_19 = tst_op(Funct3.DIVU, 0x7fffffff,
-                          0x80000000, result=0x00000000)
-
-    test_divu_20 = tst_op(Funct3.DIVU, 0x80000000,
-                          0x00000000, result=0xffffffff)
-    test_divu_21 = tst_op(Funct3.DIVU, 0x80000000,
-                          0x00000001, result=0x80000000)
-    test_divu_22 = tst_op(Funct3.DIVU, 0x80000000,
-                          0xffffffff, result=0x00000000)
-    test_divu_23 = tst_op(Funct3.DIVU, 0x80000000,
-                          0x7fffffff, result=0x00000001)
-    test_divu_24 = tst_op(Funct3.DIVU, 0x80000000,
-                          0x80000000, result=0x00000001)
-
-    # REM ------------------------------------------------------------------------
-
-    test_rem_0 = tst_op(Funct3.REM,  0x00000000, 0x00000000, result=0x00000000)
-    test_rem_1 = tst_op(Funct3.REM,  0x00000000, 0x00000001, result=0x00000000)
-    test_rem_2 = tst_op(Funct3.REM,  0x00000000, 0xffffffff, result=0x00000000)
-    test_rem_3 = tst_op(Funct3.REM,  0x00000000, 0x7fffffff, result=0x00000000)
-    test_rem_4 = tst_op(Funct3.REM,  0x00000000, 0x80000000, result=0x00000000)
-
-    test_rem_5 = tst_op(Funct3.REM,  0x00000001, 0x00000000, result=0x00000001)
-    test_rem_6 = tst_op(Funct3.REM,  0x00000001, 0x00000001, result=0x00000000)
-    test_rem_7 = tst_op(Funct3.REM,  0x00000001, 0xffffffff, result=0x00000000)
-    test_rem_8 = tst_op(Funct3.REM,  0x00000001, 0x7fffffff, result=0x00000001)
-    test_rem_9 = tst_op(Funct3.REM,  0x00000001, 0x80000000, result=0x00000001)
-
-    test_rem_10 = tst_op(Funct3.REM,  0xffffffff,
-                         0x00000000, result=0xffffffff)
-    test_rem_11 = tst_op(Funct3.REM,  0xffffffff,
-                         0x00000001, result=0x00000000)
-    test_rem_12 = tst_op(Funct3.REM,  0xffffffff,
-                         0xffffffff, result=0x00000000)
-    test_rem_13 = tst_op(Funct3.REM,  0xffffffff,
-                         0x7fffffff, result=0xffffffff)
-    test_rem_14 = tst_op(Funct3.REM,  0xffffffff,
-                         0x80000000, result=0xffffffff)
-
-    test_rem_15 = tst_op(Funct3.REM,  0x7fffffff,
-                         0x00000000, result=0x7fffffff)
-    test_rem_16 = tst_op(Funct3.REM,  0x7fffffff,
-                         0x00000001, result=0x00000000)
-    test_rem_17 = tst_op(Funct3.REM,  0x7fffffff,
-                         0xffffffff, result=0x00000000)
-    test_rem_18 = tst_op(Funct3.REM,  0x7fffffff,
-                         0x7fffffff, result=0x00000000)
-    test_rem_19 = tst_op(Funct3.REM,  0x7fffffff,
-                         0x80000000, result=0x7fffffff)
-
-    test_rem_20 = tst_op(Funct3.REM,  0x80000000,
-                         0x00000000, result=0x80000000)
-    test_rem_21 = tst_op(Funct3.REM,  0x80000000,
-                         0x00000001, result=0x00000000)
-    test_rem_22 = tst_op(Funct3.REM,  0x80000000,
-                         0xffffffff, result=0x00000000)
-    test_rem_23 = tst_op(Funct3.REM,  0x80000000,
-                         0x7fffffff, result=0xffffffff)
-    test_rem_24 = tst_op(Funct3.REM,  0x80000000,
-                         0x80000000, result=0x00000000)
-
-    # REMU -----------------------------------------------------------------------
-
-    test_remu_0 = tst_op(Funct3.REMU, 0x00000000,
-                         0x00000000, result=0x00000000)
-    test_remu_1 = tst_op(Funct3.REMU, 0x00000000,
-                         0x00000001, result=0x00000000)
-    test_remu_2 = tst_op(Funct3.REMU, 0x00000000,
-                         0xffffffff, result=0x00000000)
-    test_remu_3 = tst_op(Funct3.REMU, 0x00000000,
-                         0x7fffffff, result=0x00000000)
-    test_remu_4 = tst_op(Funct3.REMU, 0x00000000,
-                         0x80000000, result=0x00000000)
-
-    test_remu_5 = tst_op(Funct3.REMU, 0x00000001,
-                         0x00000000, result=0x00000001)
-    test_remu_6 = tst_op(Funct3.REMU, 0x00000001,
-                         0x00000001, result=0x00000000)
-    test_remu_7 = tst_op(Funct3.REMU, 0x00000001,
-                         0xffffffff, result=0x00000001)
-    test_remu_8 = tst_op(Funct3.REMU, 0x00000001,
-                         0x7fffffff, result=0x00000001)
-    test_remu_9 = tst_op(Funct3.REMU, 0x00000001,
-                         0x80000000, result=0x00000001)
-
-    test_remu_10 = tst_op(Funct3.REMU, 0xffffffff,
-                          0x00000000, result=0xffffffff)
-    test_remu_11 = tst_op(Funct3.REMU, 0xffffffff,
-                          0x00000001, result=0x00000000)
-    test_remu_12 = tst_op(Funct3.REMU, 0xffffffff,
-                          0xffffffff, result=0x00000000)
-    test_remu_13 = tst_op(Funct3.REMU, 0xffffffff,
-                          0x7fffffff, result=0x00000001)
-    test_remu_14 = tst_op(Funct3.REMU, 0xffffffff,
-                          0x80000000, result=0x7fffffff)
-
-    test_remu_15 = tst_op(Funct3.REMU, 0x7fffffff,
-                          0x00000000, result=0x7fffffff)
-    test_remu_16 = tst_op(Funct3.REMU, 0x7fffffff,
-                          0x00000001, result=0x00000000)
-    test_remu_17 = tst_op(Funct3.REMU, 0x7fffffff,
-                          0xffffffff, result=0x7fffffff)
-    test_remu_18 = tst_op(Funct3.REMU, 0x7fffffff,
-                          0x7fffffff, result=0x00000000)
-    test_remu_19 = tst_op(Funct3.REMU, 0x7fffffff,
-                          0x80000000, result=0x7fffffff)
-
-    test_remu_20 = tst_op(Funct3.REMU, 0x80000000,
-                          0x00000000, result=0x80000000)
-    test_remu_21 = tst_op(Funct3.REMU, 0x80000000,
-                          0x00000001, result=0x00000000)
-    test_remu_22 = tst_op(Funct3.REMU, 0x80000000,
-                          0xffffffff, result=0x80000000)
-    test_remu_23 = tst_op(Funct3.REMU, 0x80000000,
-                          0x7fffffff, result=0x00000001)
-    test_remu_24 = tst_op(Funct3.REMU, 0x80000000,
-                          0x80000000, result=0x00000000)
diff --git a/src/soc/minerva/test/test_units_multiplier.py b/src/soc/minerva/test/test_units_multiplier.py
deleted file mode 100644 (file)
index f2a352c..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-from nmigen import *
-from nmigen.back.pysim import *
-from nmigen.test.utils import *
-
-from ..units.multiplier import *
-from ..isa import Funct3
-
-
-def tst_op(funct3, src1, src2, result):
-    def test(self):
-        with Simulator(self.dut) as sim:
-            def process():
-                yield self.dut.x_op.eq(funct3)
-                yield self.dut.x_src1.eq(src1)
-                yield self.dut.x_src2.eq(src2)
-                yield self.dut.x_stall.eq(0)
-                yield Tick()
-                yield self.dut.m_stall.eq(0)
-                yield Tick()
-                yield Tick()
-                self.assertEqual((yield self.dut.w_result), result)
-            sim.add_clock(1e-6)
-            sim.add_sync_process(process)
-            sim.run()
-    return test
-
-
-class MultiplierTestCase(FHDLTestCase):
-    def setUp(self):
-        self.dut = Multiplier()
-
-    # Test cases are taken from the riscv-compliance testbench:
-    # https://github.com/riscv/riscv-compliance/tree/master/riscv-test-suite/rv32im
-
-    # MUL ----------------------------------------------------------------------------
-
-    test_mul_0 = tst_op(Funct3.MUL,    0x00000000,
-                        0x00000000, result=0x00000000)
-    test_mul_1 = tst_op(Funct3.MUL,    0x00000000,
-                        0x00000001, result=0x00000000)
-    test_mul_2 = tst_op(Funct3.MUL,    0x00000000,
-                        0xffffffff, result=0x00000000)
-    test_mul_3 = tst_op(Funct3.MUL,    0x00000000,
-                        0x7fffffff, result=0x00000000)
-    test_mul_4 = tst_op(Funct3.MUL,    0x00000000,
-                        0x80000000, result=0x00000000)
-
-    test_mul_5 = tst_op(Funct3.MUL,    0x00000001,
-                        0x00000000, result=0x00000000)
-    test_mul_6 = tst_op(Funct3.MUL,    0x00000001,
-                        0x00000001, result=0x00000001)
-    test_mul_7 = tst_op(Funct3.MUL,    0x00000001,
-                        0xffffffff, result=0xffffffff)
-    test_mul_8 = tst_op(Funct3.MUL,    0x00000001,
-                        0x7fffffff, result=0x7fffffff)
-    test_mul_9 = tst_op(Funct3.MUL,    0x00000001,
-                        0x80000000, result=0x80000000)
-
-    test_mul_10 = tst_op(Funct3.MUL,    0xffffffff,
-                         0x00000000, result=0x00000000)
-    test_mul_11 = tst_op(Funct3.MUL,    0xffffffff,
-                         0x00000001, result=0xffffffff)
-    test_mul_12 = tst_op(Funct3.MUL,    0xffffffff,
-                         0xffffffff, result=0x00000001)
-    test_mul_13 = tst_op(Funct3.MUL,    0xffffffff,
-                         0x7fffffff, result=0x80000001)
-    test_mul_14 = tst_op(Funct3.MUL,    0xffffffff,
-                         0x80000000, result=0x80000000)
-
-    test_mul_15 = tst_op(Funct3.MUL,    0x7fffffff,
-                         0x00000000, result=0x00000000)
-    test_mul_16 = tst_op(Funct3.MUL,    0x7fffffff,
-                         0x00000001, result=0x7fffffff)
-    test_mul_17 = tst_op(Funct3.MUL,    0x7fffffff,
-                         0xffffffff, result=0x80000001)
-    test_mul_18 = tst_op(Funct3.MUL,    0x7fffffff,
-                         0x7fffffff, result=0x00000001)
-    test_mul_19 = tst_op(Funct3.MUL,    0x7fffffff,
-                         0x80000000, result=0x80000000)
-
-    test_mul_20 = tst_op(Funct3.MUL,    0x80000000,
-                         0x00000000, result=0x00000000)
-    test_mul_21 = tst_op(Funct3.MUL,    0x80000000,
-                         0x00000001, result=0x80000000)
-    test_mul_22 = tst_op(Funct3.MUL,    0x80000000,
-                         0xffffffff, result=0x80000000)
-    test_mul_23 = tst_op(Funct3.MUL,    0x80000000,
-                         0x7fffffff, result=0x80000000)
-    test_mul_24 = tst_op(Funct3.MUL,    0x80000000,
-                         0x80000000, result=0x00000000)
-
-    # MULH ---------------------------------------------------------------------------
-
-    test_mulh_0 = tst_op(Funct3.MULH,   0x00000000,
-                         0x00000000, result=0x00000000)
-    test_mulh_1 = tst_op(Funct3.MULH,   0x00000000,
-                         0x00000001, result=0x00000000)
-    test_mulh_2 = tst_op(Funct3.MULH,   0x00000000,
-                         0xffffffff, result=0x00000000)
-    test_mulh_3 = tst_op(Funct3.MULH,   0x00000000,
-                         0x7fffffff, result=0x00000000)
-    test_mulh_4 = tst_op(Funct3.MULH,   0x00000000,
-                         0x80000000, result=0x00000000)
-
-    test_mulh_5 = tst_op(Funct3.MULH,   0x00000001,
-                         0x00000000, result=0x00000000)
-    test_mulh_6 = tst_op(Funct3.MULH,   0x00000001,
-                         0x00000001, result=0x00000000)
-    test_mulh_7 = tst_op(Funct3.MULH,   0x00000001,
-                         0xffffffff, result=0xffffffff)
-    test_mulh_8 = tst_op(Funct3.MULH,   0x00000001,
-                         0x7fffffff, result=0x00000000)
-    test_mulh_9 = tst_op(Funct3.MULH,   0x00000001,
-                         0x80000000, result=0xffffffff)
-
-    test_mulh_10 = tst_op(Funct3.MULH,   0xffffffff,
-                          0x00000000, result=0x00000000)
-    test_mulh_11 = tst_op(Funct3.MULH,   0xffffffff,
-                          0x00000001, result=0xffffffff)
-    test_mulh_12 = tst_op(Funct3.MULH,   0xffffffff,
-                          0xffffffff, result=0x00000000)
-    test_mulh_13 = tst_op(Funct3.MULH,   0xffffffff,
-                          0x7fffffff, result=0xffffffff)
-    test_mulh_14 = tst_op(Funct3.MULH,   0xffffffff,
-                          0x80000000, result=0x00000000)
-
-    test_mulh_15 = tst_op(Funct3.MULH,   0x7fffffff,
-                          0x00000000, result=0x00000000)
-    test_mulh_16 = tst_op(Funct3.MULH,   0x7fffffff,
-                          0x00000001, result=0x00000000)
-    test_mulh_17 = tst_op(Funct3.MULH,   0x7fffffff,
-                          0xffffffff, result=0xffffffff)
-    test_mulh_18 = tst_op(Funct3.MULH,   0x7fffffff,
-                          0x7fffffff, result=0x3fffffff)
-    test_mulh_19 = tst_op(Funct3.MULH,   0x7fffffff,
-                          0x80000000, result=0xc0000000)
-
-    test_mulh_20 = tst_op(Funct3.MULH,   0x80000000,
-                          0x00000000, result=0x00000000)
-    test_mulh_21 = tst_op(Funct3.MULH,   0x80000000,
-                          0x00000001, result=0xffffffff)
-    test_mulh_22 = tst_op(Funct3.MULH,   0x80000000,
-                          0xffffffff, result=0x00000000)
-    test_mulh_23 = tst_op(Funct3.MULH,   0x80000000,
-                          0x7fffffff, result=0xc0000000)
-    test_mulh_24 = tst_op(Funct3.MULH,   0x80000000,
-                          0x80000000, result=0x40000000)
-
-    # MULHSU -------------------------------------------------------------------------
-
-    test_mulhsu_0 = tst_op(Funct3.MULHSU, 0x00000000,
-                           0x00000000, result=0x00000000)
-    test_mulhsu_1 = tst_op(Funct3.MULHSU, 0x00000000,
-                           0x00000001, result=0x00000000)
-    test_mulhsu_2 = tst_op(Funct3.MULHSU, 0x00000000,
-                           0xffffffff, result=0x00000000)
-    test_mulhsu_3 = tst_op(Funct3.MULHSU, 0x00000000,
-                           0x7fffffff, result=0x00000000)
-    test_mulhsu_4 = tst_op(Funct3.MULHSU, 0x00000000,
-                           0x80000000, result=0x00000000)
-
-    test_mulhsu_5 = tst_op(Funct3.MULHSU, 0x00000001,
-                           0x00000000, result=0x00000000)
-    test_mulhsu_6 = tst_op(Funct3.MULHSU, 0x00000001,
-                           0x00000001, result=0x00000000)
-    test_mulhsu_7 = tst_op(Funct3.MULHSU, 0x00000001,
-                           0xffffffff, result=0x00000000)
-    test_mulhsu_8 = tst_op(Funct3.MULHSU, 0x00000001,
-                           0x7fffffff, result=0x00000000)
-    test_mulhsu_9 = tst_op(Funct3.MULHSU, 0x00000001,
-                           0x80000000, result=0x00000000)
-
-    test_mulhsu_10 = tst_op(Funct3.MULHSU, 0xffffffff,
-                            0x00000000, result=0x00000000)
-    test_mulhsu_11 = tst_op(Funct3.MULHSU, 0xffffffff,
-                            0x00000001, result=0xffffffff)
-    test_mulhsu_12 = tst_op(Funct3.MULHSU, 0xffffffff,
-                            0xffffffff, result=0xffffffff)
-    test_mulhsu_13 = tst_op(Funct3.MULHSU, 0xffffffff,
-                            0x7fffffff, result=0xffffffff)
-    test_mulhsu_14 = tst_op(Funct3.MULHSU, 0xffffffff,
-                            0x80000000, result=0xffffffff)
-
-    test_mulhsu_15 = tst_op(Funct3.MULHSU, 0x7fffffff,
-                            0x00000000, result=0x00000000)
-    test_mulhsu_16 = tst_op(Funct3.MULHSU, 0x7fffffff,
-                            0x00000001, result=0x00000000)
-    test_mulhsu_17 = tst_op(Funct3.MULHSU, 0x7fffffff,
-                            0xffffffff, result=0x7ffffffe)
-    test_mulhsu_18 = tst_op(Funct3.MULHSU, 0x7fffffff,
-                            0x7fffffff, result=0x3fffffff)
-    test_mulhsu_19 = tst_op(Funct3.MULHSU, 0x7fffffff,
-                            0x80000000, result=0x3fffffff)
-
-    test_mulhsu_20 = tst_op(Funct3.MULHSU, 0x80000000,
-                            0x00000000, result=0x00000000)
-    test_mulhsu_21 = tst_op(Funct3.MULHSU, 0x80000000,
-                            0x00000001, result=0xffffffff)
-    test_mulhsu_22 = tst_op(Funct3.MULHSU, 0x80000000,
-                            0xffffffff, result=0x80000000)
-    test_mulhsu_23 = tst_op(Funct3.MULHSU, 0x80000000,
-                            0x7fffffff, result=0xc0000000)
-    test_mulhsu_24 = tst_op(Funct3.MULHSU, 0x80000000,
-                            0x80000000, result=0xc0000000)
-
-    # MULHU --------------------------------------------------------------------------
-
-    test_mulhu_0 = tst_op(Funct3.MULHU,  0x00000000,
-                          0x00000000, result=0x00000000)
-    test_mulhu_1 = tst_op(Funct3.MULHU,  0x00000000,
-                          0x00000001, result=0x00000000)
-    test_mulhu_2 = tst_op(Funct3.MULHU,  0x00000000,
-                          0xffffffff, result=0x00000000)
-    test_mulhu_3 = tst_op(Funct3.MULHU,  0x00000000,
-                          0x7fffffff, result=0x00000000)
-    test_mulhu_4 = tst_op(Funct3.MULHU,  0x00000000,
-                          0x80000000, result=0x00000000)
-
-    test_mulhu_5 = tst_op(Funct3.MULHU,  0x00000001,
-                          0x00000000, result=0x00000000)
-    test_mulhu_6 = tst_op(Funct3.MULHU,  0x00000001,
-                          0x00000001, result=0x00000000)
-    test_mulhu_7 = tst_op(Funct3.MULHU,  0x00000001,
-                          0xffffffff, result=0x00000000)
-    test_mulhu_8 = tst_op(Funct3.MULHU,  0x00000001,
-                          0x7fffffff, result=0x00000000)
-    test_mulhu_9 = tst_op(Funct3.MULHU,  0x00000001,
-                          0x80000000, result=0x00000000)
-
-    test_mulhu_10 = tst_op(Funct3.MULHU,  0xffffffff,
-                           0x00000000, result=0x00000000)
-    test_mulhu_11 = tst_op(Funct3.MULHU,  0xffffffff,
-                           0x00000001, result=0x00000000)
-    test_mulhu_12 = tst_op(Funct3.MULHU,  0xffffffff,
-                           0xffffffff, result=0xfffffffe)
-    test_mulhu_13 = tst_op(Funct3.MULHU,  0xffffffff,
-                           0x7fffffff, result=0x7ffffffe)
-    test_mulhu_14 = tst_op(Funct3.MULHU,  0xffffffff,
-                           0x80000000, result=0x7fffffff)
-
-    test_mulhu_15 = tst_op(Funct3.MULHU,  0x7fffffff,
-                           0x00000000, result=0x00000000)
-    test_mulhu_16 = tst_op(Funct3.MULHU,  0x7fffffff,
-                           0x00000001, result=0x00000000)
-    test_mulhu_17 = tst_op(Funct3.MULHU,  0x7fffffff,
-                           0xffffffff, result=0x7ffffffe)
-    test_mulhu_18 = tst_op(Funct3.MULHU,  0x7fffffff,
-                           0x7fffffff, result=0x3fffffff)
-    test_mulhu_19 = tst_op(Funct3.MULHU,  0x7fffffff,
-                           0x80000000, result=0x3fffffff)
-
-    test_mulhu_20 = tst_op(Funct3.MULHU,  0x80000000,
-                           0x00000000, result=0x00000000)
-    test_mulhu_21 = tst_op(Funct3.MULHU,  0x80000000,
-                           0x00000001, result=0x00000000)
-    test_mulhu_22 = tst_op(Funct3.MULHU,  0x80000000,
-                           0xffffffff, result=0x7fffffff)
-    test_mulhu_23 = tst_op(Funct3.MULHU,  0x80000000,
-                           0x7fffffff, result=0x3fffffff)
-    test_mulhu_24 = tst_op(Funct3.MULHU,  0x80000000,
-                           0x80000000, result=0x40000000)
diff --git a/src/soc/minerva/units/adder.py b/src/soc/minerva/units/adder.py
deleted file mode 100644 (file)
index eabdc6c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-from nmigen import Elaboratable, Module, Signal, Cat
-
-
-__all__ = ["Adder"]
-
-
-class Adder(Elaboratable):
-    def __init__(self):
-        self.sub = Signal()
-        self.src1 = Signal(32)
-        self.src2 = Signal(32)
-
-        self.result = Signal(32)
-        self.carry = Signal()
-        self.overflow = Signal()
-
-    def elaborate(self, platform):
-        m = Module()
-
-        with m.If(self.sub):
-            m.d.comb += [
-                Cat(self.result, self.carry).eq(self.src1 - self.src2),
-                self.overflow.eq((self.src1[-1] != self.src2[-1]) & (self.result[-1] == self.src2[-1]))
-            ]
-        with m.Else():
-            m.d.comb += [
-                Cat(self.result, self.carry).eq(self.src1 + self.src2),
-                self.overflow.eq(~self.src1[-1] & self.src2[-1] & self.result[-1])
-            ]
-
-        return m
diff --git a/src/soc/minerva/units/compare.py b/src/soc/minerva/units/compare.py
deleted file mode 100644 (file)
index b8ba217..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-from nmigen import Elaboratable, Module, Signal
-
-from ..isa import Funct3
-
-
-__all__ = ["CompareUnit"]
-
-
-class CompareUnit(Elaboratable):
-    def __init__(self):
-        self.op = Signal(3)
-        self.zero = Signal()
-        self.negative = Signal()
-        self.overflow = Signal()
-        self.carry = Signal()
-
-        self.condition_met = Signal()
-
-    def elaborate(self, platform):
-        m = Module()
-
-        with m.Switch(self.op):
-            with m.Case(Funct3.BEQ):
-                m.d.comb += self.condition_met.eq(self.zero)
-            with m.Case(Funct3.BNE):
-                m.d.comb += self.condition_met.eq(~self.zero)
-            with m.Case(Funct3.BLT):
-                m.d.comb += self.condition_met.eq(~self.zero & (self.negative != self.overflow))
-            with m.Case(Funct3.BGE):
-                m.d.comb += self.condition_met.eq(self.negative == self.overflow)
-            with m.Case(Funct3.BLTU):
-                m.d.comb += self.condition_met.eq(~self.zero & self.carry)
-            with m.Case(Funct3.BGEU):
-                m.d.comb += self.condition_met.eq(~self.carry)
-
-        return m
diff --git a/src/soc/minerva/units/decoder.py b/src/soc/minerva/units/decoder.py
deleted file mode 100644 (file)
index 7975d2d..0000000
+++ /dev/null
@@ -1,261 +0,0 @@
-from functools import reduce
-from itertools import starmap
-from operator import or_
-
-from nmigen import Elaboratable, Module, Signal, Cat
-
-from ..isa import Opcode, Funct3, Funct7, Funct12
-
-
-__all__ = ["InstructionDecoder"]
-
-
-class Type:
-    R = 0
-    I = 1
-    S = 2
-    B = 3
-    U = 4
-    J = 5
-
-
-class InstructionDecoder(Elaboratable):
-    def __init__(self, with_muldiv):
-        self.with_muldiv = with_muldiv
-
-        self.instruction = Signal(32)
-
-        self.rd = Signal(5)
-        self.rd_we = Signal()
-        self.rs1 = Signal(5)
-        self.rs1_re = Signal()
-        self.rs2 = Signal(5)
-        self.rs2_re = Signal()
-        self.immediate = Signal((32, True))
-        self.bypass_x = Signal()
-        self.bypass_m = Signal()
-        self.load = Signal()
-        self.store = Signal()
-        self.fence_i = Signal()
-        self.adder = Signal()
-        self.adder_sub = Signal()
-        self.logic = Signal()
-        self.multiply = Signal()
-        self.divide = Signal()
-        self.shift = Signal()
-        self.direction = Signal()
-        self.sext = Signal()
-        self.lui = Signal()
-        self.auipc = Signal()
-        self.jump = Signal()
-        self.branch = Signal()
-        self.compare = Signal()
-        self.csr = Signal()
-        self.csr_we = Signal()
-        self.privileged = Signal()
-        self.ecall = Signal()
-        self.ebreak = Signal()
-        self.mret = Signal()
-        self.funct3 = Signal(3)
-        self.illegal = Signal()
-
-    def elaborate(self, platform):
-        m = Module()
-
-        opcode = Signal(5)
-        funct3 = Signal(3)
-        funct7 = Signal(7)
-        funct12 = Signal(12)
-
-        iimm12 = Signal((12, True))
-        simm12 = Signal((12, True))
-        bimm12 = Signal((13, True))
-        uimm20 = Signal(20)
-        jimm20 = Signal((21, True))
-
-        insn = self.instruction
-        fmt = Signal(range(Type.J + 1))
-
-        m.d.comb += [
-            opcode.eq(insn[2:7]),
-            funct3.eq(insn[12:15]),
-            funct7.eq(insn[25:32]),
-            funct12.eq(insn[20:32]),
-
-            iimm12.eq(insn[20:32]),
-            simm12.eq(Cat(insn[7:12], insn[25:32])),
-            bimm12.eq(Cat(0, insn[8:12], insn[25:31], insn[7], insn[31])),
-            uimm20.eq(insn[12:32]),
-            jimm20.eq(Cat(0, insn[21:31], insn[20], insn[12:20], insn[31])),
-        ]
-
-        with m.Switch(opcode):
-            with m.Case(Opcode.LUI):
-                m.d.comb += fmt.eq(Type.U)
-            with m.Case(Opcode.AUIPC):
-                m.d.comb += fmt.eq(Type.U)
-            with m.Case(Opcode.JAL):
-                m.d.comb += fmt.eq(Type.J)
-            with m.Case(Opcode.JALR):
-                m.d.comb += fmt.eq(Type.I)
-            with m.Case(Opcode.BRANCH):
-                m.d.comb += fmt.eq(Type.B)
-            with m.Case(Opcode.LOAD):
-                m.d.comb += fmt.eq(Type.I)
-            with m.Case(Opcode.STORE):
-                m.d.comb += fmt.eq(Type.S)
-            with m.Case(Opcode.OP_IMM_32):
-                m.d.comb += fmt.eq(Type.I)
-            with m.Case(Opcode.OP_32):
-                m.d.comb += fmt.eq(Type.R)
-            with m.Case(Opcode.MISC_MEM):
-                m.d.comb += fmt.eq(Type.I)
-            with m.Case(Opcode.SYSTEM):
-                m.d.comb += fmt.eq(Type.I)
-
-        with m.Switch(fmt):
-            with m.Case(Type.I):
-                m.d.comb += self.immediate.eq(iimm12)
-            with m.Case(Type.S):
-                m.d.comb += self.immediate.eq(simm12)
-            with m.Case(Type.B):
-                m.d.comb += self.immediate.eq(bimm12)
-            with m.Case(Type.U):
-                m.d.comb += self.immediate.eq(uimm20 << 12)
-            with m.Case(Type.J):
-                m.d.comb += self.immediate.eq(jimm20)
-
-        m.d.comb += [
-            self.rd.eq(insn[7:12]),
-            self.rs1.eq(insn[15:20]),
-            self.rs2.eq(insn[20:25]),
-
-            self.rd_we.eq(reduce(or_, (fmt == T for T in (Type.R, Type.I, Type.U, Type.J)))),
-            self.rs1_re.eq(reduce(or_, (fmt == T for T in (Type.R, Type.I, Type.S, Type.B)))),
-            self.rs2_re.eq(reduce(or_, (fmt == T for T in (Type.R, Type.S, Type.B)))),
-
-            self.funct3.eq(funct3)
-        ]
-
-        def matcher(encodings):
-            return reduce(or_, starmap(
-                lambda opc, f3=None, f7=None, f12=None:
-                    (opcode  == opc if opc is not None else 1) \
-                  & (funct3  == f3  if f3  is not None else 1) \
-                  & (funct7  == f7  if f7  is not None else 1) \
-                  & (funct12 == f12 if f12 is not None else 1),
-                encodings))
-
-        m.d.comb += [
-            self.compare.eq(matcher([
-                (Opcode.OP_IMM_32, Funct3.SLT,  None), # slti
-                (Opcode.OP_IMM_32, Funct3.SLTU, None), # sltiu
-                (Opcode.OP_32,     Funct3.SLT,  0),    # slt
-                (Opcode.OP_32,     Funct3.SLTU, 0)     # sltu
-            ])),
-            self.branch.eq(matcher([
-                (Opcode.BRANCH, Funct3.BEQ,  None), # beq
-                (Opcode.BRANCH, Funct3.BNE,  None), # bne
-                (Opcode.BRANCH, Funct3.BLT,  None), # blt
-                (Opcode.BRANCH, Funct3.BGE,  None), # bge
-                (Opcode.BRANCH, Funct3.BLTU, None), # bltu
-                (Opcode.BRANCH, Funct3.BGEU, None)  # bgeu
-            ])),
-
-            self.adder.eq(matcher([
-                (Opcode.OP_IMM_32, Funct3.ADD, None),       # addi
-                (Opcode.OP_32,     Funct3.ADD, Funct7.ADD), # add
-                (Opcode.OP_32,     Funct3.ADD, Funct7.SUB)  # sub
-            ])),
-            self.adder_sub.eq(self.rs2_re & (funct7 == Funct7.SUB)),
-
-            self.logic.eq(matcher([
-                (Opcode.OP_IMM_32, Funct3.XOR, None), # xori
-                (Opcode.OP_IMM_32, Funct3.OR,  None), # ori
-                (Opcode.OP_IMM_32, Funct3.AND, None), # andi
-                (Opcode.OP_32,     Funct3.XOR, 0),    # xor
-                (Opcode.OP_32,     Funct3.OR,  0),    # or
-                (Opcode.OP_32,     Funct3.AND, 0)     # and
-            ])),
-        ]
-
-        if self.with_muldiv:
-            m.d.comb += [
-                self.multiply.eq(matcher([
-                    (Opcode.OP_32, Funct3.MUL,    Funct7.MULDIV), # mul
-                    (Opcode.OP_32, Funct3.MULH,   Funct7.MULDIV), # mulh
-                    (Opcode.OP_32, Funct3.MULHSU, Funct7.MULDIV), # mulhsu
-                    (Opcode.OP_32, Funct3.MULHU,  Funct7.MULDIV), # mulhu
-                ])),
-
-                self.divide.eq(matcher([
-                    (Opcode.OP_32, Funct3.DIV,  Funct7.MULDIV), # div
-                    (Opcode.OP_32, Funct3.DIVU, Funct7.MULDIV), # divu
-                    (Opcode.OP_32, Funct3.REM,  Funct7.MULDIV), # rem
-                    (Opcode.OP_32, Funct3.REMU, Funct7.MULDIV)  # remu
-                ])),
-            ]
-
-        m.d.comb += [
-            self.shift.eq(matcher([
-                (Opcode.OP_IMM_32, Funct3.SLL, 0),          # slli
-                (Opcode.OP_IMM_32, Funct3.SR,  Funct7.SRL), # srli
-                (Opcode.OP_IMM_32, Funct3.SR,  Funct7.SRA), # srai
-                (Opcode.OP_32,     Funct3.SLL, 0),          # sll
-                (Opcode.OP_32,     Funct3.SR,  Funct7.SRL), # srl
-                (Opcode.OP_32,     Funct3.SR,  Funct7.SRA)  # sra
-            ])),
-            self.direction.eq(funct3 == Funct3.SR),
-            self.sext.eq(funct7 == Funct7.SRA),
-
-            self.lui.eq(opcode == Opcode.LUI),
-            self.auipc.eq(opcode == Opcode.AUIPC),
-
-            self.jump.eq(matcher([
-                (Opcode.JAL,  None), # jal
-                (Opcode.JALR, 0)     # jalr
-            ])),
-
-            self.load.eq(matcher([
-                (Opcode.LOAD, Funct3.B),  # lb
-                (Opcode.LOAD, Funct3.BU), # lbu
-                (Opcode.LOAD, Funct3.H),  # lh
-                (Opcode.LOAD, Funct3.HU), # lhu
-                (Opcode.LOAD, Funct3.W)   # lw
-            ])),
-            self.store.eq(matcher([
-                (Opcode.STORE, Funct3.B), # sb
-                (Opcode.STORE, Funct3.H), # sh
-                (Opcode.STORE, Funct3.W)  # sw
-            ])),
-
-            self.fence_i.eq(matcher([
-                (Opcode.MISC_MEM, Funct3.FENCEI) # fence.i
-            ])),
-
-            self.csr.eq(matcher([
-                (Opcode.SYSTEM, Funct3.CSRRW),  # csrrw
-                (Opcode.SYSTEM, Funct3.CSRRS),  # csrrs
-                (Opcode.SYSTEM, Funct3.CSRRC),  # csrrc
-                (Opcode.SYSTEM, Funct3.CSRRWI), # csrrwi
-                (Opcode.SYSTEM, Funct3.CSRRSI), # csrrsi
-                (Opcode.SYSTEM, Funct3.CSRRCI)  # csrrci
-            ])),
-            self.csr_we.eq(~funct3[1] | (self.rs1 != 0)),
-
-            self.privileged.eq((opcode == Opcode.SYSTEM) & (funct3 == Funct3.PRIV)),
-            self.ecall.eq(self.privileged & (funct12 == Funct12.ECALL)),
-            self.ebreak.eq(self.privileged & (funct12 == Funct12.EBREAK)),
-            self.mret.eq(self.privileged & (funct12 == Funct12.MRET)),
-
-            self.bypass_x.eq(self.adder | self.logic | self.lui | self.auipc | self.csr),
-            self.bypass_m.eq(self.compare | self.divide | self.shift),
-
-            self.illegal.eq((self.instruction[:2] != 0b11) | ~reduce(or_, (
-                self.compare, self.branch, self.adder, self.logic, self.multiply, self.divide, self.shift,
-                self.lui, self.auipc, self.jump, self.load, self.store,
-                self.csr, self.ecall, self.ebreak, self.mret
-            )))
-        ]
-
-        return m
diff --git a/src/soc/minerva/units/divider.py b/src/soc/minerva/units/divider.py
deleted file mode 100644 (file)
index 42deafb..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-from nmigen import Elaboratable, Module, Signal, Mux, Cat, C
-
-from ..isa import Funct3
-
-
-__all__ = ["DividerInterface", "Divider", "DummyDivider"]
-
-
-class DividerInterface:
-    def __init__(self):
-        self.x_op     = Signal(3)
-        self.x_src1   = Signal(32)
-        self.x_src2   = Signal(32)
-        self.x_valid  = Signal()
-        self.x_stall  = Signal()
-
-        self.m_result = Signal(32)
-        self.m_busy   = Signal()
-
-
-class Divider(DividerInterface, Elaboratable):
-    def elaborate(self, platform):
-        m = Module()
-
-        x_enable  = Signal()
-        x_modulus = Signal()
-        x_signed  = Signal()
-
-        with m.Switch(self.x_op):
-            with m.Case(Funct3.DIV):
-                m.d.comb += x_enable.eq(1), x_signed.eq(1)
-            with m.Case(Funct3.DIVU):
-                m.d.comb += x_enable.eq(1)
-            with m.Case(Funct3.REM):
-                m.d.comb += x_enable.eq(1), x_modulus.eq(1), x_signed.eq(1)
-            with m.Case(Funct3.REMU):
-                m.d.comb += x_enable.eq(1), x_modulus.eq(1)
-
-        x_negative = Signal()
-        with m.If(x_modulus):
-            m.d.comb += x_negative.eq(x_signed & self.x_src1[31])
-        with m.Else():
-            m.d.comb += x_negative.eq(x_signed & (self.x_src1[31] ^ self.x_src2[31]))
-
-        x_dividend = Signal(32)
-        x_divisor  = Signal(32)
-        m.d.comb += [
-            x_dividend.eq(Mux(x_signed & self.x_src1[31], -self.x_src1, self.x_src1)),
-            x_divisor.eq(Mux(x_signed & self.x_src2[31], -self.x_src2, self.x_src2))
-        ]
-
-        m_modulus  = Signal()
-        m_negative = Signal()
-
-        timer      = Signal(range(33), reset=32)
-        quotient   = Signal(32)
-        divisor    = Signal(32)
-        remainder  = Signal(32)
-        difference = Signal(33)
-
-        with m.FSM() as fsm:
-            with m.State("IDLE"):
-                with m.If(x_enable & self.x_valid & ~self.x_stall):
-                    m.d.sync += [
-                        m_modulus.eq(x_modulus),
-                        m_negative.eq(x_negative)
-                    ]
-                    with m.If(x_divisor == 0):
-                        # Division by zero
-                        m.d.sync += [
-                            quotient.eq(-1),
-                            remainder.eq(self.x_src1)
-                        ]
-                    with m.Elif(x_signed & (self.x_src1 == -2**31) & (self.x_src2 == -1)):
-                        # Signed overflow
-                        m.d.sync += [
-                            quotient.eq(self.x_src1),
-                            remainder.eq(0)
-                        ]
-                    with m.Elif(x_dividend == 0):
-                        m.d.sync += [
-                            quotient.eq(0),
-                            remainder.eq(0)
-                        ]
-                    with m.Else():
-                        m.d.sync += [
-                            quotient.eq(x_dividend),
-                            remainder.eq(0),
-                            divisor.eq(x_divisor),
-                            timer.eq(timer.reset)
-                        ]
-                        m.next = "DIVIDE"
-
-            with m.State("DIVIDE"):
-                m.d.comb += self.m_busy.eq(1)
-                with m.If(timer != 0):
-                    m.d.sync += timer.eq(timer - 1)
-                    m.d.comb += difference.eq(Cat(quotient[31], remainder) - divisor)
-                    with m.If(difference[32]):
-                        m.d.sync += [
-                            remainder.eq(Cat(quotient[31], remainder)),
-                            quotient.eq(Cat(0, quotient))
-                        ]
-                    with m.Else():
-                        m.d.sync += [
-                            remainder.eq(difference),
-                            quotient.eq(Cat(1, quotient))
-                        ]
-                with m.Else():
-                    m.d.sync += [
-                        quotient.eq(Mux(m_negative, -quotient, quotient)),
-                        remainder.eq(Mux(m_negative, -remainder, remainder))
-                    ]
-                    m.next = "IDLE"
-
-        m.d.comb += self.m_result.eq(Mux(m_modulus, remainder, quotient))
-
-        return m
-
-
-class DummyDivider(DividerInterface, Elaboratable):
-    def elaborate(self, platform):
-        m = Module()
-
-        x_result = Signal.like(self.m_result)
-
-        with m.Switch(self.x_op):
-            # As per the RVFI specification (§ "Alternative Arithmetic Operations").
-            # https://github.com/SymbioticEDA/riscv-formal/blob/master/docs/rvfi.md
-            with m.Case(Funct3.DIV):
-                m.d.comb += x_result.eq((self.x_src1 - self.x_src2) ^ C(0x7f8529ec))
-            with m.Case(Funct3.DIVU):
-                m.d.comb += x_result.eq((self.x_src1 - self.x_src2) ^ C(0x10e8fd70))
-            with m.Case(Funct3.REM):
-                m.d.comb += x_result.eq((self.x_src1 - self.x_src2) ^ C(0x8da68fa5))
-            with m.Case(Funct3.REMU):
-                m.d.comb += x_result.eq((self.x_src1 - self.x_src2) ^ C(0x3138d0e1))
-
-        with m.If(~self.x_stall):
-            m.d.sync += self.m_result.eq(x_result)
-
-        m.d.comb += self.m_busy.eq(C(0))
-
-        return m
diff --git a/src/soc/minerva/units/exception.py b/src/soc/minerva/units/exception.py
deleted file mode 100644 (file)
index 1bee840..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-from nmigen import Elaboratable, Module, Signal
-from nmigen.lib.coding import PriorityEncoder
-
-from ..csr import AutoCSR, CSR
-from ..isa import (Cause,
-                   mstatus_layout, misa_layout, mie_layout,
-                   mtvec_layout, flat_layout, mepc_layout, mcause_layout,
-                   flat_layout, mip_layout, flat_layout)
-
-
-__all__ = ["ExceptionUnit"]
-
-
-class ExceptionUnit(Elaboratable, AutoCSR):
-    def __init__(self):
-        self.mstatus     = CSR(0x300, mstatus_layout, name="mstatus")
-        self.misa        = CSR(0x301, misa_layout, name="misa") # FIXME move elsewhere
-        self.mie         = CSR(0x304, mie_layout, name="mie")
-        self.mtvec       = CSR(0x305, mtvec_layout, name="mtvec")
-        self.mscratch    = CSR(0x340, flat_layout, name="mscratch") # FIXME move elsewhere
-        self.mepc        = CSR(0x341, mepc_layout, name="mepc")
-        self.mcause      = CSR(0x342, mcause_layout, name="mcause")
-        self.mtval       = CSR(0x343, flat_layout, name="mtval")
-        self.mip         = CSR(0x344, mip_layout, name="mip")
-        self.irq_mask    = CSR(0x330, flat_layout, name="irq_mask")
-        self.irq_pending = CSR(0x360, flat_layout, name="irq_pending")
-
-        self.external_interrupt = Signal(32)
-        self.timer_interrupt = Signal()
-        self.software_interrupt = Signal()
-
-        self.m_fetch_misaligned = Signal()
-        self.m_fetch_error = Signal()
-        self.m_fetch_badaddr = Signal(30)
-        self.m_load_misaligned = Signal()
-        self.m_load_error = Signal()
-        self.m_store_misaligned = Signal()
-        self.m_store_error = Signal()
-        self.m_loadstore_badaddr = Signal(30)
-        self.m_branch_target = Signal(32)
-        self.m_illegal = Signal()
-        self.m_ebreak = Signal()
-        self.m_ecall = Signal()
-        self.m_pc = Signal(32)
-        self.m_instruction = Signal(32)
-        self.m_result = Signal(32)
-        self.m_mret = Signal()
-        self.m_stall = Signal()
-        self.m_valid = Signal()
-
-        self.m_raise = Signal()
-
-    def elaborate(self, platform):
-        m = Module()
-
-        for csr in self.iter_csrs():
-            with m.If(csr.we):
-                m.d.sync += csr.r.eq(csr.w)
-
-        trap_pe = m.submodules.trap_pe = PriorityEncoder(16)
-        m.d.comb += [
-            trap_pe.i[Cause.FETCH_MISALIGNED   ].eq(self.m_fetch_misaligned),
-            trap_pe.i[Cause.FETCH_ACCESS_FAULT ].eq(self.m_fetch_error),
-            trap_pe.i[Cause.ILLEGAL_INSTRUCTION].eq(self.m_illegal),
-            trap_pe.i[Cause.BREAKPOINT         ].eq(self.m_ebreak),
-            trap_pe.i[Cause.LOAD_MISALIGNED    ].eq(self.m_load_misaligned),
-            trap_pe.i[Cause.LOAD_ACCESS_FAULT  ].eq(self.m_load_error),
-            trap_pe.i[Cause.STORE_MISALIGNED   ].eq(self.m_store_misaligned),
-            trap_pe.i[Cause.STORE_ACCESS_FAULT ].eq(self.m_store_error),
-            trap_pe.i[Cause.ECALL_FROM_M       ].eq(self.m_ecall)
-        ]
-
-        m.d.sync += [
-            self.irq_pending.r.eq(self.external_interrupt & self.irq_mask.r),
-            self.mip.r.msip.eq(self.software_interrupt),
-            self.mip.r.mtip.eq(self.timer_interrupt),
-            self.mip.r.meip.eq(self.irq_pending.r.bool())
-        ]
-
-        interrupt_pe = m.submodules.interrupt_pe = PriorityEncoder(16)
-        m.d.comb += [
-            interrupt_pe.i[Cause.M_SOFTWARE_INTERRUPT].eq(self.mip.r.msip & self.mie.r.msie),
-            interrupt_pe.i[Cause.M_TIMER_INTERRUPT   ].eq(self.mip.r.mtip & self.mie.r.mtie),
-            interrupt_pe.i[Cause.M_EXTERNAL_INTERRUPT].eq(self.mip.r.meip & self.mie.r.meie)
-        ]
-
-        m.d.comb += self.m_raise.eq(~trap_pe.n | ~interrupt_pe.n & self.mstatus.r.mie)
-
-        with m.If(self.m_valid & ~self.m_stall):
-            with m.If(self.m_raise):
-                m.d.sync += [
-                    self.mstatus.r.mpie.eq(self.mstatus.r.mie),
-                    self.mstatus.r.mie.eq(0),
-                    self.mepc.r.base.eq(self.m_pc[2:])
-                ]
-                with m.If(~trap_pe.n):
-                    m.d.sync += [
-                        self.mcause.r.ecode.eq(trap_pe.o),
-                        self.mcause.r.interrupt.eq(0)
-                    ]
-                    with m.Switch(trap_pe.o):
-                        with m.Case(Cause.FETCH_MISALIGNED):
-                            m.d.sync += self.mtval.r.eq(self.m_branch_target)
-                        with m.Case(Cause.FETCH_ACCESS_FAULT):
-                            m.d.sync += self.mtval.r.eq(self.m_fetch_badaddr << 2)
-                        with m.Case(Cause.ILLEGAL_INSTRUCTION):
-                            m.d.sync += self.mtval.r.eq(self.m_instruction)
-                        with m.Case(Cause.BREAKPOINT):
-                            m.d.sync += self.mtval.r.eq(self.m_pc)
-                        with m.Case(Cause.LOAD_MISALIGNED, Cause.STORE_MISALIGNED):
-                            m.d.sync += self.mtval.r.eq(self.m_result)
-                        with m.Case(Cause.LOAD_ACCESS_FAULT, Cause.STORE_ACCESS_FAULT):
-                            m.d.sync += self.mtval.r.eq(self.m_loadstore_badaddr << 2)
-                        with m.Case():
-                            m.d.sync += self.mtval.r.eq(0)
-                with m.Else():
-                    m.d.sync += [
-                        self.mcause.r.ecode.eq(interrupt_pe.o),
-                        self.mcause.r.interrupt.eq(1)
-                    ]
-            with m.Elif(self.m_mret):
-                m.d.sync += self.mstatus.r.mie.eq(self.mstatus.r.mpie)
-
-        return m
diff --git a/src/soc/minerva/units/logic.py b/src/soc/minerva/units/logic.py
deleted file mode 100644 (file)
index 143cd7f..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from nmigen import Elaboratable, Module, Signal
-
-from ..isa import Funct3
-
-
-__all__ = ["LogicUnit"]
-
-
-class LogicUnit(Elaboratable):
-    def __init__(self):
-        self.op = Signal(3)
-        self.src1 = Signal(32)
-        self.src2 = Signal(32)
-
-        self.result = Signal(32)
-
-    def elaborate(self, platform):
-        m = Module()
-
-        with m.Switch(self.op):
-            with m.Case(Funct3.XOR):
-                m.d.comb += self.result.eq(self.src1 ^ self.src2)
-            with m.Case(Funct3.OR):
-                m.d.comb += self.result.eq(self.src1 | self.src2)
-            with m.Case(Funct3.AND):
-                m.d.comb += self.result.eq(self.src1 & self.src2)
-
-        return m
diff --git a/src/soc/minerva/units/multiplier.py b/src/soc/minerva/units/multiplier.py
deleted file mode 100644 (file)
index f5a0a59..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-from nmigen import Elaboratable, Module, Signal, Cat, Mux, C, signed
-
-from ..isa import Funct3
-
-
-__all__ = ["MultiplierInterface", "Multiplier", "DummyMultiplier"]
-
-
-class MultiplierInterface:
-    def __init__(self):
-        self.x_op = Signal(3)
-        self.x_src1 = Signal(32)
-        self.x_src2 = Signal(32)
-        self.x_stall = Signal()
-        self.m_stall = Signal()
-
-        self.w_result = Signal(32)
-
-
-class Multiplier(MultiplierInterface, Elaboratable):
-    def elaborate(self, platform):
-        m = Module()
-
-        x_low = Signal()
-        x_src1_signed = Signal()
-        x_src2_signed = Signal()
-
-        m.d.comb += [
-            x_low.eq(self.x_op == Funct3.MUL),
-            x_src1_signed.eq((self.x_op == Funct3.MULH) |
-                             (self.x_op == Funct3.MULHSU)),
-            x_src2_signed.eq(self.x_op == Funct3.MULH)
-        ]
-
-        x_src1 = Signal(signed(33))
-        x_src2 = Signal(signed(33))
-
-        m.d.comb += [
-            x_src1.eq(Cat(self.x_src1, x_src1_signed & self.x_src1[31])),
-            x_src2.eq(Cat(self.x_src2, x_src2_signed & self.x_src2[31]))
-        ]
-
-        m_low = Signal()
-        m_prod = Signal(signed(66))
-
-        with m.If(~self.x_stall):
-            m.d.sync += [
-                m_low.eq(x_low),
-                m_prod.eq(x_src1 * x_src2)
-            ]
-
-        with m.If(~self.m_stall):
-            m.d.sync += self.w_result.eq(Mux(m_low, m_prod[:32], m_prod[32:]))
-
-        return m
-
-
-class DummyMultiplier(MultiplierInterface, Elaboratable):
-    def elaborate(self, platform):
-        m = Module()
-
-        x_result = Signal.like(self.w_result)
-        m_result = Signal.like(self.w_result)
-
-        with m.Switch(self.x_op):
-            # As per the RVFI specification (§ "Alternative Arithmetic Operations").
-            # https://github.com/SymbioticEDA/riscv-formal/blob/master/docs/rvfi.md
-            with m.Case(Funct3.MUL):
-                m.d.comb += x_result.eq((self.x_src1 +
-                                         self.x_src2) ^ C(0x5876063e))
-            with m.Case(Funct3.MULH):
-                m.d.comb += x_result.eq((self.x_src1 +
-                                         self.x_src2) ^ C(0xf6583fb7))
-            with m.Case(Funct3.MULHSU):
-                m.d.comb += x_result.eq((self.x_src1 -
-                                         self.x_src2) ^ C(0xecfbe137))
-            with m.Case(Funct3.MULHU):
-                m.d.comb += x_result.eq((self.x_src1 +
-                                         self.x_src2) ^ C(0x949ce5e8))
-
-        with m.If(~self.x_stall):
-            m.d.sync += m_result.eq(x_result)
-        with m.If(~self.m_stall):
-            m.d.sync += self.w_result.eq(m_result)
-
-        return m
diff --git a/src/soc/minerva/units/shifter.py b/src/soc/minerva/units/shifter.py
deleted file mode 100644 (file)
index 4ecd9fc..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-from nmigen import Elaboratable, Module, Signal, Mux, Repl, Cat
-
-
-__all__ = ["Shifter"]
-
-
-class Shifter(Elaboratable):
-    def __init__(self):
-        self.x_direction = Signal()
-        self.x_sext = Signal()
-        self.x_shamt = Signal(5)
-        self.x_src1 = Signal(32)
-        self.x_stall = Signal()
-
-        self.m_result = Signal(32)
-
-    def elaborate(self, platform):
-        m = Module()
-
-        x_operand = Signal(32)
-        x_filler = Signal()
-        m_direction = Signal()
-        m_result = Signal(32)
-
-        m.d.comb += [
-            # left shifts are equivalent to right shifts with reversed bits
-            x_operand.eq(Mux(self.x_direction, self.x_src1, self.x_src1[::-1])),
-            x_filler.eq(Mux(self.x_direction & self.x_sext, self.x_src1[-1], 0))
-        ]
-
-        with m.If(~self.x_stall):
-            m.d.sync += [
-                m_direction.eq(self.x_direction),
-                m_result.eq(Cat(x_operand, Repl(x_filler, 32)) >> self.x_shamt)
-            ]
-
-        m.d.comb += self.m_result.eq(Mux(m_direction, m_result, m_result[::-1]))
-
-        return m
diff --git a/src/soc/minerva/units/trigger.py b/src/soc/minerva/units/trigger.py
deleted file mode 100644 (file)
index 203b608..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-from functools import reduce
-from operator import or_
-
-from nmigen import Elaboratable, Module, Signal, Record
-
-from ..csr import AutoCSR, CSR
-from ..isa import flat_layout, tdata1_layout
-
-
-__all__ = ["TriggerUnit"]
-
-
-class Type:
-    NOP        = 0
-    LEGACY     = 1
-    MATCH      = 2
-    INSN_COUNT = 3
-    INTERRUPT  = 4
-    EXCEPTION  = 5
-
-
-mcontrol_layout = [
-    ("load",    1),
-    ("store",   1),
-    ("execute", 1),
-    ("u",       1),
-    ("s",       1),
-    ("zero0",   1),
-    ("m",       1),
-    ("match",   4),
-    ("chain",   1),
-    ("action",  4),
-    ("size",    2),
-    ("timing",  1),
-    ("select",  1),
-    ("hit",     1),
-    ("maskmax", 6)
-]
-
-
-class TriggerUnit(Elaboratable, AutoCSR):
-    def __init__(self, nb_triggers):
-        self.nb_triggers = nb_triggers
-
-        self.tselect = CSR(0x7a0, flat_layout, name="tselect")
-        self.tdata1  = CSR(0x7a1, tdata1_layout, name="tdata1")
-        self.tdata2  = CSR(0x7a2, flat_layout, name="tdata2")
-
-        self.x_pc = Signal(32)
-        self.x_valid = Signal()
-
-        self.haltreq = Signal()
-        self.trap = Signal()
-
-    def elaborate(self, platform):
-        m = Module()
-
-        triggers = [Record.like(self.tdata1.r) for _ in range(self.nb_triggers)]
-        for t in triggers:
-            # We only support address/data match triggers.
-            m.d.comb += t.type.eq(Type.MATCH)
-
-        def do_trigger_update(trigger):
-            m.d.sync += trigger.dmode.eq(self.tdata1.w.dmode)
-            mcontrol = Record([("i", mcontrol_layout), ("o", mcontrol_layout)])
-            m.d.comb += [
-                mcontrol.i.eq(self.tdata1.w.data),
-                mcontrol.o.execute.eq(mcontrol.i.execute),
-                mcontrol.o.m.eq(mcontrol.i.m),
-                mcontrol.o.action.eq(mcontrol.i.action),
-            ]
-            m.d.sync += trigger.data.eq(mcontrol.o)
-
-        with m.Switch(self.tselect.r.value):
-            for i, t in enumerate(triggers):
-                with m.Case(i):
-                    m.d.comb += self.tdata1.r.eq(t)
-                    with m.If(self.tdata1.we):
-                        do_trigger_update(t)
-
-        with m.If(self.tselect.we):
-            with m.If(self.tselect.w.value < self.nb_triggers):
-                m.d.sync += self.tselect.r.value.eq(self.tselect.w.value)
-
-        with m.If(self.tdata2.we):
-            m.d.sync += self.tdata2.r.eq(self.tdata2.w)
-
-        hit = Signal()
-        halt = Signal()
-
-        with m.Switch(self.tdata1.r.type):
-            with m.Case(Type.MATCH):
-                mcontrol = Record(mcontrol_layout)
-                m.d.comb += mcontrol.eq(self.tdata1.r.data)
-                match = Signal()
-                with m.If(mcontrol.execute):
-                    m.d.comb += match.eq(self.tdata2.r == self.x_pc & self.x_valid)
-                m.d.comb += [
-                    hit.eq(match & mcontrol.m),
-                    halt.eq(mcontrol.action)
-                ]
-
-        with m.If(hit):
-            with m.If(halt):
-                m.d.comb += self.haltreq.eq(self.tdata1.r.dmode)
-            with m.Else():
-                m.d.comb += self.trap.eq(1)
-
-        return m