[toc] # Assignment 3 : RISC-V CPU contributed by [< jningmin >](https://github.com/jningmin/2025_computer_architecture_mycpu.git) ## 1-single-cycle For example, I loaded the quicksort.asmbin file, simulate for 1000 cycles, and save the simulation waveform to the qsort.vcd file. ```C ./run-verilator.sh -instruction src/main/resources/quicksort.asmbin -time 2000 -vcd qsort.vcd ``` If you want to run 1000 cycle, you have to set `-time` to twice of you cycle to set the maximum. ```S Disassembly of section .data: 00000000 <.data>: 0: 00002197 auipc gp,0x2 4: 82818193 addi gp,gp,-2008 # 0x1828 8: 00001137 lui sp,0x1 c: 00001297 auipc t0,0x1 ``` ![image](https://hackmd.io/_uploads/SJajA-pZbl.png) You can observe that the signal io_instruction begins with 000000000 and 00002197. In the meantime,it aligns with the expected waveform. ### Checking some importent functions through waveform #### Memory Access ```c 1d4: 02112e23 sw ra,60(sp) ``` ![image](https://hackmd.io/_uploads/r1zc2E6ZZe.png) ```c fc: 00072703 lw a4,0(a4) ``` ![image](https://hackmd.io/_uploads/BJA5p4pb-x.png) When `sw` io_memory_bundle_write_enable = 1,and when `lw` occurs io_memory_bundle_read_enable = 1 ,aligns with the expected waveform, and `writeStrobes_0`,`writeStrobes_1`,`writeStrobes_2`,`writeStrobes_3` all = 1 for `sw` and `lw`. #### Write back The control signal regs_write_source (from Decode stage) selects: - RegWriteSource.ALUResult (0): Default, use ALU computation result - RegWriteSource.Memory (1): Load instruction, use memory read data - RegWriteSource.NextInstructionAddress (2): JAL/JALR, save return address ```c 60: 03010413 addi s0,sp,48 ``` ![image](https://hackmd.io/_uploads/H1sIWBpbZg.png) ```c 70: fd842703 lw a4,-40(s0) ``` ![image](https://hackmd.io/_uploads/HyzgGHTZ-e.png) ```c a4: 0c00006f j 0x164 ``` ![image](https://hackmd.io/_uploads/r1xweST-Ze.png) ## 2-mmio-trap ![image](https://hackmd.io/_uploads/HJST63iWWx.png =150x) --- ### Test case error : UartMMIOTest When I do `make test` and this error occurs: ```c UartMMIOTest: [info] [UART] Comprehensive TX+RX test [info] - should pass all TX and RX tests *** FAILED *** [info] io_mem_debug_read_data=11 (0xb) did not equal expected=15 (0xf) (lines in UartMMIOTest.scala: 174, 161) (UartMMIOTest.scala:174) ``` It means there was a problem with the read path or data transfer. So I went to check the whole code of my Memory Acess scala code (because at that time I still can't figure out how to observe the error through the waveform) Turns out there are some problems in [CA25: Exercise 12] original code : ```c io.wb_memory_read_data := MuxLookup(io.funct3, 0.U)( Seq( // TODO: Complete LB (sign-extend byte) // Hint: Replicate sign bit, then concatenate with byte InstructionsTypeL.lb -> MuxLookup(mem_address_index, Cat(Fill(24, data(31)), data(31, 24)))( Seq( 0.U -> Cat(Fill(24, data(7)), data(7, 0)), 1.U -> Cat(Fill(24, data(15)), data(15, 8)), 2.U -> Cat(Fill(24, data(23)), data(23, 16)) ) ) ``` The new code utilizes the byte signals that already pre-computed in the MemoryAccess module, and sucessfuly eliminate this error. ```c io.wb_memory_read_data := MuxLookup(io.funct3, 0.U)( Seq( // TODO: Complete LB (sign-extend byte) // Hint: Replicate sign bit, then concatenate with byte InstructionsTypeL.lb -> MuxLookup(mem_address_index, Cat(Fill(24, data(31)), data(31, 24)))( Seq( 0.U -> Cat(Fill(24, byte(7)), byte), 1.U -> Cat(Fill(24, byte(7)), byte), 2.U -> Cat(Fill(24, byte(7)), byte) ) ) ``` ## 3-pipeline ### CA25: Exercise 21 **Q1**: Why do we need to stall for load-use hazards? >Hint: Consider data dependency and forwarding limitations A: [Because load instruction is only retrieved from memory at the end of MEM stage, when we are dealing hazard is using ex/mem or ex/wb, there is no way we can get data immediately from end of MEM stage to the front of its own EX stage. ] **signal explaination** - Hazard Detection & Stalling: The process begins when the `io_stall_flag_ctrl` signal goes $\to \mathbf{1}$ at $161 \text{ ns}$. This is the essential signal confirming that your Hazard Detection Unit recognized the data dependency (the Load-Use).Simultaneously, the `io_pc_stall` signal goes $\to \mathbf{1}$. This is the direct command to pause the pipeline. - Pipeline pausing : As a result of `io_pc_stall` being high, the `pc[31:0]` value is frozen at $\mathbf{00001010}$ for the entire clock cycle (161 ns to 163 ns). This prevents the next instruction from being fetched.Similarly, the `io_id_instruction[31:0]` signal remains at $\mathbf{005082e3}$, confirming that the IF/ID pipeline register is frozen. This ensures the instruction that needs the loaded data remains in the ID stage for one extra cycle. - NOP Insertion To prevent the frozen instruction from executing twice, a NOP bubble must be inserted into the ID/EX pipeline register.This is proven by the control signals `memory_read_enable_io_flush`, `reg1_data_io_flush`, and `regs_write_enable_io_flush` all going $\to \mathbf{1}$ during the stall cycle. In your design, these signals are used to clear or invalidate the ID/EX register's control bits, effectively forcing it to execute as a NOP. ![image](https://hackmd.io/_uploads/H1JB69MM-g.png) **Q2**: What is the difference between "stall" and "flush" operations? >Hint: Compare their effects on pipeline registers and PC A: [Stall is like a pause, we stop and wait for the data we want to be available, and freezes the PC and the IF/ID register, and clears the ID/EX register to insert a NOP bubble. Flush occurs when we get wrong next instruction, therefore we need to clear the wrong instruction that we fetched and set the pipeline registers to NOP.] **signal explaination** - `if2id_io_stall`: When a Stall occurs, this signal goes $\to \mathbf{1}$, causing the PC (Program Counter) to be frozen, holding its previous value. - `if2id_io_flush`: When a Flush occurs, this signal goes $\to \mathbf{1}$. The PC must jump to a new target address instead of being frozen. - `pc[31:0]`: Stall: The PC value remains unchanged. Flush: The PC value jumps to a new branch or jump target address. - **stall** ![image](https://hackmd.io/_uploads/ry7UJ2MMbe.png) **flush** ![image](https://hackmd.io/_uploads/BJqNJ2fGWx.png) **Q3**: Why does jump instruction with register dependency need stall? >Hint: When is jump target address available? A: [Because it is a non condition jump instruction, it will always need to calculate its next instruction address, and the jump target address will not determined until the end of the EX stage.] **signal explaination** Observe whether the `PC[31:0]` stops updating , and check if the Jump target address has already been computed . While the PC is halted, confirm that a NOP bubble (flushes) is correctly injected into the pipeline. ![image](https://hackmd.io/_uploads/rk3tQ2fGWx.png) **Q4**: In this design, why is branch penalty only 1 cycle instead of 2? >Hint: Compare ID-stage vs EX-stage branch resolution A: [Because when branch or not is determined at EX stage, we need to flush 2 instruction following behind, but when branch or not is determined at ID stage, we will only need to flush 1 instruction, it's all because of the design implements ID stage forwarding. ] **signal explaination** Branch penalty only 1 cycle. ![image](https://hackmd.io/_uploads/HJUmbQXfWx.png) **Q5**: What would happen if we removed the hazard detection logic entirely? A: [The pipeline would continue to execute instructions without checking for dependencies, leading to incorrect program execution and results.] >Hint: Consider data hazards and control flow correctness **Q6**: Complete the stall condition summary: Stall is needed when: - The instruction in the EX stage is a load ,and its destination register (rd_ex) is not x0 and matches a source register (rs1_id or rs2_id) of the instruction in the ID stage. (EX stage condition) - The instruction in the MEM stage is a Load , and the instruction in the ID stage is a Jump , and the Load destination (rd_mem) matches the Jump source .(MEM stage condition) Flush is needed when: - A branch instruction is resolved in the ID stage and is determined to be taken (misprediction),or an unconditional Jump (JALR or JAL) is executed. (Branch/Jump condition) ### Attempting to run the Assembly files from Assignment 2 on the MyCPU architecture. ```s make update /home/userjning/riscv-none-elf-gcc/bin/riscv-none-elf-as -R -march=rv32i_zicsr -mabi=ilp32 -o hanoi_gray_bare.o hanoi_gray_bare.S hanoi_gray_bare.S: Assembler messages: hanoi_gray_bare.S: Warning: end of file not at end of a line; newline inserted /home/userjning/riscv-none-elf-gcc/bin/riscv-none-elf-ld -o hanoi_gray_bare.elf -T link.lds --oformat=elf32-littleriscv hanoi_gray_bare.o /home/userjning/riscv-none-elf-gcc/bin/riscv-none-elf-ld: hanoi_gray_bare.o: in function `_start': (.text+0x0): undefined reference to `__stack_top' /home/userjning/riscv-none-elf-gcc/bin/riscv-none-elf-ld: hanoi_gray_bare.o: in function `main': (.text+0x34): undefined reference to `get_cycles' /home/userjning/riscv-none-elf-gcc/bin/riscv-none-elf-ld: hanoi_gray_bare.o: in function `print_from_label': (.text+0x23c): undefined reference to `get_cycles' make: *** [Makefile:16: hanoi_gray_bare.elf] Error 1 ``` "Only the code and data segments from the ELF file are required, while other segments can be disregarded. In the linker script, these two segments are allocated to contiguous addresses to streamline the implementation." ```c riscv-none-elf-objcopy -O binary --only-section=.text --only-section=.data stairs.elf stairs.asmbin make sim SIM_ARGS="-instruction ../../../csrc/stairs.asmbin" ``` **Successful execution form hw2 program** hw1_program ```s stairs.elf: file format elf32-littleriscv Disassembly of section .text: 00010000 <get_cycles>: get_cycles(): 10000: c80025f3 rdcycleh a1 10004: c0002573 rdcycle a0 10008: c8002673 rdcycleh a2 1000c: fec59ae3 bne a1,a2,10000 <get_cycles> 10010: 00008067 ret ... ``` ![image](https://hackmd.io/_uploads/rJJqcvVz-e.png) quiz2_program ```s hanoi.elf: file format elf32-littleriscv Disassembly of section .text: 00010000 <get_cycles>: 10000: c80025f3 rdcycleh a1 10004: c0002573 rdcycle a0 10008: c8002673 rdcycleh a2 1000c: fec59ae3 bne a1,a2,10000 <get_cycles> 10010: 00008067 ret 00010014 <get_instret>: 10014: c82025f3 rdinstreth a1 10018: c0202573 rdinstret a0 1001c: c8202673 rdinstreth a2 10020: fec59ae3 bne a1,a2,10014 <get_instret> 10024: 00008067 ret ``` ![image](https://hackmd.io/_uploads/B14YRydG-l.png) I observed that `io_instruction[31:0]` :`c0202573` signal becomes stable (00000000) in the waveform, but the` pc[31:0]` signal continues to update . This usually means that the CPU has read an invalid or logical body from the instruction memory (approximately processed to a new bit), but is still reading an invalid or logical body from the execution memory, but is still reading an invalid or logical body from the execution processor itself. ![image](https://hackmd.io/_uploads/r1yxlguM-e.png) After `bne` comes `ret`, and the PC should jump to the caller's address, but my PC is just incrementing by $PC+4$, which is the real problem. So I went to check the `ret` finction in `control.scala` and `if2id.scala` . Pull out signal in `if2id` and find out after a `flush`, all instruction returns 00000000. ![image](https://hackmd.io/_uploads/HkkSOgdfWe.png) My original code:[CA25: Exercise 20] ```s // TODO: Complete the instantiation and connection // Hint: Use Module() to instantiate PipelineRegister with appropriate default val instruction = Module(new PipelineRegister(defaultValue = 0x00000013.U)) instruction.io.in := io.instruction instruction.io.stall := io.stall instruction.io.flush := io.flush io.output_instruction := instruction.io.out // For instruction address register: // - Flush: Output entry address (ProgramCounter.EntryAddress) // TODO: Complete the instantiation and connection val instruction_address = Module(new PipelineRegister(defaultValue = 0.U)) instruction_address.io.in := io.instruction_address instruction_address.io.stall := io.stall instruction_address.io.flush := io.flush io.output_instruction_address := instruction_address.io.out ``` After changing: ```s // TODO: Complete the instantiation and connection // Hint: Use Module() to instantiate PipelineRegister with appropriate default val instruction = Module(new PipelineRegister(defaultValue = InstructionsNop.nop)) instruction.io.in := io.instruction instruction.io.stall := io.stall instruction.io.flush := io.flush io.output_instruction := instruction.io.out // For instruction address register: // - Flush: Output entry address (ProgramCounter.EntryAddress) // TODO: Complete the instantiation and connection val instruction_address = Module(new PipelineRegister(defaultValue = ProgramCounter.EntryAddress)) instruction_address.io.in := io.instruction_address instruction_address.io.stall := io.stall instruction_address.io.flush := io.flush io.output_instruction_address := instruction_address.io.out ``` Still the same. ![image](https://hackmd.io/_uploads/B1CPTlOMbg.png) alu.scala ```c // Comparison Operations // is(ALUFunctions.slt) { // TODO: Implement signed comparison (Set Less Than) // Hint: Convert both operands to signed type then compare // If op1 < op2 (signed), result is 1, otherwise 0 io.result := Mux(io.op1.asSInt < io.op2.asSInt, 1.U, 0.U) } is(ALUFunctions.sltu) { // TODO: Implement unsigned comparison (Set Less Than Unsigned) // Hint: Directly compare unsigned values // If op1 < op2 (unsigned), result is 1, otherwise 0 io.result := Mux(io.op1.asUInt < io.op2.asUInt, 1.U, 0.U) } ``` After changing: ```c // Comparison Operations // is(ALUFunctions.slt) { // TODO: Implement signed comparison (Set Less Than) // Hint: Convert both operands to signed type then compare // If op1 < op2 (signed), result is 1, otherwise 0 io.result := (io.op1.asSInt < io.op2.asSInt).asUInt } is(ALUFunctions.sltu) { // TODO: Implement unsigned comparison (Set Less Than Unsigned) // Hint: Directly compare unsigned values // If op1 < op2 (unsigned), result is 1, otherwise 0 io.result := (io.op1 < io.op2).asUInt } ``` Still the same ![image](https://hackmd.io/_uploads/B1CPTlOMbg.png) After all I assume this error have some connection with [issue 3](https://hackmd.io/f2M3DssDTWy3uYJNpmZojg#issue-3), because I tried everything that I thought might cause errror in scala code, so I think this might be related to my almost empty memory C drive, but I'm not sure. ## issue 1 For `make compliance` ```c - should pass test /home/userjning/ca_lab3/ca2025-mycpu/tests/riscv-arch-test/riscv-test-suite/rv32i_m/I/src/lui-01.S *** FAILED *** [info] java.lang.Exception: No RISC-V toolchain found. Set $RISCV or install to $HOME/riscv/toolchain [info] at riscv.compliance.ElfSignatureExtractor$.$anonfun$extractSignatureRange$10(ComplianceTestBase.scala:84) [info] at scala.Option.getOrElse(Option.scala:201) [info] at riscv.compliance.ElfSignatureExtractor$.readelfCmd$lzycompute$1(ComplianceTestBase.scala:84) [info] at riscv.compliance.ElfSignatureExtractor$.readelfCmd$1(ComplianceTestBase.scala:70) [info] at riscv.compliance.ElfSignatureExtractor$.extractSignatureRange(ComplianceTestBase.scala:95) [info] at riscv.compliance.ComplianceTestBase.runComplianceTest(ComplianceTestBase.scala:166) [info] at riscv.compliance.ComplianceTest.$anonfun$new$19(ComplianceTest.scala:176) [info] at scala.runtime.java8.JFunction0$mcV$sp.apply(JFunction0$mcV$sp.scala:18) [info] at org.scalatest.OutcomeOf.outcomeOf(OutcomeOf.scala:85) [info] at org.scalatest.OutcomeOf.outcomeOf$(OutcomeOf.scala:83) ``` ```c [info] Run completed in 45 seconds, 961 milliseconds. [info] Total number of tests run: 50 [info] Suites: completed 8, aborted 0 [info] Tests: succeeded 9, failed 41, canceled 0, ignored 0, pending 0 [info] *** 41 TESTS FAILED *** ``` It doesn't looks like my progam runs incorrectly, it looks like it didn't even generated. So I check $Path in Makefile and tried to fix it. Turns out setting path for riscv-none-elf-gcc is the real problem. **After I changed path** ```c $ export RISCV=$HOME/riscv-none-elf-gcc $ source $RISCV/setenv $ echo $RISCV ``` ```c [info] Run completed in 7 minutes, 24 seconds. [info] Total number of tests run: 50 [info] Suites: completed 8, aborted 0 [info] Tests: succeeded 50, failed 0, canceled 0, ignored 0, pending 0 [info] All tests passed. [success] Total time: 445 s (07:25), completed Dec 1, 2025, 4:57:46 PM ``` It will save a results html like this, ![image](https://hackmd.io/_uploads/rkOWI6ibZg.png) --- ```c Validating RISCOF installation... RISCOF found: /home/userjning/.local/bin/riscof Version: RISC-V Architectural Test Framework., version 1.25.3 Running RISCOF compliance tests for 1-single-cycle (RV32I)... /bin/sh: 1: ./run-compliance.sh: Permission denied make: *** [Makefile:35: compliance] Error 126 ``` --- ## issue 2 Waveform tooks me a lot of time to understand and how to generate it. Key signals to observe: - io_instruction_address: Current PC value - io_instruction: Fetched instruction - io_memory_bundle_*: Memory interface signals - inst_fetch_*, id_*, ex_*, mem_*, wb_*: Pipeline stage internals ```c WRITE_VCD=1 sbt singleCycle/test ``` After successful execution, the generated .vcd waveform archive will be stored in various subdirectories under the `test_run_dir` directory. $\rightarrow$ `TestTopModule.vcd` ## issue 3 Physical Memory Protection (PMP) registers (38 tests) ```c ERROR | Error evaluating verify condition (PMP['implemented']): name 'PMP' is not defined ``` Why all test passed, though I still duplicate error messages. ![image](https://hackmd.io/_uploads/rJDYrao-Zg.png) I find these context in readme.md ```c ### 3. config-3-pipeline.ini - Project: 3-pipeline - ISA Profile: RV32I + Zicsr (Base Integer + CSR Instructions) - ISA Spec: `mycpu_plugin/mycpu_isa_rv32i_zicsr.yaml` - Platform Spec: `mycpu_plugin/mycpu_platform.yaml` - Test Count: 119 tests (RV32I + Zicsr + PMP) ``` So I check `mycpu_plugin/mycpu_platform.yaml` and `mycpu_plugin/mycpu_isa_rv32i_zicsr.yaml` , and tried to add ```c PMP: implemented: False ``` to see if it make differance, but it turns out the same. Following on from the issues mentioned [above](https://hackmd.io/f2M3DssDTWy3uYJNpmZojg?stext=15025%3A51%3A0%3A1765458252%3AxNpjcL&both=), I decided to run my entire program on another computer, and it turns out **All PMP test cases passed**. ```c INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_all_entries_check-01.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_all_entries_check-02.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_all_entries_check-03.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_all_entries_check-04.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_A_all.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_A_off_all.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_A_tor_bot.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_A_tor_zero.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_L_access_all.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_L_modify_napot.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_L_modify_off.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_L_modify_tor.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_XWR_all-01.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_XWR_all-02.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_XWR_all-03.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_XWR_all-04.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_na4_all.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_napot_all.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_tor_all.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_tor_check-01.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_tor_check-02.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_cfg_tor_check-03.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_csr_walk.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_grain.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_grain_check.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_misaligned_na4.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_misaligned_napot.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_misaligned_off.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_misaligned_tor.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_na4_legal_lwxr.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_napot_legal_lwxr.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_priority.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_priority_off.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpm_tor_legal_lwxr.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpu_cfg_A_off.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpu_cfg_XWR.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpu_csr_access.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpu_mprv_check-01.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpu_mprv_check-02.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpu_na4_legal_lxwr.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpu_napot_legal_lxwr.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpu_none.S/ref/Reference-rv32emu.signature INFO | Reference signature generated: /home/ubuntu/j-cpu/2025_computer_architecture_mycpu/tests/riscof_work_3pl/rv32i_m/pmp/src/pmpu_tor_legal_lxwr.S/ref/Reference-rv32emu.signature ``` All cases passed. ```c INFO | Results: 119 passed, 0 failed INFO | Running Tests on Reference Model ``` ## What I learned from Bootcamp - Data Types and Structuring: Learned about Chisel's basic data types, including Bits, SInt (signed integers), UInt (unsigned integers), and Bool. Also, learned to use higher-order types like Bundles (similar to C structs for named fields) and Vecs (collections of the same type, acting as wire arrays) for organizing data flow,. - Writing Hardware Generators: Learned how to write hardware generators in Chisel that take advantage of Scala's high-level programming language features . - Unit Testing and Debugging: Acquired the ability to write unit tests for Chisel designs and learned how to generate waveform files during testing by setting the environment variable WRITE_VCD to 1.