contributed by ???
The architecture diagram of MyCPU
According to the architecture diagram's data path and control signal, complete MyCPU and verify it through testing.This project provides several tests.
[info] Run completed in 52 seconds, 294 milliseconds.
[info] Total number of tests run: 9
[info] Suites: completed 7, aborted 0
[info] Tests: succeeded 9, failed 0, canceled 0, ignored 0, pending 0
[info] All tests passed.
At 2ps, the instruction decoder received the 0x00A02223 instruction, which is an SW instruction. Therefore, the instruction decoder sets the io_memory_write_enable to 1. SW instructions do not require reading the content of memory, so the instruction decoder sets io_memory_read_enable to 0.
At 4ps, the instruction decoder received the 0x000022B7 instruction, which is a lui instruction. Consequently, the instruction decoder sets the io_memory_read_enable to 1. Lui instructions do not require modifying the content of memory, therefore the instruction decoder sets io_memory_write_enable to 0.
Connect the signals together according to the CPU architecture diagram.
My Homework 2 program involves converting a floating-point matrix to a bfloat16 matrix and performing matrix multiplication.
Here is the result of running 'make update' using the homework 2 program. During the linking process, an error occurred because the program cannot contain multiplication, division operations, and variables of floating-point type. I spent a long time trying to resolve this until the teacher reminded me that MyCPU only supports the base instruction set (RV32I).
$ make update
riscv-none-elf-as -R -march=rv32i_zicsr -mabi=ilp32 -o init.o init.S
riscv-none-elf-gcc -O0 -Wall -march=rv32i_zicsr -mabi=ilp32 -c -o myprogram.o myprogram.c
riscv-none-elf-ld -o myprogram.elf -T link.lds --oformat=elf32-littleriscv myprogram.o init.o
riscv-none-elf-ld: myprogram.o: in function `.L4':
myprogram.c:(.text+0xbc): undefined reference to `__divsf3'
riscv-none-elf-ld: myprogram.c:(.text+0xd8): undefined reference to `__addsf3'
riscv-none-elf-ld: myprogram.o: in function `.L8':
myprogram.c:(.text+0x144): undefined reference to `__floatsisf'
riscv-none-elf-ld: myprogram.c:(.text+0x158): undefined reference to `__addsf3'
riscv-none-elf-ld: myprogram.o: in function `.L7':
myprogram.c:(.text+0x184): undefined reference to `__floatsisf'
riscv-none-elf-ld: myprogram.o: in function `main':
myprogram.c:(.text+0x23c): undefined reference to `__fixsfsi'
riscv-none-elf-ld: myprogram.c:(.text+0x25c): undefined reference to `__fixsfsi'
riscv-none-elf-ld: myprogram.c:(.text+0x284): undefined reference to `__addsf3'
riscv-none-elf-ld: myprogram.c:(.text+0x2a8): undefined reference to `__fixsfsi'
riscv-none-elf-ld: myprogram.c:(.text+0x2c8): undefined reference to `__fixsfsi'
riscv-none-elf-ld: myprogram.c:(.text+0x2f0): undefined reference to `__addsf3'
riscv-none-elf-ld: myprogram.c:(.text+0x314): undefined reference to `__fixsfsi'
I replaced the floating-point matrix in the homework 2 program with an integer matrix and used multiple additions instead of multiplication operations. Finally, I saved the results at memory address 4, 8, 12, and 16.
int multiplication(int a, int b){
int temp = 0;
for(int i=0;i<b;i++){
temp += a;
}
return temp;
}
int main() {
int a[2][2] = {
{1, 2},
{3, 4}
};
int b[2][2] = {
{5, 6},
{7, 8}
};
int c[2][2] = {0};
c[0][0] += multiplication(a[0][0], b[0][0]);
c[0][0] += multiplication(a[0][1], b[1][0]);
c[0][1] += multiplication(a[0][0], b[0][1]);
c[0][1] += multiplication(a[0][1], b[1][1]);
c[1][0] += multiplication(a[1][0], b[0][0]);
c[1][0] += multiplication(a[1][1], b[1][0]);
c[1][1] += multiplication(a[1][0], b[0][1]);
c[1][1] += multiplication(a[1][1], b[1][1]);
*((volatile int *) (4)) = c[0][0];
*((volatile int *) (8)) = c[0][1];
*((volatile int *) (12)) = c[1][0];
*((volatile int *) (16)) = c[1][0];
return 0;
}
$ make update
riscv-none-elf-as -R -march=rv32i_zicsr -mabi=ilp32 -o init.o init.S
riscv-none-elf-gcc -O0 -Wall -march=rv32i_zicsr -mabi=ilp32 -c -o myprogram.o myprogram.c
riscv-none-elf-ld -o myprogram.elf -T link.lds --oformat=elf32-littleriscv myprogram.o init.o
riscv-none-elf-objcopy -O binary -j .text -j .data myprogram.elf myprogram.asmbin
cp -f fibonacci.asmbin hello.asmbin mmio.asmbin quicksort.asmbin sb.asmbin fortestprint.asmbin myprogram.asmbin ../src/main/resources
rm init.o myprogram.elf
class myprogram extends AnyFlatSpec with ChiselScalatestTester {
behavior.of("Single Cycle CPU")
it should "matrix multipicaltion" in {
test(new TestTopModule("myprogram.asmbin")).withAnnotations(TestAnnotations.annos) { c =>
for (i <- 1 to 50) {
c.clock.step(1000)
c.io.mem_debug_read_address.poke((i * 4).U) // Avoid timeout
}
c.io.mem_debug_read_address.poke(4.U)
c.clock.step()
c.io.mem_debug_read_data.expect(19.U)
c.io.mem_debug_read_address.poke(8.U)
c.clock.step()
c.io.mem_debug_read_data.expect(22.U)
c.io.mem_debug_read_address.poke(12.U)
c.clock.step()
c.io.mem_debug_read_data.expect(43.U)
c.io.mem_debug_read_address.poke(16.U)
c.clock.step()
c.io.mem_debug_read_data.expect(50.U)
}
}
}
$ sbt "testOnly riscv.singlecycle.myprogram"
[info] welcome to sbt 1.9.7 (Oracle Corporation Java 1.8.0_391)
[info] loading settings for project ca2023-lab3-build from plugins.sbt ...
[info] loading project definition from /home/cheng/ca2023-lab3/project
[info] loading settings for project root from build.sbt ...
[info] set current project to mycpu (in build file:/home/cheng/ca2023-lab3/)
[info] myprogram:
[info] Single Cycle CPU
[info] - should matrix multipicaltion
[info] Run completed in 14 seconds, 936 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: 17 s, completed Dec 1, 2023 7:18:56 PM