Practical 6 Single Cycle Processor 2
Objectives
This section is not a list of tasks for you to do. It is a list of skills you will have or things you will know after you complete the practical.
Following completion of this practical you should be able to:
- Add instructions to a single-cycle datapath drawing.
- Modify a medium-sized verilog project to have new functionality.
- Add jump and link functionality to a single cycle implementation of RISC-V
- Use waveform diagrams and verilog test benches to debug a processor implementation
- Reason about the implication of updating different registers on different clock edges.
Guidelines
- Because you will be iteratively adding functionality to one processor module, we strongly recommend that you periodically add and commit your progress to git as a backup.
Your Tasks
Follow this sequence of instructions to complete the practical.
This practical will all be done in your C-group
repository where you completed Practical 5.
1 Add lui
support
You will begin by adding the lui
(load upper immediate) instruction to your processor.
-
On the practical worksheet:
- Where indicated, write the RTL for LUI. Include all the RTL in common with other instructions, like
newPC <= PC + 4
. - Edit the datapath diagram on the practical worksheet to support your new RTL for
lui
.- You should not need to add any new components, but you will need to modify a mux (add an additional input port).
- Where indicated, write the RTL for LUI. Include all the RTL in common with other instructions, like
-
Implement Control
- Open up your
C-group
repo in VS Code (or your favorite text editor) - Edit
Control.v
to have an additional case forlui
(U_OPCODE
).- HINT: since you modified a mux, you may need to create a new control signal. Instead of making a single-bit control signal into a two-bit signal, we recommend creating a second signal and evaluating both signals when choosing an output for the mux. See the datapath section below for example usage of both signals on one mux.
- Open up your
-
Test Control
Once you've coded control for
lui
- In VS Code, open the
tb_Control.v
file and add a test forlui
. - Compile your files in ModelSim and run
tb_Control
to see if your test passes.
- In VS Code, open the
-
Implement the Datapath
-
Add
lui
to yourProcessor.v
datapath.- Most likely you will simply modify a mux to use your new control signal. Assumming you've got two signals and your new one is called
new_ctl_sig1
, your code might start like this:
always @(ctl_sig, X, Y) begin if (ctl_sig == 1) mux_output <= Y; else mux_output <= X; end
then become:
always @(ctl_sig, X, Y, new_Z, new_ctl_sig1) begin if (ctl_sig == 1) mux_output <= Y; // sig1 = 0, sig = 1 else begin if (new_ctl_sig1 == 1) // sig1 = 1, sig = 0 mux_output <= new_Z; else mux_output <= X; // sig1 = 0, sig = 0 end end
- Most likely you will simply modify a mux to use your new control signal. Assumming you've got two signals and your new one is called
-
Be sure your
Processor
compiles in ModelSim before moving on.
-
-
Test
lui
.This will be much like the iterations from the previous practical:
- create a
memory-U.txt
file with a few assembled lui instructions in it. Consider also using some R-type instructions to see if lui properly overwrites the lower bits of a register. - Create a
tb_Processor_U.v
file to test yourmemory-U.txt
instructions.- We recommend you copy one of your other tests from the last practical and edit it.
- Run your new tests. Maybe make a waveform to help debug.
- Also make sure all the old tests still work with your new Processor
- create a
-
Once you've got
lui
working, save your progress in git!- Be sure to add, commit, and push only the verilog files, changed memory file, and any waveform
.do
file you edited or created.
- Be sure to add, commit, and push only the verilog files, changed memory file, and any waveform
2 Implement jal
Use the same procedure as you did for lui
to implement jal
:
- Write the RTL for
jal
on the practical worksheet where prompted. - Edit the datapath on the practical worksheet to add jal.
- Add
jal
to control- And add a test to
tb_Control.v
forjal
.
- And add a test to
- Add
jal
toProcessor.v
. - Create a test bench
tb_Processor_UJ.v
and memory filememory-UJ.txt
to test your jal instruction.- Be sure to test both the jump part (that the
PC
gets the right new value at the right time) and also the link part (thatrd
gets the old PC+4 value)
- Be sure to test both the jump part (that the
- Once it's working, do a git add, commit, push to save your changes.
This is trickier than it seems at first because of the timing of how the link address gets written to the register file. Consider looking back at your worksheet submission for Practical5 and review the timing of when registers are written and when the PC updates.
- Remember: shortly after PC is written, the new pc value (PC+4) changes too! You might end up with the wrong link address if you're not careful.
- If you need to store data across a clock edge, consider using a register.
3 Implement jalr
Use the same procedure as you did for jal
to implement jalr
. While jalr
is an I-type, its opcode is unique so you should treat it like a separate format.
- Write the RTL for
jalr
on the practical worksheet where prompted.- Note that it is very similar to
jal
, but the branch target is not PC-relative and is insteadrs1
-relative.
- Note that it is very similar to
- Edit the datapath on the practical worksheet to add
jalr
. - Add
jalr
to control- And add a test to
tb_Control.v
forjalr
.
- And add a test to
- Add
jalr
toProcessor.v
. - Create a test bench
tb_Processor_jal.v
and memory filememory-jal.txt
to test your jal instruction.- Be sure to test both the jump part (that the
PC
gets the right new value at the right time) and also the link part (thatrd
gets the old PC+4 value)
- Be sure to test both the jump part (that the
- Once it's working, do a git add, commit, push to save your changes.
This one will be a little easier than jal
, but might require editing the mux between the branch target adder and the PC register.
4 Design and Implement a new instruction
With your team, design a new instruction that's not currently supported by RISC-V. It can have a different format and do pretty much whatever you want.
**For ideas, consult your instructor.**
- Design the instruction
- On the practical questions sheet, describe the purpose and usage of your new instruction.
- Draw the instruction format on the practical questions sheet, showing opcode and any other fields. Clearly label each field and it's size.
- Write RTL for your new instruction on the practical questions sheet.
- Make changes to the datapath on the practical questions sheet necessary to implement your new instruction.
- Update your
Control.v
unit to support your new instruction. Be sure to write a test like you did for the other instructions. - Update
Processor.v
to support your new instruction. - Create a memory file with an assembled version of your new instruction to test.
- Your memory file can also contain other instructions.
- We recommend updating one of your team's assemblers to assemble your new instruction to both (a) check that the instruction format and any addressing modes work, and (b) easily create an assembled machine code version of your instruction.
- Create a new test bench file and use your new memory file to test the instruction.
Turn It In
Grading Rubric
General Requirements for all Practicals:
- fits the need
- discuss performance
- tests for correctness
- iteration and documentation
Fill out the Practical Worksheet
In the worksheet, explain how you satisfy each of these items. Some guidelines:
-
None of these answers should be more than 100 words.
-
For item 4, if you had committed changes before you fixed the error and can show what changed to fix the error, also indicate the commit ID where you fixed the error. To find this id, go view the history of commits on your repo in github and look for commit id as a short 7-hex-digit value:
Practical 6 Rubric items Possible Points Practical Worksheet 25 lui and tests 15 jal and tests 15 jalr and tests 15 New inst and tests 20 Extra points 5 Total out of 100 For extra points, you could:
- Document (attached to the end of your practical worksheet) how your made changes to your assembler to support the new instruction. Screenshots or code snippets showing new methods or assembly-to-machine-code conversions should be included to show how you did this.
- ... etc
-
Submit your completed Practical Worksheet to gradescope.
-
Practical code will be submitted to your
C
git repository as new files and committed modifications to the repo we provided you. You must include your name and your teammates' names in a comment at the top of all files you submit.