Close

Plan for Supporting CSRs

A project log for Kestrel Computer Project

The Kestrel project is all about freedom of computing and the freedom of learning using a completely open hardware and software design.

samuel-a-falvo-iiSamuel A. Falvo II 10/03/2016 at 17:510 Comments

I'm currently planning on not providing any built-in CSRs to the Polaris core. At all. Rather, I'm planning on providing access to CSRs via an external bus. This allows Polaris to focus exclusively on its core competency (instruction execution).

The CSR bus would look something like this sketch:

I envision the CSRs will be clocked using the same clock as the Polaris core. Except in the case of CSRRW, one cannot read and write to the CSR in the same clock cycle. So, the Polaris core will need to spread CSR access out over several cycles.

Trap Vectors and Other Configuration Settings

When Polaris gains the capacity for interrupts, how will the value of mtvec be communicated, since mtvec sits in a CSR? In all likelihood, I'll just provide configuration ports on Polaris (e.g., MTVEC_I[63:2]), to which the CSRs feed back into, and which must be valid when any ERR_I or IRQ_I signal is asserted. So, altering mtvec will simply alter a bunch of bits that drive these configuration ports.

Privilege Levels

How will I handle privilege levels going forward? In all likelihood, I won't. Polaris doesn't appear to have or need any privilege-sensitive instructions, and none are currently defined in RV64G as far as I can tell (note that RV64IS is a proper subset of RV64G). Thus, privilege enforcement can be off-loaded to logic external from the Polaris core itself.

In exchange, Polaris core does need to expose control signals which will help outside logic deal with possible privilege-sensitive semantics. For example, the FENCE and FENCE.I instructions both assert a FENCE_O signal on the bus. When a trap occurs (e.g., illegal instruction), TRAP_O asserts, letting external logic know that a transition to machine-mode is required, etc.

This technique is not unproven; prior art exists. The 68010 CPU was built to handle architectural enhancements of this nature. And, of course, the 65816 CPU also provides similar capabilities, allowing one to start with an ultra-basic expanded 6502-like CPU, and to that you can bolt on virtual memory (thanks to the ABORT# signal), different privilege modes (thanks to VP# to indicate when a system call [BRK or COP] or interrupt is being processed), etc. IP built around the 65816 core can provide distinctly non-6502-like semantics; for example the 65265 microcontroller provides a lot more than your standard RESET, IRQ, and NMI interrupt vectors.

Summary

My plans for Polaris might change given the current implementation's flexibility. If this CSR interface works out as I envision, I might dive even further in this direction. Polaris might have a future as a modular RISC-V core, which stands in stark isolation from all the other "kitchen-sink included" cores I see on Github, where configuration is handled with Verilog "`define" settings instead of through module composition.

Discussions