Assignment3: SoftCPU
contributed by < shauming1020
>
Requirements
Power function
Assignment1
Re-write the Assembly Code for riscv-compliance
First, we can check the result whether correctly with Ripes.
Image Not Showing
Possible Reasons
- The image file may be corrupted
- The server hosting the image is unavailable
- The image path is incorrect
- The image format is not supported
Learn More →
x ^ y = 243, x = 3 and y = 5.
ELF file
We can use the riscv-compliance and riscv-ovpsim to generate the elf-file.
- Activate the source for riscv-none-embed-
-
Change the current folder to riscv-compliance.
-
Modify the Makefile
RISCV_DEVICE : ISA you want to use. Note: rv32im contain mul/div instruction.
TARGET_SIM : Path for riscvOVPsim.exe, and it is in the riscv-ovpsim folder.
-
Make to test and check result
Check the output
-
Change current folder to riscv-test-suite/rv32im
Put the POWER.S into src folder, then add the file name in Makefrag.
-
Put the POWER.reference_output into references folder
000000f3 = 243
The test program will compare the signature (program's output) with except result (referece_output).
We can see the signature and elf-file at riscv-compliance/work/rv32im.
-
Back to riscv-compliance folder and re-make.
Finish the verification.
-
Copy the files generated by riscv-compliance into Reindeer/sim/compliance
We have three files "POWER.elf", "POWER.signature.output" and "POWER.elf.objdump" in the work folder, and copy them into Reindeer/sim/compliance.
-
Change current folder to Reindeer/sim/verilator
-
Make the test for POWER
Output
-
Check the wave with vcd file and gtkwave tool

Result in the register s2(x18) is exactly 0xF3 (243).
Explain how your program is executed along with Reindeer Simulation
Check the POWER.elf.objdump file.
POWER.elf.objdump
/home/dcmc/CA/ASS3/riscv-compliance/work/rv32im/POWER.elf: file format elf32-littleriscv
Disassembly of section .text.init:
80000000 <_start>:
80000000: 04c0006f j 8000004c <reset_vector>
80000004 <trap_vector>:
80000004: 34202f73 csrr t5,mcause
80000008: 00800f93 li t6,8
8000000c: 03ff0a63 beq t5,t6,80000040 <write_tohost>
80000010: 00900f93 li t6,9
80000014: 03ff0663 beq t5,t6,80000040 <write_tohost>
80000018: 00b00f93 li t6,11
8000001c: 03ff0263 beq t5,t6,80000040 <write_tohost>
80000020: 80000f17 auipc t5,0x80000
80000024: fe0f0f13 addi t5,t5,-32 # 0 <_start-0x80000000>
80000028: 000f0463 beqz t5,80000030 <trap_vector+0x2c>
8000002c: 000f0067 jr t5
80000030: 34202f73 csrr t5,mcause
80000034: 000f5463 bgez t5,8000003c <handle_exception>
80000038: 0040006f j 8000003c <handle_exception>
8000003c <handle_exception>:
8000003c: 5391e193 ori gp,gp,1337
80000040 <write_tohost>:
80000040: 00001f17 auipc t5,0x1
80000044: fc3f2023 sw gp,-64(t5) # 80001000 <tohost>
80000048: ff9ff06f j 80000040 <write_tohost>
8000004c <reset_vector>:
8000004c: f1402573 csrr a0,mhartid
80000050: 00051063 bnez a0,80000050 <reset_vector+0x4>
80000054: 00000297 auipc t0,0x0
80000058: 01028293 addi t0,t0,16 # 80000064 <reset_vector+0x18>
8000005c: 30529073 csrw mtvec,t0
80000060: 18005073 csrwi satp,0
80000064: 00000297 auipc t0,0x0
80000068: 01c28293 addi t0,t0,28 # 80000080 <reset_vector+0x34>
8000006c: 30529073 csrw mtvec,t0
80000070: fff00293 li t0,-1
80000074: 3b029073 csrw pmpaddr0,t0
80000078: 01f00293 li t0,31
8000007c: 3a029073 csrw pmpcfg0,t0
80000080: 00000297 auipc t0,0x0
80000084: 01828293 addi t0,t0,24 # 80000098 <reset_vector+0x4c>
80000088: 30529073 csrw mtvec,t0
8000008c: 30205073 csrwi medeleg,0
80000090: 30305073 csrwi mideleg,0
80000094: 30405073 csrwi mie,0
80000098: 00000193 li gp,0
8000009c: 00000297 auipc t0,0x0
800000a0: f6828293 addi t0,t0,-152 # 80000004 <trap_vector>
800000a4: 30529073 csrw mtvec,t0
800000a8: 00100513 li a0,1
800000ac: 01f51513 slli a0,a0,0x1f
800000b0: 00054863 bltz a0,800000c0 <reset_vector+0x74>
800000b4: 0ff0000f fence
800000b8: 00100193 li gp,1
800000bc: 00000073 ecall
800000c0: 80000297 auipc t0,0x80000
800000c4: f4028293 addi t0,t0,-192 # 0 <_start-0x80000000>
800000c8: 00028e63 beqz t0,800000e4 <reset_vector+0x98>
800000cc: 10529073 csrw stvec,t0
800000d0: 0000b2b7 lui t0,0xb
800000d4: 10928293 addi t0,t0,265 # b109 <_start-0x7fff4ef7>
800000d8: 30229073 csrw medeleg,t0
800000dc: 30202373 csrr t1,medeleg
800000e0: f4629ee3 bne t0,t1,8000003c <handle_exception>
800000e4: 30005073 csrwi mstatus,0
800000e8: 00002537 lui a0,0x2
800000ec: 80050513 addi a0,a0,-2048 # 1800 <_start-0x7fffe800>
800000f0: 30052073 csrs mstatus,a0
800000f4: 00000297 auipc t0,0x0
800000f8: 01428293 addi t0,t0,20 # 80000108 <begin_testcode>
800000fc: 34129073 csrw mepc,t0
80000100: f1402573 csrr a0,mhartid
80000104: 30200073 mret
80000108 <begin_testcode>:
80000108: 00002417 auipc s0,0x2
8000010c: ef840413 addi s0,s0,-264 # 80002000 <test_A1_data>
80000110: 00002997 auipc s3,0x2
80000114: f0098993 addi s3,s3,-256 # 80002010 <begin_signature>
80000118: 00042403 lw s0,0(s0)
8000011c: 00500493 li s1,5
80000120 <main>:
80000120: 00100913 li s2,1
80000124 <loop>:
80000124: 02905063 blez s1,80000144 <done>
80000128: 0014f293 andi t0,s1,1
8000012c: 00100313 li t1,1
80000130: 00629463 bne t0,t1,80000138 <even>
80000134 <odd>:
80000134: 02890933 mul s2,s2,s0
80000138 <even>:
80000138: 0014d493 srli s1,s1,0x1
8000013c: 02840433 mul s0,s0,s0
80000140: fe5ff06f j 80000124 <loop>
80000144 <done>:
80000144: 0129a023 sw s2,0(s3)
80000148: 0ff0000f fence
8000014c: 00100193 li gp,1
80000150: 00000073 ecall
80000154 <end_testcode>:
80000154: 00000073 ecall
...
Disassembly of section .tohost:
80001000 <tohost>:
...
80001100 <fromhost>:
...
Disassembly of section .data:
80002000 <test_A1_data>:
80002000: 00000003 lb zero,0(zero) # 0 <_start-0x80000000>
...
80002010 <begin_signature>:
80002010: ffff 0xffff
80002012: ffff 0xffff
...
80002020 <end_signature>:
...
80002100 <begin_regstate>:
80002100: 0080 addi s0,sp,64
...
80002200 <end_regstate>:
80002200: 0004 0x4
...
Summarize how RISC-V Compliance Tests works and why the signature should be matched
The riscv-compliance/doc/README.adoc indicate that
2.1. The compliance test
At the heart of the testing infrastructure is the detailed compliance test. This is the RISC-V assembler code that is executed on the processor and that provides results in a defined memory area (the signature). The test should only use the minimum of instructions and only those absolutely necessary. It should only use instructions and registers from the ISA instruction set on which it is targeted.
2.5. The test signature
The test signature is defined as reference data written into memory during the execution of the test. It should record values and results of the operation of the Test. It is expected that an implementation, at the end of a test, dumps the signature in to a file such that only 4-bytes are written per line, starting with the most-significant byte on the left.
Explain how Reindeer works with Verilator
Verilator is a free and open-source software tool which converts Verilog (a hardware description language) to a cycle-accurate behavioral model in C++ or SystemC.
The Observation of Reindeer/sim/verilator/tb_PulseRain_RV2T.cpp
- Fetch the signature from elf-file.
What is 2 x 2 Pipeline? How can we benefit from such pipeline design?
2 x 2 Pipeline
Reindeer's pipeline is composed of 4 stages:
- Instruction Fetch (IF)
- Instruction Decode (ID)
- Instruction Execution (IE)
- Register Write Back and Memory Access (MEM)

In the 2 x 2 layout, each stage is active every other clock cycle. For the even cycle, only IF and IE stages are active, while for the odd cycle, only ID and MEM stages are active.
- Benefit:
- The Instruction Fetch and Memory Access always happen on different clock cycles, thus to avoid the structural hazard caused by the single port memory.
What is “Hold and Load”? And, how the simulation does for bootstraping?
Hold and Load
Brings a hardware based OCD (on-chip debugger) into the fore.

The soft CPU and the OCD can share the same UART port. The RX signal goes to both the soft CPU and OCD, while the TX signal has to go through a mux. And that mux is controlled by the OCD.
After reset, the soft CPU will be put into a hold state, and it will have access to the UART TX port by default. But a valid debug frame sending from the host PC can let OCD to reconfigure the mux and switch the UART TX to OCD side, for which the memory can be accessed, and the control frames can be exchanged. A new software image can be loaded into the memory during the CPU hold state, which gives rise to the name "hold-and-load".
How the simulation does for bootstraping?