# Assignment3: Single-cycle RISC-V CPU contributed by < [`RayChen`](https://github.com/padaray) > ## Environment Issue When executing the `sbt -version` command in the terminal of VSCode, the response is correct. ``` sbt version in this project: 1.9.7 sbt script version: 1.9.7 ``` When executing `sbt test` the following error occurs. ``` [error] /home/ray870317/java/jdk/ca2023-lab3/src/main/scala/riscv/core/ALU.scala:6:8: not found: object chisel3 [error] import chisel3._ [error] ^ ``` Initially, I thought that the "build.sbt" file was not properly configured, causing it to be unable to recognize the `import chisel3`. Last, it was discovered that opening the folder in VSCode needs to be done from the root directory `/java/jdk/ca2023-lab3`. </br> ## Operation of ‘Hello World in Chisel’ ```scala // Hello World in Chisel class Hello extends Module { val io = IO(new Bundle { val led = Output(UInt(1.W)) }) val CNT_MAX = (50000000 / 2 - 1).U; val cntReg = RegInit(0.U(32.W)) val blkReg = RegInit(0.U(1.W)) cntReg := cntReg + 1.U when(cntReg === CNT_MAX) { cntReg := 0.U blkReg := ~blkReg } io.led := blkReg } ``` 1. `led` is an unsigned integer output with a width of 1 bit 2. `CNT_MAX` is a constant with a value of 24999999 3. `cntReg` and`blkReg` are both unsigned integers with widths of 32 bits and 1 bit 4. `cntReg` increments by 1 for each cycle. When it reaches 24999999, it resets to 0, and simultaneously, `blkReg` is inverted. 5. Assigns the value of `blkReg` to the output `io.led`. In conclusion, this code appears to make the led flash once every 24999999 cycles. </br> **Enhance operation by incorporating logic circuit** ```scala class Hello extends Module { val io = IO(new Bundle { val led = Output(UInt(1.W)) }) val CNT_MAX = (50000000 / 2 - 1).U; val cntReg = RegInit(0.U(32.W)) val blkReg = RegInit(0.U(1.W)) cntReg := Mux(cntReg === CNT_MAX,0.U,cntReg + 1.U) blkReg := Mux(cntReg === CNT_MAX,~blkReg,blkReg) io.led := blkReg } ``` </br> ## Complete Lab3 and Test After completing lab3 with the filled-in code, we need to run tests using the test files located under the directory `/ca2023-lab3/src/test/scala/riscv/singlecycle`, and I will explain the testing process using Waveform. The waveform file is generated using the following command : ``` $ WRITE_VCD=1 sbt test ``` generated `.vcd` file will store at `/ca2023-lab3/test_run_dir` </br> ### **InstructionFetchTest** **Code Behavior :** &emsp;&emsp; We have a random constant, either 0 or 1. When the is constant equal to 0, `jump_flag_id` set False, and `instruction address` is incremented by 4; When the constant is 1, `jump_flag_id` set True, and `instruction address` jumps to 0x1000. These actions are repeated 100 times. **Waveform Analysis :** - Initial part : ![image](https://hackmd.io/_uploads/SyEpG4LBa.png) &emsp;&emsp; At the beginning, we initialize the value. The `instruction_valid` is set after one clock cycle, and the program starts executing instructions sequentially after a delay of 5 ps. I don't understand why this delay exists. - case 0 : ![image](https://hackmd.io/_uploads/r1l0BNLSp.png) &emsp;&emsp; When constant equal to 0, `jump_flag_id` is set to 0 (False), and the instruction address changes from 0x1000 to 0x1004, without performing a jump action. - case 1 : ![image](https://hackmd.io/_uploads/SJ3_DNLrT.png) &emsp;&emsp; When constant equal to 1, `jump_flag_id` is set to 1 (True), and the instruction address from 0x1010 jump back to 0x1000. ### **InstructionDecoderTest** **Code Behavior :** &emsp;&emsp; We sequentially inputs `sw`, `lui`, and `add` instructions while checking the signals of `ex_aluop1_source`, `ex_aluop2_source`, `regs_reg1_read_address`, and `regs_reg2_read_address` to verify if these four variables behave as expected. **Waveform Analysis :** - sw instruction : ![image](https://hackmd.io/_uploads/rkp2A4Urp.png) &emsp;&emsp; "0x00a02223" address represents the `sw` instruction. We can observe that the `memory_read` signal is 0, and the `memory_write` signal is 1, indicating that data can be written to memory. - lui instruction : ![image](https://hackmd.io/_uploads/ByJ6Hr8ra.png) &emsp;&emsp; "0x00a02223" address represents the `lui` instruction. The `aluop1` signal matches the expected value 1. `memory_read` and `memory_write` are both 0, indicating there is no memory access. ### **ExecuteTest** **Code Behavior :** &emsp;&emsp; Testing whether the ALU functions correctly. The test includes `add` and `beq` instructions. For the `add` instruction, it verifies if the sum of two values is correct. In the case of the beq instruction, it tests whether if_jump_flag is set to 1 when the two values are equal. **Waveform Analysis :** ![image](https://hackmd.io/_uploads/H1qN3r8rT.png) &emsp;&emsp; the sum of `op1` and `op2` equals result, indicating that our calculation result is correct. When `func` is 1, it corresponds to the `add` instruction. ### **FibonacciTest** **Code Behavior :** &emsp;&emsp; Execute the fibonacci.asmbin with the CPU and verify if the values stored in the memory locations it occupies match our expected values.