I have been working on this project intermittently for a while, but recently I began working on it more frequently. Currently the processor supports most of the MIPS r-type instructions as well as several branch and jump instructions. The memory is word aligned, so there is no support for loading and storing bytes and halfwords. When I first started designing it, I figured it would be a pain to implement control circuitry to insert bubbles in the pipeline in the case of hazards, so I decided to use branch prediction and forwarding. Boy was I wrong. The forwarding circuitry took a fair amount of debugging, and both forwarding and branch prediction seem to limit Logisim's ability to run the clock at high speeds; the clock runs at ~250Hz when executing code and at ~1.2kHz when executing no-ops. Long story short, I have learned a lot with this project and I will likely be using this core to further my understanding of computer science.
Code that tests the branch prediction (only backwards); right click on ROM labeled "program" in logisim, select load image, and choose this file to run the program.
To change value that code counts to, change the lower two bytes of the first instruction to the desired value.
As I was running some test code, I discovered that stale register data was being used to execute the jump register instruction. The fix for this was simple; I added a "new $s" signal from the forwarding registers to the branch correction. In addition, I also tidied up and simplified the branch correction.
Old Branch Correction
New Branch Correction
This simplified design is not only easier to understand, but it is also faster because there is no longer a chain of multiplexers that the "PCNext" signal has to propagate through.