Github render test
This commit is contained in:
parent
f32d674616
commit
3b635be2dc
5 changed files with 31 additions and 194 deletions
|
@ -4,8 +4,6 @@ This is the coursework for the graded part of the TDT4255 course at NTNU.
|
||||||
|
|
||||||
* Instructions
|
* Instructions
|
||||||
|
|
||||||
#+ATTR_HTML: title="Join the chat at https://gitter.im/RISCV-FiveStage/community"
|
|
||||||
[[https://gitter.im/RISCV-FiveStage/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge][file:https://badges.gitter.im/RISCV-FiveStage/community.svg]]
|
|
||||||
To get started with designing your 5-stage RISC-V pipeline you should follow the
|
To get started with designing your 5-stage RISC-V pipeline you should follow the
|
||||||
[[./exercise.org][Exercise instructions]]
|
[[./exercise.org][Exercise instructions]]
|
||||||
|
|
||||||
|
|
193
exercise.org
193
exercise.org
|
@ -1,185 +1,24 @@
|
||||||
* Exercise description
|
* Getting started
|
||||||
The task in this exercise is to implement a 5-stage pipelined processor for
|
In order to make a correct design in a somewhat expedient fashion you need to be
|
||||||
the [[./instructions.org][RISCV32I instruction set]].
|
*methodical!*
|
||||||
|
|
||||||
For exercise 1 you will build a 5-stage processor which handles one instruction
|
This means you should have a good idea of how your processor should work *before*
|
||||||
at a time, whereas in exercise 2 your design will handle multiple instructions
|
you start writing code. While chisel is more pleasent to work with than other HDLs
|
||||||
at a time.
|
the [[https://i.imgur.com/6IpVNA7.jpg][bricoleur]] approach is not recommended.
|
||||||
This is done by inserting 4 NOP instructions inbetween each source instruction,
|
|
||||||
enabling us to use the same tests and harness for both exercise 1 and 2.
|
|
||||||
|
|
||||||
Once you are done with exercise 1, you can up the difficulty by setting nopPad
|
My recommended approach is therefore to create an RTL sketch of your processor design.
|
||||||
to false and start reading the [[exercise2.org][ex2 guide]].
|
Start with an overall sketch showing all the components, then drill down.
|
||||||
|
In your sketch you will eventually add a box for registers, IMEM and DMEM, which
|
||||||
|
should make it clear how the already finished modules fit into the grander design,
|
||||||
|
making the skeleton-code less mysterious.
|
||||||
|
|
||||||
In the project skeleton files ([[./src/main/scala/][Found here]]) you can see that a lot of code has
|
To give you an idea of how a drill down looks like, here is my sketch of the ID stage:
|
||||||
already been provided, which can make it difficult to get started.
|
#+CAPTION: Instruction decode stage, showing the various signals.
|
||||||
Hopefully this document can help clear up at least some of the confusion.
|
#+attr_html: :width 1000px
|
||||||
First an overview of what you are designing is presented, followed by a walk-through
|
#+attr_latex: :width 1000px
|
||||||
for getting the most basic instructions to work.
|
|
||||||
|
|
||||||
In order to orient yourself you first need a map, thus a high level overview of the
|
|
||||||
processor you're going to design is showed underneath:
|
|
||||||
Keep in mind that this is just a high level sketch, omitting many details as well
|
|
||||||
entire features (for instance branch logic)
|
|
||||||
|
|
||||||
*Important*
|
|
||||||
When you are done, use the provided ./deliver.sh script to pack up the archive.
|
|
||||||
If you're unable to run bash scripts then please ensure that you deliver a *zip* archive.
|
|
||||||
Not .rar or anything else, just use zip because my grading script knows how to handle that
|
|
||||||
in addition to the one used by deliver.sh
|
|
||||||
named after your username. Nothing more, nothing less, just your username.
|
|
||||||
This archive should be runnable as is, thus you need to include all the necessary files.
|
|
||||||
(I may or may not diff the tests to check if you're screwing with them)
|
|
||||||
|
|
||||||
#+CAPTION: A very high level processor schematic. Registers, Instruction and data memory are already implemented.
|
|
||||||
[[./Images/FiveStage.png]]
|
|
||||||
|
|
||||||
Now that you have an idea of what you're building it is time to take inventory of
|
|
||||||
the files included in the skeleton, and what, if anything should be added.
|
|
||||||
|
|
||||||
+ [[./src/main/scala/Tile.scala]]
|
|
||||||
This is the top level module for the system as a whole. This is where the test
|
|
||||||
harness accessses your design, providing the necessary IO.
|
|
||||||
*You should not modify this module for other purposes than debugging.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/CPU.scala]]
|
|
||||||
This is the top level module for your processor.
|
|
||||||
In this module the various stages and barriers that make up your processor
|
|
||||||
should be declared and wired together.
|
|
||||||
Some of these modules have already been declared in order to wire up the
|
|
||||||
debugging logic for your test harness.
|
|
||||||
This file corresponds to the high-level overview in its entirety.
|
|
||||||
*This module is intended to be further fleshed out by you.*
|
|
||||||
As you work with this module, try keeping logic to a minimum to help readability.
|
|
||||||
If you end up with a lot of signal select logic, consider moving that to a separate
|
|
||||||
module.
|
|
||||||
|
|
||||||
+ [[./src/main/scala/IF.scala]]
|
|
||||||
This is the instruction fetch stage.
|
|
||||||
In this stage instruction fetching should happen, meaning you will have to
|
|
||||||
add logic for handling branches, jumps, and for exercise 2, stalls.
|
|
||||||
The reason this module is already included is that it contains the instruction
|
|
||||||
memory, described next which is heavily coupled to the testing harness.
|
|
||||||
*This module is intended to be further fleshed out by you.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/IMem.scala]]
|
|
||||||
This module contains the instruction memory for your processor.
|
|
||||||
Upon testing the test harness loads your program into the instruction memory,
|
|
||||||
freeing you from the hassle.
|
|
||||||
*You should not modify this module for other purposes than maaaaybe debugging.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/ID.scala]]
|
|
||||||
The instruction decode stage.
|
|
||||||
The reason this module is included is that the registers reside here, thus
|
|
||||||
for the test harness to work it must be wired up to the register unit to
|
|
||||||
record its state updates.
|
|
||||||
*This module is intended to be further fleshed out by you.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/Registers.scala]]
|
|
||||||
Contains the registers for your processor. Note that the zero register is alredy
|
|
||||||
disabled, you do not need to do this yourself.
|
|
||||||
The test harness ensures that all register updates are recorded.
|
|
||||||
*You should not modify this module for other purposes than maaaaybe debugging.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/MEM.scala]]
|
|
||||||
Like ID and IF, the MEM skeleton module is included so that the test harness
|
|
||||||
can set up and monitor the data memory
|
|
||||||
*This module is intended to be further fleshed out by you.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/DMem.scala]]
|
|
||||||
Like the registers and Imem, the DMem is already implemented.
|
|
||||||
*You should not modify this module for other purposes than maaaaybe debugging.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/Const.scala]]
|
|
||||||
Contains helpful constants for decoding, used by the decoder which is provided.
|
|
||||||
*This module may be fleshed out further by you if you so choose.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/Decoder.scala]]
|
|
||||||
The decoder shows how to conveniently demux the instruction.
|
|
||||||
In the provided ID.scala file a decoder module has already been instantiated.
|
|
||||||
You should flesh it out further.
|
|
||||||
You may find it useful to alter this module, especially in exercise 2.
|
|
||||||
*This module should be further fleshed out by you.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/ToplevelSignals.scala]]
|
|
||||||
Contains helpful constants.
|
|
||||||
You should add your own constants here when you find the need for them.
|
|
||||||
You are not required to use it at all, but it is very helpful.
|
|
||||||
*This module can be further fleshed out by you.*
|
|
||||||
|
|
||||||
+ [[./src/main/scala/SetupSignals.scala]]
|
|
||||||
You should obviously not modify this file.
|
|
||||||
You may choose to create a similar file for debug signals, modeled on how
|
|
||||||
the test harness is built.
|
|
||||||
*You should not modify this module at all.*
|
|
||||||
|
|
||||||
|
|
||||||
** Tests
|
|
||||||
In addition to the skeleton files it's useful to take a look at how the tests work.
|
|
||||||
You will not need to alter anything here other than the [[./src/test/scala/Manifest.scala][test manifest]], but some
|
|
||||||
of these settings can be quite useful to alter.
|
|
||||||
The main attraction is the test options. By altering the verbosity settings you
|
|
||||||
may change what is output.
|
|
||||||
The settings are:
|
|
||||||
|
|
||||||
+ printIfSuccessful
|
|
||||||
Enables logging on tests that succeed.
|
|
||||||
You typically want this turned off, at least for the full test runner.
|
|
||||||
|
|
||||||
+ printErrors
|
|
||||||
Enables logging of errors. You obviously want this one on, at least on the single
|
|
||||||
test.
|
|
||||||
|
|
||||||
+ printParsedProgram
|
|
||||||
Prints the desugared program. Useful when the test asm contains instructions that
|
|
||||||
needs to be expanded or altered.
|
|
||||||
Unsure what "bnez" means? Turn this setting on and see!
|
|
||||||
|
|
||||||
+ printVMtrace
|
|
||||||
Enables printing of the VM trace, showing how the ideal machine executes a test
|
|
||||||
|
|
||||||
+ printVMfinal
|
|
||||||
Enables printing of the final VM state, showing how the registers look after
|
|
||||||
completion. Useful if you want to see what a program returns.
|
|
||||||
|
|
||||||
+ printMergedTrace
|
|
||||||
Enables printing of a merged trace. With this option enabled you get to see how
|
|
||||||
the VM and your processor executed the program side by side.
|
|
||||||
This setting is extremely helpful to track down where your program goes wrong!
|
|
||||||
This option attempts to synchronize the execution traces as best as it can, however
|
|
||||||
once your processor design derails this becomes impossible, leading to rather
|
|
||||||
nonsensical output.
|
|
||||||
Instructions that were only executed by either VM or Your design is colored red or
|
|
||||||
blue.
|
|
||||||
|
|
||||||
*IF YOU ARE COLOR BLIND YOU SHOULD ALTER THE DISPLAY COLORS!*
|
|
||||||
|
|
||||||
+ nopPadded
|
|
||||||
Set this to false when you're ready to enter the big-boy league
|
|
||||||
|
|
||||||
+ breakPoints
|
|
||||||
Not implemented. It's there as a teaser, urging you to implement it so I don't have to.
|
|
||||||
|
|
||||||
|
|
||||||
** Getting started
|
|
||||||
In order to make a correct design in a somewhat expedient fashion you need to be
|
|
||||||
*methodical!*
|
|
||||||
|
|
||||||
This means you should have a good idea of how your processor should work *before*
|
|
||||||
you start writing code. While chisel is more pleasent to work with than other HDLs
|
|
||||||
the [[https://i.imgur.com/6IpVNA7.jpg][bricoleur]] approach is not recommended.
|
|
||||||
|
|
||||||
My recommended approach is therefore to create an RTL sketch of your processor design.
|
|
||||||
Start with an overall sketch showing all the components, then drill down.
|
|
||||||
In your sketch you will eventually add a box for registers, IMEM and DMEM, which
|
|
||||||
should make it clear how the already finished modules fit into the grander design,
|
|
||||||
making the skeleton-code less mysterious.
|
|
||||||
|
|
||||||
To give you an idea of how a drill down looks like, here is my sketch of the ID stage:
|
|
||||||
#+CAPTION: Instruction decode stage, showing the various signals.
|
|
||||||
[[./Images/IDstage.png]]
|
[[./Images/IDstage.png]]
|
||||||
|
|
||||||
I would generally advice to do these on paper, but don't half-ass them.
|
I would generally advice to do these on paper, but don't half-ass them.
|
||||||
|
|
||||||
|
|
||||||
** Adding numbers
|
** Adding numbers
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
4.2. Register-Register Arithmetic Instructions
|
4.2. Register-Register Arithmetic Instructions
|
||||||
--------------------------------------------------------------------------
|
--------------------------------------------------------------------------
|
||||||
|
|
||||||
These do not render well on github, try using your text editor.
|
If these do not render well on github, try using your text editor.
|
||||||
|
|
||||||
* ADD
|
* ADD
|
||||||
|
|
||||||
|
|
|
@ -136,18 +136,18 @@ object TestRunner {
|
||||||
events match {
|
events match {
|
||||||
|
|
||||||
// Scala syntax for matching a list with a head element of some type and a tail
|
// Scala syntax for matching a list with a head element of some type and a tail
|
||||||
// `case h :: t =>`
|
// `case h :: t =>`
|
||||||
// means we want to match a list with at least a head and a tail (tail can be Nil, so we
|
// means we want to match a list with at least a head and a tail (tail can be Nil, so we
|
||||||
// essentially want to match a list with at least one element)
|
// essentially want to match a list with at least one element)
|
||||||
// h is the first element of the list, t is the remainder (which can be Nil, aka empty)
|
// h is the first element of the list, t is the remainder (which can be Nil, aka empty)
|
||||||
|
|
||||||
// `case Constructor(arg1, arg2) :: t => `
|
// `case Constructor(arg1, arg2) :: t => `
|
||||||
// means we want to match a list whose first element is of type Constructor, giving us access to its internal
|
// means we want to match a list whose first element is of type Constructor, giving us access to its internal
|
||||||
// values.
|
// values.
|
||||||
|
|
||||||
// `case Constructor(arg1, arg2) :: t => if(p(arg1, arg2))`
|
// `case Constructor(arg1, arg2) :: t => if(p(arg1, arg2))`
|
||||||
// means we want to match a list whose first element is of type Constructor while satisfying some predicate p,
|
// means we want to match a list whose first element is of type Constructor while satisfying some predicate p,
|
||||||
// called an if guard.
|
// called an if guard.
|
||||||
case Taken(from, to) :: t if( predictionTable(from)) => helper(t, predictionTable)
|
case Taken(from, to) :: t if( predictionTable(from)) => helper(t, predictionTable)
|
||||||
case Taken(from, to) :: t if(!predictionTable(from)) => 1 + helper(t, predictionTable.updated(from, true))
|
case Taken(from, to) :: t if(!predictionTable(from)) => 1 + helper(t, predictionTable.updated(from, true))
|
||||||
case NotTaken(addr) :: t if( predictionTable(addr)) => 1 + helper(t, predictionTable.updated(addr, false))
|
case NotTaken(addr) :: t if( predictionTable(addr)) => 1 + helper(t, predictionTable.updated(addr, false))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue