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:

Guidelines

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.

  1. On the practical worksheet:

    1. Where indicated, write the RTL for LUI. Include all the RTL in common with other instructions, like newPC <= PC + 4.
    2. 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).
  2. Implement Control

    1. Open up your C-group repo in VS Code (or your favorite text editor)
    2. Edit Control.v to have an additional case for lui (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.
  3. Test Control

    Once you've coded control for lui

    1. In VS Code, open the tb_Control.v file and add a test for lui.
    2. Compile your files in ModelSim and run tb_Control to see if your test passes.
  4. Implement the Datapath

    1. Add lui to your Processor.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
    2. Be sure your Processor compiles in ModelSim before moving on.

  5. Test lui.

    This will be much like the iterations from the previous practical:

    1. 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.
    2. Create a tb_Processor_U.v file to test your memory-U.txt instructions.
      • We recommend you copy one of your other tests from the last practical and edit it.
    3. Run your new tests. Maybe make a waveform to help debug.
    4. Also make sure all the old tests still work with your new Processor
  6. 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.

2 Implement jal

Use the same procedure as you did for lui to implement jal:

  1. Write the RTL for jal on the practical worksheet where prompted.
  2. Edit the datapath on the practical worksheet to add jal.
  3. Add jal to control
    • And add a test to tb_Control.v for jal.
  4. Add jal to Processor.v.
  5. Create a test bench tb_Processor_UJ.v and memory file memory-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 (that rd gets the old PC+4 value)
  6. 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.

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.

  1. 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 instead rs1-relative.
  2. Edit the datapath on the practical worksheet to add jalr.
  3. Add jalr to control
    • And add a test to tb_Control.v for jalr.
  4. Add jalr to Processor.v.
  5. Create a test bench tb_Processor_jal.v and memory file memory-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 (that rd gets the old PC+4 value)
  6. 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.**
  1. Design the instruction
    1. On the practical questions sheet, describe the purpose and usage of your new instruction.
    2. Draw the instruction format on the practical questions sheet, showing opcode and any other fields. Clearly label each field and it's size.
    3. Write RTL for your new instruction on the practical questions sheet.
    4. Make changes to the datapath on the practical questions sheet necessary to implement your new instruction.
  2. Update your Control.v unit to support your new instruction. Be sure to write a test like you did for the other instructions.
  3. Update Processor.v to support your new instruction.
  4. 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.
  5. 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

  1. The solution fits the need
  2. Aspects of performance are discussed
  3. The solution is tested for correctness
  4. The submission shows iteration and documentation

Fill out the Practical Worksheet

In the worksheet, explain how you satisfy each of these items. Some guidelines:

  1. Submit your completed Practical Worksheet to gradescope.

  2. 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.