Example #1
0
        assert Funct3.SRL == Funct3.SRLI
        assert Funct3.SRA == Funct3.SRAI
        m = Module()
        with m.Switch(self.funct3):
            with m.Case(Funct3.SLL):
                m.d.comb += self.res.eq(self.src1 << self.shift)
            with m.Case(Funct3.SRL):
                assert Funct3.SRL == Funct3.SRA
                assert Funct7.SRL != Funct7.SRA

                with m.If(self.funct7 == Funct7.SRL):
                    m.d.comb += self.res.eq(self.src1 >> self.shift)
                with m.Elif(self.funct7 == Funct7.SRA):
                    m.d.comb += [
                        self.src1signed.eq(self.src1),
                        self.res.eq(self.src1signed >> self.shift),
                    ]
        return m


match_shifter_unit = matcher(
    [
        (InstrType.OP_IMM, Funct3.SLLI, Funct7.SLLI),
        (InstrType.OP_IMM, Funct3.SRLI, Funct7.SRLI),
        (InstrType.OP_IMM, Funct3.SRAI, Funct7.SRAI),
        (InstrType.ALU, Funct3.SRA, Funct7.SRA),
        (InstrType.ALU, Funct3.SRL, Funct7.SRL),
        (InstrType.ALU, Funct3.SLL, Funct7.SLL),
    ]
)
Example #2
0
from mtkcpu.utils.common import matcher
from mtkcpu.cpu.isa import InstrType

match_lui = matcher([
    (InstrType.LUI, ),
])

match_auipc = matcher([
    (InstrType.AUIPC, ),
])
Example #3
0
        with m.Switch(self.funct3):
            with m.Case(Funct3.SLT):
                m.d.comb += self.condition_met.eq(self.negative
                                                  | self.overflow)
            with m.Case(Funct3.SLTU):
                m.d.comb += self.condition_met.eq(self.carry)

            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.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.carry)
            with m.Case(Funct3.BGEU):
                m.d.comb += self.condition_met.eq(~self.carry)
        return m


match_compare_unit = matcher([
    (InstrType.ALU, Funct3.SLT),
    (InstrType.ALU, Funct3.SLTU),
    (InstrType.OP_IMM, Funct3.SLT),
    (InstrType.OP_IMM, Funct3.SLTU),
])
Example #4
0
from mtkcpu.units.exception import ExceptionUnit
from mtkcpu.utils.common import CODE_START_ADDR, EBRMemConfig
from mtkcpu.units.adder import AdderUnit, match_adder_unit
from mtkcpu.units.compare import CompareUnit, match_compare_unit
from mtkcpu.units.loadstore import (MemoryArbiter, MemoryUnit, match_load,
                                    match_loadstore_unit)
from mtkcpu.units.logic import LogicUnit, match_logic_unit
from mtkcpu.units.shifter import ShifterUnit, match_shifter_unit
from mtkcpu.units.upper import match_auipc, match_lui
from mtkcpu.utils.common import matcher
from mtkcpu.cpu.isa import Funct3, InstrType, Funct7
from mtkcpu.units.debug.top import DebugUnit
from mtkcpu.cpu.priv_isa import IrqCause, TrapCause, PrivModeBits

match_jal = matcher([
    (InstrType.JAL, ),
])

match_jalr = matcher([
    (InstrType.JALR, Funct3.JALR),
])

match_branch = matcher([
    (InstrType.BRANCH, Funct3.BEQ),
    (InstrType.BRANCH, Funct3.BNE),
    (InstrType.BRANCH, Funct3.BLT),
    (InstrType.BRANCH, Funct3.BGE),
    (InstrType.BRANCH, Funct3.BLTU),
    (InstrType.BRANCH, Funct3.BGEU),
])
Example #5
0
        self.carry = Signal(name="adder_carry")

    def elaborate(self, platform):
        m = Module()

        # neat way of setting carry flag
        res_and_carry = Cat(self.res, self.carry)

        m.d.comb += res_and_carry.eq(
            Mux(self.sub, self.src1 - self.src2, self.src1 + self.src2))

        with m.If(self.sub):
            with m.If((self.src1[-1] != self.src2[-1])
                      & (self.src1[-1] != self.res[-1])):
                m.d.comb += self.overflow.eq(1)
        with m.Else():
            # add
            with m.If((self.src1[-1] == self.src2[-1])
                      & (self.src1[-1] != self.res[-1])):
                m.d.comb += self.overflow.eq(1)

        return m


match_adder_unit = matcher([
    (InstrType.ALU, Funct3.ADD, Funct7.ADD),
    (InstrType.ALU, Funct3.SUB, Funct7.SUB),
    (InstrType.OP_IMM, Funct3.ADD),
    (InstrType.OP_IMM, Funct3.SUB),
])
Example #6
0
class LogicUnit(Elaboratable):
    def __init__(self):
        self.src1 = Signal(32, name="logic_src1")
        self.src2 = Signal(32, name="logic_src2")
        self.res = Signal(32, name="logic_res")
        self.funct3 = Signal(Funct3)

    def elaborate(self, platform):
        m = Module()
        with m.Switch(self.funct3):
            with m.Case(Funct3.OR):
                m.d.comb += self.res.eq(self.src1 | self.src2)
            with m.Case(Funct3.AND):
                m.d.comb += self.res.eq(self.src1 & self.src2)
            with m.Case(Funct3.XOR):
                m.d.comb += self.res.eq(self.src1 ^ self.src2)
        return m


match_logic_unit = matcher(
    [
        (InstrType.ALU, Funct3.OR, 0b0000000),
        (InstrType.ALU, Funct3.AND, 0b0000000),
        (InstrType.ALU, Funct3.XOR, 0b0000000),
        (InstrType.OP_IMM, Funct3.XOR),
        (InstrType.OP_IMM, Funct3.OR),
        (InstrType.OP_IMM, Funct3.AND),
    ]
)
Example #7
0
                            with m.Else():
                                # covers all non-waiting paths.
                                m.next = "FINISH"
                            
                            with m.If(_is(func3_latch, [Funct3.CSRRS, Funct3.CSRRC])):
                                with m.If(rs1_latch != 0):
                                    reg.handle_write()
                                    comb += need_wait.eq(1)
                            with m.Else():
                                reg.handle_write()
                                comb += need_wait.eq(1)
            with m.State("FINISH"):
                m.next = "IDLE"
                comb += [
                    self.vld.eq(1)
                ]

        return m

match_csr = matcher(
    [
        (InstrType.SYSTEM, Funct3.CSRRW),
        (InstrType.SYSTEM, Funct3.CSRRS),
        (InstrType.SYSTEM, Funct3.CSRRC),

        (InstrType.SYSTEM, Funct3.CSRRWI),
        (InstrType.SYSTEM, Funct3.CSRRSI),
        (InstrType.SYSTEM, Funct3.CSRRCI),
    ]
)
Example #8
0
    def port(self, priority):
        if priority < 0:
            raise ValueError(f"Negative priority passed! {priority} < 0.")
        if priority in self.ports:
            raise ValueError(
                f"Conflicting priority passed to MemoryArbiter.port(): {priority}"
            )
        port = self.ports[priority] = LoadStoreInterface()
        return port


match_load = matcher([
    (InstrType.LOAD, Funct3.W),
    (InstrType.LOAD, Funct3.B),
    (InstrType.LOAD, Funct3.BU),
    (InstrType.LOAD, Funct3.H),
    (InstrType.LOAD, Funct3.HU),
])

match_store = matcher([
    (InstrType.STORE, Funct3.W),
    (InstrType.STORE, Funct3.B),
    # (InstrType.STORE, Funct3.BU), # it doesn't exist
    (InstrType.STORE, Funct3.H),
    # (InstrType.STORE, Funct3.HU), # it doesn't exist
])


def match_loadstore_unit(op, f3, f7):
    return match_load(op, f3, f7) | match_store(op, f3, f7)