# Construct a single-cycle CPU with Chisel contributed by < [TRChen11011](https://github.com/TRChen11011/ca2023-lab3) > ## Environment setup OS : Ubuntu 22. ### Install jave : jdk 11 verilog : verilator, gtkwave apt : curl, sbt ## MyCPU ### Finish Scala #### IFE :::info Need to consider jal,j...... etc. instruction. ::: At first,I don't consider jump,so it went wrong first. #### ID :::info consider the instruction whether L type or S type. Then give the `io.memory_read_enable` and `io.memory_write_enable` ::: #### EXE :::info Need to consider op1 and op2 need address or reg_data. ::: At first,I don't consider Itype,so it went wrong first. #### CPU :::info connect EXE stage with other stages. ::: ### Check Waveform #### IFE ![image](https://hackmd.io/_uploads/r1gFDMsEa.png) When `io.jump_flag = 1` PC will be the PC that the instruction want to jump `100C -> 1000` #### ID ![image](https://hackmd.io/_uploads/SJUzE8sEp.png) According to `opcode = 23`,so the instruction will be `aupic`,which will be L type. #### EXE ![image](https://hackmd.io/_uploads/rJhxIIs4T.png) `aluop1_source`is true, so op1 will be `io.instruction_address`. ## Modify HW2 I change the instruction `mv` into `addi` for Match MyCPU. ### orignal code ```c=27 mv a0, s0 jal ra, CLZ mv t5, a0 #A's CLZ -> t5 mv a0, s1 ``` ### modified code ```c=27 addi a0, s0, 0 jal ra, CLZ addi t5, a0, 0 #A's CLZ -> t5 addi a0, s1, 0 ``` ## Modify CPUTest.scala ### failed case Add code below ```c=117 class mul_clz_Test extends AnyFlatSpec with ChiselScalatestTester { behavior.of("Single Cycle CPU") it should "0x1234567 * 0xffffdddd = 0x1234540a8f5c3d98" in { test(new TestTopModule("mul_clz.asmbin")).withAnnotations(TestAnnotations.annos) { c => for (i <- 1 to 50) { c.clock.step(1000) c.io.regs_debug_read_address.poke((i * 4).U) // Avoid timeout } c.io.regs_debug_read_address.poke(18.U) c.io.regs_debug_read_data.expect(0x1234540a.U) c.io.regs_debug_read_address.poke(19.U) c.io.regs_debug_read_data.expect(0x8f5c3d98.U) } } } ``` But I met these problem : :::warning > [info] <span style="color:red">&nbsp;&nbsp;- should 0x1234567 * 0xffffdddd = 0x1234540a8f5c3d98 *** FAILED ***</span> > [info] <span style="color:red">&nbsp;&nbsp; java.lang.IllegalArgumentException: requirement failed: UInt literal -1889780328 is negative</span> > [info] <span style="color:red">at scala.Predef.require(Predef.scala:337)</span> > [info] <span style="color:red">&nbsp;&nbsp;at chisel3.internal.firrtl.ULit.<init>(IR.scala:150)</span> > [info] <span style="color:red">&nbsp;&nbsp;at chisel3.UIntFactory.Lit(UIntFactory.scala:21)</span> > [info] <span style="color:red">&nbsp;&nbsp;at chisel3.UIntFactory.Lit(UIntFactory.scala:20)</span> > [info] <span style="color:red">&nbsp;&nbsp;at chisel3.packageUInt.Lit(package.scala:182)</span> > [info] <span style="color:red">&nbsp;&nbsp;at chisel3.packagefromBigIntToLiteral.U(package.scala:51)</span> > [info] <span style="color:red">&nbsp;&nbsp;at riscv.singlecycle.mul_clz_Test.anonfunnew40(CPUTest.scala:128)</span> > [info] <span style="color:red">&nbsp;&nbsp;at riscv.singlecycle.mul_clz_Test.anonfunnew40adapted(CPUTest.scala:120)</span> > [info] <span style="color:red">&nbsp;&nbsp;at chiseltest.internal.GenericBackend.anonfunrun1(GenericBackend.scala:170)</span> > [info] <span style="color:red">&nbsp;&nbsp;at chiseltest.internal.ThreadedBackendTesterThreadanon1.anonfunrun1(ThreadedBackend.scala:495)</span> > [info] <span style="color:red">&nbsp;&nbsp;...</span> ::: ### Modify again After I modify the code ```scla=125 c.io.regs_debug_read_address.poke(18.U) c.io.regs_debug_read_data.expect(0x1234540aL.U) c.io.regs_debug_read_address.poke(19.U) c.io.regs_debug_read_data.expect(0x8f5c3d98L.U) ``` :::success > [info] <span style="color:green">&nbsp;&nbsp;mul_clz_Test: > [info] <span style="color:green">Single Cycle CPU</span> > [info] <span style="color:green">- should 0x1234567 * 0xffffdddd = 0x1234540a8f5c3d98</span> > [info] <span style="color:blue">Run completed in 23 seconds, 303 milliseconds.</span> > [info] <span style="color:blue">Total number of tests run: 11</span> > [info] <span style="color:blue">Suites: completed 9, aborted 0</span> > [info] <span style="color:blue">Tests: succeeded 11, failed 0, canceled 0, ignored 0, pending 0</span> > [info] <span style="color:green">All tests passed.</span> > [success] <span style="color:green">Total time: 27 s, completed Nov 22, 2023, 1:18:53 PM</span> ::: ## Verilator WRITE_VCD=1 sbt test :::success > [info] <span style="color:blue">Run completed in 26 seconds, 573 milliseconds.</span> > [info] <span style="color:blue">Total number of tests run: 11</span> > [info] <span style="color:blue">Suites: completed 9, aborted 0</span> > [info] <span style="color:blue">Tests: succeeded 11, failed 0, canceled 0, ignored 0, pending 0</span> > [info] <span style="color:green">All tests passed.</span> > [success] <span style="color:green">Total time: 27 s, completed Nov 22, 2023, 1:21:59 PM</span> ::: make verilator :::success > <span style="color:green">Total time: 3 s, completed Nov 22, 2023, 1:26:33 PM</span> ::: ./run-verilator.sh -instruction src/main/resources/mul_clz.asmbin :::success > -time 10000 > -memory 1048576 > -instruction src/main/resources/mul_clz.asmbin > [-------------------->] 100% ::: hexdump src/main/resources/mul_clz.asmbin | head -1 :::success > 0000000 00ef 1c00 0113 ffc1 2023 00a1 0417 0000 ::: ![image](https://hackmd.io/_uploads/SkpStLiE6.png) above waveform prove the instruction is correct.