Desc: when an interrupt occurs, the control saves the return address onto the stack and jumps to the ISR. after executing the ISR, the RTI instruction is executed to return to normal mode of execution, where the stack is popped off to load the return address into the PC
bug: the PC is not loaded with the return address but loaded with 0x0000 when RTI or RTS instructions are used.
Solution: make the following changes into 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 the flags
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';
I have mailed you a detailed document reporting the bug and solution along with the waveforms for your convenience. Thanks Abishek Ramdas
The Open8 implementation assumes that RAM and register files take two cycles to return valid data. The RAM model used returns data in a single cycle.