Why does most CSR writes result in a pipeline flush?

There is a description in the document of “SiFive FU540-C000 Manual”:

Most CSR writes result in a pipeline flush with a five-cycle penalty.

So why does writing CSR result in a pipeline flush? What other CSR writes will not result in a pipeline flush? Why?

Thanks you.

Because they affect the interpretation of following instructions, so it’s important that instructions after the CSR write execute in that context. It’s not necessary with all, but a lot.

The alternative is to attach the contents of many CSRs to the data for each instruction as it passes through the pipeline, from the time the instruction was decoded.

This is actually done for the VTYPE information set by the VSETVL{I} instructions in the Vector extension, but it’s much too expensive to do it for all CSRs, especially when most are modified rarely.

Hello Bruce,
Thanks for your response. In the CSR module, there is the following sentence:

**io_dec.write_flush := !(io_dec.csr >= CSRs.mscratch && io_dec.csr <= CSRs.mtval || io_dec.csr >= CSRs.sscratch && io_dec.csr <= CSRs.stval)**

This statement seems to say that the operation of sscratch, sepc, scause, stval, mscratch,mepc, mcause and mtval registers will not result in a pipeline flush, and others will. Is my understanding correct? Why?
Thanks you.

Because those don’t affect the way other instructions execute. mscratch and sscratch aren’t used by anything at all. The others simply save a value for later use by MRET, SRET during their execute stage – it doesn’t change their interpretation.

Thanks for your response.

Thanks for your response.