# Lab3: Reindeer - RISCV RV32I[M] Soft CPU ###### tags: `RISC-V` ## Modify the assembly code from HW1/HW2 for Reindeer We can use the [riscv-compliance](https://github.com/riscv/riscv-compliance) and [imperas-riscv-tests](https://github.com/riscv-ovpsim/imperas-riscv-tests) to get the ELF file. I need to modify the configuration, so risc-v can run it. - /imperas-riscv-tests/Makefile ``` export RISCV_DEVICE ?= rv32i export RISCV_PREFIX ?= riscv-none-embed- export RISCV_TARGET_FLAGS ?= export RISCV_ASSERT ?= 0 export TARGET_SIM ?= /home/ccs100203/Desktop/imperas-riscv-tests/riscv-ovpsim/bin/Linux64/riscvOVPsim.exe ``` - /riscv-target/riscvOVPsim/device/rv32i/Makefile.include ``` ROOTDIR ?= /home/ccs100203/Desktop/imperas-riscv-tests TARGET_SIM ?= /home/ccs100203/Desktop/imperas-riscv-tests/riscv-ovpsim/bin/Linux64/riscvOVPsim.exe ``` - /riscv-test-suite/rv32i/Makefile ``` ROOTDIR ?= /home/ccs100203/Desktop/imperas-riscv-tests TARGET_DIR := $(ROOTDIR)/riscv-target RISCV_TARGET := riscvOVPsim RISCV_DEVICE := rv32i ``` :::warning I haven't finish the code modification. ::: ```c #include "riscv_test_macros.h" #include "compliance_test.h" #include "compliance_io.h" # Test Virtual Machine (TVM) used by program. RV_COMPLIANCE_RV32M # Test code region. RV_COMPLIANCE_CODE_BEGIN RVTEST_IO_INIT RVTEST_IO_ASSERT_GPR_EQ(x31, x0, 0x00000000) RVTEST_IO_WRITE_STR(x31, "Test Begin\n") main: lw s0, x # Set s0 equal to the parameter x lw s1, y # Set s1 equal to the parameter y mv a0, s0 # Set arguments mv a1, s1 jal power # return the result a0 mv s2, a0 # Set s2 equal to the result j print power: addi sp, sp, -12 sw ra, 0(sp) sw s0, 4(sp) sw s1, 8(sp) mv s0, a0 # s0 -> parameter x mv s1, a1 # s1 -> parameter y li s2, 1 # s2 -> res, init = 1 loop: bge x0, s1, Ret # if (0 >= y) break andi t0, s1, 0x1 # t0 -> y & 0x1 li t1, 0x1 # t1 -> 0x1 li ra, 0x54 # Set ra equal to srli s1, s1, 1 beq t0, t1, odd # y is odd srli s1, s1, 1 # y_u >> 1, y /= 2 mul s0, s0, s0 # x = x * x j loop # goto loop odd: mul s2, s2, s0 # res = res * x jr ra # goto srli s1, s1, 1 Ret: mv a0, s2 # Set return reg a0 lw ra, 0(sp) # Restore ra lw s0, 4(sp) # Restore s0 lw s1, 8(sp) # Restore s1 addi sp, sp, 12 # Free space on the stack for the 3 words jr ra # Return to the caller .data x: .word 3 y: .word 5 # unsigned RV_COMPLIANCE_DATA_END ``` ## GTKWAVE ## Explain how Reindeer works with Verilator. From [Verilator](https://en.wikipedia.org/wiki/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. ## What is 2 x 2 Pipeline? How can we benefit from such pipeline design? ![](https://github.com/PulseRain/Reindeer/raw/master/docs/pipeline_2x2.png) from [2 x 2 Pipeline](https://github.com/PulseRain/Reindeer#highlights---2-x-2-pipeline) > 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. In this way, the Instruction Fetch and Memory Access always happen on different clock cycles, thus to avoid the structural hazard caused by the single port memory. Thanks to using single port memory to store both code and data, the Reindeer soft CPU is quite portable and flexible across all FPGA platforms. Some FPGA platforms, like the Lattice iCE40 UltraPlus family, carry a large amount of SPRAM with very little EBR RAM. And those platforms will find themselves a good match with the PulseRain Reindeer when it comes to soft CPU. We knew this design has some benefits. 1. Avoid the structural hazard caused by the single port memory. If IF and MEM need to access the memory in same cycle, it will lead to structural hazard. In other design, We need to separate the IM and DM to avoid this hazard. however in this way, IF and MEM access memory in different cycles. Thus, it can avoid this hazard. 2. The Reindeer soft CPU is quite portable and flexible across all FPGA platforms. Because this design don't need extra memory, it will be more flexible. ## What is “Hold and Load”? And, how the simulation does for bootstraping? ![](https://raw.githubusercontent.com/PulseRain/Reindeer/master/docs/hold_and_load.png) from [Hold and Load](https://github.com/PulseRain/Reindeer#highlights---hold-and-load) The soft CPU and the OCD can share the same UART port, as illustrated above. 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. ## Can you show some signals/events inside Reindeer and describe? ## Summarize how RISC-V Compliance Tests works and why the signature should be matched.