def _generate_regsb(op, shift, funct):
     """
     REGSB <= '1' to select ra for data processing
     REGSB <= '0' to select ra for multiply and accumulate
     """
     return not (op == ISA.OpCodes.DATA_PROCESS.value
                 and ISA.is_multiply(funct, shift))
 def _generate_regsa(op, shift, funct):
     """
     REGSA <= '1' to select Rn (data processing instructions)
     REGSA <= '0' to select Rn (mul instruction)
     """
     return not (op == ISA.OpCodes.DATA_PROCESS.value
                 and ISA.is_multiply(funct, shift))
 def _generate_accen(op, funct, shift):
     """
     ACCEN <= '1' when accumulate set in multiply instruction (MLA)
     ACCEN <= '0' otherwise
     """
     if op == ISA.OpCodes.DATA_PROCESS.value and ISA.is_multiply(
             funct, shift):
         return ISA.parse_function_get_a(funct)
     else:
         return 0b0
 def _generate_regwrs(op, shift, funct):
     """
     REGWRS <= B"10" to select LR (bl instruction)
     REGWRS <= B"01" to select Rd (data processing instruction)
     REGWRS <= B"00" to select Rd (mul instruction)
     """
     if op == ISA.OpCodes.BRANCH.value and ISA.parse_function_get_l(
             funct, True):
         return 0b10
     elif op == ISA.OpCodes.DATA_PROCESS.value and ISA.is_multiply(
             funct, shift):
         return 0b00
     else:
         return 0b01
 def _generate_regdst(op, shift, funct):
     """
     REGDST <= B"10" to select Rd (str instruction)
     REGDST <= B"01" to select Rm (data processing intructions)
     REGDST <= B"00" to select Rm (mul instruction)
     """
     if op == ISA.OpCodes.MEMORY_SINGLE.value and not ISA.parse_function_get_l(
             funct):
         return 0b10
     elif op == ISA.OpCodes.DATA_PROCESS.value and ISA.is_multiply(
             funct, shift):
         return 0b00
     else:
         return 0b01
 def _generate_shctrl(op, funct, shift):
     """
     SHCTRL <= '00' diabled
     SHCTRL <= '01' enabled shift using constant for data processing instruction
     SHCTRL <= '10' diabled
     SHCTRL <= '11' enabled shift using register ra for data processing instruction
     """
     if op == ISA.OpCodes.DATA_PROCESS.value and not ISA.is_multiply(
             funct, shift):
         return (ISA.parse_shift_operand_get_roi(shift) << 1) | 1
     elif op == ISA.OpCodes.MEMORY_SINGLE.value and ISA.parse_function_get_i(
             funct):
         return (ISA.parse_shift_operand_get_roi(shift) << 1) | 1
     else:
         return 0b00
    def run(self, time=None):
        "Runs a timestep of controller, assert control signals on each"

        c = self._c.read()
        v = self._v.read()
        n = self._n.read()
        z = self._z.read()

        # parse instruction general
        instr = self._instr.read()
        conditionMet = ISA.condition_met(ISA.get_condition(instr), c, v, n, z)
        operation = ISA.get_opcode(instr)
        function = ISA.get_function(instr)
        shift = ISA.get_shift_operand(instr)
        rd = ISA.get_rd(instr, ISA.is_multiply(function, shift))

        self._pcsrc.write(self._generate_pcsrc(conditionMet, operation, rd))
        self._pcwr.write(self._generate_pcwr())
        self._regsa.write(self._generate_regsa(operation, shift, function))
        self._regdst.write(self._generate_regdst(operation, shift, function))
        self._regsb.write(self._generate_regsb(operation, shift, function))
        self._regwrs.write(self._generate_regwrs(operation, shift, function))
        self._regwr.write(
            self._generate_regwr(conditionMet, operation, function, rd))
        self._exts.write(self._generate_exts(operation, function))
        self._alusrcb.write(self._generate_alusrcb(operation, function))
        self._alus.write(self._generate_alus(operation, function, shift))
        self._shop.write(self._generate_shop(shift))
        self._shctrl.write(self._generate_shctrl(operation, function, shift))
        self._accen.write(self._generate_accen(operation, function, shift))
        self._aluflagwr.write(self._generate_aluflagwr(operation, function))
        self._memty.write(self._generate_memty(operation, function))
        self._memwr.write(
            self._generate_memwr(conditionMet, operation, function))
        self._regsrc.write(self._generate_regsrc(operation, function))
        self._wd3s.write(self._generate_wd3s(operation, function))
    def _generate_alus(op, funct, shift):
        """
        ALUS <= "0000" for A + B
        ALUS <= "0001" for A - B
        ALUS <= "0010" for A & B
        ALUS <= "0011" for A | B
        ALUS <= "0100" for A ^ B
        ALUS <= "0101" for A
        ALUS <= "0110" for B
        ALUS <= "0111" for A * B
        ALUS <= "1000" for A + B + Cin
        ALUS <= "1001" for A - B - Cin
        ALUS <= "1010" for B - A
        ALUS <= "1011" for B - A - Cin
        ALUS <= "1100" for A & ~ B
        ALUS <= "1101" for ~ B
        ALUS <= "1110" for 0
        ALUS <= "1111" for 1
        """
        if op == ISA.OpCodes.DATA_PROCESS.value:
            if ISA.is_multiply(funct, shift):
                return 0b0111

            cmd = ISA.parse_function_get_cmd(funct)
            if cmd == ISA.DataCMDCodes.AND.value:
                return 0b0010
            elif cmd == ISA.DataCMDCodes.EOR.value:
                return 0b0100
            elif cmd == ISA.DataCMDCodes.SUB.value:
                return 0b0001
            elif cmd == ISA.DataCMDCodes.RSB.value:
                return 0b1010
            elif cmd == ISA.DataCMDCodes.ADD.value:
                return 0b0000
            elif cmd == ISA.DataCMDCodes.ADC.value:
                return 0b1000
            elif cmd == ISA.DataCMDCodes.SBC.value:
                return 0b1001
            elif cmd == ISA.DataCMDCodes.RSC.value:
                return 0b1011
            elif cmd == ISA.DataCMDCodes.TST.value:
                return 0b0010
            elif cmd == ISA.DataCMDCodes.TEQ.value:
                return 0b0100
            elif cmd == ISA.DataCMDCodes.CMP.value:
                return 0b0001
            elif cmd == ISA.DataCMDCodes.CMN.value:
                return 0b0000
            elif cmd == ISA.DataCMDCodes.ORR.value:
                return 0b0011
            elif cmd == ISA.DataCMDCodes.MOV.value:
                return 0b0110
            elif cmd == ISA.DataCMDCodes.BIC.value:
                return 0b1100
            elif cmd == ISA.DataCMDCodes.MVN.value:
                return 0b1101
            else:
                return 0b1111
        elif op == ISA.OpCodes.MEMORY_SINGLE.value:
            if ISA.parse_function_get_p(funct):  # pre-index
                return 0b0000 if ISA.parse_function_get_u(funct) else 0b0001
            else:  # post-index not supported, just pass A
                return 0b0101
        else:
            return 0b1111