This is an implementation of a Mips processor. The features are quite limited right now, but thats enough for execution of kernel + debugging.
The reference design is as follow, but can be changed as needed.
The only constraints for pcie_mips_driver to work correctly is:
- XDMA is used with channel 1 (C2H & H2C) available
- MSI interrupt used
- Debug interface of the processor accessible through BAR1 at offset 0 (which means it needs to be accessible through DMA Bypass, not lite)
The vivado project for the reference design is available as a tcl file in vivado/MIPS_core_vivado.tcl.
To use it open a vivado tcl console, then write
cd MIPS_core/vivado
source MIPS_core_vivado.tcl
This will automatically generate the project files.
Note that this reference project is configured for a KC705 board, so modifications might be necessary to make it run on other hardware. But that's a good starting point.
- Mips32 instruction set
- 250Mhz (XC7K325T)
- Breakpoint with instruction SDBBP1 (pause the processor and triggers interrupt to notify the driver)
- SC and LL instruction2
The SDBBP instruction is normally part of the Mips EJTAG specification, but using jtag with xilinx is only available through vivado commandline, which is problematic. Instead of making a new instruction I reused that one. When the processor run into it, gonna trigger a MSI interrupt and put itself in pause. This allows to debug pretty much anything, even interrupt service routines.
Mips doesn't have interlocked instructions. Instead it uses SC and LL. LL loads a value from memory, and marks it's address for the next SC instruction. The next SC instruction store a value and will only succeed if:
- the address matches the previous LL address
- no other memory address was accessed by the processor between LL and SC
- no other processor/peripheral accessed that memory location between LL and SC
The implementation of SC and LL makes use of AXI4 exclusive access which provides equivalent functionalities. That means it can be used for synchronization with other peripherals by using memory.
A lot of things are not supported currently.
Here is a non exhaustive list:
- Exception/Interrupt vectors
- Kernel transition/syscalls
- Floating point
- MMU
- Cache
Those registers are accessible through the AXI lite interface on the processor
Address | Description |
---|---|
00000000 | Processor state (0x1: Enable, 0x2: Break pending) |
00000004 | LEDS (only 1st byte) |
00000008 - 0000007C | unused |
00000080 - 000000FC | Processor registers, only accessible if enable is 0. PC is mapped on register 0 |
00000100 - 0000017C | COP0 registers |
instruction_test_generate.py generates an asm file containing instructions with randomized operands. This is then compiled with clang and used to create a test data file.
core_test.tcl runs in simulation to read that data file and send the instructions to the processor core, then compares the result with the expected values.
Just run the following commands from the MIPS_core/core/test/ directory
python instruction_test_generate.py
vivado -mode batch -source core_test.tcl
Test | Version | Cycle count | Performance count | Instruction per second | Clock frequency |
---|---|---|---|---|---|
mips_project_test over 10s, no cache | 751259be... 64b995f9... | 1 000 000 704 | 42 512 991 | 4 251 296 | 100Mhz |