Unfortunately I am still behind schedule as I invested my time this week to analyse the flow of handling branches in AEMB. I had to do this because while I understand the big picture behind the new threading model, I still can’t see the details of it.

Now that I wish to observe the inner workings of the processor pipeline, hand drawn circuits are no longer sufficient. It’s is more helpful to analyse the processor by running the demo program through it. I got the tool chain from my supervisor fully compiled and ready to be used. All I needed to do was add it to my system $PATH variable. I copied the tools into this directory: $HOME/bin

From now on I will use this directory to contain all programs that I obtain pre compiled.

Then I edited the file called .profile which resides at my HOME folder to add all directories named bin to my $PATH variable.

Here is the change:


# set PATH so it includes user's private bin if it exists
if [ -d "$HOME/bin" ] ; then
        for d in ~/bin/*/bin; do
          PATH="$PATH:$d"
        done
fi

After that you need to run the .profile file using the source command.

In the ISA, There are 24 conditional branch instructions. There are 6 possible conditions to be checked. Further more, each branch instruction has a pair that allows a delay slot to be inserted after it. Those branches evaluate ra for a certain condition and if it is correct a branch is taken.  The branch target is calculated by adding an offset to the PC. The offset can be the contents of rb or the sign extension of an immediate.

In addition, there are 12 instructions for unconditional branching. Half of these instruction define the branch target through an immediate value and the other half through the contents of rb. There exists three options for these instructions. The branch could have a delay slot following it. The address could be calculated through an offset or by using an absolute value straight away and finally the current PC can be stored in rd.

Let’s see how does AEMB handle those two kinds of branches through the following waveform.

GTKWave output

Ich_dat carries the instruction to the decoding unit. The branch instrcution to be analysed can be observed with the op-code of 56 (octal) and the whole instruction is 0xB8080050.  This is the branch instruction at the reset vector. It is a BRAI, Branch Absolute Immediate. Thus this instruction will branch to the absolute value specified by an immediate in it, which is 0x50 in this case.

bra_ex[0] & bra_ex[1] are the key signals that control branching in AEMB. They are both generated by the branching condition checker unit (BRCC). bra_ex[1] is set when a branch is to be taken. Thus it is always set for unconditional branches. In the case of conditional branches, BRCC evaluates the condition then sets bra_ex[1] if it is true. bra_ex[0] is set when there is a delay slot following the branch.

When there is a branch to be taken with out a delay slot, the hzd_bpc is set and a NOP is inserted into the pipeline. This is the case for our BRAI. The NOP can be seen in the mux_of taking the value of 000.

The reason why instructions in the waveform are taking several clock cycles is because of cache misses. When an instruction address is ready, the instruction is looked up in the cache. If it’s a miss, it is fetched from the instruction memory. Accessing the instruction memory consumes two more cycles. Once the instruction is fetched, dena and iena are set and the pipeline runs again.

As for the address of the branch target, once a branch is decided to be taken (bra_ex[1] is set) the PC obtains it’s value from the ALU unit where the branch target is calculated instead of being incremented.

This sums it up for branching in AEMB. If you are up for more exploration you could analyse the break and return instructions as your homework. This is enough to understand every single detail about program flow in AEMB.