コード例 #1
0
ファイル: csr.py プロジェクト: ImArcangel/Bellatrix
    def elaborate(self, platform):
        m = Module()

        invalid_r = Signal()
        invalid_w = Signal()

        # do the read
        m.d.comb += invalid_r.eq(0)
        for rport in self._read_ports:
            with m.Switch(rport.addr):
                for addr, csr in self._csr_map.items():
                    with m.Case(addr):
                        m.d.comb += rport.data.eq(csr.read & csr.mask)
                with m.Default():
                    m.d.comb += invalid_r.eq(1)

        # do the write
        m.d.comb += invalid_r.eq(0)
        for wport in self._write_ports:
            with m.Switch(wport.addr):
                for addr, csr in self._csr_map.items():
                    with m.Case(addr):
                        m.d.comb += [
                            csr.we.eq(wport.en),
                            csr.write.eq(wport.data & csr.mask)
                        ]
                with m.Default():
                    m.d.comb += invalid_r.eq(1)

        m.d.comb += self.invalid.eq(invalid_r | invalid_w)
        return m
コード例 #2
0
ファイル: IC_GAL.py プロジェクト: EngRaff92/riscv-reboot
    def elaborate(self, _: Platform) -> Module:
        """Implements the logic of the buffer."""
        m = Module()

        # OE_I = 0000011 | 0001111 | 0010011
        # OE_S = 0100011
        # OE_U = 0010111 | 0110111
        # OE_B = 1100011
        # OE_J = 1100111 | 1101111
        # OE_SYS = 1110011

        m.d.comb += [
            self.i_n_oe.eq(1),
            self.s_n_oe.eq(1),
            self.u_n_oe.eq(1),
            self.b_n_oe.eq(1),
            self.j_n_oe.eq(1),
            self.sys_n_oe.eq(1),
        ]
        with m.Switch(self.opcode):
            with m.Case(0b0000011, 0b0001111, 0b0010011):  # I
                m.d.comb += self.i_n_oe.eq(0)
            with m.Case(0b0100011):  # S
                m.d.comb += self.s_n_oe.eq(0)
            with m.Case(0b0010111, 0b0110111):  # U
                m.d.comb += self.u_n_oe.eq(0)
            with m.Case(0b1100011):
                m.d.comb += self.b_n_oe.eq(0)
            with m.Case(0b1100111, 0b1101111):
                m.d.comb += self.j_n_oe.eq(0)
            with m.Default():
                m.d.comb += self.sys_n_oe.eq(0)
        return m
コード例 #3
0
ファイル: core.py プロジェクト: ircmaxell/6800_cpu
	def execute(self, m: Module):
		with m.Switch(self.registers.instr):
			for key, instr in self.instruction_set.instructions.items():
				with m.Case(key):
					instr.implement(m, self)
			with m.Default():
				self.halt(m)
コード例 #4
0
 def elaborate(self, p: Platform) -> Module:
     m = Module()
     comb = m.d.comb
     signed_lhs = as_signed(m, self.lhs)
     signed_rhs = as_signed(m, self.rhs)
     with m.If(self.en):
         if self.invalid_op is not None:
             comb += self.invalid_op.eq(0)
         with m.Switch(self.op):
             with m.Case(OpAlu.ADD):
                 comb += self.output.eq(self.lhs + self.rhs)
             with m.Case(OpAlu.SLT):
                 comb += self.output.eq(Mux(signed_lhs < signed_rhs, 1, 0))
             with m.Case(OpAlu.SLTU):
                 comb += self.output.eq(Mux(self.lhs < self.rhs, 1, 0))
             with m.Case(OpAlu.AND):
                 comb += self.output.eq(self.lhs & self.rhs)
             with m.Case(OpAlu.OR):
                 comb += self.output.eq(self.lhs | self.rhs)
             with m.Case(OpAlu.XOR):
                 comb += self.output.eq(self.lhs ^ self.rhs)
             with m.Default():
                 comb += self.output.eq(0)
                 if self.invalid_op is not None:
                     comb += self.invalid_op.eq(1)
     with m.Else():
         self.output.eq(0)
     return m
コード例 #5
0
	def setup_src_bus(self, m: Module, reg_map: Dict[IntEnum, Register], bus: Signal, selector: Signal):
		with m.Switch(selector):
			for (e, reg) in reg_map.items():
				with m.Case(e):
					m.d.comb += bus.eq(reg.register)
			with m.Default():
				m.d.comb += bus.eq(0)
コード例 #6
0
ファイル: shift_card.py プロジェクト: EngRaff92/riscv-reboot
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the shifter."""
        m = Module()
        m.submodules.shifter = shifter = ShiftCard()

        shamt = Signal(5)
        m.d.comb += shamt.eq(shifter.data_y[:5])

        with m.If(shamt > 0):
            m.d.comb += Cover(shifter.data_z == 0xFFFFAAA0)

        with m.Switch(shifter.alu_op):
            with m.Case(AluOp.SLL):
                m.d.comb += Assert(
                    shifter.data_z == (shifter.data_x << shamt)[:32])

            with m.Case(AluOp.SRL):
                m.d.comb += Assert(shifter.data_z == (shifter.data_x >> shamt))

            with m.Case(AluOp.SRA):
                m.d.comb += Assert(
                    shifter.data_z == (shifter.data_x.as_signed() >> shamt))

            with m.Default():
                m.d.comb += Assert(shifter.data_z == 0)

        return m, [
            shifter.alu_op, shifter.data_x, shifter.data_y, shifter.data_z
        ]
コード例 #7
0
ファイル: core.py プロジェクト: GuzTech/n6800
 def execute(self, m: Module):
     """Execute the instruction in the instr register."""
     with m.Switch(self.instr):
         with m.Case("00000001"):  # NOP
             self.NOP(m)
         with m.Case("01111110"):  # JMP ext
             self.JMPext(m)
         with m.Case("1-110110"):  # LDA ext
             self.ALUext(m, ALU8Func.LD)
         with m.Case("1-110000"):  # SUB ext
             self.ALUext(m, ALU8Func.SUB)
         with m.Case("1-110001"):  # CMP ext
             self.ALUext(m, ALU8Func.SUB, store=False)
         with m.Case("1-110010"):  # SBC ext
             self.ALUext(m, ALU8Func.SBC)
         with m.Case("1-110100"):  # AND ext
             self.ALUext(m, ALU8Func.AND)
         with m.Case("1-110101"):  # BIT ext
             self.ALUext(m, ALU8Func.AND, store=False)
         with m.Case("1-110111"):  # STA ext
             self.STAext(m)
         with m.Case("1-111000"):  # EOR ext
             self.ALUext(m, ALU8Func.EOR)
         with m.Case("1-111001"):  # ADC ext
             self.ALUext(m, ALU8Func.ADC)
         with m.Case("1-111010"):  # ORA ext
             self.ALUext(m, ALU8Func.ORA)
         with m.Case("1-111011"):  # ADD ext
             self.ALUext(m, ALU8Func.ADD)
         with m.Default():  # Illegal
             self.end_instr(m, self.pc)
コード例 #8
0
ファイル: core.py プロジェクト: GuzTech/n6800
 def src_bus_setup(self, m: Module, reg_map: Dict[IntEnum, Tuple[Signal,
                                                                 bool]],
                   bus: Signal, selector: Signal):
     with m.Switch(selector):
         for e, reg in reg_map.items():
             with m.Case(e):
                 m.d.comb += bus.eq(reg[0])
         with m.Default():
             m.d.comb += bus.eq(0)
コード例 #9
0
ファイル: alu_card.py プロジェクト: EngRaff92/riscv-reboot
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the ALU."""
        m = Module()
        m.submodules.alu = alu = AluCard()

        with m.Switch(alu.alu_op):
            with m.Case(AluOp.ADD):
                m.d.comb += Assert(alu.data_z == (alu.data_x +
                                                  alu.data_y)[:32])

            with m.Case(AluOp.SUB):
                m.d.comb += [
                    Assert(alu.data_z == (alu.data_x - alu.data_y)[:32]),
                    Assert(alu.alu_eq == (alu.data_x == alu.data_y)),
                    Assert(alu.alu_ltu == (alu.data_x < alu.data_y)),
                    Assert(alu.alu_lt == (
                        alu.data_x.as_signed() < alu.data_y.as_signed())),
                ]

            with m.Case(AluOp.AND):
                m.d.comb += Assert(alu.data_z == (alu.data_x & alu.data_y))

            with m.Case(AluOp.AND_NOT):
                m.d.comb += Assert(alu.data_z == (alu.data_x & ~alu.data_y))

            with m.Case(AluOp.OR):
                m.d.comb += Assert(alu.data_z == (alu.data_x | alu.data_y))

            with m.Case(AluOp.XOR):
                m.d.comb += Assert(alu.data_z == (alu.data_x ^ alu.data_y))

            with m.Case(AluOp.SLTU):
                with m.If(alu.data_x < alu.data_y):
                    m.d.comb += Assert(alu.data_z == 1)
                with m.Else():
                    m.d.comb += Assert(alu.data_z == 0)

            with m.Case(AluOp.SLT):
                with m.If(alu.data_x.as_signed() < alu.data_y.as_signed()):
                    m.d.comb += Assert(alu.data_z == 1)
                with m.Else():
                    m.d.comb += Assert(alu.data_z == 0)

            with m.Case(AluOp.X):
                m.d.comb += Assert(alu.data_z == alu.data_x)

            with m.Case(AluOp.Y):
                m.d.comb += Assert(alu.data_z == alu.data_y)

            with m.Default():
                m.d.comb += Assert(alu.data_z == 0)

        return m, [alu.alu_op, alu.data_x, alu.data_y, alu.data_z]
コード例 #10
0
ファイル: logic.py プロジェクト: AngelTerrones/Bellatrix
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        with m.Switch(self.op):
            with m.Case(Funct3.XOR):
                m.d.comb += self.result.eq(self.dat1 ^ self.dat2)
            with m.Case(Funct3.OR):
                m.d.comb += self.result.eq(self.dat1 | self.dat2)
            with m.Case(Funct3.AND):
                m.d.comb += self.result.eq(self.dat1 & self.dat2)
            with m.Default():
                m.d.comb += self.result.eq(0)

        return m
コード例 #11
0
 def make_fakemem(self, m: Module, mem: Dict[int, int]):
     comb: List[Statement] = m.d.comb
     with m.If(self.mem2core.en):
         with m.Switch(self.mem2core.addr):
             for address, value in mem.items():
                 with m.Case(address):
                     word_value = value | (
                         mem.get(address + 1, 0xff) << 8) | (
                             mem.get(address + 2, 0xff) << 16) | (
                                 mem.get(address + 3, 0xff) << 24)
                     comb += self.mem2core.value.eq(word_value)
             with m.Default():
                 comb += self.mem2core.value.eq(0xFFFFFFFF)
         comb += self.mem2core.ready.eq(1)
     with m.Else():
         comb += self.mem2core.ready.eq(1)
コード例 #12
0
ファイル: csr.py プロジェクト: AngelTerrones/Bellatrix
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        invalid_undef = Signal()  # The register is not defined
        invalid_ro = Signal()  # The register is read-only.
        invalid_priv = Signal()  # The priviledge mode is incorrect.

        # ----------------------------------------------------------------------
        # access
        for idx, port in enumerate(self._ports):
            if idx == 0:
                # The first write port is for pipeline use, and is the only one that
                # can generate exceptions
                # Other write ports do not generate exceptions: for debug use, for example.

                # Priv mode must be greater or equal to the priv mode of the register.
                m.d.comb += [
                    invalid_ro.eq(port.addr[10:12] == 0b11),
                    invalid_priv.eq(port.addr[8:10] > self.privmode)
                ]

                with m.Switch(port.addr):
                    for addr, csr in self._csr_map.items():
                        with m.Case(addr):
                            m.d.comb += [
                                csr.we.eq(port.en
                                          & ~(invalid_ro | invalid_priv)),
                                port.data_r.eq(csr.read & csr.mask),
                                csr.write.eq(port.data_w & csr.mask)
                            ]
                    with m.Default():
                        m.d.comb += invalid_undef.eq(1)

                m.d.comb += self.invalid.eq(invalid_undef
                                            | (invalid_ro & port.en)
                                            | invalid_priv)
            else:
                with m.Switch(port.addr):
                    for addr, csr in self._csr_map.items():
                        with m.Case(addr):
                            m.d.comb += [
                                csr.we.eq(port.en),
                                port.data_r.eq(csr.read & csr.mask),
                                csr.write.eq(port.data_w & csr.mask)
                            ]

        return m
コード例 #13
0
ファイル: core.py プロジェクト: martinbarez/spc700-nmigen
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        m.submodules.alu = self.alu = ALU()

        """Fetch the opcode, common for all instr"""
        m.d.sync += self.opcode.eq(Mux(self.cycle == 1, self.dout, self.opcode))

        with m.Switch(Mux(self.cycle == 1, self.dout, self.opcode)):
            for i in implemented.implemented:
                with m.Case(i.opcode):
                    i.synth(self, m)
            with m.Default():
                m.d.comb += core.alu.oper.eq(Operation.NOP)
                m.d.sync += [
                    core.reg.PC.eq(add16(core.reg.PC, 1)),
                    core.enable.eq(1),
                    core.addr.eq(add16(core.reg.PC, 1)),
                    core.RWB.eq(1),
                    core.cycle.eq(1),
                ]

        if self.verification is not None:
            self.verify(m)

            with m.If(Initial()):
                m.d.sync += [
                    self.reg.A.eq(AnyConst(8)),
                    self.reg.X.eq(AnyConst(8)),
                    self.reg.Y.eq(AnyConst(8)),
                    self.reg.SP.eq(AnyConst(16)),
                    self.reg.PC.eq(AnyConst(16)),
                ]
                m.d.sync += [
                    self.reg.PSW.N.eq(AnyConst(1)),
                    self.reg.PSW.V.eq(AnyConst(1)),
                    self.reg.PSW.P.eq(AnyConst(1)),
                    self.reg.PSW.B.eq(AnyConst(1)),
                    self.reg.PSW.H.eq(AnyConst(1)),
                    self.reg.PSW.I.eq(AnyConst(1)),
                    self.reg.PSW.Z.eq(AnyConst(1)),
                    self.reg.PSW.C.eq(AnyConst(1)),
                ]

        return m
コード例 #14
0
    def elaborate(self, _: Platform) -> Module:
        """Implements the logic for the NextDay module."""
        m = Module()

        is_leap_year = Signal()
        max_day = Signal.like(self.day)

        m.d.comb += is_leap_year.eq(0)  # We can override this below!
        with m.If((self.year % 4) == 0):
            m.d.comb += is_leap_year.eq(1)
            with m.If((self.year % 100) == 0):
                m.d.comb += is_leap_year.eq(0)
                with m.If((self.year % 400) == 0):
                    m.d.comb += is_leap_year.eq(1)

        with m.Switch(self.month):
            with m.Case(1, 3, 5, 7, 8, 10, 12):
                m.d.comb += max_day.eq(31)
            with m.Case(2):
                m.d.comb += max_day.eq(28 + is_leap_year)
            with m.Default():
                m.d.comb += max_day.eq(30)

        m.d.comb += self.next_year.eq(self.year)
        m.d.comb += self.next_month.eq(self.month)
        m.d.comb += self.next_day.eq(self.day + 1)

        with m.If(self.day == max_day):
            m.d.comb += self.next_day.eq(1)
            m.d.comb += self.next_month.eq(self.month + 1)
            with m.If(self.month == 12):
                m.d.comb += self.next_month.eq(1)
                m.d.comb += self.next_year.eq(self.year + 1)

        m.d.comb += self.invalid.eq(0)
        with m.If((self.day < 1) | (self.day > max_day) | (self.month < 1)
                  | (self.month > 12) | (self.year < 1) | (self.year > 9999)):
            m.d.comb += self.invalid.eq(1)

        with m.If(self.invalid):
            m.d.comb += self.next_year.eq(0)
            m.d.comb += self.next_month.eq(0)
            m.d.comb += self.next_day.eq(0)

        return m
コード例 #15
0
ファイル: compare.py プロジェクト: ImArcangel/Bellatrix
    def elaborate(self, platform):
        m = Module()

        with m.Switch(self.op):
            with m.Case(Funct3.BEQ):
                m.d.comb += self.cmp_ok.eq(self.zero)
            with m.Case(Funct3.BNE):
                m.d.comb += self.cmp_ok.eq(~self.zero)
            with m.Case(Funct3.BLT, Funct3.SLT):
                m.d.comb += self.cmp_ok.eq(~self.zero
                                           & (self.negative != self.overflow))
            with m.Case(Funct3.BLTU, Funct3.SLTU):
                m.d.comb += self.cmp_ok.eq(~self.zero & self.carry)
            with m.Case(Funct3.BGE):
                m.d.comb += self.cmp_ok.eq(self.negative == self.overflow)
            with m.Case(Funct3.BGEU):
                m.d.comb += self.cmp_ok.eq(~self.carry)
            with m.Default():
                m.d.comb += self.cmp_ok.eq(0)

        return m
コード例 #16
0
    def decode_const(self, m: Module):
        const_sig = Signal(32)

        with m.Switch(self._const):
            with m.Case(ConstSelect.EXC_INSTR_ADDR_MISALIGN):
                m.d.comb += const_sig.eq(
                    TrapCause.EXC_INSTR_ADDR_MISALIGN)
            with m.Case(ConstSelect.EXC_ILLEGAL_INSTR):
                m.d.comb += const_sig.eq(TrapCause.EXC_ILLEGAL_INSTR)
            with m.Case(ConstSelect.EXC_BREAKPOINT):
                m.d.comb += const_sig.eq(TrapCause.EXC_BREAKPOINT)
            with m.Case(ConstSelect.EXC_LOAD_ADDR_MISALIGN):
                m.d.comb += const_sig.eq(
                    TrapCause.EXC_LOAD_ADDR_MISALIGN)
            with m.Case(ConstSelect.EXC_STORE_AMO_ADDR_MISALIGN):
                m.d.comb += const_sig.eq(
                    TrapCause.EXC_STORE_AMO_ADDR_MISALIGN)
            with m.Case(ConstSelect.EXC_ECALL_FROM_MACH_MODE):
                m.d.comb += const_sig.eq(
                    TrapCause.EXC_ECALL_FROM_MACH_MODE)
            with m.Case(ConstSelect.INT_MACH_EXTERNAL):
                m.d.comb += const_sig.eq(TrapCause.INT_MACH_EXTERNAL)
            with m.Case(ConstSelect.INT_MACH_TIMER):
                m.d.comb += const_sig.eq(TrapCause.INT_MACH_TIMER)
            with m.Case(ConstSelect.SHAMT_0):
                m.d.comb += const_sig.eq(0)
            with m.Case(ConstSelect.SHAMT_4):
                m.d.comb += const_sig.eq(4)
            with m.Case(ConstSelect.SHAMT_8):
                m.d.comb += const_sig.eq(8)
            with m.Case(ConstSelect.SHAMT_16):
                m.d.comb += const_sig.eq(16)
            with m.Case(ConstSelect.SHAMT_24):
                m.d.comb += const_sig.eq(24)
            with m.Default():
                m.d.comb += const_sig.eq(0)

        return const_sig
コード例 #17
0
    def handle_csrs(self, m: Module):
        """Adds the SYSTEM (CSR opcodes) logic to the given module.

        Some points of interest:

        * Attempts to write a read-only register
          result in an illegal instruction exception.
        * Attempts to access a CSR that doesn't exist
          result in an illegal instruction exception.
        * Attempts to write read-only bits to a read/write CSR
          are ignored.

        Because we're building this in hardware, which is
        expensive, we're not implementing any CSRs that aren't
        strictly necessary. The documentation for the misa, mvendorid,
        marchid, and mimpid registers state that they can return zero if
        unimplemented. This implies that unimplemented CSRs still
        exist.

        The mhartid, because we only have one HART, can just return zero.
        """
        with m.Switch(self._funct3):
            with m.Case(SystemFunc.CSRRW):
                self.handle_CSRRW(m)
            with m.Case(SystemFunc.CSRRWI):
                self.handle_CSRRWI(m)
            with m.Case(SystemFunc.CSRRS):
                self.handle_CSRRS(m)
            with m.Case(SystemFunc.CSRRSI):
                self.handle_CSRRSI(m)
            with m.Case(SystemFunc.CSRRC):
                self.handle_CSRRC(m)
            with m.Case(SystemFunc.CSRRCI):
                self.handle_CSRRCI(m)
            with m.Default():
                self.handle_illegal_instr(m)
コード例 #18
0
    def formal(cls) -> Tuple[Module, List[Signal]]:
        m = Module()
        ph = ClockDomain("ph")
        clk = ClockSignal("ph")

        m.domains += ph
        m.d.sync += clk.eq(~clk)

        s = IC_reg32_with_mux(clk="ph", N=2, faster=True)

        m.submodules += s

        sync_clk = ClockSignal("sync")
        sync_rst = ResetSignal("sync")

        with m.If(Rose(clk)):
            with m.Switch(~Past(s.n_sel)):
                with m.Case(0b11):
                    m.d.comb += Assert(0)
                with m.Case(0b01):
                    m.d.comb += Assert(s.q == Past(s.d[0]))
                with m.Case(0b10):
                    m.d.comb += Assert(s.q == Past(s.d[1]))
                with m.Default():
                    m.d.comb += Assert(s.q == Past(s.q))

        # Make sure the clock is clocking
        m.d.comb += Assume(sync_clk == ~Past(sync_clk))

        # Don't want to test what happens when we reset.
        m.d.comb += Assume(~sync_rst)
        m.d.comb += Assume(~ResetSignal("ph"))

        m.d.comb += Assume(s.n_sel != 0)

        return m, [sync_clk, sync_rst, s.d[0], s.d[1], s.n_sel, s.q]
コード例 #19
0
ファイル: core.py プロジェクト: GuzTech/n6800
    else:
        # Fake memory
        mem = {
            0xFFFE: 0x12,
            0xFFFF: 0x34,
            0x1234: 0x7E,  # JMP 0xA010
            0x1235: 0xA0,
            0x1236: 0x10,
            0xA010: 0x01,  # NOP
        }
        with m.Switch(core.Addr):
            for addr, data in mem.items():
                with m.Case(addr):
                    m.d.comb += core.Din.eq(data)
            with m.Default():
                m.d.comb += core.Din.eq(0xFF)

        sim = Simulator(m)
        sim.add_clock(1e-6, domain="ph1")

        def process():
            yield
            yield
            yield
            yield
            yield
            yield
            yield
            yield
            yield
コード例 #20
0
    def elaborate(self, _: Platform) -> Module:
        """Implements the logic of the sequencer card."""
        m = Module()

        # Defaults
        m.d.comb += [
            self._next_instr_phase.eq(0),
            self.reg_to_x.eq(0),
            self.reg_to_y.eq(0),
            self.alu_op_to_z.eq(AluOp.NONE),
            self.mem_rd.eq(0),
            self.mem_wr.eq(0),
            self.mem_wr_mask.eq(0),
            self.csr_to_x.eq(0),
            self.z_to_csr.eq(0),
            self._funct12_to_csr_num.eq(0),
            self._mepc_num_to_csr_num.eq(0),
            self._mcause_to_csr_num.eq(0),
            self._x_reg_select.eq(0),
            self._y_reg_select.eq(0),
            self._z_reg_select.eq(0),
            self.enter_trap.eq(0),
            self.exit_trap.eq(0),
            self.save_trap_csrs.eq(0),
            self.pc_mux_select.eq(SeqMuxSelect.PC),
            self.memaddr_mux_select.eq(SeqMuxSelect.MEMADDR),
            self.memdata_wr_mux_select.eq(SeqMuxSelect.MEMDATA_WR),
            self.tmp_mux_select.eq(SeqMuxSelect.TMP),
            self.x_mux_select.eq(SeqMuxSelect.X),
            self.y_mux_select.eq(SeqMuxSelect.Y),
            self.z_mux_select.eq(SeqMuxSelect.Z),
            self._const.eq(0),
        ]

        m.d.comb += [
            self.load_trap.eq(0),
            self.next_trap.eq(0),
            self.load_exception.eq(0),
            self.next_exception.eq(0),
            self.next_fatal.eq(0),
        ]

        with m.If(self.enable_sequencer_rom):

            # Output control signals
            with m.Switch(self.opcode_select):
                with m.Case(OpcodeSelect.LUI):
                    self.handle_lui(m)

                with m.Case(OpcodeSelect.AUIPC):
                    self.handle_auipc(m)

                with m.Case(OpcodeSelect.OP_IMM):
                    self.handle_op_imm(m)

                with m.Case(OpcodeSelect.OP):
                    self.handle_op(m)

                with m.Case(OpcodeSelect.JAL):
                    self.handle_jal(m)

                with m.Case(OpcodeSelect.JALR):
                    self.handle_jalr(m)

                with m.Case(OpcodeSelect.BRANCH):
                    self.handle_branch(m)

                with m.Case(OpcodeSelect.LOAD):
                    self.handle_load(m)

                with m.Case(OpcodeSelect.STORE):
                    self.handle_store(m)

                with m.Case(OpcodeSelect.CSRS):
                    self.handle_csrs(m)

                with m.Case(OpcodeSelect.MRET):
                    self.handle_MRET(m)

                with m.Case(OpcodeSelect.ECALL):
                    self.handle_ECALL(m)

                with m.Case(OpcodeSelect.EBREAK):
                    self.handle_EBREAK(m)

                with m.Default():
                    self.handle_illegal_instr(m)

        return m
コード例 #21
0
ファイル: alu8.py プロジェクト: typingArtist/n6800
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        m.d.comb += self._ccs.eq(self.ccs)
        m.d.ph1 += self.ccs.eq(self._ccs)

        # intermediates
        carry4 = Signal()
        carry7 = Signal()
        carry8 = Signal()
        overflow = Signal()

        with m.Switch(self.func):
            with m.Case(ALU8Func.LD):
                m.d.comb += self.output.eq(self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.LDCHAIN):
                m.d.comb += self.output.eq(self.input2)
                m.d.comb += self._ccs[Flags.Z].eq((self.output == 0)
                                                  & self.ccs[Flags.Z])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.ADD, ALU8Func.ADC):
                no_carry = (self.func == ALU8Func.ADD)
                carry_in = Mux(no_carry, 0, self.ccs[Flags.C])

                sum0_3 = Cat(self.output[:4], carry4)
                m.d.comb += sum0_3.eq(self.input1[:4] + self.input2[:4] +
                                      carry_in)
                sum4_6 = Cat(self.output[4:7], carry7)
                m.d.comb += sum4_6.eq(self.input1[4:7] + self.input2[4:7] +
                                      carry4)
                sum7 = Cat(self.output[7], carry8)
                m.d.comb += sum7.eq(self.input1[7] + self.input2[7] + carry7)
                m.d.comb += overflow.eq(carry7 ^ carry8)

                m.d.comb += self._ccs[Flags.H].eq(carry4)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.V].eq(overflow)
                m.d.comb += self._ccs[Flags.C].eq(carry8)

            with m.Case(ALU8Func.SUB, ALU8Func.SBC, ALU8Func.CPXHI,
                        ALU8Func.CPXLO):
                carry_in = Mux(self.func != ALU8Func.SBC, 0, self.ccs[Flags.C])

                sum0_6 = Cat(self.output[:7], carry7)
                m.d.comb += sum0_6.eq(self.input1[:7] + ~self.input2[:7] +
                                      ~carry_in)
                sum7 = Cat(self.output[7], carry8)
                m.d.comb += sum7.eq(self.input1[7] + ~self.input2[7] + carry7)
                m.d.comb += overflow.eq(carry7 ^ carry8)

                with m.If(self.func != ALU8Func.CPXLO):
                    m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                    m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                    m.d.comb += self._ccs[Flags.V].eq(overflow)
                    with m.If(self.func != ALU8Func.CPXHI):
                        m.d.comb += self._ccs[Flags.C].eq(~carry8)
                with m.Else():
                    m.d.comb += self._ccs[Flags.Z].eq((self.output == 0)
                                                      & self.ccs[Flags.Z])

            with m.Case(ALU8Func.AND):
                m.d.comb += self.output.eq(self.input1 & self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.EOR):
                m.d.comb += self.output.eq(self.input1 ^ self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.ORA):
                m.d.comb += self.output.eq(self.input1 | self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.INC):
                m.d.comb += self.output.eq(self.input2 + 1)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(self.output == 0x80)

            with m.Case(ALU8Func.DEC):
                m.d.comb += self.output.eq(self.input2 - 1)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(self.output == 0x7F)

            with m.Case(ALU8Func.COM):
                m.d.comb += self.output.eq(0xFF ^ self.input2)
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.V].eq(0)
                m.d.comb += self._ccs[Flags.C].eq(1)

            with m.Case(ALU8Func.ROL):
                # IIIIIIIIC ->
                # COOOOOOOO
                m.d.comb += [
                    LCat(self._ccs[Flags.C],
                         self.output).eq(LCat(self.input2, self.ccs[Flags.C])),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.ROR):
                # CIIIIIIII ->
                # OOOOOOOOC
                m.d.comb += [
                    LCat(self.output, self._ccs[Flags.C]).eq(
                        LCat(self.ccs[Flags.C], self.input2)),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.ASL):
                # IIIIIIII0 ->
                # COOOOOOOO
                m.d.comb += [
                    LCat(self._ccs[Flags.C],
                         self.output).eq(LCat(self.input2, Const(0))),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.ASR):
                # 7IIIIIIII ->  ("7" is the repeat of input[7])
                # OOOOOOOOC
                m.d.comb += [
                    LCat(self.output, self._ccs[Flags.C]).eq(
                        LCat(self.input2[7], self.input2)),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.LSR):
                # 0IIIIIIII ->
                # OOOOOOOOC
                m.d.comb += [
                    LCat(self.output,
                         self._ccs[Flags.C]).eq(LCat(Const(0), self.input2)),
                    self._ccs[Flags.Z].eq(self.output == 0),
                    self._ccs[Flags.N].eq(self.output[7]),
                    self._ccs[Flags.V].eq(self._ccs[Flags.N]
                                          ^ self._ccs[Flags.C]),
                ]

            with m.Case(ALU8Func.CLC):
                m.d.comb += self._ccs[Flags.C].eq(0)

            with m.Case(ALU8Func.SEC):
                m.d.comb += self._ccs[Flags.C].eq(1)

            with m.Case(ALU8Func.CLV):
                m.d.comb += self._ccs[Flags.V].eq(0)

            with m.Case(ALU8Func.SEV):
                m.d.comb += self._ccs[Flags.V].eq(1)

            with m.Case(ALU8Func.CLI):
                m.d.comb += self._ccs[Flags.I].eq(0)

            with m.Case(ALU8Func.SEI):
                m.d.comb += self._ccs[Flags.I].eq(1)

            with m.Case(ALU8Func.CLZ):
                m.d.comb += self._ccs[Flags.Z].eq(0)

            with m.Case(ALU8Func.SEZ):
                m.d.comb += self._ccs[Flags.Z].eq(1)

            with m.Case(ALU8Func.TAP):
                m.d.comb += self._ccs.eq(self.input1 | 0b11000000)

            with m.Case(ALU8Func.TPA):
                m.d.comb += self.output.eq(self.ccs | 0b11000000)

            with m.Case(ALU8Func.SEF):
                m.d.comb += self._ccs.eq(self.input1 | 0b11000000)

            with m.Case(ALU8Func.DAA):
                adjust = Signal(8)
                low = self.input1[:4]
                high = self.input1[4:]
                low_ten_or_more = low >= 0xA
                high_ten_or_more = high >= 0xA

                with m.If(low_ten_or_more | self.ccs[Flags.H]):
                    m.d.comb += adjust[:4].eq(6)
                with m.If(high_ten_or_more
                          | self.ccs[Flags.C]
                          | (low_ten_or_more & (high == 9))):
                    m.d.comb += adjust[4:].eq(6)
                sum9 = LCat(carry8, self.output)

                m.d.comb += sum9.eq(self.input1 + adjust)
                m.d.comb += self._ccs[Flags.N].eq(self.output[7])
                m.d.comb += self._ccs[Flags.Z].eq(self.output == 0)
                m.d.comb += self._ccs[Flags.C].eq(carry8 | self.ccs[Flags.C])

            with m.Default():
                m.d.comb += self.output.eq(self.input1)

        return m
コード例 #22
0
 def execute(self, m: Module):
     """Execute the instruction in the instr register."""
     with m.Switch(self.instr):
         with m.Case("00000001"):  # NOP
             self.NOP(m)
         with m.Case("00000110"):  # TAP
             self.TAP(m)
         with m.Case("00000111"):  # TPA
             self.TPA(m)
         with m.Case("0000100-"):  # INX/DEX
             self.IN_DE_X(m)
         with m.Case("0000101-"):  # CLV, SEV
             self.CL_SE_V(m)
         with m.Case("0000110-"):  # CLC, SEC
             self.CL_SE_C(m)
         with m.Case("0000111-"):  # CLI, SEI
             self.CL_SE_I(m)
         with m.Case("0010----"):  # Branch instructions
             self.BR(m)
         with m.Case("01--0000"):  # NEG
             self.ALU2(m, ALU8Func.SUB, 0, 1)
         with m.Case("01--0011"):  # COM
             self.ALU2(m, ALU8Func.COM, 0, 1)
         with m.Case("01--0100"):  # LSR
             self.ALU2(m, ALU8Func.LSR, 0, 1)
         with m.Case("01--0110"):  # ROR
             self.ALU2(m, ALU8Func.ROR, 0, 1)
         with m.Case("01--0111"):  # ASR
             self.ALU2(m, ALU8Func.ASR, 0, 1)
         with m.Case("01--1000"):  # ASL
             self.ALU2(m, ALU8Func.ASL, 0, 1)
         with m.Case("01--1001"):  # ROL
             self.ALU2(m, ALU8Func.ROL, 0, 1)
         with m.Case("01--1010"):  # DEC
             self.ALU2(m, ALU8Func.DEC, 0, 1)
         with m.Case("01--1100"):  # INC
             self.ALU2(m, ALU8Func.INC, 0, 1)
         with m.Case("01--1101"):  # TST
             self.ALU2(m, ALU8Func.SUB, 1, 0, store=False)
         with m.Case("011-1110"):  # JMP
             self.JMP(m)
         with m.Case("01--1111"):  # CLR
             self.ALU2(m, ALU8Func.SUB, 1, 1)
         with m.Case("1---0110"):  # LDA
             self.ALU(m, ALU8Func.LD)
         with m.Case("1---0000"):  # SUB
             self.ALU(m, ALU8Func.SUB)
         with m.Case("1---0001"):  # CMP
             self.ALU(m, ALU8Func.SUB, store=False)
         with m.Case("1---0010"):  # SBC
             self.ALU(m, ALU8Func.SBC)
         with m.Case("1---0100"):  # AND
             self.ALU(m, ALU8Func.AND)
         with m.Case("1---0101"):  # BIT
             self.ALU(m, ALU8Func.AND, store=False)
         with m.Case("1--10111", "1-100111"):  # STA
             self.STA(m)
         with m.Case("1---1000"):  # EOR
             self.ALU(m, ALU8Func.EOR)
         with m.Case("1---1001"):  # ADC
             self.ALU(m, ALU8Func.ADC)
         with m.Case("1---1010"):  # ORA
             self.ALU(m, ALU8Func.ORA)
         with m.Case("1---1011"):  # ADD
             self.ALU(m, ALU8Func.ADD)
         with m.Default():  # Illegal
             self.end_instr(m, self.pc)
コード例 #23
0
ファイル: alu_card.py プロジェクト: EngRaff92/riscv-reboot
    def elaborate(self, _: Platform) -> Module:
        """Implements the logic of the ALU card."""
        m = Module()

        output_buffer = TransparentLatch(size=32)

        m.submodules += output_buffer
        m.d.comb += output_buffer.le.eq(1)
        m.d.comb += output_buffer.data_in.eq(0)
        m.d.comb += self.data_z.eq(output_buffer.data_out)

        m.d.comb += self.alu_eq.eq(0)
        m.d.comb += self.alu_lt.eq(0)
        m.d.comb += self.alu_ltu.eq(0)

        x = self.data_x
        y = self.data_y

        m.d.comb += self.alu_eq.eq(output_buffer.data_in == 0)
        m.d.comb += self.alu_ltu.eq(x < y)
        m.d.comb += self.alu_lt.eq(x.as_signed() < y.as_signed())

        with m.Switch(self.alu_op):
            with m.Case(AluOp.ADD):
                m.d.comb += output_buffer.data_in.eq(x + y)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Case(AluOp.SUB):
                m.d.comb += output_buffer.data_in.eq(x - y)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Case(AluOp.SLTU):
                m.d.comb += output_buffer.data_in.eq(self.alu_ltu)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Case(AluOp.SLT):
                m.d.comb += output_buffer.data_in.eq(self.alu_lt)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Case(AluOp.AND):
                m.d.comb += output_buffer.data_in.eq(x & y)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Case(AluOp.AND_NOT):
                m.d.comb += output_buffer.data_in.eq(x & ~y)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Case(AluOp.OR):
                m.d.comb += output_buffer.data_in.eq(x | y)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Case(AluOp.XOR):
                m.d.comb += output_buffer.data_in.eq(x ^ y)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Case(AluOp.X):
                m.d.comb += output_buffer.data_in.eq(x)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Case(AluOp.Y):
                m.d.comb += output_buffer.data_in.eq(y)
                m.d.comb += output_buffer.n_oe.eq(0)

            with m.Default():
                m.d.comb += output_buffer.n_oe.eq(1)

        return m
コード例 #24
0
    def elaborate(self, platform):
        m = Module()

        cpu = Core()
        m.submodules += cpu
        m.domains.ph1 = ph1 = ClockDomain("ph1")
        m.domains.ph2 = ph2 = ClockDomain("ph2", clk_edge="neg")

        # Hook up clocks and reset to pins

        if not SLOWCLK:
            clk1 = platform.request("clk1")
            clk2 = platform.request("clk2")
            rst = platform.request("rst")
            m.d.comb += [
                ph1.rst.eq(rst.i),
                ph2.rst.eq(rst.i),
                ph1.clk.eq(clk1.i),
                ph2.clk.eq(clk2.i),
            ]

        if SLOWCLK:
            clk_freq = platform.default_clk_frequency
            timer = Signal(range(0, int(clk_freq // 2)),
                           reset=int(clk_freq // 2) - 1)
            tick = Signal()
            sync = ClockDomain()

            with m.If(timer == 0):
                m.d.sync += timer.eq(timer.reset)
                m.d.sync += tick.eq(~tick)
            with m.Else():
                m.d.sync += timer.eq(timer - 1)
            m.d.comb += [
                ph1.rst.eq(sync.rst),
                ph2.rst.eq(sync.rst),
                ph1.clk.eq(tick),
                ph2.clk.eq(~tick),
            ]

        # Hook up address lines to pins
        for i in range(16):
            pin = platform.request("addr", i)
            m.d.comb += pin.o.eq(cpu.Addr[i])

        if not FAKEMEM:
            # Hook up data in/out + direction to pins
            for i in range(8):
                pin = platform.request("data", i)
                m.d.comb += pin.o.eq(cpu.Dout[i])
                m.d.ph2 += cpu.Din[i].eq(pin.i)
                m.d.comb += pin.oe.eq(~cpu.RW)

        if FAKEMEM:
            with m.Switch(cpu.Addr):
                for addr, data in mem.items():
                    with m.Case(addr):
                        m.d.comb += cpu.Din.eq(data)
                with m.Default():
                    m.d.comb += cpu.Din.eq(0xFF)
            for i in range(8):
                pin = platform.request("led", i)
                m.d.comb += pin.o.eq(cpu.Addr[i])

        for i in range(2):
            pin = platform.request("reset_state", i)
            m.d.comb += pin.o.eq(cpu.reset_state[i])

        rw = platform.request("rw")
        m.d.comb += rw.o.eq(cpu.RW)

        return m
コード例 #25
0
ファイル: exception.py プロジェクト: ImArcangel/Bellatrix
    def elaborate(self, platform):
        m = Module()

        # constants (at least, the important ones)
        if self.configuration.getOption('isa', 'enable_extra_csr'):
            misa = 0x1 << 30 | (1 << (ord('i') - ord('a'))
                                )  # 32-bits processor. RV32IM
            if self.configuration.getOption('isa', 'enable_rv32m'):
                misa |= 1 << (ord('m') - ord('a'))  # RV32M

            m.d.sync += [
                self.csr.misa.read.eq(misa),
                self.csr.mhartid.read.eq(
                    0),  # ID 0 FOREVER. TODO: make this read only
                self.csr.mimpid.read.eq(0),  # No implemented = 0
                self.csr.marchid.read.eq(0),  # No implemented = 0
                self.csr.mvendorid.read.eq(0)  # No implemented = 0
            ]
        m.d.sync += self.csr.mstatus.read.mpp.eq(0b11)  # Only machine mode

        traps = m.submodules.traps = PriorityEncoder(16)
        m.d.comb += [
            traps.i[ExceptionCause.E_INST_ADDR_MISALIGNED].eq(
                self.m_fetch_misalign),
            traps.i[ExceptionCause.E_INST_ACCESS_FAULT].eq(self.m_fetch_error),
            traps.i[ExceptionCause.E_ILLEGAL_INST].eq(self.m_illegal),
            traps.i[ExceptionCause.E_BREAKPOINT].eq(self.m_ebreak),
            traps.i[ExceptionCause.E_LOAD_ADDR_MISALIGNED].eq(
                self.m_load_misalign),
            traps.i[ExceptionCause.E_LOAD_ACCESS_FAULT].eq(self.m_load_error),
            traps.i[ExceptionCause.E_STORE_AMO_ADDR_MISALIGNED].eq(
                self.m_store_misalign),
            traps.i[ExceptionCause.E_STORE_AMO_ACCESS_FAULT].eq(
                self.m_store_error),
            traps.i[ExceptionCause.E_ECALL_FROM_M].eq(self.m_ecall)
        ]

        interrupts = m.submodules.interrupts = PriorityEncoder(16)
        m.d.comb += [
            interrupts.i[ExceptionCause.I_M_SOFTWARE].eq(
                self.csr.mip.read.msip & self.csr.mie.read.msie),
            interrupts.i[ExceptionCause.I_M_TIMER].eq(
                self.csr.mip.read.mtip & self.csr.mie.read.mtie),
            interrupts.i[ExceptionCause.I_M_EXTERNAL].eq(
                self.csr.mip.read.meip & self.csr.mie.read.meie),
        ]

        m.d.sync += [
            self.csr.mip.read.msip.eq(self.software_interrupt),
            self.csr.mip.read.mtip.eq(self.timer_interrupt),
            self.csr.mip.read.meip.eq(self.external_interrupt)
        ]

        # generate the exception/trap/interrupt signal to kill the pipeline
        m.d.comb += self.m_exception.eq(~traps.n | (
            ~interrupts.n & self.csr.mstatus.read.mie & ~self.m_store))

        # default behavior for all registers.
        for reg in self.csr.csr_list:
            with m.If(reg.we):
                m.d.sync += reg.read.eq(reg.write)

        # behavior for exception handling
        with m.If(self.m_valid):
            with m.If(self.m_exception):
                # Register the exception and move one priviledge mode down.
                # No other priviledge mode, so stay in 'machine' mode
                m.d.sync += [
                    self.csr.mepc.read.base.eq(self.m_pc[2:]),
                    self.csr.mstatus.read.mpie.eq(self.csr.mstatus.read.mie),
                    self.csr.mstatus.read.mie.eq(0)
                ]
                # store cause/mtval
                with m.If(~traps.n):
                    m.d.sync += [
                        self.csr.mcause.read.ecode.eq(traps.o),
                        self.csr.mcause.read.interrupt.eq(0)
                    ]
                    with m.Switch(traps.o):
                        with m.Case(ExceptionCause.E_INST_ADDR_MISALIGNED):
                            m.d.sync += self.csr.mtval.read.eq(
                                self.m_pc_misalign)
                        with m.Case(ExceptionCause.E_INST_ACCESS_FAULT):
                            m.d.sync += self.csr.mtval.read.eq(
                                self.m_fetch_badaddr)
                        with m.Case(ExceptionCause.E_ILLEGAL_INST):
                            m.d.sync += self.csr.mtval.read.eq(
                                self.m_instruction)
                        with m.Case(ExceptionCause.E_BREAKPOINT):
                            m.d.sync += self.csr.mtval.read.eq(self.m_pc)
                        with m.Case(
                                ExceptionCause.E_LOAD_ADDR_MISALIGNED,
                                ExceptionCause.E_STORE_AMO_ADDR_MISALIGNED):
                            m.d.sync += self.csr.mtval.read.eq(
                                self.m_ls_misalign)
                        with m.Case(ExceptionCause.E_LOAD_ACCESS_FAULT,
                                    ExceptionCause.E_STORE_AMO_ACCESS_FAULT):
                            m.d.sync += self.csr.mtval.read.eq(
                                self.m_load_store_badaddr)
                        with m.Default():
                            m.d.sync += self.csr.mtval.read.eq(0)

                with m.Else():
                    m.d.sync += [
                        self.csr.mcause.read.ecode.eq(interrupts.o),
                        self.csr.mcause.read.interrupt.eq(1)
                    ]
            with m.Elif(self.m_mret):
                # restore old mie
                # No other priviledge mode, so nothing more to do
                m.d.sync += self.csr.mstatus.read.mie.eq(
                    self.csr.mstatus.read.mpie)

        # counters
        if self.configuration.getOption('isa', 'enable_extra_csr'):
            mcycle = Signal(64)
            minstret = Signal(64)

            m.d.sync += [
                self.csr.mcycle.read.eq(mcycle[:32]),
                self.csr.mcycleh.read.eq(mcycle[32:64]),
                #
                self.csr.minstret.read.eq(minstret[:32]),
                self.csr.minstreth.read.eq(minstret[32:64])
            ]
            m.d.comb += mcycle.eq(
                Cat(self.csr.mcycle.read, self.csr.mcycleh.read) + 1)
            with m.If(self.w_retire):
                m.d.comb += minstret.eq(
                    Cat(self.csr.minstret.read, self.csr.minstreth.read) + 1)
            with m.Else():
                m.d.comb += minstret.eq(
                    Cat(self.csr.minstret.read, self.csr.minstreth.read))

        return m
コード例 #26
0
    def elaborate(self, platform: Platform) -> Module:
        m = Module()

        # Set MTVEC to the RESET address, to avoid getting lost in limbo if there's an exception
        # before the boot code sets this to a valid value
        self.mtvec.read.base.reset = self.core_reset_address >> 2

        privmode = Signal(PrivMode)
        privmode.reset = PrivMode.Machine  # default mode is Machine

        m.d.comb += self.m_privmode.eq(privmode)

        # Read/write behavior for all registers
        for reg in self.get_csrs():
            with m.If(reg.we):
                m.d.sync += reg.read.eq(reg.write)

        # constants (at least, the important ones)
        if self.enable_extra_csr:
            misa = 0x1 << 30 | (1 << (ord('i') - ord('a'))
                                )  # 32-bits processor. RV32I
            if self.enable_rv32m:
                misa |= 1 << (ord('m') - ord('a'))  # RV32M
            if self.enable_user_mode:
                misa |= 1 << (ord('u') - ord('a'))  # User mode enabled

            m.d.sync += [
                self.misa.read.eq(misa),
                self.mhartid.read.eq(0),  # ID 0 FOREVER.
                self.mimpid.read.eq(0),  # No implemented = 0
                self.marchid.read.eq(0),  # No implemented = 0
                self.mvendorid.read.eq(0)  # No implemented = 0
            ]

        traps = m.submodules.traps = PriorityEncoder(ExceptionCause.MAX_NUM)
        m.d.comb += [
            traps.i[ExceptionCause.E_INST_ADDR_MISALIGNED].eq(
                self.m_fetch_misalign),
            traps.i[ExceptionCause.E_INST_ACCESS_FAULT].eq(self.m_fetch_error),
            traps.i[ExceptionCause.E_ILLEGAL_INST].eq(self.m_illegal),
            traps.i[ExceptionCause.E_BREAKPOINT].eq(self.m_ebreak),
            traps.i[ExceptionCause.E_LOAD_ADDR_MISALIGNED].eq(
                self.m_load_misalign),
            traps.i[ExceptionCause.E_LOAD_ACCESS_FAULT].eq(self.m_load_error),
            traps.i[ExceptionCause.E_STORE_AMO_ADDR_MISALIGNED].eq(
                self.m_store_misalign),
            traps.i[ExceptionCause.E_STORE_AMO_ACCESS_FAULT].eq(
                self.m_store_error),
            traps.i[ExceptionCause.E_ECALL_FROM_M].eq(self.m_ecall)
        ]

        interrupts = m.submodules.interrupts = PriorityEncoder(
            ExceptionCause.MAX_NUM)
        m.d.comb += [
            interrupts.i[ExceptionCause.I_M_SOFTWARE].eq(self.mip.read.msip
                                                         & self.mie.read.msie),
            interrupts.i[ExceptionCause.I_M_TIMER].eq(self.mip.read.mtip
                                                      & self.mie.read.mtie),
            interrupts.i[ExceptionCause.I_M_EXTERNAL].eq(self.mip.read.meip
                                                         & self.mie.read.meie),
        ]

        # generate the exception/trap/interrupt signal to kill the pipeline
        # interrupts are globally enable for less priviledge mode than Machine
        m.d.comb += self.m_exception.eq(~traps.n | (
            ~interrupts.n & (self.mstatus.read.mie |
                             (privmode != PrivMode.Machine)) & ~self.m_store))

        # --------------------------------------------------------------------------------
        # overwrite values from the RW circuit
        # --------------------------------------------------------------------------------
        m.d.sync += [
            self.mip.read.msip.eq(self.software_interrupt),
            self.mip.read.mtip.eq(self.timer_interrupt),
            self.mip.read.meip.eq(self.external_interrupt)
        ]

        if self.enable_user_mode:
            self.mstatus.read.mpp.reset = PrivMode.User
            with m.If(self.mstatus.write.mpp != PrivMode.User):
                # In case of writting an invalid priviledge mode, force a valid one
                # For this case, anything different to the User mode is forced to Machine mode.
                m.d.sync += self.mstatus.read.mpp.eq(PrivMode.Machine)
        else:
            self.mstatus.read.mpp.reset = PrivMode.Machine
            m.d.sync += self.mstatus.read.mpp.eq(
                PrivMode.Machine)  # Only machine mode

        # Constant fields in MSTATUS
        # Disable because S-mode and User-level interrupts
        # are not supported.
        m.d.sync += [
            self.mstatus.read.uie.eq(0),
            self.mstatus.read.upie.eq(0),
            self.mstatus.read.sie.eq(0),
            self.mstatus.read.spie.eq(0),
            self.mstatus.read.spp.eq(0),
            self.mstatus.read.mxr.eq(0),
            self.mstatus.read.sum.eq(0),
            self.mstatus.read.tvm.eq(0),
            self.mstatus.read.tsr.eq(0),
            self.mstatus.read.fs.eq(0),
            self.mstatus.read.xs.eq(0),
            self.mstatus.read.sd.eq(0)
        ]
        # MIP and MIE
        m.d.sync += [
            self.mip.read.usip.eq(0),
            self.mip.read.ssip.eq(0),
            self.mip.read.utip.eq(0),
            self.mip.read.stip.eq(0),
            self.mip.read.ueip.eq(0),
            self.mip.read.seip.eq(0),
            self.mie.read.usie.eq(0),
            self.mie.read.ssie.eq(0),
            self.mie.read.utie.eq(0),
            self.mie.read.stie.eq(0),
            self.mie.read.ueie.eq(0),
            self.mie.read.seie.eq(0)
        ]

        # behavior for exception handling
        with m.If(self.m_valid):
            with m.If(self.m_exception):
                # Register the exception and move one priviledge mode down.
                m.d.sync += [
                    self.mepc.read.base.eq(self.m_pc[2:]),
                    self.mstatus.read.mpie.eq(self.mstatus.read.mie),
                    self.mstatus.read.mie.eq(0),

                    # Change priviledge mode
                    privmode.eq(PrivMode.Machine),
                    self.mstatus.read.mpp.eq(privmode)
                ]
                # store cause/mtval
                with m.If(~traps.n):
                    m.d.sync += [
                        self.mcause.read.ecode.eq(traps.o),
                        self.mcause.read.interrupt.eq(0)
                    ]
                    with m.Switch(traps.o):
                        with m.Case(ExceptionCause.E_INST_ADDR_MISALIGNED):
                            m.d.sync += self.mtval.read.eq(self.m_pc_misalign)
                        with m.Case(ExceptionCause.E_INST_ACCESS_FAULT):
                            m.d.sync += self.mtval.read.eq(
                                self.m_fetch_badaddr)
                        with m.Case(ExceptionCause.E_ILLEGAL_INST):
                            m.d.sync += self.mtval.read.eq(self.m_instruction)
                        with m.Case(ExceptionCause.E_BREAKPOINT):
                            m.d.sync += self.mtval.read.eq(self.m_pc)
                        with m.Case(
                                ExceptionCause.E_LOAD_ADDR_MISALIGNED,
                                ExceptionCause.E_STORE_AMO_ADDR_MISALIGNED):
                            m.d.sync += self.mtval.read.eq(self.m_ls_misalign)
                        with m.Case(ExceptionCause.E_LOAD_ACCESS_FAULT,
                                    ExceptionCause.E_STORE_AMO_ACCESS_FAULT):
                            m.d.sync += self.mtval.read.eq(
                                self.m_load_store_badaddr)
                        with m.Default():
                            m.d.sync += self.mtval.read.eq(0)

                with m.Else():
                    m.d.sync += [
                        self.mcause.read.ecode.eq(interrupts.o),
                        self.mcause.read.interrupt.eq(1)
                    ]
            with m.Elif(self.m_mret):
                # restore old mie
                # Restore priviledge mode
                m.d.sync += [
                    self.mstatus.read.mie.eq(self.mstatus.read.mpie),
                    privmode.eq(self.mstatus.read.mpp),
                ]
                if self.enable_user_mode:
                    m.d.sync += self.mstatus.read.mpp.eq(PrivMode.User)

        # counters
        if self.enable_extra_csr:
            mcycle = Signal(64)
            minstret = Signal(64)

            m.d.sync += [
                self.mcycle.read.eq(mcycle[:32]),
                self.mcycleh.read.eq(mcycle[32:64]),
                #
                self.minstret.read.eq(minstret[:32]),
                self.minstreth.read.eq(minstret[32:64])
            ]

            m.d.comb += mcycle.eq(Cat(self.mcycle.read, self.mcycleh.read) + 1)
            with m.If(self.w_retire):
                m.d.comb += minstret.eq(
                    Cat(self.minstret.read, self.minstreth.read) + 1)
            with m.Else():
                m.d.comb += minstret.eq(
                    Cat(self.minstret.read, self.minstreth.read))

            # shadow versions of MCYCLE and MINSTRET
            if self.enable_user_mode:
                m.d.sync += [
                    self.cycle.read.eq(mcycle[:32]),
                    self.cycleh.read.eq(mcycle[32:64]),
                    #
                    self.instret.read.eq(minstret[:32]),
                    self.instreth.read.eq(minstret[32:64])
                ]

        return m
コード例 #27
0
    def elaborate(self, platform):
        m = Module()

        cpu = Core()
        m.submodules += cpu
        m.domains.ph1 = ph1 = ClockDomain("ph1")
        m.domains.ph2 = ph2 = ClockDomain("ph2", clk_edge="neg")

        # Hook up clocks and reset to pins

        if not SLOWCLK:
            clk1 = platform.request("clk1")
            clk2 = platform.request("clk2")
            rst = platform.request("rst")
            m.d.comb += [
                ph1.rst.eq(rst.i),
                ph2.rst.eq(rst.i),
                ph1.clk.eq(clk1.i),
                ph2.clk.eq(clk2.i),
            ]

        if SLOWCLK:
            clk_freq = platform.default_clk_frequency
            timer = Signal(range(0, int(clk_freq // 2)),
                           reset=int(clk_freq // 2) - 1)
            tick = Signal()
            sync = ClockDomain()

            with m.If(timer == 0):
                m.d.sync += timer.eq(timer.reset)
                m.d.sync += tick.eq(~tick)
            with m.Else():
                m.d.sync += timer.eq(timer - 1)
            m.d.comb += [
                ph1.rst.eq(sync.rst),
                ph2.rst.eq(sync.rst),
                ph1.clk.eq(tick),
                ph2.clk.eq(~tick),
            ]

        # Hook up address lines to pins
        addr = []
        for i in range(16):
            pin = platform.request("addr", i)
            m.d.comb += pin.o.eq(cpu.Addr[i])
            addr.append(pin)

        data = []
        if not FAKEMEM:
            # Hook up data in/out + direction to pins
            for i in range(8):
                pin = platform.request("data", i)
                m.d.comb += pin.o.eq(cpu.Dout[i])
                m.d.ph2 += cpu.Din[i].eq(pin.i)
                data.append(pin)

        if FAKEMEM:
            with m.Switch(cpu.Addr):
                for a, d in mem.items():
                    with m.Case(a):
                        m.d.comb += cpu.Din.eq(d)
                with m.Default():
                    m.d.comb += cpu.Din.eq(0x00)
            for i in range(8):
                pin = platform.request("led", i)
                m.d.comb += pin.o.eq(cpu.Addr[i])

        rw = platform.request("rw")
        m.d.comb += rw.o.eq(cpu.RW)

        nIRQ = platform.request("n_irq")
        nNMI = platform.request("n_nmi")
        m.d.ph2 += cpu.IRQ.eq(~nIRQ)
        m.d.ph2 += cpu.NMI.eq(~nNMI)

        ba = platform.request("ba")
        m.d.comb += ba.o.eq(cpu.BA)
        m.d.comb += rw.oe.eq(~cpu.BA)
        for i in range(len(addr)):
            m.d.comb += addr[i].oe.eq(~cpu.BA)
        for i in range(len(data)):
            m.d.comb += data[i].oe.eq(~cpu.BA & ~cpu.RW)

        return m
コード例 #28
0
ファイル: reg_card.py プロジェクト: EngRaff92/riscv-reboot
    def formal(cls) -> Tuple[Module, List[Signal]]:
        """Formal verification for the register card."""
        m = Module()

        ph1 = ClockDomain("ph1")
        ph2 = ClockDomain("ph2")
        regs = RegCard()

        m.domains += [ph1, ph2]
        m.submodules += regs

        # Generate the ph1 and ph2 clocks.
        cycle_count = Signal(8, reset=0, reset_less=True)
        phase_count = Signal(3, reset=0, reset_less=True)

        m.d.sync += phase_count.eq(phase_count + 1)
        with m.Switch(phase_count):
            with m.Case(0, 1, 2):
                m.d.comb += ph1.clk.eq(1)
            with m.Default():
                m.d.comb += ph1.clk.eq(0)
        with m.Switch(phase_count):
            with m.Case(1, 4):
                m.d.comb += ph2.clk.eq(0)
            with m.Default():
                m.d.comb += ph2.clk.eq(1)
        with m.If(phase_count == 5):
            m.d.sync += phase_count.eq(0)
            m.d.sync += cycle_count.eq(cycle_count + 1)

        # This is how we expect to use the card.
        with m.If(phase_count > 0):
            m.d.comb += [
                Assume(Stable(regs.reg_x)),
                Assume(Stable(regs.reg_y)),
                Assume(Stable(regs.reg_z)),
                Assume(Stable(regs.reg_page)),
                Assume(Stable(regs.reg_to_x)),
                Assume(Stable(regs.reg_to_y)),
                Assume(Stable(regs.data_z)),
            ]

        # Figure out how to get to the point where X and Y are nonzero and different.
        m.d.comb += Cover((regs.data_x != 0) & (regs.data_y != 0)
                          & (regs.data_x != regs.data_y))

        # X and Y buses should not change during a cycle, except for the first phase
        with m.Switch(phase_count):
            with m.Case(2, 3, 4, 5):
                with m.If(regs.data_x != 0):
                    m.d.comb += Assert(Stable(regs.data_x))
                with m.If(regs.data_y != 0):
                    m.d.comb += Assert(Stable(regs.data_y))

        # X and Y buses should be zero if there is no data transfer.
        with m.If(regs.reg_to_x == 0):
            m.d.comb += Assert(regs.data_x == 0)
        with m.If(regs.reg_to_y == 0):
            m.d.comb += Assert(regs.data_y == 0)

        with m.If(phase_count > 0):
            # X and Y buses should be zero if we read from register 0.
            with m.If(regs.reg_to_x & (regs.reg_x == 0)):
                m.d.comb += Assert(regs.data_x == 0)
            with m.If(regs.reg_to_y & (regs.reg_y == 0)):
                m.d.comb += Assert(regs.data_y == 0)

        write_pulse = Signal()
        m.d.comb += write_pulse.eq(phase_count != 4)

        # On write, the data should have been written to both banks.
        past_mem_addr = Signal(6)
        m.d.comb += past_mem_addr[:5].eq(Past(regs.reg_z))
        m.d.comb += past_mem_addr[5].eq(Past(regs.reg_page))
        past_z = Past(regs.data_z)
        with m.If(Rose(write_pulse)):
            m.d.comb += Assert(regs._x_bank._mem[past_mem_addr] == past_z)
            m.d.comb += Assert(regs._y_bank._mem[past_mem_addr] == past_z)

        # Pick an register, any register, except 0. We assert that unless
        # it is written, its data will not change.

        check_addr = AnyConst(5)
        check_page = AnyConst(1)
        saved_data = Signal(32)
        stored_x_data = Signal(32)
        stored_y_data = Signal(32)

        write_pulse_domain = ClockDomain("write_pulse_domain", local=True)
        m.domains.write_pulse_domain = write_pulse_domain
        write_pulse_domain.clk = write_pulse

        mem_addr = Signal(6)

        m.d.comb += Assume(check_addr != 0)
        m.d.comb += [
            mem_addr[:5].eq(check_addr),
            mem_addr[5].eq(check_page),
            stored_x_data.eq(regs._x_bank._mem[mem_addr]),
            stored_y_data.eq(regs._y_bank._mem[mem_addr]),
        ]

        with m.If((regs.reg_z == check_addr) & (regs.reg_page == check_page)):
            m.d.write_pulse_domain += saved_data.eq(regs.data_z)

        with m.If(Initial()):
            m.d.comb += Assume(saved_data == stored_x_data)
            m.d.comb += Assume(stored_x_data == stored_y_data)
        with m.Else():
            m.d.comb += Assert(saved_data == stored_x_data)
            m.d.comb += Assert(saved_data == stored_y_data)

        return m, [regs.data_z, regs.reg_to_x, regs.reg_to_y,
                   regs.reg_x, regs.reg_y, regs.reg_z, regs.reg_page, ph1.clk, ph2.clk, saved_data,
                   stored_x_data, stored_y_data]
コード例 #29
0
ファイル: shift_card.py プロジェクト: EngRaff92/riscv-reboot
    def elaborate(self, _: Platform) -> Module:
        """Implements the logic of the shifter card."""
        m = Module()

        input_reverse = _ConditionalReverser(width=32)
        shift1 = _ConditionalShiftRight(width=32, N=1)
        shift2 = _ConditionalShiftRight(width=32, N=2)
        shift4 = _ConditionalShiftRight(width=32, N=4)
        shift8 = _ConditionalShiftRight(width=32, N=8)
        shift16 = _ConditionalShiftRight(width=32, N=16)
        output_reverse = _ConditionalReverser(width=32)
        output_buffer = TransparentLatch(size=32)

        m.submodules += [
            input_reverse, shift1, shift2, shift4, shift8, shift16,
            output_reverse, output_buffer
        ]

        # Hook up inputs and outputs

        m.d.comb += [
            input_reverse.data_in.eq(self.data_x),
            shift1.data_in.eq(input_reverse.data_out),
            shift2.data_in.eq(shift1.data_out),
            shift4.data_in.eq(shift2.data_out),
            shift8.data_in.eq(shift4.data_out),
            shift16.data_in.eq(shift8.data_out),
            output_reverse.data_in.eq(shift16.data_out),
            output_buffer.data_in.eq(output_reverse.data_out),
            self.data_z.eq(output_buffer.data_out),
        ]

        # Some flags
        shift_arith = Signal()
        shift_left = Signal()

        m.d.comb += shift_arith.eq(self.alu_op == AluOp.SRA)
        m.d.comb += shift_left.eq(self.alu_op == AluOp.SLL)

        m.d.comb += [
            input_reverse.en.eq(shift_left),
            output_reverse.en.eq(shift_left),
            shift1.arithmetic.eq(shift_arith),
            shift2.arithmetic.eq(shift_arith),
            shift4.arithmetic.eq(shift_arith),
            shift8.arithmetic.eq(shift_arith),
            shift16.arithmetic.eq(shift_arith),
        ]

        # Shift amount
        shamt = self.data_y[:5]

        m.d.comb += [
            shift1.en.eq(shamt[0]),
            shift2.en.eq(shamt[1]),
            shift4.en.eq(shamt[2]),
            shift8.en.eq(shamt[3]),
            shift16.en.eq(shamt[4]),
        ]

        m.d.comb += output_buffer.le.eq(1)
        m.d.comb += output_buffer.n_oe.eq(1)

        with m.Switch(self.alu_op):
            with m.Case(AluOp.SLL, AluOp.SRL, AluOp.SRA):
                m.d.comb += output_buffer.n_oe.eq(0)
            with m.Default():
                m.d.comb += output_buffer.n_oe.eq(1)

        return m