0
votes

I am writing a mips32 5-stage pipeline cpu by verilog, but I don't know how to handle exception and soft interrupt. I have read several mips32 handbooks, but I still have some questions.

  1. When the status register exl bit is 1 and a new exception occurs, do I still need to handle this exception? And if I have to do it, should I update the cp0 registers such as epc, status, cause and badvaddr?
  2. Dose eret instruction need to clear the exl bit of cp0 status register?
  3. I saw "synchronous exception" and "asynchronous interrupt" in the handbook. What does the synchronous and asynchronous mean?
  4. How to deal with soft interrupts is more appropriate? My cpu has 5 stages: Ifetch, Decode, Exe, Mem, Wb, should I always detect the cp0 status register to determine when to handle the soft interrupt? Thanks!
1

1 Answers

1
votes

Your question is too wide that it cannot be responded in just one comment. From what I see you need to revise fundamentals in computer architecture so I would recommend you to read The Bible A.K.A. Computer Architecture - A quantitative approach (Hennessy & Patterson). Anyway, although there are many things involved, this is a summary regarding your problem:

Exceptions can be classified by Synchronous and Asynchronous;

  • Synchronous Exceptions are the ones generated by the program code, as a result of executing a given instruction, and they must be handled IN ORDER. Therefore, you can blame an instruction for generating that exception. Depending on how the system is built, it can handle the exception, and recover normal execution. This type of exceptions includes TLB misses, traps, bad instructions...
  • Asynchronous Exceptions are not the product of the current executing program and therefore, there is no instruction to blame so the system can decide when to handle such an exception. A clear example of this type of exceptions are interrupts. They can be handled out of order.

Bottomline is that Synchronous exceptions must be handle whenever they occur, and the following instructions must be discarded and re-executed (if possible). However, asynchronous exceptions can be handled by the system whenever it is convenient for it, e.g. an interrupt is pendant and there is a Cache miss, then the cpu can decide that it is a good moment to serve the interrupt.

Now regarding your problem, you need to decide when the instruction is visible and your State is updated. Ofc you have 5 stages, and the usual thing is that the instruction is visible at WB stage handling the exception at that point IFF the instruction at WB has caused an exception. However you cannot just react at that stage, since you have 4 more instructions in your pipeline that must be invalidated. Also at the moment the instruction causes the exception, it needs to be invalidated as well (Memory is also architectural state so it cannot be modified if there is an exception).

You can choose the mechanism for invalidation that you prefer, maybe one additional bit as control info through your pipeline helps :P, but it is up to you. As to when to handle the interrupts it is your decision as well, you can wait, you can directly serve it... That is what makes the difference between implementations.

The execution flow in your CPU when an exception occurs should be the following: In causes an exception at stage m, instructions previous to In in time, therefore stages m+1... must be completed, instructions following In in time and In, therefore stages m and m-1... must be invalidated and there must NOT be any architectural change product of those instructions. When In becomes visible, your logic must modify the control registers so that the context is saved, the PC points to the service subroutine that will handle the exception, and the rest of the control registers contains info about the exception. It is important to note that if there is already an exception in the pipeline there won't be any more to take into account, since you need to serve the exceptions in order, so the first one will invalidate any following exception.

After handling the exception (the subroutine presumably will be provided by OS) it will execute the eret instruction, which will restore the previous context, clear the exception bit, and execution will resume safely. Note that depending on the exception, the execution will resume with the instruction that caused that exception (e.g. TLB miss) or the program will be terminated (e.g. Bad instruction).

As I said at the beginning, there are more things to take into account but I hope this clears a bit your problem. There are concepts such as context, virtual memory, etc... that I cannot explain just here so please refer to the book I mentioned because it is a really good one. Everything is explained there, and it will help you a lot :)