Ejemplo n.º 1
0
    def capture(self, m: Core, core: Core, past: int):
        comb = m.d.comb
        if past > 0:
            prefix = f"past{past}"
        else:
            prefix = "now"
        self.r = RegisterFile(core.xlen, prefix=prefix)
        for i in range(self.r.main_gpr_count()):
            comb += self.r[i].eq(Past(core.register_file.r[i], past))
        comb += self.r.pc.eq(Past(core.pc, past))

        # TODO: move to additional structure
        self.itype = IType(prefix=f"{prefix}_i")
        self.itype.elaborate(comb, Past(core.current_instruction, past))

        self.jtype = JType(prefix=f"{prefix}_j")
        self.jtype.elaborate(comb, Past(core.current_instruction, past))

        self.utype = UType(prefix=f"{prefix}_u")
        self.utype.elaborate(comb, Past(core.current_instruction, past))

        self.btype = BType(prefix=f"{prefix}_b")
        self.btype.elaborate(comb, Past(core.current_instruction, past))

        # TODO: membus
        self.input_ready = Signal.like(core.mem2core.ready,
                                       name=f"{prefix}_input_ready")
        self.input_data = Array([
            Signal(core.xlen, name=f"{prefix}_input_{i}")
            for i in range(core.look_ahead)
        ])

        self.cycle = Signal.like(core.cycle, name=f"{prefix}_cycle")
        comb += self.cycle.eq(Past(core.cycle, past))

        # TODO: move to structure
        self.mem2core_addr = Signal.like(core.mem2core.addr,
                                         name=f"{prefix}_mem2core_addr")
        self.mem2core_en = Signal.like(core.mem2core.en,
                                       name=f"{prefix}_mem2core_en")
        self.mem2core_seq = Signal.like(core.mem2core.seq,
                                        name=f"{prefix}_mem2core_seq")
        comb += self.mem2core_addr.eq(Past(core.mem2core.addr, past))
        comb += self.mem2core_en.eq(Past(core.mem2core.en, past))
        comb += self.mem2core_seq.eq(Past(core.mem2core.seq, past))
        comb += self.input_ready.eq(Past(core.mem2core.ready, past))
        comb += self.input_data[0].eq(Past(core.mem2core.value, past))
Ejemplo n.º 2
0
    def __init__(self,
                 clock,
                 look_ahead=1,
                 addr_length=32,
                 xlen=32,
                 include_enable=False,
                 include_debug_opcode=1):
        assert addr_length % 8 == 0, "address length must be octet aligned"
        assert xlen % 8 == 0, "register width must be octet aligned"

        assert look_ahead >= 1, "Core should see at least one full word ahead"
        self.look_ahead = look_ahead
        super().__init__()
        self.clock = clock

        # register width
        self.xlen = xlen
        # addr_length holds width of address bus
        self.addr_length = addr_length

        # add mem2core bus for reads
        self.mem2core = mem2core = MemoryBus(addr_length, xlen, "mem2core")
        self.add_existing_output_signal(mem2core.addr)
        self.add_existing_output_signal(mem2core.en)
        self.add_existing_output_signal(mem2core.seq)
        self.add_existing_input_signal(mem2core.ready)
        self.add_existing_input_signal(mem2core.value)

        # add core2mem bus for writes
        self.core2mem = core2mem = MemoryBus(addr_length, xlen, "core2mem")
        self.add_existing_output_signal(core2mem.addr)
        self.add_existing_output_signal(core2mem.en)
        self.add_existing_output_signal(core2mem.seq)
        self.add_existing_output_signal(core2mem.value)
        self.add_existing_input_signal(mem2core.ready)

        # instruction implementation contains actual implementation of instructions
        self.instructions: List[Instruction] = []

        # is enabled is an optional input pin that can pauses RISCV
        self.is_enabled = Signal(name="en") if include_enable else None
        # debug opcode is an optional output signal which shows what instruction was executed on last cycle
        self.debug_opcode = self.add_output_signal(
            DebugOpcode, name="dbg_op") if include_debug_opcode else None
        self.debug_value = self.add_output_signal(
            xlen, name="dbg_val") if include_debug_opcode else None

        self.iclk = None
        self.current_module: Module = None

        self.itype = IType("itype")
        self.utype = UType("utype")
        self.jtype = JType("jtype")
        self.btype = BType("btype")

        self.in_reset = Signal(reset=1)

        self.last_instruction = Signal(32)
        self.last_instruction_valid = Signal(
        )  #if true, continue execution from last_instruction, otherwise from input[0]
        self.current_instruction_valid = Signal()
        self.have_valid_instruction = Signal()
        self.current_instruction = Signal(32)

        self.cycle = Signal(4)
        self.next_pc = Signal(xlen)
        self.advance_pc = Signal()

        self.alu = ALU(self.xlen, "alu")
        self.left_shifter = Shifter(xlen, Shifter.LEFT, "SL")
        self.right_shifter = Shifter(xlen, Shifter.RIGHT, "SR")
        self.register_file = RegisterFileModule(xlen)

        self.pc = Signal(
            xlen, name="pc"
        )  #TODO: remove from register file? use additional signals in regfile?