# Assignment3: Single-cycle RISC-V CPU contributed by < [terry23304](https://github.com/terry23304/ca2023-lab3) > ## Hello World in Chisel ```c 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 } ``` Switch the LED output every `CNT_MAX` clock cycles. It is a I/O Bundle that has only one output signal and no input signals. It includes two registers, `cntReg` and `blkReg`, `cntReg` is used to count the number of clock cycles passed. When it reaches`CNT_MAX`, which is `24999999`, reset `cntReg` to 0 and invert the value of `blkReg`. The output will be the same as `blkReg` ## MyCPU ### Instruction Fetch ![image](https://hackmd.io/_uploads/Sk6nMUVB6.png) Using `jump_flag_id` to determine next pc will be `jump_address_id` or `pc + 4`. ![image](https://hackmd.io/_uploads/H1BWX8EHp.png) `instruction valid` is false only in the beginning. Therefore, the instruction is `0x00000013`, and after that, the instruction will be `0x00000000`. ### Instruction Decode ![image](https://hackmd.io/_uploads/Bkz6Wv4H6.png) The testing instruction would be: - sw x10, 4(x0) - lui x5, 2 - add x3, x1, x2 ![image](https://hackmd.io/_uploads/HkpeFwNBp.png) Set `memory_read_enable` to `1` when the instruction is of L type and set `memory_write_enable` to `1` when the instruction is of S type. Therefore, `memory_write_enable` is set to `1` only when executing the `instruction sw x10`, 4(x0). ### Execute ![image](https://hackmd.io/_uploads/rknCbDNHT.png) Using aluop_source to determine the values of `op1` and `op2`. When aluop_source is 0, op will be set to the data in register; otherwise, op will be set to 0 and immediate value. ![image](https://hackmd.io/_uploads/H1UpwONrT.png) ## Run RISC-V assembly code in Homework2 - Move assembly code to csrc directory. - Modify the makefile in csrc directory to generate corresponding .asmbin file ``` BINS = \ fibonacci.asmbin \ hello.asmbin \ mmio.asmbin \ quicksort.asmbin \ sb.asmbin \ binarization.asmbin ``` - Add test in CPUTest.scala - Run `make update` - Run `sbt "testOnly riscv.singlecycle.BinarizationTest"` ``` [info] BinarizationTest: [info] Single Cycle CPU [info] - should do binarization with threshold 128 [info] Run completed in 3 seconds, 314 milliseconds. [info] Total number of tests run: 1 [info] Suites: completed 1, aborted 0 [info] Tests: succeeded 1, failed 0, canceled 0, ignored 0, pending 0 [info] All tests passed. [success] Total time: 4 s, completed Dec 1, 2023, 12:24:30 AM ``` ## Analysis Execute the following command to generate Verilog file.z ``` $ make verilator $ ./run-verilator.sh -instruction src/main/resources/binarization.asmbin -time 2000 -vcd dump.vcd ``` Then, run `gtkwave dump.vcd` to check waveform.