Sunday, April 17, 2011

Modification of OPEN8 core to interface with the Memory

The open8 core is to be modified to interface with the memory. The modification is described here.
Description : There is an implementation change to the open8 core so as to interface it with the memory provided with us. The implementation change is for instructions RTI (return from interrupt) and RTS(return from subroutine).

1. The interrupt occurs
2. There are 3 bytes that are stored in the stack The PSR and the 16 bit memory return address. They are stored in memory locations 127, 126, 125. This is with accordance with the Instruction set guide.
3. After stack operations is done, it  jumps to the ISR. ISR is pointed to location pointed to in memory by 129,128 as specified in the Assembly language reference manual.
4. In the ISR, it continues to execute code and when I use the RTI instruction, the control does not resume execution from where it left off. Instead it starts executing form location 0.
5. When RTI is executed, the stack operands are all popped out from the stack and available at the inputs but the controller does not read the data


You can see the interrupt signal going high when the CPU is executing at address 150 (decimal). The execution is completed and the next address 151(16 bits) is written into the stack along with the Program status register. Appropriately the stack pointer is loaded into the PC and corresponding write signals are generated to write the return address into the memory. The PC branches to ISR (indicated by address 771 in address line). The controller then starts executing code from that position till it encounters the RTI instruction (indicated by opcode 186 in the rd_data line). As you can see the stack is popped off to read the values.

But after the values are popped, the PC is supposed to load the return address (151 in our case) into the program counter but instead it loads 0 into the PC and starts executing from there.

This because of a delay the interrupt pipeline in reading the return data after it is popped.

It is to be seen in the waveform that when rd_data line has the return address (151 in our case) the cache_ctrl is idle. The cache_ctrl becomes cache_oper1 only after the next data from the stack is read (which is a 0 in our case). This causes the PC to be set to 0 (16 bits). This can be avoided by making the following changes in the code
  when RTS_C1 =>
        CPU_Next_State   <= RTS_C2;
        AS_Ctrl.Src      <= ADDR_SP;
        SP_Ctrl.Oper     <= SP_POP;

   when RTS_C2 =>
        CPU_Next_State   <= RTS_C3;
        AS_Ctrl.Src      <= ADDR_SP;
        -- Abishek start
        Cache_Ctrl       <= CACHE_OPER1; --line added
        -- Abishek end
        -- if this is an RTI, then we need to POP theflags                                                                                                
        if( SubOp = SOP_RTI )then
          SP_Ctrl.Oper   <= SP_POP;
        end if;

    when RTS_C3 =>
        CPU_Next_State   <= RTS_C4;
        -- Abishek start
        Cache_Ctrl       <= CACHE_OPER2;   --line added
        -- Cache_Ctrl     <= CACHE_OPER1; --original line
        -- Abishek end
        -- It doesn't really matter what is on the address bus for RTS, while
        -- it does for RTI, so we make this the default
        AS_Ctrl.Src          <= ADDR_SP;

    when RTS_C4 =>
        CPU_Next_State       <= RTS_C5;
        --Abishek start
        PC_Ctrl.Oper         <= PC_LOAD;   --these lines are added
        PC_Ctrl.Addr         <= Operand2 & Operand1;
        Cache_Ctrl           <= CACHE_OPER2;
        --Abishek end

    when RTS_C5 =>
        CPU_Next_State       <= PIPE_FILL_0;
        --Abishek start
        --PC_Ctrl.Oper         <= PC_LOAD; --these lines are commented
        --PC_Ctrl.Addr         <= Operand2 & Operand1;
        --Abishek end
        if( SubOp = SOP_RTI )then
          CPU_Next_State     <= RTI_C6;
          Cache_Ctrl         <= CACHE_OPER1;
        end if;

    when RTI_C6 =>
        CPU_Next_State       <= PIPE_FILL_1;
        PC_Ctrl.Oper         <= PC_INCR;
        ALU_Ctrl.Oper        <= ALU_RFLG;
        ALU_Ctrl.Data        <= Operand1;
        PC_Ctrl.Oper         <= PC_INCR;
        Int_RTI_D            <= '1';

After the modification, you can see that the RTI opcode (186) is executed, the return address (151) is read from the stack and loaded into the PC and the PC starts executing from 151 onwards.

No comments:

Post a Comment