# chisel-template-cpu-jap **Repository Path**: wang-kangming/chisel-template-cpu-jap ## Basic Information - **Project Name**: chisel-template-cpu-jap - **Description**: No description available - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-05-19 - **Last Updated**: 2024-05-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 一些操作 ## 下载chisel-template ```bash mkdir ~/mycpu cd ~/mycpu git clone git@gitee.com:wang-kangming/chisel-template-cpu-jap.git cd chisel-template # delete unnecessary files rm -rf .git rm -rf src/main/scala/* src/test/scala/* # sudo apt install docker.io ? cd ~/mycpu docker build . -t riscv/mycpu # need 2 hours docker run -it -v ~/mycpu:/src riscv/mycpu ``` ## 用riscv-tests进行测试 ### 构建riscv-tests ```bash vim /opt/riscv/riscv-tests/env/p/link.ld OUTPUT_ARCH( "riscv" ) ENTRY(_start) SECTIONS { . = 0x00000000; # 0x80000000改为了0x00000000 .text.init : { *(.text.init) } . = ALIGN(0x1000); .tohost : { *(.tohost) } . = ALIGN(0x1000); .text : { *(.text) } . = ALIGN(0x1000); .data : { *(.data) } .bss : { *(.bss) } _end = .; } cd /opt/riscv/riscv-tests autoconf ./configure --prefix=/src/target make make install file /src/target/share/riscv-tests/isa/rv32ui-p-add ``` ### 将ELF文件转换为BIN文件 ELF文件具有可由内核(操作系统核心软件)重新配置的浮动信息,在运行时决定存储器地址。自制cpu没有实现内核,所以需要转换为原始的二进制文件————bin文件。 ```bash mkdir /src/chisel-template/src/riscv cd /src/chisel-template/src/riscv riscv64-unknown-elf-objcopy -O binary /src/target/share/riscv-tests/isa/rv32ui-p-add rv32ui-p-add.bin ls # 可以看到一个绿色的bin执行文件 ``` ### BIN文件的十六进制化 ```bash od -An -tx1 -w1 -v rv32ui-p-add.bin >> rv32ui-p-add.hex ls #可以看到一个hex后缀的文件 ``` od命令是将文件转换为8进制/16进制的命令。使用的4个选项的含义见如下: ```bash -An 隐藏各行左端显示的地址的信息 -t 指定转换的格式。x1以1字节(8 Bit)为单位表示16进制 -w 指定每行的数据宽度。-w1输出1行1字节 -v 禁用以*省略相同内容连续行的默认设置 ``` ### 运行测试 ```bash cd /src/chisel-template sbt "testOnly riscvtests.RiscvTest" ``` #### 批量测试 **批量生成hex文件** ```bash cd /src/chisel-template/src/shell vim tohex.sh #填写如下面的命令行,并保存 chmod a+x tohex.sh ./tohex.sh ``` tohex.sh中的内容 ```bash #!/bin/bash FILES=/src/target/share/riscv-tests/isa/rv32*i-p-* SAVE_DIR=/src/chisel-template/src/riscv for f in $FILES do FILE_NAME="${f##*/}" if [[ ! $f =~ "dump" ]]; then riscv64-unknown-elf-objcopy -O binary $f $SAVE_DIR/$FILE_NAME.bin od -An -tx1 -w1 -v $SAVE_DIR/$FILE_NAME.bin > $SAVE_DIR/$FILE_NAME.hex rm -f $SAVE_DIR/$FILE_NAME.bin fi done ``` **批量运行riscv-tests** ```bash cd /src/chisel-template/src/shell vim riscv_tests.sh #填写如下面的命令行,并保存 chmod a+x riscv_tests.sh ./riscv_tests.sh ``` riscv_tests.sh中的内容 ```bash #!/bin/bash UI_INSTS=(sw lw add addi sub and andi or ori xor xori sll srl sra slli srli srai slt sltu slti sltiu beq bne blt bge bltu bgeu jal jalr lui auipc) MI_INSTS=(csr scall) WORK_DIR=/src/chisel-template RESULT_DIR=$WORK_DIR/results mkdir -p $RESULT_DIR cd $WORK_DIR function loop_test(){ INSTS=${!1} PACKAGE_NAME=$2 ISA=$3 DIRECTORY_NAME=$4 sed -e "s/{package}/$PACKAGE_NAME/" $WORK_DIR/src/test/resources/RiscvTests.scala > $WORK_DIR/src/test/scala/RiscvTests.scala for INST in ${INSTS[@]} do echo $INST sed -e "s/{package}/$PACKAGE_NAME/" -e "s/{isa}/$ISA/" -e "s/{inst}/$INST/" $WORK_DIR/src/main/resources/Memory.scala > $WORK_DIR/src/main/scala/$DIRECTORY_NAME/Memory.scala sbt "testOnly $PACKAGE_NAME.RiscvTest" > $RESULT_DIR/$INST.txt done } PACKAGE_NAME=$1 DIRECTORY_NAME=$2 loop_test UI_INSTS[@] $PACKAGE_NAME "ui" $DIRECTORY_NAME loop_test MI_INSTS[@] $PACKAGE_NAME "mi" $DIRECTORY_NAME ``` ## 在自制CPU上运行C语言 为了在自制CPU上运行上述C程序,需要将其翻译为机器语言,也就是编译。编译软件又叫做编译器,自制CPU的人通常会自制编译器。 这是因为根据原始ISA自制CPU时,没有编译器能够输出这种ISA的机器语言。 但RISC-V这种标准ISA,由于具有丰富的生态环境,可以使用开源GCC提供的RISC-V专用编译器。使用Docker容器编译。 **编译** ```bash cd /src/chisel-template/src/c # apt install gcc-riscv64-linux-gnu riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -c -o ctest.o ctest.c ``` ```bash -march= 指定isa -mabi= 指定abi -c 编译但不链接 -o 指定输出文件名 ``` ```bash # 以下命令不要执行 riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -S ctest.c riscv64-unknown-elf-as -o ctest.o ctest.S ``` **链接** ```bash riscv64-unknown-elf-ld -b elf32-littleriscv ctest.o -T link.ld -o ctest ``` ```bash -b 指定目标架构 -T 指定读取链接脚本文件 -o 指定输出文件名 ``` **机器语言的16进制化和DUMP文件的创建** ```bash cd /src/chisel-template/src/c riscv64-unknown-elf-objcopy -O binary ctest ctest.bin od -An -tx1 -w1 -v ctest.bin > ../hex/ctest.hex riscv64-unknown-elf-objdump -b elf32-littleriscv -D ctest > ../dump/ctest.elf.dmp cat ../dump/ctest.elf.dmp ``` 内容如下: ```bash ctest: file format elf32-littleriscv Disassembly of section .text: 00000000
: 0: fe010113 addi sp,sp,-32 4: 00812e23 sw s0,28(sp) 8: 02010413 addi s0,sp,32 c: 00100793 li a5,1 10: fef42623 sw a5,-20(s0) 14: 00200793 li a5,2 18: fef42423 sw a5,-24(s0) 1c: fec42703 lw a4,-20(s0) 20: fe842783 lw a5,-24(s0) 24: 00f707b3 add a5,a4,a5 28: fef42223 sw a5,-28(s0) 2c: fe442703 lw a4,-28(s0) 30: 00100793 li a5,1 34: 00f71a63 bne a4,a5,48 38: fe442783 lw a5,-28(s0) 3c: 00178793 addi a5,a5,1 40: fef42223 sw a5,-28(s0) 44: 0100006f j 54 48: fe442783 lw a5,-28(s0) 4c: 00278793 addi a5,a5,2 50: fef42223 sw a5,-28(s0) 54: c0001073 unimp 58: 00000793 li a5,0 5c: 00078513 mv a0,a5 60: 01c12403 lw s0,28(sp) 64: 02010113 addi sp,sp,32 68: 00008067 ret Disassembly of section .comment: 00000000 <.comment>: 0: 3a434347 fmsub.d ft6,ft6,ft4,ft7,rmm 4: 2820 fld fs0,80(s0) 6: 29554e47 fmsub.s ft8,fa0,fs5,ft5,rmm a: 3920 fld fs0,112(a0) c: 322e fld ft4,232(sp) e: 302e fld ft0,232(sp) ... Disassembly of section .riscv.attributes: 00000000 <.riscv.attributes>: 0: 1b41 addi s6,s6,-16 2: 0000 unimp 4: 7200 flw fs0,32(a2) 6: 7369 lui t1,0xffffa 8: 01007663 bgeu zero,a6,14 c: 0011 c.nop 4 e: 0000 unimp 10: 1004 addi s1,sp,32 12: 7205 lui tp,0xfffe1 14: 3376 fld ft6,376(sp) 16: 6932 flw fs2,12(sp) 18: 7032 flw ft0,44(sp) 1a: 0030 addi a2,sp,8 ``` **运行测试** ```bash cd /src/chisel-template sbt "testOnly ctest.HexTest" ``` ## 指令冒险 ### 分支冒险 给/src/chisel-template/src/c/Makefile编辑如下: ```bash %: %.c riscv64-unknown-elf-gcc -O2 -march=rv32iv -mabi=ilp32 -c -o $@.o $< riscv64-unknown-elf-ld -b elf32-littleriscv $@.o -T link.ld -o $@ riscv64-unknown-elf-objcopy -O binary $@ $@.bin od -An -tx1 -w1 -v $@.bin > ../hex/$@.hex riscv64-unknown-elf-objdump -b elf32-littleriscv -D $@ > ../dump/$@.elf.dmp rm -f $@.o rm -f $@ rm -f $@.bin ``` 执行如下命令: ```bash cd /src/chisel-template/src/c make br_hazard cat /src/chisel-template/src/dump/br_hazard.elf.dmp ``` 输出结果如下: ```bash 00000000
: 0: 00100513 li a0,1 4: 00200593 li a1,2 8: 00c000ef jal ra,14 c: 00200513 li a0,2 10: 00300593 li a1,3 00000014 : 14: 00000013 nop 18: 00000013 nop 1c: 00000013 nop 20: 00000013 nop 24: 00b50633 add a2,a0,a1 28: 00000013 nop 2c: 00000013 nop 30: 00000013 nop 34: 00000013 nop 38: c0001073 unimp 3c: 00000513 li a0,0 40: 00008067 ret ``` 测试分支冒险处理前。 将PipelineTest.scala的package名改为pipeline ```bash vim /src/chisel-template/src/test/scala/PipelineTest.scala ## 修改为pipeline cd /src/chisel-template sbt "testOnly pipeline.HexTest" ``` 测试分支冒险处理后。 将PipelineBrHazardTest.scala的package名改为pipeline_brhazard ```bash vim /src/chisel-template/src/test/scala/PipelineBrHazardTest.scala ## 修改为pipeline_brhazard vim /src/chisel-template/src/main/scala/08_pipeline_brhazard/Memory.scala ## 修改为loadMemoryFromFile(mem, "src/hex/br_hazard.hex") cd /src/chisel-template sbt "testOnly pipeline_brhazard.HexTest" ``` ### 数据冒险 **数据冒险处理前的测试** ```bash cd /src/chisel-template/src/c make hazard_wb vim /src/chisel-template/src/main/scala/08_pipeline_brhazard/Memory.scala # 修改为 loadMemoryFromFile(mem, "src/hex/hazard_wb.hex") cd /src/chisel-template sbt "testOnly pipeline_brhazard.HexTest" ``` **数据冒险处理后的测试** ```bash cd /src/chisel-template/src/c make hazard_ex vim /src/chisel-template/src/main/scala/08_pipeline_brhazard/Memory.scala # 修改为 loadMemoryFromFile(mem, "src/hex/hazard_ex.hex") cd /src/chisel-template sbt "testOnly pipeline_datahazard.HexTest" ``` ### riscv-tests测试 ```bash cd /src/chisel-template/src/shell ./riscv_tests.sh pipeline_datahazard 09_pipeline_datahazard ``` ## 向量指令 ### VSETVLI指令的实现 ———— e32 m1测试 ```bash cd /src/chisel-template/src/c/ make vsetvli cat /src/chisel-template/src/dump/vsetvli.elf.dmp ``` 将输出如下内容: ```bash ... 00000000
: 0: 00500793 li a5,5 4: 0087f757 vsetvli a4,a5,e32,m1,tu,mu,d1 8: 40e787b3 sub a5,a5,a4 c: fe079ce3 bnez a5,4 10: c0001073 unimp 14: 00000513 li a0,0 18: 00008067 ret ... ``` 用寄存器加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/10_vsetvli/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vsetvli.hex") ``` 运行测试命令的执行: ```bash cd /src/chisel-template sbt "testOnly vsetvli.HexText" ``` 测试的结果如下所示: 未完待续 ### VSETVLI指令的实现 ———— e64 m1测试 ```bash cd /src/chisel-template/src/c/ make vsetvli_e64 ``` 用寄存器加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/10_vsetvli/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vsetvli_e64.hex") ``` 运行测试命令的执行: ```bash cd /src/chisel-template sbt "testOnly vsetvli.HexText" ``` 测试的结果如下所示: 未完待续 ### VSETVLI指令的实现 ———— e32 m2测试 ```bash cd /src/chisel-template/src/c/ make vsetvli_m2 ``` 用寄存器加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/10_vsetvli/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vsetvli_m2.hex") ``` 运行测试命令的执行: ```bash cd /src/chisel-template sbt "testOnly vsetvli.HexText" ``` 测试的结果如下所示: 未完待续 ### 向量加载指令 ———— e32 m1 创建hex和dump的文件 ```bash cd /src/chisel-template/src/c make vle32 ``` 用寄存器加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/11_vle/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vle32.hex") ``` 运行测试命令的执行: ```bash cd /src/chisel-template sbt "testOnly vle.HexText" ``` 测试的结果如下所示: 未完待续 ### 向量加载指令 ———— e64 m1 创建hex和dump的文件 ```bash cd /src/chisel-template/src/c make vle64 ``` 用寄存器加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/11_vle/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vle64.hex") ``` 运行测试命令的执行: ```bash cd /src/chisel-template sbt "testOnly vle64.HexText" ``` 测试的结果如下所示: 未完待续 ### 向量加载指令 ———— e32 m2 创建hex和dump的文件 ```bash cd /src/chisel-template/src/c make vle32_m2 ``` 用寄存器加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/11_vle/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vle32_m2.hex") ``` 运行测试命令的执行: ```bash cd /src/chisel-template sbt "testOnly vle.HexText" ``` 测试的结果如下所示: 未完待续 ## 向量加法指令的实现 ### e32 m1测试 创建hex文件和dump文件。 ```bash cd /src/chisel-template/src/c make vadd cat /src/chisel-template/src/dump/vadd.elf.dmp ``` 用存储器存储加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/12_vadd/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vadd.hex") ``` ```bash cd /src/chisel-template sbt "testOnly vadd.HexTest" ``` ### e64 m1测试 创建hex文件和dump文件。 ```bash cd /src/chisel-template/src/c make vadd_e64 cat /src/chisel-template/src/dump/vadd_e64.elf.dmp ``` 用存储器存储加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/12_vadd/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vadd_e64.hex") ``` ```bash cd /src/chisel-template sbt "testOnly vadd.HexTest" ``` ### e32 m2测试 创建hex文件和dump文件。 ```bash cd /src/chisel-template/src/c make vadd_m2 cat /src/chisel-template/src/dump/vadd_m2.elf.dmp ``` 用存储器存储加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/12_vadd/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vadd_m2.hex") ``` ```bash cd /src/chisel-template sbt "testOnly vadd.HexTest" ``` ## 向量存储指令的实现 ### e32 m1测试 创建hex文件和dump文件。 ```bash cd /src/chisel-template/src/c make vse32 cat /src/chisel-template/src/dump/vse32.elf.dmp ``` 用存储器存储加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/13_vse/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vse32.hex") ``` ```bash cd /src/chisel-template sbt "testOnly vse.HexTest" ``` ### e64 m1测试 创建hex文件和dump文件。 ```bash cd /src/chisel-template/src/c make vse64 cat /src/chisel-template/src/dump/vse64.elf.dmp ``` 用存储器存储加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/13_vse/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vse64.hex") ``` ```bash cd /src/chisel-template sbt "testOnly vse.HexTest" ``` ### e32 m2测试 创建hex文件和dump文件。 ```bash cd /src/chisel-template/src/c make vse32_m2 cat /src/chisel-template/src/dump/vse32_m2.elf.dmp ``` 用存储器存储加载创建的HEX文件 ```bash vim /src/chisel-template/src/main/scala/13_vse/Memory.scala ``` ```scala loadMemoryFromFile(mem, "src/hex/vse32_m2.hex") ``` ```bash cd /src/chisel-template sbt "testOnly vse.HexTest" ```