Example #1
0
    def test_conditional_instructions_incorrect_prediction_no_commit(self):
        """Test that Conditional Instructions with incorrect predicate do not commit."""
        # Initialize units.
        root = FlushableLog()
        rs = FeedLog()
        lsq = FeedLog()
        rob = ReorderBuffer(self.rf, rs, lsq, capacity=32)
        rob.set_pipeline_flush_root(root)
        rob.WIDTH = 4
        self.rf['r4'] = 0
        self.rf['r5'] = 10

        # Initialize instructions to be fed.
        cond = Blth('r4', 'r5', 100)
        cond.branch_info = BranchInfo(False, 100, 1, None)
        cond.DELAY = 0
        add = AddI('r1', 'r1', 1)
        add.DELAY = 0

        # Feed pairs of (cond, add) instructions.
        n_pairs = 5
        for i in range(n_pairs):
            rob.feed(cond)
            rob.feed(add)
        rob.tick()  # Insert into current queue.

        # Receive result for each pair in turn.
        for i in range(0, n_pairs, 2):
            rob.receive(Result(rs.log[i].tag, True))
            rob.receive(Result(rs.log[i + 1].tag, 0))
            rob.tick()
            self.assertEqual(self.rf['r1'], 0)
        self.assertEqual(self.rf['pc'], 100)
Example #2
0
    def test_conditional_instructions_correct_prediction_commit(self):
        """Test Conditional Instructions with correct predicate commit OK."""
        # Initialize units.
        rs = FeedLog()
        lsq = FeedLog()
        rob = ReorderBuffer(self.rf, rs, lsq, capacity=32)
        rob.WIDTH = 4
        self.rf['r4'] = 0
        self.rf['r5'] = 0

        # Initialize instructions to be fed.
        cond = Blth('r4', 'r5', 2)
        cond.branch_info = BranchInfo(False, 2, 2, None)
        cond.DELAY = 0
        add = AddI('r1', 'r1', 1)
        add.DELAY = 0

        # Feed pairs of (cond, add) instructions.
        n_pairs = 5
        for i in range(n_pairs):
            rob.feed(cond)
            rob.feed(add)
        rob.tick()  # Insert into current queue.

        # Receive result for each pair in turn.
        r1_value = 0
        for i in range(0, n_pairs, 2):
            rob.receive(Result(rs.log[i].tag, False))
            rob.receive(Result(rs.log[i + 1].tag, r1_value))
            rob.tick()
            self.assertEqual(self.rf['r1'], r1_value)
            r1_value += 1
Example #3
0
    def test_saturating_counter(self):
        """Test that the internal counter saturates."""
        blth_str = 'blth r1 r2 100'
        exp_info = BranchInfo(False, 100, 1, 0)

        for n_prediction_bits in [1, 2, 4, 16]:
            bht = BranchHistoryTable(1, n_prediction_bits)

            # Set counter to strongly not taken. More than req. to catch underflow.
            for _ in range((2**n_prediction_bits) * 3):
                bht.receive(0, False)

            for _ in range(2**(n_prediction_bits - 1)):
                branch_info = bht.predict(0, blth_str)
                self.assertEqual(
                    branch_info,
                    exp_info,
                    msg='BHT should take 2**(n - 1) receives to predict taken')
                bht.receive(0, True)

            branch_info = bht.predict(0, blth_str)
            exp_info.taken = True
            self.assertEqual(
                branch_info,
                exp_info,
                msg='BHT should predict taken after 2**(n - 1) receives')

            # Set counter to strongly taken. More than req. to catch overflow.
            for _ in range((2**n_prediction_bits) * 3):
                bht.receive(0, True)

            for _ in range(2**(n_prediction_bits - 1)):
                branch_info = bht.predict(0, blth_str)
                self.assertEqual(
                    branch_info,
                    exp_info,
                    msg=
                    'BHT should take 2**(n - 1) receives to predict not taken')
                bht.receive(0, False)

            branch_info = bht.predict(0, blth_str)
            exp_info.taken = False
            self.assertEqual(
                branch_info,
                exp_info,
                msg='BHT should predict taken after 2**(n - 1) receives')
Example #4
0
    def predict(self, program_counter, instruction_str):
        blth = self._parse_conditional(instruction_str)

        counter = self.history_table[program_counter % self.n_entries]
        taken = counter >= 2**(self.n_prediction_bits - 1)

        return BranchInfo(taken, blth.imm, program_counter + 1,
                          program_counter)
Example #5
0
    def test_weak_taken_initialization(self):
        """Ensure BHT entries are initialized to weak taken."""
        n_entries = 128
        blth_str = 'blth r1 r2 100'

        for n_prediction_bits in [1, 2, 4, 16]:
            bht = BranchHistoryTable(n_entries, n_prediction_bits)

            for pc in range(n_entries):
                # Weakly taken, predict taken.
                branch_info = bht.predict(pc, blth_str)
                self.assertEqual(branch_info,
                                 BranchInfo(True, 100, pc + 1, pc))
                # Receive not taken so now weakly not taken, predict not taken.
                bht.receive(pc, False)
                branch_info = bht.predict(pc, blth_str)
                self.assertEqual(branch_info,
                                 BranchInfo(False, 100, pc + 1, pc))
Example #6
0
    def test_never_taken(self):
        predictor = AlwaysTaken()

        for _ in range(100):
            pc = random.randint(1, 1000)
            imm = random.randint(1, 1000)
            blth = Blth('r1', 'r2', imm)
            self.assertEqual(predictor.predict(pc, str(blth)),
                             BranchInfo(True, imm, pc + 1, pc))
    def test_never_taken(self):
        predictor = BackTakenForwardNot()

        for _ in range(100):
            pc = random.randint(1, 1000)
            imm = random.randint(1, 1000)
            blth = Blth('r1', 'r2', imm)
            self.assertEqual(predictor.predict(pc, str(blth)),
                             BranchInfo(imm < pc, imm, pc + 1, pc))
Example #8
0
    def test_conditional_branch_tag(self):
        ins = Blth('r1', 'r2', 10)
        ins_str = str(ins)

        fetch = Fetch(self.reg_file,
                      [ins_str],
                      self.feed_log,
                      self.branch_predictor)
        fetch.tick()

        exp_ins = {'instruction_str': ins_str,
                   'branch_info': BranchInfo(False, 10, 1, 0)}

        self.assertDictEqual(self.feed_log.log[0], exp_ins)
Example #9
0
    def setUp(self):
        self.feed_log = FeedLog()
        # ReorderBuffer full method takes a param. Modify FeedLog to ignore it.
        self.feed_log._full = self.feed_log.full
        self.feed_log.full = lambda x: self.feed_log._full()

        self.test_strs = [('add r1 r2 r3', ins.Add('r1', 'r2', 'r3')),
                          ('addi r1 r2 5', ins.AddI('r1', 'r2', 5)),
                          ('sub rd r0 r9', ins.Sub('rd', 'r0', 'r9')),
                          ('subi r1 r2 10', ins.SubI('r1', 'r2', 10)),
                          ('ldr r0 r1', ins.Load('r0', 'r1')),
                          ('str r99 r100', ins.Store('r99', 'r100')),
                          ('j 1000', ins.Jump(1000)),
                          ('blth r1 r2 10', ins.Blth('r1', 'r2', 10))]
        self.test_strs = [({'instruction_str': ins_str}, exp_ins)
                          for (ins_str, exp_ins) in self.test_strs]
        self.test_strs[7][0]['branch_info'] = BranchInfo(False, 10, 9, 8)
Example #10
0
 def predict(self, program_counter, instruction_str):
     blth = self._parse_conditional(instruction_str)
     return BranchInfo(True, blth.imm, program_counter + 1, program_counter)